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 or 20.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 on Azure, see the instruction below for Swap File on Azure.

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

Swap File on Azure

The Azure WALinuxAgent will automatically create a swap file on the resource (temporary) drive.

cp /etc/waagent.conf /etc/waagent.conf.save
sed -i '/ResourceDisk.Format/c\ResourceDisk.Format=y' /etc/waagent.conf
sed -i '/ResourceDisk.EnableSwap/c\ResourceDisk.EnableSwap=y' /etc/waagent.conf
sed -i '/ResourceDisk.SwapSizeMB/c\ResourceDisk.SwapSizeMB=4096' /etc/waagent.conf
service walinuxagent restart

Create Linux Update Scripts

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

Install Updates and reboot when prompted


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 ntpdate patch psmisc screen software-properties-common sosreport update-motd update-notifier-common vim zip unzip

Set Hostname

hostnamectl set-hostname domain.tld

Rebuild Hosts File

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

Check the output at the end of the command to make sure the hosts file looks similar to this localhost 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

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

Restrict Root Login to Console

cp /etc/securetty /etc/securetty.old
cat > /etc/securetty <<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";

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

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

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


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

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


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


Suggested Next Steps

Scroll to Top