How to harden your sshd by Joost van Baal february 2006 Introduction ------------ This document explains how to harden the OpenSSH sshd, as commonly found on GNU/Linux and other Unix-like systems. Its intended audience is system administrators who are not afraid to read manpages. Examples will be somewhat Debian-specific, but are likely applicable for other systems too. If you have any suggestions or comments, please email joostvb+ssh-harden@uvt.nl. If your system is connected to the internet, and you're offering a publically accessible sshd, you'll likely have seen stuff like Feb 19 04:18:45 gelfand sshd[6461]: (pam_unix) authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=foo.example.com Feb 19 04:18:47 gelfand sshd[6461]: Failed password for invalid user ident from 10.1.2.3 port 53170 ssh2 Feb 19 04:18:49 gelfand sshd[6463]: Invalid user privoxy from 10.1.2.3 Feb 19 04:18:49 gelfand sshd[6463]: (pam_unix) check pass; user unknown Feb 19 04:18:49 gelfand sshd[6463]: (pam_unix) authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=foo.example.com Feb 19 04:18:50 gelfand sshd[6463]: Failed password for invalid user privoxy from 10.1.2.3 port 53502 ssh2 Feb 19 04:18:52 gelfand sshd[6465]: Invalid user pvm from 10.1.2.3 Feb 19 04:18:52 gelfand sshd[6465]: (pam_unix) check pass; user unknown Feb 19 04:18:52 gelfand sshd[6465]: (pam_unix) authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=foo.example.com Feb 19 04:18:54 gelfand sshd[6465]: Failed password for invalid user pvm from 10.1.2.2 port 53804 ssh2 in your /var/log/auth.log file. This means you've been under attack by a (very likely) automated sshd scanner. It tried to open a shell on your system by doing brute-force password guessing dictionary attacks. Recently, we've seen attacks like this succeed, and leading to GNU/Linux systems being added to DDoS zombie bot networks. Let me tell you this: you don't want such a thing to happen to your system. There are various ways to make sure you won't be the next target. We'll give you some of the ways here. Pick the one (or pick _more_ than one, to be even more secure!) most suitable for your situation. Questions to ask yourself in order to decide: Do you really need an sshd? Who are the legitimate users of your sshd? Are these people on static IPs? Are these people able to handle ssh keypairs? Hardening your sshd ------------------- If you make any of the suggested configuration changes: test the change before trusting it! * Don't run sshd: disable the /etc/init.d/ssh script and/or remove /usr/sbin/sshd. (You probaly want to _keep_ the client: /usr/bin/ssh!) If you're running Debian sarge, do this by invoking "dpkg-reconfigure -plow ssh". * Make sure you're behind a router/firewall which disallows ssh clients connecting to you. * Configure iptables to disallow ssh-access from untrusted IPs. You might want to use a gui wrapper like firestarter, fwbuilder or guarddog, or a bare bones wrapper like shorewall or uruk for setting up the rules. * Configure /etc/hosts.allow to allow ssh only from trusted IPs. See hosts_access(5). * Run sshd on a non-standard port (e.g. "Port 222" in /etc/ssh/sshd_config), and tell your users to use ssh's -p flag. It is preferred to use a port < 1024, so that only root can run the server. * Use a tool which blocks an IP after a set of failed logins from that IP: - fail2ban (adds rule to iptables, shipped with Debian etch in "fail2ban") - daemonshield (adds rule to iptables, http://sourceforge.net/projects/daemonshield/, not yet shipped with Debian) - denyhosts (http://denyhosts.sourceforge.net/, does not work with iptables, but with /etc/hosts.deny, not yet shipped with Debian.) * Allow sshd from an IP only when needed: use knockd (shipped with Debian sarge and later). * Allow ssh access only from specific IPs to specific local useraccounts: add something like "AllowUsers youraccount@1.2.3.* youraccount@dyn-foo.example.com yourfriend@2.3.4.5 anotheraccount" to /etc/ssh/sshd_config. This example would allow access from 1.2.3.0/24 and from the IP with PTR pointing to dyn-foo.example.com to the local user youraccount. It would furthermore allow access from 2.3.4.5 to user yourfriend. Finally, SSH access to anotheraccount is allowed from any IP. All other SSH access is denied. See sshd_config(5). * Disallow password authentication: "PasswordAuthentication no" in sshd_config. This forces people to use keypairs: .ssh/authorized_keys on your host and ~/.ssh/id_rsa[.pub] on their host. You might want to disable passwords alltogether now: the second field in /etc/shadow should be *. * ("PermitRootLogin no" in sshd_config is nice too.) * Force your users to choose good passwords. * Use One Time Passwords, via the PAM opie library. * Offer ssh via IPv6 only. See also -------- "Securing SSH, kind of." by Martin ( http://www.flexion.org/ ) at http://www.flexion.org/site/index.php?gadget=StaticPage&action=Page&id=9 . "Keeping SSH access secure" by Steve Kemp and various contributors at http://www.debian-administration.org/articles/87 . Thanks ------ Wessel Dankers for valuable feedback. Version, availability --------------------- This is version $Id: ssh-harden.txt 9678 2006-02-20 06:40:05Z joostvb $, maintained using SVN at $URL: https://infix.uvt.nl/its-id/trunk/sources/uvt-unix-doc/ssh-harden.txt $. This document is published at http://www.non-gnu.uvt.nl/pub/uvt-unix-doc/ . Copyright --------- Copyright 2006 Tilburg University http://www.uvt.nl/ This document is free; you can redistribute it and/or modify it under the terms of the GNU GPL, see http://www.gnu.org/copyleft/gpl.html . There is NO WARRANTY.