Creating A Private Web Server (Ubuntu 20.10)

A private server is a server that cannot be accessed from the internet, only from the local network. A private server is used for:

  • a development server

  • a test server

  • a non-public server

Preparation

  • Download the Ubuntu 20.10 Server image from the Ubuntu website.

  • You should have a MAC address and reserved IP address on your router for the virtual machine. In this case let's say the MAC address is BB:BB:DD:DD:02:04 and the reserved IP address is 10.0.5.204.

  • You should have a unique once in a lifetime domain name for your web server. This is the domain for the web server, not any website. In this process we will use this domain to display the default Apache website.

    webserver5.mattifesto.com

    There is domain should have a public DNS A record pointing to 10.0.5.204.

    Here's a page showing how Mattifesto sets up web server and website domains and IP addresses:

    https://devs.mattifesto.com/mattifesto-web-server-and-web-site-domain-name-strategy/

Create a new virtual machine

  • Click the "New" button to create a new virtual machine. 

  • Name and operating system panel

    Name: webserver<number>

    Type: Linux

    Version: Ubuntu (64-bit)

  • Memory size panel

    Set memory size to 1024MB to match DigitalOcean.

  • Hard disk panel

    Select "Create a virtual hard disk now"

  • Hard disk file type panel

    Select "VDI (VirtualBox Disk Image)"

  • Storage on physical hard disk panel

    Select "Fixed Size"

  • File location and size panel

    Set the hard disk size to 25GB to match DigitalOcean.

  • Click the "Create" button to create the virtual machine.

  • Click on the "Settings" toolbar button.

  • Click on the "Display" toolbar button.

  • Set "Scale Factor" to 200%

  • Click on the "OK" button.

Install Ubuntu on the new virtual machine

  • Click the "Start" toolbar button.

  • Select the Ubuntu install CD ISO file.

  • Click the "Start" button.

  • The Ubuntu install process will start.

  • Willkommen! panel

    Select "English"

    Press return

  • Installer update available panel

    If there are installer updates available select "Update to the new installer"

    Press return

  • Keyboard configuration panel

    Variant: If using a Mac select the "English (US) - English (Macintosh)"

    Press [ Done ]

  • Network connection panel

    Press [ Done ]

  • Configure proxy panel

    Select [ Done ]

  • Configure Ubuntu archive mirror panel

    Select [ Done ]

  • Guided storage configuration panel

    Select [ Done ]

  • Storage configuration panel

    Select [ Done ]

  • Confirm destructive action panel

    Select [ Continue ]

  • Profile setup panel

    Your name: enter your full name

    Your server's name: Use the webserverN name you used in the earlier step

    Pick a username: It's easiest to use the same username that you use on your workstation. You can the type "ssh webserverN" from your workstation without specifying the username.

    Choose a password: It's easiest to use the same password that you use on your workstation if that is secure in your situation.

    Confirm your password: confirm password

    Select [ Done ]

  • SSH Setup panel

    Check the "Install OpenSSH server" option.

    Select [ Done ]

  • Featured Server Snaps panel

    Select [ Done ]

  • The Ubuntu install process will complete.

  • Let the "downloading and installing security updates" process finish.

  • Select / click the "Reboot" button.

  • Log in to the virtual machine for the first time.

  • Type: sudo shutdown now

Setup virtual machine networking

  • Go the the VirtualBox Manager.

  • Make sure the virtual machine we are working on is selected.

  • Click on the "Settings" toolbar button.

  • Click on the "Network" toolbar button.

  • Attached to: Select "Bridged Adapter".

  • Expand the "Advanced" section.

  • MAC Address

    Enter the MAC Address that you have reserved for this virtual machine. The MAC address should be registered with your router to provide a reserved IP address.

    A domain should be specified in /etc/hosts associated with this IP Address.

    This same domain should be registered with you DNS provider to point to this server's IP Address.

  • Click the "OK" button.

  • Click the arrow next to the "Start" toolbar button.

  • Select "Headless Start".

    We will use MacOS terminal to log in to the machine from now on.

  • Start the Terminal app in MacOS

  • $ ssh domain

    or

    $ ssh user@domain

    If you've recreated a server for the second time or greater you may get the message that the identification has changed. If you do you can fix it with this command and then trying again.

    $ ssh-keygen -R domain

Update and Setup VirtualBox Additions

  • $ sudo apt update

  • $ sudo apt upgrade

  • In the Oracle VM VirtualBox Manger

  • Click on the "Settings" toolbar icon

  • Click on the "Storage" toolbar icon

  • Under "Controller: IDE" select the CD icon which will probably say "Emtpy"

  • On the right hand side of the panel click on the CD image to the right of "Optical Drive:" and select "VBoxGuestAdditions.iso"

  • Press the OK button

  • $ sudo mount /dev/cdrom /media

  • $ cd /media

  • $ sudo ./VBoxLinuxAdditions.run

  • This line will be in the output indicating which packages need to be installed:

    "Please install the gcc make perl packages from your distribution."

  • $ sudo apt install <list of packages>

  • $ sudo ./VBoxLinuxAdditions.run

    This time it will install the software.

  • $ sudo reboot

Install Software

$ sudo apt install ack apache2 libapache2-mod-php mysql-server php php-curl php-mysql php-gd php-mbstring

(2021_02_08) Removed: libapache2-mpm-itk

Setup Firewall

From: https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-20-04

  • $ sudo ufw allow OpenSSH

  • $ sudo ufw enable

  • $ sudo ufw status

Setup Apache

From: https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu-20-04

  • $ sudo ufw allow in "Apache Full"

  • $ sudo a2enmod ssl

  • $ sudo a2enmod rewrite

  • $ sudo vi /etc/apache2/envvars

    We are going to place the document roots for all the websites in your home directory and the only user with websites on this machine is you.

    Change:

    export APACHE_RUN_USER=www-data

    to:

    export APACHE_RUN_USER=mattcalkins

  • $ sudo vi /etc/apache2/conf-available/servername.conf

    ServerName webserver5.mattifesto.com

  • $ sudo a2enconf servername

  • Fix issue that makes Apache stop

    Note: Appears to be related to using SSL on Ubuntu. More information not available. Update if more is discovered.

    Reference: https://stackoverflow.com/questions/50652808/apache-shutdown-couldnt-grab-mutex

    • $ sudo vi /etc/apache2/conf-available/mutex-file.conf

    • This file should contain a single line:

      Mutex file:${APACHE_LOCK_DIR} default

    • $ sudo a2enconf mutex-file

  • $ sudo apache2ctl configtest

  • $ sudo systemctl restart apache2

  • Go to http://webserver5.mattifesto.com to make sure apache is working.

Create SSL Certificate Using acme.sh

https://github.com/acmesh-official/acme.sh

https://github.com/acmesh-official/acme.sh/wiki/How-to-install

$ curl https://get.acme.sh | sh

$ exit

$ ssh <virtual server domain>

Create or renew certificate.

Strategy

For private web servers, SSL certificates must be created manually. It is most convenient on private servers to create a wildcard certificate so that you don't have to create and renew multiple certificates for each website hosted on the web server.

We create a two domain certificate. The first domain is the domain of the server, webserver5.mattifesto.com, and the second domain is the wildcard domain, *.webserver5.mattifesto.com. Websites hosted on the server should add a single name to the domain such as, media.webserver5.mattifesto.com, and will not require any additional certificate to be created.

Required

Your domain must publicly point to an IP address or a CNAME that directs to a domain that points to an IP address. It's fine if the IP address is only locally available.

Dreamhost supported for API mode

I have created a Dreamhost API key. (find on dreamhost) (you only need to set it the first time per server)

https://panel.dreamhost.com/?tree=home.api

https://github.com/acmesh-official/acme.sh/wiki/dnsapi#40-use-dreamhost-dns-api

  • $ export DH_API_KEY="<api key>"

  • $ acme.sh --issue --dns dns_dreamhost -d 'webserver5.mattifesto.com' -d '*.webserver5.mattifesto.com' --dnssleep 120

    I have at times used this command without the dnssleep option, and at times it has worked, but even when the TXT record can be seen by running dig on this virtual machine, the acme process will still not see it.

    So the dnssleep option usually is a workaround to this issue but not always. This process should be easy, but it's not currently, but if you just keep trying it will work.

    Also, make sure you don't have typos in your domain names. (Made that mistake before.)

  • We are going to update the default virtual host to support SSL to verify our certificate.

    $ sudo vi /etc/apache2/sites-available/000-default.conf

  • Copy the <VirtualHost *:80> section and paste it below itself.

  • Alter the copy to use port 443 instead of port 80.

  • Copy the following lines into the end of the virtual host block:

    SSLEngine               on
    SSLCertificateFile      /home/mattcalkins/.acme.sh/webserver5.mattifesto.com/webserver5.mattifesto.com.cer
    SSLCertificateKeyFile   /home/mattcalkins/.acme.sh/webserver5.mattifesto.com/webserver5.mattifesto.com.key
    
  • $ sudo apache2ctl configtest

  • $ sudo systemctl restart apache2

  • Go to https://webserver5.mattifesto.com to make sure the SSL certificate is working.

Setup MySQL

  • $ sudo mysql_secure_installation

    Basically answer yes to everything.

Fix Gmail IPv6 Issue

$ ping smtp.gmail.com

If this works fine, you don't have issues and can move on from this section.

If this ping command doesn't work it means there is an issue with gmail and IPv6 on your server which will prevent your website from sending email. I do not currently know what causes this issue, but I do know how to fix it:

$ nslookup smtp.gmail.com

Copy the IPv4 address from the result.

$ sudo vi /etc/hosts

Add the following line to this file using the IPv4 address you copied:

xxx.xxx.xxx.xxx smtp.gmail.com

After saving the ping command should work.

$ ping smtp.gmail.com

Setup GitHub SSH

This step is only required for private GitHub repositories.

If you have private GitHub repositories you will need to authenticate with GitHub using SSH keys.

This link tells you more about this process.

https://docs.github.com/en/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent

If you have your keys on your dev machine but just created a new virtual machine these instructions help you copy them to the new VM.

In MacOS terminal signed in to Mac:

  • $ scp -r <key directory> webserver1:~

In MacOS terminal sign in to server VM:

  • move keys to .ssh directory

  • $ eval "$(ssh-agent -s)"

  • $ ssh-add <key name>