koyomi/haproxy: Init
This commit is contained in:
parent
11462ce843
commit
b418a56e09
|
@ -2,14 +2,13 @@
|
|||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
../../modules
|
||||
|
||||
./services/hypervisor.nix
|
||||
./services/haproxy.nix
|
||||
];
|
||||
|
||||
sbruder = {
|
||||
|
|
111
machines/koyomi/services/haproxy.nix
Normal file
111
machines/koyomi/services/haproxy.nix
Normal file
|
@ -0,0 +1,111 @@
|
|||
# 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 ];
|
||||
}
|
|
@ -188,6 +188,17 @@ in
|
|||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
job_name = "haproxy";
|
||||
static_configs = mkStaticTargets [
|
||||
"koyomi.vpn.sbruder.de:8404"
|
||||
];
|
||||
relabel_configs = lib.singleton {
|
||||
target_label = "instance";
|
||||
source_labels = lib.singleton "__address__";
|
||||
regex = "(.*)\\.vpn\\.sbruder\\.de:8404";
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
rules =
|
||||
|
|
|
@ -11,6 +11,14 @@ in
|
|||
hardening.enable = lib.mkEnableOption "nginx hardening";
|
||||
privacy.enable = (lib.mkEnableOption "nginx privacy options") // { default = true; };
|
||||
recommended.enable = (lib.mkEnableOption "recommended options") // { default = true; };
|
||||
proxyv4 = {
|
||||
enable = (lib.mkEnableOption "PROXY protocol for IPv4 connections");
|
||||
trustedAddresses = (lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
description = "Trusted addresses which can override the source address";
|
||||
default = [ "10.0.0.0/8" "127.0.0.0/8" "172.16.0.0/12" "192.168.0.0/16" ];
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkMerge [
|
||||
|
@ -39,5 +47,22 @@ in
|
|||
recommendedTlsSettings = lib.mkDefault true;
|
||||
};
|
||||
})
|
||||
(lib.mkIf cfg.proxyv4.enable {
|
||||
services.nginx = {
|
||||
commonHttpConfig = (lib.concatMapStrings
|
||||
(address: ''
|
||||
set_real_ip_from ${address};
|
||||
'')
|
||||
cfg.proxyv4.trustedAddresses) + ''
|
||||
real_ip_header proxy_protocol;
|
||||
'';
|
||||
defaultListen = [
|
||||
{ addr = "[::]"; port = 80; ssl = false; }
|
||||
{ addr = "0.0.0.0"; port = 80; proxyProtocol = true; ssl = false; }
|
||||
{ addr = "[::]"; port = 443; ssl = true; }
|
||||
{ addr = "0.0.0.0"; port = 443; proxyProtocol = true; ssl = true; }
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue