Remote access to a Linux machine behind a firewall

It has less to do with being concerned with a port being open and more to do with not wanting to walk a user though the process of opening up a port. I don't have any access to this router at all unfortunately.

If changing the router is completely out of the question, you may need to look at a P2P or VPN solution like Hamachi. If you setup the system to automatically establish the VPN connection at startup, then you should be able to connect in whenever you need to. Hamachi does all the firewall negotiation for you. The one drawback is you have to rely on the Hamachi servers being up and functional when you need to connect.

If you have a server that is always up, you could setup autossh so that the remote system always keeps a tunnel open and connected to your server. The one drawback is the remote system is compromised they attacker will get the keys that where used to establish the ssh session. It would be very important to keep your system that accept the ssh connection really locked down.


Below is my original answer, I had assumed that updating the router was an option.

One solution you might want to investigate if you firewall supports it, is port knocking. With some firewalls it should be possible to send out a special set of packets that the firewall notices and then temporarily opens hole through the firewall.

There are many implementations some better then others. Some use strong cryptography to make it nearly impossible for a person without the right keys to send the correct knock.


I wouldn't be that worried about leaving port 22 accessible to the internet, but I would take some steps to secure it.

Firstly, disable keyboard interactive authentication and move to ssh keys.

Secondly, install something like fail2ban on your remote server to blackball IP addresses that repeatably probe your machine. Because you have setup ssh keys, there should be no authentication failures for authorized users.

Alternatively if you are able, take WerkkreWs advice and configure the firewall in front of the machine to terminate a vpn connection, then only allow the ssh daemon on the remote server to accept connections coming across that vpn.

Alternatively if your firewall can't terminate the vpn connection, you can probably forward the GRE or IPSEC packets to your linux machine, and terminate it there.


It sounds like you are looking for knockd

You can install that on the linux server itself, with iptables so that it's kind of like a 2nd level firewall. Even with port 22 open on the frontend firewall, it wouldn't be open on the server, so portscans wouldn't see any open ports. Then when you send the "secret knock", all of a sudden you have an open path to port 22.

Does that make sense?


To sum up all answers:

use ssh, but make it more obscure and secure.

For security:

  • Make sure root login is not allowed (PermitRootLogin no).
  • Limit users, which can log in by config option AllowUsers or AllowGroups.
  • Ensure it uses only 2 version ssh protocol (Protocol 2).
  • It is advisable to use only authentication keys, but password is more convenient, when there can be a need to connect to server from holiday where you have no access to authentication keys.

For obscurity:

  • Change ssh port to some random high port you would remember, like 20486. This would get rid of most automatic bruteforcers, but it would not hide it from all port scan on server.
  • Hide ability to connect to port. One way is port knocking mentioned in other answers, but you need special software, which can not be accessible everywhere. Another simple option is to use iptables firewall with recent module to create rule, which would allow to connect only on second or third try. So you know you have to try several times to connect successfully, but simple all port scan would not reveal ssh port. Rules would be similar to those:


iptables -A INPUT -m tcp -p tcp --dport 20486 -m state --state NEW -m recent --set
iptables -A INPUT -m tcp -p tcp --dport 20486 -m state --state NEW  -m recent --rcheck --seconds 60 --hitcount 2 -j ACCEPT
iptables -A INPUT -m tcp -p tcp --dport 20486 -j DROP

Scheduled task the script for your reverse ssh tunnel, or open the firewall port.

If you're worried about SSH being open to the world you could scheduled task when your maintenance period with iptables scripts and only have the port available then.