Skip to content

biobot-01/linux-server-configuration

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 

Repository files navigation

Linux Server Configuration

IP ADDRESS: 35.176.196.186 HTTP ALIAS ADDRESS: 35.176.196.186.xip.io SSH Port: 2200

Project Overview

Take a baseline installation of a Linux server and prepare it to host web applications. To secure the server from a number of attack vectors, install & configure a database server, & deploy an existing web application onto it.

Steps to complete this project:

Setup the server

  1. Start a new Ubuntu Linux server instance on Amazon Lightsail.
  2. Log in or Sign up to AWS.
  3. Click on Create instance.
  4. Instance location:
    • You can change AWS Region or leave the default selected.
  5. Pick your instance image:
    1. Select a platform - Linux/Unix
    2. Select a blueprint - OS Only & Ubuntu 18.04 LTS
  6. Choose your instance plan - Lowest tier (First month free!)
  7. Identify your instance:
    • You can change the hostname or leave the default selected.
  8. Click on Create instance.
  9. The new instance will appear, then click on it.
  10. Take note of the Public IP: 35.176.196.186 & Username: ubuntu
    Learn more about instances

Configure SSH for the server

You can click on the Connect using SSH button to connect to the instance, however we will set up a private key to connect using our local machine.

Following from the previous section:

  1. Scroll to the bottom, where the last sentence reads:
    You can download your default private key from the Account page
  2. Click on Account page.
  3. Manage your SSH keys:
    • Click on the Download link of your AWS Region.
  4. Save the file in your Downloads folder.
  5. Open the terminal Alt + Ctrl + T.
  6. Check you are in your home directory:
    $ pwd
    • This should print /home/{your-username}
  7. Move the downloaded file LightsailDefaultKey-{AWS Region}.pem from Downloads directory into .ssh directory & rename it ubuntu_motorbike_catalog.rsa:
    $ mv -v Downloads/LightsailDefaultKey-{AWS Region}.pem .ssh/ubuntu_motorbike_catalog.rsa
  8. Change the file permissions so only the owner can read & write:
    $ chmod -v 600 .ssh/ubuntu_motorbike_catalog.rsa
  9. To SSH into the instance server using the Public IP & Username:
    $ ssh -i .ssh/ubuntu_motorbike_catalog.rsa ubuntu@35.176.196.186
    • The terminal will output some info about the instance server & the prompt will change to ubuntu@ip-{private-ip}:~$, this means you are successfully connected to the Amazon Lightsail instance server.

Secure the server

Following from the previous section:

  1. Update all currently installed packages on the instance server through the SSH connection in your terminal, run the following commands:
    $ sudo apt update
    NOTE: To view the upgradable packages, run the command $ apt list --upgradable
    $ sudo apt upgrade
    NOTE: In the terminal a message about restarting services during package upgrades: select Yes NOTE: In the terminal a message about configuring openssh-server: select install the package maintainer's version NOTE: In the terminal a message about grub menu: select install the package maintainer's version $ exit
  2. Reboot the instance server:
  3. SSH back into the instance server:
    $ ssh -i .ssh/ubuntu_motorbike_catalog.rsa ubuntu@35.176.196.186
  4. Change the SSH port from 22 to 2200:
    • Edit the /etc/ssh/sshd_config file $ sudo nano /etc/ssh/sshd_config
    • Search for #Port 22 & change to Port 2200.
    • Save the file Ctrl + O, then press Enter.
    • Exit nano, Ctrl + X
    • Restart SSH service $ sudo service ssh restart
      Learn more about nano
  5. Configure the Uncomplicated Firewall (UFW) to only allow incoming connections for SSH (port 2200), HTTP (port 80), & NTP (port 123):
    • Check the status of UFW:
      $ sudo ufw status verbose or $ sudo ufw status
    • Define default rules for allowing & denying connections:
      $ sudo ufw default deny incoming
      $ sudo ufw default allow outgoing
    • Allow connection on port 2200 (SSH) using TCP:
      $ sudo ufw allow 2200/tcp
    • Deny connection on port 22 (SSH) using TCP:
      $ sudo ufw deny 22/tcp or $ sudo ufw deny ssh
    • Allow connection on port 80 (HTTP) using TCP:
      $ sudo ufw allow 80/tcp or $ sudo ufw allow www
    • Allow connection on port 123 (NTP) using UDP:
      $ sudo ufw allow 123/udp or $ sudo ufw allow ntp
    • Check added user rules $ sudo ufw show added
    • Activate UFW $ sudo ufw enable
    • Close the SSH connection $ exit
      Source: DigitalOcean
  6. Update firewall to match changes on Amazon Lightsail instance server:
    • On the instance server, click on the three vertical dots & click on Manage.
    • Click the Networking tab.
    • Scroll down to Firewall section & click on Add another.
    • Update the rules to match the rules applied above.
    • Scroll back to the top & click on Reboot.
      NOTE: From this point forward, to SSH into the instance server, run the command:
      $ ssh -i .ssh/ubuntu_motorbike_catalog.rsa -p 2200 ubuntu@35.176.196.186
  7. Test the above command.

Create a new user grader & give grader access

Allow the grader to log in to the server with sudo privileges.

  1. Create a new user account named grader:
    $ sudo adduser grader
    • Enter a password for the new user. Password: grader
    • Press Enter for default information.
  2. Give grader the permission to sudo:
    • Open a file sudoers.tmp with the command $ sudo visudo
    • Find the comment # User privilege specification & under root, add the following grader ALL=(ALL:ALL) ALL
    • Save the file Ctrl + O, then press Enter.
    • Exit nano, Ctrl + X
  3. Create a SSH key pair for grader using the ssh-keygen tool:
    • Keep the current terminal open.
    • Open a new terminal Alt + Ctrl + T, this will be the local machine.
    • Run the command $ ssh-keygen, save file to /home/{your-username}/.ssh/grader_key & press Enter if prompted for passphrase.
    • List new files created $ ls -a .ssh/
    • Copy contents of file from terminal $ cat .ssh/grader_key.pub
    • Switch back to the other terminal with the SSH connection:
      • Login as grader $ su - grader
      • Check if there is a .ssh directory $ ls -a
      • Create .ssh directory $ mkdir .ssh
      • Create authorized_keys file in .ssh directory $ touch .ssh/authorized_keys
      • Paste contents of grader_key.pub file into authorized_keys file $ nano .ssh/authorized_keys
      • Save the file Ctrl + O, then press Enter.
      • Exit nano, Ctrl + X
      • Change .ssh folder permission chmod -v 700 .ssh/
      • Change authorized_keys file permission chmod -v 644 .ssh/authorized_keys
      • Force key based authentication:
        • Edit the /etc/ssh/sshd_config file $ sudo nano /etc/ssh/sshd_config
        • Search for #PasswordAuthentication yes & change to PasswordAuthentication no
      • Disable remote root login:
        • Search for #PermitRootLogin prohibit-password & change to PermitRootLogin no
        • Save the file Ctrl + O, then press Enter.
        • Exit nano, Ctrl + X
      • Restart SSH service $ sudo service ssh restart
      • Logout as grader $ exit
      • Close the SSH connection $ exit
        NOTE: You can now SSH into the instance server as grader, run the command:
        $ ssh -i .ssh/grader_key -p 2200 grader@35.176.196.186
  4. Test the above command.

Prepare to deploy the project

  1. Configure the local timezone to UTC:
    $ sudo dpkg-reconfigure tzdata
    • Select None of the above.
    • Select UTC. NOTE: To check the timezone $ date +%Z
  2. Install & configure Apache to serve a Python 3 mod_wsgi application:
    • Install Apache $ sudo apt install apache2
    • Test Apache installation:
      • Open a Browser & enter the Public IP address http://35.176.196.186
    • Install mod_wsgi for Python 3 $ sudo apt install python3-setuptools python3-dev libapache2-mod-wsgi-py3
    • Restart Apache $ sudo service apache2 restart
  3. Install Python 3 pip & venv:
    $ sudo apt install python3-pip python3-venv
  4. Install & configure PostgreSQL:
    $ sudo apt install postgresql postgresql-contrib libpq-dev
    • Do not allow remote connections $ sudo nano /etc/postgresql/10/main/pg_hba.conf
    • Only connections from localhost are allowed.
  5. Create a new database user named catalog that has limited permissions to the catalog application database:
    • Login to PostgreSQL as postgres $ sudo -u postgres psql
    • Create user # CREATE USER catalog WITH PASSWORD 'catalog';
    • Allow user to create databases # ALTER USER catalog CREATEDB;
    • Create the database # CREATE DATABASE catalog WITH OWNER catalog;
    • Connect to database # \c catalog
    • Only allow user catalog permission to database # GRANT ALL PRIVILEGES ON DATABASE catalog TO catalog;
    • Quit PostgreSQL # \q
  6. Install git:
    sudo apt install git - It was already installed

Deploy the Item Catalog project

The project to be deployed will be Motorbike Catalog

  1. Clone & setup the Item Catalog project from the Github repository:
    • Move to Apache root folder $ cd /var/www/
    • Clone project repo $ sudo git clone https://github.com/biobot-01/motorbike-catalog.git
    • Change ownership of project folder $ sudo chown -vR grader:grader motorbike-catalog
    • Rename motorbike-catalog directory $ sudo mv -v motorbike-catalog/ MotorbikeCatalog
    • Move into MotorbikeCatalog directory $ cd MotorbikeCatalog
    • Rename catalog directory $ mv -v catalog/ MotorbikeCatalog
    • Move database_setup.py file into inner MotorbikeCatalog $ mv -v database_setup.py MotorbikeCatalog/
    • Move to the inner MotorbikeCatalog directory $ cd MotorbikeCatalog/
    • Rename app.py to __init__.py $ mv -v app.py __init__.py
    • Edit __init__.py, models.py, database_setup.py & change engine = create_engine('sqlite:///motorbike_catalog.db') to engine = create_engine('postgresql://catalog:catalog@localhost/catalog')
    • Edit database_setup.py & change from catalog.models to from MotorbikeCatalog.models
    • Edit __init__.py & change
    from models import ...
    
    app.secret_key = 'super_secret_key'
    app.debug = True
    app.run(host='127.0.0.1', port=8000, threaded=False)
    
    to
    from MotorbikeCatalog.models import ...
    
    app.run()
    
    • Edit __init__.py & change all file paths to absolute paths.
  2. Configure wsgi file:
    • Return to outer MotorbikeCatalog directory cd ../
    • Create a new file app.wsgi touch app.wsgi
    • Edit app.wsgi & add
    #!/usr/bin/env python3
    
    import sys
    import site
    import logging
    
    python_home = '/var/www/MotorbikeCatalog/MotorbikeCatalog/venv/flask'
    # Calculate path to site-packages directory
    python_version = '.'.join(map(str, sys.version_info[:2]))
    site_packages = python_home + '/lib/python{}/site-packages'.format(python_version)
    # Add the site-packages directory
    site.addsitedir(site_packages)
    
    logging.basicConfig(stream=sys.stderr)
    sys.path.insert(0, '/var/www/MotorbikeCatalog')
    
    from secrets import token_hex
    
    from MotorbikeCatalog import app as application
    
    application.secret_key = token_hex(32)
  3. Setup Python virtual environment with python3-venv:
    • Move to the inner MotorbikeCatalog directory $ cd MotorbikeCatalog/
    • Create folder $ mkdir venv
    • Create venv $ python3 -m venv venv/flask & $ python3 -m venv venv/python
    • Activate venv/flask with $ source venv/flask/bin/activate
    • Update pip $ pip install -U pip
    • Install requirements $ pip install -r requirements.txt
    • Install psycopg2 $ pip install psycopg2
    • Create the database schema $ python models.py
    • Deactivate venv $ deactivate
  4. Set it up in the server so that it functions correctly when visiting the server's IP address in a browser: $ cd /etc/apache2/
    • Configure virtual host:
      • Copy vhost file $ sudo cp -v sites-available/000-default.conf sites-available/001-motorbikecatalog.conf
      • Edit 001-motorbikecatalog.conf $ sudo nano sites-available/001-motorbikecatalog.conf & add
      <VirtualHost *:80>
        ServerName 35.176.196.186
        ServerAlias 35.176.196.186.xip.io
      
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/MotorbikeCatalog
      
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
      
        WSGIDaemonProcess MotorbikeCatalog python-home=/var/www/MotorbikeCatalog/MotorbikeCatalog/venv/python user=grader group=grader threads=5
      
        WSGIScriptAlias / /var/www/MotorbikeCatalog/app.wsgi
      
        <Directory /var/www/MotorbikeCatalog/MotorbikeCatalog>
          WSGIProcessGroup MotorbikeCatalog
          WSGIApplicationGroup %{GLOBAL}
          Require all granted
        </Directory>
      
        Alias /static /var/www/MotorbikeCatalog/MotorbikeCatalog/static
      
        <Directory /var/www/MotorbikeCatalog/MotorbikeCatalog/static>
          Require all granted
        </Directory>
      </VirtualHost>
      
      • Disable default vhost $ sudo a2dissite 000-default.conf
      • Enable motorbikecatalog vhost $ sudo a2ensite 001-motorbikecatalog.conf
      • Restart Apache seerver $ sudo service apache2 restart
        Source: DigitalOcean
  5. Make sure that the .git directory is not publicly accessible via the browser:
    • Change to apache2 directory $ cd /etc/apache2/
    • Edit security.conf file $ sudo nano conf-available/security.conf & change ServerTokens OS to ServerTokens Prod, ServerSignature on to ServerSignature off & add
    <DirectoryMatch "/\.git">
      Require all denied
    </DirectoryMatch>
    
    • Restart Apache $ sudo service apache2 restart

Thanks to Daniel A (jungleBadger) for pointing me to his project

About

Udacity Full Stack Web Developer Nanodegree Linux Server Configuration Project

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published