initial commit for ansible haproxy role

This commit is contained in:
Michael Rennecke 2019-03-20 19:50:49 +01:00
parent e545c85ed3
commit 1fa96a719b
11 changed files with 363 additions and 0 deletions

16
.editorconfig Normal file
View File

@ -0,0 +1,16 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4
[*.yaml]
indent_size = 2

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
roles/haproxy/files/errorfiles
roles/haproxy/files/haproxy

5
common.yaml Normal file
View File

@ -0,0 +1,5 @@
---
- hosts: git.0rpheus.net
roles:
- haproxy

57
hosts.yaml Normal file
View File

@ -0,0 +1,57 @@
---
all:
hosts:
git.0rpheus.net:
vars:
ansible_become: true
# haproxy backends
haproxy_backends:
seafile.0rpheus.net:
server_defs:
- "odroid 169.254.1.3:80 check"
smokeping.0rpheus.net:
server_defs:
- "odroid 169.254.1.3:1080 check"
tt-rss.0rpheus.net:
server_defs:
- "odroid 169.254.1.3:80 check"
post.0rpheus.net:
server_defs:
- "docker 127.0.0.1:4000 check"
blog.0rpheus.net:
server_defs:
- "lighttpd 127.0.0.1:2020 check"
git.0rpheus.net:
server_defs:
- "gogs 127.0.0.1:3000 check"
ox.0rpheus.net:
server_defs:
- "docker 127.0.0.1:81 check"
#git.0rpheus.net {
# proxy / 127.0.0.1:3000 {
# except /css /fonts /js /img
# }
# root /opt/gogs/public/
#}
#dav.0rpheus.net {
# proxy / 127.0.0.1:8009/servlet/dav/ {
# transparent
# }
#}

View File

@ -0,0 +1,36 @@
[Unit]
Description=HAProxy Load Balancer
After=network.target
[Service]
Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid"
ExecStartPre=/usr/local/bin/haproxy -f $CONFIG -c -q
ExecStart=/usr/local/bin/haproxy -Ws -f $CONFIG -p $PIDFILE
ExecReload=/usr/local/bin/haproxy -f $CONFIG -c -q
ExecReload=/bin/kill -USR2 $MAINPID
KillMode=mixed
Restart=always
SuccessExitStatus=143
Type=notify
# The following lines leverage SystemD's sandboxing options to provide
# defense in depth protection at the expense of restricting some flexibility
# in your setup (e.g. placement of your configuration files) or possibly
# reduced performance. See systemd.service(5) and systemd.exec(5) for further
# information.
# NoNewPrivileges=true
# ProtectHome=true
# If you want to use 'ProtectSystem=strict' you should whitelist the PIDFILE,
# any state files and any other files written using 'ReadWritePaths' or
# 'RuntimeDirectory'.
# ProtectSystem=true
# ProtectKernelTunables=true
# ProtectKernelModules=true
# ProtectControlGroups=true
# If your SystemD version supports them, you can add: @reboot, @swap, @sync
# SystemCallFilter=~@cpu-emulation @keyring @module @obsolete @raw-io
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,36 @@
#!/bin/bash
set -e
# request certificates
while read -r domain
do
if [ ! -d "/etc/letsencrypt/live/$domain" ]
then
certbot certonly --standalone \
-d "$domain" \
--non-interactive \
--agree-tos \
--email micha@0rpheus.net \
--preferred-challenges=http \
--http-01-port=8888
fi
done < /etc/haproxy/domains.txt
# renew all certificates
certbot renew --http-01-port=8888 --preferred-challenges=http
# copy certificates
find /etc/letsencrypt/live/ -mindepth 1 -maxdepth 1 -type d | while read -r domain_path
do
domain=$(basename "$domain_path")
if grep -q "$domain" /etc/haproxy/domains.txt
then
pem_file=/etc/haproxy/certs/$domain.pem
cat "$domain_path/fullchain.pem" "$domain_path/privkey.pem" > "$pem_file"
chmod 600 "$pem_file"
fi
done
systemctl reload haproxy

View File

@ -0,0 +1,17 @@
---
- name: restart haproxy
service:
name: haproxy
state: restarted
- name: reload haproxy
service:
name: haproxy
state: reloaded
- name: reload systemd config
shell: systemctl daemon-reload
- name: update certs
shell: /usr/local/bin/update_haproxy_certs.sh

View File

@ -0,0 +1,79 @@
---
- name: install dependencies
apt:
name:
- liblua5.3-0
- libpcre3
state: latest
- name: conflicted with haproxy package
apt:
name:
- haproxy
state: absent
- name: add user 'haproxy'
user:
name: haproxy
system: yes
create_home: no
- name: create config dir
file:
path: /etc/haproxy/
state: directory
- name: copy errorcodes
copy:
src: errorfiles
dest: /etc/haproxy/
- name: copy haproxy binary
copy:
src: haproxy
dest: /usr/local/bin
mode: 0755
notify:
- restart haproxy
- name: copy scripts
copy:
src: update_haproxy_certs.sh
dest: /usr/local/bin
mode: 0755
- name: create basic HAProxy configs
template:
src: "{{ item }}"
dest: "/etc/haproxy/{{ item }}"
mode: 0644
with_items:
- hostname2backend.map
- haproxy.cfg
notify: reload haproxy
- name: create domains.txt
template:
src: domains.txt
dest: /etc/haproxy/
mode: 0644
notify:
- update certs
- name: systemd unit
copy:
src: haproxy.service
dest: /lib/systemd/system/
mode: 0644
notify:
- reload systemd config
- reload haproxy
- name: haproxy service
service:
name: haproxy
enabled: yes
state: started

View File

@ -0,0 +1,3 @@
{% for domain in haproxy_backends %}
{{ domain }}
{% endfor %}

View File

@ -0,0 +1,109 @@
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy_admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
ssl-default-bind-ciphers ECDH+AESGCM:ECDH+CHACHA20
ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
ssl-default-server-ciphers AES128+ECDHE:AES256+ECDHE
ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
defaults
log global
mode http
option httplog
option dontlognull
option tcp-smart-connect
option tcp-smart-accept
# use kernel splice system call to lower latency
option splice-auto
option forwardfor
# option forceclose
option socket-stats
timeout http-request 20s
timeout connect 5s
timeout client 50s
timeout server 50s
timeout check 800
errorfile 400 /etc/haproxy/errorfiles/400.http
errorfile 403 /etc/haproxy/errorfiles/403.http
errorfile 408 /etc/haproxy/errorfiles/408.http
errorfile 500 /etc/haproxy/errorfiles/500.http
errorfile 502 /etc/haproxy/errorfiles/502.http
errorfile 503 /etc/haproxy/errorfiles/503.http
errorfile 504 /etc/haproxy/errorfiles/504.http
frontend http
bind *:80 name http
bind *:443 name https ssl crt /etc/haproxy/certs/default.pem crt /etc/haproxy/certs/ ecdhe secp384r1 alpn h2,http/1.1 npn h2,http/1.1
compression algo gzip
compression type text/html text/plain text/javascript application/javascript application/xml text/css
# HSTS (31536000 seconds = 1 year)
http-response set-header Strict-Transport-Security max-age=31536000
http-response set-header X-Content-Type-Options nosniff
# set protocoll headers to https - works only if all https redirects happens in HAProxy
http-request set-header HTTP_X_FORWARDED_PROTO https
http-request set-header X-Forwarded-Proto https
# force https for known domains
acl hostname_has_backend hdr(Host),lower,map(/etc/haproxy/hostname2backend.map) -m found
http-request redirect scheme https code 301 if !{ ssl_fc } hostname_has_backend
# Let's encrypt
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend bk_letsencrypt if letsencrypt-acl
# stats backend
acl stats-acl path_beg /haproxy
use_backend bk_stats if stats-acl
# routing for known domains
use_backend bk_%[hdr(Host),lower,map(/etc/haproxy/hostname2backend.map)] if hostname_has_backend
backend bk_letsencrypt
server letsencrypt 127.0.0.1:8888
{% for backend in haproxy_backends %}
backend bk_{{ backend }}
{% if haproxy_backends[backend]["httpchk"] is defined %}
option httpchk {{ haproxy_backends[backend]["httpchk"] }}
{% endif %}
{% for server_def in haproxy_backends[backend]["server_defs"] %}
server {{ server_def }}
{% endfor %}
{% endfor %}
backend bk_stats
# statistics backend
stats uri /
stats enable
stats show-node
stats refresh 30s

View File

@ -0,0 +1,3 @@
{% for domain in haproxy_backends %}
{{- domain }} {{ domain }}
{% endfor %}