Ubuntu 18.04 LTS
These instructions are for Ubuntu 18.04 on a hosted VPS provider
This class is the most critical as it will ultimately determine whether your server works or not. Make sure you have at least a 20-minute block of uninterrupted time before you get started. It should also be done in one fell swoop since we’ll be configuring our firewall to keep the bad guys out!
Virtualization Drivers
When given the option, we install Ubuntu using the Intel Pro/1000 virtual network card and the Virtio disk driver.
$ sudo lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL NAME FSTYPE SIZE MOUNTPOINT LABEL sr0 1024M vda 20G ├─vda1 ext4 19G / ├─vda2 1K └─vda5 swap 1022M [SWAP]
Ok, start your engines!
1. Change The Root Password, Then Add A Sudo User
Once your server has been spun-up, login as root via SSH and change the root password by typing:
$ passwd
Done? Good. With great power comes great responsibility. So, let’s tone things down abit and create our own personal account with a lower set of system privileges. We’ll login with this user from now on. Type:
$ adduser mycoolusername
Follow the prompts. Once you’r done, add your user account to the sudo group, by typing:
$ adduser mycoolusername sudo
Deleting Users
You may delete a user by typing deluser mycoolusername
. Refer to the official Ubuntu documentation as well as the man pages for additional details.
This will add your user to the sudo group and allow it to use the sudo command. Now log off by typing
$ exit
Now log back in as the new user you just created.
2. Update the Network Interfaces File
There are 2 principal breaking changes during the transition from 14.04 LTS to 16.04 LTS. First eth0
is neither the default nor a valid interface name. Second, the default network configuration is now set to dhcp
instead of a static
IP address. Here’s the contents of our interface file after a fresh install:
$ sudo nano /etc/network/interfaces
# This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). source /etc/network/interfaces.d/* # The loopback network interface auto lo iface lo inet loopback # The primary network interface auto ens3 iface ens3 inet dhcp
In the above, note the items in red: the ens3
interface name and the dhcp
network config. You will need to change dhcp
to static
and add the following 4 new lines.:
auto ens3 iface ens3 inet static address nnn.nnn.nnn.nnn gateway nnn.nnn.nnn.1 netmask 255.255.255.0 dns-nameservers 8.8.8.8 8.8.4.4
IMPORTANT: Replace nnn
with the corresponding portions (octets) of your actual IP address
3. Name Your Server (Hostname) and Add Its Fully Qualified Domain Name (FQDN)
Note that the hostname is not tied to your your server’s websites or any applications residing on it. The hostname is nothing more than a unique name for your server. We edit the hostname file and update (re-map) the directive to that file.
To name your server create a hostname entry like so:
$ echo "myReallyCoolServerName" > /etc/hostname
$ hostname -F /etc/hostname
The next step is very important and entails two alternatives. You may either have your hostname mapped to to the localhost address (i.e., 127.0.0.1) or map your server’s IP address to your hostname. The major takeaway is that you should edit your /etc/hosts
file so the server resolves the FQDN to your localhost.
$ sudo nano /etc/hosts
If Package-x is Not Available
Run the following to install “Package-x”:
$ apt-get install package-x
Uninstalling Programs and Packages
$ apt-get purge package-x
Option 1: FQDN Localhost Mapping
127.0.0.1 myReallyCoolServerName
127.0.1.1 ubuntu
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
Option 2: FQDN IP Address Mapping
Below is an alternate set-up. Be sure to swap out 111.11.11.11
with your server’s actual IP address:
127.0.0.1 localhost
127.0.1.1 ubuntu
111.11.11.11 myReallyCoolServerName
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
Option 3: localhost + domain name to localhost, FQDN to localhost and Domain to IP Address Mapping
127.0.0.1 localhost myDomainName.com
127.0.1.1 myReallyCoolServerName
111.11.11.11 myDomainName.com
# The following lines are desirable for IPv6 capable hosts
...
We’ll now reboot our server to load these changes:
$ sudo reboot
4. Update and Upgrade Server Packages using apt-get
Now that you are logged in as your own user from a SSH terminal update Linux to ensure your packages and libraries are up to date. This is just good practice before you install anything on your system, make sure it is the latest release. To do this run these commands:
$ sudo apt-get update
$ sudo apt-get upgrade
5. Install The LAMP Stack
Ok! This is why you came to party! Actually, Linux is already installed, so we’ll just be adding additional packages, libraries as well as Apache, MySQL and PHP!
The easiest way install the LAMP stack is with tasksel. To install the LAMP with taskel
type:
$ sudo tasksel install lamp-server
Follow the prompts that appear in your terminal. Enter a MySQL root password and don’t forget it :-). Next, you’ll need to secure our MySQL installation, so type:
mysql_secure_installation
Create Web Directory Structure5
Get to your top-level directory by typing:
$ cd /home/$USER
Now create the structure for your web directory:
$ mkdir -p public_html/domain1.com
/{public,private,log,cgi-bin,backup}
Setup the group and permissions:
$ sudo usermod -a -G www-data $USER #adds $USER to www-data (the Apache user group)
$ groups #this will output the groups $USER is a member of. logout then back in again to enable the change
$ sudo chgrp -R www-data /home/$USER/public_html
$ sudo chmod -R 2750 /home/$USER/public_html #assign the sticky bit so all files are mapped to $USER and group www-data
# Create a template that has the above folder structure and permissions.
# Just recopy the folders with cp -a command:
$ cp -a /home/$USER/public_html/domain1.com
/home/$USER/public_html/template_folders
6. Server Security Basics
It’s best to think of security as a series of layers. Additionally, security is something you want integrated into your app from the beginning. You want it baked-in, not just icing on top or added as an afterthought. We’ll only address a few of these concerns in today’s class, but here’s an overview:
- Obscurity: Changing default connect ports (3306 and 22) for MySQL and SSH. Also limiting information that Apache tells the world about itself by editing
/etc/apache2/conf.d/security
Security through Obscurity is a Myth: Neither People Nor Computers Can Keep Secrets
Obscurity does not make your server more secure. However, it may make you less of a target. From the Apache 2.4 core docs: “Security through obscurity” is a myth and leads to a false sense of safety.
- Port Blocking: Using a Firewall to disable all non-essential traffic – ports and connections – including ping, ftp, and sftp
- Pubic Key Encryption: Generating an SSH public/private key-pair for passwordless logins
- Disabling Common Attack Vectors: Directory browsing and remote root login
- IP Filtering: Using
httpd.conf
or thev-host file
to restrict site access based on host IP Address - Restricting Folder Access by Traffic Type: Restricting public web traffic over http/s to only those folders those you specifically designate. This may also be done through the
httpd.conf
and thev-host
files
a. Secure Your Server With A Firewall
For now, we’ll execute all the below as root. To allow established connections to remain open:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
To allow SSH Traffic:
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
To allow HTTP traffic:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
To allow HTTPS traffic:
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
And, finally, drop all remaining traffic:
iptables -A INPUT -j DROP
Save your new rules to a file
$ iptables-save > /etc/iptables.rules
Next, instruct your server’s Network Interface Card (NIC) to load the IP table rules on each boot:
$ nano /etc/network/interfaces
Once the file is opened add the following line right below the line “iface eth0 inet static”. And, make sure it’s indented like the other lines:
pre-up iptables-restore < /etc/iptables.rules
b. Configure & Lockdown MySQL
$ nano /etc/mysql/mysql.conf.d/mysqld.cnf
Change ports in 1 2 locations and update bind address to server IP
c. Lockdown Apache
$ nano /etc/apache2/conf-enabled/httpd.conf
#ref: httpd.apache.org/docs/2.4/upgrading.html#access and httpd.apache.org/docs/2.4/howto/access.html
<Directory />
# Globally Disable .htaccess
AllowOverride None
# Globally remove directory browsing
Options -Indexes
# Globally Remove Website Viewing
# Order Deny,Allow
# Deny from all
Require all denied
</Directory>
# Allow Viewing and .htaccess in A Web Directory of Your Choice
# You may choose any /optional/path/to/web/folder/public_html
<Directory /home/username/public_html/>
AllowOverride All
# Order Deny,Allow
# Allow from all
Require all granted
</Directory>
d. Partial SSH Lockdown
Further secure your server by modifying the sshd_config
file. Change the SSH port number to something random between 1-65535. You may want to select a number over 30,000 (well after the commonly used ports). This will help to prevent brute force attacks where a bot attempts to connect over SSH on the default port 22:
$ sudo nano /etc/ssh/sshd_config #change to a port above
Reload ssh config with your new modifications:
$ sudo service ssh reload
IMPORTANT: Now update your IP table rules to allow the new SSH and MySQL ports. Port 22 and 3306 will now be blocked:
$ sudo nano /etc/iptables.rules
You're done (for now)! Pat your self on the back and grab a tasty snack for a job well done!