Udacity Full Stack web development nanodegree assignment 3 to take a baseline installation of a Linux distribution on a virtual machine and prepare it to host a web application, to include installing updates, securing it from a number of attack vectors and installing/configuring web and database servers. Webserver stack is:
- Linux 16.04
- Apache2
- PostgreSQL
Host name: http://104.197.242.30.xip.io/
Public IP: 104.197.242.30
SSH port: 22000
- Go to cloud console
- Click Compute Engine and VM instances.
- Create new instance. Free is a micro service but regardless include Ubuntu 16.04 and 50Gb SSD drive.
- Once created, click SSH connect to login to server.
- Click three dots and go to network settings. Add any firewall rules needed such as http(80), ssh(2200) and ftp(123)
- Update and upgrade installed packages
sudo apt-get update
sudo apt-get upgrade
- Change the SSH default port from 22 to 2200 by editing /etc/ssh/sshd_config:
sudo vim /etc/ssh/sshd_config
- Restart the SSH service:
sudo service ssh restart
- Configure the default Ubuntu firewall to only allow incoming connection on HTTP(80), SSH(2200) and NTP (123).
sudo ufw status # Should be inactive.
sudo ufw default deny incoming # Deny any incoming traffic.
sudo ufw default allow outgoing # Enable outgoing traffic.
sudo ufw allow 2200/tcp # Allow incoming tcp packets on port 2200 for SSH.
sudo ufw allow www # Allow HTTP traffic.
sudo ufw allow 123/udp # Allow incoming udp packets on port 123.
sudo ufw deny 22 # Deny tcp and udp packets on port 22.
- Enable UFW with
sudo ufw enable
- Check the status and all current rules with
sudo ufw status
- Install Fail2ban
sudo apt-get install fail2ban
- To send email
sudo apt-get install sendmail iptables-persistent
- Copy jail.conf to local copy
sudo cp/etc/fail2ban/jail.conf /etc/fail2ban/jail.local
- Edit jail.local to change ssh to port 2200 and configure action send email and recipient. Restart the service
sudo service fail2ban restart
destemail = user@domain
action = %(action_mwl)s
port = 2200
- To create the grader user:
sudo adduser grader
- To give permissions:
sudo visudo
- Add below root ALL=...
grader ALL=(ALL:ALL)
- To verify run:
su - grader
and enter password then run:sudo - grader
. Make sure the last line includes your ALL statement from above. - On your local machine, create an SSH key pair for user grader. This can be done using
ssh-keygen
or Putty Gen for Windows. - On the virtual machine create an ssh directory:
mkdir .ssh
- Create an authorized keys file:
sudo vim ~/.ssh/authorized_keys
- In this file copy the public key you generated on your local machine into this file and save.
- Give permissions:
chmod 700 .ssh
andchmod 644 .ssh/authorized_keys
- Change to deny password auth:
vim /etc/ssh/sshd_config
setPasswordAuthetication no
- Restart service:
sudo service ssh restart
- On your local machine test by connecting with Putty on Windows or
ssh -i <path to private key> -p 2200 grader@<public ip>
- Install Apache2 and required mod-wsgi:
sudo apt-get install apache2
sudo apt-get install libapache2-mod-wsgi python-dev
- Start mod_wsgi:
sudo a2emod wsgi
- Start the web server:
sudo service apache2 start
- Check this is working by visiting the public IP of your server to see the default page of Apache2. This will show that your firewall rules are working as well on port 80 (http).
- Create a folder for your web app:
cd /var/www
,sudo mkdir catalog
,sudo chown -R grader:grader catalog
,cd catalog
- Clone your web application:
sudo apt-get install git
,git clone <your repo link>
- Create a wsgi file:
sudo vim /var/www/catalog/catalog.wsgi
and include:
#!/usr/bin/python
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0, "/var/www/catalog/")
from catalog import app as application
application.secret_key = 'your_super_secret_key'
- Rename your
main.py
to__init__.py
:mv main.py __init__.py
- Create a virtual environment to install dependencies:
sudo apt-get install python-pip
sudo pip install virtualenv
sudo virtualenv venv
source venv/bin/activate
sudo chmod -R 777 venv
- Install dependencies:
sudo pip install Flask httplib2 oaythclient sqlalchemy psycopg2 requests
- Create, configure and enable the virtual hosts:
sudo vim /etc/apache2/sites-available/catalog.conf
- Use the following:
<VirtualHost *:80>
ServerName <YOUR PUBLIC IP ADDRESS>
ServerAlias <YOUR HOST NAME>
ServerAdmin admin@<YOUR PUBLIC IP ADDRESS>
WSGIDaemonProcess catalog python-path=/var/www/catalog:/var/www/catalog/venv/lib/python2.7/site-packages
WSGIProcessGroup catalog
WSGIScriptAlias / /var/www/catalog/catalog.wsgi
<Directory /var/www/catalog/catalog/>
Order allow,deny
Allow from all
</Directory>
Alias /static /var/www/catalog/catalog/static
<Directory /var/www/catalog/catalog/static/>
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
- Install required packages:
sudo apt-get install libpq-dev python-dev
sudo apt-get install postgresql postgresql-contrib
sudo -u postgres -i
- Enter psql command line:
psql
- Create a database, user and set permissions:
CREATE USER catalog WITH PASSWORD <your password>;
ALTER USER catalog CREATEDB;
CREATE DATABASE catalog WITH OWNER catalog;
\c catalog
REVOKE ALL ON SCHEMA public FROM public;
GRANT ALL ON SCHEMA public TO catalog;
- Change all reference to DB in your web app to
engine = create_engine('postgresql://catalog:<your_password>@localhost/catalog)
- Restart Apache server to launch your full stack web application!
sudo service apache2 restart
- https://github.com/chuanqin3/udacity-linux-configuration
- https://github.com/twhetzel/ud299-nd-linux-server-configuration
- https://github.com/boisalai/udacity-linux-server-configuration#step_5_1
- https://github.com/juvers/Linux-Configuration
- Fail2Ban
- https://www.digitalocean.com/community/tutorials/how-to-protect-ssh-with-fail2ban-on-ubuntu-14-04
- https://www.digitalocean.com/community/tutorials/how-to-configure-the-apache-web-server-on-an-ubuntu-or-debian-vps
- Postgresql