This is the final project for Udacity's Full Stack Web Developer Nanodegree.
This page explains how to secure and set up a Linux distribution on a virtual machine, install and configure a web and database server to host a web application.
- The Linux distribution is Ubuntu 16.04 LTS.
- The virtual private server is Amazon Lighsail.
- The web application is my Catalog project created earlier in this Nanodegree program.
You can visit http://18.194.242.199// or http://ec2-18-194-242-199.eu-central-1.compute.amazonaws.com for the website deployed.
sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
Enable automatic security updates
sudo apt-get install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
sudo timedatectl set-timezone UTC
sudo update-locale LANG=en_US.utf8 LANGUAGE=en_US.utf8 LC_ALL=en_US.utf8
sudo adduser grader
sudo nano /etc/sudoers.d/grader
Then add the following text grader ALL=(ALL) ALL
- On local machine
ssh-keygen
Then choose the path for storing public and private keys - On remote machine home as user grader
sudo su - grader
mkdir .ssh
touch .ssh/authorized_keys
sudo chmod 700 .ssh
sudo chmod 600 .ssh/authorized_keys
nano .ssh/authorized_keys
Then paste the contents of the public key created on the local machine
5. Change the SSH port from 22 to 2200 | Enforce key-based authentication | Disable login for root user
sudo nano /etc/ssh/sshd_config
Then change the following:
- Find the Port line and edit it to 2200.
- Find the PasswordAuthentication line and edit it to no.
- Find the PermitRootLogin line and edit it to no.
- Save the file and run
sudo service ssh restart
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 2200/tcp
sudo ufw allow www
sudo ufw allow ntp
sudo ufw allow 8000/tcp `serve another app on the server`
sudo ufw enable
sudo apt-get install fail2ban sendmail
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
Then Update the following:
destemail = [my email address]
action = %(action_mwl)s
[sshd]
banaction = ufw-ssh
port = 2200
Create the ufw-ssh action referenced above:
sudo nano /etc/fail2ban/action.d/ufw-ssh.conf
Add the following:
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = ufw insert 1 deny from <ip> to any app OpenSSH
actionunban = ufw delete deny from <ip> to any app OpenSSH
Finally, restart fail2ban:
sudo service fail2ban restart
sudo apt-get install apache2 libapache2-mod-wsgi-py3 git
Note: For Python2 replace libapache2-mod-wsgi-py3
with libapache2-mod-wsgi
sudo apt-get install libpq-dev python3-dev
sudo apt-get install postgresql postgresql-contrib
sudo su - postgres
psql
Then
CREATE USER catalog WITH PASSWORD 'password';
CREATE DATABASE catalog WITH OWNER catalog;
\c catalog
REVOKE ALL ON SCHEMA public FROM public;
GRANT ALL ON SCHEMA public TO catalog;
\q
exit
Note: In your catalog project you should change database engine to
engine = create_engine('postgresql://catalog:password@localhost/catalog')
cd /var/www/
sudo mkdir catalog
sudo chown grader:grader catalog
git clone <your_repo_url> catalog
cd catalog
git checkout production # If you have a diffrent branch!
nano catalog.wsgi
Then add the following in catalog.wsgi
file
#!/usr/bin/python3
import sys
sys.stdout = sys.stderr
# Add this if you'll create a virtual environment, So you need to activate it
# -------
activate_this = '/var/www/catalog/env/bin/activate_this.py'
with open(activate_this) as file_:
exec(file_.read(), dict(__file__=activate_this))
# -------
sys.path.insert(0,"/var/www/catalog")
from app import app as application
Optional but recommended: Setup virtual environment and Install app dependencies
sudo apt-get install python3-pip
sudo -H pip3 install virtualenv
virtualenv env
source env/bin/activate
pip3 install -r requirements.txt
- If you don't have
requirements.txt
file, you can use
pip3 install flask packaging oauth2client redis passlib flask-httpauth
pip3 install sqlalchemy flask-sqlalchemy psycopg2 bleach requests
Edit Authorized JavaScript origins
sudo nano /etc/apache2/sites-enabled/000-default.conf
Then add the following content:
# serve catalog app
<VirtualHost *:80>
ServerName <IP_Address or Domain>
ServerAlias <DNS>
ServerAdmin <Email>
DocumentRoot /var/www/catalog
WSGIDaemonProcess catalog user=grader group=grader
WSGIScriptAlias / /var/www/catalog/catalog.wsgi
<Directory /var/www/catalog>
WSGIProcessGroup catalog
WSGIApplicationGroup %{GLOBAL}
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
sudo service apache2 reload
sudo service apache2 restart
- Amazon EC2 Linux Instances
- Flask mod_wsgi (Apache)
- Apache Server Configuration Files
- Deploy a Flask Application on an Ubuntu VPS
- Set Up Apache Virtual Hosts on Ubuntu
- mod_wsgi documentation
- Automatic Security Updates
- Protect SSH with Fail2Ban
- UFW with Fail2ban
- Fix locale issue
- Ask Ubuntu
- Stack Overflow