This project is a deployment of a Flask application using Apache on a Linux machine. The project that is being deployed can be found here. For this project I used a virtual Linux machine (Ubuntu 16) hosed by Amazon Lightsail.
This project showcases my ability to configure a Linux machine to host an Apache web server from the ground up. It also shows my ability to configure said server to be protected and secure against many different threats that come along with having a public website.
IP Address: 54.245.168.69
SSH Port: 2200
SSH Key: Given to project grader, is unique ror every user
Application Link: 54.245.168.69.xip.io
I first edited the SSH port on my instance from 22 to 2200 by changing the sshd_config file
sudo vim /etc/ssh/sshd_config
I then configured my firewall, but first I checked it was offline with
sudo ufw status
Then I blocked all incoming connections and allowed all outgoing connections
sudo ufw defualt deny incoming
sudo ufw default allow outgoing
I then configured my firewall to allow HTTP on port 80, NTP on port 123, and SSH on port 2200
sudo ufw allow 2200/tcp
sudo ufw allow www
sudo ufw allow ntp
I then double checked my work, turned on the firewall and applied my changes to sshd_config
sudo ufw show added
sudo ufw enable
sudo ufw show status
sudo service sshd restart
I first created a new user named 'grader'
sudo adduser grader
I then edit the sudoers file to grant the grader user sudo access. I use the visudo command to safely do this
sudo visudo -f /etc/sudoers.d/grader
Adding this line
grader ALL=(ALL:ALL) NOPASSWD:ALL
I then went on my local machine and generated an ssh key. I named this key 'grader'
ssh-keygen
I copied the contents of "grader.pub" and went back to my linux machine where I switched to the grader user
sudo su - grader
As this user, I created a subdirectory called ".ssh" and set its permissions to only allow the grader to read write or execute
mkdir .ssh
chown grader:grader /home/grader/.ssh
chmod 700 /home/grader/.ssh
In this new directory I created a file called 'authorized_keys' and pasted in the contents of 'grader.pub'. I then set the permissions of the file to 400
sudo vim .ssh/authorized_keys
sudo chmod 400 .ssh/authorized_keys
Lastly, I disabled root login and forced key authentication by changing the file '/etc/ssh/sshd_config'. Here I changed "PermitRootLogin without-password" to "PermitRootLogin no" and uncommented the line that reads "PasswordAuthentication no" and ran "sudo service sshd restart"
I then double checked that I could login in as grader with this command
ssh -i grader.pem grader@54.245.168.69 -p 2200
There were a few steps I had to do before I could deploy the Flask app. The first was to install any packages I needed.
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install apache2 libapache2-mod-wsgi-py3
sudo apt-get install build-essential python3-dev python3-setuptools
sudo apt-get install postgresql
sudo apt-get install python3-pip
sudo apt-get install git
I then went into the postgresql command line to create a new database for my Flask app. I also made a new user that would have permission to edit the database.
sudo su - postgres
postgres $ psql;
postgres=# CREATE DATABASE itemcatalog;
postgres=# CREATE USER efren;
postgres=# ALTER ROLE efren WITH PASSWORD 'xxxxxxxxxxxxxxx';
postgres=# GRANT ALL PRIVILEGES ON DATABASE catalog TO efren;
I first run sudo a2enmod wsgi to enable the mod_wsgi
sudo a2enmod wsgi
I then go into the /var/www directory and create a ItemCatalogApp folder. I clone my repository in here, and rename it ItemCatalogApp as well. I also delete the .git folder. And rename my 'application.py' to '_init_.py'
cd /var/www
sudo mkdir ItemCatalogApp
cd ItemCatalogApp
git clone https://github.com/efrenaguilar95/Udacity-Item-Catalog.git
sudo mv Udacity-Item-Catalog ItemCatalogApp
cd ItemCatalogApp
sudo mv application.py __init__.py
sudo rm -rf .git
I then created a virtual python environment to run this app and installed all of the needed packages
sudo python3 -m virtualenv -p python3 venv
sudo chown -R username:username virtualenv
source vevn/bin/activate
pip3 install sqlalchemy
pip3 install psycopg2
pip3 install flask
pip3 install oauth2client
pip3 install requests
deactivate
Once this was done, I created the config file for the application
sudo vim /etc/apache2/sites-available/ItemCatalogApp.conf
and added the following lines:
<VirtualHost *:80>
ServerName 54.245.168.69
ServerAdmin xxxxxxxx@xxxxx
ServerAlias 54.245.168.69*
WSGIDaemonProcess ItemCatalogApp python-home=/var/www/ItemCatalogApp/venv
WSGIProcessGroup ItemCatalogApp
WSGIApplicationGroup %{GLOBAL}
WSGIScriptAlias / /var/www/ItemCatalogApp/application.wsgi
<Directory /var/www/ItemCatalogApp/ItemCatalogApp>
Order allow,deny
Allow from all
</Directory>
Alias /static /var/www/ItemCatalogApp/ItemCatalogApp/static
<Directory /var/www/ItemCatalogApp/ItemCatalogApp/static/>
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Lastly I created the file 'catalog.wsgi'
sudo vim /var/www/ItemCatalogApp/catalog.wsgi
and inserted the following lines
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,"/var/www/ItemCatalogApp/")
from ItemCatalogApp import app as application
application.secret_key = 'XXXXXXXXXXXXXXX'
Lastly, I restarted Apache, lauching my server
sudo service apache2 restart
Both of these resources were an immense help in completing this.