How to allow root login from one IP address with ssh public keys only

Posted on in Categories , , , , , , , last updated June 10, 2017

I am using MacOS on the desktop and Ubuntu Linux on the server. I disabled root login over ssh and enabled ssh based public key login. However, I recently added second Ubuntu server. I need to sync file between two using rsync command. Is there any way that I can log from the second server into my first server with root user from second server IP address only ([email protected] }# ssh [email protected]) without reducing OpenSSH server security option?

Linux/Unix: Allow root login from one IP address only
Yes, you can configure OpenSSH for root login from one IP address or subnet only using Match option. The Match option act as a conditional block. If all of the given conditions are satisfied, OpenSSH can override global section config file. You can limit or grant access to sshd features with the Match option.


The syntax is pretty simple:

Match condition 
  Override config option 1
  Override config option 2

You can use the following as condition:

  1. User – Specifies the user to match. For example, if user is root allow login with ssh-keys but disallow everyone else.
  2. Group – Specifies the group to match. For example, If user in group admin, allow login but disallow everyone else.
  3. Host – Specifies the host to match
  4. LocalAddress – Specifies and match the the local (listen) address and port upon which the incoming connection was received via LocalAddress and LocalPort clauses.
  5. LocalPort – Same as above.
  6. Address – Specifies the IP address or IP/subnet to match in CIDR format.

Where should I put Match configuration option?

You must add config option at the bottom of the config file i.e. /etc/ssh/sshd_config:
$ sudo vi /etc/ssh/sshd_config
$ doas vi /etc/ssh/sshd_config

Example: Allow root login from from with ssh-key but disallow everyone else

Append the following in your /etc/ssh/sshd_config:

## Block root login to every one ##
PermitRootLogin no
## No more password login  ##
PermitEmptyPasswords no
PasswordAuthentication no
## Okay allow root login with public ssh key for ##
Match Address
        PermitRootLogin yes

Verify sshd configuration by passing the -T option:
$ sshd -T
Reload/restart your sshd server, run:
$ sudo /etc/init.d/ssh reload
OR (Debian/Ubuntu Linux)
$ sudo systemctl reload ssh
OR (CentOS/RHEL/Fedora Linux)
$ sudo systemctl reload sshd
OR (OpenBSD)
$ doas /etc/rc.d/sshd restart
OR (FreeBSD)
$ sudo service sshd restart

You can setup multiple IP address/CIDR as follows:

PermitRootLogin no
PermitEmptyPasswords no
PasswordAuthentication no
Match Address,,
        PermitRootLogin yes

How do I setup conditional username along with an IP address?

You can combine User and Address condition as follows so that you can allow password login (a bad idea) including tunnel:

### somewhere already disabled everything ###
PasswordAuthentication no
PermitTunnel no
### but we are allowing user vivek from CIDR ###
Match User vivek Address
    PermitTunnel yes
    PasswordAuthentication yes

Using * and ! pattern

You can use the following patterns:

  1. * – It matches matches zero or more characters.
  2. ? – It matches exactly one character.
  3. ! – Patterns within pattern-lists may be negated with !.

Let us see some common examples of pattern matching

## Match to ##
Match Address 192.168.1.?
   PermitRootLogin yes
## Match 192.168.1.{2,3....}  ##
Match Address 192.168.2.* 
    X11Forwarding no
## Allow any host in the ".home.lan" set of domains ##
Match Host *.home.lan
    X11Forwarding yes
## Allow everyone except foo user ##
Match User *,!foo
      X11Forwarding yes
      PermitTunnel yes
      PermitTTY no

A list of keywords that you can use following a Match condition

From the man page ~ available keywords are

  1. AcceptEnv
  2. AllowAgentForwarding
  3. AllowGroups
  4. AllowStreamLocalForwarding
  5. AllowTcpForwarding
  6. AllowUsers
  7. AuthenticationMethods
  8. AuthorizedKeysCommand
  9. AuthorizedKeysCommandUser
  10. AuthorizedKeysFile
  11. AuthorizedPrincipalsCommand
  12. AuthorizedPrincipalsCommandUser
  13. AuthorizedPrincipalsFile
  14. Banner
  15. ChrootDirectory
  16. DenyGroups
  17. DenyUsers
  18. ForceCommand
  19. GatewayPorts
  20. GSSAPIAuthentication
  21. HostbasedAcceptedKeyTypes
  22. HostbasedAuthentication
  23. HostbasedUsesNameFromPacketOnly
  24. IPQoS
  25. KbdInteractiveAuthentication
  26. KerberosAuthentication
  27. MaxAuthTries
  28. MaxSessions
  29. PasswordAuthentication
  30. PermitEmptyPasswords
  31. PermitOpen
  32. PermitRootLogin
  33. PermitTTY
  34. PermitTunnel
  35. PermitUserRC
  36. PubkeyAcceptedKeyTypes
  37. PubkeyAuthentication
  38. RekeyLimit
  39. RevokedKeys
  40. RhostsRSAAuthentication
  41. RSAAuthentication
  42. StreamLocalBindMask
  43. StreamLocalBindUnlink
  44. TrustedUserCAKeys
  45. X11DisplayOffset
  46. X11Forwarding
  47. X11UseLocalHost

A note about using firewall

You can always use iptables or pf firewall but can not match user names and other information to control access to the default sshd tcp port 22:

## Allow our subnet to access for 22 on this box using ufw ##
sudo ufw allow from to any port 22
## Allow (insert rule) my workstation to access port 22 on this server ##
iptables -I INPUT -s -p tcp -m tcp --dport 22 -j ACCEPT
## Allow port 22 (append rule) ##
iptables -A INPUT -s -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -s -m state --state NEW -p tcp --dport 22 -j ACCEPT

Linux: 20 Iptables Examples For New SysAdmins
How to setup a UFW firewall on Ubuntu 16.04 LTS server


Posted by: Vivek Gite

The author is the creator of nixCraft and a seasoned sysadmin and a trainer for the Linux operating system/Unix shell scripting. He has worked with global clients and in various industries, including IT, education, defense and space research, and the nonprofit sector. Follow him on Twitter, Facebook, Google+.

2 comment

  1. Or you could just SSH -A into your second host to forward your SSH key agent and access your primary server with key as usual.

  2. Also works syntax:

    AllowUsers [email protected]

Comments are closed.