DB-유

Initial Server Setup on Ubuntu 18.04

· linux, ubuntu, security

I'm moving new servers to 18.04 now, and my old 16.04 checklist has a couple of surprises in it. Netplan replaces /etc/network/interfaces, and systemd-timesyncd handles time out of the box. I got caught by the netplan change on the first one. The rest is familiar: admin user, locked-down SSH, firewall, updates.

Here's what I run on a fresh 18.04 box before installing anything else. You need root over SSH or the console and an SSH key pair on your workstation.

Updates first

apt update
apt upgrade -y
apt install -y vim curl net-tools

If the upgrade installed a new kernel, /var/run/reboot-required will exist; reboot before continuing.

A sudo user

Ubuntu grants sudo through the sudo group. Create the account and add it:

adduser deploy
usermod -aG sudo deploy

adduser (the Debian wrapper, not useradd) prompts for a password and creates the home directory with the skeleton files. Verify in a second session that su - deploy followed by sudo -v works before continuing.

SSH key and sshd

From your workstation:

ssh-copy-id deploy@203.0.113.50

On the server, edit /etc/ssh/sshd_config:

PermitRootLogin no
PasswordAuthentication no
ChallengeResponseAuthentication no

18.04 ships OpenSSH 7.6, which no longer accepts the UsePrivilegeSeparation directive, so if you copy a config from an older server you will see a warning about it. Test and reload:

sshd -t
systemctl reload ssh

Open a new terminal and confirm ssh deploy@203.0.113.50 works with the key before you close the root session.

ufw

ufw allow OpenSSH
ufw enable
ufw status verbose

OpenSSH is an application profile installed by the openssh-server package; it is equivalent to ufw allow 22/tcp.

Hostname, timezone, time sync

hostnamectl set-hostname app01.example.com
timedatectl set-timezone Europe/Berlin
timedatectl

On 18.04 the timedatectl output should show System clock synchronized: yes and systemd-timesyncd.service active: yes. There is no need to install ntp or chrony unless you need to serve time to other hosts.

Netplan

Cloud images configure the interface through a file under /etc/netplan/, usually 50-cloud-init.yaml. If you need a static address, I add a separate file rather than editing the cloud-init one, because cloud-init can regenerate it:

network:
  version: 2
  ethernets:
    ens3:
      dhcp4: false
      addresses: [203.0.113.50/24]
      gateway4: 203.0.113.1
      nameservers:
        addresses: [1.1.1.1, 8.8.8.8]

Save it as /etc/netplan/01-static.yaml and apply:

netplan try
netplan apply

Use netplan try first. It rolls the change back after two minutes unless you confirm, a nice safety net over SSH.

Automatic security updates

The unattended-upgrades package is preinstalled on 18.04 server images. Make sure it is enabled:

dpkg-reconfigure -plow unattended-upgrades
cat /etc/apt/apt.conf.d/20auto-upgrades

The file should contain APT::Periodic::Unattended-Upgrade "1";.

Final check

From the deploy account:

sudo ufw status
sudo sshd -T | grep -iE 'permitrootlogin|passwordauthentication'
timedatectl | grep synchronized
ip -4 addr show

And from the workstation, ssh root@203.0.113.50 should be refused with Permission denied (publickey).

Things that went wrong for me

  • netplan apply leaves the server unreachable. Almost always an indentation error in the YAML or a wrong interface name. Use the console to run netplan --debug apply and check ip link for the real interface name (ens3, enp0s3 and eth0 are all common).
  • Temporary failure resolving 'archive.ubuntu.com' after changing netplan. DNS servers were not set in the new file. 18.04 uses systemd-resolved; systemd-resolve --status shows which servers are active.
  • sudo: unable to resolve host app01.example.com: Resource temporarily unavailable. The new hostname is not in /etc/hosts. Add 127.0.1.1 app01.example.com app01 to it.
  • Password prompt on SSH despite the key being installed. Check /var/log/auth.log for Authentication refused: bad ownership or modes; chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys fixes it.

That's the baseline. Nginx, Docker and everything else goes on top after.