We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
SSH Tunnel missing support for running non default port
My server for the ssh tunnel is not running on port 22. After recovery the tunnels are not recreated. 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `home.admin/config.scripts/internet.sshtunnel.py`
Content:
```
1 #!/usr/bin/python3
2 
3 import sys, subprocess, re
4 from pathlib import Path
5 
6 # IDEA: At the momemt its just Reverse-SSh Tunnels thats why [INTERNAL-PORT]<[EXTERNAL-PORT]
7 # For the future also just local ssh tunnels could be added with [INTERNAL-PORT]-[EXTERNAL-PORT]
8 # for the use case when a server wants to use a RaspiBlitz behind a NAT as Lightning backend
9 
10 # display config script info
11 if len(sys.argv) <= 1 or sys.argv[1] == "-h" or sys.argv[1] == "help":
12     print("forward ports from another server to raspiblitz with reverse SSH tunnel")
13     print("internet.sshtunnel.py [on|off|restore] [USER]@[SERVER] \"[INTERNAL-PORT]<[EXTERNAL-PORT]\"")
14     print("note that [INTERNAL-PORT]<[EXTERNAL-PORT] can one or multiple forwardings")
15     sys.exit(1)
16 
17 #
18 # CONSTANTS
19 # sudo journalctl -f -u autossh-tunnel
20 #
21 
22 SERVICENAME="autossh-tunnel.service"
23 SERVICEFILE="/etc/systemd/system/"+SERVICENAME
24 SERVICETEMPLATE="""# see config script internet.sshtunnel.py
25 [Unit]
26 Description=AutoSSH tunnel service
27 After=network.target
28 
29 [Service]
30 User=root
31 Group=root
32 Environment="AUTOSSH_GATETIME=0"
33 ExecStart=/usr/bin/autossh -M 0 -N -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ServerAliveCountMax=2 [PLACEHOLDER]
34 StandardOutput=journal
35 
36 [Install]
37 WantedBy=multi-user.target
38 """
39 
40 # get LND port form lnd.conf
41 LNDPORT = subprocess.getoutput("sudo cat /mnt/hdd/lnd/lnd.conf | grep '^listen=*' | cut -f2 -d':'")
42 if len(LNDPORT) == 0:
43     LNDPORT="9735"
44 
45 
46 
47 #
48 # RESTORE = SWITCHING ON with restore flag on
49 # on restore other external scripts dont need calling
50 #
51 
52 forwardingLND = False
53 restoringOnUpdate = False
54 if sys.argv[1] == "restore":
55     print("internet.sshtunnel.py -> running with restore flag")
56     sys.argv[1] = "on"
57     restoringOnUpdate = True
58 
59 #
60 # SWITCHING ON
61 #
62 
63 if sys.argv[1] == "on":
64 
65     # check if already running
66     isRunning = subprocess.getoutput("sudo systemctl --no-pager | grep -c '%s'" % (SERVICENAME))
67     if int(isRunning) > 0:
68       print("SSH TUNNEL SERVICE IS RUNNING - run 'internet.sshtunnel.py off' first to set new tunnel")
69       sys.exit(1)
70 
71     # check server address
72     if len(sys.argv) < 3:
73         print("[USER]@[SERVER] missing - use 'internet.sshtunnel.py -h' for help")
74         sys.exit(1)
75     if sys.argv[2].count("@") != 1:
76         print("[USER]@[SERVER] wrong - use 'internet.sshtunnel.py -h' for help")
77         sys.exit(1)
78     ssh_server = sys.argv[2]
79 
80     # genenate additional parameter for autossh (forwarding ports)
81     if len(sys.argv) < 4:
82         print("[INTERNAL-PORT]<[EXTERNAL-PORT] missing")
83         sys.exit(1)
84     ssh_ports=""
85     additional_parameters=""
86     i = 3
87     while i < len(sys.argv):
88 
89         # check forwarding format
90         if sys.argv[i].count("<") != 1:
91             print("[INTERNAL-PORT]<[EXTERNAL-PORT] wrong format '%s'" % (sys.argv[i]))
92             sys.exit(1)
93 
94         # get ports
95         sys.argv[i] = re.sub('"','', sys.argv[i] )
96         ports = sys.argv[i].split("<")
97         port_internal = ports[0]
98         port_external = ports[1]
99         if port_internal.isdigit() == False:
100             print("[INTERNAL-PORT]<[EXTERNAL-PORT] internal not number '%s'" % (sys.argv[i]))
101             sys.exit(1)
102         if port_external.isdigit() == False:
103             print("[INTERNAL-PORT]<[EXTERNAL-PORT] external not number '%s'" % (sys.argv[i]))
104             sys.exit(1) 
105         if port_internal == LNDPORT:
106             print("Detected LND Port Forwarding")
107             forwardingLND = True
108             if port_internal != port_external:
109                 print("FAIL: When tunneling your local LND port '%s' it needs to be the same on the external server, but is '%s'" % (LNDPORT,port_external))
110                 print("Try again by using the same port. If you cant change the external port, change local LND port with: /home/admin/config.scripts/lnd.setport.sh")
111                 sys.exit(1)
112 
113         ssh_ports = ssh_ports + "\"%s\" " % (sys.argv[i])
114         additional_parameters= additional_parameters + "-R %s:localhost:%s " % (port_external,port_internal)
115         i=i+1
116 
117     # genenate additional parameter for autossh (server)
118     ssh_ports = ssh_ports.strip()
119     additional_parameters= additional_parameters + ssh_server
120 
121     # generate custom service config
122     service_data = SERVICETEMPLATE.replace("[PLACEHOLDER]", additional_parameters)
123 
124     # debug print out service
125     print()
126     print("*** New systemd service: %s" % (SERVICENAME))
127     print(service_data)
128 
129     # write service file
130     service_file = open("/home/admin/temp.service", "w")
131     service_file.write(service_data)
132     service_file.close()
133     subprocess.call("sudo mv /home/admin/temp.service %s" % (SERVICEFILE), shell=True)
134 
135     # check if SSH keys for root user need to be created
136     print()
137     print("*** Checking root SSH pub keys")
138     ssh_pubkey=""
139     try:
140         ssh_pubkey = subprocess.check_output("sudo cat /root/.ssh/id_rsa.pub", shell=True, universal_newlines=True)
141         print("OK - root id_rsa.pub file exists")
142     except subprocess.CalledProcessError as e:
143         print("Generating root SSH keys ...")
144         subprocess.call("sudo sh -c 'yes y | sudo -u root ssh-keygen -b 2048 -t rsa -f ~/.ssh/id_rsa  -q -N \"\"'", shell=True)
145         ssh_pubkey = subprocess.check_output("sudo cat /root/.ssh/id_rsa.pub", shell=True, universal_newlines=True)
146     
147     # copy SSH keys for backup (for update with new sd card)
148     print("making backup copy of SSH keys")
149     subprocess.call("sudo cp -r /root/.ssh /mnt/hdd/ssh/root_backup", shell=True)
150     print("DONE")
151     
152     # write ssh tunnel data to raspiblitz config (for update with new sd card)
153     print("*** Updating RaspiBlitz Config")
154     with open('/mnt/hdd/raspiblitz.conf') as f:
155         file_content = f.read()
156     if file_content.count("sshtunnel=") == 0:
157         file_content = file_content+"\nsshtunnel=''"
158     file_content = re.sub("sshtunnel=.*", "sshtunnel='%s %s'" % (ssh_server, ssh_ports), file_content)
159     if restoringOnUpdate == False:
160         serverdomain=ssh_server.split("@")[1]
161 
162         # make sure serverdomain is set as tls alias 
163         print("Setting server as tls alias")
164         oldConfigHash=subprocess.getoutput("sudo shasum -a 256 /mnt/hdd/lnd/lnd.conf")
165         subprocess.call("sudo sed -i \"s/^#tlsextradomain=.*/tlsextradomain=/g\" /mnt/hdd/lnd/lnd.conf", shell=True)
166         subprocess.call("sudo sed -i \"s/^tlsextradomain=.*/tlsextradomain=%s/g\" /mnt/hdd/lnd/lnd.conf" % (serverdomain), shell=True)
167         newConfigHash=subprocess.getoutput("sudo shasum -a 256 /mnt/hdd/lnd/lnd.conf")
168         if oldConfigHash != newConfigHash:
169             print("lnd.conf changed ... generating new TLS cert")
170             subprocess.call("sudo /home/admin/config.scripts/lnd.newtlscert.sh", shell=True)
171         else:
172             print("lnd.conf unchanged... keep TLS cert")
173 
174         if forwardingLND:
175             # setting server explicitly on LND if LND port is forwarded
176             print("Setting fixed address for LND with raspiblitz lndAddress")
177             file_content = re.sub("lndAddress=.*", "lndAddress='%s'" % (serverdomain), file_content)
178         else:
179             print("No need to set fixed address for LND with raspiblitz lndAddress")
180     file_content = "".join([s for s in file_content.splitlines(True) if s.strip("\r\n")]) + "\n"
181     print(file_content)
182     with open("/mnt/hdd/raspiblitz.conf", "w") as text_file:
183         text_file.write(file_content)
184     print("DONE")
185 
186     # make sure autossh is installed
187     # https://www.everythingcli.org/ssh-tunnelling-for-fun-and-profit-autossh/
188     print()
189     print("*** Install autossh")
190     subprocess.call("sudo apt-get install -y autossh", shell=True)
191     
192     # enable service
193     print()
194     print("*** Enabling systemd service: %s" % (SERVICENAME))
195     subprocess.call("sudo systemctl daemon-reload", shell=True)
196     subprocess.call("sudo systemctl enable %s" % (SERVICENAME), shell=True)
197 
198     # final info (can be ignored if run by other script)
199     print()
200     print("**************************************")
201     print("*** WIN - SSH TUNNEL SERVICE SETUP ***")
202     print("**************************************")
203     print("See chapter 'How to setup port-forwarding with a SSH tunnel?' in:")
204     print("https://github.com/rootzoll/raspiblitz/blob/master/FAQ.md")
205     print("- Tunnel service needs final reboot to start.")
206     print("- After reboot check logs: sudo journalctl -f -u %s" % (SERVICENAME))
207     print("- Make sure the SSH pub key of this RaspiBlitz is in 'authorized_keys' of %s :" % (ssh_server))
208     print(ssh_pubkey)
209     print()
210 
211 #
212 # SWITCHING OFF
213 #
214 
215 elif sys.argv[1] == "off":
216 
217     print("*** Disabling systemd service: %s" % (SERVICENAME))
218     subprocess.call("sudo systemctl stop %s" % (SERVICENAME), shell=True)
219     subprocess.call("sudo systemctl disable %s" % (SERVICENAME), shell=True)
220     subprocess.call("sudo systemctl reset-failed", shell=True)
221     subprocess.call("sudo rm %s" % (SERVICEFILE), shell=True)
222     subprocess.call("sudo systemctl daemon-reload", shell=True)
223     print("OK Done")
224     print()
225 
226     print("*** Removing LND Address")
227     subprocess.call("sudo /home/admin/config.scripts/lnd.setaddress.sh off", shell=True)
228     print()
229 
230     print("*** Removing SSH Tunnel data from RaspiBlitz config")
231     with open('/mnt/hdd/raspiblitz.conf') as f:
232         file_content = f.read()
233     file_content = re.sub("sshtunnel=.*", "", file_content)
234     file_content = re.sub("\n\n", "\n", file_content)
235     print(file_content)
236     with open("/mnt/hdd/raspiblitz.conf", "w") as text_file:
237         text_file.write(file_content)
238     print("OK Done")
239 
240 #
241 # UNKOWN PARAMETER
242 #
243 
244 else:
245     print ("unkown parameter - use 'internet.sshtunnel.py -h' for help")
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/home.admin/config.scripts/internet.sshtunnel.py b/home.admin/config.scripts/internet.sshtunnel.py
--- a/home.admin/config.scripts/internet.sshtunnel.py
+++ b/home.admin/config.scripts/internet.sshtunnel.py
@@ -10,7 +10,7 @@
 # display config script info
 if len(sys.argv) <= 1 or sys.argv[1] == "-h" or sys.argv[1] == "help":
     print("forward ports from another server to raspiblitz with reverse SSH tunnel")
-    print("internet.sshtunnel.py [on|off|restore] [USER]@[SERVER] \"[INTERNAL-PORT]<[EXTERNAL-PORT]\"")
+    print("internet.sshtunnel.py [on|off|restore] [USER]@[SERVER:PORT] \"[INTERNAL-PORT]<[EXTERNAL-PORT]\"")
     print("note that [INTERNAL-PORT]<[EXTERNAL-PORT] can one or multiple forwardings")
     sys.exit(1)
 
@@ -70,12 +70,21 @@
 
     # check server address
     if len(sys.argv) < 3:
-        print("[USER]@[SERVER] missing - use 'internet.sshtunnel.py -h' for help")
+        print("[USER]@[SERVER:PORT] missing - use 'internet.sshtunnel.py -h' for help")
         sys.exit(1)
     if sys.argv[2].count("@") != 1:
-        print("[USER]@[SERVER] wrong - use 'internet.sshtunnel.py -h' for help")
+        print("[USER]@[SERVER:PORT] wrong - use 'internet.sshtunnel.py -h' for help")
         sys.exit(1)
     ssh_server = sys.argv[2]
+    if ssh_server.count(":") == 0:
+        ssh_server_host = ssh_server
+        ssh_server_port = "22"
+    elif ssh_server.count(":") == 1:
+        ssh_server_split = ssh_server.split(":")
+        ssh_server_host = ssh_server_split[0]
+        ssh_server_port = ssh_server_split[1]
+    else:
+        print("[USER]@[SERVER:PORT] wrong - use 'internet.sshtunnel.py -h' for help")
 
     # genenate additional parameter for autossh (forwarding ports)
     if len(sys.argv) < 4:
@@ -106,17 +115,17 @@
             print("Detected LND Port Forwarding")
             forwardingLND = True
             if port_internal != port_external:
-                print("FAIL: When tunneling your local LND port '%s' it needs to be the same on the external server, but is '%s'" % (LNDPORT,port_external))
+                print("FAIL: When tunneling your local LND port '%s' it needs to be the same on the external server, but is '%s'" % (LNDPORT, port_external))
                 print("Try again by using the same port. If you cant change the external port, change local LND port with: /home/admin/config.scripts/lnd.setport.sh")
                 sys.exit(1)
 
         ssh_ports = ssh_ports + "\"%s\" " % (sys.argv[i])
-        additional_parameters= additional_parameters + "-R %s:localhost:%s " % (port_external,port_internal)
-        i=i+1
+        additional_parameters= additional_parameters + "-R %s:localhost:%s " % (port_external, port_internal)
+        i = i + 1
 
     # genenate additional parameter for autossh (server)
     ssh_ports = ssh_ports.strip()
-    additional_parameters= additional_parameters + ssh_server
+    additional_parameters = additional_parameters + "-p " + ssh_server_port  + " " + ssh_server_host
 
     # generate custom service config
     service_data = SERVICETEMPLATE.replace("[PLACEHOLDER]", additional_parameters)
@@ -242,4 +251,4 @@
 #
 
 else:
-    print ("unkown parameter - use 'internet.sshtunnel.py -h' for help")
\ No newline at end of file
+    print ("unkown parameter - use 'internet.sshtunnel.py -h' for help")

{"golden_diff": "diff --git a/home.admin/config.scripts/internet.sshtunnel.py b/home.admin/config.scripts/internet.sshtunnel.py\n--- a/home.admin/config.scripts/internet.sshtunnel.py\n+++ b/home.admin/config.scripts/internet.sshtunnel.py\n@@ -10,7 +10,7 @@\n # display config script info\n if len(sys.argv) <= 1 or sys.argv[1] == \"-h\" or sys.argv[1] == \"help\":\n     print(\"forward ports from another server to raspiblitz with reverse SSH tunnel\")\n-    print(\"internet.sshtunnel.py [on|off|restore] [USER]@[SERVER] \\\"[INTERNAL-PORT]<[EXTERNAL-PORT]\\\"\")\n+    print(\"internet.sshtunnel.py [on|off|restore] [USER]@[SERVER:PORT] \\\"[INTERNAL-PORT]<[EXTERNAL-PORT]\\\"\")\n     print(\"note that [INTERNAL-PORT]<[EXTERNAL-PORT] can one or multiple forwardings\")\n     sys.exit(1)\n \n@@ -70,12 +70,21 @@\n \n     # check server address\n     if len(sys.argv) < 3:\n-        print(\"[USER]@[SERVER] missing - use 'internet.sshtunnel.py -h' for help\")\n+        print(\"[USER]@[SERVER:PORT] missing - use 'internet.sshtunnel.py -h' for help\")\n         sys.exit(1)\n     if sys.argv[2].count(\"@\") != 1:\n-        print(\"[USER]@[SERVER] wrong - use 'internet.sshtunnel.py -h' for help\")\n+        print(\"[USER]@[SERVER:PORT] wrong - use 'internet.sshtunnel.py -h' for help\")\n         sys.exit(1)\n     ssh_server = sys.argv[2]\n+    if ssh_server.count(\":\") == 0:\n+        ssh_server_host = ssh_server\n+        ssh_server_port = \"22\"\n+    elif ssh_server.count(\":\") == 1:\n+        ssh_server_split = ssh_server.split(\":\")\n+        ssh_server_host = ssh_server_split[0]\n+        ssh_server_port = ssh_server_split[1]\n+    else:\n+        print(\"[USER]@[SERVER:PORT] wrong - use 'internet.sshtunnel.py -h' for help\")\n \n     # genenate additional parameter for autossh (forwarding ports)\n     if len(sys.argv) < 4:\n@@ -106,17 +115,17 @@\n             print(\"Detected LND Port Forwarding\")\n             forwardingLND = True\n             if port_internal != port_external:\n-                print(\"FAIL: When tunneling your local LND port '%s' it needs to be the same on the external server, but is '%s'\" % (LNDPORT,port_external))\n+                print(\"FAIL: When tunneling your local LND port '%s' it needs to be the same on the external server, but is '%s'\" % (LNDPORT, port_external))\n                 print(\"Try again by using the same port. If you cant change the external port, change local LND port with: /home/admin/config.scripts/lnd.setport.sh\")\n                 sys.exit(1)\n \n         ssh_ports = ssh_ports + \"\\\"%s\\\" \" % (sys.argv[i])\n-        additional_parameters= additional_parameters + \"-R %s:localhost:%s \" % (port_external,port_internal)\n-        i=i+1\n+        additional_parameters= additional_parameters + \"-R %s:localhost:%s \" % (port_external, port_internal)\n+        i = i + 1\n \n     # genenate additional parameter for autossh (server)\n     ssh_ports = ssh_ports.strip()\n-    additional_parameters= additional_parameters + ssh_server\n+    additional_parameters = additional_parameters + \"-p \" + ssh_server_port  + \" \" + ssh_server_host\n \n     # generate custom service config\n     service_data = SERVICETEMPLATE.replace(\"[PLACEHOLDER]\", additional_parameters)\n@@ -242,4 +251,4 @@\n #\n \n else:\n-    print (\"unkown parameter - use 'internet.sshtunnel.py -h' for help\")\n\\ No newline at end of file\n+    print (\"unkown parameter - use 'internet.sshtunnel.py -h' for help\")\n", "issue": "SSH Tunnel missing support for running non default port\nMy server for the ssh tunnel is not running on port 22. After recovery the tunnels are not recreated. \n", "before_files": [{"content": "#!/usr/bin/python3\n\nimport sys, subprocess, re\nfrom pathlib import Path\n\n# IDEA: At the momemt its just Reverse-SSh Tunnels thats why [INTERNAL-PORT]<[EXTERNAL-PORT]\n# For the future also just local ssh tunnels could be added with [INTERNAL-PORT]-[EXTERNAL-PORT]\n# for the use case when a server wants to use a RaspiBlitz behind a NAT as Lightning backend\n\n# display config script info\nif len(sys.argv) <= 1 or sys.argv[1] == \"-h\" or sys.argv[1] == \"help\":\n    print(\"forward ports from another server to raspiblitz with reverse SSH tunnel\")\n    print(\"internet.sshtunnel.py [on|off|restore] [USER]@[SERVER] \\\"[INTERNAL-PORT]<[EXTERNAL-PORT]\\\"\")\n    print(\"note that [INTERNAL-PORT]<[EXTERNAL-PORT] can one or multiple forwardings\")\n    sys.exit(1)\n\n#\n# CONSTANTS\n# sudo journalctl -f -u autossh-tunnel\n#\n\nSERVICENAME=\"autossh-tunnel.service\"\nSERVICEFILE=\"/etc/systemd/system/\"+SERVICENAME\nSERVICETEMPLATE=\"\"\"# see config script internet.sshtunnel.py\n[Unit]\nDescription=AutoSSH tunnel service\nAfter=network.target\n\n[Service]\nUser=root\nGroup=root\nEnvironment=\"AUTOSSH_GATETIME=0\"\nExecStart=/usr/bin/autossh -M 0 -N -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ServerAliveCountMax=2 [PLACEHOLDER]\nStandardOutput=journal\n\n[Install]\nWantedBy=multi-user.target\n\"\"\"\n\n# get LND port form lnd.conf\nLNDPORT = subprocess.getoutput(\"sudo cat /mnt/hdd/lnd/lnd.conf | grep '^listen=*' | cut -f2 -d':'\")\nif len(LNDPORT) == 0:\n    LNDPORT=\"9735\"\n\n\n\n#\n# RESTORE = SWITCHING ON with restore flag on\n# on restore other external scripts dont need calling\n#\n\nforwardingLND = False\nrestoringOnUpdate = False\nif sys.argv[1] == \"restore\":\n    print(\"internet.sshtunnel.py -> running with restore flag\")\n    sys.argv[1] = \"on\"\n    restoringOnUpdate = True\n\n#\n# SWITCHING ON\n#\n\nif sys.argv[1] == \"on\":\n\n    # check if already running\n    isRunning = subprocess.getoutput(\"sudo systemctl --no-pager | grep -c '%s'\" % (SERVICENAME))\n    if int(isRunning) > 0:\n      print(\"SSH TUNNEL SERVICE IS RUNNING - run 'internet.sshtunnel.py off' first to set new tunnel\")\n      sys.exit(1)\n\n    # check server address\n    if len(sys.argv) < 3:\n        print(\"[USER]@[SERVER] missing - use 'internet.sshtunnel.py -h' for help\")\n        sys.exit(1)\n    if sys.argv[2].count(\"@\") != 1:\n        print(\"[USER]@[SERVER] wrong - use 'internet.sshtunnel.py -h' for help\")\n        sys.exit(1)\n    ssh_server = sys.argv[2]\n\n    # genenate additional parameter for autossh (forwarding ports)\n    if len(sys.argv) < 4:\n        print(\"[INTERNAL-PORT]<[EXTERNAL-PORT] missing\")\n        sys.exit(1)\n    ssh_ports=\"\"\n    additional_parameters=\"\"\n    i = 3\n    while i < len(sys.argv):\n\n        # check forwarding format\n        if sys.argv[i].count(\"<\") != 1:\n            print(\"[INTERNAL-PORT]<[EXTERNAL-PORT] wrong format '%s'\" % (sys.argv[i]))\n            sys.exit(1)\n\n        # get ports\n        sys.argv[i] = re.sub('\"','', sys.argv[i] )\n        ports = sys.argv[i].split(\"<\")\n        port_internal = ports[0]\n        port_external = ports[1]\n        if port_internal.isdigit() == False:\n            print(\"[INTERNAL-PORT]<[EXTERNAL-PORT] internal not number '%s'\" % (sys.argv[i]))\n            sys.exit(1)\n        if port_external.isdigit() == False:\n            print(\"[INTERNAL-PORT]<[EXTERNAL-PORT] external not number '%s'\" % (sys.argv[i]))\n            sys.exit(1) \n        if port_internal == LNDPORT:\n            print(\"Detected LND Port Forwarding\")\n            forwardingLND = True\n            if port_internal != port_external:\n                print(\"FAIL: When tunneling your local LND port '%s' it needs to be the same on the external server, but is '%s'\" % (LNDPORT,port_external))\n                print(\"Try again by using the same port. If you cant change the external port, change local LND port with: /home/admin/config.scripts/lnd.setport.sh\")\n                sys.exit(1)\n\n        ssh_ports = ssh_ports + \"\\\"%s\\\" \" % (sys.argv[i])\n        additional_parameters= additional_parameters + \"-R %s:localhost:%s \" % (port_external,port_internal)\n        i=i+1\n\n    # genenate additional parameter for autossh (server)\n    ssh_ports = ssh_ports.strip()\n    additional_parameters= additional_parameters + ssh_server\n\n    # generate custom service config\n    service_data = SERVICETEMPLATE.replace(\"[PLACEHOLDER]\", additional_parameters)\n\n    # debug print out service\n    print()\n    print(\"*** New systemd service: %s\" % (SERVICENAME))\n    print(service_data)\n\n    # write service file\n    service_file = open(\"/home/admin/temp.service\", \"w\")\n    service_file.write(service_data)\n    service_file.close()\n    subprocess.call(\"sudo mv /home/admin/temp.service %s\" % (SERVICEFILE), shell=True)\n\n    # check if SSH keys for root user need to be created\n    print()\n    print(\"*** Checking root SSH pub keys\")\n    ssh_pubkey=\"\"\n    try:\n        ssh_pubkey = subprocess.check_output(\"sudo cat /root/.ssh/id_rsa.pub\", shell=True, universal_newlines=True)\n        print(\"OK - root id_rsa.pub file exists\")\n    except subprocess.CalledProcessError as e:\n        print(\"Generating root SSH keys ...\")\n        subprocess.call(\"sudo sh -c 'yes y | sudo -u root ssh-keygen -b 2048 -t rsa -f ~/.ssh/id_rsa  -q -N \\\"\\\"'\", shell=True)\n        ssh_pubkey = subprocess.check_output(\"sudo cat /root/.ssh/id_rsa.pub\", shell=True, universal_newlines=True)\n    \n    # copy SSH keys for backup (for update with new sd card)\n    print(\"making backup copy of SSH keys\")\n    subprocess.call(\"sudo cp -r /root/.ssh /mnt/hdd/ssh/root_backup\", shell=True)\n    print(\"DONE\")\n    \n    # write ssh tunnel data to raspiblitz config (for update with new sd card)\n    print(\"*** Updating RaspiBlitz Config\")\n    with open('/mnt/hdd/raspiblitz.conf') as f:\n        file_content = f.read()\n    if file_content.count(\"sshtunnel=\") == 0:\n        file_content = file_content+\"\\nsshtunnel=''\"\n    file_content = re.sub(\"sshtunnel=.*\", \"sshtunnel='%s %s'\" % (ssh_server, ssh_ports), file_content)\n    if restoringOnUpdate == False:\n        serverdomain=ssh_server.split(\"@\")[1]\n\n        # make sure serverdomain is set as tls alias \n        print(\"Setting server as tls alias\")\n        oldConfigHash=subprocess.getoutput(\"sudo shasum -a 256 /mnt/hdd/lnd/lnd.conf\")\n        subprocess.call(\"sudo sed -i \\\"s/^#tlsextradomain=.*/tlsextradomain=/g\\\" /mnt/hdd/lnd/lnd.conf\", shell=True)\n        subprocess.call(\"sudo sed -i \\\"s/^tlsextradomain=.*/tlsextradomain=%s/g\\\" /mnt/hdd/lnd/lnd.conf\" % (serverdomain), shell=True)\n        newConfigHash=subprocess.getoutput(\"sudo shasum -a 256 /mnt/hdd/lnd/lnd.conf\")\n        if oldConfigHash != newConfigHash:\n            print(\"lnd.conf changed ... generating new TLS cert\")\n            subprocess.call(\"sudo /home/admin/config.scripts/lnd.newtlscert.sh\", shell=True)\n        else:\n            print(\"lnd.conf unchanged... keep TLS cert\")\n\n        if forwardingLND:\n            # setting server explicitly on LND if LND port is forwarded\n            print(\"Setting fixed address for LND with raspiblitz lndAddress\")\n            file_content = re.sub(\"lndAddress=.*\", \"lndAddress='%s'\" % (serverdomain), file_content)\n        else:\n            print(\"No need to set fixed address for LND with raspiblitz lndAddress\")\n    file_content = \"\".join([s for s in file_content.splitlines(True) if s.strip(\"\\r\\n\")]) + \"\\n\"\n    print(file_content)\n    with open(\"/mnt/hdd/raspiblitz.conf\", \"w\") as text_file:\n        text_file.write(file_content)\n    print(\"DONE\")\n\n    # make sure autossh is installed\n    # https://www.everythingcli.org/ssh-tunnelling-for-fun-and-profit-autossh/\n    print()\n    print(\"*** Install autossh\")\n    subprocess.call(\"sudo apt-get install -y autossh\", shell=True)\n    \n    # enable service\n    print()\n    print(\"*** Enabling systemd service: %s\" % (SERVICENAME))\n    subprocess.call(\"sudo systemctl daemon-reload\", shell=True)\n    subprocess.call(\"sudo systemctl enable %s\" % (SERVICENAME), shell=True)\n\n    # final info (can be ignored if run by other script)\n    print()\n    print(\"**************************************\")\n    print(\"*** WIN - SSH TUNNEL SERVICE SETUP ***\")\n    print(\"**************************************\")\n    print(\"See chapter 'How to setup port-forwarding with a SSH tunnel?' in:\")\n    print(\"https://github.com/rootzoll/raspiblitz/blob/master/FAQ.md\")\n    print(\"- Tunnel service needs final reboot to start.\")\n    print(\"- After reboot check logs: sudo journalctl -f -u %s\" % (SERVICENAME))\n    print(\"- Make sure the SSH pub key of this RaspiBlitz is in 'authorized_keys' of %s :\" % (ssh_server))\n    print(ssh_pubkey)\n    print()\n\n#\n# SWITCHING OFF\n#\n\nelif sys.argv[1] == \"off\":\n\n    print(\"*** Disabling systemd service: %s\" % (SERVICENAME))\n    subprocess.call(\"sudo systemctl stop %s\" % (SERVICENAME), shell=True)\n    subprocess.call(\"sudo systemctl disable %s\" % (SERVICENAME), shell=True)\n    subprocess.call(\"sudo systemctl reset-failed\", shell=True)\n    subprocess.call(\"sudo rm %s\" % (SERVICEFILE), shell=True)\n    subprocess.call(\"sudo systemctl daemon-reload\", shell=True)\n    print(\"OK Done\")\n    print()\n\n    print(\"*** Removing LND Address\")\n    subprocess.call(\"sudo /home/admin/config.scripts/lnd.setaddress.sh off\", shell=True)\n    print()\n\n    print(\"*** Removing SSH Tunnel data from RaspiBlitz config\")\n    with open('/mnt/hdd/raspiblitz.conf') as f:\n        file_content = f.read()\n    file_content = re.sub(\"sshtunnel=.*\", \"\", file_content)\n    file_content = re.sub(\"\\n\\n\", \"\\n\", file_content)\n    print(file_content)\n    with open(\"/mnt/hdd/raspiblitz.conf\", \"w\") as text_file:\n        text_file.write(file_content)\n    print(\"OK Done\")\n\n#\n# UNKOWN PARAMETER\n#\n\nelse:\n    print (\"unkown parameter - use 'internet.sshtunnel.py -h' for help\")", "path": "home.admin/config.scripts/internet.sshtunnel.py"}], "after_files": [{"content": "#!/usr/bin/python3\n\nimport sys, subprocess, re\nfrom pathlib import Path\n\n# IDEA: At the momemt its just Reverse-SSh Tunnels thats why [INTERNAL-PORT]<[EXTERNAL-PORT]\n# For the future also just local ssh tunnels could be added with [INTERNAL-PORT]-[EXTERNAL-PORT]\n# for the use case when a server wants to use a RaspiBlitz behind a NAT as Lightning backend\n\n# display config script info\nif len(sys.argv) <= 1 or sys.argv[1] == \"-h\" or sys.argv[1] == \"help\":\n    print(\"forward ports from another server to raspiblitz with reverse SSH tunnel\")\n    print(\"internet.sshtunnel.py [on|off|restore] [USER]@[SERVER:PORT] \\\"[INTERNAL-PORT]<[EXTERNAL-PORT]\\\"\")\n    print(\"note that [INTERNAL-PORT]<[EXTERNAL-PORT] can one or multiple forwardings\")\n    sys.exit(1)\n\n#\n# CONSTANTS\n# sudo journalctl -f -u autossh-tunnel\n#\n\nSERVICENAME=\"autossh-tunnel.service\"\nSERVICEFILE=\"/etc/systemd/system/\"+SERVICENAME\nSERVICETEMPLATE=\"\"\"# see config script internet.sshtunnel.py\n[Unit]\nDescription=AutoSSH tunnel service\nAfter=network.target\n\n[Service]\nUser=root\nGroup=root\nEnvironment=\"AUTOSSH_GATETIME=0\"\nExecStart=/usr/bin/autossh -M 0 -N -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ServerAliveCountMax=2 [PLACEHOLDER]\nStandardOutput=journal\n\n[Install]\nWantedBy=multi-user.target\n\"\"\"\n\n# get LND port form lnd.conf\nLNDPORT = subprocess.getoutput(\"sudo cat /mnt/hdd/lnd/lnd.conf | grep '^listen=*' | cut -f2 -d':'\")\nif len(LNDPORT) == 0:\n    LNDPORT=\"9735\"\n\n\n\n#\n# RESTORE = SWITCHING ON with restore flag on\n# on restore other external scripts dont need calling\n#\n\nforwardingLND = False\nrestoringOnUpdate = False\nif sys.argv[1] == \"restore\":\n    print(\"internet.sshtunnel.py -> running with restore flag\")\n    sys.argv[1] = \"on\"\n    restoringOnUpdate = True\n\n#\n# SWITCHING ON\n#\n\nif sys.argv[1] == \"on\":\n\n    # check if already running\n    isRunning = subprocess.getoutput(\"sudo systemctl --no-pager | grep -c '%s'\" % (SERVICENAME))\n    if int(isRunning) > 0:\n      print(\"SSH TUNNEL SERVICE IS RUNNING - run 'internet.sshtunnel.py off' first to set new tunnel\")\n      sys.exit(1)\n\n    # check server address\n    if len(sys.argv) < 3:\n        print(\"[USER]@[SERVER:PORT] missing - use 'internet.sshtunnel.py -h' for help\")\n        sys.exit(1)\n    if sys.argv[2].count(\"@\") != 1:\n        print(\"[USER]@[SERVER:PORT] wrong - use 'internet.sshtunnel.py -h' for help\")\n        sys.exit(1)\n    ssh_server = sys.argv[2]\n    if ssh_server.count(\":\") == 0:\n        ssh_server_host = ssh_server\n        ssh_server_port = \"22\"\n    elif ssh_server.count(\":\") == 1:\n        ssh_server_split = ssh_server.split(\":\")\n        ssh_server_host = ssh_server_split[0]\n        ssh_server_port = ssh_server_split[1]\n    else:\n        print(\"[USER]@[SERVER:PORT] wrong - use 'internet.sshtunnel.py -h' for help\")\n\n    # genenate additional parameter for autossh (forwarding ports)\n    if len(sys.argv) < 4:\n        print(\"[INTERNAL-PORT]<[EXTERNAL-PORT] missing\")\n        sys.exit(1)\n    ssh_ports=\"\"\n    additional_parameters=\"\"\n    i = 3\n    while i < len(sys.argv):\n\n        # check forwarding format\n        if sys.argv[i].count(\"<\") != 1:\n            print(\"[INTERNAL-PORT]<[EXTERNAL-PORT] wrong format '%s'\" % (sys.argv[i]))\n            sys.exit(1)\n\n        # get ports\n        sys.argv[i] = re.sub('\"','', sys.argv[i] )\n        ports = sys.argv[i].split(\"<\")\n        port_internal = ports[0]\n        port_external = ports[1]\n        if port_internal.isdigit() == False:\n            print(\"[INTERNAL-PORT]<[EXTERNAL-PORT] internal not number '%s'\" % (sys.argv[i]))\n            sys.exit(1)\n        if port_external.isdigit() == False:\n            print(\"[INTERNAL-PORT]<[EXTERNAL-PORT] external not number '%s'\" % (sys.argv[i]))\n            sys.exit(1) \n        if port_internal == LNDPORT:\n            print(\"Detected LND Port Forwarding\")\n            forwardingLND = True\n            if port_internal != port_external:\n                print(\"FAIL: When tunneling your local LND port '%s' it needs to be the same on the external server, but is '%s'\" % (LNDPORT, port_external))\n                print(\"Try again by using the same port. If you cant change the external port, change local LND port with: /home/admin/config.scripts/lnd.setport.sh\")\n                sys.exit(1)\n\n        ssh_ports = ssh_ports + \"\\\"%s\\\" \" % (sys.argv[i])\n        additional_parameters= additional_parameters + \"-R %s:localhost:%s \" % (port_external, port_internal)\n        i = i + 1\n\n    # genenate additional parameter for autossh (server)\n    ssh_ports = ssh_ports.strip()\n    additional_parameters = additional_parameters + \"-p \" + ssh_server_port  + \" \" + ssh_server_host\n\n    # generate custom service config\n    service_data = SERVICETEMPLATE.replace(\"[PLACEHOLDER]\", additional_parameters)\n\n    # debug print out service\n    print()\n    print(\"*** New systemd service: %s\" % (SERVICENAME))\n    print(service_data)\n\n    # write service file\n    service_file = open(\"/home/admin/temp.service\", \"w\")\n    service_file.write(service_data)\n    service_file.close()\n    subprocess.call(\"sudo mv /home/admin/temp.service %s\" % (SERVICEFILE), shell=True)\n\n    # check if SSH keys for root user need to be created\n    print()\n    print(\"*** Checking root SSH pub keys\")\n    ssh_pubkey=\"\"\n    try:\n        ssh_pubkey = subprocess.check_output(\"sudo cat /root/.ssh/id_rsa.pub\", shell=True, universal_newlines=True)\n        print(\"OK - root id_rsa.pub file exists\")\n    except subprocess.CalledProcessError as e:\n        print(\"Generating root SSH keys ...\")\n        subprocess.call(\"sudo sh -c 'yes y | sudo -u root ssh-keygen -b 2048 -t rsa -f ~/.ssh/id_rsa  -q -N \\\"\\\"'\", shell=True)\n        ssh_pubkey = subprocess.check_output(\"sudo cat /root/.ssh/id_rsa.pub\", shell=True, universal_newlines=True)\n    \n    # copy SSH keys for backup (for update with new sd card)\n    print(\"making backup copy of SSH keys\")\n    subprocess.call(\"sudo cp -r /root/.ssh /mnt/hdd/ssh/root_backup\", shell=True)\n    print(\"DONE\")\n    \n    # write ssh tunnel data to raspiblitz config (for update with new sd card)\n    print(\"*** Updating RaspiBlitz Config\")\n    with open('/mnt/hdd/raspiblitz.conf') as f:\n        file_content = f.read()\n    if file_content.count(\"sshtunnel=\") == 0:\n        file_content = file_content+\"\\nsshtunnel=''\"\n    file_content = re.sub(\"sshtunnel=.*\", \"sshtunnel='%s %s'\" % (ssh_server, ssh_ports), file_content)\n    if restoringOnUpdate == False:\n        serverdomain=ssh_server.split(\"@\")[1]\n\n        # make sure serverdomain is set as tls alias \n        print(\"Setting server as tls alias\")\n        oldConfigHash=subprocess.getoutput(\"sudo shasum -a 256 /mnt/hdd/lnd/lnd.conf\")\n        subprocess.call(\"sudo sed -i \\\"s/^#tlsextradomain=.*/tlsextradomain=/g\\\" /mnt/hdd/lnd/lnd.conf\", shell=True)\n        subprocess.call(\"sudo sed -i \\\"s/^tlsextradomain=.*/tlsextradomain=%s/g\\\" /mnt/hdd/lnd/lnd.conf\" % (serverdomain), shell=True)\n        newConfigHash=subprocess.getoutput(\"sudo shasum -a 256 /mnt/hdd/lnd/lnd.conf\")\n        if oldConfigHash != newConfigHash:\n            print(\"lnd.conf changed ... generating new TLS cert\")\n            subprocess.call(\"sudo /home/admin/config.scripts/lnd.newtlscert.sh\", shell=True)\n        else:\n            print(\"lnd.conf unchanged... keep TLS cert\")\n\n        if forwardingLND:\n            # setting server explicitly on LND if LND port is forwarded\n            print(\"Setting fixed address for LND with raspiblitz lndAddress\")\n            file_content = re.sub(\"lndAddress=.*\", \"lndAddress='%s'\" % (serverdomain), file_content)\n        else:\n            print(\"No need to set fixed address for LND with raspiblitz lndAddress\")\n    file_content = \"\".join([s for s in file_content.splitlines(True) if s.strip(\"\\r\\n\")]) + \"\\n\"\n    print(file_content)\n    with open(\"/mnt/hdd/raspiblitz.conf\", \"w\") as text_file:\n        text_file.write(file_content)\n    print(\"DONE\")\n\n    # make sure autossh is installed\n    # https://www.everythingcli.org/ssh-tunnelling-for-fun-and-profit-autossh/\n    print()\n    print(\"*** Install autossh\")\n    subprocess.call(\"sudo apt-get install -y autossh\", shell=True)\n    \n    # enable service\n    print()\n    print(\"*** Enabling systemd service: %s\" % (SERVICENAME))\n    subprocess.call(\"sudo systemctl daemon-reload\", shell=True)\n    subprocess.call(\"sudo systemctl enable %s\" % (SERVICENAME), shell=True)\n\n    # final info (can be ignored if run by other script)\n    print()\n    print(\"**************************************\")\n    print(\"*** WIN - SSH TUNNEL SERVICE SETUP ***\")\n    print(\"**************************************\")\n    print(\"See chapter 'How to setup port-forwarding with a SSH tunnel?' in:\")\n    print(\"https://github.com/rootzoll/raspiblitz/blob/master/FAQ.md\")\n    print(\"- Tunnel service needs final reboot to start.\")\n    print(\"- After reboot check logs: sudo journalctl -f -u %s\" % (SERVICENAME))\n    print(\"- Make sure the SSH pub key of this RaspiBlitz is in 'authorized_keys' of %s :\" % (ssh_server))\n    print(ssh_pubkey)\n    print()\n\n#\n# SWITCHING OFF\n#\n\nelif sys.argv[1] == \"off\":\n\n    print(\"*** Disabling systemd service: %s\" % (SERVICENAME))\n    subprocess.call(\"sudo systemctl stop %s\" % (SERVICENAME), shell=True)\n    subprocess.call(\"sudo systemctl disable %s\" % (SERVICENAME), shell=True)\n    subprocess.call(\"sudo systemctl reset-failed\", shell=True)\n    subprocess.call(\"sudo rm %s\" % (SERVICEFILE), shell=True)\n    subprocess.call(\"sudo systemctl daemon-reload\", shell=True)\n    print(\"OK Done\")\n    print()\n\n    print(\"*** Removing LND Address\")\n    subprocess.call(\"sudo /home/admin/config.scripts/lnd.setaddress.sh off\", shell=True)\n    print()\n\n    print(\"*** Removing SSH Tunnel data from RaspiBlitz config\")\n    with open('/mnt/hdd/raspiblitz.conf') as f:\n        file_content = f.read()\n    file_content = re.sub(\"sshtunnel=.*\", \"\", file_content)\n    file_content = re.sub(\"\\n\\n\", \"\\n\", file_content)\n    print(file_content)\n    with open(\"/mnt/hdd/raspiblitz.conf\", \"w\") as text_file:\n        text_file.write(file_content)\n    print(\"OK Done\")\n\n#\n# UNKOWN PARAMETER\n#\n\nelse:\n    print (\"unkown parameter - use 'internet.sshtunnel.py -h' for help\")\n", "path": "home.admin/config.scripts/internet.sshtunnel.py"}]}