Take a baseline installation of a Linux server and prepare it to host a web application. Secure the server from a number of attack vectors, install and configure a database server, and deploy an existing web applications onto it.
A deep understanding of exactly what a web application is doing, how they are hosted, and the interactions between multiple systems are what define you as a Full Stack Web Developer. In this project, the student will be responsible for turning a brand-new, bare bones, Linux server into the secure and efficient web application host.
IP address: 35.165.34.87
(Will be deactived after review)
URL: http://ec2-35-165-34-87.us-west-2.compute.amazonaws.com/
Web app is a modified version of Flask Catalog
- Python3
- Flask
- Postgresql
- Sqlalchemy
- Google OAuth2
- Requests
- Goto Amazon Lightsail
- Select Linux/Unix for Platform
- Select OS only and Ubuntu for Blueprint
- Select $5 Instance Plan
- Leave Default Name or change to customer name
- Create Instance
- Detailed directions can be found on ServerPilot for setting up a Lightsail instance.
- SSH into new Server
- Click SSH Keys from Account page
- Download default SSH key
- From terminal on local machine
- Rename download file
<filename>.pem
withmv <filename>.pem id_udacity.pub
- Move file to
.ssh
withmv lightsails_key.pem ~/.ssh
- Change file permissions with
chmod 600 ~/.ssh/id_udacity.pub
- Connect with SSH by entering
ssh -i ~/.ssh/id_udacity.pub ubunutu@35.165.34.87
- Rename download file
- Update system files/packages
sudo apt-get update
sudo apt-get upgrade
- Add new user for Grader
- Enter
sudo adduser grader
, set password and enter information requested or leave as default - Add grader as a sudo user
sudo touch /etc/sudoers.d/grader
sudo nano /etc/sudoers.d/grader
addgrader ALL=(ALL:ALL) ALL
- save- Verify grader has sudo acces
su - grader
- Enter password used during grader creation
sudo -l
- Enter password
- Output in terminal should indicate User grader may run the following commands:
(ALL:ALL) ALL
- Enter
- Create SSH key for grader access
su - grader
if not still in grader accountmkdir .ssh
sudo ssh-keygen
- Enter for file and path
.ssh/grader
- Enter password
- Enter for file and path
cat .ssh/grader.pub
copy output to clipboard- On local machine in terminal
cd ~/.ssh
touch grader.pub
- Using editor of choice pasts contents of clipboard into grader.pub
chmod 600 grader.pub
- Test new SSH key
- From new termainal window/tab on local machine enter
ssh -i ~/.ssh/grader.pub grader@35.165.34.87 -p 2200
- New SSH session should have command prompt
grader@<IP-ADDRESS>
- From new termainal window/tab on local machine enter
- This is the key that can be provided to Udacity Grader to access grader account
- Setup configuration for Uncomplicated Firewall
- Change sshd_config for port 2200 with
sudo nano /etc/ssh/sshd_config
edit Port 22 to Port 2200 sudo ufw allow 80/tcp
sudo ufw allow 2200/tcp
sudo ufw allow 123/upd
sudo ufw enable
sudo ufw status
to check open ufw ports- If needed
sudo ufw delete deny 22/tcp
- In Lightsails admin panel add port 2200 Customer TCP
sudo service ssh restart
to make changes to SSH active
- Change sshd_config for port 2200 with
- Change local timezone to UTC
sudo dpkg-reconfigure tzdata
select None of the Above then UTC
- Install packages needed for Flask App with Postgresql
sudo apt-get install apache2
sudo apt-get install postgresql
sudo apt-get install git
sudo apt-get install libapache2-mod-wsgi-py3
pip install flask
pip install sqlalchemy
pip install requests
pip install oauth2client
pip install psycopg2
- Configure Apache
- Check in browser
35.165.34.87
that default Apache2 page displays - sudo touch /etc/apache2/sites-available/FlaskApp.conf
- sudo nano /etc/apache2/sites-available/App.conf paste in
- Check in browser
<VirtualHost *:80>
ServerName 35.165.34.87
ServerAdmin chillieguy@live.com
WSGIScriptAlias / /var/www/Catalog/app.wsgi
<Directory /var/www/Catalog/App/>
Order allow,deny
Allow from all
</Directory>
Alias /static /var/www/Catalog/App/static
<Directory /var/www/Catalog/App/static/>
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
- Configure .wsgi
cd /var/www/Catalog
sudo touch app.wsgi
sudo nano app.wsgi
and paste in
#!/usr/bin/python
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,"/var/www/Catalog/")
from App import app as application
application.secret_key = '<ENTER A SECRET KEY>'
- Enable Virtual Host and Restart Apache
sudo a2ensite App
sude service apache2 restart
- Setup Postgresql
sudo cat /etc/postgresql/9.5/main/pg_hba.conf
to check that Postgresql does not allow remote connections.- Login to postgres with
su - postgres
- Start Postgresql cli with
psql
- Create new database
CREATE DATABASE catalog;
- Create new user
CREATE USER catalog;
- With password
ALTER ROLE catalog WITH PASSWORD 'password';
- Allow user catalog to access catalog database
GRANT ALL PRIVILEGES ON DATABASE catalog TO catalog;
- Create table(alternatively can be done in database_setup.py file)
CREATE TABLE 'user'
CREATE TABLE 'item'
CREATE TABLE 'catalog'
- Changes for Google Oauth2
- In developer console add to Authorized redirect URIs
http://ec2-35-165-34-87.us-west-2.compute.amazonaws.com/login
http://ec2-35-165-34-87.us-west-2.compute.amazonaws.com/gconnect
- Add to client_secrets.json
http://ec2-35-165-34-87.us-west-2.compute.amazonaws.com/login
http://ec2-35-165-34-87.us-west-2.compute.amazonaws.com/gconnect
- In app.py change
result = json.loads(h.request(url, 'GET')[1])
toresult = json.loads(h.request(url, 'GET')[1].decode('utf-8))
to fix byte to str error
- In developer console add to Authorized redirect URIs
- Disable default Apache2 site
sudo a2dissite 000-default.conf
- Install Fail2Ban
sudo apt-get install fail2ban
sudo apt-get install sendmail
- for mail notificationssudo apt-get install iptables-persistent
- Update jail.local with settings below -
sudo nano etc/fail2ban/jail.local
sudo service fail2ban stop
sudo service fail2ban start
set bantime = 600
destemail = useremail@domain
action = %(action_mwl)s
under [ssh] change port = 2220
- Restart Apache2
sudo service apache2 restart