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.
- Download private keys and write down your public IP address.
- Open Git Bash
- Run 'ssh ubuntu@YOUR_IP_ADDRESS -i PRIVATE_KEY.pem -p 22
- Create a new user:
$ adduser NEWUSER
- Give new user the permission to sudo
- Open the sudo configuration:
$ visudo
- Add the following line below
root ALL...
:
NEWUSER ALL=(ALL:ALL) ALL
- Update the list of available packages and their versions:
$ sudo apt-get update
- Install newer vesions of packages you have:
$ sudo sudo apt-get upgrade
-
Change ssh config file:
-
Open the config file:
$ vim /etc/ssh/sshd_config
-
Change to Port 2200.
-
Change
PermitRootLogin
fromwithout-password
tono
. -
Restart SSH Service:
$ /etc/init.d/ssh restart
or# service sshd restart
-
Create SSH Keys:
Source: [DigitalOcean][10] -
Generate a SSH key pair on the local machine:
$ ssh-keygen
-
Copy the public id to the server:
$ ssh-copy-id username@remote_host -p**_PORTNUMBER_**
-
Login with the new user:
$ ssh -v grader@PUBLIC-IP-ADDRESS -p2200
-
Open SSHD config:
$ sudo vim /etc/ssh/sshd_config
-
Change
PasswordAuthentication
back fromyes
tono
.
5 - Configure the Uncomplicated Firewall (UFW) to only allow incoming connections for SSH (port 2200), HTTP (port 80), and NTP (port 123)
- Turn UFW on with the default set of rules:
$ sudo ufw enable
- *Check the status of UFW:
$ sudo ufw status verbose
- Allow incoming TCP packets on port 2200 (SSH):
$ sudo ufw allow 2200/tcp
- Allow incoming TCP packets on port 80 (HTTP):
$ sudo ufw allow 80/tcp
- Allow incoming UDP packets on port 123 (NTP):
$ sudo ufw allow 123/udp
- Open the timezone selection dialog:
$ sudo dpkg-reconfigure tzdata
- Then chose 'None of the above', then UTC.
- Install Apache web server:
$ sudo apt-get install apache2
- 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.
- Install mod_wsgi for serving Python apps from Apache and the helper package python-setuptools:
$ sudo apt-get install python-setuptools libapache2-mod-wsgi
- Restart the Apache server for mod_wsgi to load:
$ sudo service apache2 restart
As this is by far the biggest project task, it is split in several parts.
- Install Git:
$ sudo apt-get install git
- Set your name, e.g. for the commits:
$ git config --global user.name "YOUR NAME"
- Set up your email address to connect your commits to your account:
$ git config --global user.email "YOUR EMAIL ADDRESS"
- Extend Python with additional packages that enable Apache to serve Flask applications:
$ sudo apt-get install libapache2-mod-wsgi python-dev
- Enable mod_wsgi (if not already enabled):
$ sudo a2enmod wsgi
- Create a Flask app:
- Move to the www directory:
$ cd /var/www
- 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()
- Install Flask
- Install pip installer:
$ sudo apt-get install python-pip
- Install virtualenv:
$ sudo pip install virtualenv
- Set virtual environment to name 'venv':
$ sudo virtualenv venv
- Enable all permissions for the new virtual environment (no sudo should be used within):
$ sudo chmod -R 777 venv
- Activate the virtual environment:
$ source venv/bin/activate
- Install Flask inside the virtual environment:
$ pip install Flask
- Run the app:
$ python __init__.py
- Deactivate the environment:
$ deactivate
- Configure and Enable a New Virtual Host#
- Create a virtual host config file
$ sudo nano /etc/apache2/sites-enabled/000-default.conf
- 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>
- Enable the virtual host:
$ sudo a2ensite flaskapp
- Create the .wsgi File and Restart Apache
- Create wsgi file:
$ cd /var/www/FlaskApp
and$ sudo vim flaskapp.wsgi
- 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'
- Restart Apache:
$ sudo service apache2 restart
- Clone project 3 solution repository on GitHub:
$ git clone https://github.com/alidabour/ItemCatalog.git
- Move all content of created ItemCatalog directory to
/var/www/FlaskApp/FlaskApp/
-directory and delete the leftover empty directory. - Make the GitHub repository inaccessible:
- Create and open .htaccess file:
$ cd /var/www/FlaskApp/
and$ sudo vim .htaccess
- Paste in the following:
RedirectMatch 404 /\.git
- Activate virtual environment:
$ source venv/bin/activate
- Install requests module in venv:
$ pip install requests
- Install flask
$ *sudo pip install flask
- Install oauth2client.client:
$ sudo pip install --upgrade oauth2client
- Install SQLAlchemy:
$ sudo pip install sqlalchemy
- Install the Python PostgreSQL adapter psycopg:
$ sudo apt-get install python-psycopg2
- Install PostgreSQL:
$ sudo apt-get install postgresql postgresql-contrib
- Check that no remote connections are allowed (default):
$ sudo vim /etc/postgresql/9.3/main/pg_hba.conf
- Open the database setup file:
$ sudo vim database_setup.py
- Change the line starting with "engine" to (fill in a password):
python engine = create_engine('postgresql://catalog:PW-FOR-DB@localhost/catalog')
- Change the same line in application.py respectively
- Rename application.py:
$ mv application.py __init__.py
- Create needed linux user for psql:
$ sudo adduser catalog
(choose a password) - Change to default user postgres:
$ sudo su - postgre
- Connect to the system:
$ psql
- Add postgre user with password:
Sources: [Trackets Blog][25] and [Super User][26] - Create user with LOGIN role and set a password:
# CREATE USER catalog WITH PASSWORD 'PW-FOR-DB';
(# stands for the command prompt in psql) - Allow the user to create database tables:
# ALTER USER catalog CREATEDB;
- *List current roles and their attributes:
# \du
- Create database:
# CREATE DATABASE catalog WITH OWNER catalog;
- Connect to the database catalog
# \c catalog
- Revoke all rights:
# REVOKE ALL ON SCHEMA public FROM public;
- Grant only access to the catalog role:
# GRANT ALL ON SCHEMA public TO catalog;
- Exit out of PostgreSQl and the postgres user:
# \q
, then$ exit
- Create postgreSQL database schema:
$ python database_setup.py
- Restart Apache:
$ sudo service apache2 restart
- 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
- *If getting an internal server error, check the Apache error files:
- View the last 20 lines in the error log:
$ sudo tail -20 /var/log/apache2/error.log