Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Setup NightShade

Install NightShade

Get NightShade Files

git clone
cd NightShade

Setup Pip and Postgres

sudo apt update
sudo apt install python-pip postgresql-devel

Setup PostGres

sudo apt install postgresql postgresql-contrib
sudo -i -u postgres

Now you should be the postgres user. As that user first create the database user:

$ createuser --pwprompt --interactive

Enter name of role to add: dbuser
Enter password for new role:
Enter it again:
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles? (y/n) n

Create a database with your user having access to it. createdb -O dbuser dbname

Edit Settings

vim NightShade/

You'll want to edit these settings to match what you created:

        'default': {
            'ENGINE': 'tenant_schemas.postgresql_backend',
            'NAME': 'dbname',
            'USER': 'dbuser',
            'PASSWORD': 'dbpassword',
            'HOST': 'localhost',
            'PORT': '',
TIME_ZONE = 'America/Denver'
SECRET_KEY = '3$bp7g172awaq+9!3n7jp&ml35=r71q2#$mphjd+t(1t+23igx' # Make this Key Random and Unique

Create a file named aws.env (vim aws.env) and save your creds into it:

export AWS_ACCESS_KEY_ID = 'enterIDhere'
export AWS_SECRET_ACCESS_KEY = 'enterKEYhere'

Fix Bugs

There's an issue right now with nightshade that has been fixed in this pull request. Let's apply that fix ourselves.

mkdir customers/migrations
cd customers/migrations

Setup database

python migrate_schemas --shared
python migrate_schemas

Now we have to add the domain we want to use so that django starts serving requests from those domains. This must all be entered in the python shell.

python shell

Then change the values and enter the following statements.

from customers.models import Client

# create your first real tenant
tenant = Client(domain_url='', # don't add your port or www here or things will break.
                name='UtahSec CTF') # migrate_schemas automatically called, your tenant is ready to be used!

Exit by hitting Ctrl-D

Create super user account

$ python tenant_command createsuperuser

Enter Tenant Schema ('?' to list schemas): ?
utahsec -
Enter Tenant Schema ('?' to list schemas): utahsec
Enter Tenant Schema ('?' to list schemas): utahsec
Username (leave blank to use 'ubuntu'): mike
Email address:
Password (again):
Superuser created successfully.


sudo su 
pip install -r requirements.txt
../.local/bin/gunicorn --access-logfile - --workers 3 --bind unix:..//nightshade.sock --bind NightShade.wsgi

If .local/bin/gunicorn isn't your location use:

which gunicorn to find your location.

Python Virtual Env

Create Virtual Env

sudo -H pip install virtualenv
cd ..
virtualenv NightShade
cd NightShade/

Setup Gunicorn

pip install gunicorn

Create the service file for systemctl at /etc/systemd/system/gunicorn.service. Make sure you check all the settings and verify they work for your instance.

Description=gunicorn daemon

ExecStart=/home/ubuntu/NightShade/.local/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/ubuntu/nightshade.sock --bind "NightShade.wsgi"


Enable and start Gunicorn:

sudo systemctl enable gunicorn
systemctl start gunicorn

Setup Virtual Env

Now edit bin/activate and add this line to the bottom. We're basically adding your AWS creds to it.

source ~/NightShade/aws.env

Now let's add the python

source NightShade/bin/activate
cd NightShade
pip install -r requirementes.txt

Setup Nginx with Let's Encrypt SSL

Some of these instructions are pulled from:

sudo apt install nginx
sudo apt install certbot

Create verification dir:

cd ~/
mkdir .well-known/

Create /etc/nginx/sites-available/nightshade

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    return 301 https://$server_name$request_uri;
    location /.well-known {
    	allow all;
	alias /home/ubuntu/.well-known/;

Remove old file:

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

Check your configuration for syntax errors:

sudo nginx -t

If no errors are found, restart Nginx with this command:

sudo systemctl restart nginx

Now that we have our webroot-path, we can use the Webroot plugin with certbot to request an SSL certificate with these commands. Here, we are also specifying our domain names with the -d option. Make sure that you replace the highlighted parts with the appropriate webroot path and domain name(s):

sudo certbot certonly --webroot --webroot-path=/home/ubuntu/ -d -d

Now create /etc/nginx/snippets/

ssl_certificate /etc/letsencrypt/live/;
ssl_certificate_key /etc/letsencrypt/live/;

Generate a strong DH Group

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Now create /etc/nginx/snippets/ssl-params.conf

# from
# and

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver valid=300s;
resolver_timeout 5s;
# disable HSTS header for now
#add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;

ssl_dhparam /etc/ssl/certs/dhparam.pem;

Now add this to the bottom of /etc/nginx/sites-available/nightshade

server {

    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    include snippets/;
    include snippets/ssl-params.conf;

    location /.well-known {
    	allow all;
	alias /home/ubuntu/.well-known/;
    location / {
        include proxy_params;
        proxy_pass http://unix:/home/ubuntu/nightshade.sock;


Good work. Hit me up on twitter if you have any issues with these instructions. @miketweaver

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment