Accessing NAT restricted servers
Have you ever needed secure access to a system while operating outside of its local network?
For quite some time now, I have been using on a powerful server. Unfortunately, I could only connect to it while within its network.
In this guide, I will walk you through how I bypassed this restriction.
Network administrators have their reasons for restricting specific systems. To avoid trouble, please consult them before trying this out.
I will be using the following convention when referring to the 3 systems.
||Your personal computer|
||A proxy server|
||The restricted system|
You will need prior access to
restricted to set up the tunnel.
Once the tunnel is up and running, you can securely connect to
I should advise you to read the steps carefully before executing any of the commands. Do not blindly copy and paste the commands into your terminal. Almost all of them require a slight correction.
In my case, I used an AWS EC2 instance running Ubuntu.
This guide assumes that
proxy is running Linux.
Keep this in mind before setting things up.
Secure access to
Regardless of your choice of a cloud platform, you would have received a key file that enables you to connect to
To use this file, restrict the permissions on it.
chmod 400 <path to 'proxy.pem'>
In this guide, you will need to transfer this key to
restricted. Instead of this, you could create a new key pair and set
proxyto work with it.
Filter incoming connections
Create a security rule allowing inbound
TCPconnections on a non-standard port of your choice,
We will be forwarding traffic on port
Here is an interesting article on how
22became the default port for
Setup up an
SSH config file.
This will alow you to easily connect to a server by simply specifying an alias.
Use the following skeleton template and make the necessary changes to it.
Host restricted HostName <The address for 'restricted' within the network> User hacker Host proxy HostName <The DNS address for 'proxy'> User middle IdentityFile <path to 'proxy.pem'> Host restricted-via-proxy HostName <The DNS address for 'proxy'> User hacker IdentityFile <path to 'proxy.pem'> Port 'port-A'
The configuration is in effect as soon as the file is saved.
This configuration is not necessary for actually setting up the tunnel. It just makes the process very convenient.
I should mention that all the following commands use the aliases set in this template.
Configure the system wide
sudo nano /etc/ssh/sshd_config
#AllowAgentForwarding yes #AllowTcpForwarding yes GatewayPorts yes X11Forwarding yes #X11DisplayOffset 10 #X11UseLocalhost yes #PermitTTY yes
sudo service ssh restart
Once the tunnel is set up, we would be able connect to
restrictedby first connecting to
proxyexplicitly. The above set of steps lets us do this implicitly with just one command, as we will see later.
proxykey file from
As mentioned previously, in order to set up the tunnel, we need the key file for
scp <path to 'proxy.pem'> restricted:~/.ssh/keys
Setup up an SSH Config file
Once again, use the following template and make the necessary changes to it.
Host proxy HostName <The DNS address for 'proxy'> User middle IdentityFile <path to 'proxy.pem'>
Restrict permissions on the key file
chmod 400 <path to 'proxy.pem'>
Create the tunnel
autossh -M 'port-B' -N -f -R 'port-A':localhost:22 proxy
Flag Value Description
Sets a monitoring port
- Without this flag,
autosshopens a shell for
- Set the tunnel to work in the background
Sets reverse tunnel from
restricted is restarted frequently, it might be helpful to automate the creation of the tunnel at the time of boot.
This can be done with a
Create a script
#!/bin/bash # Create the tunnel after some time (3 mins) has passed sleep 180 /usr/lib/autossh/autossh -M 'port-B' -N -f -R 'port-A':localhost:22 proxy
Add the script to your
# Edit this file to introduce tasks to be run by cron. # # Each task to run has to be defined through a single line # indicating with different fields when the task will be run # and what command to run for the task # # To define the time you can provide concrete values for # minute (m), hour (h), day of month (dom), month (mon), # and day of week (dow) or use '*' in these fields (for 'any').# # Notice that tasks will be started based on the cron's system # daemon's notion of time and timezones. # # Output of the crontab jobs (including errors) is sent through # email to the user the crontab file belongs to (unless redirected). # # For example, you can run a backup of all your user accounts # at 5 a.m every week with: # 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/ # # For more information see the manual pages of crontab(5) and cron(8) # # m h dom mon dow command @reboot /absolute/path/to/reverse-ssh-boot.sh
Monitor the running processes
Check for processes on your system that are listening on certain ports.
sudo lsof -i -P -n | grep LISTEN
You should see
sshdprocesses listening on
port-Band allowing traffic from
Test the tunnel
Using the tunnel, connect to
If you followed the instructions carefully, you would have set up an indirect
SSH connection linking
restricted via the reverse
SSH tunnel from
You can now connect to
restricted from outside its local network.