Skip to content
Scott Behrens edited this page Jun 1, 2017 · 13 revisions

Sleepy Puppy uses: Flask + Gunicorn + Nginx

##Prerequisites##

  • Python2.7
  • pip
  • git

For this setup guide, we will assume you are running on Ubuntu and you are using the following folder for installation:

/apps/sleepy-puppy

##Test Setup## This test install section will get you setup quickly in a non-production environment.

###Install these packages

sudo apt-get -y -q install python-dev python-psycopg2 libpq-dev libffi-dev libjpeg-dev zlib1g-dev

###Grab the repo

cd /apps
git clone https://github.com/netflix/sleepy-puppy.git

###Setup a Virtual Environment###

sudo pip install virtualenv setuptools
cd sleepy-puppy/
virtualenv sleepyenv
source sleepyenv/bin/activate

###Install the required dependencies

python setup.py install

###Create database, seed database, create default login with 'admin' user

python manage.py setup_sleepy_puppy

This will initialize the database, populate the database with example Payloads, PuppyScripts, and an Assessment you can use. It will also create a default user account 'admin' where you must specify the password.

If you want to run each of these steps manually you can run:

python manage.py create_db
python manage.py create_login admin
python manage.py create_bootstrap_assessment

##Test Startup## If you are just testing out Sleepy Puppy, use the following to startup the environment via command line.

###Source Virtual Environment###

cd sleepy-puppy/
source sleepyenv/bin/activate

###Run the Flask Application###

python manage.py runserver --host 127.0.0.1 --port 8000

Now that Sleepy Puppy is running, visit the host at: http://127.0.0.1:8000 and log in using the default credentials admin/[the password you used].

Take a look at the Tutorial for instructions on how to try it out!

##Production Setup# The following optional steps can be performed to configure Sleepy Puppy for a more production deployment.

The production setup includes Nginx, Gunicorn, and SSL configuration. Gunicorn should have been installed when you ran the setup.py file. The following steps assume you are running an Ubuntu system. You will want to use a certificate that has been signed by a trusted certificate authority.

SSL Certificates

We use the CDN notation when generating xss payloads (// vs http://) to save space. CDN notation resolves to the current scheme, so if you are injecting into a page hosted over ssl, the callbacks will have to be on a web server that supports ssl.

Sleepy Puppy will not work with self-signed certificates, as browsers will not load content from self-signed certs.

Once you have generated a trusted certificate pair, run the following commands to place the pub/priv keys in the appropriate directories:

sudo cp server.crt /etc/ssl/certs
sudo cp server.key /etc/ssl/private

Once these two files are in your /etc/ssl/certs and /etc/ssl/private, you are ready to move on in this guide.

Database Options

Sleepy Puppy uses SQLAlchemy which allows you to use SQLite, MySQL or Postgres. For production we suggest either MySQL or PostGres.

You can navigate to the Database Configuration page for detailed instructions on how to set your connect string. An example is below (config-default.py):

SQLALCHEMY_DATABASE_URI = 'mysql://sleepydb:[email protected]:3306/sleepy'

Configure Callback

Sleepy puppy needs to know where the payloads should call back too. This is set in the HOSTNAME setting in config-default.py. You can either hardcode in your hostname in config-default or set an environment variable like:

export host=

Nginx

Sleepy Puppy uses Gunicorn to serve up content on its internal 127.0.0.1 address. Nginx listens on 0.0.0.0 and proxies connections to Gunicorn for processing.

Start Gunicorn

cd /app/sleepy-puppy
gunicorn -w 4 -b 127.0.0.1:8000 sleepypuppy:app

Install Nginx

on ubuntu:

sudo apt-get install nginx

on osx:

brew install nginx

Create Log Files

sudo mkdir -p /var/log/nginx/
sudo touch /var/log/nginx/access.log
sudo touch /var/log/nginx/error.log

sleepy-puppy.conf

You will need to modify the following directive to the path where you have pulled Sleepy Puppy in the example sleepy-puppy.conf file below:

root /apps/sleepy-puppy; servername public_name_of_your_server

If you do not set the servername directive, Nginx will try to forward everything to localhost.

Next you can save the config file below to:

/etc/nginx/sites-available/sleepy-puppy.conf

   server {
        listen      0.0.0.0:443 ssl;
        ssl_certificate /etc/ssl/certs/server.crt;
        ssl_certificate_key /etc/ssl/private/server.key;
        access_log  /var/log/nginx/access.log;
        error_log   /var/log/nginx/error.log;

        root /apps/sleepy-puppy;

        location / {
            proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass http://127.0.0.1:8000;
            proxy_connect_timeout 30;
            proxy_read_timeout 40;
        }
    }
    server {

       listen         80;
       server_name    127.0.0.1;

       location /callbacks {
            proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass http://127.0.0.1:8000/callbacks;
            proxy_connect_timeout 30;
            proxy_read_timeout 40;
        }

       location /up {
            proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass http://127.0.0.1:8000/up;
            proxy_connect_timeout 30;
            proxy_read_timeout 40;
        }

       location / {
            return         301 https://$server_name$request_uri;
       }
    }

Symlink the sites-available file to the sites-enabled folder:

sudo ln -s /etc/nginx/sites-available/sleepy-puppy.conf /etc/nginx/sites-enabled/sleepy-puppy.conf

Delete the default configuration:

sudo rm /etc/nginx/sites-enabled/default

Restart nginx:

sudo service nginx restart

###Validate Setup Visit https://127.0.0.1:443 and confirm you can log in.

##Production Startup

If you reboot, nginx won't know how to start gunicorn. Try Supervisor:

sudo pip install supervisor

Here is an example configuration file (supervisord.conf). Make sure your change the user directive to a lower privileged user:

[unix_http_server]
file=/tmp/supervisor.sock
chmod=0700

[supervisord]
logfile = /var/log/supervisord.log
logfile_maxbytes = 50MB
logfile_backups=10
loglevel = info
pidfile = /tmp/supervisord.pid
nodaemon = False
minfds = 1024
minprocs = 200
umask = 022
identifier = supervisor
directory = /tmp
nocleanup = true
childlogdir = /tmp
[program:sleepypuppy]
command = gunicorn sleepypuppy:app
directory = /PATH_TO_SLEEPY-PUPPY
user = root

You can start supervisor and use the configuration file included with Sleepy-Puppy (after modifying command paths and users):

sudo -s
cd /path/to/sleepy-puppy
source sleepyenv/bin/activate
cd /path/to/sleepy-puppy/supervisor
supervisord -c supervisord.ini

If something is not starting correctly, you can view the Supervisor log file located at /var/log/supervisord.log.

You can double check everything is working by visiting:

https://yourhost.com

If you are presented with a login page, you are set!

Now that your production environment is setup, lets give the Tutorial a try!