41

I've installed Google-Authenticator on a CentOS 6.5 machine and configured certain users to provide OTP.

While editing /etc/ssh/sshd_config I saw a directive "PermitRootLogin" which is commented out by default.

I would like to set "PermitRootLogin no" but to still be able to ssh to the machine as root only from the local network.

Is that possible?

Itai Ganot
  • 10,424
  • 27
  • 88
  • 143
  • 5
    Don't ever do this. SSH in as your users, then use sudo to elevate permissions. Do this so that it leaves a paper trail, and so you'll know which account was compromised. – SnakeDoc Jul 18 '16 at 16:42
  • 8
    @SnakeDoc: That's one school of thought, but it's not clear-cut and I would argue the opposite. sudo is a huge complex attack surface and not something I would ever want to have installed. SSH pubkey auth is a much smaller attack surface. Either can be logged, but logging is not very useful when the user (root) can edit or delete logs, which is always the case unless you log to external append-only storage. – R.. GitHub STOP HELPING ICE Jul 18 '16 at 17:21
  • 1
    @R.. If you setup sudoers correctly, using principle of least privilege, these issues you described are largely not a problem. No user should be able to ssh in and `sudo - su` into root, or do anything their users doesn't need (in sudoers, you use white-list for commands). If you need root, you must physically be at the console - ie. Root over SSH should never be allowed... keys or not. – SnakeDoc Jul 18 '16 at 17:30
  • 1
    @SnakeDoc: You're mistaken. Sudo has both its own complex attack surfaces, **and** fundamental complex attack surface that's inherent to being a suid binary, in the form of all the state that's inherited across execve. In some cases a bug in the suid program itself (suid) is not even needed; bugs in underlying infrastructure such as the dynamic linker (e.g. CVE-2010-3856) may be sufficient. – R.. GitHub STOP HELPING ICE Jul 18 '16 at 17:40
  • On the other hand, I'm not aware of any history of viable attacks against sshd that would yield root only if PermitRootLogin is enabled. The only justifiable motivation for disabling it is if you support password logins (rather than pubkey only), since passwords are likely vulnerable to brute-force attacks. Also, your "physically be at the console" comment does not make sense in a world where most servers don't even have physical consoles. – R.. GitHub STOP HELPING ICE Jul 18 '16 at 17:44
  • @R.. IPMI is available on most servers, which serves as a physical console - VM's have an equivalent via whatever management software you use. – SnakeDoc Jul 18 '16 at 18:05
  • @R.. What will you do if a key is leaked? All of your systems that allow direct root login with that key are now very vulnerable. If the person must log in as their own user, then elevate - you only have 1 user account to disable until you can rotate keys (and if you only white-listed commands available to those users, it's likely they couldn't cause much damage anyhow). Getting into the habit of direct root login is just plain bad. And frankly, none of these sudo vulns are relevant. The attacker must first be on the system to exploit elevations. – SnakeDoc Jul 18 '16 at 18:06
  • @SnakeDoc: Keys should use passphrases, and if a key is leaked, its access should be revoked. If you want to talk about advanced attacks that wait to steal the passphrase when it's entered (which would be needed to use a leaked private key), the same can be done as attacks against a compromised user account that will be used with sudo: use the key to gain access to their user account and record their sudo password when they enter it, or simply take control of the terminal immediately to enter commands as root. – R.. GitHub STOP HELPING ICE Jul 18 '16 at 19:36
  • 1
    @R.. You assume you will always know if a key is leaked. That's one heck of an assumption. Further, once in, your attacker has root privileges. It is still better to send them through an unprivileged account, and make them have to elevate to root. This way you have a key that must be leaked, a key passphrase to break, and then a regular user account password to break. And if the attacker gets through all that... they can't do anything because this user is setup under sudoers with very limited capability... See the benefit now? Don't allow direct root login over ssh... period. It's good hygiene – SnakeDoc Jul 18 '16 at 20:55
  • @R.. A fitting analogy would be like leaving a loaded gun out in public. You say the gun has a biometric scanner that will only allow the gun to shoot with the owner's fingerprints... so you reason it's safe to leave it loaded and chambered all the time - any passerby can pick it up and try to play with it. Once someone defeats that biometric scanner, they've got a fully working gun. Now, if you had practiced defense in depth, removed the bullets and attached a slide-lock, nobody can shoot the gun even if they get past your first security measure. – SnakeDoc Jul 18 '16 at 21:00
  • Bottom line, you have a single layer of security that you hope never gets penetrated - but if it does, you're screwed because that attacker now has root without any additional effort. – SnakeDoc Jul 18 '16 at 21:12

3 Answers3

62

Use the Match config parameter in /etc/ssh/sshd_config:

# general config
PermitRootLogin no 

# the following overrides the general config when conditions are met. 
Match Address  192.168.0.*
    PermitRootLogin yes

See man sshd_config

Sven
  • 97,248
  • 13
  • 177
  • 225
  • 8
    You can also restrict the source for authentication keys in `~root/.ssh/authorized_keys`. Prefix the key with `from="192.168.0.0/24 "`. – BillThor Jul 17 '16 at 13:20
  • 10
    I would change it to also permit IPv6 link-local addresses. The way link-local addresses work in IPv6 make them very robust to misconfigured networking. Which means if you need to ssh in to fix a network misconfiguration, it is possible that using an IPv6 link-local address is the only option left. – kasperd Jul 17 '16 at 16:24
  • FYI If you additionally use the directive **AllowUser**, you have to additionally (and counter-intuitively) also do `AllowUser root` – Robert Riedl Jun 14 '19 at 09:32
  • What if IPv6 is used? – Alexey Dec 21 '19 at 19:10
15

The Match address method was already mentioned, but you can also restrict the users (or groups) that are allowed to login onto a system. For instance, to limit logins to the user itai (from anywhere) and root (from a specific network), use:

AllowUsers itai root@192.168.0.*

This prevents all other users (like apache) from logging in through SSH.

See also the AllowUsers keyword in the sshd_config(5) manual.

Lekensteyn
  • 6,111
  • 6
  • 37
  • 55
  • 4
    I prefer `AllowGroups` and adding all users that should be able to log in using SSH to a specific group. Guess it's a matter of taste, but that seems like less editing of sshd_config (which translates to less risk of messing up and locking everyone out). – user Jul 18 '16 at 08:44
  • 1
    @MichaelKjörling Also, AllowGroups means that you don't need edit permissions for sshd_config if your team expands or shrinks. This might even allow more managerial types or interns to do it. – Nzall Jul 19 '16 at 12:09
  • Good points, note that you can combine options, have `AllowUsers itai root@192.168.0.*` and `AllowGroups ssh-users` and you will not accidentally cause a lockout in case the intern accidentally clears the group :) – Lekensteyn Jul 19 '16 at 16:38
1

A different strategy could be to leave PermitRootLogin set to no for all addresses, but allow a different user to log in and use sudo. One benefit of doing this is that you can limit what that user with sudo configuration. This is an added layer of protection, in addition to limiting what IP addresses the admin user can log in from.

In /etc/ssh/sshd_config, disable root logins:

PermitRootLogin no

Create a different user called, say, admin. Configure the allowed IP addresses in this user's authorized keys file, /home/admin/.ssh/authorized_keys:

from="192.168.0.0/24,fe80::%eth0/64" <your public key here>

In this example, I also allowed traffic from IPv6 link-local addresses. This is helpful if you use mDNS that may resolve to an IPv6 address or if you need to access the server even when routing is broken. Note that the eth0 part of the address will change based on the interface name on your server. Use ifconfig or ip link to list valid network devices for your server.

xordspar0
  • 11
  • 2