From 76588a8e2f764473c586f0ca75b33c8c56508671 Mon Sep 17 00:00:00 2001 From: baudneo Date: Fri, 18 Feb 2022 14:42:11 -0700 Subject: [PATCH] Add CrowdSec OpenResty bouncer config - ENV: CROWDSEC_BOUNCER = 1 to enable. /data/crowdsec/crowdsec-openresty-bouncer.conf is the configuration file for it. Add Admin dashboard logging to the /data/logs/admin-panel_[access/error].log folder - ENV: ADMIN_PANEL_LOG = 1 to enable. Add OpenResty error log (fallback_error.log) debug level - ENV: OPENRESTY_DEBUG = 1 to enable. --- docker/Dockerfile | 21 +-- docker/rootfs/etc/cont-init.d/01_perms.sh | 2 +- .../etc/cont-init.d/98_logging-options.sh | 29 +++++ .../99_crowdsec-openresty-bouncer.sh | 50 +++++++ .../rootfs/etc/nginx/conf.d/production.conf | 54 ++++---- docker/rootfs/etc/nginx/nginx.conf | 122 +++++++++--------- 6 files changed, 180 insertions(+), 98 deletions(-) create mode 100755 docker/rootfs/etc/cont-init.d/98_logging-options.sh create mode 100755 docker/rootfs/etc/cont-init.d/99_crowdsec-openresty-bouncer.sh diff --git a/docker/Dockerfile b/docker/Dockerfile index a976ade2..b75a2980 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -11,18 +11,19 @@ ARG BUILD_COMMIT ARG BUILD_DATE ENV SUPPRESS_NO_CONFIG_WARNING=1 \ - S6_FIX_ATTRS_HIDDEN=1 \ - S6_BEHAVIOUR_IF_STAGE2_FAILS=1 \ - NODE_ENV=production \ - NPM_BUILD_VERSION="${BUILD_VERSION}" \ - NPM_BUILD_COMMIT="${BUILD_COMMIT}" \ - NPM_BUILD_DATE="${BUILD_DATE}" + S6_FIX_ATTRS_HIDDEN=1 \ + S6_BEHAVIOUR_IF_STAGE2_FAILS=1 \ + NODE_ENV=production \ + NPM_BUILD_VERSION="${BUILD_VERSION}" \ + NPM_BUILD_COMMIT="${BUILD_COMMIT}" \ + NPM_BUILD_DATE="${BUILD_DATE}" \ + OPENRESTY_DEBUG="0" RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \ - && apt-get update \ - && apt-get install -y --no-install-recommends jq logrotate \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* + && apt-get update \ + && apt-get install -y --no-install-recommends jq logrotate \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* # s6 overlay COPY scripts/install-s6 /tmp/install-s6 diff --git a/docker/rootfs/etc/cont-init.d/01_perms.sh b/docker/rootfs/etc/cont-init.d/01_perms.sh index e7875d32..7aeccc0c 100755 --- a/docker/rootfs/etc/cont-init.d/01_perms.sh +++ b/docker/rootfs/etc/cont-init.d/01_perms.sh @@ -1,7 +1,7 @@ #!/usr/bin/with-contenv bash +# shellcheck shell=bash set -e mkdir -p /data/logs echo "Changing ownership of /data/logs to $(id -u):$(id -g)" chown -R "$(id -u):$(id -g)" /data/logs - diff --git a/docker/rootfs/etc/cont-init.d/98_logging-options.sh b/docker/rootfs/etc/cont-init.d/98_logging-options.sh new file mode 100755 index 00000000..78b3b28e --- /dev/null +++ b/docker/rootfs/etc/cont-init.d/98_logging-options.sh @@ -0,0 +1,29 @@ +#!/usr/bin/with-contenv bash +# shellcheck shell=bash + +set -e # Exit immediately if a command exits with a non-zero status. +set -u # Treat unset variables as an error. + +# Redirect admin panel logs from /dev/null to log files if enabled +if [[ ${ADMIN_PANEL_LOG} == "1" ]] || [[ ${ADMIN_PANEL_LOG} -eq 1 ]]; then + echo "Enabling admin dashboard logging" + echo "ADMIN_PANEL_LOG = $ADMIN_PANEL_LOG" + sed-patch 's||/data/logs/admin-panel_access.log standard|' /etc/nginx/conf.d/production.conf + sed-patch 's||/data/logs/admin-panel_error.log warn|' /etc/nginx/conf.d/production.conf +else + echo "Leaving admin dashboard logging off (default behavior)" + echo "ADMIN_PANEL_LOG = $ADMIN_PANEL_LOG" + sed-patch 's||/dev/null|' /etc/nginx/conf.d/production.conf + sed-patch 's||/dev/null|' /etc/nginx/conf.d/production.conf +fi + +if [[ ${OPENRESTY_DEBUG} == "1" ]] || [[ ${OPENRESTY_DEBUG} -eq 1 ]]; then + echo "Changing OpenResty ERROR (fallback_error.log) logging to level: DEBUG" + echo "OPENRESTY_DEBUG = $OPENRESTY_DEBUG" + sed-patch 's||debug|' /etc/nginx/nginx.conf + +else + echo "Leaving OpenResty ERROR (fallback_error.log) logging at level: WARN (default behavior)" + echo "OPENRESTY_DEBUG = $OPENRESTY_DEBUG" + sed-patch 's||warn|' /etc/nginx/nginx.conf +fi diff --git a/docker/rootfs/etc/cont-init.d/99_crowdsec-openresty-bouncer.sh b/docker/rootfs/etc/cont-init.d/99_crowdsec-openresty-bouncer.sh new file mode 100755 index 00000000..0baaed9b --- /dev/null +++ b/docker/rootfs/etc/cont-init.d/99_crowdsec-openresty-bouncer.sh @@ -0,0 +1,50 @@ +#!/usr/bin/with-contenv bash +# shellcheck shell=bash + +set -e # Exit immediately if a command exits with a non-zero status. +set -u # Treat unset variables as an error. + +# Redirect admin panel logs from /dev/null to log files if enabled +if [[ ${ADMIN_PANEL_LOG} == "1" ]] || [[ ${ADMIN_PANEL_LOG} -eq 1 ]]; then + echo "Enabling admin dashboard logging" + echo "ADMIN_PANEL_LOG = $ADMIN_PANEL_LOG" + sed-patch 's||/data/logs/admin-panel_access.log standard|' /etc/nginx/conf.d/production.conf + sed-patch 's||/data/logs/admin-panel_error.log warn|' /etc/nginx/conf.d/production.conf +else + echo "Leaving admin dashboard logging off (default behavior)" + echo "ADMIN_PANEL_LOG = $ADMIN_PANEL_LOG" + sed-patch 's||/dev/null|' /etc/nginx/conf.d/production.conf + sed-patch 's||/dev/null|' /etc/nginx/conf.d/production.conf +fi + +if [[ ${OPENRESTY_DEBUG} == "1" ]] || [[ ${OPENRESTY_DEBUG} -eq 1 ]]; then + echo "Changing OpenResty ERROR (fallback_error.log) logging to level: DEBUG" + echo "OPENRESTY_DEBUG = $OPENRESTY_DEBUG" + sed-patch 's||debug|' /etc/nginx/nginx.conf + +else + echo "Leaving OpenResty ERROR (fallback_error.log) logging at level: WARN (default behavior)" + echo "OPENRESTY_DEBUG = $OPENRESTY_DEBUG" + sed-patch 's||warn|' /etc/nginx/nginx.conf +fi + +❯ cat docker/rootfs/etc/cont-init.d/99_crowdsec-openresty-bouncer.sh +#!/usr/bin/with-contenv bash +# shellcheck shell=bash + +set -e # Exit immediately if a command exits with a non-zero status. +set -u # Treat unset variables as an error. + +log() { + echo "[cont-init.d] $(basename "$0"): $*" +} + +if [ "${CROWDSEC_BOUNCER}" == "1" ] || [ "${CROWDSEC_BOUNCER}" -eq 1 ]; then + mkdir -p /data/crowdsec + #Install Crowdsec Bouncer Config. + [ -f /data/crowdsec/crowdsec-openresty-bouncer.conf ] || cp /crowdsec/crowdsec-openresty-bouncer.conf /data/crowdsec/crowdsec-openresty-bouncer.conf + mkdir -p /etc/nginx/lualib/plugins/crowdsec/ + cp /crowdsec/lua/* /etc/nginx/lualib/plugins/crowdsec/ + cp /crowdsec/crowdsec_openresty.conf /etc/nginx/conf.d/ + sed-patch 's|ok, err = require "crowdsec".allowIp(ngx.var.remote_addr)|local ok, err = require "crowdsec".allowIp(ngx.var.remote_addr)|' /etc/nginx/lualib/plugins/crowdsec/access.lua +fi \ No newline at end of file diff --git a/docker/rootfs/etc/nginx/conf.d/production.conf b/docker/rootfs/etc/nginx/conf.d/production.conf index 877e51dd..49db676c 100644 --- a/docker/rootfs/etc/nginx/conf.d/production.conf +++ b/docker/rootfs/etc/nginx/conf.d/production.conf @@ -1,33 +1,35 @@ # Admin Interface server { - listen 81 default; - listen [::]:81 default; + listen 81 default; + listen [::]:81 default; - server_name nginxproxymanager; - root /app/frontend; - access_log /dev/null; + server_name nginxproxymanager; + root /app/frontend; + # Replaced with /dev/null by default unless ADMIN_PANEL_LOG is set to '1' + access_log ; + error_log ; - location /api { - return 302 /api/; - } + location /api { + return 302 /api/; + } - location /api/ { - add_header X-Served-By $host; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-Scheme $scheme; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_pass http://127.0.0.1:3000/; + location /api/ { + add_header X-Served-By $host; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Scheme $scheme; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_pass http://127.0.0.1:3000/; - proxy_read_timeout 15m; - proxy_send_timeout 15m; - } + proxy_read_timeout 15m; + proxy_send_timeout 15m; + } - location / { - index index.html; - if ($request_uri ~ ^/(.*)\.html$) { - return 302 /$1; - } - try_files $uri $uri.html $uri/ /index.html; - } -} + location / { + index index.html; + if ($request_uri ~ ^/(.*)\.html$) { + return 302 /$1; + } + try_files $uri $uri.html $uri/ /index.html; + } +} \ No newline at end of file diff --git a/docker/rootfs/etc/nginx/nginx.conf b/docker/rootfs/etc/nginx/nginx.conf index 4d5ee901..0a9fc036 100644 --- a/docker/rootfs/etc/nginx/nginx.conf +++ b/docker/rootfs/etc/nginx/nginx.conf @@ -9,87 +9,87 @@ worker_processes auto; # Enables the use of JIT for regular expressions to speed-up their processing. pcre_jit on; -error_log /data/logs/fallback_error.log warn; +error_log /data/logs/fallback_error.log ; # Includes files with directives to load dynamic modules. include /etc/nginx/modules/*.conf; events { - worker_connections 1024; + worker_connections 1024; } http { - include /etc/nginx/mime.types; - default_type application/octet-stream; - sendfile on; - server_tokens off; - tcp_nopush on; - tcp_nodelay on; - client_body_temp_path /tmp/nginx/body 1 2; - keepalive_timeout 90s; - proxy_connect_timeout 90s; - proxy_send_timeout 90s; - proxy_read_timeout 90s; - ssl_prefer_server_ciphers on; - gzip on; - proxy_ignore_client_abort off; - client_max_body_size 2000m; - server_names_hash_bucket_size 1024; - proxy_http_version 1.1; - proxy_set_header X-Forwarded-Scheme $scheme; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Accept-Encoding ""; - proxy_cache off; - proxy_cache_path /var/lib/nginx/cache/public levels=1:2 keys_zone=public-cache:30m max_size=192m; - proxy_cache_path /var/lib/nginx/cache/private levels=1:2 keys_zone=private-cache:5m max_size=1024m; + include /etc/nginx/mime.types; + default_type application/octet-stream; + sendfile on; + server_tokens off; + tcp_nopush on; + tcp_nodelay on; + client_body_temp_path /tmp/nginx/body 1 2; + keepalive_timeout 90s; + proxy_connect_timeout 90s; + proxy_send_timeout 90s; + proxy_read_timeout 90s; + ssl_prefer_server_ciphers on; + gzip on; + proxy_ignore_client_abort off; + client_max_body_size 2000m; + server_names_hash_bucket_size 1024; + proxy_http_version 1.1; + proxy_set_header X-Forwarded-Scheme $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Accept-Encoding ""; + proxy_cache off; + proxy_cache_path /var/lib/nginx/cache/public levels=1:2 keys_zone=public-cache:30m max_size=192m; + proxy_cache_path /var/lib/nginx/cache/private levels=1:2 keys_zone=private-cache:5m max_size=1024m; - log_format proxy '[$time_local] $upstream_cache_status $upstream_status $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] [Sent-to $server] "$http_user_agent" "$http_referer"'; - log_format standard '[$time_local] $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] "$http_user_agent" "$http_referer"'; + log_format proxy '[$time_local] $upstream_cache_status $upstream_status $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] [Sent-to $server] "$http_user_agent" "$http_referer"'; + log_format standard '[$time_local] $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] "$http_user_agent" "$http_referer"'; - access_log /data/logs/fallback_access.log proxy; + access_log /data/logs/fallback_access.log proxy; - # Dynamically generated resolvers file - include /etc/nginx/conf.d/include/resolvers.conf; + # Dynamically generated resolvers file + include /etc/nginx/conf.d/include/resolvers.conf; - # Default upstream scheme - map $host $forward_scheme { - default http; - } + # Default upstream scheme + map $host $forward_scheme { + default http; + } - # Real IP Determination - - # Local subnets: - set_real_ip_from 10.0.0.0/8; - set_real_ip_from 172.16.0.0/12; # Includes Docker subnet - set_real_ip_from 192.168.0.0/16; - # NPM generated CDN ip ranges: - include conf.d/include/ip_ranges.conf; - # always put the following 2 lines after ip subnets: - real_ip_header X-Real-IP; - real_ip_recursive on; + # Real IP Determination - # Custom - include /data/nginx/custom/http_top[.]conf; + # Local subnets: + set_real_ip_from 10.0.0.0/8; + set_real_ip_from 172.16.0.0/12; # Includes Docker subnet + set_real_ip_from 192.168.0.0/16; + # NPM generated CDN ip ranges: + include conf.d/include/ip_ranges.conf; + # always put the following 2 lines after ip subnets: + real_ip_header X-Real-IP; + real_ip_recursive on; - # Files generated by NPM - include /etc/nginx/conf.d/*.conf; - include /data/nginx/default_host/*.conf; - include /data/nginx/proxy_host/*.conf; - include /data/nginx/redirection_host/*.conf; - include /data/nginx/dead_host/*.conf; - include /data/nginx/temp/*.conf; + # Custom + include /data/nginx/custom/http_top[.]conf; - # Custom - include /data/nginx/custom/http[.]conf; + # Files generated by NPM + include /etc/nginx/conf.d/*.conf; + include /data/nginx/default_host/*.conf; + include /data/nginx/proxy_host/*.conf; + include /data/nginx/redirection_host/*.conf; + include /data/nginx/dead_host/*.conf; + include /data/nginx/temp/*.conf; + + # Custom + include /data/nginx/custom/http[.]conf; } stream { - # Files generated by NPM - include /data/nginx/stream/*.conf; + # Files generated by NPM + include /data/nginx/stream/*.conf; - # Custom - include /data/nginx/custom/stream[.]conf; + # Custom + include /data/nginx/custom/stream[.]conf; } # Custom -include /data/nginx/custom/root[.]conf; +include /data/nginx/custom/root[.]conf; \ No newline at end of file