Vulnerabilities are discovered everyday. The recent Heart bleed attack caught many people off guard. I was wondering if a serious flaw was to be discovered that allows unfettered access to SSH, how should I defend myself and minimize my exposure to such an attack in order to have sufficient time to patch the server?
Setup a port knock daemon which opens the firewall for some time when specific ports are "touched" in some specific order. See for more information Port knocking
OpenSSH provides a very good initial security, because it uses privilege separation and sandboxing. This way the small network listen and authentication part is separated from the rest, that is, it runs as a different non-privileged user and with sandboxing it also can do only limited system calls.
The major problem then is brute-force password probing. The easiest way to limit your attack surface here is to disallow password authentication, i.e. only allow public-key authentication or at least limit password authentication to few users with known hard-to-guess passwords. Because, once the attacker has access as a local user it is often easy to use a privilege escalation exploit to get full system access.
Also, limiting the amount of SSH connection attempts limits the attack surface as does moving to a non-standard port. Examples from my sshd_config:
Port 22 # port 22 gets rate limit with iptables Port 22922 # use an uncommon port where nobody probes for unlimited access AllowUsers user1 user2 trusted_user # limit users which might connect PasswordAuthentication no # no password authentication by default # allow password authentication only for users which care about their password Match User trusted_user PasswordAuthentication yes
And the iptables rules I use to limit connection rate for SSH.
iptables -N SSH_CHECK # limit ssh on default port from same IP to 3/40 sec iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j SSH_CHECK iptables -A SSH_CHECK -m recent --set --name SSH iptables -A SSH_CHECK -m recent --update --seconds 40 --hitcount 3 --name SSH -j DROP
And if you think that these methods combined don't give you enough time to react in case of a major security problem you can set up a multi-staged system. For example you could run the externally visible SSH daemon in some kind of sandbox (chroot, container, virtual or real machine) and make the user log in there. After the first successful login the user then must continue to log into the next stage of your system etc.
I honestly can't believe any of the previous posters have told you the obvious answer.
Both of the above answers are WRONG.... you don't need port knocking, you don't need to change your port, you don't need to set up IP filters.... unless you really want to do "belt and braces".
All you need to do is do what most people are too lazy to do ....
(a) Setup public key authentication and disable all other forms of authentication PasswordAuthentication no ChallengeResponseAuthentication no PermitRootLogin no (b) Keep your system patched and up to date
Really, its that simple. There's no need to go all OTT.