Skip to content
Snippets Groups Projects
Commit b5b9d046 authored by Pierre Ozoux's avatar Pierre Ozoux
Browse files

modularize haproxy

parent 5cc67e18
No related branches found
No related tags found
No related merge requests found
FROM debian:jessie
ENV DEBIAN_FRONTEND noninteractive
RUN \
apt-get update &&\
apt-get install -y \
wget \
ca-certificates &&\
rm -rf /var/lib/apt/lists/*
ADD confd /etc/confd
RUN \
wget https://github.com/kelseyhightower/confd/releases/download/v0.7.1/confd-0.7.1-linux-amd64 -O confd && \
chmod +x confd
RUN \
wget https://get.docker.com/builds/Linux/x86_64/docker-1.5.0 -O docker && \
chmod +x docker
ENTRYPOINT ["/confd"]
CMD ["-interval=60", "-node=172.17.42.1:4001", "-watch=true", "-verbose=true"]
# Confd
The smallest confd docker image in town ;)
## Run
This image will log everything to stdout/stderr.
It was designed to work with HAproxy, but you can use it for anything! There is no configuration, you'll have to mount the config folder. There is a nice example in [indiehosters/confd git repo](https://github.com/indiehosters/dockerfiles/tree/master/server-wide/confd).
```bash
docker run\
-v /haproxy-config:/etc/haproxy/\
-v ./confd/:/etc/confd/\
-v /var/run/docker.sock:/var/run/docker.sock\
indiehosters/confd
```
It works really well with [indiehosters/haproxy](https://registry.hub.docker.com/u/indiehosters/haproxy/) to have automatic configuration of HAproxy backed by `etcd` or `consul`.
[template]
src = "haproxy.cfg.tmpl"
dest = "/etc/haproxy/haproxy.cfg"
keys = [
"/services"
]
reload_cmd = "/docker exec haproxy /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -D -p /var/run/haproxy.pid -st $(/docker exec haproxy cat /var/run/haproxy.pid)"
global
log /dev/log local0 info
log /dev/log local0 notice
maxconn 4096
user haproxy
group haproxy
tune.ssl.default-dh-param 2048
ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
defaults
log global
mode http
option forwardfor
option httpclose
option httplog
option dontlognull
retries 3
timeout connect 5000
timeout client 50000
timeout server 50000
frontend https-in
mode http
bind *:443 ssl no-sslv3 crt-list /etc/haproxy/crt-list crt /etc/haproxy/approved-certs/default.pem
# HSTS (15768000 seconds = 6 months)
rspadd Strict-Transport-Security:\ max-age=15768000
reqadd X-Forwarded-Proto:\ https
acl autoconfig hdr_beg(host) -i autoconfig
acl letsencrypt path_beg /.well-known/acme
{{range $app := lsdir "/services"}}
{{$hostnames := printf "/services/%s/*" $app}}
{{range gets $hostnames}}
{{$hostname := .Key}}
{{$data := json .Value}}
# {{base $hostname}}:
acl https_{{base $hostname}} hdr(host) -i {{base $hostname}}
acl https_{{base $hostname}} hdr(host) -i www.{{base $hostname}}
use_backend {{base $hostname}} if https_{{base $hostname}}
{{end}}
{{end}}
use_backend letsencrypt if letsencrypt !https_letsencrypt.indie.host
use_backend autoconfig if autoconfig
frontend http-in
bind *:80
redirect scheme https code 301
{{range $app := lsdir "/services"}}
{{$hostnames := printf "/services/%s/*" $app}}
{{range gets $hostnames}}
{{$hostname := .Key}}
{{$data := json .Value}}
# {{base $hostname}}:
backend {{base $hostname}}
cookie SERVERID insert nocache indirect
server Server {{$data.ip}}:{{$data.port}} cookie Server
{{end}}
{{end}}
backend letsencrypt
cookie SERVERID insert nocache indirect
server Server letsencrypt.indie.host:443 cookie Server ssl verify none
backend autoconfig
cookie SERVERID insert nocache indirect
server Server mail.indie.host:443 cookie Server ssl verify none
[Unit]
Description=%p for %i etcd registration
# Requirements
Requires=etcd.service
# Dependency binding
BindsTo=u@%i.service
[Service]
Type=oneshot
RemainAfterExit=yes
Environment=URL=%i
ExecStart=/bin/bash -xc ' \
ip=""; \
while [ -z $ip ]; \
do \
container_name=`echo ${URL}_web_1 | sed "s/\.//g" | sed "s/-//g"`; \
ip=`docker inspect --format \'{{.NetworkSettings.IPAddress}}\' $container_name`; \
sleep 1; \
done; \
etcdctl --peers 172.17.42.1:4001 set /services/web/%i \'{"ip":"\'$ip\'", "port":"80"}\';'
ExecStop=-/usr/bin/etcdctl rm /services/web/%i
[Path]
PathExists=/data/runtime/haproxy/haproxy.cfg
[Install]
WantedBy=multi-user.target
[Unit]
Description=%p
# Requirements
Requires=docker.service
# Dependency ordering
After=docker.service
[Service]
Restart=always
RestartSec=20
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill %p
ExecStartPre=-/usr/bin/docker rm %p
ExecStart=/usr/bin/docker run \
--rm \
--name %p \
-v /dev/log:/dev/log \
-v /data/runtime/haproxy:/etc/haproxy \
-p 80:80 \
-p 443:443 \
haproxy haproxy -f /etc/haproxy/haproxy.cfg
ExecReload=/usr/bin/docker restart %p
ExecStop=/usr/bin/docker stop %p
[Unit]
Description=Get the OCSP data from the cert provider
[Service]
Type=oneshot
TimeoutStartSec=0
ExecStart=/bin/bash -euxc ' \
for cert in `ls /data/runtime/haproxy/approved-certs/*.pem`;do \
/data/indiehosters/utils/ocsp.sh $cert; \
done; \
systemctl restart haproxy; \
rm /tmp/*.crt'
[Unit]
Description=Daily timer for OCSP stapling
[Timer]
OnBootSec=15min
OnUnitActiveSec=1day
[Install]
WantedBy=multi-user.target
...@@ -3,12 +3,10 @@ Description=%p-%i ...@@ -3,12 +3,10 @@ Description=%p-%i
# Requirements # Requirements
Requires=docker.service Requires=docker.service
Requires=d-u@%i.service
Requires=b-u@%i.timer Requires=b-u@%i.timer
# Dependency ordering # Dependency ordering
After=docker.service After=docker.service
Before=d-u@%i.service
Before=b-u@%i.timer Before=b-u@%i.timer
[Service] [Service]
...@@ -17,9 +15,8 @@ RestartSec=10 ...@@ -17,9 +15,8 @@ RestartSec=10
TimeoutStartSec=60 TimeoutStartSec=60
TimeoutStopSec=15 TimeoutStopSec=15
WorkingDirectory=/data/domains/%i/ WorkingDirectory=/data/domains/%i/
ExecStartPre=/bin/cp /data/domains/%i/TLS/%i.pem /data/runtime/haproxy/approved-certs/%i.pem
ExecStartPre=-/opt/bin/docker-compose rm -f ExecStartPre=-/opt/bin/docker-compose rm -f
ExecStart=/opt/bin/docker-compose up ExecStart=/bin/bash -euxc "HOST=%i /opt/bin/docker-compose up"
ExecStop=/opt/bin/docker-compose stop ExecStop=/opt/bin/docker-compose stop
[Install] [Install]
......
#!/bin/bash -eux
domain=$1
echo "/etc/haproxy/approved-certs/$domain.pem $domain" >> /data/runtime/haproxy/crt-list
echo "/etc/haproxy/approved-certs/$domain.pem www.$domain" >> /data/runtime/haproxy/crt-list
#!/bin/bash -eux
PEM_FILE=${1}
CRT_FILE=/tmp/`basename ${PEM_FILE} | sed 's/pem/crt/'`
DIR=`dirname ${PEM_FILE}`
URL=`openssl x509 -in ${PEM_FILE} -text | grep OCSP | cut -d: -f2,3`
HEADER=`echo $URL | cut -d/ -f3`
ISSUER_CRT_URL=`openssl x509 -in ${PEM_FILE} -text | grep Issuers | cut -d: -f2,3`
wget ${ISSUER_CRT_URL} -q -O - | openssl x509 -inform DER -outform PEM > ${PEM_FILE}.issuer
openssl x509 -outform PEM -in ${PEM_FILE} > ${CRT_FILE}
openssl ocsp -noverify -issuer ${PEM_FILE}.issuer -cert ${CRT_FILE} -url ${URL} -no_nonce -header Host ${HEADER} -respout ${PEM_FILE}.ocsp
...@@ -28,11 +28,8 @@ LOG_LEVEL="${LOG_LEVEL:-6}" # 7 = debug -> 0 = emergency ...@@ -28,11 +28,8 @@ LOG_LEVEL="${LOG_LEVEL:-6}" # 7 = debug -> 0 = emergency
# opts & defaults from. The parsing is unforgiving so be precise in your syntax # opts & defaults from. The parsing is unforgiving so be precise in your syntax
read -r -d '' usage <<-'EOF' read -r -d '' usage <<-'EOF'
-u [arg] URL to process. Required. -u [arg] URL to process. Required.
-f [arg] Certificate file to use.
-a [arg] Application to install. (in the form github.com/indiehosters/wordress) -a [arg] Application to install. (in the form github.com/indiehosters/wordress)
-s Start the application right away. -s Start the application right away.
-g Generates the necessary certificate.
-p Paste certificate from previous run.
-b Buys the associated domain name. -b Buys the associated domain name.
-i Configure OpenDKIM. -i Configure OpenDKIM.
-c Configures DNS on Namecheap. -c Configures DNS on Namecheap.
...@@ -47,11 +44,6 @@ source /etc/environment ...@@ -47,11 +44,6 @@ source /etc/environment
source /data/indiehosters/utils/helpers.sh source /data/indiehosters/utils/helpers.sh
source /data/indiehosters/utils/configure_dkim_dns.sh source /data/indiehosters/utils/configure_dkim_dns.sh
function scaffold () {
info "Creating application folder"
mkdir -p ${FOLDER}
}
function buy_domain_name () { function buy_domain_name () {
not_supported_extensions=( "us" "eu" "nu" "asia" "ca" "co.uk" "me.uk" "org.uk" "com.au" "net.au" "org.au" "es" "nom.es" "com.es" "org.es" "de" "fr" ) not_supported_extensions=( "us" "eu" "nu" "asia" "ca" "co.uk" "me.uk" "org.uk" "com.au" "net.au" "org.au" "es" "nom.es" "com.es" "org.es" "de" "fr" )
...@@ -112,56 +104,6 @@ function buy_domain_name () { ...@@ -112,56 +104,6 @@ function buy_domain_name () {
call_API ${arguments} call_API ${arguments}
} }
function provision_certificate () {
scaffold
filename=$(basename "${arg_f}")
extension="${filename##*.}"
if [ "${extension}" != "pem" ]; then
error "File extension must be pem."
exit 1
fi
info "Provisionning certificate."
mkdir -p ${TLS_FOLDER}
cd ${TLS_FOLDER}
cp ${arg_f} ${arg_u}.pem
/data/indiehosters/utils/append_crt_list.sh ${arg_u}
}
function generate_certificate () {
scaffold
info "creating TLS ans CSR folder."
mkdir -p ${TLS_FOLDER}/CSR
info "Generating the key."
openssl genrsa -out ${TLS_FOLDER}/CSR/${arg_u}.key 4096
info "Creating the request."
openssl req -new \
-key ${TLS_FOLDER}/CSR/${arg_u}.key \
-out ${TLS_FOLDER}/CSR/${arg_u}.csr \
-subj "/C=${CountryCode}/ST=${City}/L=${City}/O=${arg_u}/OU=/CN=${arg_u}/emailAddress=${EmailAddress}"
info "Here is your CSR, paste it in your Certificate authority interface."
echo ""
cat ${TLS_FOLDER}/CSR/${arg_u}.csr
paste_certificate
}
function paste_certificate () {
echo ""
info "You should have received a certificate."
info "Please paste your certificate now: (finish with enter and ctrl-d)"
cat > ${TLS_FOLDER}/CSR/${arg_u}.crt
info "Concat certificate, CA and key into pem file."
cat ${TLS_FOLDER}/CSR/${arg_u}.crt /data/indiehosters/certs/sub.class2.server.sha2.ca.pem /data/indiehosters/certs/ca-sha2.pem ${TLS_FOLDER}/CSR/${arg_u}.key > ${TLS_FOLDER}/${arg_u}.pem
/data/indiehosters/utils/append_crt_list.sh ${arg_u}
}
function application () { function application () {
export MAIL_PASS=`tr -dc A-Za-z0-9_ < /dev/urandom | head -c 20 | xargs` export MAIL_PASS=`tr -dc A-Za-z0-9_ < /dev/urandom | head -c 20 | xargs`
export MAIL_USER="noreply.${arg_u}@${MAIL_DOMAIN}" export MAIL_USER="noreply.${arg_u}@${MAIL_DOMAIN}"
...@@ -268,9 +210,6 @@ TLS_FOLDER=${FOLDER}/TLS ...@@ -268,9 +210,6 @@ TLS_FOLDER=${FOLDER}/TLS
[ ${arg_b} -eq 1 ] && buy_domain_name [ ${arg_b} -eq 1 ] && buy_domain_name
[ ! -z "${arg_a}" ] && application [ ! -z "${arg_a}" ] && application
[ ${arg_g} -eq 1 ] && generate_certificate
[ ${arg_p} -eq 1 ] && paste_certificate
[ ! -z "${arg_f}" ] && provision_certificate
[ ${arg_i} -eq 1 ] && provision_dkim [ ${arg_i} -eq 1 ] && provision_dkim
[ ${arg_c} -eq 1 ] && configure_dns [ ${arg_c} -eq 1 ] && configure_dns
[ ${arg_s} -eq 1 ] && start [ ${arg_s} -eq 1 ] && start
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment