When dealing with Linux user authentication, it's crucial to understand the difference between direct login (SSH) and privilege switching (su). The authentication process follows different pathways:
SSH Login: sshd → PAM → /etc/passwd (shell)
su Command: su binary → PAM → /etc/passwd (shell)
Setting /bin/false as shell completely blocks all access. Instead, use a more nuanced approach:
sudo usermod -s /usr/sbin/nologin username
Then create a custom PAM configuration for su in /etc/pam.d/su:
auth sufficient pam_succeed_if.so user = username
auth required pam_unix.so
For SSH-specific restrictions while allowing local su access:
# In /etc/ssh/sshd_config
DenyUsers username
# OR for more granular control
Match User username
ForceCommand /usr/sbin/nologin
Create a special group for users with this access pattern:
sudo groupadd suonly
sudo usermod -aG suonly username
Then modify sudoers file:
# In /etc/sudoers or /etc/sudoers.d/suonly
%suonly ALL=(ALL) NOPASSWD: /bin/su - username
After implementing any solution, always test:
# Test SSH access (should fail)
ssh username@localhost
# Test su access (should work)
sudo su - username
Remember these important security aspects:
- Always maintain at least one root-access backup account
- Regularly audit user access patterns
- Consider implementing 2FA for privileged access
- Monitor auth logs (/var/log/auth.log or /var/log/secure)
In Linux system administration, there are legitimate scenarios where you need to:
- Prevent direct SSH login for a specific user
- Allow privileged users to switch to this account via
su - username - Maintain the user's ability to run background processes
A common but incorrect approach is setting the shell to /bin/false or /sbin/nologin:
# This doesn't work for our purpose
usermod -s /bin/false username
The problem with this method is that it prevents all interactive sessions, including su switches.
The proper solution involves SSH configuration. Add this to /etc/ssh/sshd_config:
DenyUsers username
# Or alternatively for multiple users:
DenyUsers user1 user2 user3
After modifying the config, restart SSH:
systemctl restart sshd
# Or on older systems:
service ssh restart
Check that:
# This should fail:
ssh username@server
# This should work (from root or sudo user):
su - username
For more granular control, consider these approaches:
# Method 1: Using PAM
# Edit /etc/pam.d/sshd and add:
auth required pam_listfile.so item=user sense=deny file=/etc/ssh/denied_users onerr=succeed
# Method 2: Using AllowUsers (reverse logic)
# In /etc/ssh/sshd_config:
AllowUsers !username root admin
To ensure the account remains functional for other purposes:
# Set a proper shell (not /bin/false)
usermod -s /bin/bash username
# Verify account status
chage -l username
- Regularly audit who has sudo privileges to
suto restricted accounts - Monitor authentication logs:
/var/log/auth.logor/var/log/secure - Combine with other security measures like SSH key authentication