Sixth and final project of Udacity's Full Stack Web Developer Nanodegree program
The Linux Server Configuration project consists of configuring a secure Ubuntu server to host a Python Flask app using Amazon Lightsail with PostgreSQL as the database.
The app develops a CRUD application that provides a list of items within a variety of categories, as well as provide a user registration and authentication system.
- Python 2.7.12
- Flask - http://flask.pocoo.org
- SQLAlchemy - http://www.sqlalchemy.org
- OAuth 2.0 Client - http://github.com/google/oauth2client
Create an account at https://aws.amazon.com/lightsail/ and setup you instance. Choose the plain Ubuntu Linux image, and "OS Only" and choose Ubuntu as the operating system. For the instance plan, the lowest tier of $3.50 per month is good with the first 30 days free. Name the instance and then create it.
Connect to your instance from the AWS browser-based ssh client using the Connect using SSH
button and run commands: sudo apt-get update
and sudo apt-get upgrade
Connect using the Connect using SSH
button on your account page and only allow incoming connections for SSH (Port 2200), HTTP (Port 80), and NTP (Port 123):
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 enable
sudo ufw status
On your local machine edit the sshd_config file and change port to 2200: sudo nano /etc/ssh/sshd_config
Download the ssh key (.pem file) from your account page and store it in /user/.ssh/
on your local machine. Open a terminal on your local machine and enter ssh -i ~/.ssh/LightsailDefaultPrivateKey-us-east-1.pem -p 2200 ubuntu@52.207.68.245
to connect to your instance. Now you can disable port 22: sudo ufw deny 22
Connect to your instance and enter command: sudo adduser grader
Create grader file in directory sudo nano /etc/sudoers.d/grader
and type grader ALL=(ALL) NOPASSWD:ALL
to grant grader sudo permissions.
On your local machine create a new key pair using command ssh-keygen
Save the key pair in /user/ssh/
directory.
On your local machine, enter command cat .ssh/keyPairName.pub
and your public key will be outputted. Copy it.
Connect to your server, make directory .ssh mkdir .ssh
and create authorized_keys file touch .ssh/authorized_keys
in that directory which will have 1 line for each public key you want to authorize. Open the file nano .ssh/authorized_keys
and paste in the public key you copied from your local machine and save.
chmod 700 /home/grader/.ssh
chmod 644 /home/grader/.ssh/authorized_keys
ssh -i ~/.ssh/keyPairName -p 2200 grader@52.207.68.245
sudo timedatectl set-timezone UTC
sudo apt-get install libapache2-mod-wsgi
sudo apt-get install postgresql
To disable remote connections enter sudo nano /etc/ssh/sshd_config
and change PermitRootLogin to PermitRootLogin no
and the PasswordAuthentication to PasswordAuthentication no
Then restart SSH service sudo service ssh restart
sudo -u postgres createuser -P catalog
sudo -u postgres createdb -O catalog catalog
sudo apt-get install git
Clone app from GitHub and make .git inaccessible
cd /var/www
sudo mkdir catalog
cd /var/www/catalog
sudo mkdir catalog
git clone https://github.com/basant1/item-catalog.git catalog
sudo nano .htaccess
Add line RedirectMatch 404 /\.git
- Change all instances where sqlite database engine is being used to
engine = create_engine('postgresql://catalog:my_password@localhost/catalog')
- To change project.py file name to init.py cd into the directory where the file is located and do
sudo mv application.py __init.py__
- Update the absolute path for all references to client_secrets.json which will now be
/var/www/catalog/catalog/client_secrets.json
sudo apt-get install python-pip
sudo pip install virtualenv
virtualenv -p /usr/bin/python2.7 my_env
source my_env/bin/activate
In your virtual environment run the following commands:
sudo pip install flask
sudo pip install oauth2client
sudo pip install sqlalchemy
sudo pip install requests
sudo pip install httplib2
sudo pip install psycopg2
Add .xip.io at the end of your authorized urls in the Google Developers Console credentials page so in this case it will be http://52.207.68.245.xip.io
sudo nano /etc/apache2/sites-available/catalog.conf
and add the following the code:
<VirtualHost *:80>
ServerName http://52.207.68.245/
ServerAlias HOSTNAME http://52.207.68.245/
ServerAdmin grader@52.207.68.245
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>
Save and close the file.
Enable the virtual host with the following command:
sudo a2ensite catalog
cd /var/www/catalog
sudo nano catalog.wsgi
and add the following code:
#!/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 = 'super_secret_key'
Now your directory structure should look like this:
|--------catalog
|----------------catalog
|-----------------------static
|-----------------------templates
|-----------------------venv
|-----------------------__init__.py
|----------------catalog.wsgi
sudo service apache2 restart
View the app at http://52.207.68.245.xip.io/