Maybe you've got a local network, maybe with many users, that you trust, and an external connection which is hammering your SSH port (#22) constantly with dictionary/DOS attacks. So you want to turn off that port externally, but keep using that default port number as the default when local users want to connect internally. Or at least I do.
Presumably you've already got SSH up and running, and you have IPtables.
I assume that you want port 22 as the default port for internal users, and 2222 isn't suffering a dictionary/DOS attack.
# /etc/ssh/sshd_config # This listens to port 22 internally, and port 2222 externally (and internally) Port 2222 ListenAddress [myhostname_or_myinternalIPaddress]:22 ListenAddress 0.0.0.0
The problem with this is that it closes 22 to the outside world, but leaves both 22 and 2222 open for the internal network.
Here, we let sshd remain blissfully unaware of the existence of the external network, and then get IPtables to reroute packets from the chosen external port to an internal one.
# /etc/ssh/sshd_config # This listens to port 22 internally and not externally. iptables will permit external rerouting Port 22 ListenAddress [myhostname_or_myinternalIPaddress]
# /etc/rc.local /sbin/iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 2222 -j DNAT --to [myhostname_or_myinternalIPaddress]:22One 'problem' with this method is that it bypasses the normal
/etc/hosts.allowprotections that you might have. I personally like the fact that the external port can be changed on the fly without needing to restart sshd - simply remove the IPtables rule and add a new one with a different port. (This will screw up any SSH sessions currently active, of course.)
/sbin/iptables -t nat -L --line-numbers /sbin/iptables -t nat -D PREROUTING [rule_number_to_delete]
All balls-ups are mine, and all the useful info came from The Debian IRC channel, in particular from dudes (or dudettes) calling themselves 'felixs' and 'petemc'