I'm using a combination of /etc/hosts.deny and ufw on my ubuntu 10.04.04 server. Most days, I see failed ssh attempts from machines in the .com.cn domain, reported like so:
Failed logins from:
112.114.63.139 (139.63.114.112.broad.km.yn.dynamic.163data.com.cn): 1 time
However, in /etc/hosts.deny, I have this rule:
ALL: .com.cn
Shouldn't this be blocking the connection before it even hits ssh? I've tested it via blocking my home machine, and it certainly denies me a connection right away before I get a login prompt (and yes, I've moved my ssh keys away so those aren't involved).
Is this working as intended?
Edit: James Sneeringer prompted me to look more closely at the logs, and perhaps I see why this is happening. From auth.log:
Nov 5 09:38:40 mymachine sshd[22864]: warning: /etc/hosts.deny, line 21: can't verify hostname: getaddrinfo(139.63.114.112.broad.km.yn.dynamic.163data.com.cn, AF_INET) failed
Nov 5 09:38:44 mymachine sshd[22864]: reverse mapping checking getaddrinfo for 139.63.114.112.broad.km.yn.dynamic.163data.com.cn [112.114.63.139] failed - POSSIBLE BREAK-IN ATTEMPT!
Nov 5 09:38:45 mymachine sshd[22864]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=112.114.63.139 user=root
Nov 5 09:38:47 mymachine sshd[22864]: Failed password for root from 112.114.63.139 port 37245 ssh2
Nov 5 09:38:47 mymachine sshd[22866]: Connection closed by 112.114.63.139
This implies to me that if sshd isn't sure about the IP->name lookup, then it errs on the side of caution and does not block that host. Is that right?
This is expected for sshd because it is linked directly to libwrap, so sshd is actually what performs the host check. If you want to block the connection before sshd is invoked, you'll need to place something in front of it to handle the connection attempt before passing it off to sshd. A couple options would be:
Run sshd under inetd (or xinetd). This will allow you to invoke sshd as an argument to tcpd, and tcpd is what ends up performing the actual host check.
Run sshd under xinetd, which has
only_from
andno_access
service options that provide functionality similar to /etc/hosts.allow and /etc/hosts.deny.The sshd manpage discourages these approaches, though:
Using iptables or placing a firewall in front of your server might seem like a good alternative, but most do not perform any name resolution, so you're limited to controlling access by IP address. This isn't necessarily a bad thing, but it doesn't help with what you're trying to accomplish.