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 Lightsail 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
- 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 [email protected] -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
- 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 Lightsail, 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 [email protected] -i .ssh/LightsailDefaultPrivateKey-eu-central-1.pem -p 2200
-
But now login as user grader locally run: 💻
$ ssh [email protected] -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
$ 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:
"from project" phrase is actually the name of my main python file.import sys sys.path.insert(0, "/var/www/catalog") from project import app as application
-
We need to configure Apache to handle requests using the WSGI module. 📌
- Creating new configuration file.
$ 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 18.194.121.80 ServerAdmin [email protected] ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined WSGIScriptAlias / /var/www/catalog/project.wsgi <directory /var/www/catalog> WSGIApplicationGroup %{GLOBAL} WSGIScriptReloading On Order deny,allow Allow from all </directory> </VirtualHost>
- Creating new configuration file.
-
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
- To active the new configuration we need to run:
$ sudo service apache2 restart
$ sudo apache2ctl restart
- 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 server side error: ❌
$ 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.