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.
- The web application is my Item Catalog project created earlier in this Nanodegree program.
- The database server is PostgreSQL.
You can visit http://54.161.86.157/ or http://ec2-54-161-86-157.compute-1.amazonaws.com/ for the website deployed.
- Login to aws.amazon.com and login to default user (ubuntu)
- Choose EC2 and Launch Instance with appropriate settings.
- Check for instance IPv4 public IP - 54.161.86.157
- we can download a .pem file and connect with following command
ssh -i ItemCatalog_19_01_2019.pem ubuntu@54.161.86.157 - 22 is Port by Default,Later we need to change it to 2200 as per the udacity-linux-server-configuration rubrics.
sudo apt-get update
sudo apt-get upgrade
- Edit the
/etc/ssh/sshd_configfile:sudo vi /etc/ssh/sshd_config. - Change the port number on line 5 from
22to2200. - Save and exit using esc and confirm with :wq.
- Restart SSH:
sudo service ssh restart. - Change inbound rules in Amazon EC2 --> Type : Custom TCP Rule as 2200
- To check port 2200 wether working or not by
ssh -i ItemCatalog_19_01_2019.pem -p 2200 ubuntu@54.161.86.157
-
Configure the default firewall for Ubuntu to only allow incoming connections for SSH (port 2200), HTTP (port 80), and NTP (port 123).
sudo ufw status # The UFW 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. sudo ufw allow www # Allow HTTP traffic in. sudo ufw allow 123/udp # Allow incoming udp packets on port 123. sudo ufw deny 22 # Deny tcp and udp packets on port 53. -
Turn UFW on:
sudo ufw enable. The output should be like this:Command may disrupt existing ssh connections. Proceed with operation (y|n)? y Firewall is active and enabled on system startup -
Check the status of UFW to list current roles:
sudo ufw status. The output should be like this:Status: active To Action From -- ------ ---- 2200/tcp ALLOW Anywhere 80/tcp ALLOW Anywhere 123/udp ALLOW Anywhere 22 DENY Anywhere 2200/tcp (v6) ALLOW Anywhere (v6) 80/tcp (v6) ALLOW Anywhere (v6) 123/udp (v6) ALLOW Anywhere (v6) 22 (v6) DENY Anywhere (v6)
- While logged in as
ubuntu, add user:sudo adduser grader. - Enter a password (twice) and fill out information for this new user.
-
Edits the sudoers file:
sudo visudo. -
Search for the line that looks like this:
root ALL=(ALL:ALL) ALL -
Below this line, add a new line to give sudo privileges to
graderuser.root ALL=(ALL:ALL) ALL grader ALL=(ALL:ALL) ALL -
Save and exit using CTRL+X and confirm with Y.
-
Verify that
graderhas sudo permissions. Runsu - grader, enter the password.
-Configure key-based authentication for grader user
- create .ssh folder by
mkdir /home/grader/.ssh - Run this command
cp /home/ubuntu/.ssh/authorized_keys /home/grader/.ssh/authorized_keys - change ownership
chown grader.grader /home/grader/.ssh - add 'grader' to sudo group
usermod -aG sudo grader - change permissions for .ssh folder
chmod 0700 /home/grader/.ssh/, for authorized_keyschmod 644 authorized_keys - Check in
vi /etc/ssh/sshd_configfile ifPermitRootLoginis set tono - Restart SSH:
sudo service ssh restart - On the local machine, cheking if the grader account working or not by running this command :
ssh -i ItemCatalog_19_01_2019.pem -p 2200 grader@54.161.86.157.
- While logged in as
grader, configure the time zone:sudo dpkg-reconfigure tzdata. Choose time zone UTC.
- While logged in as
grader, install Apache:sudo apt-get install apache2. - Enter public IP of the Amazon EC2 instance into browser. Check Apache is working or not by executing public IP.
- My project is built with Python 3. So, I need to install the Python 3 mod_wsgi package:
sudo apt-get install libapache2-mod-wsgi-py3. - Enable
mod_wsgiusing:sudo a2enmod wsgi.
sudo apt-get install libpq-dev python-devsudo apt-get install postgresql postgresql-contribsudo su - postgrespsqlCREATE USER catalog WITH PASSWORD 'catalog';ALTER USER catalog CREATEDB;CREATE DATABASE catalog WITH OWNER catalog;\c catalogREVOKE ALL ON SCHEMA public FROM public;GRANT ALL ON SCHEMA public TO catalog;\qexit- Switch back to the
graderuser:exit.
- While logged in as
grader, installgit:sudo apt-get install git.
- While logged in as
grader, - From the
/var/wwwdirectory, Clone the catalog project:
sudo git clone https://github.com/SkBadulla/catalog.git. - Change the ownership of the
catalogdirectory tograderusing:sudo chown -R grader:grader catalog/. - Change to the
/var/www/catalog/catalogdirectory. - Rename the
mainpage.pyfile to__init__.pyusing:mv mainpage.py __init__.py. - We need to change sqlite to postgresql create_engine in
__init__.py,db_setup.pyanddb_init.py,# engine = create_engine("sqlite:///catalog.db") engine = create_engine('postgresql://catalog:catalog@localhost/catalog')
- Go to Google Cloud Plateform.
- Click
APIs & serviceson left menu. - Click
Credentials. - Create an OAuth Client ID (under the Credentials tab), and add http://54.161.86.157.xip.io and http://ec2-54-161-86-157.compute-1.amazonaws.com/ as authorized JavaScript origins.
- Add http://54.161.86.157.xip.io/login,http://54.161.86.157.xip.io/gconnect,http://54.161.86.157.xip.io/callback as authorized redirect URI.
- Download the corresponding JSON file, open it and copy the contents.
- Open
/var/www/catalog/catalog/client_secrets.jsonand paste the previous contents into the this file. - Replace the client ID
templates/login.htmlfile in the project directory.
- While logged in as
grader, install pip:sudo apt-get install python3-pip. - Install the virtual environment:
sudo apt-get install python-virtualenv - Change to the
/var/www/catalog/catalog/directory. - Create the virtual environment:
sudo virtualenv -p python3 venv3. - Change the ownership to
graderwith:sudo chown -R grader:grader venv3/. - Activate the new environment:
. venv3/bin/activate. - Install the following dependencies:
pip install httplib2 pip install requests pip install --upgrade oauth2client pip install sqlalchemy pip install flask sudo apt-get install libpq-dev pip install psycopg2-binary
Configure and enable a new virtual host
- Run this:
sudo vi /etc/apache2/sites-available/catalog.conf - Paste this code:
<VirtualHost *:80>
ServerName 54.161.86.157.xip.io
ServerAlias ec2-54-161-86-157.compute-1.amazonaws.com
ServerAdmin ubuntu@54.161.86.157
WSGIDaemonProcess catalog python-path=/var/www/catalog:/var/www/catalog/catalog/venv3/lib/python3.6/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>
- Enable the virtual host
sudo a2ensite catalog
Enabling site catalog. To activate the new configuration, you need to run: service apache2 reload
- Reload Apache:
sudo service apache2 reload.
-
Create
/var/www/catalog/catalog.wsgifile add the following lines: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 = 'supersecretkey' -
Restart Apache:
sudo service apache2 restart. -
From the
/var/www/catalog/catalog/directory, activate the virtual environment:. venv3/bin/activate. -
Run:
python db_setup.py. -
Deactivate the virtual environment:
deactivate.
-
Disable the default Apache site:
sudo a2dissite 000-default.conf. The following prompt will be returned:Site 000-default disabled. To activate the new configuration, you need to run: service apache2 reload -
Reload Apache:
sudo service apache2 reload.
- Restart Apache again:
sudo service apache2 restart. - Open your browser to http://54.161.86.157 or http://ec2-54-161-86-157.compute-1.amazonaws.com.
The unattended-upgrades package can be used to automatically install important system updates.
- Enable automatic (security) updates:
sudo apt-get install unattended-upgrades. - Edit
/etc/apt/apt.conf.d/50unattended-upgrades, uncomment the line${distro_id}:${distro_codename}-updatesand save it. - Modify
/etc/apt/apt.conf.d/20auto-upgradesfile so that the upgrades are downloaded and installed every day:APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Download-Upgradeable-Packages "1"; APT::Periodic::AutocleanInterval "7"; APT::Periodic::Unattended-Upgrade "1"; - Enable it:
sudo dpkg-reconfigure --priority=low unattended-upgrades. - Restart Apache:
sudo service apache2 restart.
- To get log messages from Apache server:
sudo tail /var/log/apache2/error.log. - To restart Apache:
sudo service apache2 restart.
- DigitalOcean How To Deploy a Flask Application on an Ubuntu VPS
- GitHub Repositories
Special Thanks to Alain Boisvert for a very helpful README in Linux Server Configuration Project-Udacity*