From e6db3cea7b6bda5f234471121bb1ca0e493693ce Mon Sep 17 00:00:00 2001 From: MattIPv4 Date: Fri, 8 May 2020 17:58:38 +0100 Subject: [PATCH] Begin making conf files --- package-lock.json | 29 ++++++ package.json | 2 + src/nginxconfig/generators/index.js | 26 ++++++ src/nginxconfig/generators/nginx.conf.js | 114 +++++++++++++++++++++++ src/nginxconfig/templates/app.vue | 9 +- src/nginxconfig/util/ssl_profiles.js | 83 +++++++++++++++++ 6 files changed, 259 insertions(+), 4 deletions(-) create mode 100644 src/nginxconfig/generators/index.js create mode 100644 src/nginxconfig/generators/nginx.conf.js create mode 100644 src/nginxconfig/util/ssl_profiles.js diff --git a/package-lock.json b/package-lock.json index 785a17f..a413ff1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1117,6 +1117,14 @@ } } }, + "@webantic/nginx-config-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@webantic/nginx-config-parser/-/nginx-config-parser-1.2.0.tgz", + "integrity": "sha512-f+APSFykPZ06UaRgaxBCxAEUSG+qY9NVcGGqQkKfnJZaHBpqGxlR4FZixkdapnIadbw/uyWQ+96iTAXjyyJ+SQ==", + "requires": { + "glob": "^7.1.3" + } + }, "abab": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", @@ -1785,6 +1793,14 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "chevrotain": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-7.0.1.tgz", + "integrity": "sha512-B/44jrdw5GAzy483LEeVSgXSX0qOYM8lUd3l5+yf6Vl6OQjEUCm2BUiYbHRCIK6xCEvCLAFe1kj8uyV6+zdaVw==", + "requires": { + "regexp-to-ast": "0.5.0" + } + }, "chokidar": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", @@ -5388,6 +5404,14 @@ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", "dev": true }, + "nginx-format": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/nginx-format/-/nginx-format-0.1.7.tgz", + "integrity": "sha512-+6k0BGrASE0vE4X2sYujh0k2cZG+2DT0G82N3O+hS/7/7b3ZNzfHogthRGIJB+2xSJOvgIbJgKRVjqpyerPOtw==", + "requires": { + "chevrotain": "^7.0.1" + } + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -6649,6 +6673,11 @@ "safe-regex": "^1.1.0" } }, + "regexp-to-ast": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.5.0.tgz", + "integrity": "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==" + }, "regexpp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", diff --git a/package.json b/package.json index bcf03ef..c46fd70 100644 --- a/package.json +++ b/package.json @@ -34,10 +34,12 @@ "homepage": "https://github.com/do-community/nginxconfig-vue#readme", "dependencies": { "@babel/runtime": "^7.9.2", + "@webantic/nginx-config-parser": "^1.2.0", "babel-polyfill": "^6.26.0", "clone": "^2.1.2", "do-bulma": "git+https://github.com/do-community/do-bulma.git", "do-vue": "git+https://github.com/do-community/do-vue.git", + "nginx-format": "^0.1.7", "parcel-bundler": "^1.12.4", "pretty-checkbox-vue": "^1.1.9", "prismjs": "^1.20.0", diff --git a/src/nginxconfig/generators/index.js b/src/nginxconfig/generators/index.js new file mode 100644 index 0000000..ab47395 --- /dev/null +++ b/src/nginxconfig/generators/index.js @@ -0,0 +1,26 @@ +import ConfigParser from '@webantic/nginx-config-parser'; +const parser = new ConfigParser(); + +import { nginxFormat } from 'nginx-format'; + +import nginxConf from './nginx.conf'; + +const toConf = obj => { + // Convert the obj to nginx + const rawConf = nginxFormat(parser.toConf(obj)); + + const commentConf = rawConf + .replace(/((?:^|\n)(?:[^\S\r\n]*)#.+);($|\n)/g, '$1$2') // Remove semis on comments + .replace(/((?:^|\n)[^\S\r\n]*[^#\s].*[^\n])\n([^\S\r\n]*)#/g, '$1\n$2\n$2#') // Double linebreak before comment + .replace(/((?:^|\n)[^\S\r\n]*#.*\n[^\S\r\n]*#.*\n)([^\S\r\n]*)([^#\s])/g, '$1\n$2$3'); // Double linebreak after double comment + + return commentConf; +} + +export default (domains, global) => { + const files = {}; + + files['nginx.conf'] = toConf(nginxConf(domains, global)); + + return files; +} diff --git a/src/nginxconfig/generators/nginx.conf.js b/src/nginxconfig/generators/nginx.conf.js new file mode 100644 index 0000000..4d136d0 --- /dev/null +++ b/src/nginxconfig/generators/nginx.conf.js @@ -0,0 +1,114 @@ +import sslProfiles from '../util/ssl_profiles'; + +export default (domains, global) => { + const config = {}; + + // Source + config['# Generated by nginxconfig.io'] = ''; + if (window.location.search) + config[`# ${window.location.protocol}//${window.location.host}${window.location.pathname}${window.location.search}`] = ''; + + // Basic nignx 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 + config.http = {}; + + if (global.php.phpBackupServer.computed) + config.http['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.charset = 'utf-8'; + config.http.sendfile = 'on'; + config.http.tcp_nopush = 'on'; + config.http.tcp_nodelay = 'on'; + if (!global.security.serverTokens.computed) + config.http.server_tokens = 'off'; + if (!global.logging.logNotFound.computed) + config.http.log_not_found = 'off'; + config.http.types_hash_max_size = 2048; + config.http.client_max_body_size = `${global.nginx.clientMaxBodySize.computed}M`; + + config.http['# MIME'] = ''; + config.http.include = 'mime.types'; + config.http.default_type = 'application/octet-stream'; + + config.http['# logging'] = ''; + config.http.access_log = global.logging.accessLog.computed.trim() || 'off'; + config.http.error_log = global.logging.errorLog.computed.trim() || '/dev/null'; + + if (global.security.limitReq.computed) { + config.http['# limits'] = ''; + config.http.limit_req_log_level = 'warn'; + config.http.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['# SSL'] = ''; + config.http.ssl_session_timeout = '1d'; + config.http.ssl_session_cache = 'shared:SSL:10m'; + config.http.ssl_session_tickets = 'off'; + + if (sslProfiles[global.https.sslProfile.computed].dh_param_size) { + config.http['# Diffie-Hellman parameter for DHE ciphersuites'] = ''; + config.http.ssl_dhparam = `${global.nginx.nginxConfigDirectory.computed.replace(/\/+$/, '')}/dhparam.pem`; + } + + config.http[`# ${sslProfiles[global.https.sslProfile.computed].name} configuration`] = ''; + config.http.ssl_protocols = sslProfiles[global.https.sslProfile.computed].protocols.join(' '); + if (sslProfiles[global.https.sslProfile.computed].ciphers.length) + config.http.ssl_ciphers = sslProfiles[global.https.sslProfile.computed].ciphers.join(':'); + if (sslProfiles[global.https.sslProfile.computed].server_preferred_order) + config.http.ssl_prefer_server_ciphers = 'on'; + + config.http['# OCSP Stapling'] = ''; + config.http.ssl_stapling = 'on'; + config.http.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.resolver = `${ips.join(' ')} valid=60s`; + config.http.resolver_timeout = '2s'; + } + } + + // Configs! + config.http['# load configs'] = ''; + config.http.include = [ + `${global.nginx.nginxConfigDirectory.computed.replace(/\/+$/, '')}/conf.d/*.conf`, + global.tools.modularizedStructure.computed ? `${global.nginx.nginxConfigDirectory.computed.replace(/\/+$/, '')}/sites-enabled/*` : '', + ].filter(x => !!x); + + // Single file configs + if (!global.tools.modularizedStructure.computed) { + // TODO: figure out merging in all the other configs + } + + // Done! + return config; +}; diff --git a/src/nginxconfig/templates/app.vue b/src/nginxconfig/templates/app.vue index fda41c0..8215c0e 100644 --- a/src/nginxconfig/templates/app.vue +++ b/src/nginxconfig/templates/app.vue @@ -63,7 +63,8 @@ limitations under the License.

Config files

- + +
{{exportData}}
@@ -75,14 +76,14 @@ limitations under the License.