You will take a baseline installation of a Linux server and prepare it to host your web applications. You will secure your server from a number of attack vectors, install and configure a database server, and deploy one of your existing web applications onto it.
-
Create EC2 instance.
-
First check for Updates of the Packages then upgrade them.
$ sudo apt-get update
$ sudo apt-get upgrade
-
Install package finger. 📦
$ sudo apt-get install finger
-
Restart the Server.
$ sudo reboot
-
Create new User grader (I created password: grader).
$ sudo adduser grader
-
Create file in given directory with name (grader).
$ sudo touch /etc/sudoers.d/grader
-
Set sudo permissons for the new user (grader).
$ sudo nano /etc/sudoers.d/grader
- Type:
$ grader ALL=(ALL) NOPASSWD:ALL
- Type 'ctrl-o' to save.
- Type 'ctrl-x' to exit.
- Type:
-
Now login to user grader.
$ sudo su grader
-
Setup ssh-key based ssh login.
- Generate SSH Key on local Machine.
$ ssh-keygen -t rsa -b 4096 -C [email protected]
- Note the filename and file location used (I used the default that was created at .ssh/id_rsa).
- When prompted, create passphrase for ssh key (I created passphrase:
grader
for this instance).
- Generate SSH Key on local Machine.
-
Copy public key from local machine to virtual machine.
- Make new directory after login to the grader.
$ sudo mkdir .ssh
- Create file authorized_keys in .shh directory.
$ sudo touch .ssh/authorized_keys
- Edit authorized_keys.
$ sudo nano .ssh/authorized_keys
- Copy public key from local machine (.ssh/id_rsa.pub) and paste into .ssh/authorized_keys file on virtual machine.
- Make new directory after login to the grader.
-
Set file permissions. 📜
$ sudo chmod 700 .ssh
$ sudo chmod 644 .ssh/authorized_keys
-
Set Owner/Group to user grader.
$ sudo chown grader .ssh
$ sudo chgrp grader .ssh
$ sudo chown grader .ssh/authorized_keys
$ sudo chgrp grader .ssh/authorized_keys
-
Restart SSH service.
$ sudo service ssh restart
-
Login command from Local Machine. 💻
$ ssh grader@<public-ip> -i .ssh/id_rsa
-
Forcing Key Based Authentication. 🔑
$ sudo nano /etc/ssh/sshd_config
- Change: PasswordAuthentication to no.
- Type 'ctrl-o' to save.
- Type 'ctrl-x' to exit.
-
Configure Firewall. 🔐
- Enter the following commands to configure defaults:
$ sudo ufw default deny incoming
$ sudo ufw default allow outgoing
- Enter the following to allow only specified ports:
$ sudo ufw allow ssh
$ sudo ufw allow 2200/tcp
$ sudo ufw allow 80/tcp
$ sudo ufw allow 123/udp
$ sudo ufw allow 443/tcp
- Enable Firewall and make sure port 22 is disabled:
-
sudo nano /etc/ssh/sshd_config
to open editor and change port number from 22 to 2200, set PermitRootLogin to no. -
$ sudo ufw deny 22
-
$ sudo ufw status
-
$ sudo ufw enable
-
$ sudo service ufw restart
Note: If using Amazon EC2, Amazon also applies a firewall, need to make sure the same ports are enabled in the Amazon console as well.
-
- Enter the following commands to configure defaults:
-
So we can access the server locally by downloading the SSH key pairs provided inside AWS account and then run:
$ ssh ubuntu@<public-ip> -i .ssh/LightsailDefaultPrivateKey-eu-central-1.pem -p 2200
-
But now login as user grader locally run: 💻
$ ssh grader@<public-ip> -i .ssh/id_rsa -p 2200
-
Configure Linux timezone to UTC. 🕓
- Open linux time zone configuration:
$ sudo dpkg-reconfigure tzdata
- Navigate to and Select None of the above
- Navigate to and Select UTC
- Open linux time zone configuration:
-
Install apache2, wsgi, postgresql, git, python and other dependencies: 🔃 📦
$ sudo apt-get install git
$ sudo apt-get install python-pip
$ sudo apt-get install apache2
$ sudo apt-get install libapache2-mod-wsgi-py3
$ sudo apt-get install postgresql
$ sudo pip install --upgrade pip
$ sudo pip install flask
$ sudo pip install SQLAlchemy
$ sudo pip install oauth2client
$ sudo pip install passlib
$ sudo pip install requests
$ sudo pip install psycopg2
-
Clone Build-an-item-catalog-application repository. 🌀
- Change the directory.
$ cd /var/www
- Inside that directory run:
$ sudo git clone https://github.com/FixEight/udacity-buid-an-item-catalog-application.git catalog
- Get inside the clone repository.
$ cd /var/www/catalog
- Change the directory.
-
Create new project.wsgi file inside the downloaded repository which will serve my flask application.
$ sudo touch /var/www/catalog/project.wsgi
- Edit the file and add the follwing contents:
-
$ sudo nano /var/www/catalog/project.wsgi
-
Content:
import sys sys.path.insert(0, "/var/www/catalog") from project import app as application
"from project" phrase is actually the name of my main python file.
-
-
We need to configure Apache to handle requests using the WSGI module. 📌
-
Creating new configuration file for HTTP.
$ sudo touch /etc/apache2/sites-available/catalog.conf
-
Open the editor and add the following content.
-
$ sudo nano /etc/apache2/sites-available/catalog.conf
-
Content:
<VirtualHost *:80> ServerName <public-ip/localhost> ServerAdmin [email protected] WSGIScriptAlias / /var/www/catalog/project.wsgi <Directory /var/www/catalog> Require all granted WSGIApplicationGroup %{GLOBAL} WSGIScriptReloading On </Directory> ErrorLog ${APACHE_LOG_DIR}/catalog_error.log CustomLog ${APACHE_LOG_DIR}/catalog_access.log combined </VirtualHost>
-
-
Creating new configuration file HTTPS.
$ sudo touch /etc/apache2/sites-available/catalog-ssl.conf
-
Open the editor and add the following content.
-
$ sudo nano /etc/apache2/sites-available/catalog-ssl.conf
-
Content:
<IfModule mod_ssl.c> <VirtualHost *:443> ServerName <public-ip/localhost> ServerAdmin [email protected] WSGIScriptAlias / /var/www/catalog/project.wsgi <Directory /var/www/catalog> Require all granted WSGIApplicationGroup %{GLOBAL} WSGIScriptReloading On </Directory> SSLEngine on SSLCertificateFile /etc/ssl/certs/selfsigned.crt SSLCertificateKeyFile /etc/ssl/private/selfsigned.key ErrorLog ${APACHE_LOG_DIR}/catalog_ssl_error.log CustomLog ${APACHE_LOG_DIR}/catalog_ssl_access.log combined </VirtualHost> </IfModule>
-
-
Optional: Redirect HTTP to HTTPS.
-
$ sudo nano /etc/apache2/sites-available/catalog.conf
-
Content:
<VirtualHost *:80> ServerName <public-ip/localhost> Redirect permanent / https://<public-ip/localhost>/ </VirtualHost>
-
-
-
Now, disable the default Apache site, enable your flask app. ✅ ❎
- Disable the default configuration file:
$ sudo a2dissite 000-default.conf
- Enable the catalog.conf (Our flask app configuration):
$ sudo a2ensite catalog.conf
- Enable the catalog-ssl.conf (Our flask app configuration):
$ sudo a2enmod ssl
$ sudo a2ensite catalog-ssl.conf
- To active the new configuration we need to run:
$ sudo service apache2 restart
$ sudo apache2ctl restart
$ sudo systemctl reload apache2
- Disable the default configuration file:
-
If app was cloned from (https://github.com/FixEight/udacity-buid-an-item-catalog-application) then all the following (Line numbers: 27, 28, 29) modification are made already in the repository.
-
Modify app.secret_key location Move app.secret_key so that it becomes available to the app in the new wsgi configuration.
-
Edit the project.py file and move the app.secret_key out of ...
if __name__ == '__main__': app.secret_key = 'super_secret_key' app.run()
-- by moving it to the following line:
app = Flask(__name__) app.secret_key = 'super_secret_key'
-
-
Also change the client_secrets.json directory in project.py according to the linux server.
CLIENT_ID = json.loads( open('client_secrets.json', 'r').read())['web']['client_id']
-- to this form:
CLIENT_ID = json.loads( open('/var/www/catalog/client_secrets.json', 'r').read())['web']['client_id']
-
Edit project.py, database_setup.py in clone repository to use postgresql database instead of sqlite.
# engine = create_engine('sqlite:///catalog.db') engine = create_engine( 'postgresql+psycopg2://catalog:catalog@localhost/catalog')
-
Install and Configure PostgreSQL database. 📂
- Create database user 'catalog'
$ sudo -u postgres psql postgres
postgres=# CREATE DATABASE catalog;
postgres=# CREATE USER catalog;
postgres=# ALTER ROLE catalog with PASSWORD 'catalog';
postgres=# GRANT ALL PRIVILEGES ON DATABASE catalog TO catalog;
postgres=# \q
- Create database user 'catalog'
-
To view last few lines of server side error: ❌
$ sudo tail -n 30 /var/log/apache2/catalog_error.log
$ sudo tail /var/log/apache2/error.log
These are the following addresses to run the Website on browser.
- IP Address: 18.194.121.80
- SSH Port Configured and Allowed in Firewall: 2200
- HTTP Port Configured and Allowed in Firewall: 80
- NTP Port Configured and Allowed in Firewall: 123
- Sudoer User for Testing:
- Username : grader
- Password: grader
- Private/public key as grader user is attached with it.
Linux Server Configuration is Copyright ©️ 2018 Kashif Iqbal. It is free, and may be redistributed under the terms specified in the LICENSE file.