stura-infra/hosts/proxy/default.nix
2026-02-25 18:18:01 +01:00

225 lines
5 KiB
Nix

{
config,
lib,
pkgs,
...
}:
{
imports = [
./hardware-configuration.nix
];
networking = {
hostName = "proxy";
interfaces.ens18.ipv4.addresses = [
{
address = "141.56.51.1";
prefixLength = 24;
}
];
defaultGateway.address = "141.56.51.254";
nameservers = [
"9.9.9.9"
"1.1.1.1"
];
firewall = {
allowedTCPPorts = [
22
80
443
1005
2142
];
};
nftables = {
enable = true;
};
};
security.acme = {
certs."stura.htw-dresden.de" = {
listenHTTP = ":8888";
extraDomainNames = [
"www.stura.htw-dresden.de"
];
group = "haproxy";
# postRun = ''
# cat cert.pem key.pem > full.pem
# chmod 640 full.pem
# systemctl reload haproxy
# '';
};
};
# give haproxy access to the cert files
users.users.haproxy.extraGroups = [ "acme" ];
systemd.services.haproxy = {
after = [ "acme-finished-stura.htw-dresden.de.target" ];
wants = [ "acme-finished-stura.htw-dresden.de.target" ];
};
services = {
openssh = {
enable = true;
listenAddresses = [
{
addr = "141.56.51.1";
port = 1005;
}
];
};
haproxy =
let
forwards = {
plone = {
dest = "141.56.51.3";
domain = "stura.htw-dresden.de";
httpPort = 80;
httpsPort = 443;
};
plone_alt = {
dest = "141.56.51.3";
domain = "www.stura.htw-dresden.de";
httpPort = 80;
httpsPort = 443;
};
tix = {
dest = "141.56.51.220";
domain = "tix.htw.stura-dresden.de";
httpPort = 80;
httpsPort = 443;
};
vot = {
dest = "141.56.51.81";
domain = "vot.htw.stura-dresden.de";
httpPort = 80;
httpsPort = 443;
};
dat = {
dest = "141.56.51.81";
domain = "dat.htw.stura-dresden.de";
httpPort = 80;
httpsPort = 443;
};
pro = {
dest = "141.56.51.15";
domain = "pro.htw.stura-dresden.de";
httpPort = 80;
httpsPort = 443;
};
cloud = {
dest = "141.56.51.16";
domain = "cloud.htw.stura-dresden.de";
httpPort = 80;
httpsPort = 443;
};
wiki = {
dest = "141.56.51.13";
domain = "wiki.htw.stura-dresden.de";
httpPort = 80;
httpsPort = 443;
};
};
in{
enable = true;
config = ''
global
log /dev/log local0
maxconn 4096
# for ACME/Let's Encrypt cert + key in one file:
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
crt-base /var/lib/acme
defaults
log global
mode tcp
option tcplog
timeout connect 5s
timeout client 30s
timeout server 30s
frontend stats
bind 127.0.0.1:8404
mode http
stats enable
stats uri /stats
stats refresh 10s
stats auth admin:yourpassword
stats show-legends
stats show-node
frontend http-in
bind *:80
${
lib.foldlAttrs(prev: name: value: prev +
"acl is_${name} hdr(host) -i ${value.domain}\n"
) "" forwards
}
${
lib.foldlAttrs(prev: name: value: prev +
"use_backend ${name}_80 if is_${name}\n"
) "" forwards
}
default_backend plone_80
frontend ssh_jump_alt
bind *:2142
mode tcp
timeout client 30m
log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq dst:%[var(sess.dst)] "
use_backend ssh_srs2
# ---- SNI routing (TCP, peek at handshake) ----
frontend sni_router
bind *:443
mode tcp
tcp-request inspect-delay 1s
tcp-request content accept if { req_ssl_hello_type 1 }
# terminated here
${
lib.foldlAttrs(prev: name: value: prev +
"use_backend ${name}_443 if { req_ssl_sni -i ${value.domain} }\n"
) "" forwards
}
backend ssh_srs2
mode tcp
timeout server 30m
timeout connect 10s
option tcpka
server srs2 141.56.51.2:80 check
${
lib.foldlAttrs(prev: name: value: prev +
''
backend ${name}_80
mode http
server ${name} ${value.dest}:${builtins.toString value.httpPort}
backend ${name}_443
mode tcp
server ${name} ${value.dest}:${builtins.toString value.httpsPort} check
''
) "" forwards
}
'';
};
};
environment.systemPackages = with pkgs; [
openvpn
tcpdump
];
system.stateVersion = "25.11";
}