How to Restrict SSH Login While Allowing ‘su – user’ Access in Linux


49 views

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 su to restricted accounts
  • Monitor authentication logs: /var/log/auth.log or /var/log/secure
  • Combine with other security measures like SSH key authentication