|
Literature
Africa |
SSHTunnelAn SSH tunnel can be used for many things but it's great for SSH access to a machine that is not visible for the wider internet. If there is an intermediary server that is accessible, then the target can establish a reverse tunnel to the server. A client can connect to the target, via the server. Tunnel explicit port through a proxyE.g. Unencrypted web traffic uses port 80.
Firstly, an application that uses a forward tunnel is accessing a local-only website from a remote location.
This can be used to access an intranet site, or control a http interface from elsewhere on the internet.
It uses an externally reachable 'gateway' machine on the same network as the web site, e.g. In a shell on your remote machine: ssh -L 1080:proxymachine:80 user@server_behind_firewall and then in a browser (dedicated browser for tunnelling so you don't have to keep changing proxies) you set the proxy to localhost, port 1080, and have no exceptions.
Alternatively, you may be able to browse directly to The Dynamic SOCKS proxyAs above, a port can be opened on your local machine that tunnels to the remote machine.
A dynamic port can be used as a SOCKS proxy for both encrypted and unencrypted TCP access, even on alternate ports.
This is configured with the ssh -D 8080 user@gatewaymachine You can then configure your browser to use this port as a SOCKS5 or SOCKS4 proxy. Some browser extensions can dynamically pick a proxy based on URL.
FoxyPAC is a Firefox addon that can match patterns for proxies.
Proxy Helper is available from the chrome store.
This requires a PAC file which is a javascipt function
function FindProxyForURL (url, host) {
// Match explicit psi FQDNs
if (dnsDomainIs(host, "uj.ac.za") && shExpMatch(host, 'psi-*.uj.ac.za') || (
host == "bhubesi.uj.ac.za"
|| host == "didingwe.uj.ac.za"
|| host == "ukhozi.uj.ac.za"
|| host == "odin.uj.ac.za"
)) {
return 'SOCKS5 localhost:8080';
}
// Match 10.60.6.0/24 IPs
if (isInNet(host, '10.60.6.0', '255.255.255.0')) {
return 'SOCKS5 localhost:8080';
}
// Else don't use proxy
return 'DIRECT';
}
In Proxy Helper, the PAC file can be specified in the extension options and the plugin mode set to `PAC Script": ![]() FoxyPAC can have patterns specified in the extension options and the plugin mode set to "Proxy by patterns": ![]() Reverse SSH tunnelIf you are at a remote location where the network is blocked by a firewall (iThemba, for example) it's impossible for someone at UJ, or anywhere else, to connect to your PC - which is the security that you want from a firewall, in general. But if you, for example, need someone from UJ to run a program on that PC - then it becomes a problem. A way to circumvent this is to use SSH (Secure SHell) to make a "tunnel" from a target machine: ssh -R 11022:localhost:22 myserver In this way port 11022 (or your choice of a random high port, >1024) on myserver (a server where it is possible to SSH in) will be temporarily be connected to port 22 (which is the standard SSH port) of your target PC. So your colleague at UJ can just login on to myserver, and do ssh -p 11022 target_user@localhost and this will actually connect him to your remote PC at iThemba! You can even SSH from another machine to an intermediary server and then on to the target in a single step: ssh -t myserver ssh -p 11022 target_user@localhost HOWTO: Create a permanent ssh back-tunnelThis is for a permanent setup. For a once off case, the recipe above is sufficient. Warning: if this looks complicated, it's because it is complicated! Actually, it's not that complicated, but it takes quite a few steps. Some of these steps could be avoided if OpenSSH on SL4 and SL5 supported the
root@host1# useradd tunnel root@host1# su - tunnel
tunnel@host1$ ssh localhost
tunnel@host1$ ssh-keygen -t dsa
root@host2# useradd tunnel root@host2# su - tunnel tunnel@host2$ ssh localhost tunnel@host2$ ssh-keygen -t dsa
tunnel@host2$ cat .ssh/id-dsa.pub # then copy from one host tunnel@host1$ cat >> .ssh/authorized_keys # and paste on the other (ctrl-D to end) tunnel@host1$ chmod go-w .ssh/authorized_keys tunnel@host1$ cat .ssh/id-dsa.pub # then copy from one host tunnel@host2$ cat >> .ssh/authorized_key # and paste on the other (ctrl-D to end) tunnel@host2$ chmod go-w .ssh/authorized_keys
tunnel@host2$ ssh host1.example.com
Host host2_host1_tunnel
Hostname host1.example.com
User tunnell
Compression no
ForwardX11 no
KeepAlive yes
GSSAPIAuthentication no
RemoteForward 10001 localhost:22
#GatewayPorts yes # uncomment this to make this tunnel available to other hosts
BatchMode yes
#ExitOnForwardFailure yes # not implemented in OpenSSH 4.3
ServerAliveInterval 3
Host host1_tunnel_test
Hostname host1.example.com
User tunnell
Compression no
ForwardX11 no
BatchMode yes
ConnectTimeout 30
tunnel@host2$ ssh host2_host1_tunnel
tunnel@host2$ ssh host1.example.com
Host host2
Hostname localhost
Port 10001
HostKeyAlias host2_tunnel
CheckHostIP no
This makes it easy for a user on host1 to use the tunnel. The
#!/bin/bash
#set -x
#while true; do
T=host2_host1_tunnel
H1test=host1_tunnel_test
H2test=host2
LOG="logger -i -p authpriv.info -t tunnel "
if [ -z "$(pidof sshd)" ]; then
$LOG "Waiting for sshd to come up"
sleep 30
exit 1
fi
SPID=$(ps xa | grep ${T} | grep ssh | cut -b-5)
if [ -z "$SPID" ]; then
#echo "Starting tunnel"
$LOG "Starting tunnel $T"
ssh -f -N ${T}
sleep 30 # give it time to come up
else
if ! ssh $H1test "ssh $H2test -o ConnectTimeout=15 true 2>/dev/null" ; then
$LOG "Killing dead tunnel $T at $SPID"
kill -9 $SPID
sleep 10 # give it time to die
else
# All fine, rest 10 minutes
sleep 600
fi
fi
#done
t1:345:respawn:/usr/local/sbin/host1_tunnel.sh and have init reload it: /sbin/telinit q Notes:
Known bugs:The tunnel can fail for a while if the connection is temporarily dropped, and host1 still keeps the local sshd instance running and the tunnel port open, so that a new tunnel cannot use it, until the TCP socket dies of natural death. For a faster recovery, assuming the connection is up again, try the following: host1$ sudo netstat -l -p --tcp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 localhost.localdomain:10001 *:* LISTEN 4915/sshd: tunnel host1$ sudo kill 4915 Physics gateway machineThere is already a tunnel account on physics.uj.ac.za. Additional machines can tunnel in for remote access to specific services. First up, the machine running the service must be able to SSH to the tunnel account from its root account. Create an ssh key: > sudo -i # ssh-keygen -t ed25519 Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_ed25519 Your public key has been saved in /root/.ssh/id_ed25519.pub ... # cat /root/.ssh/id_ed25519.pub Copy the public key into the authorized_keys file in the tunnel account on the physics.uj.ac.za host: > sudo -i # echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX root@Machine" >> ~tunnel/.ssh/authorized_keys Test that the machine can now log into physics.uj.ac.za: # sudo ssh tunnel@physics.uj.ac.za If root can log in correctly as the tunnel user, the service can now be set up to maintain the tunnel. First install autossh: # sudo apt install autossh A systemd service can then be placed at [Unit] Description=SSH Tunnel from %I port XXX22 Wants=network.target network-online.target After=network.target network-online.target [Service] Environment="AUTOSSH_GATETIME=0" ExecStart=/usr/bin/autossh -M0 -vv -o "ServerAliveInterval 10" -o "ServerAliveCountMax 3" -o "ExitOnForwardFailure yes" -N -R XXX22:localhost:22 tunnel@%i Restart=on-failure UMask=0066 StandardOutput=null Restart=on-failure [Install] WantedBy=multi-user.target Note to replace the XXX in both port numbers with an unused number on the physics.uj.ac.za machine. Also, if you are making a tunnel for a service other than SSH, change the localhost port from 22 to whatever is needed, and adjust the Description to match. Update systemd, then start the new service:
# systemctl daemon-reload
# systemctl start tunnel@physics.uj.ac.za
# systemctl status tunnel@physics.uj.ac.za
tunnel@physics.uj.ac.za.service - SSH Tunnel from physics.uj.ac.za port 11022
Loaded: loaded (/lib/systemd/system/tunnel@.service; disabled; vendor preset: enabled)
Active: active (running) ...
DATE MACHINE autossh[PID]: port set to 0, monitoring disabled
DATE MACHINE autossh[PID]: starting ssh (count 1)
DATE MACHINE autossh[PID]: ssh child pid is PID
If that all looks ok then also enable the service such that it start on system boot:
# systemctl enable tunnel@physics.uj.ac.za
Created symlink /etc/systemd/system/multi-user.target.wants/tunnel@physics.uj.ac.za.service → /lib/systemd/system/tunnel@.service.
# systemctl status tunnel@physics.uj.ac.za
tunnel@physics.uj.ac.za.service - SSH Tunnel from physics.uj.ac.za port 11022
Loaded: loaded (/lib/systemd/system/tunnel@.service; enabled; vendor preset: enabled)
Active: active (running) ...
DATE MACHINE autossh[PID]: port set to 0, monitoring disabled
DATE MACHINE autossh[PID]: starting ssh (count 1)
DATE MACHINE autossh[PID]: ssh child pid is PID
|