There is a server running sshd to force all its connecting users into using chrooted SFTP. Everything is working fine so far.

I would like to have user root being able to log in using pubkey authentication, but whenever I try to "exclude" user root from being forced into SFTP every other is excluded as well.

Port 22
Protocol 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
UsePrivilegeSeparation yes

KeyRegenerationInterval 3600
ServerKeyBits 1024

SyslogFacility AUTH
LogLevel INFO

LoginGraceTime 120
PermitRootLogin without-password
StrictModes yes

RSAAuthentication yes
PubkeyAuthentication yes

IgnoreRhosts yes
RhostsRSAAuthentication no
HostbasedAuthentication no

PermitEmptyPasswords no

ChallengeResponseAuthentication no

X11Forwarding yes
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes

AcceptEnv LANG LC_*

Subsystem sftp internal-sftp

UsePAM yes

#Match User !root
        ChrootDirectory %h
        ForceCommand internal-sftp
        AllowTcpForwarding no

This configuration is working as expected, but as soon as I enable the Match-rule near end of file everyone is able to log into regular shell via SSH.

Match User !root
        ChrootDirectory %h
        ForceCommand internal-sftp
        AllowTcpForwarding no

Forcing into chrooted SFTP works for all users or for no one. Either I'm misunderstanding what Match is good for - and all three listed rules are part of subset supported in context of Match as well - or it's just failing to handle negated criteria. I even tried to replace root with name of non-root user to no avail: every other user is capable of logging in as soon as the rule is enabled. What is it?

FWIW, I was observing sort of "confusing" log output as well when logging in as non-root user:

Nov 12 22:39:06 host sshd[8687]: Accepted password for nonroot from port 54988 ssh2
Nov 12 22:39:06 host sshd[8687]: pam_unix(sshd:session): session opened for user nonroot by (uid=0)

The confusion is due to using privilege separation and having uid=0 opening a session for nonroot user. However, I assume this is basically intended behaviour for uid=0 is required to create processes on behalf of other users. But is this somehow messing with the test of being root or not!?

1 Answer 1


Well, had a look into the code and must admit, Match doesn't work as expected, but it's possible. According to the code a conditional block started by Match User

  1. must have a positive test to match. (src) (src)
  2. can be negated to limit some additionally provided positive test, only:

    Match User @a,!b

    would cause that any user in group a would satisfy the condition except for user b.

Thus testing !root alone doesn't help:

  1. The test fails for user root as expected.
  2. But due to the lack of any positive test it is failing for any other user as well.

To fix this the negated test must be combined with a positive test basically matching any user first:

Match User *,!root

  • isn't it a due reason to file a bug?
    – poige
    Nov 13, 2019 at 15:38
  • Well, it depends ... I think it's not a bug but intended behaviour, which happens to be documented rather poorly. Apart from that I have a sufficient number of filed open issues for many different applications so I can spare to have another one requiring some discussion. ;) Nov 13, 2019 at 16:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.