commit 1f98fc734c8c657285450db1db9389232413cf25 Author: crusader Date: Sat Oct 27 12:58:37 2018 +0900 ing diff --git a/certbot/Dockerfile b/certbot/Dockerfile new file mode 100644 index 0000000..18c4a4c --- /dev/null +++ b/certbot/Dockerfile @@ -0,0 +1,26 @@ +FROM certbot/certbot:latest + +MAINTAINER LOAFLE Docker Maintainers "rnd@loafle.com" + +COPY conf/crontab /var/spool/cron/crontabs/certbot-renew +COPY bin/* /opt/letsencrypt/bin/ + +RUN chmod +x /opt/letsencrypt/bin/*.sh \ + && crontab /var/spool/cron/crontabs/certbot-renew + +ENV CERT_DOMAINS="" \ + CERT_EMAIL="" \ + CERT_RSA_KEY_SIZE=4096 \ + CERT_STAGING=true + + +ENV PATH "$PATH:/opt/letsencrypt/bin" + +VOLUME /etc/letsencrypt +VOLUME /var/log/letsencrypt/ + +VOLUME /usr/share/nginx/html +VOLUME /etc/haproxy/ssl/ + +ENTRYPOINT ["docker-entrypoint.sh"] +CMD ["crond", "-f"] \ No newline at end of file diff --git a/certbot/bin/docker-entrypoint.sh b/certbot/bin/docker-entrypoint.sh new file mode 100644 index 0000000..9af15b0 --- /dev/null +++ b/certbot/bin/docker-entrypoint.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +set -e + +# Validate required environment variables. +echo "Target domains for Certification are $CERT_DOMAINS." +echo "E-main for Certification are $CERT_EMAIL." + +export CERT_OPTIONS + +if [ "$CERT_STAGING" == true ]; then + CERT_OPTIONS="--staging" +fi + +echo "Cert option is [$CERT_OPTIONS]" + +run_certbot.sh + +exec "$@" \ No newline at end of file diff --git a/certbot/bin/reload_haproxy.sh b/certbot/bin/reload_haproxy.sh new file mode 100644 index 0000000..ec209e1 --- /dev/null +++ b/certbot/bin/reload_haproxy.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +set -e \ No newline at end of file diff --git a/certbot/bin/run_certbot.sh b/certbot/bin/run_certbot.sh new file mode 100644 index 0000000..36f4208 --- /dev/null +++ b/certbot/bin/run_certbot.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +set -e + +get_certificate() { + local LIVE_DIR_PATH="/etc/letsencrypt/live" + + if [ -z "$CERT_DOMAINS" ]; then + return + fi + + if [ ! -d "$LIVE_DIR_PATH" ]; then + mkdir -p $LIVE_DIR_PATH + fi + + # Certificates are separated by semi-colon (;). Domains on each certificate are + # separated by comma (,). + local CERT_TARGETS=${CERT_DOMAINS//;/ } + local RESULT_CODE= + + echo "Cerbot start to generate certificate." + + # Create or renew certificates. Don't exit on error. It's likely that certbot + # will fail on first run, if HAproxy is not running. + for DOMAINS in $CERT_TARGETS; do + local FIRST_DOMAIN=${DOMAINS//,*/ } # read first domain + echo "Certificating of $DOMAINS is start." + + if [[ ! -d "$LIVE_DIR_PATH/$FIRST_DOMAIN" || ! -f "$LIVE_DIR_PATH/$FIRST_DOMAIN/fullchain.pem" || ! -f "$LIVE_DIR_PATH/$FIRST_DOMAIN/privkey.pem" ]]; then + certbot certonly \ + --agree-tos \ + --email "$CERT_EMAIL" \ + --domains "$DOMAINS" \ + --rsa-key-size $CERT_RSA_KEY_SIZE \ + --expand \ + --noninteractive \ + --logs-dir /var/log/letsencrypt/ \ + --webroot \ + --webroot-path /usr/share/nginx/html/ \ + $CERT_OPTIONS || true + + RESULT_CODE=$? + echo "certbot exit code $RESULT_CODE" + + if [ $RESULT_CODE -ne 0 ]; then + echo "Cerbot failed for $DOMAINS. Check the logs for details." + fi + else + echo "Certificating of $DOMAINS is exist already." + fi + + done + + echo "Cerbot ended to generate certificate." +} + +get_certificate + +update_crt_list.sh \ No newline at end of file diff --git a/certbot/bin/update_crt_list.sh b/certbot/bin/update_crt_list.sh new file mode 100644 index 0000000..5390a70 --- /dev/null +++ b/certbot/bin/update_crt_list.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +#/etc/haproxy/ssl/example.com.pem example.com +#/etc/haproxy/ssl/www.example.com.pem www.example.com +#/etc/haproxy/ssl/mail.example.com.pem mail.example.com + + +set -e + +update_crt_list() { + local CRT_LIST_PATH=/etc/haproxy/ssl/crt-list.txt + local CERT_LIST="" + local LIVE_DIR_PATH="/etc/letsencrypt/live" + local FULLCHAIN_FILE_NAME="fullchain.pem" + local PRIVATEKEY_FILE_NAME="privkey.pem" + local SSL_DIR_PATH="/etc/haproxy/ssl" + local B_CHANGED=false + + if [ ! -d "$LIVE_DIR_PATH" ]; then + mkdir -p $LIVE_DIR_PATH + fi + if [ ! -d "$SSL_DIR_PATH" ]; then + mkdir -p $SSL_DIR_PATH + fi + + echo "Generation of crt-list.txt is start." + + cd "$LIVE_DIR_PATH" + + local DOMAIN_LIST="$(ls)" + + for DOMAIN in $DOMAIN_LIST; do + if [ ! -d "$DOMAIN" ]; then + continue + fi + cd "$DOMAIN" + if [ -f "$FULLCHAIN_FILE_NAME" -a -f "$PRIVATEKEY_FILE_NAME" ]; then + # Check if something has changed + OLD_COMBINED_PEM= + [ -f "${SSL_DIR_PATH}/${DOMAIN}.pem" ] && OLD_COMBINED_PEM="$(cat ${SSL_DIR_PATH}/${DOMAIN}.pem)" + CURRENT_COMBINED_PEM="$(cat ${FULLCHAIN_FILE_NAME} ${PRIVATEKEY_FILE_NAME})" + if [ "$OLD_COMBINED_PEM" != "$CURRENT_COMBINED_PEM" ]; then + # Store new combined cert + echo "$CURRENT_COMBINED_PEM" > "${SSL_DIR_PATH}/${DOMAIN}.pem" + B_CHANGED=true + fi + CERT_LIST="${CERT_LIST}${SSL_DIR_PATH}/${DOMAIN}.pem $DOMAIN\n" + fi + cd .. + done + + if [ "$CERT_LIST" != "$(cat $CRT_LIST_PATH)" -o $B_CHANGED == true ]; then + # Update list and reload server + DEFAULT_CRT=$(head -n 1 $CRT_LIST_PATH) + echo -e "$DEFAULT_CRT\n$CERT_LIST" > ${CRT_LIST_PATH} + reload_haproxy.sh + fi + + echo "Generation of crt-list.txt was ended." + +} + +update_crt_list \ No newline at end of file diff --git a/certbot/conf/crontab b/certbot/conf/crontab new file mode 100644 index 0000000..13b2ab8 --- /dev/null +++ b/certbot/conf/crontab @@ -0,0 +1 @@ +0 3 1 */2 * /usr/local/bin/certbot renew --quiet --no-self-upgrade --renew-hook /opt/letsencrypt/bin/update_crt_list.sh \ No newline at end of file diff --git a/haproxy/1.7-alpine/Dockerfile b/haproxy/1.7-alpine/Dockerfile new file mode 100644 index 0000000..c7dd1ae --- /dev/null +++ b/haproxy/1.7-alpine/Dockerfile @@ -0,0 +1,25 @@ +FROM haproxy:1.7-alpine + +RUN apk add --update --no-cache openssl \ + && rm -rf /var/cache/apk/* \ + && mkdir -p /etc/haproxy/ \ + && mkdir -p /opt/haproxy/ \ + && mkdir -p /var/lib/haproxy \ + && touch /var/lib/haproxy/server-state \ + && cp -R /usr/local/etc/haproxy/errors /etc/haproxy/errors \ + && rm -rf /usr/local/etc/haproxy + +COPY config/*.cfg /etc/haproxy/conf.d/ +COPY bin/* /opt/haproxy/bin/ + +RUN chmod +x /opt/haproxy/bin/*.sh + +EXPOSE 80 443 1936 + +ENV PATH "$PATH:/opt/haproxy/bin" + +VOLUME /etc/haproxy/ssl/ +VOLUME /etc/haproxy/sites/ + +ENTRYPOINT ["prepare-entrypoint.sh"] +CMD ["haproxy", "-f", "/etc/haproxy/conf.d", "-f", "/etc/haproxy/sites"] \ No newline at end of file diff --git a/haproxy/1.7-alpine/bin/generate-default-crt.sh b/haproxy/1.7-alpine/bin/generate-default-crt.sh new file mode 100644 index 0000000..1b0aff5 --- /dev/null +++ b/haproxy/1.7-alpine/bin/generate-default-crt.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +set -e + +generate_default_certificate() { + local CRT_LIST_PATH=/etc/haproxy/ssl/crt-list.txt + local DEFAULT_CRT_KEY_PATH=/tmp/default_key.pem + local DEFAULT_CRT_CA_PATH=/tmp/default_ca.pem + local DEFAULT_CRT_CERT_PATH=/etc/haproxy/ssl/default-cert.pem + + if [[ ! -f ${DEFAULT_CRT_CERT_PATH} ]]; then + openssl req -x509 -newkey rsa:2048 -keyout ${DEFAULT_CRT_KEY_PATH} -out ${DEFAULT_CRT_CA_PATH} -days 90 -nodes -subj '/CN=*/O=Temp SSL Cert/C=US' + cat ${DEFAULT_CRT_KEY_PATH} ${DEFAULT_CRT_CA_PATH} > ${DEFAULT_CRT_CERT_PATH} + rm ${DEFAULT_CRT_KEY_PATH} ${DEFAULT_CRT_CA_PATH} + echo "Default certification is generated in ${DEFAULT_CRT_CERT_PATH}" + fi + + mkdir -p /etc/haproxy/ssl + + if [[ ! -f ${CRT_LIST_PATH} ]]; then + touch ${CRT_LIST_PATH} + + echo -e "$DEFAULT_CRT_CERT_PATH www.example.com" > ${CRT_LIST_PATH} + + echo "Certification list file is generated in ${CRT_LIST_PATH}" + fi +} + +generate_default_certificate \ No newline at end of file diff --git a/haproxy/1.7-alpine/bin/generate_http_sites_list.sh b/haproxy/1.7-alpine/bin/generate_http_sites_list.sh new file mode 100644 index 0000000..7f5c499 --- /dev/null +++ b/haproxy/1.7-alpine/bin/generate_http_sites_list.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +set -e + +#domainname backendname +#one.example.com site:one.example.com +#two.example.com site:two.example.com +#etc.domain1.com site:etc.example.com + +generate_http_sites_list() { + local HTTP_SITES_MAP_PATH=/etc/haproxy/sites/http-sites.map + local SITES_DIR_PATH=/etc/haproxy/sites + local SITE_NAME="" + local HTTP_SITES_MAP="" + + mkdir -p $SITES_DIR_PATH + + if [[ ! -f ${HTTP_SITES_MAP_PATH} ]]; then + touch $HTTP_SITES_MAP_PATH + fi + + cd $SITES_DIR_PATH + + for SITE_FILE_NAME in http-*.cfg; do + if [[ ! -f $SITE_FILE_NAME ]]; then + continue + fi + SITE_NAME=${SITE_FILE_NAME/http-/} + SITE_NAME=${SITE_NAME/.cfg/} + HTTP_SITES_MAP=$HTTP_SITES_MAP"$SITE_NAME site-http:$SITE_NAME\n" + done + + echo -e "$HTTP_SITES_MAP" > $HTTP_SITES_MAP_PATH +} + +generate_http_sites_list \ No newline at end of file diff --git a/haproxy/1.7-alpine/bin/generate_https_sites_list.sh b/haproxy/1.7-alpine/bin/generate_https_sites_list.sh new file mode 100644 index 0000000..16d78a1 --- /dev/null +++ b/haproxy/1.7-alpine/bin/generate_https_sites_list.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +set -e + +#domainname backendname +#one.example.com site:one.example.com +#two.example.com site:two.example.com +#etc.domain1.com site:etc.example.com + +generate_https_sites_list() { + local HTTPS_SITES_MAP_PATH=/etc/haproxy/sites/https-sites.map + local SITES_DIR_PATH=/etc/haproxy/sites + local SITE_NAME="" + local HTTPS_SITES_MAP="" + + mkdir -p $SITES_DIR_PATH + + if [[ ! -f ${HTTPS_SITES_MAP_PATH} ]]; then + touch $HTTPS_SITES_MAP_PATH + fi + + cd $SITES_DIR_PATH + + for SITE_FILE_NAME in https-*.cfg; do + if [[ ! -f $SITE_FILE_NAME ]]; then + continue + fi + SITE_NAME=${SITE_FILE_NAME/https-/} + SITE_NAME=${SITE_NAME/.cfg/} + HTTPS_SITES_MAP=$HTTPS_SITES_MAP"$SITE_NAME site-https:$SITE_NAME\n" + done + + echo -e "$HTTPS_SITES_MAP" > $HTTPS_SITES_MAP_PATH +} + +generate_https_sites_list \ No newline at end of file diff --git a/haproxy/1.7-alpine/bin/generate_sites_list.sh b/haproxy/1.7-alpine/bin/generate_sites_list.sh new file mode 100644 index 0000000..ad02349 --- /dev/null +++ b/haproxy/1.7-alpine/bin/generate_sites_list.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +set -e + +generate_http_sites_list.sh +generate_https_sites_list.sh \ No newline at end of file diff --git a/haproxy/1.7-alpine/bin/prepare-entrypoint.sh b/haproxy/1.7-alpine/bin/prepare-entrypoint.sh new file mode 100644 index 0000000..a043300 --- /dev/null +++ b/haproxy/1.7-alpine/bin/prepare-entrypoint.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +set -e + +generate-default-crt.sh +generate_sites_list.sh + +exec /docker-entrypoint.sh "$@" \ No newline at end of file diff --git a/haproxy/1.7-alpine/config/30.global.cfg b/haproxy/1.7-alpine/config/30.global.cfg new file mode 100644 index 0000000..4ccdab4 --- /dev/null +++ b/haproxy/1.7-alpine/config/30.global.cfg @@ -0,0 +1,19 @@ +global + log 127.0.0.1 local0 info + + chroot /var/lib/haproxy + maxconn 4096 + + # Turn on stats unix socket + stats socket /var/lib/haproxy/stats + server-state-file /var/lib/haproxy/server-state + + # Mozilla security tips for intermediate level + # https://mozilla.github.io/server-side-tls/ssl-config-generator/ + tune.ssl.default-dh-param 2048 + + ssl-default-bind-options no-sslv3 no-tls-tickets + ssl-default-bind-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE + + ssl-default-server-options no-sslv3 no-tls-tickets + ssl-default-server-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:D diff --git a/haproxy/1.7-alpine/config/40.default.cfg b/haproxy/1.7-alpine/config/40.default.cfg new file mode 100644 index 0000000..cbd6b70 --- /dev/null +++ b/haproxy/1.7-alpine/config/40.default.cfg @@ -0,0 +1,29 @@ +defaults + mode http + log global + option httplog + option dontlognull + option http-server-close + option forwardfor except 127.0.0.0/8 + 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 /etc/haproxy/errors/400.http + errorfile 403 /etc/haproxy/errors/403.http + errorfile 408 /etc/haproxy/errors/408.http + errorfile 500 /etc/haproxy/errors/500.http + errorfile 502 /etc/haproxy/errors/502.http + errorfile 503 /etc/haproxy/errors/503.http + errorfile 504 /etc/haproxy/errors/504.http diff --git a/haproxy/1.7-alpine/config/50.listen-stats.cfg b/haproxy/1.7-alpine/config/50.listen-stats.cfg new file mode 100644 index 0000000..27aea0b --- /dev/null +++ b/haproxy/1.7-alpine/config/50.listen-stats.cfg @@ -0,0 +1,8 @@ +listen stats + bind *:1936 + mode http + stats enable + #stats hide-version + stats realm Haproxy\ Statistics + stats uri /stats + stats auth admin:54321 \ No newline at end of file diff --git a/haproxy/1.7-alpine/config/60.frontend.cfg b/haproxy/1.7-alpine/config/60.frontend.cfg new file mode 100644 index 0000000..060fb77 --- /dev/null +++ b/haproxy/1.7-alpine/config/60.frontend.cfg @@ -0,0 +1,52 @@ +frontend www-http + bind *:80 + + # Required variables from the request + http-request set-var(req.path) path + + # # http-sites-map ACLs + # acl http-sites-acl req.hdr(host),lower,map_beg(/etc/haproxy/sites/http-sites.map) -m found + + # https-sites-map ACLs + acl https-sites-acl req.hdr(host),lower,map_beg(/etc/haproxy/sites/https-sites.map) -m found + + # # Required ACLs + acl letsencrypt-acl path_beg /.well-known/acme-challenge/ + + # Normal requests should get secured + redirect scheme https code 301 if !letsencrypt-acl https-sites-acl + #redirect scheme https code 301 if https-sites-acl + + # # Redirect ACME requests to certbot + use_backend site-http:default if letsencrypt-acl + + # Redirect HTTP requests to http site + use_backend %[req.hdr(host),lower,map(/etc/haproxy/sites/http-sites.map,site-http:default)] + + default_backend site-http:default + +frontend www-https + # BEFORE BIND HOOK + bind :443 ssl strict-sni crt-list /etc/haproxy/ssl/crt-list.txt + + # AFTER BIND HOOK + + # Standard headers to inform app about inverse proxy status + http-request set-header X-SSL %[ssl_fc] + http-request set-header X-SSL-Session_ID %[ssl_fc_session_id,hex] + http-request set-header X-SSL-Client-Verify %[ssl_c_verify] + http-request set-header X-SSL-Client-DN %{+Q}[ssl_c_s_dn] + http-request set-header X-SSL-Client-CN %{+Q}[ssl_c_s_dn(cn)] + http-request set-header X-SSL-Issuer %{+Q}[ssl_c_i_dn] + http-request set-header X-SSL-Client-NotBefore %{+Q}[ssl_c_notbefore] + http-request set-header X-SSL-Client-NotAfter %{+Q}[ssl_c_notafter] + http-request set-header X-Forwarded-Proto https if { ssl_fc } + http-request set-header X-Forwarded-Host %[req.hdr(host)] + http-request set-header X-Forwarded-Port %[dst_port] + http-request set-header X-Forwarded-For %[src] + http-request set-header X-Real-IP %[src] + + + # AFTER WWW HOOK + + use_backend %[req.hdr(host),lower,map(/etc/haproxy/sites/https-sites.map,site-http:default)] \ No newline at end of file diff --git a/haproxy/1.7-alpine/config/70.backend.cfg b/haproxy/1.7-alpine/config/70.backend.cfg new file mode 100644 index 0000000..ba8fd23 --- /dev/null +++ b/haproxy/1.7-alpine/config/70.backend.cfg @@ -0,0 +1,5 @@ +backend site-http:default + mode http + + # Redirect all traffic to the default service + server default-www nginx:80 \ No newline at end of file diff --git a/haproxy/1.8-alpine/Dockerfile b/haproxy/1.8-alpine/Dockerfile new file mode 100644 index 0000000..e0ba454 --- /dev/null +++ b/haproxy/1.8-alpine/Dockerfile @@ -0,0 +1,25 @@ +FROM haproxy:1.8-alpine + +RUN apk add --update --no-cache openssl \ + && rm -rf /var/cache/apk/* \ + && mkdir -p /etc/haproxy/ \ + && mkdir -p /opt/haproxy/ \ + && mkdir -p /var/lib/haproxy \ + && touch /var/lib/haproxy/server-state \ + && cp -R /usr/local/etc/haproxy/errors /etc/haproxy/errors \ + && rm -rf /usr/local/etc/haproxy + +COPY config/*.cfg /etc/haproxy/conf.d/ +COPY bin/* /opt/haproxy/bin/ + +RUN chmod +x /opt/haproxy/bin/*.sh + +EXPOSE 80 443 1936 + +ENV PATH "$PATH:/opt/haproxy/bin" + +VOLUME /etc/haproxy/ssl/ +VOLUME /etc/haproxy/sites/ + +ENTRYPOINT ["prepare-entrypoint.sh"] +CMD ["haproxy", "-f", "/etc/haproxy/conf.d", "-f", "/etc/haproxy/sites"] \ No newline at end of file diff --git a/haproxy/1.8-alpine/bin/generate-default-crt.sh b/haproxy/1.8-alpine/bin/generate-default-crt.sh new file mode 100644 index 0000000..1b0aff5 --- /dev/null +++ b/haproxy/1.8-alpine/bin/generate-default-crt.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +set -e + +generate_default_certificate() { + local CRT_LIST_PATH=/etc/haproxy/ssl/crt-list.txt + local DEFAULT_CRT_KEY_PATH=/tmp/default_key.pem + local DEFAULT_CRT_CA_PATH=/tmp/default_ca.pem + local DEFAULT_CRT_CERT_PATH=/etc/haproxy/ssl/default-cert.pem + + if [[ ! -f ${DEFAULT_CRT_CERT_PATH} ]]; then + openssl req -x509 -newkey rsa:2048 -keyout ${DEFAULT_CRT_KEY_PATH} -out ${DEFAULT_CRT_CA_PATH} -days 90 -nodes -subj '/CN=*/O=Temp SSL Cert/C=US' + cat ${DEFAULT_CRT_KEY_PATH} ${DEFAULT_CRT_CA_PATH} > ${DEFAULT_CRT_CERT_PATH} + rm ${DEFAULT_CRT_KEY_PATH} ${DEFAULT_CRT_CA_PATH} + echo "Default certification is generated in ${DEFAULT_CRT_CERT_PATH}" + fi + + mkdir -p /etc/haproxy/ssl + + if [[ ! -f ${CRT_LIST_PATH} ]]; then + touch ${CRT_LIST_PATH} + + echo -e "$DEFAULT_CRT_CERT_PATH www.example.com" > ${CRT_LIST_PATH} + + echo "Certification list file is generated in ${CRT_LIST_PATH}" + fi +} + +generate_default_certificate \ No newline at end of file diff --git a/haproxy/1.8-alpine/bin/generate_http_sites_list.sh b/haproxy/1.8-alpine/bin/generate_http_sites_list.sh new file mode 100644 index 0000000..7f5c499 --- /dev/null +++ b/haproxy/1.8-alpine/bin/generate_http_sites_list.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +set -e + +#domainname backendname +#one.example.com site:one.example.com +#two.example.com site:two.example.com +#etc.domain1.com site:etc.example.com + +generate_http_sites_list() { + local HTTP_SITES_MAP_PATH=/etc/haproxy/sites/http-sites.map + local SITES_DIR_PATH=/etc/haproxy/sites + local SITE_NAME="" + local HTTP_SITES_MAP="" + + mkdir -p $SITES_DIR_PATH + + if [[ ! -f ${HTTP_SITES_MAP_PATH} ]]; then + touch $HTTP_SITES_MAP_PATH + fi + + cd $SITES_DIR_PATH + + for SITE_FILE_NAME in http-*.cfg; do + if [[ ! -f $SITE_FILE_NAME ]]; then + continue + fi + SITE_NAME=${SITE_FILE_NAME/http-/} + SITE_NAME=${SITE_NAME/.cfg/} + HTTP_SITES_MAP=$HTTP_SITES_MAP"$SITE_NAME site-http:$SITE_NAME\n" + done + + echo -e "$HTTP_SITES_MAP" > $HTTP_SITES_MAP_PATH +} + +generate_http_sites_list \ No newline at end of file diff --git a/haproxy/1.8-alpine/bin/generate_https_sites_list.sh b/haproxy/1.8-alpine/bin/generate_https_sites_list.sh new file mode 100644 index 0000000..16d78a1 --- /dev/null +++ b/haproxy/1.8-alpine/bin/generate_https_sites_list.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +set -e + +#domainname backendname +#one.example.com site:one.example.com +#two.example.com site:two.example.com +#etc.domain1.com site:etc.example.com + +generate_https_sites_list() { + local HTTPS_SITES_MAP_PATH=/etc/haproxy/sites/https-sites.map + local SITES_DIR_PATH=/etc/haproxy/sites + local SITE_NAME="" + local HTTPS_SITES_MAP="" + + mkdir -p $SITES_DIR_PATH + + if [[ ! -f ${HTTPS_SITES_MAP_PATH} ]]; then + touch $HTTPS_SITES_MAP_PATH + fi + + cd $SITES_DIR_PATH + + for SITE_FILE_NAME in https-*.cfg; do + if [[ ! -f $SITE_FILE_NAME ]]; then + continue + fi + SITE_NAME=${SITE_FILE_NAME/https-/} + SITE_NAME=${SITE_NAME/.cfg/} + HTTPS_SITES_MAP=$HTTPS_SITES_MAP"$SITE_NAME site-https:$SITE_NAME\n" + done + + echo -e "$HTTPS_SITES_MAP" > $HTTPS_SITES_MAP_PATH +} + +generate_https_sites_list \ No newline at end of file diff --git a/haproxy/1.8-alpine/bin/generate_sites_list.sh b/haproxy/1.8-alpine/bin/generate_sites_list.sh new file mode 100644 index 0000000..ad02349 --- /dev/null +++ b/haproxy/1.8-alpine/bin/generate_sites_list.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +set -e + +generate_http_sites_list.sh +generate_https_sites_list.sh \ No newline at end of file diff --git a/haproxy/1.8-alpine/bin/prepare-entrypoint.sh b/haproxy/1.8-alpine/bin/prepare-entrypoint.sh new file mode 100644 index 0000000..a043300 --- /dev/null +++ b/haproxy/1.8-alpine/bin/prepare-entrypoint.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +set -e + +generate-default-crt.sh +generate_sites_list.sh + +exec /docker-entrypoint.sh "$@" \ No newline at end of file diff --git a/haproxy/1.8-alpine/config/30.global.cfg b/haproxy/1.8-alpine/config/30.global.cfg new file mode 100644 index 0000000..4ccdab4 --- /dev/null +++ b/haproxy/1.8-alpine/config/30.global.cfg @@ -0,0 +1,19 @@ +global + log 127.0.0.1 local0 info + + chroot /var/lib/haproxy + maxconn 4096 + + # Turn on stats unix socket + stats socket /var/lib/haproxy/stats + server-state-file /var/lib/haproxy/server-state + + # Mozilla security tips for intermediate level + # https://mozilla.github.io/server-side-tls/ssl-config-generator/ + tune.ssl.default-dh-param 2048 + + ssl-default-bind-options no-sslv3 no-tls-tickets + ssl-default-bind-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE + + ssl-default-server-options no-sslv3 no-tls-tickets + ssl-default-server-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:D diff --git a/haproxy/1.8-alpine/config/40.default.cfg b/haproxy/1.8-alpine/config/40.default.cfg new file mode 100644 index 0000000..cbd6b70 --- /dev/null +++ b/haproxy/1.8-alpine/config/40.default.cfg @@ -0,0 +1,29 @@ +defaults + mode http + log global + option httplog + option dontlognull + option http-server-close + option forwardfor except 127.0.0.0/8 + 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 /etc/haproxy/errors/400.http + errorfile 403 /etc/haproxy/errors/403.http + errorfile 408 /etc/haproxy/errors/408.http + errorfile 500 /etc/haproxy/errors/500.http + errorfile 502 /etc/haproxy/errors/502.http + errorfile 503 /etc/haproxy/errors/503.http + errorfile 504 /etc/haproxy/errors/504.http diff --git a/haproxy/1.8-alpine/config/50.listen-stats.cfg b/haproxy/1.8-alpine/config/50.listen-stats.cfg new file mode 100644 index 0000000..27aea0b --- /dev/null +++ b/haproxy/1.8-alpine/config/50.listen-stats.cfg @@ -0,0 +1,8 @@ +listen stats + bind *:1936 + mode http + stats enable + #stats hide-version + stats realm Haproxy\ Statistics + stats uri /stats + stats auth admin:54321 \ No newline at end of file diff --git a/haproxy/1.8-alpine/config/60.frontend.cfg b/haproxy/1.8-alpine/config/60.frontend.cfg new file mode 100644 index 0000000..060fb77 --- /dev/null +++ b/haproxy/1.8-alpine/config/60.frontend.cfg @@ -0,0 +1,52 @@ +frontend www-http + bind *:80 + + # Required variables from the request + http-request set-var(req.path) path + + # # http-sites-map ACLs + # acl http-sites-acl req.hdr(host),lower,map_beg(/etc/haproxy/sites/http-sites.map) -m found + + # https-sites-map ACLs + acl https-sites-acl req.hdr(host),lower,map_beg(/etc/haproxy/sites/https-sites.map) -m found + + # # Required ACLs + acl letsencrypt-acl path_beg /.well-known/acme-challenge/ + + # Normal requests should get secured + redirect scheme https code 301 if !letsencrypt-acl https-sites-acl + #redirect scheme https code 301 if https-sites-acl + + # # Redirect ACME requests to certbot + use_backend site-http:default if letsencrypt-acl + + # Redirect HTTP requests to http site + use_backend %[req.hdr(host),lower,map(/etc/haproxy/sites/http-sites.map,site-http:default)] + + default_backend site-http:default + +frontend www-https + # BEFORE BIND HOOK + bind :443 ssl strict-sni crt-list /etc/haproxy/ssl/crt-list.txt + + # AFTER BIND HOOK + + # Standard headers to inform app about inverse proxy status + http-request set-header X-SSL %[ssl_fc] + http-request set-header X-SSL-Session_ID %[ssl_fc_session_id,hex] + http-request set-header X-SSL-Client-Verify %[ssl_c_verify] + http-request set-header X-SSL-Client-DN %{+Q}[ssl_c_s_dn] + http-request set-header X-SSL-Client-CN %{+Q}[ssl_c_s_dn(cn)] + http-request set-header X-SSL-Issuer %{+Q}[ssl_c_i_dn] + http-request set-header X-SSL-Client-NotBefore %{+Q}[ssl_c_notbefore] + http-request set-header X-SSL-Client-NotAfter %{+Q}[ssl_c_notafter] + http-request set-header X-Forwarded-Proto https if { ssl_fc } + http-request set-header X-Forwarded-Host %[req.hdr(host)] + http-request set-header X-Forwarded-Port %[dst_port] + http-request set-header X-Forwarded-For %[src] + http-request set-header X-Real-IP %[src] + + + # AFTER WWW HOOK + + use_backend %[req.hdr(host),lower,map(/etc/haproxy/sites/https-sites.map,site-http:default)] \ No newline at end of file diff --git a/haproxy/1.8-alpine/config/70.backend.cfg b/haproxy/1.8-alpine/config/70.backend.cfg new file mode 100644 index 0000000..ba8fd23 --- /dev/null +++ b/haproxy/1.8-alpine/config/70.backend.cfg @@ -0,0 +1,5 @@ +backend site-http:default + mode http + + # Redirect all traffic to the default service + server default-www nginx:80 \ No newline at end of file diff --git a/sentry/_9/.env b/sentry/_9/.env new file mode 100644 index 0000000..5406666 --- /dev/null +++ b/sentry/_9/.env @@ -0,0 +1,7 @@ +SENTRY_POSTGRES_HOST=db +SENTRY_POSTGRES_PORT=5432 +SENTRY_DB_USER=sentry +SENTRY_DB_PASSWORD=secret +SENTRY_REDIS_HOST=redis +SENTRY_REDIS_PORT=6379 +SENTRY_SECRET_KEY=eh7o01-t(z606764qvg=nmkkb9=oz1#*#sseh6w=2#fxr50b+e \ No newline at end of file diff --git a/sentry/_9/docker-compose.yml b/sentry/_9/docker-compose.yml new file mode 100644 index 0000000..4328b75 --- /dev/null +++ b/sentry/_9/docker-compose.yml @@ -0,0 +1,53 @@ +version: '3' + +services: + sentry: + container_name: sentry + image: sentry + env_file: + - .env + ports: + - '9000:9000' + depends_on: + - db + - redis + tty: true + stdin_open: true + cron: + container_name: sentry-cron + image: sentry + command: run cron + env_file: + - .env + depends_on: + - db + - redis + worker: + container_name: sentry-worker + image: sentry + command: run worker + env_file: + - .env + depends_on: + - db + - redis + redis: + container_name: sentry-redis + image: redis + volumes: + - redis-data:/data + ports: + - '6379:6379' + db: + container_name: sentry-postgres + image: postgres + environment: + POSTGRES_USER: sentry + POSTGRES_PASSWORD: secret + volumes: + - pg-data:/var/lib/postgresql/data + ports: + - '5432:5432' +volumes: + redis-data: + pg-data: \ No newline at end of file