Using a baseline installation of a Linux server and preparing it to host my web application. This includes securing it against a number of attack vectors, installing and configuring a database server and deploying a handmade web application. The steps reflect the steps recorded in the Project Details section from Udacity.
I began by creating a new server instance through Amazon Lightsail. I followed the instructions to SSH into my newly created server. Until specified, all the commands are issued from the browser console on the AWS site.
IP Address: 18.218.28.108
PORT: 2200
SSH Key: I included the private key in the "Notes to Reviewer" section when I submitted my project.
I first updated all my currently installed packages by running the command:
$ sudo apt-get update
After it had fetched the details, I retrieved thos updates using:
$ sudo apt-get udgrade
I changed the SSH port on my instance from 22 to 2200 using the 'sudo nano' command. The SSH configuration is found in /etc/ssh/sshd_config.
$ sudo nano /etc/ssh/sshd_config
Inside the file I simply changed the port number to reflect the necessary change.
Then I began to configure my UFW. First I verified that my firewall was inactive by running:
$ sudo ufw status
Then I blocked all incoming and allowed all outgoing connections using:
$ sudo ufw default deny incoming
and
$ sudo ufw allow outgoing
In order to configure the UFW to allow the necessary connections, I had to run the following series of commands. They made allowances for SSH on port 2200, HTTP on port 80, and NTP on port 123.
$ sudo ufw allow 2200/tcp
$ sudo ufw allow www
$ sudo ufw allow ntp
After words, I ran $ sudo ufw show added
to check the rules I'd made, followed by $ sudo ufw enable
turning on the firewall, and $ sudo ufw status
to check the status of the enabled firewall.
I created a new user named grader.
$ sudo adduser grader
I had to edit the sudoers file in order to grant grader access to the sudo
command. Add the line grader ALL=(ALL:ALL) ALL
to the file /etc/sudoers.d/grader.
$ sudo nano /etc/sudoers.d/grader
In order to log into the grader user on the server instance from the command line, it is necessary to generate a key pair either locally or through the Lightsail terminal. According to the Udacity specifications, I generated them locally (IN MY TERMINAL NOW) by first creating a '.ssh' directory to store the keys. I had to make my vagrant user the owner and vagrant the group in order to make the files private enough to meet the Amazon security policy. Then after changing into that newly created directory, I generated a key pair using the keygen command. These commands were issued from inside a vagrant machine on my local command line within the '/home/vagrant' directory.
/home/vagrant $ mkdir .ssh
/home/vagrant $ chown vagrant:vagrant /home/vagrant/.ssh
/home/vagrant $ cd .ssh
/home/vagrant/.ssh $ ssh-keygen
Running the ssh-keygen
command will prompt the user for a file in which to save the newly created keys. I named the file 'grader'. This resulted in the creation of both 'grader' and 'grader.pub'. I renamed 'grader' to 'grader.pem' to remove any confusion about which file was the public and which was the private.
$ mv grader grader.pem
Then I read the contents of the 'grader.pub' file in order to copy them and then jumped back to my Lightsail instance.
$ sudo nano grader.pub
In my instance (accessed through the browser console) I then switched into the grader user-- $ sudo su - grader
--and created a subdirectory called '.ssh' and set the owner to the grader user and set the permission to read write and execute only to the grader user.
$ mkdir .ssh
$ chown grader:grader /home/grader/.ssh
$ chmod 700 /home/grader/.ssh
I then 'cd'ed into the '.ssh' directory and created a file called 'authorized_keys', used sudo nano
to edit the 'authorized_keys' file and inserted the copied 'grader.pub' contents. I set the permissions of the file to 400.
$ sudo nano /.ssh
$ sudo chmod 400 /.ssh/authorized_keys
Back in my terminal I verified that I could now log in to the instance as grader from my local machine. I had to specify the port because of my firewall and ssh configuration from earlier.
$ ssh -i grader.pem [email protected] -p 2200
Once I was logged in, I completed the rest of the steps from my terminal while logged in to my instance as grader.
I needed to disable root login and force authentication using the key pair, so in the file '/etc/ssh/sshd_config' I changed "PermitRootLogin without-password" to "PermitRootLogin no" and uncommented the line that reads "PasswordAuthentication no". I ran $ sudo service ssh restart
The instance timezone was already set to UTC, but to verify I ran $ sudo dpkg-reconfigure tzdata
Install Apache and the libapache2-mod-wsgi, and the python set up tools packages and then restarted the Apache service.
$ sudo apt-get install apache2
$ sudo apt-get install libapache2-mod-wsgi
$ sudo apt-get install python-setuptools
$ sudo service apache2 restart
I installed PostgreSQL and then opened the file '/etc/postgresql/9.5/main/pg_hba.conf' to ensure that remote connections weren't allowed.
$ sudo apt-get install postgresql
$ sudo nano /etc/postgresql/9.5/main/pg_hba.conf
I then switched to the postgres user and switched into the interactive postgres mode. Within the interactive prompt I created a new database and user both named catalog and set the password to catalog. I then gave the catalog user permission to use the catalog database and used ctrl+z to exit the prompt.
$ sudo su - postgres
postgres $ psql
postgres=# CREATE DATABASE catalog;
# CREATE USER catalog;
# ALTER ROLE catalog WITH PASSWORD 'catalog'
# GRANT ALL PRIVILEGES ON DATABASE catalog TO catalog;
In order to clone my remote repository I needed to install git within my instance so I ran $ sudo apt-get install git
Following the guidance of the Digital Ocean article linked below (in the Acknowledgements section) I ran $ sudo a2enmod wsgi
to enable the mod_wsgi. Then I changed into the /var/www directory, created a 'catalog' directory, changed into that directory and created yet another 'catalog' directory and changed to be inside of the nested catalog directory.
$ cd /var/www
/var/www $ mkdir catalog
/var/www $ cd catalog
/var/www/catalog $ mkdir catalog
/var/www/catalog $ cd catalog
Into that directory I cloned my GitHub item catalog project, renamed 'views.py' 'init.py', changed the url inside the create_engine calls in both the 'models.py' and 'init.py' to reflect the use of PostgreSQL: "create_engine('postgresql://catalog:catalog@localhost/catalog')". Lastly I installed psycopg2 using $ sudo apt-get install python-psycopg2
and python $ sudo apt-get install python
$ git clone https://github.com/kotamichael/catalog.git
$ sudo mv views.py __init__.py
$ sudo nano models.py
$ sudo nano __init__.py
I then created '/etc/apache2/sites-available/catalog.conf' $ sudo nano /etc/apache2/sites-available/catalog.conf
and inserted the following lines:
<VirtualHost *:80>
ServerName 18.218.28.108
ServerAdmin [email protected]
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>
I then changed to the '/var/www/catalog' directory and created and edited the 'catalog.wsgi' file:
#!/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'
Afterwards I restarted Apache $ sudo service apache2 restart
and added my path to the Google Developers console under Credentials/Authorized Javascript Origins.