Wiki source code of SSH tunnel

Version 2.1 by Jan Rhebergen on 2022/12/29 13:56

Show last authors
1 = Intro =
2
3 The remote access to 'Beethoven' is realised by means of (an) ssh tunnel(s). This means the traffic is encrypted and access is limited to personnel who's public keys have been copied to their respective accounts on 'Beethoven' (we'll refer to 'Beethoven' as beethoven from now on)
4
5
6 Below you will find a desciption how this was implemented. Basically it boils down to configuring the restricted host to create an ssh tunnel to a middle man, a.k.a. jump server. This tunnel is persistent en kept alive using the autossh tool. One can subsequently login from home on the jump server and connect through to the restricted host. If so configured, it is also possible to be directly forwarded to the restricted host. In our case the jump server is called dashy (117.204.107.243) and is a JISTARC controlled host that is specifically used for cases where we need full internet access. Users that want to make use of the facility described here naturally need an account on dashy.
7
8
9 **NB:** the numbers in the sections below denote the order in which the steps are to be taken!
10
11
12 == Restricted host ==
13
14 This is the host that we want to reach from the outside (e.g. from home). This host is properly firewalled but is able to ssh to the outside world. In our case this is beethoven.
15
16 {{{#JBR lines like this are comments
17 }}}
18
19
20 **step 1**
21 Execute the following sequence of commands:
22
23 (% class="box" %)
24 {{{apt install openssh-server
25 apt install autossh
26 useradd -s /bin/true -m autotunnel
27 su - autotunnel -s /bin/bash
28 ssh-keygen -t rsa
29 ssh-keygen -t dsa
30 ssh-keygen -t ed25519
31 #JBR first make sure account on dashy exists (see step 2)
32 ssh-copy-id autotunnel@dashy}}}
33
34 This installs the ##autossh## program, adds the ##autotunnel## user which will **not** have a default login shell. To still be able to execute commands as ##autotunnel## we have to specify a shell to execute, i.e. ##/bin/bash##. This enables us to generate the keys and copy them to the middleman server ##dashy##. The ##ssh-copy-id## command copies the most recent ##id_*.pub## file. As of recent the ##ed25519## is considered safest (and quick). **NB:** the ##autotunnel## account password needs to be known (temporarily set) see step 2. **NB:** The last command of step 2 can only be executed when step 2 below has been completed! Also temporarily enable logins using a password  by setting ##PasswordAuthentication yes## in the ##/etc/ssh/sshd_config## file.
35
36 **step 3**
37
38 This step is to test some aspects of the setup:
39
40 First try a regular ##ssh## session:
41
42 (% class="box" %)
43 {{{ssh autotunnel@dashy}}}
44
45 This should work without supplying a password and relies on the public keys we copied in ##step 1##. Exit this after determining that it works. Now start an ##autossh## one:
46
47 (% class="box" %)
48 {{{autossh -M0 autotunnel@dashy -N -R 8082:localhost:22 -vvv}}}
49
50 Due to the ##-vvv## option this will cause a lot of output on screen. Switch over to the Middleman server execute ##step 4## and try to connect.
51
52 == Middle man ==
53
54 This is a server somewhere on the internet that we control. In our case this is ##dashy##.
55
56 **step 2**
57
58 (% class="box" %)
59 {{{useradd -s /bin/bash -m autotunnel
60 #JBR generate a password
61 pw=`date|md5sum|cut -c1-10` && echo $pw
62 #JBR sets the password for the autotunnel user
63 echo -e "$pw\n$pw"| passwd autotunnel}}}
64
65 Next edit the## /etc/ssh/sshd_config## file to include the
66
67 (% class="box" %)
68 {{{GatewayPorts clientspecified
69 }}}
70
71 line. This enables the client to specify an IP address from which connections to the port are allowed (it proved crucial in getting the tunnel to work like I wanted). Next we need to restart the ssh service for this to take effect.
72
73 (% class="box" %)
74 {{{systemctl status sshd.service
75 }}}
76
77 Make sure the firewall allows connection on port 8082 (or whatever port you chose).
78
79 (% class="box" %)
80 {{{ufw allow 8082
81 }}}
82
83
84 **step 4**
85
86 There are two ways to test the connection. First is simple and aimed at finding out if it connects at all (if you have a telnet client installed).
87
88 (% class="box" %)
89 {{{telnet localhost 8082}}}
90
91 This should generate some output on the restricted client due to the ##-vvv## option we supplied. When this indeed is the case just quit and commence with the following actual test.
92
93 (% class="box" %)
94 {{{ssh -p 8082 localhost}}}
95
96 This should log you in on the restricted host. If you need to supply a password it means you did not copy your own public keys or the permission of the ##authorized_keys## file in set incorrectly. These keys are different (personal) public keys that you should have on your home pc/laptop account. Again this should generate respective verbose output on the restricted host. When succesful you can logout on the middle man host and also stop the ##autossh## running on the restricted host.
97
98 == Automation and persistence ==
99
100 In step 1-4 we have demonstrated the sshtunnel. Now we need to have it start automatically and make it persistent. This can be accomplished using appropriate systemd scripts on the //**restricted host**//, as indicated below.
101
102 Put the script below in ##/etc/systemd/system## and name it ##autossh-dashy.service##
103
104 (% class="box" %)
105 {{{[Unit]
106 Description=AutoSSH tunnel service to dashy
107 After=network-online.target
108
109 [Service]
110 Restart=always
111 RuntimeMaxSec=86400
112 Environment="AUTOSSH_GATETIME=0"
113 ExecStart=/bin/su -s /bin/bash autotunnel -c 'autossh -M 0 -q -N -C -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -o "ConnectTimeout 10" -o "ExitOnForwardFailure yes" -R *:8082:localhost:22 autotunnel@117.204.107.243'
114
115 [Install]
116 WantedBy=multi-user.target
117 }}}
118
119 Then activate it and start it by using the following commands:
120
121 (% class="box" %)
122 {{{systemctl enable autossh-dashy.service
123 systemctl start autossh-dashy.service
124 }}}
125
126 We also want to do the same to the web related ##ports 80,443##. Put the script below in ##/etc/systemd/system## and name it ##autossh-dashy-web.service##
127
128 (% class="box" %)
129 {{{[Unit]
130 Description=AutoSSH tunnel for web-service to dashy a.k.a. zij.informeer.de
131 After=network-online.target
132
133 [Service]
134 Restart=always
135 RuntimeMaxSec=86400
136 Environment="AUTOSSH_GATETIME=0"
137 #JBRv this is different than the other autossh-dashy script because it is run as root!
138 #OFF ExecStart=autossh -M 0 -q -N -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -o "ConnectTimeout 10" -o "ExitOnForwardFailure yes" -R :80:localhost:80 -R *:81:localhost:81 -R *:443:localhost:443 root@zij.informeer.de
139 #JBRv the entry for port 81 is only needed once and can be disabled after the admin has secured and configured the access over https
140 ExecStart=autossh -M 0 -q -N -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -o "ConnectTimeout 10" -o "ExitOnForwardFailure yes" -R :80:localhost:80 -R *:443:localhost:443 root@117.204.107.243
141
142 [Install]
143 WantedBy=multi-user.target
144 }}}
145
146 Then activate it and start it by using the following commands:
147
148 (% class="box" %)
149 {{{systemctl enable autossh-dashy-web.service
150 systemctl start autossh-dashy-web.service
151 }}}
152
153 **Important!**
154
155 * For this to work ##ports 80,443## **cannot** be occupied by other processes.
156 * Because these are privileged ports it needs root access! (hence the ##root@zij.informeer.de## entry above)
157 * The root public keys need to be copied to the middle man server (i.e. ##ssh-copyid## or manually into ##/.ssh/authorized_keys##)
158 * The host fingerprint needs to be accepted. This can be achieved by fist executing a manual ##ssh login## from the restricted host to the middle man server and manually accept the fingerprint when prompted.
159 * We initially open ##port 81## because this is the ##admin port## of ##nginxproxymanager##. This can be disabled (commented out) after ##nginxproxymanager## has been set up (webinterface https)
160 * When you (temporariy) edit/change the script you need to restart thedaemon i.e.: ##systemctl daemon-reloa##d
161
162 == Troubleshooting ==
163
164 Usually the SSH tunnel works fine. Problems can potentially occur when disconnecting and reconnecting the hosts ##liszt## and ##beeethoven##. Typically issues consist of:
165
166 * authentication problems (i.e. wrong keys of missing keys)
167 * connection problems (i.e. ports that are occupied or misdirected, unintended fail2ban jails)
168
169 Sometimes problems can simply be solved by restarting the ssh daemon on ##dashy## and the ##autossh## daemon that maintain the ssh tunnel(s) in ##liszt## and ##beethoven##.
170
171 (% class="box" %)
172 {{{#JBR on beethoven and liszt
173 systemctl restart autossh-dashy.service
174 systemctl restart autossh-dashy-web.service
175 }}}
176
177 (% class="box" %)
178 {{{#JBR on dashy
179 systemctl restart sshd.service
180 }}}
181
182 When using ##ssh## and entering a wrong password multiple times in quick succession ##fail2ban## (temporarily) blacklists the originating host IP. This so called jailing can be undone if you can login by another means (i.e. from a different host). Alternately one can permanently **whitelist** a specific trusted host to prevent an unintended lock-out situation. **NB:** ##fail2ban## naturally runs on ##dashy## the middleman server.
183
184
185