Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have configured my server's sshd to listen on a non-standard port 42.

However, at work I am behind a firewall/proxy, which only allow outgoing connections to ports 21, 22, 80 and 443. Consequently, I cannot ssh to my server from work, which is bad. I do not want to return sshd to port 22.

The idea is this: on my server, locally forward port 22 to port 42 if source IP is matching the external IP of my work's network. For clarity, let us assume that my server's IP is (on eth1), and my work external IP is For all IPs different from, my server should respond with an expected 'connection refused', as it does for a non-listening port.

I'm very new to iptables. I have briefly looked through the long iptables manual and these related / relevant questions:

However, those questions deal with more complicated several-host scenarios, and it is not clear to me which tables and chains I should use for local port-forwarding, and if I should have 2 rules (for "question" and "answer" packets), or only 1 rule for "question" packets.

So far I have only enabled forwarding via sysctl. I will start testing solutions tomorrow, and will appreciate pointers or maybe case-specific examples for implementing my simple scenario.

Is the draft solution below correct?

iptables -A INPUT [-m state] [-i eth1] --source -p tcp
    --destination --dport 22 --state NEW,ESTABLISHED,RELATED
    -j ACCEPT

Should I use the mangle table instead of filter? And/or FORWARD chain instead of INPUT?

share|improve this question
i cannot imagine why you'd want to not run sshd on 22. – djangofan Jun 2 '10 at 22:03
I can imagine why, but there are far more effective ways to secure the system then just changing the port. – Zoredache Jun 2 '10 at 22:33
It's definitely a good idea to not run on 22 when possible. It prevents most basic dictionary-based attacks. I'd suggest using something much higher than 42, like over 1024 or even above 10000 to avoid default nmap port scans to find the open port. However, like Zoredache is saying, this can't be the sole source of security (it's only security through obscurity). – Paul Kroon Jun 3 '10 at 0:11
It's a good idea to change the port if you're trying to avoid clutter in your authlog (all the failed hacking attempts). It's a bad idea if you think you get any level of security from changing the port. – Chris S Jun 3 '10 at 1:30
exactly my point. – djangofan Jun 3 '10 at 15:26
up vote 2 down vote accepted

To forward/redirect things you must edit the NAT table.

A rule like this is probably closest to what you need.

/sbin/iptables --table nat --append PREROUTING --protocol tcp \
               --source --dport 22 \
               --jump REDIRECT --to-ports 42

It would be much easier and probably better to just leave SSH on the standard port and properly secure it. Using an alternate port would only slow down a motivated attacker for a couple seconds. Setup a intrusion prevention system like denyhosts/fail2ban and disable password-based authentication. Or consider rate-limit incoming ssh connections.


share|improve this answer
Thank you, will try that rule tomorrow. As for standard port: I have fail2ban, denyhosts, and rate-limiting, and I cannot yet disable password authentication (there are several users of varying skills). The problem I had with standard port with all the defences was 10-20 fail2ban emails every day on ssh bruteforcing attempts. I got tired of that. Disabling fail2ban email alerts is not a good solution. After switching to non-standard port about a month ago I haven't seen a single bruteforce attempt :) – chronos Jun 2 '10 at 22:54
If anyone wonders why would I have both fail2ban and denyhosts: denyhosts has a nice feature of extending denied periods with more attempts from a specific IP, up to permanent denial (which fail2ban doesn't do), while fail2ban is very flexible and allows protecting a plethora of exposed services (which denyhosts isn't capable of). – chronos Jun 2 '10 at 22:57

I would use Shorewall to manage ip-tables. It sets up a decent base firewall, and doing thing like you want is simple. Add a rule to /etc/shorewall/rules like:

DNAT net: loc: tcp 42 22

Like the others I am not sure why you run sshd on anotther port. If this is an internet port you may want to look at port knocking to keep the port closed unless you hit another port first. Shorewall handles this simplely.

share|improve this answer
Thank you for the suggestion, I'll consider Shorewall if the list of "manual" rules (like this forward) keeps growing. But for a single rule, with all other rules managed by other scripts/software, I do not yet feel the need for Shorewall. Port knocking would be a great solution, which I still have to master. I think that will eventually become my ultimate solution :) – chronos Jun 3 '10 at 12:29

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.