[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.GON-3874-DD-moodle
parent
e6325c9618
commit
09fec74915
40
dd-ctl
40
dd-ctl
|
@ -182,7 +182,31 @@ build_compose(){
|
||||||
setconf CUSTOM_PATH "$CUSTOM_PATH" .env
|
setconf CUSTOM_PATH "$CUSTOM_PATH" .env
|
||||||
setconf BUILD_APPS_ROOT_PATH "$CUSTOM_PATH/dd-apps" .env
|
setconf BUILD_APPS_ROOT_PATH "$CUSTOM_PATH/dd-apps" .env
|
||||||
setconf BUILD_SSO_ROOT_PATH "$CUSTOM_PATH/dd-sso" .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
|
## Prepare apps environment
|
||||||
ln -sf "${CUSTOM_PATH}/.env" dd-apps/.env
|
ln -sf "${CUSTOM_PATH}/.env" dd-apps/.env
|
||||||
ln -sf "${CUSTOM_PATH}/.env" dd-apps/docker/postgresql && \
|
ln -sf "${CUSTOM_PATH}/.env" dd-apps/docker/postgresql && \
|
||||||
|
@ -204,20 +228,10 @@ build_compose(){
|
||||||
rm -rf custom/system/keycloak-themes
|
rm -rf custom/system/keycloak-themes
|
||||||
rmdir custom/system 2>/dev/null || true
|
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
|
# Build compose ymls
|
||||||
# shellcheck disable=SC2086
|
|
||||||
docker-compose \
|
docker-compose \
|
||||||
$MODSECURITY $HAPROXY_WAF \
|
-f "dd-sso/docker-compose-parts/$WAF_YML" \
|
||||||
\
|
-f "dd-sso/docker-compose-parts/$HAPROXY_YML"\
|
||||||
-f dd-sso/docker-compose-parts/$BEHIND \
|
|
||||||
-f dd-sso/docker-compose-parts/api.yml \
|
-f dd-sso/docker-compose-parts/api.yml \
|
||||||
-f dd-sso/docker-compose-parts/keycloak.yml \
|
-f dd-sso/docker-compose-parts/keycloak.yml \
|
||||||
-f dd-sso/docker-compose-parts/avatars.yml \
|
-f dd-sso/docker-compose-parts/avatars.yml \
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
version: '3.7'
|
version: '3.7'
|
||||||
services:
|
services:
|
||||||
dd-sso-haproxy:
|
dd-sso-haproxy:
|
||||||
|
image: registry.dd-work.space/dd/haproxy:${DD_BUILD:-latest}
|
||||||
build:
|
build:
|
||||||
args:
|
args:
|
||||||
HAPROXY_IMG: ${HAPROXY_IMG-haproxy:2.4.12-alpine3.15}
|
HAPROXY_IMG: ${HAPROXY_IMG-haproxy:2.4.12-alpine3.15}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# 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"
|
|
@ -20,6 +20,7 @@
|
||||||
version: '3.7'
|
version: '3.7'
|
||||||
services:
|
services:
|
||||||
dd-sso-haproxy:
|
dd-sso-haproxy:
|
||||||
|
image: registry.dd-work.space/dd/haproxy:${DD_BUILD:-latest}
|
||||||
build:
|
build:
|
||||||
args:
|
args:
|
||||||
HAPROXY_IMG: ${HAPROXY_IMG-haproxy:2.4.12-alpine3.15}
|
HAPROXY_IMG: ${HAPROXY_IMG-haproxy:2.4.12-alpine3.15}
|
||||||
|
@ -39,11 +40,6 @@ services:
|
||||||
target: 80
|
target: 80
|
||||||
- published: 443
|
- published: 443
|
||||||
target: 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_file:
|
||||||
- .env
|
- .env
|
||||||
logging:
|
logging:
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Dummy file for a disabled WAF
|
||||||
|
version: '3.7'
|
|
@ -3,7 +3,7 @@ services:
|
||||||
dd-waf-apache:
|
dd-waf-apache:
|
||||||
image: registry.dd-work.space/dd/waf-apache:${DD_BUILD:-latest}
|
image: registry.dd-work.space/dd/waf-apache:${DD_BUILD:-latest}
|
||||||
build:
|
build:
|
||||||
context: ${BUILD_WAF_ROOT_PATH}/docker/modsecurity
|
context: ${BUILD_SSO_ROOT_PATH}/docker/waf-modsecurity
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
target: production
|
target: production
|
||||||
container_name: dd-waf-apache
|
container_name: dd-waf-apache
|
|
@ -31,7 +31,13 @@ COPY auto-generate-certs.sh /usr/local/sbin/
|
||||||
|
|
||||||
COPY docker-entrypoint.sh /usr/local/bin/
|
COPY docker-entrypoint.sh /usr/local/bin/
|
||||||
RUN ln -s /usr/local/bin/docker-entrypoint.sh /
|
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
|
COPY haproxy.cnf.parts /haproxy.cnf.parts
|
||||||
ADD haproxy.proxy-protocol.conf /usr/local/etc/haproxy/haproxy.proxy-protocol.cfg
|
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
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
set -e
|
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
|
LETSENCRYPT_DOMAIN="$DOMAIN" letsencrypt.sh
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
#!/bin/sh -eu
|
||||||
|
|
||||||
|
_help(){
|
||||||
|
cat <<EOF
|
||||||
|
USAGE: gen-haproxy-conf.sh waf|no-waf proxy|no-proxy
|
||||||
|
|
||||||
|
Generate a DD-compatible HAProxy configuration to stdout.
|
||||||
|
|
||||||
|
- The first argument indicates whether or not WAF will be enabled.
|
||||||
|
waf: enable WAF
|
||||||
|
no-waf: do not use WAF
|
||||||
|
- The second argument indicates whether or not the PROXY protocol will
|
||||||
|
be enabled on ports 8888 (HTTP) and 561 (HTTPS) for the outer layer
|
||||||
|
(either with WAF or without).
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
case "${1:-}" in
|
||||||
|
[wW][aA][fF])
|
||||||
|
USE_WAF="YES"
|
||||||
|
;;
|
||||||
|
[nN][oO]-[wW][aA][fF])
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
_help >> /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"
|
|
@ -1,96 +1,6 @@
|
||||||
#
|
#
|
||||||
# Copyright © 2021,2022 IsardVDI S.L.
|
# BEGIN: backends.cnf
|
||||||
# Copyright © 2022 Evilham <contact@evilham.com>
|
|
||||||
#
|
#
|
||||||
# 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 <https://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# 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
|
backend letsencrypt
|
||||||
server letsencrypt 127.0.0.1:8080
|
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-SSL %[ssl_fc]
|
||||||
http-request set-header X-Forwarded-Proto https
|
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
|
server wp dd-apps-wordpress:80 check port 80 inter 5s rise 2 fall 10 resolvers mydns init-addr none
|
||||||
|
#
|
||||||
|
# END: backends.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
|
||||||
|
#
|
|
@ -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
|
||||||
|
#
|
|
@ -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
|
||||||
|
#
|
|
@ -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
|
||||||
|
#
|
|
@ -0,0 +1,7 @@
|
||||||
|
#
|
||||||
|
# BEGIN: waf-head.cnf
|
||||||
|
#
|
||||||
|
frontend tf_waf
|
||||||
|
#
|
||||||
|
# END: waf-head.cnf
|
||||||
|
#
|
22
dd-waf/docker/haproxy/letsencrypt-hook-deploy-concatenante.sh → dd-sso/docker/haproxy/haproxy.cnf.parts/head.cnf
Executable file → Normal file
22
dd-waf/docker/haproxy/letsencrypt-hook-deploy-concatenante.sh → dd-sso/docker/haproxy/haproxy.cnf.parts/head.cnf
Executable file → Normal file
|
@ -1,6 +1,7 @@
|
||||||
#!/bin/sh
|
|
||||||
#
|
#
|
||||||
# Copyright © 2021,2022 IsardVDI S.L.
|
# Copyright © 2021,2022 IsardVDI S.L.
|
||||||
|
# Copyright © 2022 Evilham <contact@evilham.com>
|
||||||
|
# Copyright © 2022 Teradisk <info@teradisk.com>
|
||||||
#
|
#
|
||||||
# This file is part of DD
|
# This file is part of DD
|
||||||
#
|
#
|
||||||
|
@ -18,6 +19,21 @@
|
||||||
# along with DD. If not, see <https://www.gnu.org/licenses/>.
|
# along with DD. If not, see <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# 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
|
||||||
|
#
|
|
@ -0,0 +1,7 @@
|
||||||
|
#
|
||||||
|
# BEGIN: tail-non-waf.cnf
|
||||||
|
#
|
||||||
|
frontend ft_web
|
||||||
|
#
|
||||||
|
# END: tail-non-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
|
||||||
|
#
|
|
@ -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
|
||||||
|
#
|
|
@ -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
|
||||||
|
#
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# 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.
|
|
|
@ -1,182 +0,0 @@
|
||||||
#
|
|
||||||
# Copyright © 2021,2022 IsardVDI S.L.
|
|
||||||
# Copyright © 2022 Evilham <contact@evilham.com>
|
|
||||||
#
|
|
||||||
# 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 <https://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# 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
|
|
|
@ -9,6 +9,6 @@
|
||||||
ProxyPreserveHost On
|
ProxyPreserveHost On
|
||||||
ProxyRequests off
|
ProxyRequests off
|
||||||
ProxyVia Off
|
ProxyVia Off
|
||||||
ProxyPass "/" "http://dd-waf-haproxy:81/"
|
ProxyPass "/" "http://dd-sso-haproxy:81/"
|
||||||
ProxyPassReverse "/" "http://dd-waf-haproxy:81/"
|
ProxyPassReverse "/" "http://dd-sso-haproxy:81/"
|
||||||
</VirtualHost>
|
</VirtualHost>
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -e
|
||||||
set -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
|
sed -i.orig -e "s/modsecurity On/modsecurity Off/" /etc/apache2/sites-available/000-default.conf
|
||||||
else
|
else
|
||||||
sed -i.orig -e "s/modsecurity Off/modsecurity On/" /etc/apache2/sites-available/000-default.conf
|
sed -i.orig -e "s/modsecurity Off/modsecurity On/" /etc/apache2/sites-available/000-default.conf
|
|
@ -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
|
|
||||||
```
|
|
|
@ -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"
|
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# 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
|
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# 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
|
|
|
@ -1,43 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# Copyright © 2021,2022 IsardVDI S.L.
|
|
||||||
# Copyright © 2022 Evilham <contact@evilham.com>
|
|
||||||
#
|
|
||||||
# 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 <https://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# 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 "$@"
|
|
|
@ -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.
|
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
||||||
certbot renew --http-01-port 8080 --cert-name sso.$LETSENCRYPT_DOMAIN
|
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# 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
|
|
|
@ -146,11 +146,11 @@ MARIADB_PASSWORD=SuperSecret
|
||||||
##=============================================================================
|
##=============================================================================
|
||||||
IPA_ADMIN_PWD=freeipafreeipa
|
IPA_ADMIN_PWD=freeipafreeipa
|
||||||
|
|
||||||
## WORKS BEHIND PROXY
|
## ACCEPT PROXY PROTOCOL ON 8888 (HTTP) AND 561 (HTTPS)
|
||||||
BEHIND_PROXY=false
|
#PROXY_PROTOCOL=false
|
||||||
|
|
||||||
## MODSECURITY
|
## DISABLE WAF/MODSECURITY
|
||||||
DISABLE_WAF=true
|
#DISABLE_WAF=true
|
||||||
|
|
||||||
# SOURCES & SYSTEM VARS
|
# SOURCES & SYSTEM VARS
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,10 @@ Això es fa en l'aplicació admin.
|
||||||
- anar a groups i verificar que apareix
|
- anar a groups i verificar que apareix
|
||||||
- anar a users i crear l'usuari "docent01" del grup "docents" amb role "teacher"
|
- 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)
|
## Plantilles Nextcloud (Opcional)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
```
|
Loading…
Reference in New Issue