Creation of SSH tunnels through jump host and obtaining of an access to target host's SSH daemon which have no public IP.
Description of tunnels
- Reverse tunnel – created from Target host (TH) to Jump host (JH). Creating socket on JH which forwards all traffic to some port on TH.
- Straight tunnel – created from Client host (CH) to JH. Creating socket on CH which forwards all traffic to some port on JH.
Hence, having such tunnels allows us to get an access to some port on TH. We can proxy one single port – SSH server port from TH and then establish SSH connection or create SOCKS5 proxy directly with TH.
Creation of tunnel user at JH
In order to make tunnels it is very handy to have special nologin user. Lets name it tunnel. Code creates user without home directory and entry shell. Also we need to restrict authentication method to password only.
sudo adduser -s /bin/false -M -N tunnel sudo usermod -d / tunnel echo 'tunnel:tunnel' | sudo chpasswd cat <<EOF | sudo tee -a /etc/ssh/sshd_config Match User tunnel PasswordAuthentication yes AuthenticationMethods "password" EOF sudo systemctl restart sshd
Lets create reverse tunnel from TH to JH. Code below use utility sshpass which enters SSH password automatically. Can be installed on Ubuntu by default or from EPEL repository on CentOS.
if command -v apt; then sudo apt update sudo apt install -y sshpass elif command -v yum; then sudo yum install -y epel-release sudo yum makecache fast sudo yum install sshpass fi
Lets finally create the tunnel. Execute the following on TH.
sshpass -p 'tunnel' ssh -o StrictHostKeyChecking=no -fNR 2222:localhost:22 [email protected]
sshpass -p 'tunnel' – using of sshpass in order to automate entering of SSH password. This section can be omitted.
ssh -o StrictHostKeyChecking=no -fNR – calling ssh ignoring host key checking – do not do this :) You should create first tunnel manually and print yes confirming host key check at first SSH session. After that moment, you can prepend sshpass utility and all will work. In case if you as lazy, as I, and was not been hacked because of laziness – you're welcome.
2222:localhost:22 – tunnel configuration has format <address on start of tunnel>:<port on start of tunnel>:<adress on the end of tunnel>:<port on the end of tunnel>. Hence, command above does the following: proxy all requests from 127.0.0.1:2222 (default value of address is localhost) of JH to 127.0.0.1:22 on TH. Now we have an access to have SSH server on TH from JH. You can check that executing
ssh -p 2222 localhost from JH.
Notice: the start of the reverse tunnel is on remote server (JH in our case) while the end is on localhost (TH in our case). In case of using of straight tunnel – swapped.
Lets create straight tunnel from CH to JH. Execute the following on CH.
sshpass -p 'tunnel' ssh -o StrictHostKeyChecking=no -fNL 2222:localhost:2222 [email protected]
2222:localhost:2222 – proxy all requests from 127.0.0.1:2222 of CH to 127.0.0.1:2222 on TH. In fact, we forward traffic from CH:2222 to TH:22.
Checking of the tunnel can be done executing
netstat -tunlp on the host where it starts, or simply using it.
If you want to have access to some services on multiple ports from TH network you can use it as SOCKS5 proxy as follows. Execute following command on CH.
ssh -fND 1329 -p 2222 [email protected]
Now, simply navigate to Settings of your browser, type proxy in search bar, open proxy settings and set SOCKS5 proxy to
localhost:1329 and do not forget to tick Proxy DNS over proxy.