Skip to content

Instantly share code, notes, and snippets.

@phoikoi
Last active August 9, 2016 17:29
Show Gist options
  • Save phoikoi/41b31a6c86ee50629e57d6691cbced43 to your computer and use it in GitHub Desktop.
Save phoikoi/41b31a6c86ee50629e57d6691cbced43 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
""" Generates an nginx configuration for a given site name (with optional params)
Requirements: jinja2, click
"""
# (c) 2016 Peter Hull, use and redistribution granted under the MIT license:
# https://opensource.org/licenses/MIT
import sys
import jinja2
import click
template = """
#upstream {{ site }}_app {
# server 127.0.0.1:{{ app_port }} fail_timeout=0;
#}
server {
listen 80;
listen [::]:80;
server_name {{ site }};
return 301 https://{{ site }}$request_uri;
}
# HTTPS server
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name {{ site }};
client_max_body_size 4G;
root {{ site_base }}/{{ site }}/root;
index index.html;
keepalive_timeout 5;
# location / {
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header Host $http_host;
# proxy_set_header X-Forwarded-Proto $scheme;
# proxy_redirect off;
# proxy_buffering off;
# proxy_pass http://{{ site }}_app;
# }
# location /static {
# alias {{ site_base }}/{{ site }}/static;
# }
ssl on;
ssl_certificate /etc/letsencrypt/live/{{ site }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ site }}/privkey.pem;
ssl_session_timeout 5m;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_dhparam {{ ssl_dhparams }};
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains";
ssl_session_cache shared:SSL:50m;
}
"""
@click.command()
@click.argument('site',default='example.com')
@click.option('--app-port', default='8000', help='port number of app server')
@click.option('--ssl-dhparams', default='/etc/ssl/dhparams.pem', help='path to DH params file')
@click.option('--site-base', default='/home/web', help='path to site base directory')
def command(site, app_port, ssl_dhparams, site_base):
env = jinja2.Environment()
vars = dict(
site=site,
app_port=app_port,
ssl_dhparams=ssl_dhparams,
site_base=site_base,
)
template_object = env.from_string(template, globals=vars)
rendered_template = template_object.render()
sys.stdout.write(rendered_template)
if __name__ == '__main__':
command()
@phoikoi
Copy link
Author

phoikoi commented Aug 9, 2016

This program generates an nginx configuration file customized for the site passed as an argument on the command line. Various other substitutions are available.

The SSL certificate/key paths are assumed to be using the Let's Encrypt (certbot) scheme, and the various other SSL parameters are specified in such a way as to get a high score on the Qualys SSL test. Whether or not this is sufficiently secure for your needs is up to you. Note that in order to get the high score, the parameters as set will be incompatible with some older clients.

There are also some commented-out bits to facilitate usage with a reverse-proxied app server such as gunicorn for python, and an alias for static files such as would be used with Django's collectstatic command.

The generated config file also specifies HTTP2 as the protocol, so you'll need to have a fairly recent version of nginx. If you want to use it with an older version, just change the http2 to http.

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