koyomi/haproxy: Init
This commit is contained in:
parent
11462ce843
commit
b418a56e09
|
@ -2,14 +2,13 @@
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
../../modules
|
../../modules
|
||||||
|
|
||||||
./services/hypervisor.nix
|
./services/hypervisor.nix
|
||||||
|
./services/haproxy.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
sbruder = {
|
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 =
|
rules =
|
||||||
|
|
|
@ -11,6 +11,14 @@ in
|
||||||
hardening.enable = lib.mkEnableOption "nginx hardening";
|
hardening.enable = lib.mkEnableOption "nginx hardening";
|
||||||
privacy.enable = (lib.mkEnableOption "nginx privacy options") // { default = true; };
|
privacy.enable = (lib.mkEnableOption "nginx privacy options") // { default = true; };
|
||||||
recommended.enable = (lib.mkEnableOption "recommended 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 [
|
config = lib.mkMerge [
|
||||||
|
@ -39,5 +47,22 @@ in
|
||||||
recommendedTlsSettings = lib.mkDefault true;
|
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