diff --git a/machines/core-security/default.nix b/machines/core-security/default.nix index d27f94a..5cf363c 100644 --- a/machines/core-security/default.nix +++ b/machines/core-security/default.nix @@ -20,6 +20,7 @@ profiles = with profiles; [ vm-simple-network server + behind-sniproxy ]; ips = { public.ipv4 = "82.67.34.230"; diff --git a/machines/gustave/pages.nix b/machines/gustave/pages.nix index 32978df..19a7f95 100644 --- a/machines/gustave/pages.nix +++ b/machines/gustave/pages.nix @@ -4,6 +4,9 @@ config, ... }: +let + allowedUpstream = "2a01:e0a:de4:a0e1:4bb5:9275:6010:e9b5/128"; +in { age.secrets."pages-settings-file".file = ../../secrets/pages-settings-file.age; @@ -39,42 +42,62 @@ settingsFile = config.age.secrets."pages-settings-file".path; }; + networking.nftables.enable = true; + + # Only requests from the router must be accepted by proxy protocol listeners + # in order to prevent ip spoofing. + networking.firewall.extraInputRules = '' + ip6 saddr ${allowedUpstream} tcp dport 444 accept + ip6 saddr ${allowedUpstream} tcp dport 8110 accept + ''; networking.firewall.allowedTCPPorts = [ - 444 8010 ]; luj.nginx.enable = true; services.nginx = { appendHttpConfig = '' - set_real_ip_from 127.0.0.1; + set_real_ip_from ${allowedUpstream}; real_ip_header proxy_protocol; ''; defaultListen = [ + # proxy protocol listener with ipv6, which is what is used by the sniproxy { addr = "[::]"; port = 444; ssl = true; proxyProtocol = true; } + # used for certificate requests with let's encrypt { addr = "[::]"; port = 80; ssl = false; } + # listener for ipv6 clients in private infra + { + addr = "[${config.machine.meta.ips.vpn.ipv6}]"; + port = 443; + ssl = true; + } + # listener for ipv4 client in private infra { addr = config.machine.meta.ips.vpn.ipv4; port = 443; ssl = true; } + # used for certificate request with internal CA { - addr = config.machine.meta.ips.vpn.ipv4; + addr = "[${config.machine.meta.ips.vpn.ipv6}]"; port = 80; ssl = false; } ]; + # Listen to ipv6 packets coming from the internet, check the SNI + # If they are one of the declared virtualHosts, forward them to the proxy protocol listener + # for that virtualHost, else forward them to the page server streamConfig = '' map $ssl_preread_server_name $sni_upstream { hostnames; @@ -85,7 +108,7 @@ } server { - listen [::]:443; + listen [${config.machine.meta.ips.public.ipv6}]:443; ssl_preread on; proxy_pass $sni_upstream; proxy_protocol on; diff --git a/machines/nuage/default.nix b/machines/nuage/default.nix index bf1dbc1..312223e 100644 --- a/machines/nuage/default.nix +++ b/machines/nuage/default.nix @@ -19,6 +19,7 @@ profiles = with profiles; [ vm-simple-network server + behind-sniproxy ]; ips = { public.ipv4 = "82.67.34.230"; diff --git a/machines/tower/default.nix b/machines/tower/default.nix index e45151c..27b2ef5 100644 --- a/machines/tower/default.nix +++ b/machines/tower/default.nix @@ -19,6 +19,7 @@ profiles = with profiles; [ vm-simple-network server + behind-sniproxy ]; ips = { public.ipv4 = "82.67.34.230"; diff --git a/modules/irc/default.nix b/modules/irc/default.nix index aa98774..d5c2a8f 100644 --- a/modules/irc/default.nix +++ b/modules/irc/default.nix @@ -2,7 +2,7 @@ with lib; let cfg = config.luj.irc; - port = 9000; + port = 8349; in { @@ -19,6 +19,7 @@ in config = mkIf cfg.enable (mkMerge [ { services.thelounge = { + inherit port; enable = true; public = false; extraConfig.fileUpload.enable = true; diff --git a/profiles/behind-sniproxy.nix b/profiles/behind-sniproxy.nix new file mode 100644 index 0000000..10460f4 --- /dev/null +++ b/profiles/behind-sniproxy.nix @@ -0,0 +1,61 @@ +{ config, ... }: + +let + allowedUpstream = "2a01:e0a:de4:a0e1:4bb5:9275:6010:e9b5/128"; +in +{ + services.nginx = { + appendHttpConfig = '' + set_real_ip_from ${allowedUpstream}; + real_ip_header proxy_protocol; + ''; + + defaultListen = [ + # proxy protocol listener with ipv6, which is what is used by the sniproxy + { + addr = "[::]"; + port = 444; + ssl = true; + proxyProtocol = true; + } + # regular listener with ipv6, for ipv6 clients + { + addr = "[::]"; + port = 443; + ssl = true; + } + # used for certificate requests with let's encrypt + { + addr = "[::]"; + port = 80; + ssl = false; + } + # listener for ipv6 clients in private infra + { + addr = "[${config.machine.meta.ips.vpn.ipv6}]"; + port = 443; + ssl = true; + } + # listener for ipv4 client in private infra + { + addr = config.machine.meta.ips.vpn.ipv4; + port = 443; + ssl = true; + } + # used for certificate request with internal CA + { + addr = "[${config.machine.meta.ips.vpn.ipv6}]"; + port = 80; + ssl = false; + } + ]; + }; + + networking.nftables.enable = true; + # Only requests from the router must be accepted by proxy protocol listeners + # in order to prevent ip spoofing. + networking.firewall.extraInputRules = '' + ip6 saddr ${allowedUpstream} tcp dport 444 accept + ''; + +}