Understanding /sbin/nologin vs /bin/false: Best Practices for Disabling Linux User Accounts


54 views

In Linux system administration, both /sbin/nologin and /bin/false serve as restricted shells designed to prevent interactive login, but they differ in behavior and use cases:


# Compare exit status and behavior
$ /bin/false; echo $?
1
$ /sbin/nologin; echo $?
1

While both return exit status 1, /sbin/nologin displays a customizable message (stored in /etc/nologin.txt) before exiting, whereas /bin/false simply exits silently.

The presence in /etc/shells creates important security distinctions:


# Typical /etc/shells contents
/bin/sh
/bin/bash
/usr/bin/bash
/usr/bin/sh
/sbin/nologin

Services like FTP daemons (vsftpd, proftpd) often check /etc/shells to determine valid login shells. This means:

  • Accounts with /bin/false will be denied by these services
  • Accounts with /sbin/nologin might technically pass the shells check but still fail later

For different scenarios:


# For system accounts that should NEVER log in:
usermod -s /bin/false username

# For service accounts where audit trails are valuable:
usermod -s /sbin/nologin username

The actual binaries differ significantly:


# Sample nologin.c implementation (simplified)
#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *fp = fopen("/etc/nologin.txt", "r");
    if (fp) {
        int c;
        while ((c = getc(fp)) != EOF) putchar(c);
        fclose(fp);
    } else {
        printf("This account is currently not available.\n");
    }
    exit(1);
}

Compare this to /bin/false which is typically a minimal shell that simply exits with status 1.

Customize the nologin message:


# Create custom message
echo "Service account 'backup': Interactive login prohibited" > /etc/nologin.txt

# Verify configuration
getent passwd backup | cut -d: -f7
/sbin/nologin

Different services handle these shells differently:

  • SSH: Blocks both equally
  • FTP: May allow nologin to authenticate before shell rejection
  • Cron: Works with both (shell only affects interactive login)

For comprehensive security, consider combining with other restrictions:


# Additional security measures
usermod -s /sbin/nologin -L -e 1 username

When managing Linux system accounts, the choice between /sbin/nologin and /bin/false affects both user experience and security:

# Sample /etc/passwd entries demonstrating both approaches
postgres:x:114:126:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/false
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

The fundamental differences in implementation:

# /bin/false implementation (simplified)
int main() { return 1; }

# /sbin/nologin implementation (simplified)
int main() {
    printf("This account is currently not available.\n");
    return 1;
}

The /etc/shells listing creates important behavioral differences:

# Example /etc/shells content
/bin/bash
/bin/sh
/usr/bin/zsh
/usr/sbin/nologin  # Notice /bin/false is absent

Services like vsftpd typically check /etc/shells using:

# vsftpd configuration example (relevant portion)
check_shell=YES

Best practices for different scenarios:

# For completely locked accounts (e.g., backup operators)
usermod -s /bin/false backupuser

# For service accounts where audit trails matter
usermod -s /usr/sbin/nologin wwwuser

Customizing nologin behavior (RHEL/CentOS):

# Create custom message file
echo "Access restricted to authorized personnel only" > /etc/nologin.txt
chmod 644 /etc/nologin.txt

# Verify custom message appears when attempting login
su - restricteduser
# Output shows custom message from /etc/nologin.txt

How different services react to these shells:

  • SSH: Both shells prevent login, but nologin provides audit trail
  • Cron: Neither shell affects cron job execution
  • Sudo: Shell setting doesn't impact sudo privileges
# Testing cron behavior (works regardless of shell)
crontab -u restricteduser -e
# Still able to edit crontab even with /bin/false shell