From adf4752e1ccafa2aa731b552ba693bda29985752 Mon Sep 17 00:00:00 2001 From: MattIPv4 Date: Thu, 14 May 2020 18:01:55 +0100 Subject: [PATCH] Some more conf files --- src/nginxconfig/generators/drupal.conf.js | 34 ++++++ src/nginxconfig/generators/general.conf.js | 103 ++++++++++++++++++ .../generators/letsencrypt.conf.js | 11 ++ src/nginxconfig/generators/magento.conf.js | 65 +++++++++++ src/nginxconfig/templates/app.vue | 2 +- src/nginxconfig/util/types_extensions.js | 14 +++ 6 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 src/nginxconfig/generators/drupal.conf.js create mode 100644 src/nginxconfig/generators/general.conf.js create mode 100644 src/nginxconfig/generators/letsencrypt.conf.js create mode 100644 src/nginxconfig/generators/magento.conf.js create mode 100644 src/nginxconfig/util/types_extensions.js diff --git a/src/nginxconfig/generators/drupal.conf.js b/src/nginxconfig/generators/drupal.conf.js new file mode 100644 index 0000000..9d1596e --- /dev/null +++ b/src/nginxconfig/generators/drupal.conf.js @@ -0,0 +1,34 @@ +export default (domains, 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; +}; diff --git a/src/nginxconfig/generators/general.conf.js b/src/nginxconfig/generators/general.conf.js new file mode 100644 index 0000000..3047fac --- /dev/null +++ b/src/nginxconfig/generators/general.conf.js @@ -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; +}; diff --git a/src/nginxconfig/generators/letsencrypt.conf.js b/src/nginxconfig/generators/letsencrypt.conf.js new file mode 100644 index 0000000..76061b7 --- /dev/null +++ b/src/nginxconfig/generators/letsencrypt.conf.js @@ -0,0 +1,11 @@ +export default (domains, global) => { + const config = {}; + + config['# ACME-challenge'] = ''; + config['location ^~ /.well-known/acme-challenge/'] = { + root: global.https.letsEncryptRoot.computed.replace(/\/+$/, ''), + }; + + // Done! + return config; +}; diff --git a/src/nginxconfig/generators/magento.conf.js b/src/nginxconfig/generators/magento.conf.js new file mode 100644 index 0000000..6d8f570 --- /dev/null +++ b/src/nginxconfig/generators/magento.conf.js @@ -0,0 +1,65 @@ +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', + }, + }; + + // TODO: static route + // TODO: static files + // TODO: deny cron + + // Done! + return config; +}; diff --git a/src/nginxconfig/templates/app.vue b/src/nginxconfig/templates/app.vue index db2ed87..7c0e521 100644 --- a/src/nginxconfig/templates/app.vue +++ b/src/nginxconfig/templates/app.vue @@ -118,7 +118,7 @@ limitations under the License. return this.$data.global.nginx.nginxConfigDirectory.computed.replace(/\/+$/, ''); }, confFiles() { - return generators(this.$data.domains, this.$data.global); + return generators(this.$data.domains.filter(d => d !== null), this.$data.global); }, }, mounted() { diff --git a/src/nginxconfig/util/types_extensions.js b/src/nginxconfig/util/types_extensions.js new file mode 100644 index 0000000..1b952dd --- /dev/null +++ b/src/nginxconfig/util/types_extensions.js @@ -0,0 +1,14 @@ +export const gzipTypes = 'text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml'; + +export const extensions = { + assets: 'css(\\.map)?|js(\\.map)?', + fonts: 'ttf|ttc|otf|eot|woff2?', + svg: 'svgz?', + images: 'jpe?g|png|gif|ico|cur|heic|webp|tiff?', + audio: 'mp3|m4a|aac|ogg|midi?|wav', + video: 'mp4|mov|webm|mpe?g|avi|ogv|flv|wmv', + docs: 'pdf|' + + 'docx?|dotx?|docm|dotm|' + + 'xlsx?|xltx?|xlsm|xltm|' + + 'pptx?|potx?|pptm|potm|ppsx?', +};