Linux-Server-Configuration

A baseline installation of Ubuntu Linux on a virtual machine to host a Flask web application. This includes the installation of updates, securing the system from a number of attack vectors and installing/configuring web and database servers.

To test : Replace any ip address with 52.206.155.23

1- Launch Virtual Machine and SSH into the server

  1. Download private keys and write down your public IP address.
  2. Open Git Bash
  3. Run 'ssh ubuntu@YOUR_IP_ADDRESS -i PRIVATE_KEY.pem -p 22

2 - User Management: Create a new user and give user the permission to sudo

  1. Create a new user:
    $ adduser NEWUSER
  2. Give new user the permission to sudo
  3. Open the sudo configuration:
    $ visudo
  4. Add the following line below root ALL...:
    NEWUSER ALL=(ALL:ALL) ALL

3 - Update and upgrade all currently installed packages

  1. Update the list of available packages and their versions:
    $ sudo apt-get update
  2. Install newer vesions of packages you have:
    $ sudo sudo apt-get upgrade

4 - Change the SSH port from 22 to 2200 and configure SSH access

  1. Change ssh config file:

  2. Open the config file:
    $ vim /etc/ssh/sshd_config

  3. Change to Port 2200.

  4. Change PermitRootLogin from without-password to no.

  5. Restart SSH Service:
    $ /etc/init.d/ssh restart or # service sshd restart

  6. Create SSH Keys:
    Source: [DigitalOcean][10]

  7. Generate a SSH key pair on the local machine:
    $ ssh-keygen

  8. Copy the public id to the server:
    $ ssh-copy-id username@remote_host -p**_PORTNUMBER_**

  9. Login with the new user:
    $ ssh -v grader@PUBLIC-IP-ADDRESS -p2200

  10. Open SSHD config:
    $ sudo vim /etc/ssh/sshd_config

  11. Change PasswordAuthentication back from yes to no.

5 - Configure the Uncomplicated Firewall (UFW) to only allow incoming connections for SSH (port 2200), HTTP (port 80), and NTP (port 123)

  1. Turn UFW on with the default set of rules:
    $ sudo ufw enable
  2. *Check the status of UFW:
    $ sudo ufw status verbose
  3. Allow incoming TCP packets on port 2200 (SSH):
    $ sudo ufw allow 2200/tcp
  4. Allow incoming TCP packets on port 80 (HTTP):
    $ sudo ufw allow 80/tcp
  5. Allow incoming UDP packets on port 123 (NTP):
    $ sudo ufw allow 123/udp

6 - Configure the local timezone to UTC

  1. Open the timezone selection dialog:
    $ sudo dpkg-reconfigure tzdata
  2. Then chose 'None of the above', then UTC.

7 - Install and configure Apache to serve a Python mod_wsgi application

  1. Install Apache web server:
    $ sudo apt-get install apache2
  2. Open a browser and open your public ip address, e.g. http://52.25.0.41/ - It should say 'It works!' on the top of the page.
  3. Install mod_wsgi for serving Python apps from Apache and the helper package python-setuptools:
    $ sudo apt-get install python-setuptools libapache2-mod-wsgi
  4. Restart the Apache server for mod_wsgi to load:
    $ sudo service apache2 restart

8 - Install git, clone and setup your Catalog App project

As this is by far the biggest project task, it is split in several parts.

8.1 - Install and configure git

  1. Install Git:
    $ sudo apt-get install git
  2. Set your name, e.g. for the commits:
    $ git config --global user.name "YOUR NAME"
  3. Set up your email address to connect your commits to your account:
    $ git config --global user.email "YOUR EMAIL ADDRESS"

8.2 - Setup for deploying a Flask Application on Ubuntu VPS

  1. Extend Python with additional packages that enable Apache to serve Flask applications:
    $ sudo apt-get install libapache2-mod-wsgi python-dev
  2. Enable mod_wsgi (if not already enabled):
    $ sudo a2enmod wsgi
  3. Create a Flask app:
  4. Move to the www directory:
    $ cd /var/www
  5. Setup a directory for the app, e.g. catalog:
       1. $ sudo mkdir FlaskApp   2. $ cd FlaskApp and $ sudo mkdir FlaskApp
    3. $ cd FlaskApp and $ sudo mkdir static templates
    4. Create the file that will contain the flask application logic:
    $ sudo nano __init__.py 5. Paste in the following code:
    python from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Veni vidi vici!!" if __name__ == "__main__": app.run()
  6. Install Flask
  7. Install pip installer:
    $ sudo apt-get install python-pip
  8. Install virtualenv:
    $ sudo pip install virtualenv
  9. Set virtual environment to name 'venv':
    $ sudo virtualenv venv
  10. Enable all permissions for the new virtual environment (no sudo should be used within):
    $ sudo chmod -R 777 venv
  11. Activate the virtual environment:
    $ source venv/bin/activate
  12. Install Flask inside the virtual environment:
    $ pip install Flask
  13. Run the app:
    $ python __init__.py
  14. Deactivate the environment:
    $ deactivate
  15. Configure and Enable a New Virtual Host#
  16. Create a virtual host config file
    $ sudo nano /etc/apache2/sites-enabled/000-default.conf
  17. Paste in the following lines of code and change names and addresses regarding your application:
  <VirtualHost *:80>
      ServerName PUBLIC-IP-ADDRESS
      ServerAdmin admin@PUBLIC-IP-ADDRESS
      WSGIScriptAlias / /var/www/FlaskApp/flaskapp.wsgi
      <Directory /var/www/FlaskApp/FlaskApp/>
          Order allow,deny
          Allow from all
      </Directory>
      Alias /static /var/www/FlaskApp/FlaskApp/static
      <Directory /var/www/FlaskApp/FlaskApp/static/>
          Order allow,deny
          Allow from all
      </Directory>
      ErrorLog ${APACHE_LOG_DIR}/error.log
      LogLevel warn
      CustomLog ${APACHE_LOG_DIR}/access.log combined
  </VirtualHost>
  1. Enable the virtual host:
    $ sudo a2ensite flaskapp
  2. Create the .wsgi File and Restart Apache
  3. Create wsgi file:
    $ cd /var/www/FlaskApp and $ sudo vim flaskapp.wsgi
  4. Paste in the following lines of 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 = 'Add your secret key'
  1. Restart Apache:
    $ sudo service apache2 restart

8.3 - Clone GitHub repository and make it web inaccessible

  1. Clone project 3 solution repository on GitHub:
    $ git clone https://github.com/alidabour/ItemCatalog.git
  2. Move all content of created ItemCatalog directory to /var/www/FlaskApp/FlaskApp/-directory and delete the leftover empty directory.
  3. Make the GitHub repository inaccessible:
  4. Create and open .htaccess file:
    $ cd /var/www/FlaskApp/ and $ sudo vim .htaccess
  5. Paste in the following:
    RedirectMatch 404 /\.git

8.4 - Install needed modules & packages

  1. Activate virtual environment:
    $ source venv/bin/activate
  2. Install requests module in venv:
    $ pip install requests
  3. Install flask
    $ *sudo pip install flask
  4. Install oauth2client.client:
    $ sudo pip install --upgrade oauth2client
  5. Install SQLAlchemy:
    $ sudo pip install sqlalchemy
  6. Install the Python PostgreSQL adapter psycopg:
    $ sudo apt-get install python-psycopg2

9 - Install and configure PostgreSQL

  1. Install PostgreSQL:
    $ sudo apt-get install postgresql postgresql-contrib
  2. Check that no remote connections are allowed (default):
    $ sudo vim /etc/postgresql/9.3/main/pg_hba.conf
  3. Open the database setup file:
    $ sudo vim database_setup.py
  4. Change the line starting with "engine" to (fill in a password):
    python engine = create_engine('postgresql://catalog:PW-FOR-DB@localhost/catalog')
  5. Change the same line in application.py respectively
  6. Rename application.py:
    $ mv application.py __init__.py
  7. Create needed linux user for psql:
    $ sudo adduser catalog (choose a password)
  8. Change to default user postgres:
    $ sudo su - postgre
  9. Connect to the system:
    $ psql
  10. Add postgre user with password:
    Sources: [Trackets Blog][25] and [Super User][26]
  11. Create user with LOGIN role and set a password:
    # CREATE USER catalog WITH PASSWORD 'PW-FOR-DB'; (# stands for the command prompt in psql)
  12. Allow the user to create database tables:
    # ALTER USER catalog CREATEDB;
  13. *List current roles and their attributes: # \du
  14. Create database:
    # CREATE DATABASE catalog WITH OWNER catalog;
  15. Connect to the database catalog # \c catalog
  16. Revoke all rights:
    # REVOKE ALL ON SCHEMA public FROM public;
  17. Grant only access to the catalog role:
    # GRANT ALL ON SCHEMA public TO catalog;
  18. Exit out of PostgreSQl and the postgres user:
    # \q, then $ exit
  19. Create postgreSQL database schema:
    $ python database_setup.py

10 - Run application

  1. Restart Apache:
    $ sudo service apache2 restart
  2. Open a browser and put in your public ip-address as url, e.g. 52.25.0.41 - if everything works, the application should come up
  3. *If getting an internal server error, check the Apache error files:
  4. View the last 20 lines in the error log: $ sudo tail -20 /var/log/apache2/error.log