How to Restrict SSH Access to Specific Groups While Allowing SFTP for Others


5 views

When managing Linux servers, there's often a need to differentiate access levels between regular users and administrators. The scenario where you want to:

  • Allow full SSH access for admin groups
  • Restrict regular users to SFTP-only access

This configuration enhances security while maintaining necessary functionality for different user types.

The most effective method involves using OpenSSH's Match Group directive combined with ForceCommand. Here's the recommended configuration for your sshd_config:

# Default restrictions for all users
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp

# Exception for admin group
Match Group admin
    X11Forwarding yes
    AllowTcpForwarding yes
    ForceCommand none

For more granular control, you can implement a custom script solution. Here's an improved version of your approach:

# /etc/ssh/sshd_config
Subsystem sftp internal-sftp

Match Group admin
    AllowTcpForwarding yes
    X11Forwarding yes
    ForceCommand /usr/local/bin/ssh-allowcmd

Match All
    ForceCommand internal-sftp
    ChrootDirectory /home/%u
    PermitTunnel no
    AllowAgentForwarding no
    AllowTcpForwarding no
    X11Forwarding no

Create the allow script at /usr/local/bin/ssh-allowcmd:

#!/bin/bash
if [[ -z "$SSH_ORIGINAL_COMMAND" ]]; then
    exec /bin/bash
else
    exec $SSH_ORIGINAL_COMMAND
fi

After implementing these changes:

  1. Restart SSH service: sudo systemctl restart sshd
  2. Test regular user access: ssh regularuser@server (should connect to SFTP only)
  3. Test admin access: ssh adminuser@server (should provide full shell access)

For enterprise environments, consider these additional measures:

  • Combine with PAM modules for additional authentication requirements
  • Implement logging for all SSH sessions
  • Use certificates instead of passwords for admin access
  • Consider implementing two-factor authentication

If you encounter problems:

# Check SSH configuration syntax
sudo sshd -t

# Verify group membership
id username

# Examine auth logs
tail -f /var/log/auth.log

When managing Linux servers, we often need to restrict regular users to SFTP-only access while allowing administrative users full SSH capabilities. The default SSH configuration doesn't provide a straightforward way to implement this kind of conditional access control.

The OpenSSH server configuration allows conditional blocks using the Match directive. While there's no direct "not equal" operator for groups, we can achieve the desired behavior through careful ordering:

# Global restrictions (applies to everyone)
X11Forwarding no
AllowTcpForwarding no
PermitTTY no
ForceCommand internal-sftp

# Exceptions for admin group
Match Group admin
    X11Forwarding yes
    AllowTcpForwarding yes
    PermitTTY yes
    ForceCommand none

For more granular control, we can use a custom script as mentioned in the question. Here's an improved version of the ssh-allowcmd.sh script:

#!/bin/bash

# Check if we're being called as a forced command
if [[ -n "$SSH_ORIGINAL_COMMAND" ]]; then
    # Execute the original command if provided
    exec /bin/bash -c "$SSH_ORIGINAL_COMMAND"
else
    # Otherwise, start an interactive shell
    exec /bin/bash
fi
  • The ForceCommand internal-sftp directive applies to all users not matched by subsequent rules
  • We explicitly disable common SSH features (X11Forwarding, AllowTcpForwarding) globally
  • The Match Group block overrides these restrictions for admin users
  • For security, the custom script should be placed in a restricted directory (e.g., /usr/local/sbin/) with proper permissions

After modifying /etc/ssh/sshd_config, always test the configuration:

sudo sshd -t && sudo systemctl restart sshd

For more complex scenarios, you can combine this with AuthorizedKeysCommand:

Match Group admin
    AuthorizedKeysCommand /usr/local/bin/check_admin_keys %u
    AuthorizedKeysCommandUser nobody