nixos-config/machines/koyomi/services/haproxy.nix

119 lines
3.5 KiB
Nix
Raw Permalink Normal View History

2024-05-18 15:24:41 +02:00
# SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ config, lib, pkgs, ... }:
let
baseDomain = "koyomi.sbruder.de";
backends = {
hiroshi = [
2024-08-22 23:12:58 +02:00
"bangs.sbruder.de"
2024-11-09 12:35:47 +01:00
"i7y.eu"
"languagetool.sbruder.de"
2024-11-09 12:35:47 +01:00
"phss.sbruder.de"
];
};
2024-05-18 15:24:41 +02:00
fallbackCert = pkgs.runCommandNoCC "fallback-cert" { } ''
cat > openssl.cnf << EOF
[ ca ]
default_ca = CA_default
[ CA_default ]
database = database
new_certs_dir = .
serial = serial
default_md = default
policy = policy_default
[ policy_default ]
EOF
echo 01 > serial
touch database
${pkgs.openssl}/bin/openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out fallback.key
${pkgs.openssl}/bin/openssl req -key fallback.key -new -out fallback.csr -subj "/"
${pkgs.openssl}/bin/openssl ca -batch -config openssl.cnf -in fallback.csr -keyfile fallback.key -selfsign -out fallback.crt -startdate 19700101000000Z -enddate 20380119031407Z
mkdir $out
cat fallback.{key,crt} > $out/full.pem
mv fallback.{crt,key} $out
'';
in
{
services.haproxy = {
enable = true;
config = ''
global
stats socket /var/run/haproxy/haproxy-admin.sock mode 600 level admin
stats timeout 2m
defaults
timeout client 30s
timeout server 30s
timeout connect 30s
resolvers system
parse-resolv-conf
frontend http-in
bind :80
mode http
${lib.concatStrings (lib.mapAttrsToList (name: domains: ''
use_backend http-${name} if { hdr(Host) -i ${lib.concatStringsSep " " domains} and path_beg '/.well-known/acme-challenge/' }
'') backends)}
default_backend https-redirect
frontend https-in
bind :443
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
tcp-request content reject if WAIT_END
${lib.concatStrings (lib.mapAttrsToList (name: domains: ''
use_backend https-${name} if { req.ssl_sni -i ${lib.concatStringsSep " " domains} }
'') backends)}
default_backend https-fallback
frontend v6-in
bind [::]:80
bind [::]:443 ssl crt ${fallbackCert}/full.pem
mode http
http-request return status 400 content-type text/html string "<html><body><h1>400 Bad Request</h1>For requests over IPv6, please use the address of the virtual machine directly.</body></html>"
frontend fallback
bind /var/run/haproxy/fallback.sock ssl crt ${fallbackCert}/full.pem
mode http
frontend stats
bind ${config.sbruder.wireguard.home.address}:8404
mode http
http-request use-service prometheus-exporter if { path /metrics }
stats enable
stats uri /stats
stats refresh 10s
backend https-redirect
mode http
http-request redirect scheme https
backend https-fallback
server fallback /var/run/haproxy/fallback.sock
${lib.concatStrings (lib.mapAttrsToList (name: domains: ''
backend http-${name}
mode http
server ${name} ${name}.${baseDomain}:80 resolvers system resolve-prefer ipv4 send-proxy-v2
'') backends)}
${lib.concatStrings (lib.mapAttrsToList (name: domains: ''
backend https-${name}
mode tcp
server ${name} ${name}.${baseDomain}:443 resolvers system resolve-prefer ipv4 send-proxy-v2
'') backends)}
'';
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
}