When configuring SSH access control, it's crucial to understand how AllowUsers
and AllowGroups
interact. These directives don't override each other but work in conjunction with the following logic:
# User must satisfy BOTH conditions when both directives are present: 1. User must be listed in AllowUsers (if present) 2. User must belong to a group listed in AllowGroups (if present)
The core issue emerges from the unexpected interaction between these directives. Take this example configuration:
AllowUsers user1 user2 AllowGroups ssh-users
Even though testuser
belongs to ssh-users
, access is denied because:
- The user isn't explicitly listed in
AllowUsers
- SSHd requires BOTH conditions to be true by default
Option 1: Use Only AllowGroups
The simplest approach for group-based access control:
# Comment out or remove AllowUsers # AllowUsers user1 user2 AllowGroups ssh-users
Option 2: Match Directive for Conditional Logic
For more complex scenarios, use Match
blocks:
Match Group ssh-users AllowUsers * Match All AllowUsers user1 user2
Option 3: Special Case Handling
When you need to maintain both:
AllowUsers user1 user2 %ssh-users
The %
prefix indicates group membership (Debian/Ubuntu specific syntax)
After making changes, always verify:
# Check config syntax sshd -t # Reload configuration systemctl reload sshd # Test connection ssh -v testuser@server
- Prefer group-based access for scalability
- Document all access rules in configuration comments
- Consider using SSH certificates for large deployments
- Regularly audit active users and group memberships
When configuring SSH server access, many administrators need to implement both user-level and group-level restrictions simultaneously. The core issue arises when trying to make AllowUsers
and AllowGroups
directives work in conjunction rather than conflicting with each other.
The OpenSSH server evaluates access rules in this order:
1. DenyUsers
2. AllowUsers
3. DenyGroups
4. AllowGroups
A user must pass all applicable checks - meaning when both AllowUsers
and AllowGroups
are specified, the user must be listed in AllowUsers
(if the directive exists) and belong to a group in AllowGroups
(if specified).
For the described scenario with user testuser
in group ssh-users
, here's a working configuration:
# /etc/ssh/sshd_config snippet:
AllowUsers user1 user2
AllowGroups ssh-users
# Important: The user must be in BOTH lists:
# 1. Either explicitly in AllowUsers OR not restricted by AllowUsers
# 2. Member of a group in AllowGroups
When troubleshooting, check these critical points:
- Verify group membership with
id <username>
- Confirm the user's primary group isn't interfering
- Check for typos in group names (case-sensitive)
- Ensure PAM isn't overriding SSH rules
For our test case, running:
id testuser
# Should show: uid=1001(testuser) gid=1001(testuser) groups=1001(testuser),1002(ssh-users)
For more flexible management without modifying sshd_config
:
# Option 1: Match blocks
Match Group ssh-users
AllowUsers user1 user2 testuser
# Option 2: LDAP integration
AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys
AuthorizedKeysCommandUser nobody
- Use centralized authentication (LDAP/AD)
- Implement certificate-based authentication
- Combine with
Match Address
for network-based restrictions - Regularly audit access logs (
/var/log/auth.log
)
Remember to always test configurations with a secondary session before logging out of your primary SSH connection.