Last active
April 29, 2016 05:59
-
-
Save jjones646/dd2c6c7455d1ae4f98ea to your computer and use it in GitHub Desktop.
A bare-bones setup that generates the NGINX configurations needed for hosting multiple WordPress websites on a single host. Supports individual SSL control.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2 | |
import os | |
import re | |
import sys | |
import argparse | |
import configparser | |
import pystache | |
from os.path import abspath, isfile, islink, join | |
parser = argparse.ArgumentParser(description='Generate NGINX site configurations from a config file describing each site\'s domain.') | |
parser.add_argument('--cfile', metavar='config-file', type=argparse.FileType('r'), default='sites.conf', help='configuration file for nginx sites templates to generate') | |
parser._parse_known_args(sys.argv[:1], argparse.Namespace()) | |
args = parser.parse_args() | |
# get the absolute path to the file and make sure it exists | |
cfile = abspath(args.cfile.name) | |
if not isfile(cfile): | |
print('unable to access {}'.format(cfile)) | |
sys.exit(1) | |
# read in the config file | |
config = configparser.ConfigParser() | |
config.read(cfile) | |
# read in the template file | |
subTemplate = '' | |
templateFn = abspath('/etc/nginx/snippets/wordpress-multi.conf') | |
with open(templateFn, 'r') as fp: | |
for line in fp: | |
line = line.partition('#')[0] | |
subTemplate += 4*' ' + line | |
siteTemplate = '' | |
templateFn = abspath('/etc/nginx/snippets/site-template.conf') | |
with open(templateFn, 'r') as fp: | |
for line in fp: | |
line = line.partition('#')[0] | |
siteTemplate += line | |
for c in config.sections(): | |
if config.has_option(c, 'domain'): | |
# read in the values from the config file | |
domain = config.get(c, 'domain') | |
rootDir = config.get(c, 'root_dir') | |
port = config.get(c, 'port') | |
sslKey = config.get(c, 'ssl_key') | |
sslCert = config.get(c, 'ssl_cert') | |
# create the template | |
subTemplateFilled = pystache.render(subTemplate, {'canonical_domain': domain, 'root_dir': rootDir}) | |
siteBlock = pystache.render(siteTemplate, {'sub_server_block': subTemplateFilled, 'listening_port': port, 'ssl_key': sslKey, 'ssl_cert': sslCert}) | |
# clean up a bit | |
siteBlockClean = os.linesep.join([s for s in siteBlock.splitlines() if s]) | |
# write out the configuration | |
outFile = abspath(join('/etc/nginx/sites-available', domain + '.conf')) | |
print('writing configuration for {} to {}'.format(c, outFile)) | |
with open(outFile, "w") as fp: | |
fp.write(siteBlockClean) | |
# enable the config | |
print('enabling site for {}'.format(c)) | |
linkName = abspath(join('/etc/nginx/sites-enabled', domain + '.conf')) | |
if not islink(linkName): | |
os.symlink(outFile, linkName) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#=========================================================== | |
# Title: site-template.conf | |
# Description: NGINX snippet for establishing an SSL | |
# frontend proxy for a locally running server. | |
# Author: Jonathan Jones | |
# Date: Apr. 29, 2016 | |
# Version: 0.1 | |
# Nginx Version: 1.6.2 | |
# Usage: Place file in /etc/nginx/snippets, | |
# and use 'include snippets/...' for | |
# use in other files. Place within | |
# a 'server {}' block. | |
#=========================================================== | |
# Requests to https. | |
server { | |
listen {{listening_port}}; | |
ssl on; | |
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; | |
ssl_certificate {{ssl_cert}}; | |
ssl_certificate_key {{ssl_key}}; | |
include snippets/wordpress-global.conf; | |
include snippets/redirect.conf; | |
{{sub_server_block}} | |
include snippets/denygit.conf; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[example1] | |
domain = example1.com | |
port = 443 | |
root_dir = /usr/share/nginx/sites/example1.com | |
ssl_cert = /etc/ssl/example1.com.crt | |
ssl_key = /etc/ssl/example1.com.key | |
[example2] | |
domain = example2.com | |
port = 443 | |
root_dir = /usr/share/nginx/sites/example2.com | |
ssl_cert = /etc/ssl/example2.com.crt | |
ssl_key = /etc/ssl/example2.com.key |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#=========================================================== | |
# Title: wordpress-global.conf | |
# Description: NGINX snippet for establishing some of the | |
# global declarations needed in a server block. | |
# Author: Jonathan Jones | |
# Date: Feb. 18, 2016 | |
# Version: 0.1 | |
# Nginx Version: 1.6.2 | |
# Usage: Place file in /etc/nginx/snippets, | |
# and use 'include snippets/...' for | |
# use in other files. Place within | |
# a 'server {}' block. | |
#=========================================================== | |
location = /favicon.ico { | |
log_not_found off; | |
access_log off; | |
} | |
location = /robots.txt { | |
allow all; | |
log_not_found off; | |
access_log off; | |
} | |
# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac). | |
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban) | |
location ~ /\. { | |
deny all; | |
} | |
# Deny access to any files with a .php extension in the uploads directory | |
# Works in sub-directory installs and also in multisite network | |
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban) | |
location ~* /(?:uploads|files)/.*\.php$ { | |
deny all; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#=========================================================== | |
# Title: wordpress-multi.conf | |
# Description: NGINX snippet for establishing some of the | |
# server declarations needed for hosting | |
# multiple wordpress websites on a single | |
# server. | |
# Author: Jonathan Jones | |
# Date: Feb. 21, 2016 | |
# Version: 0.1 | |
# Nginx Version: 1.6.2 | |
# Usage: Place file in /etc/nginx/snippets, | |
# and use 'include snippets/...' for | |
# use in other files. Place within | |
# a 'server {}' block. | |
#=========================================================== | |
location / { | |
try_files $uri $uri/ /index.php?$args; | |
} | |
# Directives to send expires headers and turn off 404 error logging. | |
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { | |
expires 24h; | |
log_not_found off; | |
} | |
location ~ ^/[_0-9a-zA-Z-]+/files/(.*)$ { | |
try_files /wp-content/blogs.dir/$blogid/files/$2 /wp-includes/ms-files.php?file=$2 ; | |
access_log off; | |
log_not_found off; | |
expires max; | |
} | |
# Rewrite multisite '.../wp-.*' and '.../*.php'. | |
if (!-e $request_filename) { | |
rewrite /wp-admin$ $scheme://$host$uri/ permanent; | |
rewrite ^/[_0-9a-zA-Z-]+(/wp-.*) $1 last; | |
rewrite ^/[_0-9a-zA-Z-]+(/.*\.php)$ $1 last; | |
} | |
# Pass all .php files onto a php-fpm/php-fcgi server. | |
location ~ \.php$ { | |
# Zero-day exploit defense. | |
# http://forum.nginx.org/read.php?2,88845,page=3 | |
# Won't work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi. | |
# Comment the 'try_files' line out if you set up php-fpm/php-fcgi on another machine. And then cross your fingers that you won't get hacked. | |
try_files $uri =404; | |
fastcgi_split_path_info ^(.+\.php)(/.+)$; | |
include fastcgi_params; | |
fastcgi_index index.php; | |
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | |
fastcgi_pass php; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#=========================================================== | |
# Title: wordpress-single.conf | |
# Description: NGINX snippet for establishing some of the | |
# server declarations needed for a single hosted | |
# wordpress server. | |
# Author: Jonathan Jones | |
# Date: Feb. 18, 2016 | |
# Version: 0.1 | |
# Nginx Version: 1.6.2 | |
# Usage: Place file in /etc/nginx/snippets, | |
# and use 'include snippets/...' for | |
# use in other files. Place within | |
# a 'server {}' block. | |
#=========================================================== | |
location / { | |
try_files $uri $uri/ /index.php?$args; | |
} | |
# Add trailing slash to */wp-admin requests. | |
rewrite /wp-admin$ $scheme://$host$uri/ permanent; | |
# Directives to send expires headers and turn off 404 error logging. | |
location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ { | |
access_log off; log_not_found off; expires max; | |
} | |
# Pass all .php files onto a php-fpm/php-fcgi server. | |
location ~ [^/]\.php(/|$) { | |
fastcgi_split_path_info ^(.+?\.php)(/.*)$; | |
if (!-f $document_root$fastcgi_script_name) { | |
return 404; | |
} | |
include fastcgi_params; | |
fastcgi_index index.php; | |
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | |
fastcgi_pass php; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment