From 43b250ba8af62c654796dd37ab7afc9ebe54d2fa Mon Sep 17 00:00:00 2001 From: Zoey Date: Sun, 5 Feb 2023 16:37:49 +0100 Subject: [PATCH] add tls support Signed-off-by: Zoey --- Dockerfile | 14 ++++++-- haproxy.cfg | 98 +++++++++++++++++++++++++++++++++-------------------- start.sh | 4 +++ 3 files changed, 76 insertions(+), 40 deletions(-) create mode 100644 start.sh diff --git a/Dockerfile b/Dockerfile index 1a13d20..1dee79b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,13 @@ -FROM haproxy:2.2-alpine +FROM haproxy:2.7-alpine +USER root + +COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg +COPY start.sh /usr/local/bin/start.sh + +RUN apk upgrade --no-cache && \ + apk add --no-cache ca-certificates wget tzdata openssl && \ + chmod +x /usr/local/bin/start.sh -EXPOSE 2375 ENV ALLOW_RESTARTS=0 \ AUTH=0 \ BUILD=0 \ @@ -28,4 +35,5 @@ ENV ALLOW_RESTARTS=0 \ TASKS=0 \ VERSION=1 \ VOLUMES=0 -COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg + +ENTRYPOINT start.sh \ No newline at end of file diff --git a/haproxy.cfg b/haproxy.cfg index 011137e..e6de4a5 100644 --- a/haproxy.cfg +++ b/haproxy.cfg @@ -1,46 +1,66 @@ global - log stdout format raw daemon "${LOG_LEVEL}" - - pidfile /run/haproxy.pid - maxconn 4000 - - # Turn on stats unix socket - server-state-file /var/lib/haproxy/server-state - + ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 + ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 + ssl-default-bind-options prefer-client-ciphers no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets + ssl-default-server-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 + ssl-default-server-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 + ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets + defaults - mode http - log global - option httplog - option dontlognull - option http-server-close - option redispatch - retries 3 - timeout http-request 10s - timeout queue 1m timeout connect 10s - timeout client 10m - timeout server 10m - timeout http-keep-alive 10s - timeout check 10s - maxconn 3000 - - # Allow seamless reloads - load-server-state-from-file global - - # Use provided example error pages - errorfile 400 /usr/local/etc/haproxy/errors/400.http - errorfile 403 /usr/local/etc/haproxy/errors/403.http - errorfile 408 /usr/local/etc/haproxy/errors/408.http - errorfile 500 /usr/local/etc/haproxy/errors/500.http - errorfile 502 /usr/local/etc/haproxy/errors/502.http - errorfile 503 /usr/local/etc/haproxy/errors/503.http - errorfile 504 /usr/local/etc/haproxy/errors/504.http - -backend dockerbackend - server dockersocket $SOCKET_PATH + timeout client 30s + timeout server 30s frontend dockerfrontend + mode tcp bind :2375 + tcp-request inspect-delay 10s + tcp-request content accept if HTTP + tcp-request content accept if { req.ssl_hello_type 1 } + use_backend http if HTTP + default_backend https + +backend http + mode tcp + server loopback-for-http abns@haproxy-http send-proxy-v2 +backend https + mode tcp + server loopback-for-https abns@haproxy-https send-proxy-v2 + +frontend http + mode http + bind abns@haproxy-http accept-proxy + http-request deny unless METH_GET || { env(POST) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/((stop)|(restart)|(kill)) } { env(ALLOW_RESTARTS) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/auth } { env(AUTH) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/build } { env(BUILD) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/commit } { env(COMMIT) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/configs } { env(CONFIGS) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/containers } { env(CONTAINERS) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/distribution } { env(DISTRIBUTION) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/events } { env(EVENTS) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/exec } { env(EXEC) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/grpc } { env(GRPC) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/images } { env(IMAGES) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/info } { env(INFO) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/networks } { env(NETWORKS) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/nodes } { env(NODES) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/_ping } { env(PING) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/plugins } { env(PLUGINS) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/secrets } { env(SECRETS) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/services } { env(SERVICES) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/session } { env(SESSION) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/swarm } { env(SWARM) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/system } { env(SYSTEM) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/tasks } { env(TASKS) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/version } { env(VERSION) -m bool } + http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/volumes } { env(VOLUMES) -m bool } + http-request deny + default_backend dockerbackend + +frontend https + mode http + bind abns@haproxy-https accept-proxy ssl crt /etc/cert.pem alpn h3,h2,http/1.1 http-request deny unless METH_GET || { env(POST) -m bool } http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/containers/[a-zA-Z0-9_.-]+/((stop)|(restart)|(kill)) } { env(ALLOW_RESTARTS) -m bool } http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/auth } { env(AUTH) -m bool } @@ -68,3 +88,7 @@ frontend dockerfrontend http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/volumes } { env(VOLUMES) -m bool } http-request deny default_backend dockerbackend + +backend dockerbackend + mode http + server dockersocket $SOCKET_PATH diff --git a/start.sh b/start.sh new file mode 100644 index 0000000..55051c3 --- /dev/null +++ b/start.sh @@ -0,0 +1,4 @@ +#!/bin/sh +openssl req -nodes -new -x509 -subj '/CN=*' -sha256 -keyout /etc/privkey.pem -out /etc/fullchain.pem -days 365000 > /dev/null 2>&1 +cat /etc/fullchain.pem /etc/privkey.pem | tee /etc/cert.pem > /dev/null 2>&1 +haproxy -f /usr/local/etc/haproxy/haproxy.cfg \ No newline at end of file