[network] Fix handling of forwarded headers
This fixes several issues where services would see the internal IP of the proxy and not that of the client. It works by first unsetting any proxy-related headers that arrive from the internet, then setting those as seen by HAProxy's entrypoint frontend. And finally making sure that neither WAF when enabled nor other HAProxy backends touch these headers, while they are actually used by the final services. Services affected: Netcloud, Keycloak, MoodleGON-3874-DD-moodle
parent
ba3b4ba46f
commit
8f5de8af6a
|
@ -9,6 +9,7 @@ COPY 02-configure-moodle.sh /docker-entrypoint-init.d/
|
|||
COPY 03-plugins.sh /docker-entrypoint-init.d/
|
||||
COPY src/rootfs/var/www/html/admin/cli/isinstalled.php /
|
||||
COPY is_moodle_ready.sh /
|
||||
COPY nginx.conf /etc/nginx/
|
||||
RUN echo "user=nobody" >> /etc/php7/php-fpm.d/www.conf
|
||||
RUN echo "group=nobody" >> /etc/php7/php-fpm.d/www.conf
|
||||
RUN apk add --no-cache dcron libcap && \
|
||||
|
|
|
@ -3,3 +3,4 @@
|
|||
02-configure-moodle.sh MIT https://github.com/erseco/ https://raw.githubusercontent.com/erseco/alpine-moodle/63b8b80d333eaec1cdffa2e768a364e973d6c1ee/rootfs/docker-entrypoint-init.d/02-configure-moodle.sh
|
||||
Dockerfile MIT https://github.com/erseco/ https://raw.githubusercontent.com/erseco/alpine-moodle/63b8b80d333eaec1cdffa2e768a364e973d6c1ee/Dockerfile
|
||||
moodle.yml MIT https://github.com/erseco/ https://raw.githubusercontent.com/erseco/alpine-moodle/63b8b80d333eaec1cdffa2e768a364e973d6c1ee/docker-compose.yml
|
||||
nginx.conf MIT https://github.com/erseco/ https://raw.githubusercontent.com/erseco/alpine-moodle/63b8b80d333eaec1cdffa2e768a364e973d6c1ee/rootfs/etc/nginx/nginx.conf
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
worker_processes 1;
|
||||
error_log stderr warn;
|
||||
pid /run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# Define custom log format to include reponse times
|
||||
log_format main_timed '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for" '
|
||||
'$request_time $upstream_response_time $pipe $upstream_cache_status';
|
||||
|
||||
access_log /dev/stdout main_timed;
|
||||
error_log /dev/stderr notice;
|
||||
|
||||
keepalive_timeout 65;
|
||||
|
||||
# Write temporary files to /tmp so they can be created as a non-privileged user
|
||||
client_body_temp_path /tmp/client_temp;
|
||||
proxy_temp_path /tmp/proxy_temp_path;
|
||||
fastcgi_temp_path /tmp/fastcgi_temp;
|
||||
uwsgi_temp_path /tmp/uwsgi_temp;
|
||||
scgi_temp_path /tmp/scgi_temp;
|
||||
|
||||
set_real_ip_from 10.0.0.0/8;
|
||||
set_real_ip_from 172.16.0.0/12;
|
||||
set_real_ip_from 192.168.0.0/16;
|
||||
real_ip_header X-Forwarded-For;
|
||||
|
||||
# Default server definition
|
||||
server {
|
||||
listen 8080 default_server;
|
||||
server_name _;
|
||||
|
||||
sendfile off;
|
||||
|
||||
# Increase proxy buffers for large requests
|
||||
proxy_buffer_size 128k;
|
||||
proxy_buffers 4 256k;
|
||||
proxy_busy_buffers_size 256k;
|
||||
|
||||
# Upload limit
|
||||
client_max_body_size 200M;
|
||||
client_body_buffer_size 128k;
|
||||
|
||||
root /var/www/html;
|
||||
index index.php index.html;
|
||||
|
||||
location / {
|
||||
# First attempt to serve request as file, then
|
||||
# as directory, then fall back to index.php
|
||||
try_files $uri $uri/ /index.php?q=$uri&$args;
|
||||
}
|
||||
|
||||
# Redirect server error pages to the static page /50x.html
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /var/lib/nginx/html;
|
||||
}
|
||||
|
||||
# Pass the PHP scripts to PHP-FPM listening on 127.0.0.1:9000
|
||||
location ~ [^/]\.php(/|$) {
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass 127.0.0.1:9000;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
|
||||
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
}
|
||||
|
||||
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
|
||||
expires 5d;
|
||||
}
|
||||
|
||||
# Deny access to . files, for security
|
||||
location ~ /\. {
|
||||
log_not_found off;
|
||||
deny all;
|
||||
}
|
||||
|
||||
# Allow fpm ping and status from localhost
|
||||
location ~ ^/(fpm-status|fpm-ping)$ {
|
||||
access_log off;
|
||||
allow 127.0.0.1;
|
||||
deny all;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
fastcgi_pass 127.0.0.1:9000;
|
||||
}
|
||||
}
|
||||
|
||||
# Include other server configs
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
|
||||
gzip on;
|
||||
gzip_proxied any;
|
||||
gzip_types text/plain application/xml text/css text/js text/xml application/x-javascript text/javascript application/json application/xml+rss;
|
||||
gzip_vary on;
|
||||
gzip_disable "msie6";
|
||||
|
||||
}
|
|
@ -25,7 +25,7 @@ http {
|
|||
set_real_ip_from 10.0.0.0/8;
|
||||
set_real_ip_from 172.16.0.0/12;
|
||||
set_real_ip_from 192.168.0.0/16;
|
||||
real_ip_header X-Real-IP;
|
||||
real_ip_header X-Forwarded-For;
|
||||
upstream php-handler {
|
||||
server dd-apps-nextcloud-app:9000;
|
||||
}
|
||||
|
|
|
@ -7,10 +7,6 @@ backend letsencrypt
|
|||
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
|
||||
|
@ -18,74 +14,40 @@ backend be_api
|
|||
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
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
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
|
||||
|
||||
# This comes from the internet, do not trust the forwarding headers
|
||||
http-request del-header X-Forwarded-For
|
||||
http-request del-header X-Forwarded-Proto
|
||||
# But add our forwarding headers instead
|
||||
option forwardfor
|
||||
|
||||
# New line to test URI to see if its a letsencrypt request
|
||||
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
CustomLog /var/log/apache2/access.log combined
|
||||
|
||||
ProxyPreserveHost On
|
||||
ProxyRequests off
|
||||
ProxyVia Off
|
||||
ProxyRequests off
|
||||
ProxyVia Off
|
||||
# Do not touch the proxy headers, these are set by HAProxy before
|
||||
ProxyAddHeaders off
|
||||
ProxyPass "/" "http://dd-sso-haproxy:81/"
|
||||
ProxyPassReverse "/" "http://dd-sso-haproxy:81/"
|
||||
</VirtualHost>
|
||||
|
|
Loading…
Reference in New Issue