From 09fec7491586080463cc478c24d4b1993526cc68 Mon Sep 17 00:00:00 2001 From: Evilham Date: Wed, 23 Nov 2022 20:10:13 +0100 Subject: [PATCH] [WAF] Consolidate proxies and documentation The environment / dd.conf variables: PROXY_PROTOCOL and DISABLE_WAF determine how DD and HAProxy will behave. - PROXY_PROTOCOL: whether or not the PROXY protocol will be accepted - DISABLE_WAF: whether or not WAF will be enabled This simplifies maintenance, as well as the overall architecture and operation. While at it, we now publish images for DD's HAProxy as well. --- dd-ctl | 40 ++- ...aproxy-behind.yml => haproxy.no-ports.yml} | 1 + dd-sso/docker-compose-parts/haproxy.proxy.yml | 54 ++++ dd-sso/docker-compose-parts/haproxy.yml | 6 +- .../waf-modsecurity.disabled.yml | 2 + .../docker-compose-parts/waf-modsecurity.yml | 2 +- dd-sso/docker/haproxy/Dockerfile | 12 +- dd-sso/docker/haproxy/docker-entrypoint.sh | 2 +- dd-sso/docker/haproxy/gen-haproxy-conf.sh | 73 ++++++ .../haproxy/haproxy.cnf.parts/backends.cnf | 95 +------ .../haproxy/haproxy.cnf.parts/bind-direct.cnf | 16 ++ .../haproxy/haproxy.cnf.parts/bind-proxy.cnf | 8 + .../haproxy.cnf.parts/defaults-non-waf.cnf | 21 ++ .../haproxy.cnf.parts/defaults-waf.cnf | 27 ++ .../haproxy/haproxy.cnf.parts/head-waf.cnf | 7 + .../docker/haproxy/haproxy.cnf.parts/head.cnf | 22 +- .../haproxy.cnf.parts/tail-non-waf.cnf | 7 + .../haproxy/haproxy.cnf.parts/tail-waf.cnf | 28 +++ .../haproxy/haproxy.cnf.parts/web-head.cnf | 31 +++ .../haproxy/haproxy.cnf.parts/web-tail.cnf | 21 ++ dd-sso/docker/haproxy/haproxy.conf | 236 ------------------ .../haproxy/haproxy.proxy-protocol.conf | 182 -------------- .../docker/waf-modsecurity}/000-default.conf | 4 +- .../docker/waf-modsecurity}/Dockerfile | 0 .../docker/waf-modsecurity}/crs-setup.conf | 0 .../waf-modsecurity}/docker-entrypoint.sh | 2 +- .../docker/waf-modsecurity}/modsec_rules.conf | 0 .../waf-modsecurity}/rules/dd_rules.conf | 0 .../docker/waf-modsecurity}/rules_apps.conf | 0 dd-waf/README.md | 77 ------ dd-waf/docker-compose-parts/haproxy.yml | 34 --- dd-waf/docker/haproxy/Dockerfile | 35 --- dd-waf/docker/haproxy/auto-generate-certs.sh | 50 ---- dd-waf/docker/haproxy/docker-entrypoint.sh | 43 ---- dd-waf/docker/haproxy/haproxy.cfg | 86 ------- .../docker/haproxy/letsencrypt-renew-cron.sh | 21 -- dd-waf/docker/haproxy/letsencrypt.sh | 50 ---- dd.conf.sample | 8 +- docs/post-install.ca.md | 4 + docs/waf-modsecurity.es.md | 49 ++++ 40 files changed, 418 insertions(+), 938 deletions(-) rename dd-sso/docker-compose-parts/{haproxy-behind.yml => haproxy.no-ports.yml} (95%) create mode 100644 dd-sso/docker-compose-parts/haproxy.proxy.yml create mode 100644 dd-sso/docker-compose-parts/waf-modsecurity.disabled.yml rename dd-waf/docker-compose-parts/modsecurity.yml => dd-sso/docker-compose-parts/waf-modsecurity.yml (85%) create mode 100644 dd-sso/docker/haproxy/gen-haproxy-conf.sh rename dd-waf/docker/haproxy/haproxy.proxy-protocol.conf => dd-sso/docker/haproxy/haproxy.cnf.parts/backends.cnf (58%) create mode 100644 dd-sso/docker/haproxy/haproxy.cnf.parts/bind-direct.cnf create mode 100644 dd-sso/docker/haproxy/haproxy.cnf.parts/bind-proxy.cnf create mode 100644 dd-sso/docker/haproxy/haproxy.cnf.parts/defaults-non-waf.cnf create mode 100644 dd-sso/docker/haproxy/haproxy.cnf.parts/defaults-waf.cnf create mode 100644 dd-sso/docker/haproxy/haproxy.cnf.parts/head-waf.cnf rename dd-waf/docker/haproxy/letsencrypt-hook-deploy-concatenante.sh => dd-sso/docker/haproxy/haproxy.cnf.parts/head.cnf (64%) mode change 100755 => 100644 create mode 100644 dd-sso/docker/haproxy/haproxy.cnf.parts/tail-non-waf.cnf create mode 100644 dd-sso/docker/haproxy/haproxy.cnf.parts/tail-waf.cnf create mode 100644 dd-sso/docker/haproxy/haproxy.cnf.parts/web-head.cnf create mode 100644 dd-sso/docker/haproxy/haproxy.cnf.parts/web-tail.cnf delete mode 100644 dd-sso/docker/haproxy/haproxy.conf delete mode 100644 dd-sso/docker/haproxy/haproxy.proxy-protocol.conf rename {dd-waf/docker/modsecurity => dd-sso/docker/waf-modsecurity}/000-default.conf (78%) rename {dd-waf/docker/modsecurity => dd-sso/docker/waf-modsecurity}/Dockerfile (100%) rename {dd-waf/docker/modsecurity => dd-sso/docker/waf-modsecurity}/crs-setup.conf (100%) rename {dd-waf/docker/modsecurity => dd-sso/docker/waf-modsecurity}/docker-entrypoint.sh (84%) rename {dd-waf/docker/modsecurity => dd-sso/docker/waf-modsecurity}/modsec_rules.conf (100%) rename {dd-waf/docker/modsecurity => dd-sso/docker/waf-modsecurity}/rules/dd_rules.conf (100%) rename {dd-waf/docker/modsecurity => dd-sso/docker/waf-modsecurity}/rules_apps.conf (100%) delete mode 100644 dd-waf/README.md delete mode 100644 dd-waf/docker-compose-parts/haproxy.yml delete mode 100644 dd-waf/docker/haproxy/Dockerfile delete mode 100755 dd-waf/docker/haproxy/auto-generate-certs.sh delete mode 100644 dd-waf/docker/haproxy/docker-entrypoint.sh delete mode 100644 dd-waf/docker/haproxy/haproxy.cfg delete mode 100755 dd-waf/docker/haproxy/letsencrypt-renew-cron.sh delete mode 100755 dd-waf/docker/haproxy/letsencrypt.sh create mode 100644 docs/waf-modsecurity.es.md diff --git a/dd-ctl b/dd-ctl index 3907528..67673b0 100755 --- a/dd-ctl +++ b/dd-ctl @@ -182,7 +182,31 @@ build_compose(){ setconf CUSTOM_PATH "$CUSTOM_PATH" .env setconf BUILD_APPS_ROOT_PATH "$CUSTOM_PATH/dd-apps" .env setconf BUILD_SSO_ROOT_PATH "$CUSTOM_PATH/dd-sso" .env - setconf BUILD_WAF_ROOT_PATH "$CUSTOM_PATH/dd-waf" .env + + # Choose HAProxy configuration flavour + if [ "${PROXY_PROTOCOL:-false}" = "true" ]; then + HAPROXY_YML="haproxy.proxy.yml" + HAPROXY_PROXY="proxy" + else + # Default + HAPROXY_YML="haproxy.yml" + HAPROXY_PROXY="no-proxy" + fi + # Enable or disable WAF + if [ "${DISABLE_WAF:-true}" = "true" ]; then + # Current default (might change) + WAF_YML="waf-modsecurity.disabled.yml" + HAPROXY_WAF="no-waf" + else + WAF_YML="waf-modsecurity.yml" + HAPROXY_WAF="waf" + fi + + # Persist resulting HAProxy config + export HAPROXY_CFG="haproxy.${HAPROXY_WAF}.${HAPROXY_PROXY}.cfg" + setconf HAPROXY_CFG "${HAPROXY_CFG}" + setconf HAPROXY_CFG "${HAPROXY_CFG}" .env + ## Prepare apps environment ln -sf "${CUSTOM_PATH}/.env" dd-apps/.env ln -sf "${CUSTOM_PATH}/.env" dd-apps/docker/postgresql && \ @@ -204,20 +228,10 @@ build_compose(){ rm -rf custom/system/keycloak-themes rmdir custom/system 2>/dev/null || true - if [ "$BEHIND_PROXY" = "true" ]; then - BEHIND="haproxy-behind.yml" - MODSECURITY="-f dd-waf/docker-compose-parts/modsecurity.yml" - HAPROXY_WAF="-f dd-waf/docker-compose-parts/haproxy.yml" - else - BEHIND="haproxy.yml" - fi - # Build compose ymls - # shellcheck disable=SC2086 docker-compose \ - $MODSECURITY $HAPROXY_WAF \ - \ - -f dd-sso/docker-compose-parts/$BEHIND \ + -f "dd-sso/docker-compose-parts/$WAF_YML" \ + -f "dd-sso/docker-compose-parts/$HAPROXY_YML"\ -f dd-sso/docker-compose-parts/api.yml \ -f dd-sso/docker-compose-parts/keycloak.yml \ -f dd-sso/docker-compose-parts/avatars.yml \ diff --git a/dd-sso/docker-compose-parts/haproxy-behind.yml b/dd-sso/docker-compose-parts/haproxy.no-ports.yml similarity index 95% rename from dd-sso/docker-compose-parts/haproxy-behind.yml rename to dd-sso/docker-compose-parts/haproxy.no-ports.yml index 42db73d..2ef11c9 100644 --- a/dd-sso/docker-compose-parts/haproxy-behind.yml +++ b/dd-sso/docker-compose-parts/haproxy.no-ports.yml @@ -20,6 +20,7 @@ version: '3.7' services: dd-sso-haproxy: + image: registry.dd-work.space/dd/haproxy:${DD_BUILD:-latest} build: args: HAPROXY_IMG: ${HAPROXY_IMG-haproxy:2.4.12-alpine3.15} diff --git a/dd-sso/docker-compose-parts/haproxy.proxy.yml b/dd-sso/docker-compose-parts/haproxy.proxy.yml new file mode 100644 index 0000000..d5830c5 --- /dev/null +++ b/dd-sso/docker-compose-parts/haproxy.proxy.yml @@ -0,0 +1,54 @@ +# +# Copyright © 2021,2022 IsardVDI S.L. +# +# This file is part of DD +# +# DD is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# DD is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License +# along with DD. If not, see . +# +# SPDX-License-Identifier: AGPL-3.0-or-later +version: '3.7' +services: + dd-sso-haproxy: + image: registry.dd-work.space/dd/haproxy:${DD_BUILD:-latest} + build: + args: + HAPROXY_IMG: ${HAPROXY_IMG-haproxy:2.4.12-alpine3.15} + context: ${BUILD_SSO_ROOT_PATH}/docker/haproxy + dockerfile: Dockerfile + target: production + container_name: dd-sso-haproxy + restart: unless-stopped + volumes: + - /etc/localtime:/etc/localtime:ro + - ${SRC_FOLDER}/haproxy/letsencrypt:/etc/letsencrypt:rw + - ${SRC_FOLDER}/haproxy/certs:/certs:rw + networks: + - dd_net + ports: + - published: 80 + target: 80 + - published: 443 + target: 443 + # These are for cases when operators want to use PROXY protocol in front + - published: 8888 + target: 8888 + - published: 591 + target: 591 + env_file: + - .env + logging: + driver: "json-file" + options: + max-size: "5m" + max-file: "10" diff --git a/dd-sso/docker-compose-parts/haproxy.yml b/dd-sso/docker-compose-parts/haproxy.yml index 24452b5..c373259 100644 --- a/dd-sso/docker-compose-parts/haproxy.yml +++ b/dd-sso/docker-compose-parts/haproxy.yml @@ -20,6 +20,7 @@ version: '3.7' services: dd-sso-haproxy: + image: registry.dd-work.space/dd/haproxy:${DD_BUILD:-latest} build: args: HAPROXY_IMG: ${HAPROXY_IMG-haproxy:2.4.12-alpine3.15} @@ -39,11 +40,6 @@ services: target: 80 - published: 443 target: 443 - # These are for cases when operators want to use PROXY protocol in front - - published: 8888 - target: 8888 - - published: 591 - target: 591 env_file: - .env logging: diff --git a/dd-sso/docker-compose-parts/waf-modsecurity.disabled.yml b/dd-sso/docker-compose-parts/waf-modsecurity.disabled.yml new file mode 100644 index 0000000..8605503 --- /dev/null +++ b/dd-sso/docker-compose-parts/waf-modsecurity.disabled.yml @@ -0,0 +1,2 @@ +# Dummy file for a disabled WAF +version: '3.7' diff --git a/dd-waf/docker-compose-parts/modsecurity.yml b/dd-sso/docker-compose-parts/waf-modsecurity.yml similarity index 85% rename from dd-waf/docker-compose-parts/modsecurity.yml rename to dd-sso/docker-compose-parts/waf-modsecurity.yml index aac51d7..1817fb8 100644 --- a/dd-waf/docker-compose-parts/modsecurity.yml +++ b/dd-sso/docker-compose-parts/waf-modsecurity.yml @@ -3,7 +3,7 @@ services: dd-waf-apache: image: registry.dd-work.space/dd/waf-apache:${DD_BUILD:-latest} build: - context: ${BUILD_WAF_ROOT_PATH}/docker/modsecurity + context: ${BUILD_SSO_ROOT_PATH}/docker/waf-modsecurity dockerfile: Dockerfile target: production container_name: dd-waf-apache diff --git a/dd-sso/docker/haproxy/Dockerfile b/dd-sso/docker/haproxy/Dockerfile index e8fdf86..35401f0 100644 --- a/dd-sso/docker/haproxy/Dockerfile +++ b/dd-sso/docker/haproxy/Dockerfile @@ -31,7 +31,13 @@ COPY auto-generate-certs.sh /usr/local/sbin/ COPY docker-entrypoint.sh /usr/local/bin/ RUN ln -s /usr/local/bin/docker-entrypoint.sh / -RUN chmod 775 docker-entrypoint.sh +RUN chmod 555 docker-entrypoint.sh -ADD haproxy.conf /usr/local/etc/haproxy/haproxy.normal.cfg -ADD haproxy.proxy-protocol.conf /usr/local/etc/haproxy/haproxy.proxy-protocol.cfg +COPY haproxy.cnf.parts /haproxy.cnf.parts +ADD gen-haproxy-conf.sh /gen-haproxy-conf.sh +RUN chmod 555 gen-haproxy-conf.sh +# Generate all flavours of configuration +RUN /gen-haproxy-conf.sh waf no-proxy > /usr/local/etc/haproxy/haproxy.waf.no-proxy.cfg +RUN /gen-haproxy-conf.sh waf proxy > /usr/local/etc/haproxy/haproxy.waf.proxy.cfg +RUN /gen-haproxy-conf.sh no-waf no-proxy > /usr/local/etc/haproxy/haproxy.no-waf.no-proxy.cfg +RUN /gen-haproxy-conf.sh no-waf proxy > /usr/local/etc/haproxy/haproxy.no-waf.proxy.cfg diff --git a/dd-sso/docker/haproxy/docker-entrypoint.sh b/dd-sso/docker/haproxy/docker-entrypoint.sh index ade9bce..837ad6c 100644 --- a/dd-sso/docker/haproxy/docker-entrypoint.sh +++ b/dd-sso/docker/haproxy/docker-entrypoint.sh @@ -21,7 +21,7 @@ # SPDX-License-Identifier: AGPL-3.0-or-later set -e -ln -sf /usr/local/etc/haproxy/${HAPROXY_CFG:-haproxy.normal.cfg} /usr/local/etc/haproxy/haproxy.cfg +ln -sf /usr/local/etc/haproxy/${HAPROXY_CFG:-haproxy.no-waf.no-proxy.cfg} /usr/local/etc/haproxy/haproxy.cfg LETSENCRYPT_DOMAIN="$DOMAIN" letsencrypt.sh diff --git a/dd-sso/docker/haproxy/gen-haproxy-conf.sh b/dd-sso/docker/haproxy/gen-haproxy-conf.sh new file mode 100644 index 0000000..df3317c --- /dev/null +++ b/dd-sso/docker/haproxy/gen-haproxy-conf.sh @@ -0,0 +1,73 @@ +#!/bin/sh -eu + +_help(){ + cat <> /dev/stderr + exit 1 + ;; +esac + +case "${2:-}" in + [pP][rR][oO][xX][yY]) + USE_PROXY="YES" + ;; + [nN][oO]-[pP][rR][oO][xX][yY]) + ;; + *) + _help >> /dev/stderr + exit 1 + ;; +esac + +PARTS_DIR="haproxy.cnf.parts" + +_binds(){ + cat "${PARTS_DIR}/bind-direct.cnf" + if [ -n "${USE_PROXY:-}" ]; then + cat "${PARTS_DIR}/bind-proxy.cnf" + fi +} + +# Beginning +cat "${PARTS_DIR}/head.cnf" + +if [ -n "${USE_WAF:-}" ]; then + # WAF bits + cat "${PARTS_DIR}/defaults-waf.cnf" + cat "${PARTS_DIR}/head-waf.cnf" + _binds + cat "${PARTS_DIR}/tail-waf.cnf" + cat "${PARTS_DIR}/web-head.cnf" +else + # Non-WAF bits + cat "${PARTS_DIR}/defaults-non-waf.cnf" + cat "${PARTS_DIR}/tail-non-waf.cnf" + cat "${PARTS_DIR}/web-head.cnf" + _binds +fi + +# bk_web ending +cat "${PARTS_DIR}/web-tail.cnf" + +# Application backends +cat "${PARTS_DIR}/backends.cnf" diff --git a/dd-waf/docker/haproxy/haproxy.proxy-protocol.conf b/dd-sso/docker/haproxy/haproxy.cnf.parts/backends.cnf similarity index 58% rename from dd-waf/docker/haproxy/haproxy.proxy-protocol.conf rename to dd-sso/docker/haproxy/haproxy.cnf.parts/backends.cnf index e433219..8467433 100644 --- a/dd-waf/docker/haproxy/haproxy.proxy-protocol.conf +++ b/dd-sso/docker/haproxy/haproxy.cnf.parts/backends.cnf @@ -1,96 +1,6 @@ # -# Copyright © 2021,2022 IsardVDI S.L. -# Copyright © 2022 Evilham +# BEGIN: backends.cnf # -# This file is part of DD -# -# DD is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# DD is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more -# details. -# -# You should have received a copy of the GNU Affero General Public License -# along with DD. If not, see . -# -# SPDX-License-Identifier: AGPL-3.0-or-later -resolvers mydns - nameserver dns1 127.0.0.11:53 - -global -# debug - daemon - log 127.0.0.1 local0 - tune.ssl.default-dh-param 2048 - h1-case-adjust content-type Content-Type - h1-case-adjust content-encoding Content-Encoding - h1-case-adjust transfer-encoding Transfer-Encoding - - defaults - mode http - timeout connect 120s - timeout client 120s - timeout client-fin 120s - timeout server 120s - timeout tunnel 7200s - option http-server-close - option httpclose - log global - option httplog - backlog 4096 - maxconn 2000 - option tcpka - option h1-case-adjust-bogus-client - -frontend website - mode http - bind :80 - bind :8888 accept-proxy - redirect scheme https if !{ env(BEHIND_PROXY) -m str true } !{ ssl_fc } - http-request del-header ssl_client_cert unless { ssl_fc_has_crt } - http-request set-header ssl_client_cert -----BEGIN\ CERTIFICATE-----\ %[ssl_c_der,base64]\ -----END\ CERTIFICATE-----\ if { ssl_fc_has_crt } - bind :443 ssl crt /certs/chain.pem - bind :591 accept-proxy ssl crt /certs/chain.pem - - acl is_upgrade hdr(Connection) -i upgrade - acl is_websocket hdr(Upgrade) -i websocket - - acl is_nextcloud hdr_beg(host) nextcloud. - acl is_moodle hdr_beg(host) moodle. !path_beg -i /local/tresipuntimportgc/ - acl is_moodle_long hdr_beg(host) moodle. path_beg -i /local/tresipuntimportgc/ - acl is_oof hdr_beg(host) oof. - acl is_wp hdr_sub(host) .wp. - acl is_wp hdr_beg(host) wp. - acl is_pad hdr_beg(host) pad. - acl is_sso hdr_beg(host) sso. - acl is_api hdr_beg(host) api. - acl is_admin hdr_beg(host) admin. - - acl is_root path -i / - http-request deny if is_pad is_root - - use_backend be_api if { path_end -i favicon.ico } or { path_end -i favicon } or { path_beg -i /apps/theming/favicon/ } - - use_backend letsencrypt if { path_beg /.well-known/acme-challenge/ } - use_backend be_api if is_nextcloud { path_beg /avatar/ } - use_backend be_nextcloud if is_nextcloud - use_backend be_moodle_long if is_moodle_long - use_backend be_moodle if is_moodle - use_backend be_oof if is_oof - use_backend be_wp if is_wp - use_backend be_etherpad if is_pad - use_backend be_admin if is_sso { path_beg /socket.io } - use_backend be_admin if is_admin - use_backend be_sso if is_sso - use_backend be_api if is_api - - http-request redirect code 301 location https://moodle."${DOMAIN}" if { hdr(host) -i "${DOMAIN}" } -# default_backend be_sso - backend letsencrypt server letsencrypt 127.0.0.1:8080 @@ -180,3 +90,6 @@ backend be_wp http-request set-header X-SSL %[ssl_fc] http-request set-header X-Forwarded-Proto https server wp dd-apps-wordpress:80 check port 80 inter 5s rise 2 fall 10 resolvers mydns init-addr none +# +# END: backends.cnf +# diff --git a/dd-sso/docker/haproxy/haproxy.cnf.parts/bind-direct.cnf b/dd-sso/docker/haproxy/haproxy.cnf.parts/bind-direct.cnf new file mode 100644 index 0000000..d9b3a5d --- /dev/null +++ b/dd-sso/docker/haproxy/haproxy.cnf.parts/bind-direct.cnf @@ -0,0 +1,16 @@ +# +# BEGIN: bind-direct.cnf +# + bind :80 + http-request redirect scheme https code 301 unless { ssl_fc } + http-request del-header ssl_client_cert unless { ssl_fc_has_crt } + http-request set-header ssl_client_cert -----BEGIN\ CERTIFICATE-----\ %[ssl_c_der,base64]\ -----END\ CERTIFICATE-----\ if { ssl_fc_has_crt } + bind :443 ssl crt /certs/chain.pem + + + # New line to test URI to see if its a letsencrypt request + acl letsencrypt-acl path_beg /.well-known/acme-challenge/ + use_backend letsencrypt if letsencrypt-acl +# +# END: bind-direct.cnf +# diff --git a/dd-sso/docker/haproxy/haproxy.cnf.parts/bind-proxy.cnf b/dd-sso/docker/haproxy/haproxy.cnf.parts/bind-proxy.cnf new file mode 100644 index 0000000..b967367 --- /dev/null +++ b/dd-sso/docker/haproxy/haproxy.cnf.parts/bind-proxy.cnf @@ -0,0 +1,8 @@ +# +# BEGIN: bind-proxy.cnf +# + bind :8888 accept-proxy + bind :591 accept-proxy ssl crt /certs/chain.pem +# +# END: bind-proxy.cnf +# diff --git a/dd-sso/docker/haproxy/haproxy.cnf.parts/defaults-non-waf.cnf b/dd-sso/docker/haproxy/haproxy.cnf.parts/defaults-non-waf.cnf new file mode 100644 index 0000000..650ecd1 --- /dev/null +++ b/dd-sso/docker/haproxy/haproxy.cnf.parts/defaults-non-waf.cnf @@ -0,0 +1,21 @@ +# +# BEGIN: defaults-non-waf.cnf +# +defaults + mode http + timeout connect 120s + timeout client 120s + timeout client-fin 120s + timeout server 120s + timeout tunnel 7200s + option http-server-close + option httpclose + log global + option httplog + backlog 4096 + maxconn 2000 + option tcpka + option h1-case-adjust-bogus-client +# +# END: defaults-non-waf.cnf +# diff --git a/dd-sso/docker/haproxy/haproxy.cnf.parts/defaults-waf.cnf b/dd-sso/docker/haproxy/haproxy.cnf.parts/defaults-waf.cnf new file mode 100644 index 0000000..be87e38 --- /dev/null +++ b/dd-sso/docker/haproxy/haproxy.cnf.parts/defaults-waf.cnf @@ -0,0 +1,27 @@ +# +# BEGIN: defaults-waf.cnf +# +defaults + mode http + option http-server-close + option dontlognull + option redispatch + # Since ulimit -n (-H) is patched in container + # HAProxy is supposed to adjust this value accordingly + # maxconn 2000 + option tcpka # For the backends + option h1-case-adjust-bogus-client + timeout connect 5s # non-waf has 120s + # Slowloris protection + timeout http-request 15s + # By setting timeout http-request these values are shadowed? + # timeout client 120s + # timeout client-fin 120s + # timeout server 120s + # timeout tunnel 2h + timeout queue 30s + timeout tarpit 1m # tarpit hold time + backlog 8192 # Less or equal power of 2 is used +# +# END: defaults-waf.cnf +# diff --git a/dd-sso/docker/haproxy/haproxy.cnf.parts/head-waf.cnf b/dd-sso/docker/haproxy/haproxy.cnf.parts/head-waf.cnf new file mode 100644 index 0000000..b4b90ff --- /dev/null +++ b/dd-sso/docker/haproxy/haproxy.cnf.parts/head-waf.cnf @@ -0,0 +1,7 @@ +# +# BEGIN: waf-head.cnf +# +frontend tf_waf +# +# END: waf-head.cnf +# diff --git a/dd-waf/docker/haproxy/letsencrypt-hook-deploy-concatenante.sh b/dd-sso/docker/haproxy/haproxy.cnf.parts/head.cnf old mode 100755 new mode 100644 similarity index 64% rename from dd-waf/docker/haproxy/letsencrypt-hook-deploy-concatenante.sh rename to dd-sso/docker/haproxy/haproxy.cnf.parts/head.cnf index 3b3fc34..a6ffe0a --- a/dd-waf/docker/haproxy/letsencrypt-hook-deploy-concatenante.sh +++ b/dd-sso/docker/haproxy/haproxy.cnf.parts/head.cnf @@ -1,6 +1,7 @@ -#!/bin/sh # # Copyright © 2021,2022 IsardVDI S.L. +# Copyright © 2022 Evilham +# Copyright © 2022 Teradisk # # This file is part of DD # @@ -18,6 +19,21 @@ # along with DD. If not, see . # # SPDX-License-Identifier: AGPL-3.0-or-later -cat $RENEWED_LINEAGE/fullchain.pem $RENEWED_LINEAGE/privkey.pem > /certs/chain.pem -kill -SIGUSR2 1 +# +# BEGIN: head.cnf +# +resolvers mydns + nameserver dns1 127.0.0.11:53 + +global + daemon + log 127.0.0.1 local0 + tune.ssl.default-dh-param 2048 + h1-case-adjust content-type Content-Type + h1-case-adjust content-encoding Content-Encoding + h1-case-adjust transfer-encoding Transfer-Encoding + +# +# END: head.cnf +# diff --git a/dd-sso/docker/haproxy/haproxy.cnf.parts/tail-non-waf.cnf b/dd-sso/docker/haproxy/haproxy.cnf.parts/tail-non-waf.cnf new file mode 100644 index 0000000..abfe778 --- /dev/null +++ b/dd-sso/docker/haproxy/haproxy.cnf.parts/tail-non-waf.cnf @@ -0,0 +1,7 @@ +# +# BEGIN: tail-non-waf.cnf +# +frontend ft_web +# +# END: tail-non-waf.cnf +# diff --git a/dd-sso/docker/haproxy/haproxy.cnf.parts/tail-waf.cnf b/dd-sso/docker/haproxy/haproxy.cnf.parts/tail-waf.cnf new file mode 100644 index 0000000..76e7691 --- /dev/null +++ b/dd-sso/docker/haproxy/haproxy.cnf.parts/tail-waf.cnf @@ -0,0 +1,28 @@ +# +# BEGIN: waf-tail.cnf +# + # Internal traffic + use_backend bk_web if { src 172.16.0.0/12 } + + default_backend bk_waf + +# WAF farm where users' traffic is routed first +backend bk_waf + mode http + server modsecurity dd-waf-apache:80 check port 80 inter 5s rise 2 fall 10 resolvers mydns init-addr none + +# Internal traffic passes through this backend +backend bk_web + mode http + server bk_web dd-sso-haproxy:81 resolvers mydns init-addr 127.0.0.1 + +# Traffic secured by the WAF arrives here +frontend ft_web + bind :81 name http + log global + option httplog + timeout client 25s + maxconn 1000 +# +# END: waf-tail.cnf +# diff --git a/dd-sso/docker/haproxy/haproxy.cnf.parts/web-head.cnf b/dd-sso/docker/haproxy/haproxy.cnf.parts/web-head.cnf new file mode 100644 index 0000000..5ce45b0 --- /dev/null +++ b/dd-sso/docker/haproxy/haproxy.cnf.parts/web-head.cnf @@ -0,0 +1,31 @@ +# +# BEGIN: web-head.cnf +# + mode http + + # http-request directives must happen here + + http-request del-header ssl_client_cert unless { ssl_fc_has_crt } + http-request set-header ssl_client_cert -----BEGIN\ CERTIFICATE-----\ %[ssl_c_der,base64]\ -----END\ CERTIFICATE-----\ if { ssl_fc_has_crt } + acl is_upgrade hdr(Connection) -i upgrade + acl is_websocket hdr(Upgrade) -i websocket + + acl is_nextcloud hdr_beg(host) nextcloud. + acl is_moodle hdr_beg(host) moodle. !path_beg -i /local/tresipuntimportgc/ + acl is_moodle_long hdr_beg(host) moodle. path_beg -i /local/tresipuntimportgc/ + acl is_oof hdr_beg(host) oof. + acl is_wp hdr_sub(host) .wp. + acl is_wp hdr_beg(host) wp. + acl is_pad hdr_beg(host) pad. + acl is_sso hdr_beg(host) sso. + acl is_api hdr_beg(host) api. + acl is_admin hdr_beg(host) admin. + + acl is_root path -i / + http-request deny if is_pad is_root + + http-request redirect code 301 location https://moodle."${DOMAIN}" if { hdr(host) -i "${DOMAIN}" } + +# +# END: web-head.cnf +# diff --git a/dd-sso/docker/haproxy/haproxy.cnf.parts/web-tail.cnf b/dd-sso/docker/haproxy/haproxy.cnf.parts/web-tail.cnf new file mode 100644 index 0000000..c5a85c1 --- /dev/null +++ b/dd-sso/docker/haproxy/haproxy.cnf.parts/web-tail.cnf @@ -0,0 +1,21 @@ +# +# BEGIN: web-tail.cnf +# + use_backend be_api if { path_end -i favicon.ico } or { path_end -i favicon } or { path_beg -i /apps/theming/favicon/ } + + use_backend be_api if is_nextcloud { path_beg /avatar/ } + use_backend be_nextcloud if is_nextcloud + use_backend be_moodle_long if is_moodle_long + use_backend be_moodle if is_moodle + use_backend be_oof if is_oof + use_backend be_wp if is_wp + use_backend be_etherpad if is_pad + use_backend be_admin if is_sso { path_beg /socket.io } + use_backend be_admin if is_admin + use_backend be_sso if is_sso + use_backend be_api if is_api + +# default_backend be_sso +# +# END: web-tail.cnf +# diff --git a/dd-sso/docker/haproxy/haproxy.conf b/dd-sso/docker/haproxy/haproxy.conf deleted file mode 100644 index 4f11c19..0000000 --- a/dd-sso/docker/haproxy/haproxy.conf +++ /dev/null @@ -1,236 +0,0 @@ -# -# Copyright © 2021,2022 IsardVDI S.L. -# -# This file is part of DD -# -# DD is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# DD is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more -# details. -# -# You should have received a copy of the GNU Affero General Public License -# along with DD. If not, see . -# -# SPDX-License-Identifier: AGPL-3.0-or-later -resolvers mydns - nameserver dns1 127.0.0.11:53 - -global -# debug - daemon - log 127.0.0.1 local0 - tune.ssl.default-dh-param 2048 - h1-case-adjust content-type Content-Type - h1-case-adjust content-encoding Content-Encoding - h1-case-adjust transfer-encoding Transfer-Encoding - - defaults - mode http - timeout connect 120s - timeout client 120s - timeout client-fin 120s - timeout server 120s - timeout tunnel 7200s - option http-server-close - option httpclose - log global - option httplog - backlog 4096 - maxconn 2000 - option tcpka - option h1-case-adjust-bogus-client - -frontend website - mode http - bind :80 - redirect scheme https if !{ env(BEHIND_PROXY) -m str true } !{ ssl_fc } - http-request del-header ssl_client_cert unless { ssl_fc_has_crt } - http-request set-header ssl_client_cert -----BEGIN\ CERTIFICATE-----\ %[ssl_c_der,base64]\ -----END\ CERTIFICATE-----\ if { ssl_fc_has_crt } - bind :443 ssl crt /certs/chain.pem - - acl is_upgrade hdr(Connection) -i upgrade - acl is_websocket hdr(Upgrade) -i websocket - - acl is_nextcloud hdr_beg(host) nextcloud. - acl is_moodle hdr_beg(host) moodle. !path_beg -i /local/tresipuntimportgc/ - acl is_moodle_long hdr_beg(host) moodle. path_beg -i /local/tresipuntimportgc/ - acl is_jitsi hdr_beg(host) jitsi. - acl is_oof hdr_beg(host) oof. - acl is_wp hdr_sub(host) .wp. - acl is_wp hdr_beg(host) wp. - acl is_pad hdr_beg(host) pad. - acl is_sso hdr_beg(host) sso. - acl is_ipa hdr_beg(host) ipa. - acl is_api hdr_beg(host) api. - acl is_admin hdr_beg(host) admin. - - acl is_root path -i / - http-request deny if is_pad is_root - - use_backend be_api if { path_end -i favicon.ico } or { path_end -i favicon } or { path_beg -i /apps/theming/favicon/ } - - use_backend letsencrypt if { path_beg /.well-known/acme-challenge/ } - use_backend be_api if is_nextcloud { path_beg /avatar/ } - use_backend be_nextcloud if is_nextcloud - use_backend be_moodle_long if is_moodle_long - use_backend be_moodle if is_moodle - use_backend be_jitsi if is_jitsi - use_backend be_oof if is_oof - use_backend be_wp if is_wp - use_backend be_etherpad if is_pad - use_backend be_admin if is_sso { path_beg /socket.io } - use_backend be_adminer if is_sso { path_beg /dd-sso-adminer } - use_backend be_admin if is_admin - use_backend be_sso if is_sso - use_backend be_ipa if is_ipa - use_backend be_api if is_api - - http-request redirect code 301 location https://moodle."${DOMAIN}" if { hdr(host) -i "${DOMAIN}" } -# default_backend be_sso - -backend letsencrypt - server letsencrypt 127.0.0.1:8080 - -backend be_api - mode http - http-request set-path /img/favicon.ico if { path_end -i favicon.ico } or { path_end -i favicon } or { path_beg -i /apps/theming/favicon/ } - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - # Nextcloud use /avatar/username/32 /avatar/username/64 and /avatar/username/128 - http-request set-path %[path,regsub(\"^(/avatar/[^/]+).*\",\"\1\")] - server api dd-sso-api:80 check port 80 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -backend be_ipa - mode http - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - server freeipa dd-sso-freeipa:443 check port 443 ssl verify none inter 5s rise 2 fall 10 resolvers mydns init-addr none - -backend be_sso - mode http - option httpclose - #option http-server-close - option forwardfor - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - http-response replace-header Set-Cookie (KEYCLOAK_LOCALE=[^;]*);(.*) \1;Domain="${DOMAIN}";Version=1;Path=/;Secure; - server keycloak dd-sso-keycloak:8080 check port 8080 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -backend be_admin - mode http - option forwardfor - timeout queue 600s - timeout server 600s - timeout connect 600s - # acl authorized http_auth(AuthUsers) - # http-request auth realm AuthUsers unless authorized - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - server dd-sso-admin dd-sso-admin:9000 check port 9000 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -backend be_adminer - mode http - # acl authorized http_auth(AuthUsers) - # http-request auth realm AuthUsers unless authorized - http-request redirect scheme http drop-query append-slash if { path -m str /dd-sso-adminer } - http-request replace-path /dd-sso-adminer/(.*) /\1 - # http-request del-header Authorization - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - server dd-sso-adminer dd-sso-adminer:8080 check port 8080 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -## APPS -backend be_moodle - mode http - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - server moodle dd-apps-moodle:8080 check port 8080 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -backend be_moodle_long - mode http - timeout server 900s - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - server moodle dd-apps-moodle:8080 check port 8080 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -backend be_nextcloud - mode http - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - server nextcloud dd-apps-nextcloud-nginx:80 check port 80 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -backend be_etherpad - mode http - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - server etherpad dd-apps-etherpad:9001 check port 9001 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -backend be_jitsi - mode http - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - server jitsi dd-apps-jitsi:80 check port 80 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -backend be_oof - mode http - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - server onlyoffice dd-apps-onlyoffice:80 check port 80 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -backend be_wp - mode http - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - - http-request set-header X-SSL %[ssl_fc] - http-request set-header X-Forwarded-Proto https - server wp dd-apps-wordpress:80 check port 80 inter 5s rise 2 fall 10 resolvers mydns init-addr none - - - listen stats - bind 0.0.0.0:8888 - mode http - stats enable - option httplog - stats show-legends - stats uri /haproxy - stats realm Haproxy\ Statistics - stats refresh 5s - #stats auth staging:mypassword - #acl authorized http_auth(AuthUsers) - #stats http-request auth unless authorized - timeout connect 5000ms - timeout client 50000ms - timeout server 50000ms - -userlist AuthUsers - user admin password $6$grgQMVfwI0XSGAQl$2usaQC9LVXXXYHtSkGUf74CIGsiH8fi/K.V6DuKSq0twPkmFGP2vL/b//Ulp2I4xBEZ3eYDhUbwBPK8jpmsbo. diff --git a/dd-sso/docker/haproxy/haproxy.proxy-protocol.conf b/dd-sso/docker/haproxy/haproxy.proxy-protocol.conf deleted file mode 100644 index e433219..0000000 --- a/dd-sso/docker/haproxy/haproxy.proxy-protocol.conf +++ /dev/null @@ -1,182 +0,0 @@ -# -# Copyright © 2021,2022 IsardVDI S.L. -# Copyright © 2022 Evilham -# -# This file is part of DD -# -# DD is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# DD is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more -# details. -# -# You should have received a copy of the GNU Affero General Public License -# along with DD. If not, see . -# -# SPDX-License-Identifier: AGPL-3.0-or-later -resolvers mydns - nameserver dns1 127.0.0.11:53 - -global -# debug - daemon - log 127.0.0.1 local0 - tune.ssl.default-dh-param 2048 - h1-case-adjust content-type Content-Type - h1-case-adjust content-encoding Content-Encoding - h1-case-adjust transfer-encoding Transfer-Encoding - - defaults - mode http - timeout connect 120s - timeout client 120s - timeout client-fin 120s - timeout server 120s - timeout tunnel 7200s - option http-server-close - option httpclose - log global - option httplog - backlog 4096 - maxconn 2000 - option tcpka - option h1-case-adjust-bogus-client - -frontend website - mode http - bind :80 - bind :8888 accept-proxy - redirect scheme https if !{ env(BEHIND_PROXY) -m str true } !{ ssl_fc } - http-request del-header ssl_client_cert unless { ssl_fc_has_crt } - http-request set-header ssl_client_cert -----BEGIN\ CERTIFICATE-----\ %[ssl_c_der,base64]\ -----END\ CERTIFICATE-----\ if { ssl_fc_has_crt } - bind :443 ssl crt /certs/chain.pem - bind :591 accept-proxy ssl crt /certs/chain.pem - - acl is_upgrade hdr(Connection) -i upgrade - acl is_websocket hdr(Upgrade) -i websocket - - acl is_nextcloud hdr_beg(host) nextcloud. - acl is_moodle hdr_beg(host) moodle. !path_beg -i /local/tresipuntimportgc/ - acl is_moodle_long hdr_beg(host) moodle. path_beg -i /local/tresipuntimportgc/ - acl is_oof hdr_beg(host) oof. - acl is_wp hdr_sub(host) .wp. - acl is_wp hdr_beg(host) wp. - acl is_pad hdr_beg(host) pad. - acl is_sso hdr_beg(host) sso. - acl is_api hdr_beg(host) api. - acl is_admin hdr_beg(host) admin. - - acl is_root path -i / - http-request deny if is_pad is_root - - use_backend be_api if { path_end -i favicon.ico } or { path_end -i favicon } or { path_beg -i /apps/theming/favicon/ } - - use_backend letsencrypt if { path_beg /.well-known/acme-challenge/ } - use_backend be_api if is_nextcloud { path_beg /avatar/ } - use_backend be_nextcloud if is_nextcloud - use_backend be_moodle_long if is_moodle_long - use_backend be_moodle if is_moodle - use_backend be_oof if is_oof - use_backend be_wp if is_wp - use_backend be_etherpad if is_pad - use_backend be_admin if is_sso { path_beg /socket.io } - use_backend be_admin if is_admin - use_backend be_sso if is_sso - use_backend be_api if is_api - - http-request redirect code 301 location https://moodle."${DOMAIN}" if { hdr(host) -i "${DOMAIN}" } -# default_backend be_sso - -backend letsencrypt - server letsencrypt 127.0.0.1:8080 - -backend be_api - mode http - http-request set-path /img/favicon.ico if { path_end -i favicon.ico } or { path_end -i favicon } or { path_beg -i /apps/theming/favicon/ } - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - # Nextcloud use /avatar/username/32 /avatar/username/64 and /avatar/username/128 - http-request set-path %[path,regsub(\"^(/avatar/[^/]+).*\",\"\1\")] - server api dd-sso-api:80 check port 80 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -backend be_sso - mode http - option httpclose - option forwardfor - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - http-response replace-header Set-Cookie (KEYCLOAK_LOCALE=[^;]*);(.*) \1;Domain="${DOMAIN}";Version=1;Path=/;Secure; - server keycloak dd-sso-keycloak:8080 check port 8080 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -backend be_admin - mode http - option forwardfor - timeout queue 600s - timeout server 600s - timeout connect 600s - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - server dd-sso-admin dd-sso-admin:9000 check port 9000 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -## APPS -backend be_moodle - mode http - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - server moodle dd-apps-moodle:8080 check port 8080 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -backend be_moodle_long - mode http - timeout server 900s - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - server moodle dd-apps-moodle:8080 check port 8080 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -backend be_nextcloud - mode http - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - server nextcloud dd-apps-nextcloud-nginx:80 check port 80 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -backend be_etherpad - mode http - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - server etherpad dd-apps-etherpad:9001 check port 9001 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -backend be_oof - mode http - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - server onlyoffice dd-apps-onlyoffice:80 check port 80 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -backend be_wp - mode http - acl existing-x-forwarded-host req.hdr(X-Forwarded-Host) -m found - acl existing-x-forwarded-proto req.hdr(X-Forwarded-Proto) -m found - http-request add-header X-Forwarded-Host %[req.hdr(Host)] unless existing-x-forwarded-host - http-request add-header X-Forwarded-Proto https unless existing-x-forwarded-proto - - http-request set-header X-SSL %[ssl_fc] - http-request set-header X-Forwarded-Proto https - server wp dd-apps-wordpress:80 check port 80 inter 5s rise 2 fall 10 resolvers mydns init-addr none diff --git a/dd-waf/docker/modsecurity/000-default.conf b/dd-sso/docker/waf-modsecurity/000-default.conf similarity index 78% rename from dd-waf/docker/modsecurity/000-default.conf rename to dd-sso/docker/waf-modsecurity/000-default.conf index 9b6cb8a..953f305 100644 --- a/dd-waf/docker/modsecurity/000-default.conf +++ b/dd-sso/docker/waf-modsecurity/000-default.conf @@ -9,6 +9,6 @@ ProxyPreserveHost On ProxyRequests off ProxyVia Off - ProxyPass "/" "http://dd-waf-haproxy:81/" - ProxyPassReverse "/" "http://dd-waf-haproxy:81/" + ProxyPass "/" "http://dd-sso-haproxy:81/" + ProxyPassReverse "/" "http://dd-sso-haproxy:81/" diff --git a/dd-waf/docker/modsecurity/Dockerfile b/dd-sso/docker/waf-modsecurity/Dockerfile similarity index 100% rename from dd-waf/docker/modsecurity/Dockerfile rename to dd-sso/docker/waf-modsecurity/Dockerfile diff --git a/dd-waf/docker/modsecurity/crs-setup.conf b/dd-sso/docker/waf-modsecurity/crs-setup.conf similarity index 100% rename from dd-waf/docker/modsecurity/crs-setup.conf rename to dd-sso/docker/waf-modsecurity/crs-setup.conf diff --git a/dd-waf/docker/modsecurity/docker-entrypoint.sh b/dd-sso/docker/waf-modsecurity/docker-entrypoint.sh similarity index 84% rename from dd-waf/docker/modsecurity/docker-entrypoint.sh rename to dd-sso/docker/waf-modsecurity/docker-entrypoint.sh index 3014e5b..5a47f2b 100644 --- a/dd-waf/docker/modsecurity/docker-entrypoint.sh +++ b/dd-sso/docker/waf-modsecurity/docker-entrypoint.sh @@ -1,7 +1,7 @@ #!/bin/bash -e set -e -if [ "$DISABLE_WAF" == "true" ]; then +if [ "${DISABLE_WAF:-true}" == "true" ]; then sed -i.orig -e "s/modsecurity On/modsecurity Off/" /etc/apache2/sites-available/000-default.conf else sed -i.orig -e "s/modsecurity Off/modsecurity On/" /etc/apache2/sites-available/000-default.conf diff --git a/dd-waf/docker/modsecurity/modsec_rules.conf b/dd-sso/docker/waf-modsecurity/modsec_rules.conf similarity index 100% rename from dd-waf/docker/modsecurity/modsec_rules.conf rename to dd-sso/docker/waf-modsecurity/modsec_rules.conf diff --git a/dd-waf/docker/modsecurity/rules/dd_rules.conf b/dd-sso/docker/waf-modsecurity/rules/dd_rules.conf similarity index 100% rename from dd-waf/docker/modsecurity/rules/dd_rules.conf rename to dd-sso/docker/waf-modsecurity/rules/dd_rules.conf diff --git a/dd-waf/docker/modsecurity/rules_apps.conf b/dd-sso/docker/waf-modsecurity/rules_apps.conf similarity index 100% rename from dd-waf/docker/modsecurity/rules_apps.conf rename to dd-sso/docker/waf-modsecurity/rules_apps.conf diff --git a/dd-waf/README.md b/dd-waf/README.md deleted file mode 100644 index cb4f6d0..0000000 --- a/dd-waf/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# DD - Apache2 ModSecurity + HAProxy - -Instalación de los servicios Apache2 ModSecurity y HAProxy. - -* En el servicio de Apache2 con ModSecurity V3 se incluyen las reglas OWASP -* En servicio HAProxy actua de frontend de la aplicación, gestiona y negocia el certificado del dominio a través de letsencrypt. -* En la instalación el ModSecurity se encuentra deshabilitado para no interferir en el proceso de setup inicial del DD. -* La instalación se puede realizar con o sin la parte WAF. -* Si tenemos instalado el WAF podemos tenerlo activo o en modo bypass - - -## HAProxy - -Podemos encontrar la configuración del servicio en [dd-waf/haproxy](dd-waf/harpoxy) - -La versión por defecto que se usara en HAProxy es `haproxy:2.4.12-alpine3.15` pero podemos definir usar otra versión -definiendo el valor de la variable `HAPROXY_IMG` en nuestro fichero dd.conf - -La configuración del servicio se encuentra en fichero haproxy.cfg. Todo el tráfico que pasa por el haproxy se enruta al Apache2-ModSecurity. - -El servicio de HAProxy se encarga de negociar y configurar el certicado del dominio de instalación - -La comunicación desde fuera del stack de la aplicación es cifrada pero internamente la comunción usa el protocolo http - - -## Apache - ModSecurity - -Podemos encontrar la configuración del servicio en [dd-waf/haproxy](dd-waf/harpoxy) - -Tenemos diferentes ficheros para configurar este servicio - -* En el fichero 000-default.conf tendremos la configuración del servidor web Apache2. -* En el fichero crs-setup.conf configuramos OWASP ModSecurity Core Rule Set ver.3.2.0 -* En el fichero modsec_rules.conf incluimos los ficheros necesarios del owasp servicio de Apache2 -* En el fichero rules_apps.conf se configuran los falsos positivos, de las diferentes aplicaciones, que se tienen idenficados hasta el momento. - - -## Instalación WAF - -Podemos hacer la intalación del proyecto con o sin servico waf. - -### Instalación - -Para la instalación del haproxy + modsecurity debemos definir a `true` la variable `BEHIND_PROXY` en el fichero `dd.conf` - -* Instalación del servicio WAF -``` -BEHIND_PROXY=true -``` - -* No se instala el servicio WAF -``` -BEHIND_PROXY=true -``` - - -### Enable/Disable - -Si tenemos instalado la parte del WAF en nuestro proyecto podemos tenerlo activo o desactivado. - -* HAProxy activado -``` -DISABLE_WAF=false -``` - -* HAProxy desactivado -``` -DISABLE_WAF=true -``` - -### Configuración - -Ahora tenemos que desplegar el modsecurity + haproxy ejecutando el comando `update` del `dd-ctl` - -``` -./dd-ctl update -``` diff --git a/dd-waf/docker-compose-parts/haproxy.yml b/dd-waf/docker-compose-parts/haproxy.yml deleted file mode 100644 index 309b958..0000000 --- a/dd-waf/docker-compose-parts/haproxy.yml +++ /dev/null @@ -1,34 +0,0 @@ -version: '3.7' -services: - dd-waf-haproxy: - build: - args: - HAPROXY_IMG: ${HAPROXY_IMG-haproxy:2.4.12-alpine3.15} - context: ${BUILD_WAF_ROOT_PATH}/docker/haproxy - dockerfile: Dockerfile - target: production - container_name: dd-waf-haproxy - restart: unless-stopped - volumes: - - /etc/localtime:/etc/localtime:ro - - ${SRC_FOLDER}/haproxy/letsencrypt:/etc/letsencrypt:rw - - ${SRC_FOLDER}/haproxy/certs:/certs:rw - networks: - - dd_net - ports: - - published: 80 - target: 80 - - published: 443 - target: 443 - # These are for cases when operators want to use PROXY protocol in front - - published: 8888 - target: 8888 - - published: 591 - target: 591 - env_file: - - .env - logging: - driver: "json-file" - options: - max-size: "5m" - max-file: "10" \ No newline at end of file diff --git a/dd-waf/docker/haproxy/Dockerfile b/dd-waf/docker/haproxy/Dockerfile deleted file mode 100644 index 04846d7..0000000 --- a/dd-waf/docker/haproxy/Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -# -# This file is part of DD -# -# DD is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# DD is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more -# details. -# -# You should have received a copy of the GNU Affero General Public License -# along with DD. If not, see . -# -# SPDX-License-Identifier: AGPL-3.0-or-later - -ARG HAPROXY_IMG -FROM $HAPROXY_IMG as production - -USER root -RUN apk add openssl certbot py-pip -RUN pip install certbot-plugin-gandi - -COPY letsencrypt-hook-deploy-concatenante.sh /usr/local/sbin/ -COPY letsencrypt.sh /usr/local/sbin/ -COPY letsencrypt-renew-cron.sh /etc/periodic/daily/letsencrypt-renew -COPY auto-generate-certs.sh /usr/local/sbin/ - -COPY docker-entrypoint.sh /usr/local/bin/ -RUN ln -s /usr/local/bin/docker-entrypoint.sh / -RUN chmod 775 docker-entrypoint.sh - -ADD haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg diff --git a/dd-waf/docker/haproxy/auto-generate-certs.sh b/dd-waf/docker/haproxy/auto-generate-certs.sh deleted file mode 100755 index 5d9a10a..0000000 --- a/dd-waf/docker/haproxy/auto-generate-certs.sh +++ /dev/null @@ -1,50 +0,0 @@ -# -# Copyright © 2021,2022 IsardVDI S.L. -# -# This file is part of DD -# -# DD is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# DD is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more -# details. -# -# You should have received a copy of the GNU Affero General Public License -# along with DD. If not, see . -# -# SPDX-License-Identifier: AGPL-3.0-or-later -cd /certs - -# Self signed cert generic data -C=CA -L=Barcelona -O=localdomain -CN_CA=$O -CN_HOST=*.$O -OU=$O - -echo '#### Creating 2048-bit RSA key:' -openssl genrsa -out ca-key.pem 2048 - -echo '#### Using the key to create a self-signed certificate to your CA:' -openssl req -new -x509 -days 9999 -key ca-key.pem -out ca-cert.pem -sha256 \ - -subj "/C=$C/L=$L/O=$O/CN=$CN_CA" - -echo '#### Creating server certificate:' -openssl genrsa -out server-key.pem 2048 - -echo '#### Creating a certificate signing request for the server:' -openssl req -new -key server-key.pem -sha256 -out server-key.csr \ - -subj "/CN=$CN_HOST" - -echo '#### Creating server certificate:' -RND=$(( ( RANDOM % 1000 ) + 1 )) -openssl x509 -req -days 9999 -in server-key.csr -CA ca-cert.pem -CAkey ca-key.pem \ - -set_serial $RND -sha256 -out server-cert.pem - -echo '#### Concatenate certs for haprox' -cat server-cert.pem server-key.pem > chain.pem diff --git a/dd-waf/docker/haproxy/docker-entrypoint.sh b/dd-waf/docker/haproxy/docker-entrypoint.sh deleted file mode 100644 index a3ff9e0..0000000 --- a/dd-waf/docker/haproxy/docker-entrypoint.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh -# -# Copyright © 2021,2022 IsardVDI S.L. -# Copyright © 2022 Evilham -# -# This file is part of DD -# -# DD is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# DD is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more -# details. -# -# You should have received a copy of the GNU Affero General Public License -# along with DD. If not, see . -# -# SPDX-License-Identifier: AGPL-3.0-or-later -set -e - -LETSENCRYPT_DOMAIN="$DOMAIN" letsencrypt.sh - -if [ ! -e "/certs/chain.pem" ]; then - auto-generate-certs.sh -fi - -# first arg is `-f` or `--some-option` -if [ "${1#-}" != "$1" ]; then - set -- haproxy "$@" -fi - -if [ "$1" = 'haproxy' ]; then - shift # "haproxy" - # if the user wants "haproxy", let's add a couple useful flags - # -W -- "master-worker mode" (similar to the old "haproxy-systemd-wrapper"; allows for reload via "SIGUSR2") - # -db -- disables background mode - set -- haproxy -W -db "$@" -fi - -exec "$@" diff --git a/dd-waf/docker/haproxy/haproxy.cfg b/dd-waf/docker/haproxy/haproxy.cfg deleted file mode 100644 index 723a598..0000000 --- a/dd-waf/docker/haproxy/haproxy.cfg +++ /dev/null @@ -1,86 +0,0 @@ -resolvers mydns - nameserver dns1 127.0.0.11:53 - -global - daemon - log 127.0.0.1 local0 - tune.ssl.default-dh-param 2048 - h1-case-adjust content-type Content-Type - h1-case-adjust content-encoding Content-Encoding - h1-case-adjust transfer-encoding Transfer-Encoding - -defaults - mode http - option http-server-close - option dontlognull - option redispatch - option contstats - retries 3 - timeout connect 5s - timeout http-keep-alive 1s - # Slowloris protection - timeout http-request 15s - timeout queue 30s - timeout tarpit 1m # tarpit hold tim - backlog 10000 - - -frontend tf_waf - mode http - bind :80 - http-request redirect scheme https code 301 unless { ssl_fc } - http-request del-header ssl_client_cert unless { ssl_fc_has_crt } - http-request set-header ssl_client_cert -----BEGIN\ CERTIFICATE-----\ %[ssl_c_der,base64]\ -----END\ CERTIFICATE-----\ if { ssl_fc_has_crt } - bind :443 ssl crt /certs/chain.pem - - - # New line to test URI to see if its a letsencrypt request - acl letsencrypt-acl path_beg /.well-known/acme-challenge/ - use_backend letsencrypt if letsencrypt-acl - - # Internal traffic - use_backend bk_web if { src 192.168.0.0/16 } - - default_backend bk_waf - -# Traffic secured by the WAF arrives here -frontend ft_web - bind :81 name http - mode http - log global - option httplog - timeout client 25s - maxconn 1000 - default_backend bk_web - -backend letsencrypt - server letsencrypt 127.0.0.1:8080 - -# WAF farm where users' traffic is routed first -backend bk_waf - mode http - server modsecurity dd-waf-apache:80 check port 80 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -# application server farm -backend bk_web - mode http - server sso dd-sso-haproxy:80 check port 80 inter 5s rise 2 fall 10 resolvers mydns init-addr none - -listen stats - bind 0.0.0.0:9999 - mode http - stats enable - option httplog - stats show-legends - stats uri /haproxy - stats realm Haproxy\ Statistics - stats refresh 5s - #stats auth staging:mypassword - #acl authorized http_auth(AuthUsers) - #stats http-request auth unless authorized - timeout connect 5000ms - timeout client 50000ms - timeout server 50000ms - -userlist AuthUsers - user admin password $6$grgQMVfwI0XSGAQl$2usaQC9LVXXXYHtSkGUf74CIGsiH8fi/K.V6DuKSq0twPkmFGP2vL/b//Ulp2I4xBEZ3eYDhUbwBPK8jpmsbo. diff --git a/dd-waf/docker/haproxy/letsencrypt-renew-cron.sh b/dd-waf/docker/haproxy/letsencrypt-renew-cron.sh deleted file mode 100755 index 486d64a..0000000 --- a/dd-waf/docker/haproxy/letsencrypt-renew-cron.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh -# -# Copyright © 2021,2022 IsardVDI S.L. -# -# This file is part of DD -# -# DD is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# DD is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more -# details. -# -# You should have received a copy of the GNU Affero General Public License -# along with DD. If not, see . -# -# SPDX-License-Identifier: AGPL-3.0-or-later -certbot renew --http-01-port 8080 --cert-name sso.$LETSENCRYPT_DOMAIN diff --git a/dd-waf/docker/haproxy/letsencrypt.sh b/dd-waf/docker/haproxy/letsencrypt.sh deleted file mode 100755 index a571eff..0000000 --- a/dd-waf/docker/haproxy/letsencrypt.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/sh -# -# Copyright © 2021,2022 IsardVDI S.L. -# -# This file is part of DD -# -# DD is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# DD is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more -# details. -# -# You should have received a copy of the GNU Affero General Public License -# along with DD. If not, see . -# -# SPDX-License-Identifier: AGPL-3.0-or-later -if [ ! -L /etc/letsencrypt/renewal-hooks/deploy/letsencrypt-hook-deploy-concatenante.sh ] -then - mkdir -p /etc/letsencrypt/renewal-hooks/deploy/ - ln -s /usr/local/sbin/letsencrypt-hook-deploy-concatenante.sh /etc/letsencrypt/renewal-hooks/deploy/ -fi - -if [ -n "$LETSENCRYPT_DOMAIN" -a -n "$LETSENCRYPT_EMAIL" ] -then - LETSENCRYPT_DOMAIN="$LETSENCRYPT_DOMAIN" crond - if [ "$LETSENCRYPT_DOMAIN_ROOT" == "true" ] - then - option_root_domain="-d $LETSENCRYPT_DOMAIN" - fi - if [ ! -f /certs/chain.pem ] - then - if certbot certonly --standalone -m "$LETSENCRYPT_EMAIL" -n --agree-tos \ - -d "sso.$LETSENCRYPT_DOMAIN" \ - -d "api.$LETSENCRYPT_DOMAIN" \ - -d "admin.$LETSENCRYPT_DOMAIN" \ - -d "moodle.$LETSENCRYPT_DOMAIN" \ - -d "nextcloud.$LETSENCRYPT_DOMAIN" \ - -d "wp.$LETSENCRYPT_DOMAIN" \ - -d "oof.$LETSENCRYPT_DOMAIN" \ - -d "pad.$LETSENCRYPT_DOMAIN" \ - $option_root_domain - then - RENEWED_LINEAGE="/etc/letsencrypt/live/sso.$LETSENCRYPT_DOMAIN" /etc/letsencrypt/renewal-hooks/deploy/letsencrypt-hook-deploy-concatenante.sh - fi - fi -fi diff --git a/dd.conf.sample b/dd.conf.sample index b938757..52db7da 100644 --- a/dd.conf.sample +++ b/dd.conf.sample @@ -146,11 +146,11 @@ MARIADB_PASSWORD=SuperSecret ##============================================================================= IPA_ADMIN_PWD=freeipafreeipa -## WORKS BEHIND PROXY -BEHIND_PROXY=false +## ACCEPT PROXY PROTOCOL ON 8888 (HTTP) AND 561 (HTTPS) +#PROXY_PROTOCOL=false -## MODSECURITY -DISABLE_WAF=true +## DISABLE WAF/MODSECURITY +#DISABLE_WAF=true # SOURCES & SYSTEM VARS diff --git a/docs/post-install.ca.md b/docs/post-install.ca.md index 6a5196e..e8d2f24 100644 --- a/docs/post-install.ca.md +++ b/docs/post-install.ca.md @@ -30,6 +30,10 @@ Això es fa en l'aplicació admin. - anar a groups i verificar que apareix - anar a users i crear l'usuari "docent01" del grup "docents" amb role "teacher" +## Activar WAF + +Si així ho volem, podem activar el Web Application Firewall/Modsecurity seguint +[aquestes instruccions](waf-modsecurity.es.md). ## Plantilles Nextcloud (Opcional) diff --git a/docs/waf-modsecurity.es.md b/docs/waf-modsecurity.es.md new file mode 100644 index 0000000..4b8d6d7 --- /dev/null +++ b/docs/waf-modsecurity.es.md @@ -0,0 +1,49 @@ +# DD - Apache2 ModSecurity + HAProxy + +Instalación de los servicios Apache2 ModSecurity y HAProxy. + +* En el servicio de Apache2 con ModSecurity V3 se incluyen las reglas OWASP +* En servicio HAProxy actua de frontend de la aplicación, gestiona y negocia el certificado del dominio a través de letsencrypt. +* En la instalación el ModSecurity se encuentra deshabilitado para no interferir en el proceso de setup inicial del DD. +* La instalación se puede realizar con o sin la parte WAF. +* Si tenemos instalado el WAF podemos tenerlo activo o en modo bypass + +## Apache - ModSecurity + +Podemos encontrar la definición del servicio en `dd-sso/docker/waf-modsecurity`. + +Tenemos diferentes ficheros para configurar este servicio: + +* En el fichero `000-default.conf` tendremos la configuración del servidor web Apache2. +* En el fichero `crs-setup.conf` configuramos OWASP ModSecurity Core Rule Set ver.3.2.0 +* En el fichero `modsec_rules.conf` incluimos los ficheros necesarios del owasp servicio de Apache2 +* En el fichero `rules_apps.conf` se configuran los falsos positivos, de las diferentes aplicaciones, que se tienen idenficados hasta el momento. + +### Enable/Disable + +DD se puede utilizar con WAF tenerlo activo o desactivado, esto se gestiona +con la variable `DISABLE_WAF` en `dd.conf`. + +El valor por defecto actual es `true` (WAF desactivado), +esto cambiará en un futuro. + +``` +# Ejemplo de dd.conf + +# Usar WAF +DISABLE_WAF=false + +# No usar WAF +DISABLE_WAF=false +``` + +### Configuración + +Los cambios en `dd.conf` no son inmediatos, +tenemos que re-desplegar los contenedores de DD usando `dd-ctl`: + +```sh +./dd-ctl down +./dd-ctl build +./dd-ctl up +```