It is common knowledge that if on a linux system, a local account is set to /bin/false or /sbin/nologin, that user cannot use SSH, right?
As one of my clients learned the hard way. Alerted to the fact his server was blacklisted on a (large!) number of RBLs, we started investigating how and why spam was getting sent from his server. What we found was that a local user account (listed in /etc/passwd) had been compromised, due to an easy to guess password.
On all the recent Linux distributions I attempted this on, it is possible to connect to the SSH daemon and initiate not a shell, but a TCP port forwarding session. Using /sbin/nologin as a shell only causes the SSH daemon to spawn a shell that closes immediately. So if you tell SSH not to spawn a shell, and use TCP port forwardings instead, you can then exploit the remote host.
Here is how it works.
if I create a user with [/bin/false|/sbin/nologin] as a shell, and give him a password. I can then SSH to the machine and forward a local port.
[user@panel~]ssh -N email@example.com -L 2525:127.0.0.1:25
this forwards my local port of 2525 to the remote port 25. Allowing me to spam via the remote server, via my local TCP 2525 socket I just created:
[user@panel ~] telnet localhost 2525 Trying ::1... Connected to localhost. Escape character is '^]'. 220 linuxserver.cconn.info ESMTP Sendmail 8.14.4/8.14.4; Sun, 6 May 2012 18:06:57 -0400
From “panel” I can connect to “linuxserver” over my ssh tunnel, and spam…my email appears to come from 127.0.0.1 when you look at the headers, causing a certain level of difficulty in tracing the spam back to that account after the fact;
Received: from foo (localhost [127.0.0.1]) by linuxserver.cconn.info (8.14.4/8.14.4) with SMTP id q36MAbio019457 for firstname.lastname@example.org; Sun, 6 May 2012 18:10:48 -0400
Why does this work? Because sshd by default is configured, on my distros anyway, to use PAM for authentication, and has TCP port forwardings enabled by default. If a shell listed in /etc/shells is configured for the account (/sbin/nologin is listed in /etc/shells), the password is valid and TCP port forwarding is enabled, this allows an account to establish said port forwardings and utilize services on the remote host. Spam is an example, but there could be more.
How can this be fixed?
Well, there are a number of ways. The simplest and most drastic, if possible in your scenario, is to simply disable TCP port forwarding in your sshd configuration file (/etc/ssh/sshd_config on many systems):
AllowAgentForwarding no AllowTcpForwarding no X11Forwarding no
However, note that this will not deny the actual ssh connection to be established; it will simply deny the ability to exploit the forwarding (see below);
ssh -N email@example.com -L 2525:127.0.0.1:25 firstname.lastname@example.org's password: channel 2: open failed: administratively prohibited: open failed channel 2: open failed: administratively prohibited: open failed
The SSH session is allowed, however when I try to connect to my local 2525 TCP port, I note a “prohibited” error. Therefore there is still room for exploitation possibly via DoS. As far as I know however it is not possible to spam using this method 😉
Another way appears to be by not have the user shell listed in /etc/shells (/bin/false is not in every distro I checked). Adding users with an invalid shell will invalidate this exact issue since sshd, via PAM, checks if the shell exists. However, this will break any other system daemon that queries PAM for this very information, for example vsftpd/proftpd. Therefore this “solution” is just a broken way of limiting ssh, however could have other, nasty consequences.
The other, smarter ways, would be to use AllowUser/AllowGroup directives in the sshd configuration, to specify exactly which users can and cannot connect. And in all cases, it would be ideal to deny the ability to connect via SSH in iptables/ip6tables since OpenSSH has in the past (and likely will again) had security vulnerabilities that could be exploited to gain root access an pnwn the server :-\ As well, having your ssh socket open to the Internet attracts people to bruteforce scan your server, which is ugly in itself and causes a massive amout of syslog spam.