diff --git a/Dockerfile b/Dockerfile index 4fcc0cb1..885b153a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,21 +29,47 @@ RUN apk add --no-cache ca-certificates nodejs-current yarn && \ yarn cache clean --all FROM python:3.11.3-alpine3.18 as certbot -RUN apk add --no-cache build-base libffi-dev && \ +RUN apk add --no-cache ca-certificates build-base libffi-dev && \ python3 -m venv /usr/local/certbot && \ . /usr/local/certbot/bin/activate && \ pip install --no-cache-dir certbot -FROM zoeyvid/nginx-quic:122 +FROM --platform="$BUILDPLATFORM" alpine:3.18.0 as crowdsec +RUN apk add --no-cache ca-certificates git build-base && \ + git clone --recursive https://github.com/crowdsecurity/cs-nginx-bouncer /src && \ + cd /src && \ + make && \ + tar xzf crowdsec-nginx-bouncer.tgz && \ + mv crowdsec-nginx-bouncer-* crowdsec-nginx-bouncer && \ + cd /src/crowdsec-nginx-bouncer && \ + sed -i "/lua_package_path/d" nginx/crowdsec_nginx.conf && \ + sed -i "s|/etc/crowdsec/bouncers/crowdsec-nginx-bouncer.conf|/data/etc/crowdsec/crowdsec.conf|g" nginx/crowdsec_nginx.conf && \ + sed -i "s|API_KEY=.*|API_KEY=|g" lua-mod/config_example.conf && \ + sed -i "s|ENABLED=.*|ENABLED=false|g" lua-mod/config_example.conf && \ + sed -i "s|API_URL=.*|API_URL=http://127.0.0.1:8080|g" lua-mod/config_example.conf && \ + sed -i "s|BAN_TEMPLATE_PATH=.*|BAN_TEMPLATE_PATH=/data/etc/crowdsec/ban.html|g" lua-mod/config_example.conf && \ + sed -i "s|CAPTCHA_TEMPLATE_PATH=.*|CAPTCHA_TEMPLATE_PATH=/data/etc/crowdsec/crowdsec.conf|g" lua-mod/config_example.conf + +FROM zoeyvid/nginx-quic:126 RUN apk add --no-cache ca-certificates tzdata \ nodejs-current \ + luarocks5.1 wget lua5.1-dev build-base \ openssl apache2-utils \ - coreutils grep jq curl shadow sudo + coreutils grep jq curl shadow sudo && \ + luarocks-5.1 install lua-resty-http && \ + luarocks-5.1 install lua-cjson && \ + apk del --no-cache luarocks5.1 wget lua5.1-dev build-base -COPY rootfs / -COPY --from=backend /build/backend /app -COPY --from=frontend /build/frontend/dist /app/frontend -COPY --from=certbot /usr/local/certbot /usr/local/certbot +COPY rootfs / +COPY --from=backend /build/backend /app +COPY --from=frontend /build/frontend/dist /app/frontend +COPY --from=certbot /usr/local/certbot /usr/local/certbot +COPY --from=crowdsec /src/crowdsec-nginx-bouncer/lua-mod/lib/plugins /usr/local/nginx/lib/lua/plugins +COPY --from=crowdsec /src/crowdsec-nginx-bouncer/lua-mod/lib/crowdsec.lua /usr/local/nginx/lib/lua/crowdsec.lua +COPY --from=crowdsec /src/crowdsec-nginx-bouncer/lua-mod/templates/ban.html /usr/local/nginx/conf/conf.d/include/ban.html +COPY --from=crowdsec /src/crowdsec-nginx-bouncer/lua-mod/templates/captcha.html /usr/local/nginx/conf/conf.d/include/captcha.html +COPY --from=crowdsec /src/crowdsec-nginx-bouncer/lua-mod/config_example.conf /usr/local/nginx/conf/conf.d/include/crowdsec.conf +COPY --from=crowdsec /src/crowdsec-nginx-bouncer/nginx/crowdsec_nginx.conf /usr/local/nginx/conf/conf.d/include/crowdsec_nginx.conf RUN ln -s /app/password-reset.js /usr/local/bin/password-reset.js && \ ln -s /app/sqlite-vaccum.js /usr/local/bin/sqlite-vaccum.js && \ diff --git a/README.md b/README.md index 2b3f33d3..9e909527 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ so that the barrier for entry here is low. # List of new features - Supports HTTP/3 (QUIC) protocol +- Supports Crowdsec. Please read below for instructions on how to use it. - Darkmode button in the footer for comfortable viewing - Fixes proxy to https origin when the origin only accepts TLSv1.3 - Only enables TLSv1.2 and TLSv1.3 protocols @@ -86,6 +87,20 @@ so that the barrier for entry here is low. - 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 - please delete all dnspod certs and recreate them OR you manually change the credentialsfile (see [here](https://github.com/ZoeyVid/nginx-proxy-manager/blob/develop/global/certbot-dns-plugins.js) for the template) +- since this fork has dependency on `network_mode: host`, please don't forget to open port 80 and 443 (and maybe 81) in your firewall + +# Crowdsec +1. Install crowdsec: https://doc.crowdsec.net/docs/getting_started/install_crowdsec +2. make sure to use `network_mode: host` in your compose file +3. run `cscli bouncers add npm -o raw` and save the output +4. run `cscli config show --key "Config.API.Client.Credentials.URL"` and save the output +5. open `/data/etc/crowdsec/crowdsec.conf` +6. set `ENABLED` to `true` +7. use the output of step 4 as `API_KEY` +8. use the output of step 5 as `API_URL` - But remove the `/` at the end (correct: `http://127.0.0.1:8080` - incorrect: `http://127.0.0.1:8080/`) +9. make your changes +10. save the file +11. restart the npm # Use as webserver diff --git a/rootfs/bin/start.sh b/rootfs/bin/start.sh index 8921caf7..8cf45c5e 100755 --- a/rootfs/bin/start.sh +++ b/rootfs/bin/start.sh @@ -179,7 +179,7 @@ fi mkdir -p /tmp/acme-challenge \ /tmp/certbot-work \ - /tmp/certbot-log + /tmp/certbot-log \ /tmp/npmhome mkdir -vp /data/tls/certbot/renewal \ @@ -187,6 +187,7 @@ mkdir -vp /data/tls/certbot/renewal \ /data/etc/npm \ /data/etc/html \ /data/etc/access \ + /data/etc/crowdsec \ /data/nginx/redirection_host \ /data/nginx/proxy_host \ /data/nginx/dead_host \ @@ -214,15 +215,15 @@ if [ -f /data/nginx/dummykey.pem ]; then fi if [ -n "$(ls -A /data/nginx/html 2> /dev/null)" ]; then - mv -v /data/nginx/html/* /data/etc/html + mv -vn /data/nginx/html/* /data/etc/html fi if [ -n "$(ls -A /data/access 2> /dev/null)" ]; then - mv -v /data/access/* /data/etc/access + mv -vn /data/access/* /data/etc/access fi if [ -n "$(ls -A /data/nginx/access 2> /dev/null)" ]; then - mv -v /data/nginx/access/* /data/etc/access + mv -vn /data/nginx/access/* /data/etc/access fi if [ -n "$(ls -A /etc/letsencrypt 2> /dev/null)" ]; then @@ -230,15 +231,15 @@ if [ -n "$(ls -A /etc/letsencrypt 2> /dev/null)" ]; then fi if [ -n "$(ls -A /data/letsencrypt 2> /dev/null)" ]; then - mv -v /data/letsencrypt/* /data/tls/certbot + mv -vn /data/letsencrypt/* /data/tls/certbot fi if [ -n "$(ls -A /data/custom_ssl 2> /dev/null)" ]; then - mv -v /data/custom_ssl/* /data/tls/custom + mv -vn /data/custom_ssl/* /data/tls/custom fi if [ -n "$(ls -A /data/ssl 2> /dev/null)" ]; then - mv -v /data/ssl/* /data/tls + mv -vn /data/ssl/* /data/tls fi if [ -z "$CLEAN" ]; then @@ -283,7 +284,7 @@ if [ "$FULLCLEAN" = "true" ]; then certbot-cleaner.sh fi -find /data/nginx -type f -name '*.conf' -exec sed -i "s|listen 80 http2|listen 80|g" {} \; +find /data/nginx -type f -name '*.conf' -exec sed -i "s|80 http2|80|g" {} \; find /data/nginx -type f -name '*.conf' -exec sed -i "s|\(listen .*\) http3|\1 quic|g" {} \; find /data/nginx -type f -name '*.conf' -exec sed -i "s|/data/nginx/html/|/data/etc/html/|g" {} \; @@ -424,36 +425,31 @@ else /data/tls/dummykey.pem fi -ns="$(tr "[:upper:]" "[:lower:]" < /etc/resolv.conf | grep -P "^nameserver ((?:[0-9.]+)|(?:[0-9a-f:]+))$" | awk 'BEGIN{ORS=" "} $1=="nameserver" { sub(/%.*$/,"",$2); print ($2 ~ ":")? "["$2"]": $2}' | sed "s| *$||")" -export ns if [ "$DISABLE_IPV6" = "true" ]; then - sed -i "s|resolver.*|resolver $ns valid=10s ipv6=off;|g" /usr/local/nginx/conf/nginx.conf + sed -i "s|#\?resolver .*|resolver local=on valid=10s ipv6=off;|g" /usr/local/nginx/conf/nginx.conf else - sed -i "s|resolver.*|resolver $ns valid=10s;|g" /usr/local/nginx/conf/nginx.conf + sed -i "s|#\?resolver .*|resolver local=on valid=10s;|g" /usr/local/nginx/conf/nginx.conf fi -echo "using this nameservers: \"$ns\"" -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/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/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-no-server-name.conf -sed -i "s|#ssl_certificate_key .*|ssl_certificate_key $NPM_KEY;|g" /usr/local/nginx/conf/conf.d/npm-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/npm-no-server-name.conf; fi +sed -i "s|#\?ssl_certificate .*|ssl_certificate $NPM_CERT;|g" /usr/local/nginx/conf/conf.d/npm-no-server-name.conf +sed -i "s|#\?ssl_certificate_key .*|ssl_certificate_key $NPM_KEY;|g" /usr/local/nginx/conf/conf.d/npm-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/npm-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" /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 - -find /data/nginx -type f -name '*.conf' -exec sed -i "s|80 http2|80|g" {} \; +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 export NIBEP="${NIBEP:-48693}" sed -i "s|48693|$NIBEP|g" /app/index.js @@ -525,11 +521,29 @@ if [ "$NGINX_LOG_NOT_FOUND" = "true" ]; then fi if [ ! -f /data/nginx/default.conf ]; then - mv -vn /usr/local/nginx/conf/conf.d/include/default.conf /data/nginx/default.conf + cp -vn /usr/local/nginx/conf/conf.d/include/default.conf /data/nginx/default.conf fi if [ ! -f /data/tls/certbot/config.ini ]; then - mv -vn /etc/tls/certbot.ini /data/tls/certbot/config.ini + cp -vn /etc/tls/certbot.ini /data/tls/certbot/config.ini +fi + +if [ ! -f /data/etc/crowdsec/ban.html ]; then + cp -vn /usr/local/nginx/conf/conf.d/include/ban.html /data/etc/crowdsec/ban.html +fi + +if [ ! -f /data/etc/crowdsec/captcha.html ]; then + cp -vn /usr/local/nginx/conf/conf.d/include/captcha.html /data/etc/crowdsec/captcha.html +fi + +if [ ! -f /data/etc/crowdsec/crowdsec.conf ]; then + cp -vn /usr/local/nginx/conf/conf.d/include/crowdsec.conf /data/etc/crowdsec/crowdsec.conf +fi + +if grep -Eiq "ENABLED.*=.*true" /data/etc/crowdsec/crowdsec.conf; then + cp -vn /usr/local/nginx/conf/conf.d/include/crowdsec_nginx.conf /usr/local/nginx/conf/conf.d/crowdsec.conf +else + rm -vf /usr/local/nginx/conf/conf.d/crowdsec.conf fi sed -i "s|ssl_certificate .*|ssl_certificate $NPM_CERT;|g" /data/nginx/default.conf @@ -573,6 +587,6 @@ else /usr/local/nginx \ /data \ /tmp - sed -i "s|#user root;|user root;|g" /usr/local/nginx/conf/nginx.conf + sed -i "s|#\?user root;|user root;|g" /usr/local/nginx/conf/nginx.conf launch.sh fi diff --git a/rootfs/usr/local/nginx/conf/nginx.conf b/rootfs/usr/local/nginx/conf/nginx.conf index 635eac7d..11b97482 100644 --- a/rootfs/usr/local/nginx/conf/nginx.conf +++ b/rootfs/usr/local/nginx/conf/nginx.conf @@ -4,8 +4,6 @@ pcre_jit on; worker_processes auto; error_log stderr; -quic_bpf on; - # Custom include /data/nginx/custom/root.conf; @@ -22,15 +20,13 @@ http { include mime.types; default_type text/plain; + lua_package_path "/usr/local/nginx/lib/lua/?.lua;;"; server_tokens build; aio threads; sendfile on; - quic_gso on; - #quic_retry on; tcp_nopush on; tcp_nodelay on; - http3_push_preload on; client_max_body_size 0; client_body_buffer_size 512k; @@ -42,7 +38,7 @@ http { gunzip on; gzip_static on; - resolver localhost; + #resolver ; fastcgi_index index.php; index index.php index.html; @@ -119,8 +115,6 @@ http { } stream { - quic_gso on; - #quic_retry on; # Files generated by NPM include /data/nginx/stream/*.conf; diff --git a/security.txt b/security.txt index 772eb654..1629814c 100644 --- a/security.txt +++ b/security.txt @@ -5,13 +5,11 @@ Contact: mailto:zoeyvid@zvcdn.de Expires: 2023-12-31T22:59:00.000Z Encryption: https://zvcdn.de/publickey.asc Preferred-Languages: de, en -Canonical: https://npm.zvcdn.de/.well-known/security.txt -Canonical: https://npm-mx.zvcdn.de/.well-known/security.txt Canonical: https://raw.githubusercontent.com/ZoeyVid/nginx-proxy-manager/develop/security.txt -----BEGIN PGP SIGNATURE----- -iHUEARYKAB0WIQQZsl0LheH0mUz2hsVuOQn3bP/+fAUCY+oWmgAKCRBuOQn3bP/+ -fG4EAP9WXH5lT1OXjtNeM44ZaRwdtrm/Z/x515E0TDJ1S6NFTgD/WENwGwBzKApW -Qv+aYLdHLBaYnJsj9D3RYjCuijLckQs= -=nFDM +iHUEARYKAB0WIQQZsl0LheH0mUz2hsVuOQn3bP/+fAUCZG0RHAAKCRBuOQn3bP/+ +fBHSAP9YsPZ5LqsVuZYQ5bKEtcp3OfXGx9HaGob+XA78MNhOkAD+LueNhMhRYeHx +ohiJZNIAx8DsB9YZPGwvhY2nGCUbqwg= +=/m+5 -----END PGP SIGNATURE-----