Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
/bin/false is not security (semicomplete.com)
140 points by parenthesis on Feb 4, 2012 | hide | past | favorite | 23 comments


If you have a server where only a few people should ever SSH in, use AllowUsers.

If you have a larger number, assign them to a group and AllowGroup.

Simple, fast, and effective.

If you can turn off password auth in favor of keys, do that, too.


If you're using keys for special-purpose accounts, be sure to limit what they can do. You can specify that only a certain command can be run, that port forwarding isn't permitted, etc.

http://www.openbsd.org/cgi-bin/man.cgi?query=sshd&sektio...


Keys get pretty unmanageable at scale. The biggest part of key management is changing keys, which is a really important part of security.

Use Kerberos and a Directory Service if you can, unless you have a solution to SSH key changes.


Keys probably don't have to become unmanageable at scale - you can try use SSH certificate authentication.

Sign your keys with a CA, and encode the "principals" that the user has (so, be able to log into some machines as themself, some machines as some other user), and a validity period. Revocation wasn't there yet when last I looked at it (mid-last-year), but might be there now.

One benefit is that individual connections don't need to be brokered by an external authentication/authorisation service. However, it is a relatively new feature and there may be rough edges (such as making sure all your clients have a recent enough version of the tools to work with certificates - Lion was the first MacOS X version to have it, for example).


Another point to remember: If you use /bin/false and it's dynamically linked (which it probably is), then you MUST make sure that you have PermitUserEnvironment set to "no" -- otherwise people can LD_PRELOAD their way in.


JFTR PermitUserEnvironment is nowadays per default disabled. You should also make sure that AcceptEnv is sane (e.g. just accept LC_* and LANG)

But even if you use a static linked /bin/false you must make sure that you disable PermitUserEnvironment as sh(1) is executed if ~/.ssh/rc exists and sh is typically dynamically linked


It's disabled by default on most systems, but I wouldn't want to assume that Crazy Chimpanzee Linux doesn't do something stupid, or that no sysadmin flips that option on without understanding the consequences.


I ran into similar issues several years ago in setting up "sftp-only" ssh logins to a server. As I recall, the most robust solution involved disabling port forwarding and running the "sftp" ssh daemons in a nearly empty chroot environment.

At the time, I recall finding lots of misleading information on the Internet about restricting ssh, mostly task-oriented "howtos" that overlook the basic principles of operation in order to "get started quickly!"

In my experience, beyond "whitelisting" ssh access in the first place with AllowGroup and related, one should rely more on "deep" kernel-level restriction mechanisms (chroot, BSD jails, sandboxing, etc.) than "shallow" authorization controls ostensibly provided by ssh and/or the login subsystem.


I'm missing something. Why allow people to 'authenticate against [a machine] via ssh' at all if you don't want them to run any program there or use any ssh services on that machine?

(It seems one of the reasons you might want to allow someone an ssh account without a shell would be to give them a proxy with an internal IP address – a feature not a bug. Alternatively, it's possible every user casually ssh-enabled on these machines already had equivalent port-forwarding and shell capabilities on some other 'inside' machines, so this 'insecurity' is trivial.)


For example, you may be hosting a git repository on that machine and wish to allow ssh access, while limiting shell privileges for some developers (contractors vs full-time).


gitosis handles this with a single git account that has the public keys for the developers and the access rules set in the .conf. At that point, a developer doesn't need ssh to the git host. This is the infrastructure I believe kernel.org moved to after they were hacked.


I've seen applications (older, usually IT created, but sometimes "enterprise software") that use the passwd file for their own authentication. Remove the ability for a user to authenticate against the system and they no longer have access to the application.

It wouldn't surprise me if this server was involved with the school's student information system and did just that.


a lot of people think that "locking" someones account is setting their shell to /bin/false or something.


"If command is specified, it is executed on the remote host instead of a login shell." (man 1 ssh)

Isn't this a greater problem than port forwards? Eg you could say ssh example.com sh to get a shell even if your login shell is set to /bin/false?


The command is executed through the shell anyway.

ssh example.com sh would just execute "/bin/false sh", or something like that, on the distant machine.


So it seems. I find the man-page slightly misleading in that regard. Other interesting way to escape /bin/false login shell from ssh man page:

       ~/.ssh/rc
             Commands in this file are executed by ssh when the user logs in,
             just before the user's shell (or command) is started.  See the
             sshd(8) manual page for more information.
If you copy shellcode to that file with scp (which I'd imagine would not try to invoke login shell), you'd get shell to the server.


I just tested it and i didn't get it to work. ~/.ssh/rc is not executed directly but given as an parameter to your shell (/bin/false) which will ignore the parameter.

To be more precise sh -c /bin/false -c '/bin/sh .ssh/rc' is executed where /bin/false is your shell as ssh uses popen(3) to run the command /bin/false -c '/bin/sh .ssh/rc'. I tested several shells which may be used as sh and none seems to read a user configurable file.

If you use a static linked shell and enabled PermitUserEnvironment an attacker can still use LD_* variables to circumvent restrictions as /bin/sh is typically dynamically linked.


Interesting. That ssh is full of scary options.

I don't think it would work directly through scp. From what I can tell from skimming the source, it is really just a wrapper over ssh. Meaning: it forks an ssh, with the commands 'scp -t/-f' on the distant side, and does its magic to connect the pipes where they should go. 'scp -v' gives the exact command, but I don't think it works without previously having a shell.

But, if you have access to the filesystem through other means, you could use the .ssh/rc trick to bypass /bin/false, and get ssh access.


A common mistake back in the day:

/bin/false was set for the shell, BUT

feel free to use XDMCP.


If you don't want people to log on a box in anyway, don't have the account. I don't see what's so strange or complex about that.

/bin/false has never been security. It's just good behavior for users that aren't supposed to get a shell. And that's that, they dont get a shell. They get everything else. Generally, those are daemons !


Include in /etc/pam.d/sshd: account requisite pam_succeed_if.so shell != /sbin/nologin


This DoS would require constant poking since sshd drops all looped connections once fds are exhausted... And can be fixed via small open fd limit put on sshd.


On a different note, false has possibly the best man page of any command.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: