Skip to content

Instantly share code, notes, and snippets.

@sepehr
Last active August 23, 2023 04:28
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sepehr/337dc627b2175f3163a3 to your computer and use it in GitHub Desktop.
Save sepehr/337dc627b2175f3163a3 to your computer and use it in GitHub Desktop.
Webserver recipe for Ubuntu 14.04

Webserver setup recipe for Ubuntu 14.04 LTS

A few notes:

  • All commands should be run as root unless specified otherwise.
  • Commands that sould be run locally have a local$ prefix.

Initial setup

Hostname

hostname SHINYNODE

Upgrade

apt-get update

# Review what will be upgraded
apt-get -u upgrade

apt-get upgrade -y

apt-get autoremove

Install some base packages

apt-get install git tree httpie python-pip python-software-properties software-properties-common

Timezone & time sync

# Configure timezones
dpkg-reconfigure tzdata

# Configure NTP sync
apt-get install ntp

Add SSH key

# Add your SSH key
local$ ssh-copy-id root@SERVER_IP

# Or manually:
mkdir ~/.ssh
chmod 700 ~/.ssh

echo "YOUR_SSH_KEY" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

Add a new user if necessary

adduser sepehr

# Add new user to the `sudo` group to be a sudoer
gpasswd -a sepehr sudo

local$ ssh-copy-id sepehr@SERVER_IP

# If logged-in with root, you can switch to the new user without logging out:
su - sepehr

Enable swap for mini nodes

# Allocate an empty 1G file
fallocate -l 1G /swapfile

# Format as swap
mkswap /swapfile

# Enable swap
swapon /swapfile

NOTE: The system will only use this space until the next reboot, but the only time that the server is likely to exceed its available memory is during the build processes, so this shouldn't be a problem.

Security

Disallow remote root logins, if necessary

# Simply change `PermitRootLogin yes` to `PermitRootLogin no`
nano /etc/ssh/sshd_config

service ssh restart

# Exit and login using the new user
# NOTE: Make sure there's at least a sudoer user available
exit

Protect SSH against bruteforce

A service called fail2ban can mitigate this problem by creating rules that can automatically alter your iptables firewall configuration based on a predefined number of unsuccessful login attempts. This will allow the server to respond to illegitimate access attempts without intervention from you.

apt-get install fail2ban

# Since this file can be modified by package upgrades, we should not edit this file in-place, but rather copy it so that
# we can make our changes safely.
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

# Configure:
#
# bantime: 600
# findtime: 600
# maxretry: 3
#
# Other entries to pay attention to:
#     destemail, sendername, mta, filter, logpath
#
# SSH is enabled by default, all other services are disabled. Read more:
# https://www.digitalocean.com/community/tutorials/how-to-protect-ssh-with-fail2ban-on-ubuntu-14-04
nano /etc/fail2ban/jail.local

Configure the firewall

ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp

ufw show added

ufw enable

Install LAMP stack

Install Apache 2.4

apt-get install apache2

# Resolve this error for 2.4:
# "apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName"
echo "ServerName localhost" | sudo tee /etc/apache2/conf-available/fqdn.conf
a2enconf fqdn

Install Apache 2.2

# Add `precise` repos so the 2.2 version will be available to us:
#
# deb http://archive.ubuntu.com/ubuntu precise main restricted universe
# deb http://archive.ubuntu.com/ubuntu precise-updates main restricted universe
# deb http://security.ubuntu.com/ubuntu precise-security main restricted universe multiverse
#
nano /etc/apt/sources.list.d/precise.list

apt-get update

apt-get install apache2-mpm-prefork=2.2.22-1ubuntu1.10 \
  apache2-prefork-dev=2.2.22-1ubuntu1.10 \
  apache2.2-bin=2.2.22-1ubuntu1.10 \
  apache2.2-common=2.2.22-1ubuntu1.10

# Resolve this error for 2.2:
# "apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName"
echo "ServerName localhost" > nano /etc/apache2/conf.d/fqdn

service apache2 restart

NOTE: Due to dependency conflicts the default php5 package cannot be installed alongside this apache 2.2. You need to install a compatible php5 package. Instructions to do so is not included in this guide... yet.

Enable rewrite module

a2enmod rewrite

# Allow .htaccess files under the document root
# Within "<Directory /var/www/>" change "AllowOverride None" to "AllowOverride All"
nano /etc/apache2/apache2.conf

service apache2 restart

Disable directory listing

# Within "<Directory /var/www/>" remove "Indexes" from "Options Indexes"
nano /etc/apache2/apache2.conf

Setup Apache virtualhosts

# 1. Create directory structure
mkdir -p /var/www/html/www.example.com/public
mkdir -p /var/www/html/dev.example.com/public

# 2. Setup virtualhost for example.com
# NOTE: Default Ubuntu configuration requires that each virtual host file end in `.conf`
cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/example.com.conf

# <VirtualHost *:80>
#    ServerAdmin  sysadmin@example.com
#    ServerName   example.com
#    ServerAlias  www.example.com
#    DocumentRoot /var/www/html/www.example.com/public
#    ErrorLog     ${APACHE_LOG_DIR}/error.log
#    CustomLog    ${APACHE_LOG_DIR}/access.log combined
# </VirtualHost>
#
# Copy and customize this file for dev.example.com domain
#
nano /etc/apache2/sites-available/example.com.conf
nano /etc/apache2/sites-available/dev.example.com.conf

# 3. Enable new virtual host files
a2ensite example.com.conf
a2ensite dev.example.com.conf

# Disable the default virtual host
a2dissite 000-default.conf

service apache2 restart

Install PHP 5.5.x

apt-get install php5

php -v

Install PHP 5.6.x

add-apt-repository ppa:ondrej/php5-5.6

apt-get update

apt-get install php5

php -v

Install composer globally

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

Install PHP extensions

apt-get install php5-mysql php5-gd php5-mongo php5-mcrypt

service apache2 restart

Install MariaDB 10.1

# Add the official repo:
apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db

# Add these to a new mariadb.list file:
#
# deb [arch=amd64,i386] http://nyc2.mirrors.digitalocean.com/mariadb/repo/10.1/ubuntu trusty main
# deb-src http://nyc2.mirrors.digitalocean.com/mariadb/repo/10.1/ubuntu trusty main
#
nano /etc/apt/sources.list.d/mariadb.list

apt-get update

apt-get install mariadb-server

service mysql start

# Post-installation setup
mysql_install_db
mysql_secure_installation

# In case you need to reconfigure the package
dpkg-reconfigure mariadb-server-10.1

Enabling SSL on Apache

Enable SSL module

# With apache2 already installed, enable the SSL module
a2enmod ssl

service apache2 restart

Disable SSLv3

# Disable SSLv3 against POODLE attacks
# The "SSLProtocol" directive should be explicitly set to "SSLProtocol all -SSLv3". SSLv2 is no longer supported.
nano /etc/apache2/mods-available/ssl.conf

service apache2 restart

Securing Apache with letsencrypt

# 1. Download the Let's Encrypt client
cd /opt
git clone https://github.com/letsencrypt/letsencrypt

# 2. Setup SSL certificates
# Execute the interactive installation and obtain a certificate that covers only a single domain.
#
# When the installation is finished, you should be able to find the generated certificate files at
# /etc/letsencrypt/live directory.
#
# Verify the status of your SSL certificate with the following link:
# https://www.ssllabs.com/ssltest/analyze.html?d=example.com&latest
#
# During installation letsencryot will ask to whether disable HTTP or not. Make sure to choose the 
# second option to redirect HTTP traffic to HTTPS.
#
./letsencrypt-auto --apache -d example.com -d www.example.com -d dev.example.com

# 3. Setup auto-renewal
# Let’s Encrypt certificates are valid for 90 days. Manually renew a Let’s Encrypt certificate for Apache with no
# interaction using this command. Pass the same list of domains again for the renewal command:
#
# ./letsencrypt-auto certonly --apache --renew-by-default -d example.com -d www.example.com -d dev.example.com
#
# 3.1. Download the renewal script
curl -L -o /usr/local/sbin/le-renew http://do.co/le-renew
chmod +x /usr/local/sbin/le-renew

# 3.2. Now we can manually renew using just the base domain
# You can check which domain was used by Let’s Encrypt as the base domain name by looking at the contents inside
# /etc/letsencrypt/live
#
le-renew example.com

# 3.3. Setup a CRON task to automatically check for renewals every week
#
# 30 2 * * 1 /usr/local/sbin/le-renew example.com >> /var/log/le-renew.log
#
crontab -e

Securing Apache with self-signed SSL certificates

# 1. Create a directory to store server keys
mkdir /etc/apache2/ssl

# 2. Create a Self Signed SSL Certificate
# This command will prompt terminal to display a lists of fields that need to be filled in. The most important line is
# "Common Name". Enter your official domain name here or, if you don't have one yet, your site's IP address.
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/apache2/ssl/apache.key -out /etc/apache2/ssl/apache.crt

# 3. Setup virtualhosts
# Default virtualhost with SSL enabled:
# /etc/apache2/sites-available/default-ssl.conf
#
# Create new virtualhosts for each site based on the default. Here's a sample:
#     example.com-ssl.conf
#
<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
            ServerAdmin   sysadmin@example.com
            ServerName    example.com:443
            ServerAlias   www.example.com:443
            DocumentRoot  /var/www/html/www.example.com/public
            ErrorLog      ${APACHE_LOG_DIR}/error.log
            CustomLog     ${APACHE_LOG_DIR}/access.log combined

            SSLEngine on
            SSLCertificateFile    /etc/apache2/ssl/apache.crt
            SSLCertificateKeyFile /etc/apache2/ssl/apache.key

            <FilesMatch "\.(cgi|shtml|phtml|php)$">
                    SSLOptions +StdEnvVars
            </FilesMatch>

            <Directory /usr/lib/cgi-bin>
                    SSLOptions +StdEnvVars
            </Directory>

            BrowserMatch "MSIE [2-6]" \
                nokeepalive ssl-unclean-shutdown \
                downgrade-1.0 force-response-1.0

            # MSIE 7 and newer should be able to use keepalive
            BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
    </VirtualHost>
</IfModule>

# 4. Enable SSL virtualhosts
# You might want to disable the corresponding non-SSL virtualhost
a2ensite example.com-ssl.conf

service apache2 restart

Refs

Initial Server Setup with Ubuntu 14.04

Additional Recommended Steps for New Ubuntu 14.04 Servers

How To Protect SSH with Fail2Ban on Ubuntu 14.04

How To Set Up Apache Virtual Hosts on Ubuntu 14.04 LTS

How To Create a SSL Certificate on Apache for Ubuntu 12.04

How To Secure Apache with Let's Encrypt on Ubuntu 14.04

How To Protect your Server Against the POODLE SSLv3 Vulnerability

How to setup / install PHP 5.6 on Ubuntu 14.04 LTS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment