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:
- Restart SSH service:
sudo systemctl restart sshd
- Test regular user access:
ssh regularuser@server
(should connect to SFTP only) - 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