LowEndBox - Cheap VPS, Hosting and Dedicated Server Deals

Server Security: How to Install Sudo and Configure SSH Server

lowendtutorial

One of the most important aspects of running a server is a good security policy. It is also one of the things that comes last, usually. But if you don’t pay attention to it up front, it’s going to cost you in the long run in case you are breached. This tutorial is one in a series of security-related tutorials (not all will be released sequentially).

When you install a new machine, the default security configuration often isn’t optimal. For example: CentOS gives  you just a root account and Ubuntu doesn’t come with a preconfigured firewall. You often want to secure your server, but most beginners don’t know how to (on the other hand, I’ve seen people with years of experience not understanding the sudo-concept). My goal is to show you how to initially harden your server a bit by configuring the SSH server and my enabling sudo. This can be both done on new installations or on existing machines.

NOTE: I’m using ‘mpkossen’ as an example username here. Please replace it with a username of your choosing.

Securing SSH

The first thing you should always do with a server, it upload your public key (that matches your private key) and enable password-less login. This will prevent people from guessing passwords to enter your server from ever succeeding. Let’s first upload the public key. From a terminal on a Linux or Mac OS machine, run:

ssh-copy-id -i ~/.ssh/id_rsa.pub root@198.51.100.100

It then asks for the password for the root user. Fill that in. Once that’s done, it gives you a notice telling what has happened.

What you do here, is copy a public key (in this case .ssh/id_rsa.pub [indicated by -i], which is often the default name for an SSH key) to your server at 198.51.100.100. It then adds the public key to the .ssh/authorized_keys file on the server for the user you’ve used in the command. From this point on, you only need your SSH key to log in. Be sure to use a strong password for it and don’t leave it lying around, since it is the entrance to your server.

Next, login to the server. We’re going to tweak some SSH server settings to make it more secure. Open up /etc/ssh/sshd_config with an editor (vim, nano, or anything else). First, we’re going to disable password authentication. Look for the following line:

#PasswordAuthentication yes

And change it to:

PasswordAuthentication no

This disables password authentication and forces you to use only public keys. No worries, in case you ever loose your private key you can always access your server via an out-of-band console. In case you have a dedicated server without any out-of-band access, well, don’t loose your private key ;-)

Now look for the following line:

PermitRootLogin yes

And change it to:

PermitRootLogin no

This disables logging in as root. When these things are done, we would usually restart SSH to get these changes live. However, this time, we need to make sure we have a non-root account with sudo access first. If you’ve installed Ubuntu on a KVM machine, this should already be the case and you can safely run the following command. WARNING: if you are currently logged in as root, do not log out, or you’ll have a nice trip to your console ;-)

Again, only as a non-root user with sudo privileges, run:

sudo /etc/init.d/ssh restart

Now, if you’ve run this command, that’s it for you! Otherwise, head over to the next part.

How to Install and Configure Sudo

Sudo… the ground of quite some discussion. To many, sudo is an inconvenience. Rightly so, because inconvenience in security is good. If your security doesn’t annoy you ever, you’re either a very patient human being or your security isn’t good enough.

But why should you use sudo, because inconvenience in itself isn’t an argument. Sudo adds an extra layer of security. When you log in as root, the only thing you need is either your private key or your root password. When you’re in, you’re in and you can do everything you want. Sudo prevents that last part. If you use sudo and somebody manages to get hold of your private key, they can log into the server but still not do much to ruin it, since they haven’t got your password. That alone is, for me, enough reason to use sudo rather than log in as root.

There are additional reasons for using sudo, which are listed here. Not all of them are very strong, though.

So, let’s enable sudo for you. These are instructions for both Ubuntu and CentOS.

Installing Sudo: Ubuntu

Logged in as root, make sure sudo is installed first:

apt-get install sudo

Once that is done, add a new user:

adduser mpkossen

This will ask you for the password twice, make sure you pick a strong one. It then asks some additional questions like you name, room number, etc. Fill these out to your liking. Once done, you need to confirm the information after which your user was created.

Next, add it to the sudo group:

usermod -a -G sudo mpkossen

The above command modifies the user. It adds it to the group(s) mentioned by using -G. The -a is for append. If you wouldn’t use -a, the user would only be in the sudo group, causing all kinds of different problems.

Now the newly created user is all set up, log out and transfer the SSH key for this user (like we’ve done above):

ssh-copy-id -i ~/.ssh/id_rsa.pub mpkossen@198.51.100.100

Finally, log in to the server to disable the root account and clean up. First, disable the root account:

sudo passwd -dl root

What you do here, is delete the root password (-d) and lock the account (-l). From this point on, logging in a root is impossible, even via the CLI.

Finally, remove root’s SSH authorized_keys:

rm -rf /root/.ssh

And you’re done! From now on, commands that require root access should be prefixed with sudo and you will be asked for your password.

Installing Sudo: CentOS

Logged in as root, make sure sudo is installed first:

yum install sudo

Once that is done, add a new user:

adduser mpkossen

And add a password to the user:

passwd mpkossen

This will ask you for the password twice, make sure you pick a strong one.

Next, add sudo right to the user. Run ‘visudo’. It will open a file. Look for the following line:

root            ALL=(ALL)       ALL

Add the following line under it:

root            ALL=(ALL)       ALL
mpkossen        ALL=(ALL)       ALL

Now, save the file and exit. What you just did was ensure that user ‘mpkossen’ can run any command as any user (even as root).

Now the newly created user is all set up, log out and transfer the SSH key for this user (like we’ve done above):

ssh-copy-id -i ~/.ssh/id_rsa.pub mpkossen@198.51.100.100

Finally, log in to the server to lock the root account and clean up. First, disable the root account:

sudo passwd -l root

What you did here is lock (-l) the root account. You could optionally delete (-d) the password first. CentOS doesn’t like combining -d and -l, though.

Remove root’s SSH authorized_keys:

rm -rf /root/.ssh

And you’re done! From now on, commands that require root access should be prefixed with sudo and you will be asked for your password.

Final notes

Now, with the above, you’ve definitely made your server more secure. Other good security practices would add to this one, though. Like keeping a strong password and changing it regularly. The same goes for your SSH key. A good firewall is a must as well, but that is something for a future guide!

For now, get used to a life with sudo! It’s going to get annoying at some moments, but it is more secure.

mpkossen

45 Comments

  1. rm:

    > ssh-copy-id -i ~/.ssh/id_rsa.pub root@198.51.100.100

    It’s enough to just do:

    > ssh-copy-id root@198.51.100.100

    June 29, 2013 @ 12:06 pm | Reply
    • Maarten Kossen:

      Correct. If you’re just using the default private key (with the default name), that is the shortest command to do it.

      I wanted to show how to point to a private key file, though. In case you’re not using the default name or if you have more than one, then you need the -i flag :-)

      June 29, 2013 @ 12:24 pm | Reply
    • Nice! I didn’t know about ssh-copy-id … this makes things a lot easier.

      June 30, 2013 @ 10:38 pm | Reply
      • Maarten Kossen:

        I know! I only found out about it about 4 years ago after having done it manually for ages…

        July 1, 2013 @ 3:22 pm | Reply
  2. RoestVrijStaal:

    In addition to enforce authentication to via SSH, how about to change sshd’s listening port and install an intrusion prevention system like fail2ban or Suricata?

    June 29, 2013 @ 1:07 pm | Reply
    • Maarten Kossen:

      Thank you for your suggestions! Those are topics I wanted to cover in a future guide. If I were to do it all in one article, I’d spend over a week writing it and it’d be quite long ;-)

      June 29, 2013 @ 5:01 pm | Reply
      • Robert:

        I personally use Denyhosts (although just slightly dated) and don’t bother to change listening ports. It seems to have done the job well enough.

        July 14, 2013 @ 6:15 pm | Reply
  3. Gherman:

    Thank you for sharing this with us. Expecting more how-tos in the near future :)

    June 29, 2013 @ 1:10 pm | Reply
  4. Pete S.:

    Public keys are a great way to secure your SSH server, but can often be a hassle. As an alternative, consider something like Google Authenticator (which uses time-based one-time passwords) as a way of strengthening your login credentials. See https://scottlinux.com/2013/06/02/use-google-authenticator-for-two-factor-ssh-authentication-in-linux/ and http://highball.se/2012/08/how-to-install-google-authenticator-under-debian-squeeze/ for examples of how to set it up.

    It’s worth pointing out that although Google developed the Google Authenticator PAM module and code-generating app for iOS and Android, these are merely implementations of the open TOTP standard. No connection to Google is necessary, nor do you need to rely on them for any aspect of the authentication: it’s entirely local. Any TOTP-compatible code generator will work fine.

    For users who are seeking slightly more security (at the cost of a slight extra hassle) and want to avoid bad guys trying to gain access to your server using SSH, you can firewall out SSH from the outside world and only allow it over OpenVPN connections to your server. Using OpenVPN’s tls-auth functionality, the OpenVPN server will silently reject any packets without the correct HMAC signature. Port scans and other attacks by bad guys will not receive any response from the server, so they have no way of knowing if OpenVPN exists or not — only users in possession of the correct keys will be able to get any sort of response from the OpenVPN server. If you use certificate-based logins with OpenVPN, you gain comparable security as using SSH with public keys but with the benefit of hiding the existence of your SSH server from the world. See http://openvpn.net/index.php/open-source/documentation/howto.html#security for details.

    Restricting certain server-management tools like Webmin to only be accessible from a VPN connection (rather than available to the entire internet) helps secure these tools from potential access or compromise by bad guys on the internet.

    June 29, 2013 @ 2:49 pm | Reply
    • Maarten Kossen:

      Thanks for your response and highlighting Google Authenticator! I’ve considered explaining it as an alternative, but I thought it was too off-topic. I may consider it for a future guide, as it’s quite nice.

      Also, great suggestion on the VPN usage!

      June 29, 2013 @ 5:03 pm | Reply
  5. Nice read Maarten. Few points:

    – talk about how tot generate a key pair (ssh-keygen)
    – make sure there is a password on your private key
    – install a key agent so that you only have to type your key password once (ssh-add)

    ssh on another port only keeps standard bots away, it keeps your loges clean. It is not extra secure, an nmap reveals your port right away. fail2ban however works quite well for targetet brute force attacks.

    Confession: I’m lazy, I always use sudo su – or sudo -i to become root…

    Looking forward to the rest of the articles in this series.

    June 29, 2013 @ 2:57 pm | Reply
    • perennate:

      I agree about changing port, it’s super easy to find, and even some automated bots will search for the port these days. An inconvenience not worth the tiny amount of extra security you get.

      June 29, 2013 @ 3:54 pm | Reply
    • Maarten Kossen:

      Thanks, Raymii! I’m sometimes lazy as well! But sudo hasn’t lost its purpose if you sudo su, because you still need the password to do that!

      Generating an SSH-key and using a secure password would indeed have been a good addition to this guide. I may devote a separate one to it and include key agent instructions (or recommend people to use Ubuntu, which does it by default ;-)). It would be a Linux-only guide, though.

      June 29, 2013 @ 5:05 pm | Reply
  6. On paranoid mode, you can add with Authy or Google Authenticator.

    June 29, 2013 @ 3:36 pm | Reply
  7. I don’t know why, if I’m using non-root user I can’t upload file but I can download them.

    June 29, 2013 @ 4:29 pm | Reply
    • Maarten Kossen:

      Upload to and download from where?

      June 29, 2013 @ 5:06 pm | Reply
  8. Fritz:

    What if I do this:
    I log in into my server using normal user (non root), then I issue this command
    “su -”
    After this I can manage my server, do you think this is better?

    Thanks

    June 29, 2013 @ 5:16 pm | Reply
    • RoestVrijStaal:

      “su -” makes the current shell a just login shell, so i wonder which user you use to log into that shell.

      However, I rather like to use su as well, since for sudo you have to enter the root passport ‘almost’ every time again.

      June 29, 2013 @ 9:05 pm | Reply
      • “sudo su -” means you sudo into root. Not sure if it is that much better than logging into root other than that it’s probably logged to some extent. Would be best to perform your actions without root as much as possible, including via “sudo su -“.

        June 30, 2013 @ 5:02 am | Reply
        • Maarten Kossen:

          It’s always better than logging in as root. If you do “sudo su -” you still need the password of the sudo user to get access, which is basically the main reason I use sudo. You SSH private key + password are not enough anymore to gain root access on your server.

          June 30, 2013 @ 5:33 am | Reply
        • Makes sense, but I just hope it’s not an excuse to run everything as “sudo su -“, i.e. still root. If root isn’t required – don’t use it.

          July 2, 2013 @ 7:02 am | Reply
  9. How about port-knocking?

    June 29, 2013 @ 5:40 pm | Reply
  10. Nobody:

    Your ssh server will not allow mpkossen to log in, unless you configure it accordingly. You would need to add something like “AllowUsers mkpossen” to your sshd configuration.

    June 29, 2013 @ 7:14 pm | Reply
    • Maarten Kossen:

      I’ve never had to do that myself. What kind of distribution did you have to do this on?

      June 30, 2013 @ 5:35 am | Reply
  11. Thanks for the great post. :)

    A little corrention:
    “and disable password-less login.”
    I think it should be: “and enable password-less login.”
    or “and disable password login.”

    Am I missing anything?

    June 29, 2013 @ 8:17 pm | Reply
    • Maarten Kossen:

      You’re right. Corrected! Thanks for pointing that out!

      June 30, 2013 @ 5:36 am | Reply
  12. sep:

    I always take similar steps on new systems. In addition, I also change the SSH port and make /tmp non-executable amongst other things.

    June 30, 2013 @ 4:51 am | Reply
    • Locking it down to a gateway server / single ip is always a plus, then securing the gateway server

      June 30, 2013 @ 3:10 pm | Reply
      • This would also be simple if you had several employees that needed access to all the servers. Are there any security implications to using a single server/single ip to access everything? Does that create a single point that attackers could try to exploit?… although how would an attacker know about your single gateway server…

        June 30, 2013 @ 10:59 pm | Reply
      • Maarten Kossen:

        Like BA-Corey says, this isn’t an option for many environments. If I’m on a holiday, I definitely want to be able to access my servers. Also when I’m on the move.

        It’s a very common (and unsolved) problem, though. You want to limit access to yourself (or a number of people) but you don’t want to “lock” yourself out. The only solution that comes to mind at this moment is using a VPN to limit access to your servers. But the downside of that is more latency, single point of failure, etc.

        July 1, 2013 @ 3:25 pm | Reply
  13. thanks Maarten for another informative post

    June 30, 2013 @ 11:24 am | Reply
  14. A summary of what should be added, methinks:
    ssh:
    – selection of alternate SSH port
    – usage of [Allow/Deny][Users/Groups] directives. Personally, I’d strongly recommended using AllowGroups to further restrict access to known users only
    – usage of ‘~/.ssh/config’ file and, say, ‘Host’ sections in it, to create easy to remember aliases
    – modifying public key files, to restrict capabilities, to allow logging in from certain hosts only
    – advanced techniques such as port knocking, to still further restrict access and to prevent port scanning

    sudo:
    – usage of per-group rights instead of per-user rights
    – logging success/failures and alerting sysadm in case of those

    There are otehr topics, of course.

    Thanks for good intro.

    June 30, 2013 @ 11:15 pm | Reply
    • Maarten Kossen:

      Hi Konstantin! Thanks for your suggestions.

      I’ve tried to keep this tutorial as simple and as limited as possible. Just hit some basic (and obvious) security principles. Security is a very broad subject and it deserves much more than one tutorial.

      I’ll make sure to include (some of) your suggestions in any future tutorials. You’ve actually given me a good idea for an additional one ;-)

      July 1, 2013 @ 3:29 pm | Reply
  15. stim:

    Good tips. I do similar. Even knocked-up a script that does it automatically on a clean server:

    – Move ssh port (for good of my logfiles if nothing else).
    – Disable root logins
    – Disable passwords – use keys
    – Install UFW to manage the firewall.
    – Install denyhosts

    July 1, 2013 @ 9:28 am | Reply
  16. Mark:

    Personally i just change the default ssh port in /etc/ssh/sshd_config
    to something like 1993 and add in /etc/rc.local:

    iptables -A INPUT -j ACCEPT -p tcp –dport 1993 -s 151.22.14.10
    iptables -A INPUT -j DROP -p tcp –dport 1993

    then reboot afterwards

    now only one valid ip (151.22.14.10) can log into the server,
    i use this way on all my virtual private servers so they only can log into eachother.

    July 1, 2013 @ 8:48 pm | Reply
  17. tkimball83:

    There is another great service called Dome9 that’ll manage your firewall for you (instead of UFW), and you can generate temporary leases when you’re out of town!

    July 2, 2013 @ 3:39 am | Reply
  18. nico:

    There is no point in using sudo over su. There is no big difference between issuing your password to get root access (sudo) or a specific root password (su). The big difference apperas when your hard drives fail and fsck asks for your root password on boot. You are kind of screwed when fsck does not accept your users password here. You can easily disable root logins in ssh, there is no need to use sudo to “disable” root.

    July 3, 2013 @ 8:06 am | Reply
    • Maarten Kossen:

      Well, there is, actually. When using su, the root account still has a password and everybody who needs root access will need and know that password. With sudo, that isn’t the case, because everybody has his own password. But using su over sudo is more secure than logging in as root :-)

      July 9, 2013 @ 4:37 am | Reply
  19. Garrett:

    I’m relatively new to managing my servers, but I must say… sudo is super annoying. My root password is like 20 chars long and I have fail2ban running… SSH is also on a different port. Would you say I’m at risk?

    The biggest reason I use root is because my text editor, Coda, always gets these annoying “permissions” errors when I SFTP with the non-root account. It got so annoying, I just said screw it, I’ll be root!. And since then, I really enjoy not ever having to type sudo.

    July 3, 2013 @ 1:57 pm | Reply
    • Maarten Kossen:

      I think the file permissions are wrong if Coda keeps giving errors. Or Coda should log in as the user who can edit the files (except root).

      Annoyance is good, because it often means it’s secure. If it’s easy for you, it’s easy for an attacker. I don’t know you or what you do. But people try to break into servers regardless who runs them.

      July 9, 2013 @ 4:40 am | Reply
  20. It has also been my experience that some VPS providers don’t generate new ssh host keys (Chicago VPS comes to mind) when deployed. This means that anybody else on the same VPS image could launch a man-in-the-middle attack because they have access to the same ssh host key.

    Regenerating it is simple:
    ssh-keygen -N “” -t rsa -f /etc/ssh/ssh_host_rsa_key
    ssh-keygen -N “” -t dsa -f /etc/ssh/ssh_host_dsa_key
    ssh-keygen -N “” -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key
    chmod 600 /etc/ssh/ssh_host_*_key

    July 4, 2013 @ 6:43 pm | Reply
    • Oh yeah, restart sshd when you’re done re-generating the keys to put the new keys in to effect.

      On Ubuntu, this is as easy as `sudo restart ssh`

      And you can double check the path to the keys are correct by reviewing /etc/ssh/sshd.conf (or your specific sshd.conf file)

      July 4, 2013 @ 6:49 pm | Reply
      • Maarten Kossen:

        Thanks for pointing this out!

        July 9, 2013 @ 4:40 am | Reply
  21. Hi, thanks for tuts, and its a good practice to change your default 22 port :)

    July 10, 2013 @ 4:49 pm | Reply

Leave a Reply

Some notes on commenting on LowEndBox:

  • Do not use LowEndBox for support issues. Go to your hosting provider and issue a ticket there. Coming here saying "my VPS is down, what do I do?!" will only have your comments removed.
  • Akismet is used for spam detection. Some comments may be held temporarily for manual approval.
  • Use <pre>...</pre> to quote the output from your terminal/console, or consider using a pastebin service.

Your email address will not be published. Required fields are marked *