| Tested on | RHEL 10.2 (Coughlan) |
|---|---|
| Package | openssh-server 9.9p1-25.el10_2 |
| Applies to | Linux systems with OpenSSH (sshd) |
| Privilege | root or sudo for sshd_config edits and service reload |
| Scope | Match Group with User wildcards and negation; validation with sshd -t and sshd -T -C |
| Related guides | OpenSSH authentication and sshd_config, SSH client config file, systemctl command, SSH command in Linux |
OpenSSH lets you combine Group and User criteria on one Match
line. To apply settings to a group while excluding one member, match
all users with * and then add a negated username with !.
Match Group developers User *,!john
AllowTcpForwarding noA user must belong to developers, * provides the positive user
match, and !john removes that one member from this block. Every
criterion on the Match line must be satisfied before the indented
options apply.
Quick Reference: Exclude Users from Match Group
| Requirement | Match syntax |
|---|---|
| Match one group | Match Group developers |
| Group except one user | Match Group developers User *,!john |
| Group except two users | Match Group developers User *,!john,!alice |
| Match two groups | Match Group developers,admins |
| Match group and one user | Match Group developers User john |
| Validate syntax | sudo sshd -t |
| Show effective configuration | sudo sshd -T -C user=john,host=localhost,addr=127.0.0.1 |
User !john. A negated pattern excludes a match but
does not create the positive match needed for the criterion itself.
1. How Match Group Works in OpenSSH
A Match block applies indented sshd_config options only when its
criteria match. The block continues until another Match line or the
end of the file.
Match Group developers
AllowTcpForwarding noEvery member of developers gets AllowTcpForwarding no. Everyone
else keeps the global default or another applicable Match block.
You can combine criteria on one line. Both must match:
Match Group developers User alice
AllowTcpForwarding noHere the logic is Group = developers and User = alice. Only
alice receives the restriction, and only when she is in
developers.
2. Exclude One User from a Match Group
This is the pattern most administrators need when one group member should skip a group-specific SSH setting.
Match Group admins User *,!foc
Banner /etc/ssh/banner-admins.txtThe three parts work together:
Group admins— the user must belong toadmins.User *— provides a positive match for usernames.!foc— removesfocfrom this block.
Effective logic:
member of admins
AND
any user
AND
not focSo golinux matches when in admins, while foc does not—even if
foc is also in admins.
An excluded user is not blocked from SSH. They simply do not receive
the options inside this Match block. They keep global settings or
another Match block that applies to them.
3. Exclude Multiple Users from a Group
List exclusions after the wildcard:
Match Group admins User *,!foc,!golinux
Banner /etc/ssh/banner-admins.txt* matches users positively. !foc and !golinux remove those
accounts from this block.
Do not write:
Match Group admins User !foc,!golinuxA list with only negated patterns does not satisfy the User
criterion. On OpenSSH 9.9, both foc and golinux then keep the
default Banner instead of the group banner.
Another common case is SFTP-only members with exceptions:
Match Group sftpusers User *,!backup,!automation
ForceCommand internal-sftpbackup and automation stay in sftpusers for filesystem or sudo
policy, but this ForceCommand does not apply to them.
4. Exclude a User Without Removing Them from the Linux Group
Group membership for SSH Match rules comes from the system account,
not from a separate group= parameter in sshd -T.
Confirm membership with id:
id focuid=1011(foc) gid=1012(foc) groups=1012(foc),1011(admins)foc is in admins, yet you can still exclude that account from a
Match block without running:
gpasswd -d foc adminsThat matters when the user still needs the Linux group for filesystem permissions, sudo policy, or application access. Use:
Match Group admins User *,!focThe exception exists only in OpenSSH configuration.
5. Validate sshd_config Before Reloading SSH
After editing /etc/ssh/sshd_config or a drop-in under
/etc/ssh/sshd_config.d/, test syntax before reloading SSH:
sudo sshd -tA valid file produces no output and exits successfully:
Do not reload SSH until sshd -t passes. A syntax error looks like
this:
sudo sshd -t -f /tmp/bad-sshd-test.conf/tmp/bad-sshd-test.conf: line 1: Bad configuration option: BadOption
/tmp/bad-sshd-test.conf: terminating, 1 bad configuration optionsKeep your current administrator SSH session open while testing. Open a second terminal for reload and login checks so a bad change cannot lock you out.
6. Verify Which Match Rules Apply to a User
Repeated SSH logins are slow for troubleshooting. OpenSSH extended test mode shows the effective configuration for a connection context.
On the lab host, the drop-in sets a default banner and a group banner
for admins except foc:
Banner /etc/ssh/banner-default.txt
Match Group admins User *,!foc
Banner /etc/ssh/banner-admins.txtCheck which banner applies to golinux:
sudo sshd -T -C user=golinux,host=localhost,addr=127.0.0.1 | grep -i '^banner 'banner /etc/ssh/banner-admins.txtgolinux is in admins and is not excluded, so the group banner
applies.
Check the excluded user:
sudo sshd -T -C user=foc,host=localhost,addr=127.0.0.1 | grep -i '^banner 'banner /etc/ssh/banner-default.txtfoc keeps the global banner because the Match block does not
apply.
The -C connection specification accepts values such as user,
host, addr, laddr, lport, and rdomain. Group membership is
derived from the supplied user account. There is no group=admins
parameter.
Filter for any option you set inside the block, not only Banner:
sudo sshd -T -C user=golinux,host=localhost,addr=127.0.0.1 | grep -i allowtcpforwarding7. Reload SSH Safely
After sshd -t succeeds, reload the daemon instead of restarting it.
A reload applies the new configuration to new connections without
dropping existing sessions.
On RHEL, Rocky Linux, AlmaLinux, and Fedora:
sudo systemctl reload sshdOn Ubuntu and Debian the service name is usually ssh:
sudo systemctl reload sshKeep your current session open, then test a new login from another terminal:
Test the excluded user first:
ssh foc@localhostThen confirm a non-excluded group member:
ssh golinux@localhostUse these logins to confirm behavior you already predicted with
sshd -T. Prefer reload over restart when a reload is enough.
8. Match Group Exclusion vs AllowUsers, AllowGroups and DenyUsers
Searchers asking how to exclude an SSH user often mean one of two different problems.
Match Group ... User *,!john — John can still log in, but a
particular group-specific SSH setting does not apply to him:
Match Group sftpusers User *,!john
ForceCommand internal-sftpDenyUsers john — John cannot log in through SSH at all.
AllowGroups sshusers — Only members of listed groups may use
SSH.
DenyGroups contractors — Members of the group are denied SSH
access.
Match exclusions shape which options apply. AllowUsers,
DenyUsers, AllowGroups, and DenyGroups control whether login is
permitted.
9. Common Match Mistakes
| Problem | Cause / fix |
|---|---|
User !john does not behave as expected |
Add a positive wildcard: User *,!john |
| Multiple exclusions fail | Use User *,!john,!alice |
| Exception user cannot SSH at all | Check AllowUsers, AllowGroups, DenyUsers, and DenyGroups separately |
Settings after Match affect unexpected users |
A Match block continues until another Match or end of file |
| Configuration reload fails | Run sshd -t and correct syntax first |
Two Match blocks set the same option |
OpenSSH uses the first obtained applicable value |
| Works on one distro but reload command fails | RHEL uses sshd; Debian and Ubuntu commonly use ssh |
| Group rule does not apply | Verify membership with id USER |
Only a subset of sshd_config directives is allowed inside a Match
block. Check the Match section of the manual for your installed
OpenSSH version:
man sshd_configSearch inside the manual for the Match section, or press / and type
Match.
Summary
Exclude one user from a group Match block:
Match Group GROUP User *,!USERExclude several users:
Match Group GROUP User *,!USER1,!USER2Always validate before reload:
sudo sshd -tInspect effective settings:
sudo sshd -T -C user=USER,host=localhost,addr=127.0.0.1Reload SSH, keep your current session open, and confirm with a new login.
References
- sshd_config(5) —
Matchdirective and supported criteria - ssh_config(5) — pattern lists, wildcards, and negation
- sshd(8) —
-Tand-Ceffective configuration testing - RHEL 10 — Configuring OpenSSH — safe SSH access-control changes

