I have a Synology NAS which runs using Synology's DSM OS. I can access this via its quickconnect cloud system. Unfortunately this only allows for DSM's web interface even though it's sometimes useful to access the NAS remotely via SFTP or SSH.
The usual way to achieve this might be to forward ports from the internet through the router firewall to tne NAS on the local network (also called opening a port). Unfortunately, not all networks are setup to allow port forwarding. To overcome this, I recently setup ngrok on the NAS to allow access permanently via SFTP and on-demand via SSH.
First ngrok needs to be setup by following the steps shown on the ngrok website.
Next, I installed python3 via the DSM package manager because I monitor the SFTP ngrok tunnel using a python script.
To setup ngrok, the following needs to be done:
I'm placing all the files needed in this article together in an accessible location on one of the data volumes (
The ngrok configuration (
/volume1/ngrok/config.yml) was added. Its job is to pre-configure the ngrok tunnels. Its content is below:
authtoken: # THIS IS THE NGROK AUTHTOKEN FOR THE ACCOUNT BEING USED region: us # THIS IS THE REGION CODE AS PER YOUR SETUP IN NGROK tunnels: sftp: addr: 123 # THIS IS THE NAS SFTP PORT (INTEGER) WHICH IS CONFIGURED IN DSM. proto: tcp remote-addr: 1.tcp.us.ngrok.io:12345 # THIS IS THE NGROK TCP TUNNEL PREVIOUSLY CREATED (PUBLIC_ADDRESS:PUBLIC_PORT) ssh: addr: 1234 # THIS IS THE NAS SSH PORT (INTEGER) WHICH IS CONFIGURED IN DSM. proto: tcp
The monitoring script (
/volume1/ngrok/sftp_tunnel_watchdog.py) was added. Its job is to ensure that the SFTP tunnel remains accessible.
It does this by checking if the port is open via ngrok, and if not it kills and restarts the ngrok tunnel.
Its content is below:
import socket import os import time import signal ngrok_host = [STR: PUBLIC ADDRESS] ngrok_port = [INT: PUBLIC PORT] def checkNgrok(): # checking if the port is open via ngrok sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) result = sock.connect_ex((ngrok_host,ngrok_port)) if result == 0: sock.close() return True else: sock.close() return False while True: # forever try: # don't want this to ever stop... if checkNgrok(): print(" > ngrok port is open - nothing to do.") else: print(" > ngrok port is not open - kill the process and relaunch tunnel.") # if the ngrok process is still running, kill it for line in os.popen("ps -ef | grep \"ngrok start\""): if "sftp" in line: print(" > killing process.") fields = line.split() # extracting Process ID from the output pid = fields # terminating process os.kill(int(pid), signal.SIGKILL) # start the ngrok tunnel print(" > starting process.") cmd = "/volume1/ngrok/ngrok start sftp -config /volume1/ngrok/config.yml -log=stdout > /dev/null &" os.system(cmd) except: None print() time.sleep(10)
Via the DSM task scheduler, for following tasks were created:
python3 /volume1/ngrok/sftp_ngrok_watchdog.py &
/volume1/ngrok/ngrok start ssh -config /volume1/ngrok/config.yml
On the ngrok website, there are various pages which will help you control or view the status of active tunnels.
The endpoint status page tells you the hostnames the active tunnels which is needed for ssh random hostnames.
The tunnel agent sessions page lets you stop the active sessions tunnel which is useful to stop the ssh tunnel.