112 lines
3.4 KiB
Nix
112 lines
3.4 KiB
Nix
# 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 = { };
|
|
|
|
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 ];
|
|
}
|