mirror of
https://github.com/digitalocean/nginxconfig.io.git
synced 2025-11-05 18:56:09 +08:00
Move confs into own dir
This commit is contained in:
34
src/nginxconfig/generators/conf/drupal.conf.js
Normal file
34
src/nginxconfig/generators/conf/drupal.conf.js
Normal file
@@ -0,0 +1,34 @@
|
||||
export default global => {
|
||||
const config = {};
|
||||
|
||||
config['# Drupal: deny private files'] = '';
|
||||
config['location ~ ^/sites/.*/private/'] = {
|
||||
deny: 'all',
|
||||
};
|
||||
|
||||
config['# Drupal: deny php in files'] = '';
|
||||
config['location ~ ^/sites/[^/]+/files/.*\\.php$'] = {
|
||||
deny: 'all',
|
||||
};
|
||||
|
||||
config['# Drupal: deny php in vendor'] = '';
|
||||
config['location ~ /vendor/.*\\.php$'] = {
|
||||
deny: 'all',
|
||||
};
|
||||
|
||||
config['# Drupal: handle private files'] = '';
|
||||
config['location ~ ^(/[a-z\\-]+)?/system/files/'] = {
|
||||
try_files: '$uri /index.php?$query_string',
|
||||
};
|
||||
|
||||
if (global.security.limitReq.computed) {
|
||||
config['# Drupal: throttle user functions'] = '';
|
||||
config['location ~ ^/user/(?:login|register|password)'] = {
|
||||
limit_req: 'zone=login burst=2 nodelay',
|
||||
try_files: '$uri /index.php?$query_string',
|
||||
};
|
||||
}
|
||||
|
||||
// Done!
|
||||
return config;
|
||||
};
|
||||
103
src/nginxconfig/generators/conf/general.conf.js
Normal file
103
src/nginxconfig/generators/conf/general.conf.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import { gzipTypes, extensions } from '../../util/types_extensions';
|
||||
|
||||
export default (domains, global) => {
|
||||
const config = {};
|
||||
|
||||
config['# favicon.ico'] = '';
|
||||
config['location = /favicon.ico'] = {
|
||||
log_not_found: 'off',
|
||||
};
|
||||
if (global.logging.accessLog.computed) config['location = /favicon.ico'].access_log = 'off';
|
||||
|
||||
config['# robots.txt'] = '';
|
||||
config['location = /robots.txt'] = {
|
||||
log_not_found: 'off',
|
||||
};
|
||||
if (global.logging.accessLog.computed) config['location = /robots.txt'].access_log = 'off';
|
||||
|
||||
if (domains.every(d => d.routing.root.computed)) {
|
||||
if (global.performance.assetsExpiration.computed === global.performance.mediaExpiration.computed) {
|
||||
if (global.performance.assetsExpiration.computed) {
|
||||
// Assets & media combined
|
||||
config['# assets, media'] = '';
|
||||
const loc = `location ~* \\.(?:${extensions.assets}|${extensions.images}|${extensions.audio}|${extensions.video})$`;
|
||||
config[loc] = {
|
||||
expires: global.performance.assetsExpiration.computed,
|
||||
};
|
||||
if (global.logging.accessLog.computed) config[loc].access_log = 'off';
|
||||
}
|
||||
} else {
|
||||
// Assets & media separately
|
||||
if (global.performance.assetsExpiration.computed) {
|
||||
config['# assets'] = '';
|
||||
const loc = `location ~* \\.(?:${extensions.assets})$`;
|
||||
config[loc] = {
|
||||
expires: global.performance.assetsExpiration.computed,
|
||||
};
|
||||
if (global.logging.accessLog.computed) config[loc].access_log = 'off';
|
||||
}
|
||||
|
||||
if (global.performance.mediaExpiration.computed) {
|
||||
config['# media'] = '';
|
||||
const loc = `location ~* \\.(?:${extensions.images}|${extensions.audio}|${extensions.video})$`;
|
||||
config[loc] = {
|
||||
expires: global.performance.mediaExpiration.computed,
|
||||
};
|
||||
if (global.logging.accessLog.computed) config[loc].access_log = 'off';
|
||||
}
|
||||
}
|
||||
|
||||
if (global.performance.svgExpiration.computed === global.performance.fontsExpiration.computed) {
|
||||
if (global.performance.svgExpiration.computed) {
|
||||
// SVG & fonts combined
|
||||
config['# svg, fonts'] = '';
|
||||
const loc = `location ~* \\.(?:${extensions.svg}|${extensions.fonts})$`;
|
||||
config[loc] = {
|
||||
add_header: 'Access-Control-Allow-Origin "*"',
|
||||
expires: global.performance.svgExpiration.computed,
|
||||
};
|
||||
if (global.logging.accessLog.computed) config[loc].access_log = 'off';
|
||||
}
|
||||
} else {
|
||||
// SVG & fonts separately
|
||||
if (global.performance.svgExpiration.computed) {
|
||||
config['# svg'] = '';
|
||||
const loc = `location ~* \\.${extensions.svg}$`;
|
||||
config[loc] = {
|
||||
add_header: 'Access-Control-Allow-Origin "*"',
|
||||
expires: global.performance.svgExpiration.computed,
|
||||
};
|
||||
if (global.logging.accessLog.computed) config[loc].access_log = 'off';
|
||||
}
|
||||
|
||||
if (global.performance.fontsExpiration.computed) {
|
||||
config['# fonts'] = '';
|
||||
const loc = `location ~* \\.${extensions.fonts}$`;
|
||||
config[loc] = {
|
||||
add_header: 'Access-Control-Allow-Origin "*"',
|
||||
expires: global.performance.fontsExpiration.computed,
|
||||
};
|
||||
if (global.logging.accessLog.computed) config[loc].access_log = 'off';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (global.performance.gzipCompression.computed) {
|
||||
config['# gzip'] = '';
|
||||
config.gzip = 'on';
|
||||
config.gzip_vary = 'on';
|
||||
config.gzip_proxied = 'any';
|
||||
config.gzip_comp_level = 6;
|
||||
config.gzip_types = gzipTypes;
|
||||
}
|
||||
|
||||
if (global.performance.brotliCompression.computed) {
|
||||
config['# brotli'] = '';
|
||||
config.brotli = 'on';
|
||||
config.brotli_comp_level = 6;
|
||||
config.brotli_types = gzipTypes;
|
||||
}
|
||||
|
||||
// Done!
|
||||
return config;
|
||||
};
|
||||
11
src/nginxconfig/generators/conf/letsencrypt.conf.js
Normal file
11
src/nginxconfig/generators/conf/letsencrypt.conf.js
Normal file
@@ -0,0 +1,11 @@
|
||||
export default global => {
|
||||
const config = {};
|
||||
|
||||
config['# ACME-challenge'] = '';
|
||||
config['location ^~ /.well-known/acme-challenge/'] = {
|
||||
root: global.https.letsEncryptRoot.computed.replace(/\/+$/, ''),
|
||||
};
|
||||
|
||||
// Done!
|
||||
return config;
|
||||
};
|
||||
89
src/nginxconfig/generators/conf/magento.conf.js
Normal file
89
src/nginxconfig/generators/conf/magento.conf.js
Normal file
@@ -0,0 +1,89 @@
|
||||
export default () => {
|
||||
const config = {};
|
||||
|
||||
config['# Magento: setup'] = '';
|
||||
config['location ^~ /setup'] = {
|
||||
root: '$base',
|
||||
|
||||
'# allow index.php': '',
|
||||
'location ~ ^/setup/index.php': {
|
||||
include: 'nginxconfig.io/php_fastcgi.conf',
|
||||
},
|
||||
|
||||
'# deny everything except pub': '',
|
||||
'location ~ ^/setup/(?!pub/).': {
|
||||
deny: 'all',
|
||||
},
|
||||
};
|
||||
|
||||
config['# Magento: update'] = '';
|
||||
config['location ^~ /update'] = {
|
||||
root: '$base',
|
||||
|
||||
'# allow index.php': '',
|
||||
'location ~ ^/update/index.php': {
|
||||
include: 'nginxconfig.io/php_fastcgi.conf',
|
||||
},
|
||||
|
||||
'# deny everything except pub': '',
|
||||
'location ~ ^/update/(?!pub/).': {
|
||||
deny: 'all',
|
||||
},
|
||||
};
|
||||
|
||||
config['# Magento: media files'] = '';
|
||||
config['location ^~ /media/'] = {
|
||||
try_files: '$uri $uri/ /get.php?$args',
|
||||
|
||||
'location ~* \\.(?:ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$': {
|
||||
expires: '+1y',
|
||||
add_header: 'Cache-Control "public"',
|
||||
try_files: '$uri $uri/ /get.php?$args',
|
||||
},
|
||||
|
||||
'location ~* \\.(?:zip|gz|gzip|bz2|csv|xml)$': {
|
||||
expires: 'off',
|
||||
add_header: 'Cache-Control "no-store"',
|
||||
try_files: '$uri $uri/ /get.php?$args',
|
||||
},
|
||||
|
||||
'location ~ ^/media/theme_customization/.*\\.xml': {
|
||||
deny: 'all',
|
||||
},
|
||||
|
||||
'location ~ ^/media/(?:customer|downloadable|import)/': {
|
||||
deny: 'all',
|
||||
},
|
||||
};
|
||||
|
||||
config['# Magento: static route'] = '';
|
||||
config['location @magento_static'] = {
|
||||
rewrite: '^/static/(version\\d*/)?(.*)$ /static.php?resource=$2 last',
|
||||
};
|
||||
|
||||
config['# Magento: static files'] = '';
|
||||
config['location ^~ /static/'] = {
|
||||
expires: 'max',
|
||||
try_files: '$uri $uri/ @magento_static',
|
||||
|
||||
'location ~* \\.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$': {
|
||||
expires: '+1y',
|
||||
add_header: 'Cache-Control "public"',
|
||||
try_files: '$uri $uri/ magento_static',
|
||||
},
|
||||
|
||||
'location ~* .(zip|gz|gzip|bz2|csv|xml)$': {
|
||||
expires: 'off',
|
||||
add_header: 'Cache-Control "no-store"',
|
||||
try_files: '$uri $uri/ @magento_static',
|
||||
},
|
||||
};
|
||||
|
||||
config['# Magento: deny cron'] = '';
|
||||
config['location ~ cron\\.php'] = {
|
||||
deny: 'all',
|
||||
};
|
||||
|
||||
// Done!
|
||||
return config;
|
||||
};
|
||||
113
src/nginxconfig/generators/conf/nginx.conf.js
Normal file
113
src/nginxconfig/generators/conf/nginx.conf.js
Normal file
@@ -0,0 +1,113 @@
|
||||
import sslProfiles from '../../util/ssl_profiles';
|
||||
|
||||
export default (domains, global) => {
|
||||
const config = {};
|
||||
|
||||
// Source
|
||||
config['# Generated by nginxconfig.io'] = '';
|
||||
config[`# ${window.location.protocol}//${window.location.host}${window.location.pathname}${window.location.search}`] = '';
|
||||
|
||||
// Basic nginx conf
|
||||
config.user = global.nginx.user.computed;
|
||||
config.pid = global.nginx.pid.computed;
|
||||
config.worker_processes = global.nginx.workerProcesses.computed;
|
||||
config.worker_rlimit_nofile = 65535;
|
||||
config.events = {
|
||||
multi_accept: 'on',
|
||||
worker_connections: 65535,
|
||||
};
|
||||
|
||||
// HTTP (kv so we can use the same key multiple times)
|
||||
config.http = [];
|
||||
|
||||
if (global.php.phpBackupServer.computed)
|
||||
config.http.push(['upstream php', {
|
||||
server: [
|
||||
`${global.php.phpServer.computed[0] === '/' ? 'unix:' : ''}${global.php.phpServer.computed}`,
|
||||
`${global.php.phpBackupServer.computed[0] === '/' ? 'unix:' : ''}${global.php.phpBackupServer.computed} backup`,
|
||||
],
|
||||
}]);
|
||||
|
||||
config.http.push(['charset', 'utf-8']);
|
||||
config.http.push(['sendfile', 'on']);
|
||||
config.http.push(['tcp_nopush', 'on']);
|
||||
config.http.push(['tcp_nodelay', 'on']);
|
||||
if (!global.security.serverTokens.computed)
|
||||
config.http.push(['server_tokens', 'off']);
|
||||
if (!global.logging.logNotFound.computed)
|
||||
config.http.push(['log_not_found', 'off']);
|
||||
config.http.push(['types_hash_max_size', 2048]);
|
||||
config.http.push(['client_max_body_size', `${global.nginx.clientMaxBodySize.computed}M`]);
|
||||
|
||||
config.http.push(['# MIME', '']);
|
||||
config.http.push(['include', 'mime.types']);
|
||||
config.http.push(['default_type', 'application/octet-stream']);
|
||||
|
||||
config.http.push(['# Logging', '']);
|
||||
config.http.push(['access_log', global.logging.accessLog.computed.trim() || 'off']);
|
||||
config.http.push(['error_log', global.logging.errorLog.computed.trim() || '/dev/null']);
|
||||
|
||||
if (global.security.limitReq.computed) {
|
||||
config.http.push(['# Limits', '']);
|
||||
config.http.push(['limit_req_log_level', 'warn']);
|
||||
config.http.push(['limit_req_zone', '$binary_remote_addr zone=login:10m rate=10r/m']);
|
||||
}
|
||||
|
||||
// HTTPS
|
||||
let hasHttps = false;
|
||||
for (const domain of domains) {
|
||||
if (domain && domain.https && domain.https.https && domain.https.https.computed) {
|
||||
hasHttps = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasHttps) {
|
||||
config.http.push(['# SSL', '']);
|
||||
config.http.push(['ssl_session_timeout', '1d']);
|
||||
config.http.push(['ssl_session_cache', 'shared:SSL:10m']);
|
||||
config.http.push(['ssl_session_tickets', 'off']);
|
||||
|
||||
if (sslProfiles[global.https.sslProfile.computed].dh_param_size) {
|
||||
config.http.push(['# Diffie-Hellman parameter for DHE ciphersuites', '']);
|
||||
config.http.push(['ssl_dhparam', `${global.nginx.nginxConfigDirectory.computed.replace(/\/+$/, '')}/dhparam.pem`]);
|
||||
}
|
||||
|
||||
config.http.push([`# ${sslProfiles[global.https.sslProfile.computed].name} configuration`, '']);
|
||||
config.http.push(['ssl_protocols', sslProfiles[global.https.sslProfile.computed].protocols.join(' ')]);
|
||||
if (sslProfiles[global.https.sslProfile.computed].ciphers.length)
|
||||
config.http.push(['ssl_ciphers', sslProfiles[global.https.sslProfile.computed].ciphers.join(':')]);
|
||||
if (sslProfiles[global.https.sslProfile.computed].server_preferred_order)
|
||||
config.http.push(['ssl_prefer_server_ciphers', 'on']);
|
||||
|
||||
config.http.push(['# OCSP Stapling', '']);
|
||||
config.http.push(['ssl_stapling', 'on']);
|
||||
config.http.push(['ssl_stapling_verify', 'on']);
|
||||
|
||||
if (global.https.ocspCloudflare.computed
|
||||
|| global.https.ocspGoogle.computed
|
||||
|| global.https.ocspOpenDns.computed) {
|
||||
const ips = [];
|
||||
if (global.https.ocspCloudflare.computed) ips.push('1.1.1.1', '1.0.0.1');
|
||||
if (global.https.ocspGoogle.computed) ips.push('8.8.8.8', '8.8.4.4');
|
||||
if (global.https.ocspOpenDns.computed) ips.push('208.67.222.222', '208.67.220.220');
|
||||
|
||||
config.http.push(['resolver', `${ips.join(' ')} valid=60s`]);
|
||||
config.http.push(['resolver_timeout', '2s']);
|
||||
}
|
||||
}
|
||||
|
||||
// Configs!
|
||||
config.http.push(['# Load configs', '']);
|
||||
config.http.push(['include', [
|
||||
`${global.nginx.nginxConfigDirectory.computed.replace(/\/+$/, '')}/conf.d/*.conf`,
|
||||
global.tools.modularizedStructure.computed ? `${global.nginx.nginxConfigDirectory.computed.replace(/\/+$/, '')}/sites-enabled/*` : '',
|
||||
].filter(x => x.length)]);
|
||||
|
||||
// Single file configs
|
||||
if (!global.tools.modularizedStructure.computed) {
|
||||
// TODO: figure out merging in all the other configs
|
||||
}
|
||||
|
||||
// Done!
|
||||
return config;
|
||||
};
|
||||
33
src/nginxconfig/generators/conf/php_fastcgi.conf.js
Normal file
33
src/nginxconfig/generators/conf/php_fastcgi.conf.js
Normal file
@@ -0,0 +1,33 @@
|
||||
export default (domains, global) => {
|
||||
const legacyRouting = domains.some(d => d.routing.legacyPhpRouting.computed);
|
||||
const config = {};
|
||||
|
||||
if (legacyRouting) {
|
||||
config['# split path'] = '';
|
||||
config.fastcgi_split_path_info = '^(.+\\.php)(/.+)$';
|
||||
config.set = '$_fastcgi_path_info $fastcgi_path_info';
|
||||
}
|
||||
|
||||
config['# 404'] = '';
|
||||
config.try_files = '$fastcgi_script_name =404';
|
||||
|
||||
config['# default fastcgi_params'] = '';
|
||||
config.include = 'fastcgi_params';
|
||||
|
||||
config['# fastcgi settings'] = '';
|
||||
config.fastcgi_pass = domains.some(d => d.php.php.computed) && global.php.phpBackupServer
|
||||
? 'php'
|
||||
: ((global.php.phpServer.computed[0] === '/' ? 'unix:' : '') + global.php.phpServer.computed);
|
||||
config.fastcgi_index = 'index.php';
|
||||
config.fastcgi_buffers = '8 16k';
|
||||
config.fastcgi_buffer_size = '32k';
|
||||
|
||||
config['# fastcgi params'] = '';
|
||||
config['fastcgi_param DOCUMENT_ROOT'] = '$realpath_root';
|
||||
config['fastcgi_param SCRIPT_FILENAME'] = '$realpath_root$fastcgi_script_name';
|
||||
if (legacyRouting) config['fastcgi_param PATH_INFO'] = '$_fastcgi_path_info';
|
||||
config['fastcgi_param PHP_ADMIN_VALUE'] = '"open_basedir=$base/:/usr/lib/php/:/tmp/"';
|
||||
|
||||
// Done!
|
||||
return config;
|
||||
};
|
||||
18
src/nginxconfig/generators/conf/proxy.conf.js
Normal file
18
src/nginxconfig/generators/conf/proxy.conf.js
Normal file
@@ -0,0 +1,18 @@
|
||||
export default () => {
|
||||
const config = {};
|
||||
|
||||
config.proxy_http_version = '1.1';
|
||||
config.proxy_cache_bypass = '$http_upgrade';
|
||||
|
||||
config['proxy_set_header Upgrade'] = '$http_upgrade';
|
||||
config['proxy_set_header Connection'] = '"upgrade"';
|
||||
config['proxy_set_header Host'] = '$host';
|
||||
config['proxy_set_header X-Real-IP'] = '$remote_addr';
|
||||
config['proxy_set_header X-Forwarded-For'] = '$proxy_add_x_forwarded_for';
|
||||
config['proxy_set_header X-Forwarded-Proto'] = '$scheme';
|
||||
config['proxy_set_header X-Forwarded-Host'] = '$host';
|
||||
config['proxy_set_header X-Forwarded-Port'] = '$server_port';
|
||||
|
||||
// Done!
|
||||
return config;
|
||||
};
|
||||
17
src/nginxconfig/generators/conf/python_uwsgi.conf.js
Normal file
17
src/nginxconfig/generators/conf/python_uwsgi.conf.js
Normal file
@@ -0,0 +1,17 @@
|
||||
export default global => {
|
||||
const config = {};
|
||||
|
||||
config['# default uwsgi_params'] = '';
|
||||
config.include = 'uwsgi_params';
|
||||
|
||||
config['# uwsgi settings'] = '';
|
||||
config.uwsgi_pass = (global.python.pythonServer.computed[0] === '/' ? 'unix:' : '')
|
||||
+ global.python.pythonServer.computed;
|
||||
config['uwsgi_param Host'] = '$host';
|
||||
config['uwsgi_param X-Real-IP'] = '$remote_addr';
|
||||
config['uwsgi_param X-Forwarded-For'] = '$proxy_add_x_forwarded_for';
|
||||
config['uwsgi_param X-Forwarded-Proto'] = '$http_x_forwarded_proto';
|
||||
|
||||
// Done!
|
||||
return config;
|
||||
};
|
||||
29
src/nginxconfig/generators/conf/security.conf.js
Normal file
29
src/nginxconfig/generators/conf/security.conf.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import commonHsts from '../../util/common_hsts';
|
||||
|
||||
export default (domains, global) => {
|
||||
const config = [];
|
||||
|
||||
config.push(['# security headers', '']);
|
||||
config.push(['add_header', 'X-Frame-Options "SAMEORIGIN" always']);
|
||||
config.push(['add_header', 'X-XSS-Protection "1; mode=block" always']);
|
||||
config.push(['add_header', 'X-Content-Type-Options "nosniff" always']);
|
||||
config.push(['add_header', `Referrer-Policy "${global.security.referrerPolicy.computed}" always`]);
|
||||
|
||||
if (global.security.contentSecurityPolicy.computed)
|
||||
config.push(['add_header', `Content-Security-Policy "${global.security.contentSecurityPolicy.computed}" always`]);
|
||||
|
||||
// Every domain has HSTS enabled, and they all have same hstsSubdomains/hstsPreload settings
|
||||
if (commonHsts(domains)) {
|
||||
const commonHSTSSubdomains = domains.length && domains[0].https.hstsSubdomains.computed;
|
||||
const commonHSTSPreload = domains.length && domains[0].https.hstsPreload.computed;
|
||||
config.push(['add_header', `Strict-Transport-Security "max-age=31536000${commonHSTSSubdomains ? '; includeSubDomains' : ''}${commonHSTSPreload ? '; preload' : ''}" always`]);
|
||||
}
|
||||
|
||||
config.push(['# . files', '']);
|
||||
config.push(['location ~ /\\.(?!well-known)', {
|
||||
deny: 'all',
|
||||
}]);
|
||||
|
||||
// Done!
|
||||
return config;
|
||||
};
|
||||
312
src/nginxconfig/generators/conf/website.conf.js
Normal file
312
src/nginxconfig/generators/conf/website.conf.js
Normal file
@@ -0,0 +1,312 @@
|
||||
import { getSslCertificate, getSslCertificateKey } from '../../util/get_ssl_certificate';
|
||||
import { getAccessLogDomainPath, getErrorLogDomainPath } from '../../util/get_log_paths';
|
||||
import { extensions, gzipTypes } from '../../util/types_extensions';
|
||||
import commonHsts from '../../util/common_hsts';
|
||||
import securityConf from './security.conf';
|
||||
import pythonConf from './python_uwsgi.conf';
|
||||
import proxyConf from './proxy.conf';
|
||||
import phpConf from './php_fastcgi.conf';
|
||||
import generalConf from './general.conf';
|
||||
import wordPressConf from './wordpress.conf';
|
||||
import drupalConf from './drupal.conf';
|
||||
import magentoConf from './magento.conf';
|
||||
import letsEncryptConf from './letsencrypt.conf';
|
||||
|
||||
const sslConfig = (domain, global) => {
|
||||
const config = [];
|
||||
if (domain.https.https.computed) {
|
||||
config.push(['# SSL', '']);
|
||||
config.push(['ssl_certificate', getSslCertificate(domain, global)]);
|
||||
config.push(['ssl_certificate_key', getSslCertificateKey(domain, global)]);
|
||||
|
||||
// Let's encrypt
|
||||
if (domain.https.certType.computed === 'letsEncrypt')
|
||||
config.push(['ssl_trusted_certificate',
|
||||
`/etc/letsencrypt/live/${domain.server.domain.computed}/chain.pem`]);
|
||||
}
|
||||
return config;
|
||||
};
|
||||
|
||||
const httpsListen = domain => {
|
||||
const config = [];
|
||||
|
||||
// HTTPS
|
||||
config.push(['listen', `${domain.server.listenIpv4.computed === '*' ? '' : `${domain.server.listenIpv4.computed}:`}443 ssl${domain.https.http2.computed ? ' http2' : ''}`]);
|
||||
|
||||
// v6
|
||||
if (domain.server.listenIpv6.computed)
|
||||
config.push(['listen',
|
||||
`[${domain.server.listenIpv6.computed}]:443 ssl${domain.https.http2.computed ? ' http2' : ''}`]);
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
const httpListen = domain => {
|
||||
const config = [];
|
||||
|
||||
// Not HTTPS
|
||||
config.push(['listen', `${domain.server.listenIpv4.computed === '*' ? '' : `${domain.server.listenIpv4.computed}:`}80`]);
|
||||
|
||||
// v6
|
||||
if (domain.server.listenIpv6.computed)
|
||||
config.push(['listen', `[${domain.server.listenIpv6.computed}]:80`]);
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
const listenConfig = domain => {
|
||||
if (domain.https.https.computed) return httpsListen(domain);
|
||||
return httpListen(domain);
|
||||
};
|
||||
|
||||
export default (domain, domains, global) => {
|
||||
// Use kv so we can use the same key multiple times
|
||||
const config = [];
|
||||
|
||||
// Build the server config on its own before adding it to the parent config
|
||||
const serverConfig = [];
|
||||
|
||||
// Not HTTPS or not force HTTPS
|
||||
if (!domain.https.https.computed || !domain.https.forceHttps.computed) serverConfig.push(...httpListen(domain));
|
||||
|
||||
// HTTPS
|
||||
if (domain.https.https.computed) serverConfig.push(...httpsListen(domain));
|
||||
|
||||
serverConfig.push(['server_name',
|
||||
`${domain.server.wwwSubdomain.computed ? 'www.' : ''}${domain.server.domain.computed}`]);
|
||||
|
||||
// PHP or Django
|
||||
if (domain.php.php.computed || (domain.python.python.computed && domain.python.djangoRules.computed)) {
|
||||
serverConfig.push(['set', `$base ${domain.server.path.computed}`]);
|
||||
|
||||
// root
|
||||
if (domain.routing.root.computed)
|
||||
serverConfig.push(['root', `$base${domain.server.documentRoot.computed}`]);
|
||||
}
|
||||
|
||||
// Not PHP and not Django and root
|
||||
if (!domain.php.php.computed
|
||||
&& (!domain.python.python.computed || !domain.python.djangoRules.computed)
|
||||
&& domain.routing.root.computed)
|
||||
serverConfig.push(['root', `${domain.server.path.computed}${domain.server.documentRoot.computed}`]);
|
||||
|
||||
// HTTPS
|
||||
serverConfig.push(...sslConfig(domain, global));
|
||||
|
||||
// HSTS
|
||||
if (!commonHsts(domains) && domain.https.hsts.computed) {
|
||||
serverConfig.push(['# HSTS', '']);
|
||||
serverConfig.push(['add_header Strict-Transport-Security',
|
||||
`'"max-age=31536000${domain.https.hstsSubdomains.computed ? '; includeSubDomains' : ''}${domain.https.hstsPreload.computed ? '; preload' : ''}" always'`]);
|
||||
}
|
||||
|
||||
// Security
|
||||
if (global.tools.modularizedStructure.computed) {
|
||||
// Modularized
|
||||
serverConfig.push(['# security', '']);
|
||||
serverConfig.push(['include', 'nginxconfig.io/security.conf']);
|
||||
} else {
|
||||
// Unified
|
||||
serverConfig.push(...securityConf(domains, global));
|
||||
}
|
||||
|
||||
// Access log or error log for domain
|
||||
if (domain.logging.accessLog.computed || domain.logging.errorLog.computed) {
|
||||
serverConfig.push(['# logging', '']);
|
||||
|
||||
if (domain.logging.accessLog.computed)
|
||||
serverConfig.push(['access_log', getAccessLogDomainPath(domain, global)]);
|
||||
|
||||
if (domain.logging.errorLog.computed)
|
||||
serverConfig.push(['error_log', getErrorLogDomainPath(domain, global)]);
|
||||
}
|
||||
|
||||
// index.php
|
||||
if (domain.routing.index.computed === 'index.php') {
|
||||
serverConfig.push(['# index.php', '']);
|
||||
serverConfig.push(['index', 'index.php']);
|
||||
}
|
||||
|
||||
// Fallback index.html or index.php
|
||||
if ((domain.routing.fallbackHtml.computed || domain.routing.fallbackPhp.computed)
|
||||
&& (!domain.reverseProxy.reverseProxy.computed || domain.reverseProxy.path.computed !== '/')) {
|
||||
serverConfig.push([`# index.${domain.routing.fallbackHtml.computed ? 'html' : (domain.routing.fallbackPhp.computed ? 'php' : '')} fallback`, '']);
|
||||
serverConfig.push(['location /', {
|
||||
try_files: `$uri $uri/ /index.${domain.routing.fallbackHtml.computed ? '.html' : (domain.routing.fallbackPhp.computed ? '.php?$query_string' : '')}`,
|
||||
}]);
|
||||
}
|
||||
|
||||
// Fallback index.html and index.php
|
||||
if (domain.routing.fallbackHtml.computed && domain.routing.fallbackPhp.computed) {
|
||||
serverConfig.push(['# index.php fallback', '']);
|
||||
serverConfig.push([`location ~ ^${domain.routing.fallbackPhpPath.computed}`, {
|
||||
try_files: '$uri $uri/ /index.php?$query_string',
|
||||
}]);
|
||||
}
|
||||
|
||||
// Python
|
||||
if (domain.python.python.computed) {
|
||||
if (global.tools.modularizedStructure.computed) {
|
||||
// Modularized
|
||||
serverConfig.push(['location /', { include: 'nginxconfig.io/python_uwsgi.conf' }]);
|
||||
} else {
|
||||
// Unified
|
||||
serverConfig.push(['location /', pythonConf(global)]);
|
||||
}
|
||||
|
||||
// Django
|
||||
if (domain.python.djangoRules.computed) {
|
||||
serverConfig.push(['# Django media', '']);
|
||||
serverConfig.push(['location /media/', { alias: '$base/media/' }]);
|
||||
|
||||
serverConfig.push(['# Django static', '']);
|
||||
serverConfig.push(['location /static/', { alias: '$base/static/' }]);
|
||||
}
|
||||
}
|
||||
|
||||
// Reverse proxy
|
||||
if (domain.reverseProxy.reverseProxy.computed) {
|
||||
const locConf = [];
|
||||
locConf.push(['proxy_pass', domain.reverseProxy.proxyPass.computed]);
|
||||
|
||||
if (global.tools.modularizedStructure.computed) {
|
||||
// Modularized
|
||||
locConf.push(['include', 'nginxconfig.io/python_uwsgi.conf']);
|
||||
} else {
|
||||
// Unified
|
||||
locConf.push(...Object.entries(proxyConf()));
|
||||
}
|
||||
|
||||
serverConfig.push(['# reverse proxy', '']);
|
||||
serverConfig.push([`location ${domain.reverseProxy.path.computed}`, locConf]);
|
||||
}
|
||||
|
||||
// PHP
|
||||
if (domain.php.php.computed) {
|
||||
serverConfig.push(['# handle .php', '']);
|
||||
|
||||
const loc = `location ~ ${domain.routing.legacyPhpRouting.computed ? '[^/]\\.php(/|$)' : '\\.php$'}`;
|
||||
if (global.tools.modularizedStructure.computed) {
|
||||
// Modularized
|
||||
serverConfig.push([loc, { include: 'nginxconfig.io/php_fastcgi.conf' }]);
|
||||
} else {
|
||||
// Unified
|
||||
serverConfig.push([loc, phpConf(domains, global)]);
|
||||
}
|
||||
}
|
||||
|
||||
// Additional config
|
||||
if (global.tools.modularizedStructure.computed) {
|
||||
// Modularized
|
||||
serverConfig.push(['# additional config', '']);
|
||||
serverConfig.push(['include', 'nginxconfig.io/general.conf']);
|
||||
|
||||
if (domain.php.wordPressRules.computed) serverConfig.push(['include', 'nginxconfig.io/wordpress.conf']);
|
||||
if (domain.php.drupalRules.computed) serverConfig.push(['include', 'nginxconfig.io/drupal.conf']);
|
||||
if (domain.php.magentoRules.computed) serverConfig.push(['include', 'nginxconfig.io/magento.conf']);
|
||||
} else {
|
||||
// Unified
|
||||
serverConfig.push(...Object.entries(generalConf(domains, global)));
|
||||
|
||||
if (domain.php.wordPressRules.computed) serverConfig.push(...Object.entries(wordPressConf(global)));
|
||||
if (domain.php.drupalRules.computed) serverConfig.push(...Object.entries(drupalConf(global)));
|
||||
if (domain.php.magentoRules.computed) serverConfig.push(...Object.entries(magentoConf()));
|
||||
}
|
||||
|
||||
// Add the server config to the parent config now its built
|
||||
config.push(['server', serverConfig]);
|
||||
|
||||
// CDN!
|
||||
if (domain.server.cdnSubdomain.computed) {
|
||||
// Build the server config on its own before adding it to the parent config
|
||||
const cdnConfig = [];
|
||||
|
||||
cdnConfig.push(...listenConfig(domain));
|
||||
cdnConfig.push(['server_name', `cdn.${domain.server.domain.computed}`]);
|
||||
cdnConfig.push(['root', `${domain.server.path.computed}${domain.server.documentRoot.computed}`]);
|
||||
|
||||
// HTTPS
|
||||
cdnConfig.push(...sslConfig(domain, global));
|
||||
|
||||
cdnConfig.push(['# disable access_log', '']);
|
||||
cdnConfig.push(['access_log', 'off']);
|
||||
|
||||
// Gzip
|
||||
if (global.performance.gzipCompression.computed) {
|
||||
cdnConfig.push(['# gzip', '']);
|
||||
cdnConfig.push(['gzip', 'on']);
|
||||
cdnConfig.push(['gzip_vary', 'on']);
|
||||
cdnConfig.push(['gzip_proxied', 'any']);
|
||||
cdnConfig.push(['gzip_comp_level', 6]);
|
||||
cdnConfig.push(['gzip_types', gzipTypes]);
|
||||
}
|
||||
|
||||
cdnConfig.push(['# allow safe files', '']);
|
||||
cdnConfig.push([
|
||||
`location ~* \\.(?:${extensions.assets}|${extensions.fonts}|${extensions.svg}|${extensions.images}|${extensions.audio}|${extensions.video}|${extensions.docs})$`,
|
||||
[
|
||||
['add_header', 'Access-Control-Allow-Origin "*"'],
|
||||
['add_header', 'Cache-Control "public"'],
|
||||
['expires', '30d'],
|
||||
],
|
||||
]);
|
||||
|
||||
cdnConfig.push(['# deny everything else', '']);
|
||||
cdnConfig.push(['location /', { deny: 'all' }]);
|
||||
|
||||
// Add the CDN config to the parent config now its built
|
||||
config.push(['# CDN', '']);
|
||||
config.push(['server', cdnConfig]);
|
||||
}
|
||||
|
||||
// Subdomains redirect
|
||||
if (domain.server.redirectSubdomains.computed) {
|
||||
// Build the server config on its own before adding it to the parent config
|
||||
const redirectConfig = [];
|
||||
|
||||
redirectConfig.push(...listenConfig(domain));
|
||||
redirectConfig.push(['server_name', `${domain.server.wwwSubdomain.computed ? '' : '*'}.${domain.server.domain.computed}`]);
|
||||
|
||||
// HTTPS
|
||||
redirectConfig.push(...sslConfig(domain, global));
|
||||
|
||||
redirectConfig.push(['return', `301 http${domain.https.https.computed ? 's' : ''}://${domain.server.wwwSubdomain.computed ? 'www.' : ''}${domain.server.domain.computed}$request_uri`]);
|
||||
|
||||
// Add the redirect config to the parent config now its built
|
||||
config.push([`# ${domain.server.wwwSubdomain.computed ? 'non-www, ' : ''}subdomains redirect`, '']);
|
||||
config.push(['server', redirectConfig]);
|
||||
}
|
||||
|
||||
// HTTP redirect
|
||||
if (domain.https.forceHttps.computed) {
|
||||
// Build the server config on its own before adding it to the parent config
|
||||
const redirectConfig = [];
|
||||
|
||||
redirectConfig.push(...httpListen(domain));
|
||||
|
||||
if (domain.https.certType.computed === 'letsEncrypt') {
|
||||
// Let's encrypt
|
||||
|
||||
if (global.tools.modularizedStructure.computed) {
|
||||
// Modularized
|
||||
redirectConfig.push(['include', 'nginxconfig.io/letsencrypt.conf']);
|
||||
} else {
|
||||
// Unified
|
||||
redirectConfig.push(...Object.entries(letsEncryptConf(global)));
|
||||
}
|
||||
|
||||
redirectConfig.push(['location /', {
|
||||
return: `301 https://${domain.server.wwwSubdomain.computed ? 'www.' : ''}${domain.server.domain.computed}$request_uri`,
|
||||
}]);
|
||||
} else {
|
||||
// Custom cert
|
||||
redirectConfig.push(['return', `301 https://${domain.server.wwwSubdomain.computed ? 'www.' : ''}${domain.server.domain.computed}$request_uri`]);
|
||||
}
|
||||
|
||||
// Add the redirect config to the parent config now its built
|
||||
config.push(['# HTTP redirect', '']);
|
||||
config.push(['server', redirectConfig]);
|
||||
}
|
||||
|
||||
return config;
|
||||
};
|
||||
44
src/nginxconfig/generators/conf/wordpress.conf.js
Normal file
44
src/nginxconfig/generators/conf/wordpress.conf.js
Normal file
@@ -0,0 +1,44 @@
|
||||
export default global => {
|
||||
const config = {};
|
||||
|
||||
config['# WordPress: allow TinyMCE'] = '';
|
||||
config['location = /wp-includes/js/tinymce/wp-tinymce.php'] = {
|
||||
include: 'nginxconfig.io/php_fastcgi.conf',
|
||||
};
|
||||
|
||||
config['# WordPress: deny wp-content, wp-includes php files'] = '';
|
||||
config['~* ^/(?:wp-content|wp-includes)/.*\\.php$'] = {
|
||||
deny: 'all',
|
||||
};
|
||||
|
||||
config['# WordPress: deny wp-content/uploads nasty stuff'] = '';
|
||||
config['location ~* ^/wp-content/uploads/.*\\.(?:s?html?|php|js|swf)$'] = {
|
||||
deny: 'all',
|
||||
};
|
||||
|
||||
config['# WordPress: deny wp-content/plugins (except earlier rules)'] = '';
|
||||
config['location ~ ^/wp-content/plugins'] = {
|
||||
deny: 'all',
|
||||
};
|
||||
|
||||
config['# WordPress: deny scripts and styles concat'] = '';
|
||||
config['location ~* \\/wp-admin\\/load-(?:scripts|styles)\\.php'] = {
|
||||
deny: 'all',
|
||||
};
|
||||
|
||||
config['# WordPress: deny general stuff'] = '';
|
||||
config['location ~* ^/(?:xmlrpc\\.php|wp-links-opml\\.php|wp-config\\.php|wp-config-sample\\.php|wp-comments-post\\.php|readme\\.html|license\\.txt)$'] = {
|
||||
deny: 'all',
|
||||
};
|
||||
|
||||
if (global.security.limitReq.computed) {
|
||||
config['# WordPress: throttle wp-login.php'] = '';
|
||||
config['location = /wp-login.php'] = {
|
||||
limit_req: 'zone=login burst=2 nodelay',
|
||||
include: 'nginxconfig.io/php_fastcgi.conf',
|
||||
};
|
||||
}
|
||||
|
||||
// Done!
|
||||
return config;
|
||||
};
|
||||
Reference in New Issue
Block a user