##Linux Server Configuration 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 Movie Item project created earlier in this Nanodegree program.
- The database server is PostgreSQL.
You can visit http://35.183.64.11 or ehttp://ec2-35-183-64-11.ca-central-1.compute.amazonaws.com for the website deployed.
ssh port is currently set to default port 2200
- Login into Amazon Lightsail using an Amazon Web Services account.
- Choose
Linux/Unix
platform,OS Only
andUbuntu 16.04 LTS
. - Choose a instance plan (I took the cheapest, $5/month).
- Keep the default name provided by AWS or rename your instance.
- Click the
Create
button to create the instance. - Wait for the instance to start up.
- From the
Account
menu on Amazon Lightsail, click onSSH keys
tab and download the Default Private Key. - Move this private key file named
LightsailDefaultPrivateKey-*.pem
into the local folder~/.ssh
and rename itudacity.rsa
. - In your terminal, type:
chmod 600 ~/.ssh/udacity.rsa
. - To connect to the instance via the terminal:
ssh -i ~/.ssh/udacity.rsa [email protected]
, where35.183.64.11
is the public IP address of the instance.
sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-updgrade
- Edit the
/etc/ssh/sshd_config
file:sudo nano /etc/ssh/sshd_config
. - Change the port number on line 5 from
22
to2200
. - Save and exit using CTRL+X and confirm with Y.
- Restart SSH:
sudo service ssh restart
.
-
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)
-
Exit the SSH connection:
exit
. -
Click on the
Manage
option of the Amazon Lightsail Instance, then theNetworking
tab, and then change the firewall configuration to match the internal firewall settings above. -
Allow ports 80(TCP), 123(UDP), and 2200(TCP), and deny the default port 22.
-
From your local terminal, run:
ssh -i ~/.ssh/udacity.rsa -p 2200 [email protected]
, where35.183.64.11
is the public IP address of the instance.
-
I did these commands:
sudo apt-get update sudo apt-get dist-upgrade sudo shutdown -r now
-
Logged back in, and I now see this message:
Alains-MBP:udacity-linux-server-configuration boisalai$ ssh -i ~/.ssh/udacity.rsa -p 2200 [email protected] Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-1039-aws x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage Get cloud support with Ubuntu Advantage Cloud Guest: http://www.ubuntu.com/business/services/cloud 0 packages can be updated. 0 updates are security updates. Last login: Tue Oct 31 06:35:28 2017 from 24.201.154.77 ubuntu@ip-172-26-0-7:~$
Reference
- DigitalOcean, Updating Ubuntu 14.04 -- Security Updates.
- While logged in as
ubuntu
, add user:sudo adduser grader
. - Enter a password (twice) and fill out information for this new user(optional).
-
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
grader
user.root ALL=(ALL:ALL) ALL grader ALL=(ALL:ALL) ALL
-
Save and exit using CTRL+X and confirm with Y.
-
Verify that
grader
has sudo permissions. Runsu - grader
, enter the password, runsudo -l
and enter the password again. The output should be like this:Matching Defaults entries for grader on ip-172-26-13-170.us-east-2.compute.internal: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin User grader may run the following commands on ip-172-26-13-170.us-east-2.compute.internal: (ALL : ALL) ALL
Resources
- DigitalOcean, How To Add and Delete Users on an Ubuntu 14.04 VPS
- On the local machine:
- Run
ssh-keygen
- Enter file in which to save the key (I gave the name
grader_key
) in the local directory~/.ssh
- Enter in a passphrase twice. Two files will be generated (
~/.ssh/grader_key
and~/.ssh/grader_key.pub
) - Run
cat ~/.ssh/grader_key.pub
and copy the contents of the file - Log in to the grader's virtual machine
- Run
- On the grader's virtual machine:
- Create a new directory called
~/.ssh
(mkdir .ssh
) - Run
sudo nano ~/.ssh/authorized_keys
and paste the content into this file, save and exit - Give the permissions:
chmod 700 .ssh
andchmod 644 .ssh/authorized_keys
- Check in
/etc/ssh/sshd_config
file ifPasswordAuthentication
is set tono
- Restart SSH:
sudo service ssh restart
- Create a new directory called
- On the local machine, run:
ssh -i ~/.ssh/grader_key -p 2200 [email protected]
.
-
While logged in as
grader
, install Apache:sudo apt-get install apache2
. -
Enter public IP of the Amazon Lightsail instance into browser. If Apache is working, you should see:
-
My project is built with Python 2. So, I need to install the Python 2 mod_wsgi package:
sudo apt-get install libapache2-mod-wsgi-py
. -
Enable
mod_wsgi
using:sudo a2enmod wsgi
.
-
While logged in as
grader
, install PostgreSQL:sudo apt-get install postgresql
. -
PostgreSQL should not allow remote connections. In the
/etc/postgresql/9.5/main/pg_hba.conf
file, you should see:local all postgres peer local all all peer host all all 127.0.0.1/32 md5 host all all ::1/128 md5
-
Switch to the
postgres
user:sudo su - postgres
. -
Open PostgreSQL interactive terminal with
psql
. -
Create the
catalog
user with a password and give them the ability to create databases:postgres=# CREATE ROLE catalog WITH LOGIN PASSWORD 'catalog'; postgres=# ALTER ROLE catalog CREATEDB;
-
List the existing roles:
\du
. The output should be like this:List of roles Role name | Attributes | Member of -----------+------------------------------------------------------------+----------- catalog | Create DB | {} postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
-
Exit psql:
\q
. -
Switch back to the
grader
user:exit
. -
Create a new Linux user called
catalog
:sudo adduser catalog
. Enter password and fill out information. -
Give to
catalog
user the permission to sudo. Run:sudo visudo
. -
Search for the lines that looks like this:
root ALL=(ALL:ALL) ALL grader ALL=(ALL:ALL) ALL
-
Below this line, add a new line to give sudo privileges to
catalog
user.root ALL=(ALL:ALL) ALL grader ALL=(ALL:ALL) ALL catalog ALL=(ALL:ALL) ALL
-
Save and exit using CTRL+X and confirm with Y.
-
While logged in as
catalog
, create a user 'grader': `CREATE USER catalog WITH PASSWORD [password];.postgres=# ALTER USER catalog CREATEDB; postgres=# CREATE DATABASE catalog with OWNER catalog; postgres=# \c catalog catalog=# REVOKE ALL ON SCHEMA public FROM public; catalog=# GRANT ALL ON SCHEMA public TO catalog;
-
Exit psql:
\q
. -
Switch back to the
grader
user:exit
.
- While logged in as
grader
, installgit
:sudo apt-get install git
.
-
While logged in as
grader
, create/var/www/catalog/
directory. -
Change to that directory and clone the catalog project:
sudo git clone https://github.com/boisalai/udacity-catalog-app.git catalog
. -
From the
/var/www
directory, change the ownership of thecatalog
directory tograder
using:sudo chown -R grader:grader catalog/
. -
Change to the
/var/www/catalog/catalog
directory. -
Rename the
application.py
file to__init__.py
using:mv application.py __init__.py
. -
In
__init__.py
, replace line 27:# app.run(host="0.0.0.0", port=5000, debug=False) app.run()
-
In
database.py
, replace line 9:# engine = create_engine("sqlite:///catalog.db") engine = create_engine('postgresql://catalog:PASSWORD@localhost/catalog')
- Go to Google Cloud Plateform.
- Click
APIs & services
on left menu. - Click
Credentials
. - Create an OAuth Client ID (under the Credentials tab), and add http://13.59.39.163 and http://ec2-35-183-64-11.ca-central-1.compute.amazonaws.com as authorized JavaScript origins.
- Add http://ec2-35-183-64-11.ca-central-1.compute.amazonaws.com/oauth2callback as authorized redirect URI.
- Download the corresponding JSON file, open it and copy the contents.
- Open
/var/www/catalog/catalog/client_secret.json
and paste the previous contents into the this file. - Replace the client ID to line 25 of the
templates/login.html
file in the project directory.
-
While logged in as
grader
, install pip:sudo apt-get install python-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 python venv
. -
Change the ownership to
grader
with:sudo chown -R grader:grader venv/
. -
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
-
Run
python __init__.py
and you should see:* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
-
Deactivate the virtual environment:
deactivate
.
-
Create
/etc/apache2/sites-available/catalog.conf
and add the following lines to configure the virtual host:<VirtualHost *:80> ServerName 35.183.64.11 ServerAlias ec2-35-183-64-11.ca-central-1.compute.amazonaws.com 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 virtual host:
sudo a2ensite catalog
. The following prompt will be returned: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.wsgi
file add the following lines:activate_this = '/var/www/catalog/catalog/venv/bin/activate_this.py' with open(activate_this) as file_: exec(file_.read(), dict(__file__=activate_this)) #!/usr/bin/python import sys import logging logging.basicConfig(stream=sys.stderr) sys.path.insert(0, "/var/www/catalog/catalog/") sys.path.insert(1, "/var/www/catalog/") from catalog import app as application application.secret_key = "SUPER_SECTET_KEY"
-
Restart Apache:
sudo service apache2 restart
.
-
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
.
- Change the ownership of the project directories:
sudo chown -R www-data:www-data catalog/
. - Restart Apache again:
sudo service apache2 restart
. - Open your browser to http://35.183.64.11 or http://ec2-35-183-64-11.ca-central-1.compute.amazonaws.com
Reference
- mulligan121, Udacity Linux Configuration.
- boisalai, [Udacity linux Config] (https://github.com/boisalai/udacity-linux-server-configuration/blob/master/README.md)