/bin/false is a utility program, companion to
/bin/true, which is useful in some abstract sense to ensure that unix is feature-complete. However, emergent purposes for these programs have been found; consider the BASH statement
/some/program || /bin/true, which will always boolean-evaluate to true (
$? = 0) no matter the return of
An emergent use of
/bin/false, as you identified, is as a null shell for users not allowed to log in. The system in this case will behave exactly as though the shell failed to run.
POSIX (though I may be wrong and it may the the SUS) constrains both these commands to do exactly nothing other than return the appropriate boolean value.
/sbin/nologin is a BSD utility which has similar behaviour to
/bin/false (returns boolean false), but prints output as well, as
/bin/false is prohibited from doing. This is supposed to help the user understand what happened, though in practice many terminal emulators will simply close when the shell terminates, rendering the message all but unreadable anyway in some cases.
There is little purpose to listing
/etc/shells. The standard effect of
/etc/shells is to list the programs permissible for use with
chsh when users are changing their own shell (and there is no credible reason to change your own shell to
/sbin/nologin). The superuser can change anyone's shell to anything. However, you may want to list both
/etc/rsh, which will prohibit users with these shells from changing their shell using
chsh in the unfortunate event that they get a shell.
FTP daemons may disallow access to users with a shell not in /etc/shells, or they may use any other logic they wish. Running FTP is to be avoided in any case because
sftp (which provides similar functionality) is similar but secure. Some sites use
/sbin/nologin to disable shell access while allowing sftp access by putting it in
/etc/shells. This may open a backdoor if the user is allowed to create cronjobs.
In either case,
scp will not operate with an invalid shell.
scponly can be used as a shell in this instance.
Additionally, the choice of shell affects the operation of
su - (AKA
su -l). Particularly, the output of
/sbin/nologin will be printed to stdout if it is the shell; this cannot be the case with
/bin/false. In either case commands run with
su -cl will fail.
Finally, the answer:
To disable an account, you should do three things.
- Set the shell to
- Set the password field in
/etc/passwd to the appropriate locked value for your UNIX (
! on Linux, but
*LOCKED* on FreeBSD). This prevents SSH login with keys unless
UsePAM yes is set in the
- Set the account expiration date to the distant past (e.g.,
usermod --expiredate 1). This step will prevent SSH login with any method if PAM is used to process the login.
If it's a service account, it's enough to make sure that it has no SSH authorized keys in its home directory and the first two steps above. If you're worried someone might get an SSH certificate for it or something, you could always list your service accounts and groups in