ensure the consistency of application environments at deploy time
$ tar -zxvf taslug-webapp-1.2.3.tar.gz
$ sudo apt-get install taslug-webapp-1.2.3.deb
$ git clone --branch=v1.2.3 http://code.repository.com/taslug.git
$ git fetch origin && git merge --ff-only origin v1.2.3
$ sudo apt-get install python-flask gunicorn
$ pip install flask gunicorn
requirements.txt
Flask==0.10.1
gunicorn==19.3.0
install dependencies:
$ pip install -r requirements.txt
Web interface configuration:
http://webapp.taslug.org.au/install.php
Edit config file:
$ cp config.php-dist config.php
$ vi config.php
$ export DB_HOSTNAME=taslugdb1
$ export DB_PASSWORD=sekrit!
config.py
from os import environ
def get_env_setting(setting):
try:
return environ[setting]
except KeyError:
error_msg = "Set the %s env variable" % setting
raise ImproperlyConfigured(error_msg)
...
DB_HOSTNAME = get_env_setting('DB_HOSTNAME')
DB_USERNAME = 'taslug_webapp'
DB_PASSWORD = get_env_var('DB_PASSWORD')
DB_PORT = 80
Web interface configuration:
http://webapp.taslug.org.au/install.php
Login to update:
http://webapp.taslug.org.au/admin.php
apache + mod_proxy + application server
$ pip freeze
BeautifulSoup==3.2.1
CherryPy==3.5.0
Jinja2==2.8
Markdown==2.6.5
MarkupSafe==0.23
Pillow==3.1.1
...
supervisor==3.2.0
tornado==4.2.1
uTidylib==0.2
vboxapi==1.0
virtualenv==1.11.6
wsgiref==0.1.2
requirements.txt
Flask==0.10.1
gunicorn==19.4.5
Install dependencies in virtualenv:
$ cd taslug
$ virtualenv venv
$ source venv/bin/activate
(venv)$ pip install -r requirements.txt
(venv)$ pip freeze
Flask==0.10.1
Jinja2==2.8
MarkupSafe==0.23
Werkzeug==0.11.4
argparse==1.2.1
gunicorn==19.4.5
itsdangerous==0.24
wsgiref==0.1.2
root@stark:/var/www/taslug# gunicorn -b 0.0.0.0:80 webapp:app
code:
import yaml
data = yaml.load(request.data)
yaml request:
first_name: John
last_name: Kristensen
exploit:
!!python/object/apply:subprocess.check_output [['rm', '-rf', '/']]
root@stark:/var/www/taslug# adduser taslug
root@stark:/var/www/taslug# su - taslug
taslug@stark:/var/www/taslug$ gunicorn -b 0.0.0.0:80 webapp:app
yaml request:
cat_passwd:
!!python/object/apply:subprocess.check_output [['cat', '/etc/passwd']]
list_packages:
!!python/object/apply:subprocess.check_output [['dpkg-query', '-l']]
processes:
!!python/object/apply:subprocess.check_output [['ps', 'aux']]
Create chroot directory structure:
<insert lots of work to create a directory structure>
Enter chroot environment:
root@stark:~# chroot --userspec=taslug /home/taslug/chroot/ /bin/bash
taslug@stark:/var/www/taslug$ gunicorn -b 0.0.0.0:80 webapp:app
or
LXC — rkt — systemd-spawn
webapp.py
import socket
import config
from flask import Flask, request
app = Flask(__name__)
@app.route('/')
def main():
return """\
Hello TasLUG!
From: {}
Listening on port: {}
The secret is: {}
""".format(socket.gethostname(), request.environ['SERVER_PORT'],
config.SECRET)
config.py
from os import environ
def get_env_settings(setting):
try:
return environ[setting]
except KeyError:
error_msg = "Set the %s env variable" % setting
raise EnvironmentError(error_msg)
SECRET = get_env_settings('WEBAPP_SECRET')
requirements.txt
Flask==0.10.1
gunicorn==19.3.0
Dockerfile
FROM debian:jessie
RUN apt-get update && apt-get install -y python python-virtualenv
RUN mkdir -p /var/www/taslug
ADD webapp.py config.py requirements.txt /var/www/taslug/
WORKDIR /var/www/taslug
RUN virtualenv venv
RUN venv/bin/pip install -r requirements.txt
CMD /var/www/taslug/venv/bin/gunicorn -b 0.0.0.0:80 webapp:app
Support the Software Freedom Conservancy
https://sfconservancy.org/supporter/