Ubuntu Linux Cloud Install

After deploying a new Ubuntu Linux server on Digital Ocean or Linode, there are a few customization steps I take to improve usability and security of the server. These instructions are assuming you’ve install Ubuntu Linux 18.04 LTS.


Install Strong Entropy

apt update
apt -y install haveged pollinate


Schedule re-seeding random number generator at boot

(crontab -l ; echo "@reboot sleep 60 ; /usr/bin/pollinate -r" )| crontab -


SSH Server Hardening

Backup SSH Server Config files

cp /etc/ssh/sshd_config /etc/ssh/backup.sshd_config
cp /etc/ssh/moduli /etc/ssh/backup.moduli


Security Changes to sshd_conf

sed -i '/X11Forwarding/c\X11Forwarding no' /etc/ssh/sshd_config
sed -i 's/^#HostKey \/etc\/ssh\/ssh_host_\(rsa\|ed25519\)_key$/\HostKey \/etc\/ssh\/ssh_host_\1_key/g' /etc/ssh/sshd_config
sed -i 's/^HostKey \/etc\/ssh\/ssh_host_\(dsa\|ecdsa\)_key$/\#HostKey \/etc\/ssh\/ssh_host_\1_key/g' /etc/ssh/sshd_config
echo -e "\n# Restrict key exchange, cipher, and MAC algorithms\nKexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256\nCiphers aes128-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr\nMACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256,hmac-sha2-512" >> /etc/ssh/sshd_config


Remove small Diffie-Hellman moduli

awk '$5 >= 3071' /etc/ssh/moduli > /etc/ssh/moduli.safe
mv /etc/ssh/moduli.safe /etc/ssh/moduli


Regenerate SSH Server Keys

rm /etc/ssh/ssh_host_*
ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ""
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""


Restart OpenSSH server

service ssh restart


Generate New Root SSH Keys

ssh-keygen -t rsa -b 4096 ; ssh-keygen -t ed25519


Replace Authorized SSH Public Keys

The keys you just created will be used as an emergency fail-safe in case you lose your password and/or your own ssh keys and cannot access the system. To make sure no other unknown keys are authorized to login as root, we will create a new authorized_keys file and add our fail-safe keys to it.

cd /root/.ssh
cp id_rsa.pub authorized_keys
cat id_ed25519.pub >> authorized_keys

Download the private key files and store someplace safe (offline). DO NOT DELETE THEM FROM THE SERVER.

  • /root/.ssh/id_rsa
  • /root/.ssh/id_ed25519

Edit the authorized_keys file and paste your own keys to the bottom of the file

vi /root/.ssh/authorized_keys


Swap File

If a swap partition was not created by the deployment, create one based on the amount of RAM installed.

Installed RAM (GB)Swap File (GB)
2 or less1
3 – 62
7 – 123
13 – 204

Create swap file (example for 1GB swap file)

fallocate -l 1G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab


Create Linux Update Scripts

cat > /usr/local/bin/linux-update << EOF
apt-get -y autoremove --purge
sync
apt-get clean
apt-get autoclean
apt update
apt -y full-upgrade
sync
update-grub
echo "Press Enter to reboot or Ctrl-C to abort..."
read aa
sync
reboot
EOF
cat > /usr/local/bin/linux-cleanup << EOF
apt-get -y autoremove --purge
sync
update-grub
EOF
chmod +rx /usr/local/bin/linux-update /usr/local/bin/linux-cleanup


Install Updates and reboot when prompted

linux-update


Install Various Useful Packages

apt -y install apport apt-transport-https aptitude at build-essential byobu command-not-found curl dnsutils ethtool git htop man patch psmisc screen software-properties-common sosreport update-motd update-notifier update-notifier-common vim zip unzip


Set Hostname

hostnamectl set-hostname domain.tld


Rebuild Hosts File

cat > /etc/hosts <<EOF
127.0.0.1  localhost
`hostname -i`  `hostname -f`  `hostname -s`
EOF
cat /etc/hosts


Check the output at the end of the command to make sure the hosts file looks similar to this

127.0.0.1 localhost
192.168.1.100 domain.tld domain


Harden IPv4 Network

cat > /etc/sysctl.conf <<EOF
# IP Spoofing protection
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Ignore ICMP broadcast requests
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Disable source packet routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# Ignore send redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# Block SYN attacks
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 5
# Log Martians
net.ipv4.conf.all.log_martians = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
# Ignore ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0 
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
EOF


If you are not using IPv6, disable it

cat >> /etc/sysctl.conf <<EOF
# Disable IPv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
EOF


Restrict Root Login to Console

cp /etc/securetty /etc/securetty.old
cat > /etc/securetty <<EOF
console
tty1
tty2
tty3
tty4
tty5
tty6
EOF


Configure Time Services

Set Local Time Zone

dpkg-reconfigure tzdata


Define Time Servers

sed -i '/^#NTP=/c\NTP=time.google.com' /etc/systemd/timesyncd.conf


Restart Time Sync

systemctl restart systemd-timesyncd
ntpdate -u time.google.com



Journal Log Cleanup

(crontab -l ; echo "@daily journalctl --vacuum-time=30d --vacuum-size=1G" )| crontab -


Unattended Security Updates

Install unattended-upgrades package

apt install unattended-upgrades


Enable automatic upgrades

dpkg-reconfigure unattended-upgrades


Configure apt options

cat > /etc/apt/apt.conf.d/10periodic <<EOF
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "1";
EOF


Configure only security updates and reboot time (2:00am)

cat > /etc/apt/apt.conf.d/50unattended-upgrades <<EOF
Unattended-Upgrade::Allowed-Origins {
        "\${distro_id}:\${distro_codename}";
        "\${distro_id}:\${distro_codename}-security";
        "\${distro_id}ESM:\${distro_codename}";
};
Unattended-Upgrade::Package-Blacklist {
};
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "02:00";
EOF


Configure Download Timer Service

rm -rf /etc/systemd/system/apt-daily.timer*
systemctl --full edit apt-daily.timer


modify the following for random download time between 6am – noon and 6pm – midnight

RandomizedDelaySec=6h


Configure Upgrade Timer Service

rm -rf /etc/systemd/system/apt-daily-upgrade.timer*
systemctl --full edit apt-daily-upgrade.timer


modify the following for random upgrade time between 12:25am and 12:55am

OnCalendar=*-*-* 0:25
RandomizedDelaySec=30m


Update to Latest Linux Kernel

Install new Kernel

apt -y install --install-recommends linux-virtual-hwe-18.04


reboot and reconnect with putty as root user

reboot


Remove old kernel packages and dependencies

apt-get -y autoremove ; apt -y purge linux-generic linux-headers-generic linux-image-generic linux-virtual linux-headers-virtual linux-image-virtual ; apt -y purge linux*4.15.*


Make sure all Linux packages are up-to-date

linux-update


Suggested Next Steps

Scroll to Top