How To Initially Setup an Ubuntu 20.04 Server

For now, this installation process has only been tested on a fresh DigitalOcean Droplet of any size with Ubuntu 20.04. Near the bottom of the Create Droplet page, you need to add an SSH Key for the root user — not a password. (The following instructions assume you are using the default SSH Key on your local computer.)

If you plan to associate your installation with a domain name, and want to install an SSL certificate below (with EFF's CertBot), then open up DigitalOcean's Networking tab now. Add your domain for DNS management, with A records for "@" and "www" pointing to your new Droplet's IP address.

It generally seems best to take advantage of DigitalOcean's Managed Databases. It's easiest to create one first, assign your Droplet as a Trusted Source, and create a new database for this installation. The auto-install scripts below assume an external database. The list of All Commands below does include instructions to install a MYSQL server within your new Droplet instead.


Create Super User, Disable Root

For these instructions, the new user is named rockhopuser, but you can call it anything.

Instead of 22, we will select a SSH Port to connect to (between 23 and 1023). The custom SSH port here will be 123.

For these instructions, the Server IP Address will be 123.45.67.890. We will setup SSH access restricted to your fixed IP Adress — hopefully this is your VPN's IP Address — here it will be 98.76.54.321.

% ssh root@server.ip.address
e.g.
% ssh root@123.45.67.890


Temporary Bug Workaround

Recently, fresh DigitalOcean Droplets have been giving errors when 'apt upgrade' is run. A post helped me through this [temporary] problem...

Before running the main installation steps below, run the first three commands manually:

$ apt-add-repository universe
$ apt update
$ echo "Y" | apt upgrade

If the 'apt upgrade' command hangs on a sshd_config screen, close your terminal tab and reconnect to the server in a fresh terminal. Then get a list of locked processed:

sudo lsof /var/cache/apt/archives/lock

Hopefully, this provides some results including a line like this:

focal   14627 root   66u   REG  259,3        0 12328392 /var/cache/apt/archives/lock

Use those results to identify the process number to kill:

sudo kill 14627  # focal upgrade process

If this workaround works, you should now hopefully be able to continue the installation process as intended below.



In your new server, first pull down a copy of the Survloop installation scripts. Then run the Create Super User script to create a super user to be used instead of the root account. This will restrict SSH access to your IP, or that of your VPN tunnel. This script includes an installation of Fail2ban, and disables some unneeded networking tools.

When prompted, enter your new super user's strong password — and copy it somewhere super duper safe, like a password manager. This first installation script will configure your SSH access to a custom port number. Be sure to securely copy this port number too.

If you have a YubiKey, then you can optionally enter your token for UFA. Press your YubiKey USB button, and delete all but the first 12 characters for this token. (SSH Public key+MFA with Yubikey on Ubuntu 20.04 LTS)


$ git clone http://github.com/rockhopsoft/install-scripts
$ bash install-scripts/src/ubuntu20/create-super-user.sh

This is a summary of Digital Ocean's Initial Server Setup with Ubuntu 20.04. The last line copies your SSH Key from your root user to your new one.

$ apt-add-repository universe
$ apt update
$ echo "Y" | apt upgrade
$ adduser rockhopuser
$ usermod -aG sudo rockhopuser
$ rsync --archive --chown=rockhopuser:rockhopuser ~/.ssh /home/rockhopuser


If you have a Yubikey...

You will need the first 12 characters of your Yubikey, e.g. cccccfghjcff:

$ apt install libpam-yubico -y
$ echo "rockhopuser:cccccfghjcff" >> /etc/yubico
$ sed -i 's/@include common-auth/auth required pam_yubico.so id=16 debug authfile=\/etc\/yubico/g' /etc/pam.d/sshd
$ sed -i 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' /etc/ssh/sshd_config
$ sed -i 's/# Authentication:/AuthenticationMethods publickey,keyboard-interactive/g' /etc/ssh/sshd_config
$ sed -i 's/UsePAM no/UsePAM yes/g' /etc/ssh/sshd_config
$ systemctl restart sshd
If you do not have a Yubikey...
$ sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
$ systemctl restart sshd


Edit Port and User IP in Uncomplicated Firewall (UFW)

Instead of 22, what SSH PORT will you connect to, between 23 and 1023? e.g. 123

This will also restrict SSH access to your VPN's IP, e.g. 98.76.54.321

$ sed -i "s/#Port 22/Port 123/g" /etc/ssh/sshd_config
$ sed -i 's/PermitRootLogin yes/PermitRootLogin no/g' /etc/ssh/sshd_config
$ sed -i 's/#LogLevel INFO/LogLevel VERBOSE/g' /etc/ssh/sshd_config
$ ufw default deny incoming
$ ufw default allow outgoing
$ ufw limit from 98.76.54.321 to any port 123
$ echo "y" | ufw enable
$ systemctl restart sshd

Disabling various over~networking

$ sed -i 's/#net.ipv4.conf.default.rp_filter=1/net.ipv4.conf.default.rp_filter=1/g' /etc/sysctl.conf
$ sed -i 's/#net.ipv4.conf.all.rp_filter=1/net.ipv4.conf.all.rp_filter=1/g' /etc/sysctl.conf
$ sed -i 's/#net.ipv4.conf.all.accept_redirects = 0/net.ipv4.conf.all.accept_redirects = 0/g' /etc/sysctl.conf
$ sed -i 's/#net.ipv6.conf.all.accept_redirects = 0/net.ipv6.conf.all.accept_redirects = 0/g' /etc/sysctl.conf
$ sed -i 's/#net.ipv4.conf.all.send_redirects = 0/net.ipv4.conf.all.send_redirects = 0/g' /etc/sysctl.conf
$ sed -i 's/#net.ipv4.conf.all.accept_source_route = 0/net.ipv4.conf.all.accept_source_route = 0/g' /etc/sysctl.conf
$ sed -i 's/#net.ipv6.conf.all.accept_source_route = 0/net.ipv6.conf.all.accept_source_route = 0/g' /etc/sysctl.conf
$ sed -i 's/#net.ipv4.conf.all.log_martians = 1/net.ipv4.conf.all.log_martians = 1/g' /etc/sysctl.conf
$ sysctl -p


Install Fail2ban

Include exception for your VPN's IP address:

$ apt update
$ apt upgrade
$ add-apt-repository universe
$ echo "Y" | apt install fail2ban
$ systemctl start fail2ban
$ systemctl enable fail2ban
$ cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
$ sed -i "s/#ignoreip = 127.0.0.1\/8 ::1/ignoreip = 98.76.54.321/g" /etc/fail2ban/jail.local
$ sed -i 's/bantime  = 10m/bantime  = 30m/g' /etc/fail2ban/jail.local
$ sed -i 's/maxretry = 5/maxretry = 3/g' /etc/fail2ban/jail.local
$ sed -i 's/enabled = false/enabled = true/g' /etc/fail2ban/jail.local
$ systemctl enable fail2ban
$ systemctl status fail2ban.service
$ fail2ban-client status sshd


Give the server a minute or two to reboot...

# reboot

Then log back into the server with your new super user.

% ssh super_user@server.ip.address -p custom_ssh_port
e.g.
% ssh rockhopuser@123.45.67.890 -p 123


Frequently Update Ubuntu, etc
$ sudo apt-get update
$ sudo apt update && sudo apt dist-upgrade
$ sudo apt install update-manager-core
$ sudo do-release-upgrade
$ composer update
$ php artisan cache:clear