From 7994460e83a2ace11e3be1373916c55049ffff20 Mon Sep 17 00:00:00 2001 From: Zoey Date: Tue, 7 Jan 2025 10:50:53 +0100 Subject: [PATCH] improve host recreation try to catch beautifier error --- Caddy.Dockerfile | 2 +- Dockerfile | 12 +- backend/internal/access-list.js | 14 +- backend/internal/certificate.js | 4 +- backend/internal/host.js | 4 +- backend/internal/nginx.js | 35 ++--- backend/package.json | 2 +- backend/setup.js | 133 ++++++++---------- backend/templates/_certificates.conf | 2 - .../{_forced_tls.conf => _force_https.conf} | 4 +- backend/templates/_listen.conf | 8 +- backend/templates/_location.conf | 2 +- backend/templates/dead_host.conf | 3 +- backend/templates/default.conf | 17 --- backend/templates/proxy_host.conf | 11 +- backend/templates/redirection_host.conf | 3 +- compose.yaml | 2 +- rootfs/usr/local/bin/launch.sh | 1 + rootfs/usr/local/bin/start.sh | 2 + .../nginx/conf/conf.d/include/always.conf | 15 +- .../{force-tls.conf => force-https.conf} | 0 .../nginx/conf/conf.d/include/goaccess.conf | 14 +- .../{proxy.conf => proxy-headers.conf} | 0 .../conf/conf.d/include/tls-ciphers.conf | 11 -- rootfs/usr/local/nginx/conf/conf.d/npm.conf | 15 +- rootfs/usr/local/nginx/conf/nginx.conf | 12 ++ 26 files changed, 126 insertions(+), 202 deletions(-) rename backend/templates/{_forced_tls.conf => _force_https.conf} (58%) rename rootfs/usr/local/nginx/conf/conf.d/include/{force-tls.conf => force-https.conf} (100%) rename rootfs/usr/local/nginx/conf/conf.d/include/{proxy.conf => proxy-headers.conf} (100%) delete mode 100644 rootfs/usr/local/nginx/conf/conf.d/include/tls-ciphers.conf diff --git a/Caddy.Dockerfile b/Caddy.Dockerfile index 7c73154c9..65b40bca9 100644 --- a/Caddy.Dockerfile +++ b/Caddy.Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.21.0 +FROM alpine:3.21.1 RUN apk add --no-cache ca-certificates tzdata COPY --from=caddy:2.8.4 /usr/bin/caddy /usr/bin/caddy COPY Caddyfile /etc/caddy/Caddyfile diff --git a/Dockerfile b/Dockerfile index 510e00a72..94651c628 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:labs -FROM --platform="$BUILDPLATFORM" alpine:3.21.0 AS frontend +FROM --platform="$BUILDPLATFORM" alpine:3.21.1 AS frontend SHELL ["/bin/ash", "-eo", "pipefail", "-c"] ARG NODE_ENV=production \ NODE_OPTIONS=--openssl-legacy-provider @@ -19,7 +19,7 @@ COPY darkmode.css /app/dist/css/darkmode.css COPY security.txt /app/dist/.well-known/security.txt -FROM --platform="$BUILDPLATFORM" alpine:3.21.0 AS build-backend +FROM --platform="$BUILDPLATFORM" alpine:3.21.1 AS build-backend SHELL ["/bin/ash", "-eo", "pipefail", "-c"] ARG NODE_ENV=production \ TARGETARCH @@ -38,7 +38,7 @@ RUN apk upgrade --no-cache -a && \ fi && \ yarn cache clean --all && \ clean-modules --yes -FROM alpine:3.21.0 AS strip-backend +FROM alpine:3.21.1 AS strip-backend COPY --from=build-backend /app /app RUN apk upgrade --no-cache -a && \ apk add --no-cache ca-certificates binutils file && \ @@ -46,7 +46,7 @@ RUN apk upgrade --no-cache -a && \ find /app/node_modules -name "*.node" -type f -exec file {} \; -FROM --platform="$BUILDPLATFORM" alpine:3.21.0 AS crowdsec +FROM --platform="$BUILDPLATFORM" alpine:3.21.1 AS crowdsec SHELL ["/bin/ash", "-eo", "pipefail", "-c"] ARG CSNB_VER=v1.0.8 WORKDIR /src @@ -72,7 +72,7 @@ RUN apk upgrade --no-cache -a && \ sed -i "s|APPSEC_PROCESS_TIMEOUT=.*|APPSEC_PROCESS_TIMEOUT=10000|g" /src/crowdsec-nginx-bouncer/lua-mod/config_example.conf -FROM zoeyvid/nginx-quic:371-python +FROM zoeyvid/nginx-quic:372-python SHELL ["/bin/ash", "-eo", "pipefail", "-c"] ARG CRS_VER=v4.10.0 COPY rootfs / @@ -117,7 +117,7 @@ COPY --from=frontend /app/dist LABEL com.centurylinklabs.watchtower.monitor-only="true" ENV NODE_ENV=production \ - TV=1a \ + TV=1b \ ACME_SERVER="https://acme-v02.api.letsencrypt.org/directory" \ ACME_MUST_STAPLE=false \ ACME_OCSP_STAPLING=true \ diff --git a/backend/internal/access-list.js b/backend/internal/access-list.js index 9f1f31a50..97e9fa4c8 100644 --- a/backend/internal/access-list.js +++ b/backend/internal/access-list.js @@ -86,7 +86,7 @@ const internalAccessList = { .build(row) .then(() => { if (row.proxy_host_count) { - return internalNginx.bulkGenerateConfigs('proxy_host', row.proxy_hosts); + return internalNginx.bulkGenerateConfigs(proxyHostModel, 'proxy_host', row.proxy_hosts); } }) .then(() => { @@ -163,7 +163,7 @@ const internalAccessList = { return query.then(() => { // Add new items - if (promises.length) { + if (promises.length > 0) { return Promise.all(promises); } }); @@ -190,7 +190,7 @@ const internalAccessList = { return query.then(() => { // Add new items - if (promises.length) { + if (promises.length > 0) { return Promise.all(promises); } }); @@ -221,7 +221,7 @@ const internalAccessList = { .build(row) .then(() => { if (row.proxy_host_count) { - return internalNginx.bulkGenerateConfigs('proxy_host', row.proxy_hosts); + return internalNginx.bulkGenerateConfigs(proxyHostModel, 'proxy_host', row.proxy_hosts); } }) .then(internalNginx.reload) @@ -320,7 +320,7 @@ const internalAccessList = { row.proxy_hosts[idx].access_list_id = 0; }); - return internalNginx.bulkGenerateConfigs('proxy_host', row.proxy_hosts); + return internalNginx.bulkGenerateConfigs(proxyHostModel, 'proxy_host', row.proxy_hosts); }) .then(() => { return internalNginx.reload(); @@ -476,12 +476,12 @@ const internalAccessList = { } }).then((htpasswd_file) => { // 3. generate password for each user - if (list.items.length) { + if (list.items.length > 0) { return new Promise((resolve, reject) => { batchflow(list.items) .sequential() .each((i, item, next) => { - if (typeof item.password !== 'undefined' && item.password.length) { + if (typeof item.password !== 'undefined' && item.password.length > 0) { logger.info('Adding: ' + item.username); try { diff --git a/backend/internal/certificate.js b/backend/internal/certificate.js index 07870df27..2b64ec0f0 100644 --- a/backend/internal/certificate.js +++ b/backend/internal/certificate.js @@ -60,7 +60,7 @@ const internalCertificate = { .where('is_deleted', 0) .andWhere('provider', 'letsencrypt') .then((certificates) => { - if (certificates && certificates.length) { + if (certificates && certificates.length > 0) { const promises = []; certificates.map(function (certificate) { @@ -782,7 +782,7 @@ const internalCertificate = { await certbot.installPlugin(certificate.meta.dns_provider); logger.info(`Requesting Certbot certificates via ${dnsPlugin.name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`); - const credentialsLocation = '/data/tls/certbot/credentials/credentials-' + certificate.id; + const credentialsLocation = '/tmp/certbot-credentials/credentials-' + certificate.id; fs.writeFileSync(credentialsLocation, certificate.meta.dns_provider_credentials, { mode: 0o600 }); try { diff --git a/backend/internal/host.js b/backend/internal/host.js index b858955bb..52396507b 100644 --- a/backend/internal/host.js +++ b/backend/internal/host.js @@ -160,7 +160,7 @@ const internalHost = { _checkHostnameRecordsTaken: function (hostname, existing_rows, ignore_id) { let is_taken = false; - if (existing_rows && existing_rows.length) { + if (existing_rows && existing_rows.length > 0) { existing_rows.map(function (existing_row) { existing_row.domain_names.map(function (existing_hostname) { // Does this domain match? @@ -186,7 +186,7 @@ const internalHost = { _getHostsWithDomains: function (hosts, domain_names) { const response = []; - if (hosts && hosts.length) { + if (hosts && hosts.length > 0) { hosts.map(function (host) { let host_matches = false; diff --git a/backend/internal/nginx.js b/backend/internal/nginx.js index 51fd6a37f..16c1d0ebe 100644 --- a/backend/internal/nginx.js +++ b/backend/internal/nginx.js @@ -80,22 +80,12 @@ const internalNginx = { reload: () => { if (process.env.ACME_OCSP_STAPLING === 'true') { return utils.execFile('certbot-ocsp-fetcher.sh', ['-c', '/data/tls/certbot', '-o', '/data/tls/certbot/live', '--no-reload-webserver', '--quiet']).finally(() => { - if (fs.existsSync('/usr/local/nginx/logs/nginx.pid') && fs.readFileSync('/usr/local/nginx/logs/nginx.pid', 'utf8').trim().length > 0) { - logger.info('Reloading Nginx'); - return utils.execFile('nginx', ['-s', 'reload']); - } else { - logger.info('Starting Nginx'); - utils.execfg('nginx', ['-e', 'stderr']); - } - }); - } else { - if (fs.existsSync('/usr/local/nginx/logs/nginx.pid') && fs.readFileSync('/usr/local/nginx/logs/nginx.pid', 'utf8').trim().length > 0) { logger.info('Reloading Nginx'); return utils.execFile('nginx', ['-s', 'reload']); - } else { - logger.info('Starting Nginx'); - utils.execfg('nginx', ['-e', 'stderr']); - } + }); + } else { + logger.info('Reloading Nginx'); + return utils.execFile('nginx', ['-s', 'reload']); } }, @@ -219,7 +209,11 @@ const internalNginx = { }) .then(() => { if (process.env.DISABLE_NGINX_BEAUTIFIER === 'false') { - utils.execFile('nginxbeautifier', ['-s', '4', filename]); + try { + utils.execFile('nginxbeautifier', ['-s', '4', filename]); + } catch { + logger.error("nginxbeautifier failed"); + } } }); }); @@ -276,13 +270,10 @@ const internalNginx = { * @param {Array} hosts * @returns {Promise} */ - bulkGenerateConfigs: (host_type, hosts) => { - const promises = []; - hosts.map(function (host) { - promises.push(internalNginx.generateConfig(host_type, host)); - }); - - return Promise.all(promises); + bulkGenerateConfigs: (model, host_type, hosts) => { + return hosts.reduce((promise, host) => { + return promise.then(() => internalNginx.configure(model, host_type, host)); + }, Promise.resolve()); }, /** diff --git a/backend/package.json b/backend/package.json index 974c87425..b98c919df 100644 --- a/backend/package.json +++ b/backend/package.json @@ -30,7 +30,7 @@ "author": "Jamie Curnow and ZoeyVid ", "license": "MIT", "devDependencies": { - "@apidevtools/swagger-parser": "10.1.0", + "@apidevtools/swagger-parser": "10.1.1", "@eslint/js": "9.17.0", "eslint": "9.17.0", "eslint-config-prettier": "9.1.0", diff --git a/backend/setup.js b/backend/setup.js index 8070203a5..4df96cad7 100644 --- a/backend/setup.js +++ b/backend/setup.js @@ -101,6 +101,15 @@ const setupDefaultSettings = () => { logger.info('Default settings added'); }); } + }) + .then(() => { + settingModel + .query() + .where('id', 'default-site') + .first() + .then((row) => { + internalNginx.generateConfig('default', row); + }); }); }; @@ -115,7 +124,7 @@ const setupCertbotPlugins = () => { .where('is_deleted', 0) .andWhere('provider', 'letsencrypt') .then((certificates) => { - if (certificates && certificates.length) { + if (certificates && certificates.length > 0) { const plugins = []; const promises = []; @@ -129,7 +138,7 @@ const setupCertbotPlugins = () => { }); return certbot.installPlugins(plugins).then(() => { - if (promises.length) { + if (promises.length > 0) { return Promise.all(promises).then(() => { logger.info('Added Certbot plugins ' + plugins.join(', ')); }); @@ -145,76 +154,56 @@ const setupCertbotPlugins = () => { * @returns {Promise} */ const regenerateAllHosts = () => { - settingModel - .query() - .where('id', 'default-site') - .first() - .then((row) => { - internalNginx.generateConfig('default', row); - }) - .then(() => { - if (process.env.REGENERATE_ALL === 'true') { - const promises = []; - - promises.push( - proxyModel - .query() - .where('is_deleted', 0) - .andWhere('enabled', 1) - .withGraphFetched('[access_list.[clients, items], certificate]') - .then((rows) => { - if (rows && rows.length) { - internalNginx.bulkGenerateConfigs('proxy_host', rows); - } - }), - ); - - promises.push( - redirectModel - .query() - .where('is_deleted', 0) - .andWhere('enabled', 1) - .withGraphFetched('[certificate]') - .then((rows) => { - if (rows && rows.length) { - internalNginx.bulkGenerateConfigs('redirection_host', rows); - } - }), - ); - - promises.push( - deadModel - .query() - .where('is_deleted', 0) - .andWhere('enabled', 1) - .withGraphFetched('[certificate]') - .then((rows) => { - if (rows && rows.length) { - internalNginx.bulkGenerateConfigs('dead_host', rows); - } - }), - ); - - promises.push( - streamModel - .query() - .where('is_deleted', 0) - .andWhere('enabled', 1) - .then((rows) => { - if (rows && rows.length) { - internalNginx.bulkGenerateConfigs('stream', rows); - } - }), - ); - - // Execute all promises and then write the hash - return Promise.all(promises).then(() => { - utils.writeHash(); - }); - } - }); - - return Promise.resolve(); // Return resolved promise if REGENERATE_ALL is not true + if (process.env.REGENERATE_ALL === 'true') { + return proxyModel + .query() + .where('is_deleted', 0) + .andWhere('enabled', 1) + .withGraphFetched('[access_list.[clients, items], certificate]') + .then((rows) => { + if (rows && rows.length > 0) { + internalNginx.bulkGenerateConfigs(proxyModel, 'proxy_host', rows); + } + }) + .then(() => { + return redirectModel + .query() + .where('is_deleted', 0) + .andWhere('enabled', 1) + .withGraphFetched('[certificate]') + .then((rows) => { + if (rows && rows.length > 0) { + internalNginx.bulkGenerateConfigs(redirectModel, 'redirection_host', rows); + } + }); + }) + .then(() => { + return deadModel + .query() + .where('is_deleted', 0) + .andWhere('enabled', 1) + .withGraphFetched('[certificate]') + .then((rows) => { + if (rows && rows.length > 0) { + internalNginx.bulkGenerateConfigs(deadModel, 'dead_host', rows); + } + }); + }) + .then(() => { + return streamModel + .query() + .where('is_deleted', 0) + .andWhere('enabled', 1) + .then((rows) => { + if (rows && rows.length > 0) { + internalNginx.bulkGenerateConfigs(streamModel, 'stream', rows); + } + }); + }) + .then(() => { + utils.writeHash(); + }); + } }; module.exports = function () { diff --git a/backend/templates/_certificates.conf b/backend/templates/_certificates.conf index 9ab7408f1..b3b89d1f5 100644 --- a/backend/templates/_certificates.conf +++ b/backend/templates/_certificates.conf @@ -1,7 +1,6 @@ {% if certificate and certificate_id > 0 %} {% if certificate.provider == "letsencrypt" %} # Certbot TLS - include conf.d/include/tls-ciphers.conf; ssl_certificate /data/tls/certbot/live/npm-{{ certificate_id }}/fullchain.pem; ssl_certificate_key /data/tls/certbot/live/npm-{{ certificate_id }}/privkey.pem; {% if env.ACME_OCSP_STAPLING == "true" %} @@ -11,7 +10,6 @@ {% endif %} {% else %} # Custom TLS - include conf.d/include/tls-ciphers-no-stapling.conf; ssl_certificate /data/tls/custom/npm-{{ certificate_id }}/fullchain.pem; ssl_certificate_key /data/tls/custom/npm-{{ certificate_id }}/privkey.pem; {% endif %} diff --git a/backend/templates/_forced_tls.conf b/backend/templates/_force_https.conf similarity index 58% rename from backend/templates/_forced_tls.conf rename to backend/templates/_force_https.conf index 55a7b3b04..03604a751 100644 --- a/backend/templates/_forced_tls.conf +++ b/backend/templates/_force_https.conf @@ -1,6 +1,6 @@ {% if certificate and certificate_id > 0 %} {% if ssl_forced %} - # Force TLS - include conf.d/include/force-tls.conf; + # Force HTTPS + include conf.d/include/force-https.conf; {% endif %} {% endif %} diff --git a/backend/templates/_listen.conf b/backend/templates/_listen.conf index a7bf8e4ad..259da31c1 100644 --- a/backend/templates/_listen.conf +++ b/backend/templates/_listen.conf @@ -9,16 +9,10 @@ listen {{ env.IPV4_BINDING }}:{{ env.HTTPS_PORT }} ssl; {% if env.DISABLE_IPV6 == "false" %}listen {{ env.IPV6_BINDING }}:{{ env.HTTPS_PORT }} ssl;{% endif %} -{% if env.DISABLE_H3_QUIC == "false" %} +{% if hsts_subdomains and env.DISABLE_H3_QUIC == "false" %} listen {{ env.IPV4_BINDING }}:{{ env.HTTPS_PORT }} quic; {% if env.DISABLE_IPV6 == "false" %}listen {{ env.IPV6_BINDING }}:{{ env.HTTPS_PORT }} quic;{% endif %} - -{% if hsts_subdomains %} more_set_headers 'Alt-Svc: h3=":{{ env.HTTPS_PORT }}"; ma=86400'; -{% else %} - more_clear_headers "Alt-Svc"; - http3 off; -{% endif %} {% endif %} {% endif %} server_name {{ domain_names | join: " " }}; diff --git a/backend/templates/_location.conf b/backend/templates/_location.conf index 95ca77bbe..0ee7c6d78 100644 --- a/backend/templates/_location.conf +++ b/backend/templates/_location.conf @@ -8,7 +8,7 @@ location {{ path }} { proxy_set_header Connection $connection_upgrade; {% endif %} - include conf.d/include/proxy.conf; + include conf.d/include/proxy-headers.conf; proxy_set_header X-Forwarded-Host $host{{ path }}; if ($forward_path = "") { rewrite ^{{ path }}(/.*)$ $1 break; diff --git a/backend/templates/dead_host.conf b/backend/templates/dead_host.conf index e8709c6bb..75a8e186d 100644 --- a/backend/templates/dead_host.conf +++ b/backend/templates/dead_host.conf @@ -5,7 +5,7 @@ server { {% include "_listen.conf" %} {% include "_certificates.conf" %} {% include "_hsts.conf" %} -{% include "_forced_tls.conf" %} +{% include "_force_https.conf" %} {% include "_brotli.conf" %} include conf.d/include/always.conf; @@ -14,7 +14,6 @@ include conf.d/include/always.conf; {% if use_default_location %} location / { - include conf.d/include/always.conf; root /html/404deadpage; error_page 404 /404deadpage.html; try_files $uri =404; diff --git a/backend/templates/default.conf b/backend/templates/default.conf index d2974117a..a5b9e3430 100644 --- a/backend/templates/default.conf +++ b/backend/templates/default.conf @@ -14,17 +14,9 @@ server { listen {{ env.IPV4_BINDING }}:{{ env.HTTPS_PORT }} quic reuseport; {% if env.DISABLE_IPV6 == "false" %}listen {{ env.IPV6_BINDING }}:{{ env.HTTPS_PORT }} quic reuseport;{% endif %} more_set_headers 'Alt-Svc: h3=":{{ env.HTTPS_PORT }}"; ma=86400'; -{% else %} - more_clear_headers "Alt-Svc"; - http3 off; {% endif %} server_name ""; - include conf.d/include/always.conf; - include conf.d/include/brotli.conf; - include conf.d/include/force-tls.conf; - include conf.d/include/tls-ciphers.conf; - ssl_certificate ; ssl_certificate_key ; #ssl_stapling on; @@ -47,16 +39,11 @@ server { listen {{ env.IPV4_BINDING }}:{{ env.HTTPS_PORT }} quic default_server; {% if env.DISABLE_IPV6 == "false" %}listen {{ env.IPV6_BINDING }}:{{ env.HTTPS_PORT }} quic default_server;{% endif %} more_set_headers 'Alt-Svc: h3=":{{ env.HTTPS_PORT }}"; ma=86400'; -{% else %} - more_clear_headers "Alt-Svc"; - http3 off; {% endif %} server_name _; include conf.d/include/always.conf; include conf.d/include/brotli.conf; - include conf.d/include/force-tls.conf; - include conf.d/include/tls-ciphers.conf; ssl_certificate ; ssl_certificate_key ; @@ -66,7 +53,6 @@ server { {% if value == "404" %} location / { - include conf.d/include/always.conf; root /html/404deadpage; error_page 404 /404deadpage.html; try_files $uri =404; @@ -79,14 +65,12 @@ server { {% if value == "redirect" %} location / { - include conf.d/include/always.conf; return 307 {{ meta.redirect }}; } {% endif %} {% if value == "congratulations" %} location / { - include conf.d/include/always.conf; root /html/default; try_files $uri /index.html; } @@ -94,7 +78,6 @@ server { {% if value == "html" %} location / { - include conf.d/include/always.conf; root /data/html; try_files $uri /index.html; } diff --git a/backend/templates/proxy_host.conf b/backend/templates/proxy_host.conf index f89b301d5..d4b30db51 100644 --- a/backend/templates/proxy_host.conf +++ b/backend/templates/proxy_host.conf @@ -9,7 +9,7 @@ server { {% include "_listen.conf" %} {% include "_certificates.conf" %} {% include "_hsts.conf" %} -{% include "_forced_tls.conf" %} +{% include "_force_https.conf" %} {% include "_brotli.conf" %} {% include "_access.conf" %} @@ -37,15 +37,12 @@ server { {% if use_default_location %} location / { - include conf.d/include/always.conf; - {% if allow_websocket_upgrade %} - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; {% endif %} - # Proxy! - include conf.d/include/proxy.conf; + include conf.d/include/proxy-headers.conf; proxy_pass $forward_scheme://$server:$port$request_uri; } {% endif %} diff --git a/backend/templates/redirection_host.conf b/backend/templates/redirection_host.conf index 8d0359acd..292d9b6e7 100644 --- a/backend/templates/redirection_host.conf +++ b/backend/templates/redirection_host.conf @@ -5,7 +5,7 @@ server { {% include "_listen.conf" %} {% include "_certificates.conf" %} {% include "_hsts.conf" %} -{% include "_forced_tls.conf" %} +{% include "_force_https.conf" %} {% include "_brotli.conf" %} include conf.d/include/always.conf; @@ -14,7 +14,6 @@ include conf.d/include/always.conf; {% if use_default_location %} location / { - include conf.d/include/always.conf; {% if preserve_path %} return {{ forward_http_code }} {{ forward_scheme }}://{{ forward_domain_name }}$request_uri; {% else %} diff --git a/compose.yaml b/compose.yaml index f275b1eb1..263d98d7e 100644 --- a/compose.yaml +++ b/compose.yaml @@ -38,7 +38,7 @@ services: # not released # - "HTTP_PORT=8080" # tcp port to use for http traffic, changing this may breaks certbot http challenge, default 80 # not released # - "HTTPS_PORT=8443" # udp and tcp port to use for https traffic, this also needs to be changed if you don't use network_mode host to keep http3/quic working, changing this may breaks certbot http challenge, default 443 # - "DISABLE_HTTP=true" # disables nginx to listen on port 80, default false -# - "DISABLE_H3_QUIC=true" # disables nginx to listen on port 443 udp for default and your hosts, this will fully disable HTTP/3 and QUIC, even if you enable it inside the UI, not recommended, default false +# - "DISABLE_H3_QUIC=true" # disables nginx to listen on port 443 udp for default host and all your hosts, this will fully disable HTTP/3 and QUIC, even if you enable it inside the UI, not recommended, default false # not released # - "NGINX_QUIC_BPF=true" # enables nginxs quic_bpf (https://nginx.org/en/docs/http/ngx_http_v3_module.html#quic_bpf), you also need to to give the NPMplus container privileged permissions to use this, default false # - "NGINX_LOG_NOT_FOUND=true" # Allow logging of 404 errors, default false # - "NGINX_404_REDIRECT=true" # Redirect to / instead of showing a 404 error page, default false diff --git a/rootfs/usr/local/bin/launch.sh b/rootfs/usr/local/bin/launch.sh index ac6b21e4d..433354142 100755 --- a/rootfs/usr/local/bin/launch.sh +++ b/rootfs/usr/local/bin/launch.sh @@ -84,5 +84,6 @@ if [ "$LOGROTATE" = "true" ]; then while true; do touch /data/logrotate.lock; lo # shellcheck disable=SC2086 if [ "$GOA" = "true" ]; then while true; do if [ -f /data/nginx/access.log ] && [ ! -f /data/logrotate.lock ]; then goaccess --no-global-config --num-tests=0 --tz="$TZ" --date-format="%d/%b/%Y" --time-format="%H:%M:%S" --log-format='[%d:%t %^] %v %h %T "%r" %s %b %b %R %u' --no-ip-validation \ --addr=127.0.0.1 --port="$GOAIWSP" -f /data/nginx/access.log --real-time-html -o /tmp/goa/index.html --persist --restore --db-path=/data/goaccess/data -b /etc/goaccess/browsers.list -b /etc/goaccess/podcast.list $GOACLA; else sleep 10s; fi; done; fi & +nginx -e stderr & aio.sh & index.js diff --git a/rootfs/usr/local/bin/start.sh b/rootfs/usr/local/bin/start.sh index b7a1a314a..ee96a177b 100755 --- a/rootfs/usr/local/bin/start.sh +++ b/rootfs/usr/local/bin/start.sh @@ -588,6 +588,7 @@ touch /data/modsecurity/modsecurity-extra.conf \ /data/custom_nginx/server_stream_udp.conf + if [ -s /data/keys.json ]; then mv -vn /data/keys.json /data/npmplus/keys.json fi @@ -614,6 +615,7 @@ fi if [ -n "$(ls -A /data/etc 2> /dev/null)" ]; then mv -vn /data/etc/* /data fi +sed -i "s|/data/etc|/data|g" /data/crowdsec/crowdsec.conf #tmp if [ -n "$(ls -A /data/npm 2> /dev/null)" ]; then diff --git a/rootfs/usr/local/nginx/conf/conf.d/include/always.conf b/rootfs/usr/local/nginx/conf/conf.d/include/always.conf index 53d0c3415..c614543cf 100644 --- a/rootfs/usr/local/nginx/conf/conf.d/include/always.conf +++ b/rootfs/usr/local/nginx/conf/conf.d/include/always.conf @@ -1,17 +1,9 @@ location /.well-known/acme-challenge/ { + root /tmp/acme-challenge; + fancyindex off; + index off; auth_basic off; - auth_request off; allow all; - root /tmp/acme-challenge; -} - -location = /.well-known/acme-challenge/ { - return 404; -} - - -location = /fancyindex { - return 301 /fancyindex/; } location /fancyindex/ { @@ -20,7 +12,6 @@ location /fancyindex/ { index off; } - location ~ /\.ht { deny all; } diff --git a/rootfs/usr/local/nginx/conf/conf.d/include/force-tls.conf b/rootfs/usr/local/nginx/conf/conf.d/include/force-https.conf similarity index 100% rename from rootfs/usr/local/nginx/conf/conf.d/include/force-tls.conf rename to rootfs/usr/local/nginx/conf/conf.d/include/force-https.conf diff --git a/rootfs/usr/local/nginx/conf/conf.d/include/goaccess.conf b/rootfs/usr/local/nginx/conf/conf.d/include/goaccess.conf index f6bf35c9b..3d86074d8 100644 --- a/rootfs/usr/local/nginx/conf/conf.d/include/goaccess.conf +++ b/rootfs/usr/local/nginx/conf/conf.d/include/goaccess.conf @@ -3,11 +3,6 @@ server { listen [::]:91 ssl; server_name ""; - include conf.d/include/always.conf; - include conf.d/include/brotli.conf; - include conf.d/include/force-tls.conf; - include conf.d/include/tls-ciphers.conf; - ssl_certificate ; ssl_certificate_key ; #ssl_stapling on; @@ -22,22 +17,17 @@ server { listen [::]:91 ssl default_server; server_name _; - include conf.d/include/always.conf; - include conf.d/include/brotli.conf; - include conf.d/include/force-tls.conf; - include conf.d/include/tls-ciphers.conf; - ssl_certificate ; ssl_certificate_key ; #ssl_stapling on; #ssl_stapling_verify on; #ssl_stapling_file ; + include conf.d/include/brotli.conf; location / { - include conf.d/include/always.conf; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; - include conf.d/include/proxy-location.conf; + include conf.d/include/proxy-headers.conf; if ($goaccess = "socket") { proxy_pass http://127.0.0.1:48693$request_uri; diff --git a/rootfs/usr/local/nginx/conf/conf.d/include/proxy.conf b/rootfs/usr/local/nginx/conf/conf.d/include/proxy-headers.conf similarity index 100% rename from rootfs/usr/local/nginx/conf/conf.d/include/proxy.conf rename to rootfs/usr/local/nginx/conf/conf.d/include/proxy-headers.conf diff --git a/rootfs/usr/local/nginx/conf/conf.d/include/tls-ciphers.conf b/rootfs/usr/local/nginx/conf/conf.d/include/tls-ciphers.conf deleted file mode 100644 index 400efdbd7..000000000 --- a/rootfs/usr/local/nginx/conf/conf.d/include/tls-ciphers.conf +++ /dev/null @@ -1,11 +0,0 @@ -ssl_session_timeout 1d; -ssl_session_cache shared:SSL:10m; - -ssl_dhparam /etc/dhparam; -ssl_protocols TLSv1.2 TLSv1.3; -ssl_ecdh_curve X25519MLKEM768:x25519:x448:secp521r1:secp384r1:secp256r1; - -ssl_early_data on; -ssl_prefer_server_ciphers on; -ssl_conf_command Options PrioritizeChaCha; -ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256; diff --git a/rootfs/usr/local/nginx/conf/conf.d/npm.conf b/rootfs/usr/local/nginx/conf/conf.d/npm.conf index 50f268666..5287b88aa 100644 --- a/rootfs/usr/local/nginx/conf/conf.d/npm.conf +++ b/rootfs/usr/local/nginx/conf/conf.d/npm.conf @@ -3,11 +3,6 @@ server { listen [::]:81 ssl; server_name ""; - include conf.d/include/always.conf; - include conf.d/include/brotli.conf; - include conf.d/include/force-tls.conf; - include conf.d/include/tls-ciphers.conf; - ssl_certificate ; ssl_certificate_key ; #ssl_stapling on; @@ -22,29 +17,23 @@ server { listen [::]:81 ssl default_server; server_name _; - include conf.d/include/always.conf; - include conf.d/include/brotli.conf; - include conf.d/include/force-tls.conf; - include conf.d/include/tls-ciphers.conf; - ssl_certificate ; ssl_certificate_key ; #ssl_stapling on; #ssl_stapling_verify on; #ssl_stapling_file ; + include conf.d/include/brotli.conf; location /api { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; - - include conf.d/include/proxy.conf; + include conf.d/include/proxy-headers.conf; rewrite ^/api(/.*)$ $1 break; proxy_pass http://127.0.0.1:48683; } location / { - include conf.d/include/always.conf; root /html/frontend; if ($request_uri ~ ^/(.*)\.html$) { return 302 /$1; diff --git a/rootfs/usr/local/nginx/conf/nginx.conf b/rootfs/usr/local/nginx/conf/nginx.conf index e7bd40d0d..cc9833d7d 100644 --- a/rootfs/usr/local/nginx/conf/nginx.conf +++ b/rootfs/usr/local/nginx/conf/nginx.conf @@ -62,7 +62,19 @@ http { http3 on; quic_gso on; quic_retry on; + ssl_dyn_rec_enable on; + ssl_session_timeout 1d; + ssl_session_cache shared:SSL:10m; + + ssl_dhparam /etc/dhparam; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ecdh_curve X25519MLKEM768:x25519:x448:secp521r1:secp384r1:secp256r1; + + ssl_early_data on; + ssl_prefer_server_ciphers on; + ssl_conf_command Options PrioritizeChaCha; + ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256; resolver local=on valid=10s ipv6=on; fastcgi_index index.php;