From e0be3a5ea3a6a5027a82f3ad9b3e85fb5b2bd996 Mon Sep 17 00:00:00 2001 From: Zoey Date: Fri, 6 Jan 2023 23:16:51 +0100 Subject: [PATCH] allow to change dummycert Signed-off-by: Zoey --- Dockerfile | 2 +- README.md | 8 +- backend/internal/certificate.js | 12 +- backend/templates/default.conf | 5 +- compose.yaml | 3 +- frontend/js/app/nginx/certificates/form.ejs | 3 +- .../js/app/nginx/certificates/list/item.ejs | 2 + rootfs/bin/start.sh | 161 +++++++++++++++--- rootfs/etc/tls/certbot.ini | 6 +- .../nginx/conf/conf.d/include/default.conf | 5 +- .../nginx/conf/conf.d/no-server-name.conf | 5 +- rootfs/usr/local/nginx/conf/conf.d/npm.conf | 9 +- 12 files changed, 176 insertions(+), 45 deletions(-) diff --git a/Dockerfile b/Dockerfile index a643d1e8..e3148eb9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM zoeyvid/nginx-quic:31 +FROM zoeyvid/nginx-quic:32 COPY rootfs / COPY backend /app COPY global /app/global diff --git a/README.md b/README.md index 7b160b54..3b9745a8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

+



@@ -60,6 +60,11 @@ so that the barrier for entry here is low. ## Soon - more +## migration +- **NOTE: migrating back to the original is not possible**, so make first a **backup** before migration, so you can use the backup to switch back +- if you use custom certificates, you need to upload the CA/Intermediate Certificate (file name: `chain.pem`) in the `/opt/npm/tls/custom/npm-[certificate-id]` folder +- some buttons have changed, check if they are still correct + # Use as webserver 1. Create a new Proxy Host @@ -120,6 +125,7 @@ services: - "TZ=Europe/Berlin" # - "NGINX_LOG_NOT_FOUND=true" # Allow logging of 404 errors # - "NPM_LISTEN_LOCALHOST=true" # Bind the NPM Dashboard on Port 81 only to localhost +# - "NPM_CERT_ID=1" # ID of cert, which should be used instead of dummycerts # - "PHP_APKS=php81-curl php-82-curl" # Add php extensions, see aviable packages here: https://pkgs.alpinelinux.org/packages?branch=edge&repo=community&arch=x86_64&name=php8*-* ``` diff --git a/backend/internal/certificate.js b/backend/internal/certificate.js index aac045bc..a54262bb 100644 --- a/backend/internal/certificate.js +++ b/backend/internal/certificate.js @@ -43,10 +43,11 @@ const internalCertificate = { internalCertificate.intervalProcessing = true; logger.info('Renewing TLS certs close to expiry...'); - const cmd = certbotCommand + ' renew --non-interactive --quiet ' + + const cmd = certbotCommand + ' renew --quiet ' + '--config "' + certbotConfig + '" ' + '--preferred-challenges "dns,http" ' + - '--disable-hook-validation'; + '--no-random-sleep-on-renew ' + + '--disable-hook-validation '; return utils.exec(cmd) .then((result) => { @@ -1005,11 +1006,12 @@ const internalCertificate = { logger.info(`Renewing Certbot certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`); - let mainCmd = certbotCommand + ' renew ' + + let mainCmd = certbotCommand + ' renew --force-renewal ' + '--config "' + certbotConfig + '" ' + '--cert-name "npm-' + certificate.id + '" ' + - '--disable-hook-validation ' + - '--no-random-sleep-on-renew'; + '--preferred-challenges "dns,http" ' + + '--no-random-sleep-on-renew ' + + '--disable-hook-validation '; // Prepend the path to the credentials file as an environment variable if (certificate.meta.dns_provider === 'route53') { diff --git a/backend/templates/default.conf b/backend/templates/default.conf index de6bca2d..921882b5 100644 --- a/backend/templates/default.conf +++ b/backend/templates/default.conf @@ -19,8 +19,9 @@ server { include conf.d/include/block-exploits.conf; add_header alt-svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400'; - ssl_certificate /data/tls/dummycert.pem; - ssl_certificate_key /data/tls/dummykey.pem; + #ssl_certificate ; + #ssl_certificate_key ; + #ssl_trusted_certificate ; {%- if value == "404" %} location / { diff --git a/compose.yaml b/compose.yaml index dabd9fb5..cbafca1e 100644 --- a/compose.yaml +++ b/compose.yaml @@ -13,4 +13,5 @@ services: - "TZ=Europe/Berlin" # - "NGINX_LOG_NOT_FOUND=true" # Allow logging of 404 errors # - "NPM_LISTEN_LOCALHOST=true" # Bind the NPM Dashboard on Port 81 only to localhost -# - "PHP_APKS=php81-curl php-82-curl" # Add php extensions, see aviable packages here: https://pkgs.alpinelinux.org/packages?branch=edge&repo=community&arch=x86_64&name=php8*-* \ No newline at end of file +# - "NPM_CERT_ID=1" # ID of cert, which should be used instead of dummycerts +# - "PHP_APKS=php81-curl php-82-curl" # Add php extensions, see aviable packages here: https://pkgs.alpinelinux.org/packages?branch=edge&repo=community&arch=x86_64&name=php8*-* diff --git a/frontend/js/app/nginx/certificates/form.ejs b/frontend/js/app/nginx/certificates/form.ejs index dc409eab..fe4e3ba9 100644 --- a/frontend/js/app/nginx/certificates/form.ejs +++ b/frontend/js/app/nginx/certificates/form.ejs @@ -18,7 +18,7 @@

<%- i18n('ssl', 'hosts-warning') %>
- +
diff --git a/frontend/js/app/nginx/certificates/list/item.ejs b/frontend/js/app/nginx/certificates/list/item.ejs index bdeeecad..d8cf48e4 100644 --- a/frontend/js/app/nginx/certificates/list/item.ejs +++ b/frontend/js/app/nginx/certificates/list/item.ejs @@ -42,9 +42,11 @@ <% if (provider === 'letsencrypt') { %> <%- i18n('certificates', 'force-renew') %> <%- i18n('certificates', 'download') %> + <% } %> <%- i18n('str', 'delete') %> diff --git a/rootfs/bin/start.sh b/rootfs/bin/start.sh index 0e14604a..1913f667 100644 --- a/rootfs/bin/start.sh +++ b/rootfs/bin/start.sh @@ -3,9 +3,9 @@ # From https://github.com/nextcloud/all-in-one/pull/1377/files if [ -n "$PHP_APKS" ]; then if ! echo "$PHP_APKS" | grep -q "^[a-z0-9 _-]\+$"; then - echo "You've set PHP_APKS but not to an allowed value. -It needs to be a string. Allowed are small letters a-z, digits 0-9, spaces, hyphens and underscores. -It is set to "$PHP_APKS"." || sleep inf + echo "You've set PHP_APKS but not to an allowed value." || echo "error 1" + echo "It needs to be a string. Allowed are small letters a-z, digits 0-9, spaces, hyphens and underscores." || echo "error 2" + echo "It is set to \""$PHP_APKS"\"." || echo "error 3" sleep inf || exit 1 fi @@ -13,16 +13,16 @@ It is set to "$PHP_APKS"." || sleep inf read -ra APKS_ARRAY <<< "$PHP_APKS" || sleep inf for apk in "${APKS_ARRAY[@]}"; do - if ! echo "$apk" | grep -Eq "php81-.*|php82-.*"; then - echo ""$apk" is a non allowed value. -It needs to start with \"php81-\" or \"php82-\". -It is set to "$apk"." || sleep inf + if ! echo "$apk" | grep -Ewq "php81-.*|php82-.*"; then + echo ""$apk" is a non allowed value." || echo "error 4" + echo "It needs to start with \"php81-\" or \"php82-\"." || echo "error 5" + echo "It is set to \""$apk"\"." || echo "error 6" sleep inf || exit 1 fi - echo "Installing "$apk" via apk..." + echo "Installing "$apk" via apk..." | echo "error 7" if ! apk add --no-cache "$apk" &> /dev/null; then - echo "The packet "$apk" was not installed!" || sleep inf + echo "The apk \""$apk"\" was not installed!" || echo "error 8" fi done @@ -38,8 +38,6 @@ mkdir -vp /data/tls/certbot/renewal \ /data/nginx/dead_host \ /data/nginx/stream \ /data/nginx/custom \ - /data/nginx/access \ - /data/nginx/html \ /tmp/acme-challenge || sleep inf if [ -f /data/nginx/default_host/site.conf ]; then @@ -86,7 +84,11 @@ if [ -n "$(ls -A /data/ssl 2> /dev/null)" ]; then mv -v /data/ssl/* /data/tls || sleep inf fi -rm -vrf /data/letsencrypt-acme-challenge \ +rm -vrf /data/nginx/default_host/site.conf \ + /data/nginx/default_www/index.html \ + /data/letsencrypt-acme-challenge \ + /data/nginx/dummycert.pem \ + /data/nginx/dummykey.pem \ /data/nginx/default_host \ /data/nginx/default_www \ /data/nginx/streams \ @@ -131,18 +133,6 @@ find /data/nginx -type f -name '*.conf' -exec sed -i "s|include conf.d/include/a find /data/nginx -type f -name '*.conf' -exec sed -i "s/access_log.*//g" {} \; || sleep inf find /data/nginx -type f -name '*.conf' -exec sed -i "s/proxy_http_version.*//g" {} \; || sleep inf -if [ ! -f /data/tls/dummycert.pem ] || [ ! -f /data/tls/dummykey.pem ]; then -openssl req -new -newkey rsa:4096 -days 365000 -nodes -x509 -subj '/CN=*' -sha256 -keyout /data/tls/dummykey.pem -out /data/tls/dummycert.pem || sleep inf -fi - -if [ ! -f /data/nginx/default.conf ]; then -mv -vn /usr/local/nginx/conf/conf.d/include/default.conf /data/nginx/default.conf || sleep inf -fi - -if [ ! -f /data/tls/certbot/config.ini ]; then -mv -vn /etc/tls/certbot.ini /data/tls/certbot/config.ini || sleep inf -fi - touch /data/etc/html/index.html \ /data/nginx/default.conf \ /data/nginx/custom/root.conf \ @@ -164,6 +154,106 @@ for phpv in $(ls -1 /etc | grep php | sed "s|php||g"); do sed -i "s|group =.*|gr for phpv in $(ls -1 /etc | grep php | sed "s|php||g"); do sed -i "s|listen =.*|listen = /dev/php"$phpv".sock|" /data/php/"$phpv"/php-fpm.d/www.conf; done; for phpv in $(ls -1 /etc | grep php | sed "s|php||g"); do sed -i "s|include=.*|include=/data/php/"$phpv"/php-fpm.d/*.conf|g" /data/php/"$phpv"/php-fpm.conf; done; +if [ -z "$NPM_CERT_ID" ]; then + export NPM_CERT=/data/tls/dummycert.pem + export NPM_KEY=/data/tls/dummykey.pem + echo "no NPM_CERT_ID set, using dummycerts for npm and default hosts." || echo "error 9" +else + if ! echo "$NPM_CERT_ID" | grep -q [0-9]; then + echo "NPM_CERT_ID is a non allowed value." || echo "error 10" + echo "It needs to be a number." || echo "error 11" + echo "It is set to \""$NPM_CERT_ID"\"." || echo "error 12" + export NPM_CERT=/data/tls/dummycert.pem + export NPM_KEY=/data/tls/dummykey.pem + echo "using dummycerts for npm and default hosts." || echo "error 13" + else + + if [ -d "/data/tls/certbot/live/npm-"$NPM_CERT_ID"" ]; then + if ! ls /data/tls/certbot/live/npm-"$NPM_CERT_ID"/fullchain.pem &> /dev/null; then + echo "/data/tls/certbot/live/npm-"$NPM_CERT_ID"/fullchain.pem does not exist" || echo "error 14" + export NPM_CERT=/data/tls/dummycert.pem + export NPM_KEY=/data/tls/dummykey.pem + echo "using dummycerts for npm and default hosts." || echo "error 15" + else + export NPM_CERT=/data/tls/certbot/live/npm-"$NPM_CERT_ID"/fullchain.pem + echo "NPM_CERT set to /data/tls/certbot/live/npm-"$NPM_CERT_ID"/fullchain.pem" || echo "error 16" + + if ! ls /data/tls/certbot/live/npm-"$NPM_CERT_ID"/privkey.pem &> /dev/null; then + echo "/data/tls/certbot/live/npm-"$NPM_CERT_ID"/privkey.pem does not exist" || echo "error 17" + export NPM_CERT=/data/tls/dummycert.pem + export NPM_KEY=/data/tls/dummykey.pem + echo "using dummycerts for npm and default hosts." || echo "error 18" + else + export NPM_KEY=/data/tls/certbot/live/npm-"$NPM_CERT_ID"/privkey.pem + echo "NPM_KEY set to /data/tls/certbot/live/npm-"$NPM_CERT_ID"/privkey.pem" || echo "error 19" + + if ! ls /data/tls/certbot/live/npm-"$NPM_CERT_ID"/chain.pem &> /dev/null; then + echo "/data/tls/certbot/live/npm-"$NPM_CERT_ID"/chain.pem does not exist" || echo "error 20" + export NPM_CERT=/data/tls/dummycert.pem + export NPM_KEY=/data/tls/dummykey.pem + echo "using dummycerts for npm and default hosts." || echo "error 21" + else + export NPM_CHAIN=/data/tls/certbot/live/npm-"$NPM_CERT_ID"/chain.pem + echo "NPM_CHAIN set to /data/tls/certbot/live/npm-"$NPM_CERT_ID"/chain.pem" || echo "error 22" + fi + fi + fi + + elif [ -d "/data/tls/custom/npm-"$NPM_CERT_ID"" ]; then + if ! ls /data/tls/custom/npm-"$NPM_CERT_ID"/fullchain.pem &> /dev/null; then + echo "/data/tls/custom/npm-"$NPM_CERT_ID"/fullchain.pem does not exist" || echo "error 23" + export NPM_CERT=/data/tls/dummycert.pem + export NPM_KEY=/data/tls/dummykey.pem + echo "using dummycerts for npm and default hosts." || echo "error 24" + else + export NPM_CERT=/data/tls/custom/npm-"$NPM_CERT_ID"/fullchain.pem + echo "NPM_CERT set to /data/tls/custom/npm-"$NPM_CERT_ID"/fullchain.pem" || echo "error 25" + + if ! ls /data/tls/custom/npm-"$NPM_CERT_ID"/privkey.pem &> /dev/null; then + echo "/data/tls/custom/npm-"$NPM_CERT_ID"/privkey.pem does not exist" || echo "error 26" + export NPM_CERT=/data/tls/dummycert.pem + export NPM_KEY=/data/tls/dummykey.pem + echo "using dummycerts for npm and default hosts." || echo "error 27" + else + export NPM_KEY=/data/tls/custom/npm-"$NPM_CERT_ID"/privkey.pem + echo "NPM_KEY set to /data/tls/custom/npm-"$NPM_CERT_ID"/privkey.pem" + + if ! ls /data/tls/custom/npm-"$NPM_CERT_ID"/chain.pem &> /dev/null; then + echo "/data/tls/custom/npm-"$NPM_CERT_ID"/chain.pem does not exist" || echo "error 28" + export NPM_CERT=/data/tls/dummycert.pem + export NPM_KEY=/data/tls/dummykey.pem + echo "using dummycerts for npm and default hosts." || echo "error 29" + else + export NPM_CHAIN=/data/tls/custom/npm-"$NPM_CERT_ID"/chain.pem + echo "NPM_CHAIN set to /data/tls/custom/npm-"$NPM_CERT_ID"/chain.pem" || echo "error 30" + fi + fi + fi + + else + export NPM_CERT=/data/tls/dummycert.pem + export NPM_KEY=/data/tls/dummykey.pem + echo "cert with ID "$NPM_CERT_ID" does not exist, using dummycerts for npm and default hosts." || echo "error 31" + fi + fi +fi + +sed -i "s|#ssl_certificate .*|ssl_certificate "$NPM_CERT";|g" /usr/local/nginx/conf/conf.d/include/default.conf +sed -i "s|#ssl_certificate_key .*|ssl_certificate_key "$NPM_KEY";|g" /usr/local/nginx/conf/conf.d/include/default.conf +if [ -n "$NPM_CHAIN" ]; then sed -i "s|#ssl_trusted_certificate .*|ssl_trusted_certificate "$NPM_CHAIN";|g" /usr/local/nginx/conf/conf.d/include/default.conf; fi + +sed -i "s|#ssl_certificate .*|ssl_certificate "$NPM_CERT";|g" /usr/local/nginx/conf/conf.d/no-server-name.conf +sed -i "s|#ssl_certificate_key .*|ssl_certificate_key "$NPM_KEY";|g" /usr/local/nginx/conf/conf.d/no-server-name.conf +if [ -n "$NPM_CHAIN" ]; then sed -i "s|#ssl_trusted_certificate .*|ssl_trusted_certificate "$NPM_CHAIN";|g" /usr/local/nginx/conf/conf.d/no-server-name.conf; fi + +sed -i "s|#ssl_certificate .*|ssl_certificate "$NPM_CERT";|g" /usr/local/nginx/conf/conf.d/npm.conf +sed -i "s|#ssl_certificate_key .*|ssl_certificate_key "$NPM_KEY";|g" /usr/local/nginx/conf/conf.d/npm.conf +if [ -n "$NPM_CHAIN" ]; then sed -i "s|#ssl_trusted_certificate .*|ssl_trusted_certificate "$NPM_CHAIN";|g" /usr/local/nginx/conf/conf.d/npm.conf; fi + +sed -i "s|#ssl_certificate .*|ssl_certificate "$NPM_CERT";|g" /app/templates/default.conf +sed -i "s|#ssl_certificate_key .*|ssl_certificate_key "$NPM_KEY";|g" /app/templates/default.conf +if [ -n "$NPM_CHAIN" ]; then sed -i "s|#ssl_trusted_certificate .*|ssl_trusted_certificate "$NPM_CHAIN";|g" /app/templates/default.conf; fi + if [ "$NPM_LISTEN_LOCALHOST" == "true" ]; then sed -i "s/listen 81/listen 127.0.0.1:81/g" /usr/local/nginx/conf/conf.d/npm.conf || sleep inf sed -i "s/listen \[::\]:81/listen \[::1\]:81/g" /usr/local/nginx/conf/conf.d/npm.conf || sleep inf @@ -173,6 +263,27 @@ if [ "$NGINX_LOG_NOT_FOUND" == "true" ]; then sed -i "s/log_not_found off;/log_not_found on;/g" /usr/local/nginx/conf/nginx.conf || sleep inf fi +if [ -z "$NPM_CERT_ID" ]; then + if [ ! -f /data/tls/dummycert.pem ] || [ ! -f /data/tls/dummykey.pem ]; then + openssl req -new -newkey rsa:4096 -days 365000 -nodes -x509 -subj '/CN=*' -sha256 -keyout /data/tls/dummykey.pem -out /data/tls/dummycert.pem || sleep inf + fi +else + rm -vrf /data/tls/dummycert.pem \ + /data/tls/dummykey.pem +fi + +if [ ! -f /data/nginx/default.conf ]; then +mv -vn /usr/local/nginx/conf/conf.d/include/default.conf /data/nginx/default.conf || sleep inf +fi + +if [ ! -f /data/tls/certbot/config.ini ]; then +mv -vn /etc/tls/certbot.ini /data/tls/certbot/config.ini || sleep inf +fi + +sed -i "s|ssl_certificate .*|ssl_certificate "$NPM_CERT";|g" /data/nginx/default.conf +sed -i "s|ssl_certificate_key .*|ssl_certificate_key "$NPM_KEY";|g" /data/nginx/default.conf +if [ -n "$NPM_CHAIN" ]; then sed -i "s|ssl_trusted_certificate .*|ssl_trusted_certificate "$NPM_CHAIN";|g" /data/nginx/default.conf; fi + if ! nginx -t &> /dev/null; then nginx -T || sleep inf sleep inf || exit 1 @@ -206,4 +317,4 @@ fi if ! cross-env PHP_INI_SCAN_DIR=/data/php/82/conf.d php-fpm82 -c /data/php/82 -y /data/php/82/php-fpm.conf -FORt &> /dev/null; then cross-env PHP_INI_SCAN_DIR=/data/php/82/conf.d php-fpm82 -c /data/php/82 -y /data/php/82/php-fpm.conf -FORt || exit 1 -fi \ No newline at end of file +fi diff --git a/rootfs/etc/tls/certbot.ini b/rootfs/etc/tls/certbot.ini index e50f5b5d..a9a0f909 100644 --- a/rootfs/etc/tls/certbot.ini +++ b/rootfs/etc/tls/certbot.ini @@ -1,11 +1,13 @@ -text = true agree-tos = true non-interactive = true +webroot-path = /tmp/acme-challenge + +new-key= true key-type = ecdsa must-staple = true +no-reuse-key = true rsa-key-size = 4096 elliptic-curve = secp384r1 -webroot-path = /tmp/acme-challenge # An example of using an alternate ACME server that uses EAB credentials # server = https://dv.acme-v02.api.pki.goog/directory diff --git a/rootfs/usr/local/nginx/conf/conf.d/include/default.conf b/rootfs/usr/local/nginx/conf/conf.d/include/default.conf index bfa3e1b8..83d79b4a 100644 --- a/rootfs/usr/local/nginx/conf/conf.d/include/default.conf +++ b/rootfs/usr/local/nginx/conf/conf.d/include/default.conf @@ -19,8 +19,9 @@ server { include conf.d/include/block-exploits.conf; add_header alt-svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400'; - ssl_certificate /data/tls/dummycert.pem; - ssl_certificate_key /data/tls/dummykey.pem; + #ssl_certificate ; + #ssl_certificate_key ; + #ssl_trusted_certificate ; location / { include conf.d/include/acme-challenge.conf; diff --git a/rootfs/usr/local/nginx/conf/conf.d/no-server-name.conf b/rootfs/usr/local/nginx/conf/conf.d/no-server-name.conf index a1b58b35..44a87c4a 100644 --- a/rootfs/usr/local/nginx/conf/conf.d/no-server-name.conf +++ b/rootfs/usr/local/nginx/conf/conf.d/no-server-name.conf @@ -22,6 +22,7 @@ server { include conf.d/include/block-exploits.conf; add_header alt-svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400'; - ssl_certificate /data/tls/dummycert.pem; - ssl_certificate_key /data/tls/dummykey.pem; + #ssl_certificate ; + #ssl_certificate_key ; + #ssl_trusted_certificate ; } diff --git a/rootfs/usr/local/nginx/conf/conf.d/npm.conf b/rootfs/usr/local/nginx/conf/conf.d/npm.conf index e7501a27..035a8cc4 100644 --- a/rootfs/usr/local/nginx/conf/conf.d/npm.conf +++ b/rootfs/usr/local/nginx/conf/conf.d/npm.conf @@ -4,13 +4,16 @@ server { listen [::]:81 ssl http2 default_server; listen [::]:81 http3 default_server; + add_header alt-svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400'; server_name _; - ssl_certificate /data/tls/dummycert.pem; - ssl_certificate_key /data/tls/dummykey.pem; + include conf.d/include/force-ssl.conf; include conf.d/include/tls-ciphers.conf; include conf.d/include/block-exploits.conf; - add_header alt-svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400'; + + #ssl_certificate ; + #ssl_certificate_key ; + #ssl_trusted_certificate ; location /api { return 301 /api/;