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:
- Login to your ngrok account.
- Retrieve your authtoken.
- Setup a TCP address endpoint for the sftp tunnel; the ssh tunnel will be randomly generated.
The ngrok configuration (
/volume1/ngrok/config.yml) was added.
Its job is to pre-configure the ngrok tunnels.
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.
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, the following tasks were created:
- Launch the SFTP tunnel monitoring script (as root and triggered on boot):
python3 /volume1/ngrok/sftp_ngrok_watchdog.py &
- SSH tunnel (as root at a time in the past as it will be run manually via DSM when needed):
/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.