Just spun up a droplet that runs Linux? Here are 7 important things that you should do first before you actually put it to use.

1. Set the timezone

All your servers should be set to the same time zone. Really. Don’t wait for the day when you have to read through two logs with timestamps in different time zones.

And ideally, this should be UTC. Why UTC? Well, for one, it does not have daylight savings rules. Also it’s one less confusion to worry about when your code converts epoch timestamps to calendar time and vice versa.

Here’s how you do it, in Debian 8, Ubuntu 14.10+ and Centos 7:

# timedatectl set-timezone UTC

Want to see all the timezones that are available? Use this:

$ timedatectl list-timezones

2. Set up automatic clock synchronization

Ever had to debug strange authentication failures and finally traced it to a wrong / drifted clock on your system? Yeah that’s right – it wasn’t fun. Set up automatic clock synchronization to never have that happen again!

Debian 8 and Ubuntu 15.10 come with systemd-timesyncd, an NTP client that’s part of the systemd suite (but of course!). To ensure it is enabled, run:

# timedatectl set-ntp true

Centos 7 needs an NTP client (or a full NTP server) to be installed. We recommend the lighter chronyd:

# yum install chronyd
# timedatectl set-ntp true

ProTip: To set the system clock once, based on external time servers, use ntpdate or sntp.

3. Create an alternate user

Don’t use root. Lock it up and throw away the keys. As a first step, create another user just as powerful:

For Debian/Ubuntu:

# useradd -d /home/bofh -G sudo -m -s /bin/bash bofh

For CentOS:

# useradd -d /home/bofh -G wheel -m -s /bin/bash bofh

Don’t use a password for this user – set up password-less SSH login:

# cd /home/bofh
# mkdir .ssh
# cat > .ssh/authorized_keys # paste-in a public key here
# chmod 400 .ssh/authorized_keys
# chmod 700 .ssh
# chown -R bofh:bofh .ssh

Allow bofh user to sudo without a password (because he doesn’t have one!). Debian users may need to “apt-get install sudo” first.

# visudo

Find and edit/uncomment the group to not require a password.

For Debian/Ubuntu:


For CentOS:

%wheel  ALL=(ALL)       NOPASSWD: ALL

That’s it! Now you should be able to ssh in as bofh:

$ ssh -i ~/.ssh/bofh bofh@your.new.server

ProTip: Google bofh.

4. Secure your SSH

Now that you have an alternate root user, improve your SSH security by (1) disallowing root login and (2) disallowing password authentication. Do this by editing /etc/ssh/sshd_config, and editing relevant lines to:

PermitRootLogin no
PasswordAuthentication no

Restart the sshd server for changes to take effect:

$ sudo systemctl restart sshd

ProTip: Your SSH session will survive an sshd restart.

5. Set up the firewall

Security is not optional! Security measures should be enforced at every level possible. Since your server comes with an iptables-based firewall that can provably reduce attack surface area, use it.

However, editing iptables rules are downright masochistic. It’s also easy to leave a gaping big security hole if you get a rule wrong. Unless you’re an iptables expert, stick with a front-end designed for humans – ufw on Debian/Ubuntu and firewall-cmd on CentOS.

Here’s how you can allow only SSH traffic and block everything else. On a Debian/Ubuntu:

$ sudo ufw limit 22/tcp
$ sudo ufw default deny
$ sudo ufw enable # ok to say 'y' at the prompt

(limit is like allow but additionally rate-limits connections.)

On CentOS:

$ sudo systemctl enable firewalld
$ sudo systemctl start firewalld
$ sudo firewall-cmd --list-all # default settings are good
public (default, active)
  interfaces: eth0 eth1
  services: dhcpv6-client ssh
  masquerade: no
  rich rules:

ProTip: Get to know firewalld and ufw.

6. Update packages

Bring all packages and metadata up to date. Reboot afterwards if needed.

On Debian/Ubuntu:

$ sudo apt-get update
$ sudo apt-get upgrade

On CentOS:

$ sudo yum update

While you’re at it, install your favorite packages and essential tools:

screen # or tmux

ProTip: Invest in learning screen or tmux. It pays off well. But don’t be tempted into using it to daemonize processes.

7. Set up a server certificate

These days even internal communication between your VMs must be encrypted. All major databases support connecting to them over SSL, so make use of it (see for eg MySQL, PostgreSQL, MongoDB). Internal websites, or web services with HTTP APIs should use https endpoints.

To facilitate all this, your server needs a certificate. This can be referred to in your database, web server and other configuration files.

The simplest is to create a self-signed certificate. This is good for encryption, but not for much else (like authentication). Nevertheless, if you can’t do the next option, you should at least do this, and use SSL-enabled connections as much as possible. (BTW, the steps to do that are too much to cover here, but are quite easy to Google.)

The other option is the full-blown solution:

  • choose an internal subdomain like “.corp.yourdomain.com”
  • create your own certificate authority that can issue certificates to servers with names like “db1.corp.yourdomain.com”
  • setup a highly-available, secure, DNS server
  • issue a certificate to the new server using the CA
  • register it’s IP(s) with the DNS server
  • add your root (and any intermediate) CA certificates to the trusted store of the new server

Yup, it’s a lot to setup. However, it ensures that your servers can verify each other’s identity, and talk to each other privately.

Bonus Tip: Automate All This!

Use a configuration management system like Chef, Puppet, Saltstack or Ansible to automate these steps. Done properly, you should be able to issue a command (or click a button) to spin up a node on your favorite cloud provider and get all of the above done in one go.