What is the better option: Using su to switch to root or enabeling sudo? Without the use of sudo an intruder would need to know the password (or key) of a user allowed to ssh and then also the root password. With sudo the password of the unprivileged user would be enough.

I set up a fresh webserver (Debian 8.2) and am wondering what the best practice is to make connecting to it via SSH secure and still easy for me to work with it.

So far I have disabled PermitRootLogin on SSH and switched the port. Also iptables is in place blocking everything that I don't need. Now I have to login with an unprivileged user and then switch with

su root

But working as root isn't the best thing to do I've heard... So I thought about just granting my unprivileged user sudo rights.

Then again an intruder would only need to know one password since sudo is asking for the current users password and not for the root password. So my plan to make it harder for an attacker by disabeling PermitRootLogin in SSH isn't working anymore.

So: su root or sudo?


So far I have disabled PermitRootLogin on SSH and switched the port.

I'm not a big fan of running services on non-standard ports; you make interopability harder for yourself and others, for no real gain. With a decent password (or better: key), random SSH scans have no chance of succeeding anyway, and targeted attacks are not phased by a different port.

But working as root isn't the best thing to do I've heard... So I thought about just granting my unprivileged user sudo rights.

This is a personal preference; there are valid reasons for choosing either approach.

Personally, I prefer to avoid sudo, mainly because it's a lot more complex than su. And this complexity carries a higher security risk, both in sudo's configuration, and sudo itself (there have been several security advisories). sudo can be very useful in allowing an unprivileged user to execute very specific commands without password, though.

That said, switching to root and using sudo in the way you describe is pretty much interchangable, except for a few things:

  • Sudo can log each command executed through it. When using su, you have to rely on root's shell history for logging. (An attacker can trivially circumvent this though, e.g. by simply doing sudo su)

  • With sudo, you typically need your user's password, with su you need root's.

  • With sudo it's easier to interleave privileged and non-privileged commands.

    However, I usually find myself either doing administrative tasks for which I need a lot of root, or something non-administrative for which I don't need root. And to avoid confusion, I color my shell prompts to distinguish between root (red) and user (blue).

  • By default, sudo is limited to certain accounts.

    For su, a similar thing can be achieved by using pam_wheel.so to limit su-to-root to members of a certain group. (addgroup --system wheel, adduser YOU wheel, uncomment the pam_wheel line in /etc/pam.d/su)

Should I disable SSH Authentication via password and just use keys? Then it would be difficult for me to access the server if I'm not on my own laptop.

Yes, that's probably one of the biggest security gains.

You can grant access for the SSH keys of your accounts on multiple (trusted) machines.

If the machines aren't trusted, you should consider not logging in from them anyway; they could inject commands or have a keylogger sniffing your passwords.

Some additional tips:

  • Consider limiting SSH access to user accounts that need SSH access.

    I like to do this by addgroup --system allowssh, and then in /etc/ssh/sshd_config setting PubkeyAuthentication no, and adding a Match Group allowssh\n PubkeyAuthentication yes stanza.

    I'm sure this could be done through PAM as well, using something like auth required pam_succeed_if.so quiet_success user ingroup allowssh in /etc/pam.d/sshd.

  • Consider installing a logchecker that reports anomalies. To cut down on the volume of mails, you could consider having successful login attempts mailed, rather than unsuccessful ones.

  • Great answer, thanks! This together with fail2ban and maybe PAM's Google Authenticator plugin makes things already pretty safe in my opinion. I already limited SSH access to users that need it. I think I also prefer using su over sudo since I know that I have to be careful while being root and I manage the machine alone, so no worries about managing root passwords. In my opinion it creates another layer of security (You first have to break in with SSH using an unprivileged user with a password protected key and limited tries and then have to guess the root password) – Øle Bjarnstroem Jun 9 '15 at 18:13

My thoughts:

  • Set PasswordAuthentication and PermitRootLogin to no
  • Optionally, passphrase your SSH keys (though there's no way to enforce this)
  • Use MFA as Tim's answer suggests to further restrict SSH access (personally, I'd do this via PAM's Google Authenticator plugin)
  • Do not enable passwordless sudo, and ensure strong passwords are set for your users.
  • Changing the port for SSH is not really necessary, any dedicated port-scanner will end up finding your open port.
  • Use Fail2Ban to guard against brute-force SSH attacks
  • Disable port forwarding by setting AllowTcpForwarding no
  • Regarding iptables, use a "default deny" rule to systematically drop anything that isn't on your whitelist of ports.
  • If you're super-paranoid, use iptables to restrict SSH access to a known-good IP address (note that this is not a good idea if you're accessing from home or from an IP address that could change).
  • Thanks. I now did most of that. Google Authenticator is quite sweet! I think I misunderstood the purpose of sudo. It is not so much to prevent an intruder from doing anything damaging as to prevent me from messing something up by accident. And to make managing of passwords and user rights easier in larger oranisations (no need to pass root passwords around) – Øle Bjarnstroem Jun 9 '15 at 14:23
  • I would not recommend disabling port forwarding. Any attack a logged in user could perform on your network through port forwarding could be performed using standard shell commands. So you'd be breaking an extremely useful feature of ssh for no security benefit. If you are using authorized_keys to limit some public key to only execute a specific command, then sure it makes sense to disable port forwarding on that one line of authorized_keys. – kasperd Jun 9 '15 at 16:10
  • Using the Google Authenticator plugin, can I still use WinSCP with my key? Will it prompt for the verification code? – Canadian Luke Jun 9 '15 at 17:54
  • I had to enable AlowTcpForwarding again and agree with kasperd. Otherwise you for example aren't able to connect to your MySQL server via a secure SSH connection, which is extremely handy when managing databases. – Øle Bjarnstroem Jun 9 '15 at 18:07

What we do (ops company) is disable password logins and only allow keys. Use a cryptostick (new name, NitroKey) or just a smartcard, but that means you'll also need a reader along. This way you have two-factor authentication, something you have (the stick or card) and something you know (the password for sudo).

Do not ever switch to root unless you really really need to, consider it bad practise and always take the time to consider if you really need to switch.

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