From 2d1ce42e2397cbff8a0bf07e550f4eda4383a8c0 Mon Sep 17 00:00:00 2001 From: Julien Moutinho Date: Thu, 29 Oct 2020 12:24:36 +0100 Subject: [PATCH 01/16] nginx: small config modifs on losurdo --- machines/losurdo/nginx/sourcephile.fr/losurdo.nix | 8 +++++++- nixos/profiles/services/nginx.nix | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/machines/losurdo/nginx/sourcephile.fr/losurdo.nix b/machines/losurdo/nginx/sourcephile.fr/losurdo.nix index c0960ee..3d74149 100644 --- a/machines/losurdo/nginx/sourcephile.fr/losurdo.nix +++ b/machines/losurdo/nginx/sourcephile.fr/losurdo.nix @@ -63,7 +63,13 @@ services.nginx = { }; }; systemd.services.nginx = { - serviceConfig.LogsDirectory = lib.mkForce ["nginx/${domain}/${srv}"]; + serviceConfig = { + LogsDirectory = lib.mkForce ["nginx/${domain}/${srv}"]; + BindReadOnlyPaths = [ + "/home/julm/dl:/var/lib/nginx/julm/dl" + "/home/julm/haskell:/var/lib/nginx/julm/haskell" + ]; + }; wants = [ gnupg.secrets."nginx/sevy/htpasswd".service ]; after = [ gnupg.secrets."nginx/sevy/htpasswd".service ]; }; diff --git a/nixos/profiles/services/nginx.nix b/nixos/profiles/services/nginx.nix index d14c9f7..9cbfedb 100644 --- a/nixos/profiles/services/nginx.nix +++ b/nixos/profiles/services/nginx.nix @@ -102,6 +102,7 @@ services.nginx = { types { text/html html5; text/plain md; + text/plain dump; } '' + lib.concatStringsSep "\n" (lib.attrValues { -- 2.44.1 From affcfd09e00fb2ec74e3d515a85c05c7ec957ae4 Mon Sep 17 00:00:00 2001 From: Julien Moutinho Date: Tue, 3 Nov 2020 08:39:02 +0100 Subject: [PATCH 02/16] knot: setup knsupdate on losurdo --- flake.lock | 2 +- machines/losurdo/networking.nix | 1 + machines/losurdo/networking/nsupdate.nix | 50 +++++++++++++++ machines/losurdo/networking/upnpc.nix | 63 +++++++++++++++++++ machines/mermet/knot/autogeree.net.nix | 5 +- machines/mermet/knot/sourcephile.fr.nix | 62 ++++++++++++------ machines/mermet/nginx/sourcephile.fr.nix | 1 + .../mermet/nginx/sourcephile.fr/whoami.nix | 24 +++++++ 8 files changed, 185 insertions(+), 23 deletions(-) create mode 100644 machines/losurdo/networking/nsupdate.nix create mode 100644 machines/losurdo/networking/upnpc.nix create mode 100644 machines/mermet/nginx/sourcephile.fr/whoami.nix diff --git a/flake.lock b/flake.lock index 18e721f..d189039 100644 --- a/flake.lock +++ b/flake.lock @@ -34,7 +34,7 @@ "pass": { "flake": false, "locked": { - "narHash": "sha256-vtAPPoIhIXhM5JJBAT0piYu5GanFJcPfxqUCBjidoRo=", + "narHash": "sha256-F3SgXxJ7Z6TBeDTSvpkL8Cq9d3kCxCrCpKnj3BO7IA8=", "path": "./pass", "type": "path" }, diff --git a/machines/losurdo/networking.nix b/machines/losurdo/networking.nix index 9fd06ca..cfcaa64 100644 --- a/machines/losurdo/networking.nix +++ b/machines/losurdo/networking.nix @@ -14,6 +14,7 @@ imports = [ networking/wireguard/intranet.nix networking/wireguard/extranet.nix networking/tor.nix + networking/nsupdate.nix ]; boot.initrd.network = { diff --git a/machines/losurdo/networking/nsupdate.nix b/machines/losurdo/networking/nsupdate.nix new file mode 100644 index 0000000..8585ed6 --- /dev/null +++ b/machines/losurdo/networking/nsupdate.nix @@ -0,0 +1,50 @@ +{ pkgs, lib, config, machines, ... }: +let + inherit (config.security) gnupg; + inherit (config.users) users groups; + inherit (config.networking) domain; +in +{ +systemd.services.nsupdate = { + after = [ + "network-online.target" + gnupg.secrets."knot/tsig/${domain}/bureau1.key".service + ]; + wants = [ + gnupg.secrets."knot/tsig/${domain}/bureau1.key".service + ]; + wantedBy = [ "multi-user.target" ]; + startAt = "*:0/5"; # every 5 min + serviceConfig = { + Type = "simple"; + ExecStart = pkgs.writeShellScript "nsupdate" '' + set -eux + publicIPv4=$(${pkgs.curl}/bin/curl -s4 https://whoami.sourcephile.fr/addr || true) + publicIPv6=$(${pkgs.curl}/bin/curl -s6L https://icanhazip.com || true) + privateIPv4=$(${pkgs.miniupnpc}/bin/upnpc -s | sed -ne 's/^Local LAN ip address : //p') + ${pkgs.knot-dns}/bin/knsupdate -k ${gnupg.secrets."knot/tsig/${domain}/bureau1.key".path} < IPv4) @ A ${machines.mermet.extraArgs.ipv4} mermet A ${machines.mermet.extraArgs.ipv4} - losurdo A ${machines.losurdo.extraArgs.ipv4} autoconfig A ${machines.mermet.extraArgs.ipv4} doc A ${machines.mermet.extraArgs.ipv4} code A ${machines.mermet.extraArgs.ipv4} @@ -95,17 +100,21 @@ services.knot.zones."${domain}" = { www A ${machines.mermet.extraArgs.ipv4} lemoutona5pattes A ${machines.mermet.extraArgs.ipv4} covid19 A ${machines.mermet.extraArgs.ipv4} - openconcerto A ${machines.losurdo.extraArgs.ipv4} croc A ${machines.mermet.extraArgs.ipv4} - xmpp A ${machines.losurdo.extraArgs.ipv4} - tmp A ${machines.losurdo.extraArgs.ipv4} stun A ${machines.mermet.extraArgs.ipv4} turn A ${machines.mermet.extraArgs.ipv4} - proxy65 A ${machines.losurdo.extraArgs.ipv4} - cryptpad A ${machines.losurdo.extraArgs.ipv4} - cryptpad-api A ${machines.losurdo.extraArgs.ipv4} - cryptpad-files A ${machines.losurdo.extraArgs.ipv4} - cryptpad-sandbox A ${machines.losurdo.extraArgs.ipv4} + whoami A ${machines.mermet.extraArgs.ipv4} + + ; CNAME (Canonical Name) + losurdo CNAME bureau1 + openconcerto CNAME losurdo + xmpp CNAME losurdo + tmp CNAME losurdo + proxy65 CNAME losurdo + cryptpad CNAME losurdo + cryptpad-api CNAME losurdo + cryptpad-files CNAME losurdo + cryptpad-sandbox CNAME losurdo ; SPF (Sender Policy Framework) @ 3600 IN SPF "v=spf1 mx ip4:${machines.mermet.extraArgs.ipv4} -all" @@ -128,15 +137,30 @@ services.knot.zones."${domain}" = { }; users.groups.keys.members = [ users.knot.name ]; services.knot = { - keyFiles = [ gnupg.secrets."knot/tsig/${domain}/acme.conf".path ]; + keyFiles = [ + gnupg.secrets."knot/tsig/${domain}/acme.conf".path + gnupg.secrets."knot/tsig/${domain}/bureau1.conf".path + ]; }; -security.gnupg.secrets."knot/tsig/${domain}/acme.conf" = { - # Generated with: keymgr -t acme_${domainID} - user = users.knot.name; +security.gnupg.secrets = { + "knot/tsig/${domain}/acme.conf" = { + # Generated with: keymgr -t acme_${domainID} + user = users.knot.name; + }; + "knot/tsig/${domain}/bureau1.conf" = { + # Generated with: keymgr -t bureau1_${domainID} + user = users.knot.name; + }; }; systemd.services.knot = { - after = [ gnupg.secrets."knot/tsig/${domain}/acme.conf".service ]; - wants = [ gnupg.secrets."knot/tsig/${domain}/acme.conf".service ]; + after = [ + gnupg.secrets."knot/tsig/${domain}/acme.conf".service + gnupg.secrets."knot/tsig/${domain}/bureau1.conf".service + ]; + wants = [ + gnupg.secrets."knot/tsig/${domain}/acme.conf".service + gnupg.secrets."knot/tsig/${domain}/bureau1.conf".service + ]; }; /* Useless since the zone is public services.unbound.extraConfig = '' diff --git a/machines/mermet/nginx/sourcephile.fr.nix b/machines/mermet/nginx/sourcephile.fr.nix index c282baa..0ca0981 100644 --- a/machines/mermet/nginx/sourcephile.fr.nix +++ b/machines/mermet/nginx/sourcephile.fr.nix @@ -7,6 +7,7 @@ imports = map (m: import m {inherit domain;}) [ sourcephile.fr/lemoutona5pattes.nix sourcephile.fr/covid19.nix sourcephile.fr/public-inbox.nix + sourcephile.fr/whoami.nix ]; security.acme.certs."${domain}" = { postRun = "systemctl reload nginx"; diff --git a/machines/mermet/nginx/sourcephile.fr/whoami.nix b/machines/mermet/nginx/sourcephile.fr/whoami.nix new file mode 100644 index 0000000..0eafcda --- /dev/null +++ b/machines/mermet/nginx/sourcephile.fr/whoami.nix @@ -0,0 +1,24 @@ +{ domain, ... }: +{ pkgs, lib, config, ... }: +let inherit (config) networking; + inherit (config.services) nginx; + srv = "whoami"; +in +{ +services.nginx = { + virtualHosts."${srv}" = { + serverName = "${srv}.${domain}"; + forceSSL = true; + useACMEHost = domain; + root = "/var/empty"; + extraConfig = '' + access_log off; + error_log /var/log/nginx/${domain}/${srv}/error.log warn; + keepalive_requests 0; + default_type text/plain; + ''; + locations."/addr".return = "200 $remote_addr\\n"; + }; +}; +systemd.services.nginx.serviceConfig.LogsDirectory = lib.mkForce ["nginx/${domain}/${srv}"]; +} -- 2.44.1 From 0eb882744b97ce448d56773133ea0856efe55d7a Mon Sep 17 00:00:00 2001 From: Julien Moutinho Date: Tue, 3 Nov 2020 15:31:58 +0100 Subject: [PATCH 03/16] upnpc: use DHCP and UPnP on losurdo --- machines/losurdo/networking.nix | 9 +- machines/losurdo/networking/nftables.nix | 8 +- machines/losurdo/networking/ssh.nix | 7 ++ machines/losurdo/networking/upnpc.nix | 104 +++++++++++++---------- machines/losurdo/nginx.nix | 3 + machines/losurdo/prosody.nix | 5 ++ machines/mermet/knot/sourcephile.fr.nix | 2 +- 7 files changed, 86 insertions(+), 52 deletions(-) diff --git a/machines/losurdo/networking.nix b/machines/losurdo/networking.nix index cfcaa64..5e54934 100644 --- a/machines/losurdo/networking.nix +++ b/machines/losurdo/networking.nix @@ -15,6 +15,7 @@ imports = [ networking/wireguard/extranet.nix networking/tor.nix networking/nsupdate.nix + networking/upnpc.nix ]; boot.initrd.network = { @@ -48,6 +49,7 @@ boot.kernelParams = map ]; */ /* DIY network config, but a right one */ +/* boot.initrd.preLVMCommands = '' set -x @@ -71,6 +73,7 @@ boot.initrd.preLVMCommands = '' set +x ''; +*/ # Workaround https://github.com/NixOS/nixpkgs/issues/56822 #boot.initrd.kernelModules = [ "ipv6" ]; @@ -91,11 +94,11 @@ networking = { useDHCP = false; enableIPv6 = true; + /* defaultGateway = { address = lanIPv4Gateway; interface = "enp5s0"; }; - /* defaultGateway6 = { address = lanIPv6Gateway; interface = "enp5s0"; @@ -120,10 +123,10 @@ system.activationScripts.ipv6 = '' ''; */ networking.interfaces.enp5s0 = { - useDHCP = false; + useDHCP = true; + /* ipv4.addresses = [ { address = lanIPv4; prefixLength = 24; } ]; - /* ipv4.routes = [ { address = networking.defaultGateway.address; prefixLength = 32; } ]; ipv6.addresses = [ { address = lanIPv6; prefixLength = 64; } { address = "fe80::1"; prefixLength = 10; } diff --git a/machines/losurdo/networking/nftables.nix b/machines/losurdo/networking/nftables.nix index 22f020f..291c97d 100644 --- a/machines/losurdo/networking/nftables.nix +++ b/machines/losurdo/networking/nftables.nix @@ -14,6 +14,11 @@ networking.nftables = { enable = true; ruleset = lib.mkBefore '' table inet filter { + # A set containing the udp port(s) to which SSDP replies are allowed. + set ssdp_out { + type inet_service + timeout 5s + } set lograte4 { type ipv4_addr; size 65535; flags dynamic; } set lograte6 { type ipv6_addr; size 65535; flags dynamic; } chain block { @@ -164,7 +169,6 @@ networking.nftables = { # which do not have an associated connection. #ip daddr 224.0.0.251 udp dport 5353 counter accept comment "mDNS" - #ip daddr 239.255.255.250 udp dport 1900 counter accept comment "UPnP" #ip saddr 0.0.0.0/32 counter accept comment "DHCP" #ip udp sport 67 udp dport 68 counter accept comment "DHCP" @@ -178,7 +182,6 @@ networking.nftables = { ip6 nexthdr ipv6-icmp log level err prefix "net2fw: icmpv6: catch all: " counter reject ip6 daddr ff02::fb udp dport 5353 counter accept comment "mDNS" - ip6 daddr ff02::f udp dport 1900 counter accept comment "UPnP" ''} ip saddr 224.0.0.0/4 counter goto smurf @@ -230,7 +233,6 @@ networking.nftables = { ct state { related, established } accept ip protocol icmp counter accept - ip daddr 224.0.0.0/4 udp dport 1900 counter accept comment "UPnP" meta skuid 0 udp dport 33434-33523 counter accept comment "traceroute" ${lib.optionalString networking.enableIPv6 '' diff --git a/machines/losurdo/networking/ssh.nix b/machines/losurdo/networking/ssh.nix index 480c337..08b51c2 100644 --- a/machines/losurdo/networking/ssh.nix +++ b/machines/losurdo/networking/ssh.nix @@ -25,4 +25,11 @@ boot.initrd.network.ssh = { authorizedKeys = users.root.openssh.authorizedKeys.keys; hostKeys = [ "/root/initrd/ssh.key" ]; }; +services.upnpc.redirections = [ + { port = 22; externalPort = 10022; protocol = "TCP"; } # SSH + { port = 2222; protocol = "TCP"; } # SSH (boot) + { port = 60000; protocol = "UDP"; } # Mosh + { port = 60001; protocol = "UDP"; } # Mosh + { port = 60002; protocol = "UDP"; } # Mosh +]; } diff --git a/machines/losurdo/networking/upnpc.nix b/machines/losurdo/networking/upnpc.nix index cdb2748..4953d47 100644 --- a/machines/losurdo/networking/upnpc.nix +++ b/machines/losurdo/networking/upnpc.nix @@ -1,63 +1,77 @@ { pkgs, lib, config, machines, ... }: let + inherit (lib) types; + inherit (config) networking; inherit (config.security) gnupg; inherit (config.users) users groups; inherit (config.networking) domain; + inherit (config.services) upnpc; in { -options = { +options.services.upnpc = { + redirections = lib.mkOption { + default = []; + type = types.listOf (types.submodule ({config, ...}: { + options = { + port = lib.mkOption { + type = types.port; + }; + externalPort = lib.mkOption { + type = types.port; + default = config.port; + }; + protocol = lib.mkOption { + type = with types; enum ["TCP" "UDP"]; + default = "TCP"; + }; + duration = lib.mkOption { + type = types.int; + default = 0; + }; + }; + })); + }; }; config = { -networking.nftables.ruleset = '' - # Create a set for remembering the port on which ssdp replies will be received - add set filter ssdp_out {type inet_service \; timeout 5s \;} - # Create a rule for accepting any ssdp packets going to a remembered port. - add rule filter net2fw udp dport @ssdp_out accept - # Create a rule for adding the ports to the set - add rule filter fw2net ip daddr 239.255.255.250 udp dport 1900 set add udp sport @ssdp_out - '' + lib.optionalString networking.enableIPv6 '' - # The same for ipv6 - add rule filter fw2net ip6 daddr {FF02::C, FF05::C, FF08::C, FF0E::C} udp dport 1900 set add udp sport @ssdp_out - ''; - -/* -systemd.services.nsupdate = { - after = [ - "network-online.target" - gnupg.secrets."knot/tsig/${domain}/bureau1.key".service - ]; - wants = [ - gnupg.secrets."knot/tsig/${domain}/bureau1.key".service - ]; +systemd.services.upnpc = { + after = [ "network-online.target" ]; wantedBy = [ "multi-user.target" ]; - startAt = "*:0/5"; + #startAt = "*:0/5"; serviceConfig = { Type = "simple"; - ExecStart = pkgs.writeShellScript "nsupdate" '' - set -eux - ip=$(${pkgs.curl}/bin/curl -s4 https://whoami.sourcephile.fr/addr) - test -n "$ip" - ${pkgs.knot-dns}/bin/knsupdate -k ${gnupg.secrets."knot/tsig/${domain}/bureau1.key".path} < Date: Wed, 4 Nov 2020 16:00:01 +0100 Subject: [PATCH 04/16] upnpc: fix port opening and dynamic DNS --- machines/losurdo.nix | 1 - machines/losurdo/fail2ban.nix | 4 ++-- machines/losurdo/networking/nsupdate.nix | 6 +++--- machines/losurdo/networking/ssh.nix | 4 +++- machines/losurdo/networking/upnpc.nix | 17 ++++++++++++----- machines/losurdo/nginx.nix | 16 +++++++++------- .../losurdo/nginx/sourcephile.fr/cryptpad.nix | 6 +----- .../losurdo/nginx/sourcephile.fr/losurdo.nix | 10 ++-------- machines/mermet/fail2ban.nix | 4 ++-- machines/mermet/knot/sourcephile.fr.nix | 2 +- 10 files changed, 35 insertions(+), 35 deletions(-) diff --git a/machines/losurdo.nix b/machines/losurdo.nix index a0d34ed..db91ec9 100644 --- a/machines/losurdo.nix +++ b/machines/losurdo.nix @@ -5,7 +5,6 @@ { system = "x86_64-linux"; extraArgs = { - ipv4 = "80.67.180.251"; wireguard = rec { wg-intra = { ipv4 = "192.168.42.2"; diff --git a/machines/losurdo/fail2ban.nix b/machines/losurdo/fail2ban.nix index 27a0a14..8bc3b78 100644 --- a/machines/losurdo/fail2ban.nix +++ b/machines/losurdo/fail2ban.nix @@ -22,8 +22,8 @@ services.fail2ban = { ignoreIP = [ machines.mermet.extraArgs.ipv4 machines.mermet.extraArgs.wireguard.wg-intra.ipv4 - machines.losurdo.extraArgs.ipv4 - "198.252.154.1" # wren.riseup.net + "losurdo.sourcephile.fr" + "vpn.riseup.net" ]; jails = { DEFAULT = '' diff --git a/machines/losurdo/networking/nsupdate.nix b/machines/losurdo/networking/nsupdate.nix index 8585ed6..4851635 100644 --- a/machines/losurdo/networking/nsupdate.nix +++ b/machines/losurdo/networking/nsupdate.nix @@ -30,14 +30,14 @@ systemd.services.nsupdate = { ''${publicIPv4:+update add bureau1 300 A $publicIPv4} update delete bureau1 AAAA ''${publicIPv6:+update add bureau1 300 AAAA $publicIPv6} - update delete lan.bureau1 A - ''${privateIPv4:+update add lan.bureau1 300 A $privateIPv4} + update delete lan.losurdo A + ''${privateIPv4:+update add lan.losurdo 300 A $privateIPv4} show send EOF ''; Restart = "on-failure"; - #RestartSec = "5s"; + RestartSec = "30s"; DynamicUser = true; User = users."nsupdate".name; }; diff --git a/machines/losurdo/networking/ssh.nix b/machines/losurdo/networking/ssh.nix index 08b51c2..1a68090 100644 --- a/machines/losurdo/networking/ssh.nix +++ b/machines/losurdo/networking/ssh.nix @@ -9,6 +9,8 @@ systemd.services.ssh-mermet-reverse = { wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "simple"; + # Require services.openssh.gatewayPorts = "clientspecified"; + # on the target. ExecStart = ''${pkgs.openssh}/bin/ssh -v -g -N -T \ -o ServerAliveInterval=10 \ -o ExitOnForwardFailure=yes \ @@ -26,7 +28,7 @@ boot.initrd.network.ssh = { hostKeys = [ "/root/initrd/ssh.key" ]; }; services.upnpc.redirections = [ - { port = 22; externalPort = 10022; protocol = "TCP"; } # SSH + { port = 22; protocol = "TCP"; } # SSH { port = 2222; protocol = "TCP"; } # SSH (boot) { port = 60000; protocol = "UDP"; } # Mosh { port = 60001; protocol = "UDP"; } # Mosh diff --git a/machines/losurdo/networking/upnpc.nix b/machines/losurdo/networking/upnpc.nix index 4953d47..5e8b482 100644 --- a/machines/losurdo/networking/upnpc.nix +++ b/machines/losurdo/networking/upnpc.nix @@ -36,9 +36,11 @@ config = { systemd.services.upnpc = { after = [ "network-online.target" ]; wantedBy = [ "multi-user.target" ]; - #startAt = "*:0/5"; + startAt = "*:0/15"; serviceConfig = { Type = "simple"; + # Note that one may need to upnpc -d $externalPort $port + # if $externalPort is already mapped ExecStart = "${pkgs.miniupnpc}/bin/upnpc -r" + lib.concatMapStrings (r: " ${toString r.port} ${toString r.externalPort} ${r.protocol}") upnpc.redirections; @@ -55,21 +57,26 @@ networking.nftables.ruleset = '' add rule inet filter net2fw udp dport @ssdp_out \ counter accept comment "SSDP answer" add rule inet filter fw2net \ - skuid ${users.upnpc.name} \ + skuid {${users.upnpc.name},${users.nsupdate.name}} \ + tcp dport 1900 \ + counter accept \ + comment "SSDP automatic opening" + add rule inet filter fw2net \ + skuid {${users.upnpc.name},${users.nsupdate.name}} \ ip daddr 239.255.255.250 udp dport 1900 \ set add udp sport @ssdp_out \ comment "SSDP automatic opening" add rule inet filter fw2net \ - skuid ${users.upnpc.name} \ + skuid {${users.upnpc.name},${users.nsupdate.name}} \ ip daddr 239.255.255.250 udp dport 1900 \ counter accept comment "SSDP" '' + lib.optionalString networking.enableIPv6 '' add rule inet filter fw2net \ - skuid ${users.upnpc.name} \ + skuid {${users.upnpc.name},${users.nsupdate.name}} \ ip6 daddr {FF02::C, FF05::C, FF08::C, FF0E::C} udp dport 1900 \ set add udp sport @ssdp_out comment "SSDP automatic opening" add rule inet filter fw2net \ - skuid ${users.upnpc.name} \ + skuid {${users.upnpc.name},${users.nsupdate.name}} \ ip6 daddr {FF02::C, FF05::C, FF08::C, FF0E::C} udp dport 1900 \ counter accept comment "SSDP" ''; diff --git a/machines/losurdo/nginx.nix b/machines/losurdo/nginx.nix index 1899422..1568105 100644 --- a/machines/losurdo/nginx.nix +++ b/machines/losurdo/nginx.nix @@ -11,11 +11,12 @@ imports = [ users.groups."acme".members = [nginx.user]; users.groups."transmission".members = [nginx.user]; networking.nftables.ruleset = '' + add rule inet filter net2fw tcp dport 80 counter accept comment "HTTP" add rule inet filter net2fw tcp dport 443 counter accept comment "HTTPS" - add rule inet filter net2fw tcp dport 8443 counter accept comment "HTTPS" ''; services.upnpc.redirections = [ - { port = 8443; protocol = "TCP"; } + { port = 80; protocol = "TCP"; } + { port = 443; protocol = "TCP"; } ]; services.nginx = { enable = true; @@ -28,13 +29,14 @@ services.nginx = { addresses = [ "127.0.0.1:53" ]; valid = ""; }; - /* virtualHosts."_" = { - listen = [ { addr = "0.0.0.0"; port = 8443; ssl = true; } ]; - onlySSL = true; - #forceSSL = true; + default = true; + extraConfig = '' + # Connection closed without response + return 444; + ''; + forceSSL = true; useACMEHost = networking.domain; }; - */ }; } diff --git a/machines/losurdo/nginx/sourcephile.fr/cryptpad.nix b/machines/losurdo/nginx/sourcephile.fr/cryptpad.nix index 9cf6470..4130ee3 100644 --- a/machines/losurdo/nginx/sourcephile.fr/cryptpad.nix +++ b/machines/losurdo/nginx/sourcephile.fr/cryptpad.nix @@ -173,12 +173,8 @@ systemd.services.nginx = { services.nginx.virtualHosts.${main_domain} = { serverAliases = [ sandbox_domain ]; - listen = [ - { addr="0.0.0.0"; port = 443; ssl = true; } - { addr="[::]"; port = 443; ssl = true; } - ]; - useACMEHost = domain; forceSSL = true; + useACMEHost = domain; # DOC: https://github.com/xwiki-labs/cryptpad/blob/master/docs/example.nginx.conf root = "${pkgs.cryptpad}/lib/node_modules/cryptpad"; diff --git a/machines/losurdo/nginx/sourcephile.fr/losurdo.nix b/machines/losurdo/nginx/sourcephile.fr/losurdo.nix index 3d74149..18f55c0 100644 --- a/machines/losurdo/nginx/sourcephile.fr/losurdo.nix +++ b/machines/losurdo/nginx/sourcephile.fr/losurdo.nix @@ -30,15 +30,9 @@ security.gnupg.secrets."tor/auth/julm" = {}; services.nginx = { virtualHosts."${srv}.${domain}" = { serverAliases = [ domain "${onion}.onion" ]; - listen = [ - { addr="127.0.0.1"; port = 80; ssl = false; } - { addr="[::1]"; port = 80; ssl = false; } - { addr="0.0.0.0"; port = 8443; ssl = true; } - { addr="[::]"; port = 8443; ssl = true; } - ]; #onlySSL = true; - #forceSSL = true; - addSSL = true; + #addSSL = true; + forceSSL = true; useACMEHost = domain; root = "/var/lib/nginx"; extraConfig = '' diff --git a/machines/mermet/fail2ban.nix b/machines/mermet/fail2ban.nix index eaa3270..b6dc9a0 100644 --- a/machines/mermet/fail2ban.nix +++ b/machines/mermet/fail2ban.nix @@ -22,8 +22,8 @@ services.fail2ban = { packageFirewall = pkgs.nftables; ignoreIP = [ machines.mermet.extraArgs.ipv4 - machines.losurdo.extraArgs.ipv4 - "198.252.154.1" # wren.riseup.net + "losurdo.sourcephile.fr" + "vpn.riseup.net" ]; jails = { DEFAULT = '' diff --git a/machines/mermet/knot/sourcephile.fr.nix b/machines/mermet/knot/sourcephile.fr.nix index 0301d32..3a42b6e 100644 --- a/machines/mermet/knot/sourcephile.fr.nix +++ b/machines/mermet/knot/sourcephile.fr.nix @@ -30,7 +30,7 @@ services.knot.zones."${domain}" = { action: update update-owner: name update-owner-match: equal - update-owner-name: [bureau1, lan.bureau1] + update-owner-name: [bureau1, lan.losurdo] update-type: [A, AAAA] zone: -- 2.44.1 From 15b9cc9144e8b5660b6f292f39c8969d224c42e3 Mon Sep 17 00:00:00 2001 From: Julien Moutinho Date: Wed, 4 Nov 2020 16:00:34 +0100 Subject: [PATCH 05/16] nftables: allow gemini output --- machines/losurdo/networking/nftables.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/machines/losurdo/networking/nftables.nix b/machines/losurdo/networking/nftables.nix index 291c97d..1685d5a 100644 --- a/machines/losurdo/networking/nftables.nix +++ b/machines/losurdo/networking/nftables.nix @@ -78,6 +78,7 @@ networking.nftables = { chain fw2net { tcp dport { 80, 443 } counter accept comment "HTTP" udp dport 123 skuid ${users.systemd-timesync.name} counter accept comment "NTP" + tcp dport 1965 counter accept comment "Gemini" tcp dport 9418 counter accept comment "Git" # Some .nix append rules here with: add rule inet filter fw2net ... -- 2.44.1 From df4d09546bf707448655758668c37d1fc123386c Mon Sep 17 00:00:00 2001 From: Julien Moutinho Date: Wed, 4 Nov 2020 16:01:16 +0100 Subject: [PATCH 06/16] nginx: fix binding of paths --- machines/losurdo/nginx/sourcephile.fr/losurdo.nix | 2 +- machines/mermet/nginx/sourcephile.fr/lemoutona5pattes.nix | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/machines/losurdo/nginx/sourcephile.fr/losurdo.nix b/machines/losurdo/nginx/sourcephile.fr/losurdo.nix index 18f55c0..8df0448 100644 --- a/machines/losurdo/nginx/sourcephile.fr/losurdo.nix +++ b/machines/losurdo/nginx/sourcephile.fr/losurdo.nix @@ -61,7 +61,7 @@ systemd.services.nginx = { LogsDirectory = lib.mkForce ["nginx/${domain}/${srv}"]; BindReadOnlyPaths = [ "/home/julm/dl:/var/lib/nginx/julm/dl" - "/home/julm/haskell:/var/lib/nginx/julm/haskell" + "/home/julm/work/sourcephile/haskell:/var/lib/nginx/julm/haskell" ]; }; wants = [ gnupg.secrets."nginx/sevy/htpasswd".service ]; diff --git a/machines/mermet/nginx/sourcephile.fr/lemoutona5pattes.nix b/machines/mermet/nginx/sourcephile.fr/lemoutona5pattes.nix index be06654..34c59b3 100644 --- a/machines/mermet/nginx/sourcephile.fr/lemoutona5pattes.nix +++ b/machines/mermet/nginx/sourcephile.fr/lemoutona5pattes.nix @@ -6,12 +6,15 @@ let srv = "lemoutona5pattes"; in { +systemd.services.nginx.serviceConfig = { + BindPaths = [ "/home/julm/work/sourcephile/${srv}:/www" ]; +}; services.nginx = { virtualHosts."${srv}" = { serverName = "${srv}.${domain}"; forceSSL = true; useACMEHost = domain; - root = "/home/julm/www/${srv}"; + root = "/www"; extraConfig = '' access_log /var/log/nginx/${domain}/${srv}/access.log json buffer=32k; error_log /var/log/nginx/${domain}/${srv}/error.log warn; -- 2.44.1 From 8ae06c931f5af399b6385c4e9b14fb74487a311e Mon Sep 17 00:00:00 2001 From: Julien Moutinho Date: Fri, 6 Nov 2020 12:33:56 +0100 Subject: [PATCH 07/16] hostapd: enable WiFi on losurdo --- machines/losurdo.nix | 2 +- machines/losurdo/networking.nix | 4 +- machines/losurdo/networking/nftables.nix | 9 ++ machines/losurdo/networking/wireless.nix | 100 ++++++++++++++++ machines/losurdo/system.nix | 1 - machines/losurdo/unbound.nix | 146 +++++++++++++++++++++++ nixos/profiles/hardware/dl10j.nix | 3 + 7 files changed, 260 insertions(+), 5 deletions(-) create mode 100644 machines/losurdo/networking/wireless.nix create mode 100644 machines/losurdo/unbound.nix diff --git a/machines/losurdo.nix b/machines/losurdo.nix index db91ec9..dec007b 100644 --- a/machines/losurdo.nix +++ b/machines/losurdo.nix @@ -21,7 +21,6 @@ extraArgs = { modules = [ (inputs.nixpkgs + "/nixos/modules/profiles/hardened.nix") ../nixos/defaults.nix - ../nixos/profiles/services/unbound.nix losurdo/acme.nix losurdo/debug.nix losurdo/fail2ban.nix @@ -37,6 +36,7 @@ modules = [ losurdo/syncoid.nix losurdo/system.nix losurdo/transmission.nix + losurdo/unbound.nix losurdo/users.nix (inputs.secrets + "/machines/losurdo/users.nix") ]; diff --git a/machines/losurdo/networking.nix b/machines/losurdo/networking.nix index 5e54934..1c235cf 100644 --- a/machines/losurdo/networking.nix +++ b/machines/losurdo/networking.nix @@ -16,6 +16,7 @@ imports = [ networking/tor.nix networking/nsupdate.nix networking/upnpc.nix + networking/wireless.nix ]; boot.initrd.network = { @@ -134,7 +135,4 @@ networking.interfaces.enp5s0 = { ipv6.routes = [ { address = networking.defaultGateway6.address; prefixLength = 64; } ]; */ }; -networking.interfaces.wlp4s0 = { - useDHCP = false; -}; } diff --git a/machines/losurdo/networking/nftables.nix b/machines/losurdo/networking/nftables.nix index 1685d5a..f5cfff7 100644 --- a/machines/losurdo/networking/nftables.nix +++ b/machines/losurdo/networking/nftables.nix @@ -83,6 +83,15 @@ networking.nftables = { # Some .nix append rules here with: add rule inet filter fw2net ... } + chain wifi2fw { + # Some .nix append rules here with: add rule inet filter wifi2fw ... + } + chain fw2wifi { + # Some .nix append rules here with: add rule inet filter fw2wifi ... + } + chain fwd-wifi { + # Some .nix append rules here with: add rule inet filter fwd-wifi ... + } chain intra2fw { # Some .nix append rules here with: add rule inet filter intra2fw ... } diff --git a/machines/losurdo/networking/wireless.nix b/machines/losurdo/networking/wireless.nix new file mode 100644 index 0000000..cccfbf3 --- /dev/null +++ b/machines/losurdo/networking/wireless.nix @@ -0,0 +1,100 @@ +{ pkgs, lib, config, machines, ... }: +let iface = "wlp4s0"; +in +{ +networking.interfaces.${iface} = { + ipv4.addresses = [ + { address = "192.168.2.1"; prefixLength = 24; } + ]; +}; +boot.kernel.sysctl."net.ipv6.conf.${iface}.addr_gen_mode" = 1; +networking.nftables.ruleset = '' + # Hook ${iface} into relevant chains + add rule inet filter input iifname "${iface}" jump wifi2fw + add rule inet filter input iifname "${iface}" log level warn prefix "wifi2fw: " counter drop + add rule inet filter output oifname "${iface}" jump fw2wifi + add rule inet filter output oifname "${iface}" log level warn prefix "fw2wifi: " counter drop + + # ${iface} firewalling + add rule inet filter fw2wifi counter accept + add rule inet filter forward iifname "${iface}" jump fwd-wifi + + # Allow forwarding to the internet + add rule inet filter fwd-wifi oifname "enp5s0" counter accept + + # Allow networking services + add rule inet filter wifi2fw udp dport 53 counter accept comment "DNS" + add rule inet filter wifi2fw tcp dport 53 counter accept comment "DNS" + add rule inet filter wifi2fw tcp dport 67 counter accept comment "DHCP" +''; +#boot.kernel.sysctl."net.ipv4.ip_forward" = 1; + +services.unbound.extraConfig = '' + server: + interface: 192.168.2.1 + access-control: 192.168.2.0/24 allow + local-zone: "tracking.intl.miui.com" always_refuse + local-zone: sourcephile.fr typetransparent + local-data: "bureau1.sourcephile.fr A 192.168.2.1" +''; + +networking.wlanInterfaces = { + ${iface} = { + device = "phy0"; + }; +}; + +/* +networking.networkmanager.unmanaged = [ + "interface-name:phy0" + "interface-name:${iface}" +]; +*/ + +services.hostapd = { + enable = true; + logLevel = 2; + interface = iface; + hwMode = "g"; + ssid = "bureau1"; + wpa = true; + wpaPassphrase = "bidonpoissonmaisonronron"; + countryCode = "FR"; + extraConfig = '' + ''; +}; +services.dhcpd4 = { + enable = true; + interfaces = [ iface ]; + extraConfig = '' + option subnet-mask 255.255.255.0; + option broadcast-address 192.168.2.255; + option routers 192.168.2.1; + option domain-name-servers 192.168.2.1; + subnet 192.168.2.0 netmask 255.255.255.0 { + range 192.168.2.100 192.168.2.200; + } + ''; +}; + +#networking.firewall.allowedUDPPorts = [ 53 67 ]; # DNS & DHCP +/* +# Sometimes slow connection speeds are attributed to absence of haveged. +services.haveged.enable = true; +*/ + +/* + +systemd.services.wifi-relay = let inherit (pkgs) iptables gnugrep; +in { + description = "iptables rules for wifi-relay"; + after = [ "dhcpd4.service" ]; + wantedBy = [ "multi-user.target" ]; + script = '' + ${iptables}/bin/iptables -w -t nat -I POSTROUTING -s 192.168.2.0/24 ! -o wlp4s0 -j MASQUERADE + ${iptables}/bin/iptables -w -I FORWARD -i wlp4s0 -s 192.168.2.0/24 -j ACCEPT + ${iptables}/bin/iptables -w -I FORWARD -i wlan-station0 -d 192.168.2.0/24 -j ACCEPT + ''; +}; +*/ +} diff --git a/machines/losurdo/system.nix b/machines/losurdo/system.nix index 1bd19cc..b62f04d 100644 --- a/machines/losurdo/system.nix +++ b/machines/losurdo/system.nix @@ -15,7 +15,6 @@ services.logind.killUserProcesses = false; nix.gc.dates = "weekly"; nix.gc.options = "--delete-older-than 7d"; -services.unbound.enable = true; documentation.nixos = { enable = false; # NOTE: useless on a server, and CPU intensive. }; diff --git a/machines/losurdo/unbound.nix b/machines/losurdo/unbound.nix new file mode 100644 index 0000000..3b3c46f --- /dev/null +++ b/machines/losurdo/unbound.nix @@ -0,0 +1,146 @@ +{ pkgs, lib, config, ... }: +let + inherit (config.services) unbound; + inherit (config.users) users; + stateDir = "/var/lib/unbound"; +in +{ +networking.resolvconf.useLocalResolver = true; +services.unbound = { + enable = true; + # DOC: https://calomel.org/unbound_dns.html + extraConfig = '' + remote-control: + control-enable: yes + control-interface: /run/unbound/unbound.socket + + server: + log-queries: no + verbosity: 1 + interface: 127.0.0.1 + interface: ::1 + + port: 53 + + # The file which contains the listing of primary root DNS servers. + # To be updated once every six months. + root-hints: /var/lib/unbound/named.root + + # Do no answer id.server and hostname.bind queries. + hide-identity: yes + # Do not answer version.server and version.bind queries. + hide-version: yes + + # Will trust glue only if it is within the servers authority. + # Harden against out of zone rrsets, to avoid spoofing attempts. + # Hardening queries multiple name servers for the same data to make + # spoofing significantly harder and does not mandate dnssec. + harden-glue: yes + + # Require DNSSEC data for trust-anchored zones, if such data is absent, the + # zone becomes bogus. Harden against receiving dnssec-stripped data. If you + # turn it off, failing to validate dnskey data for a trustanchor will trigger + # insecure mode for that zone (like without a trustanchor). Default on, + # which insists on dnssec data for trust-anchored zones. + harden-dnssec-stripped: yes + + # Use 0x20-encoded random bits in the query to foil spoof attempts. + # http://tools.ietf.org/html/draft-vixie-dnsext-dns0x20-00 + # + # When Unbound sends a query to a remote server it sends the hostname + # string in random upper and lower characters. The remote server must + # resolve the hostname as if all the characters were lower case. The remote + # server must then send the query back to Unbound in the same random upper + # and lower characters that Unbound sent. If the characters of the hostname + # in the response are in the same format as the query then the dns-0x20 + # check is satisfied. + # Attackers hoping to poison a Unbound DNS cache must therefore guess the + # mixed-case encoding of the query and the timing of the return dns answer + # in addition to all other fields required in a DNS poisoning attack. + # dns-0x20 increases the difficulty of the attack significantly. + # + # It may result in maybe 0.4% of domains getting no answers + # due to no support on the authoritative server side + use-caps-for-id: yes + + #cache-min-ttl: 3600 + cache-max-ttl: 86400 + + # Perform prefetching of close to expired message cache entries. If a client + # requests the dns lookup and the TTL of the cached hostname is going to + # expire in less than 10% of its TTL, unbound will (1st) return the IP of the + # host to the client and (2nd) pre-fetch the DNS request from the remote DNS server. + # This method has been shown to increase the amount of cached hits by + # local clients by 10% on average. + prefetch: yes + + # Number of threads to create. 1 disables threading. + # This should equal the number of CPU cores in the machine. + num-threads: ${toString config.nix.maxJobs} + + # The number of slabs to use for cache and must be a power of 2 times the + # number of num-threads set above. more slabs reduce lock contention, + # but fragment memory usage. + msg-cache-slabs: 8 + rrset-cache-slabs: 8 + infra-cache-slabs: 8 + key-cache-slabs: 8 + + # Increase the memory size of the cache. Use roughly twice as much rrset cache + # memory as you use msg cache memory. Due to malloc overhead, the total memory + # usage is likely to rise to double (or 2.5x) the total cache memory. + rrset-cache-size: 32m + msg-cache-size: 16m + + # buffer size for UDP port 53 incoming (SO_RCVBUF socket option). This sets + # the kernel buffer larger so that no messages are lost in spikes in the traffic. + so-rcvbuf: 1m + + # Enforce privacy of these addresses. Strips them away from answers. + # It may cause DNSSEC validation to additionally mark it as bogus. + # Protects against 'DNS Rebinding' (uses browser as network proxy). + # Only 'private-domain' and 'local-data' names are allowed + # to have these private addresses. No default. + private-address: 192.168.0.0/16 + private-address: 172.16.0.0/12 + private-address: 10.0.0.0/8 + + # Allow the domain (and its subdomains) to contain private addresses. + # local-data statements are allowed to contain private addresses too. + #private-domain: "home.lan" + + # If nonzero, unwanted replies are not only reported in statistics, but also + # a running total is kept per thread. If it reaches the threshold, a warning + # is printed and a defensive action is taken, the cache is cleared to flush + # potential poison out of it. A suggested value is 10000000, the default is + # 0 (turned off). calomel.org thinks 10K is a good value. + unwanted-reply-threshold: 10000 + + # IMPORTANT FOR TESTING: If you are testing and setup NSD or BIND on + # localhost you will want to allow the resolver to send queries to localhost. + # Make sure to set do-not-query-localhost: yes. + do-not-query-localhost: yes + + # Should additional section of secure message also be kept clean of unsecure + # data. Useful to shield the users of this validator from potential bogus + # data in the additional section. All unsigned data in the additional section + # is removed from secure messages. + val-clean-additional: yes + ''; +}; +networking.nftables.ruleset = '' + add rule inet filter fw2net tcp dport 53 skuid ${users.unbound.name} counter accept comment "Unbound" + add rule inet filter fw2net udp dport 53 skuid ${users.unbound.name} counter accept comment "Unbound" +''; +systemd.services.unbound = { + serviceConfig = { + RuntimeDirectory = "unbound"; + RuntimeDirectoryMode = "0700"; + }; + preStart = '' + install -m 444 -o unbound -g nogroup \ + ${../../nixos/profiles/services/unbound/named.root} \ + /var/lib/unbound/named.root + ''; +}; +} diff --git a/nixos/profiles/hardware/dl10j.nix b/nixos/profiles/hardware/dl10j.nix index 0801457..bb36a00 100644 --- a/nixos/profiles/hardware/dl10j.nix +++ b/nixos/profiles/hardware/dl10j.nix @@ -74,6 +74,9 @@ boot.kernelParams = [ "console=tty0" ]; +# rtlwifi/rtl8188efw.bin +hardware.enableRedistributableFirmware = true; + environment.systemPackages = with pkgs; [ pciutils nvme-cli -- 2.44.1 From 72b991f97a971406de1415405a6747ec54a7cfe4 Mon Sep 17 00:00:00 2001 From: Julien Moutinho Date: Fri, 6 Nov 2020 13:26:34 +0100 Subject: [PATCH 08/16] rspamd: fix paths to DKIM keys --- machines/mermet/rspamd.nix | 10 +++++----- machines/mermet/rspamd/autogeree.net.nix | 2 +- machines/mermet/rspamd/sourcephile.fr.nix | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/machines/mermet/rspamd.nix b/machines/mermet/rspamd.nix index 362caab..f3cbfb6 100644 --- a/machines/mermet/rspamd.nix +++ b/machines/mermet/rspamd.nix @@ -8,9 +8,9 @@ let inherit (config.users) users; in { -imports = map (domain: import (./rspamd + "/${domain}.nix") {inherit domain;}) [ - "sourcephile.fr" - "autogeree.net" +imports = [ + rspamd/autogeree.net.nix + rspamd/sourcephile.fr.nix ]; options = { services.rspamd.dkimSelectorMap = lib.mkOption { @@ -31,12 +31,12 @@ services.rspamd = { locals = { "dkim_signing.conf".text = '' selector_map = ${rspamd.dkimSelectorMap}; - path = "/run/pass-secrets/rspamd/dkim/$domain/$selector.key"; + path = "/run/keys/gnupg/rspamd/dkim/$domain/$selector.key"; allow_username_mismatch = true; ''; "arc.conf".text = '' selector_map = ${rspamd.dkimSelectorMap}; - path = "/run/pass-secrets/rspamd/dkim/$domain/$selector.key"; + path = "/run/keys/gnupg/rspamd/dkim/$domain/$selector.key"; allow_username_mismatch = true; ''; "redis.conf".text = '' diff --git a/machines/mermet/rspamd/autogeree.net.nix b/machines/mermet/rspamd/autogeree.net.nix index e5f0b35..bcadc0b 100644 --- a/machines/mermet/rspamd/autogeree.net.nix +++ b/machines/mermet/rspamd/autogeree.net.nix @@ -1,8 +1,8 @@ -{ domain, ... }: { pkgs, lib, config, ... }: let inherit (config.security) gnupg; inherit (config.services) rspamd; + domain = "autogeree.net"; selector = "20200101"; in { diff --git a/machines/mermet/rspamd/sourcephile.fr.nix b/machines/mermet/rspamd/sourcephile.fr.nix index 086c51f..6eadf85 100644 --- a/machines/mermet/rspamd/sourcephile.fr.nix +++ b/machines/mermet/rspamd/sourcephile.fr.nix @@ -1,8 +1,8 @@ -{ domain, ... }: { pkgs, lib, config, ... }: let inherit (config.security) gnupg; inherit (config.services) rspamd; + domain = "sourcephile.fr"; selector = "20200101"; in { -- 2.44.1 From 4b73e8b604910b8633286efb7d111ca03a2963fb Mon Sep 17 00:00:00 2001 From: Julien Moutinho Date: Fri, 6 Nov 2020 18:29:58 +0100 Subject: [PATCH 09/16] jmtpfs: add MTP support to losurdo --- machines/losurdo/fileSystems.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/machines/losurdo/fileSystems.nix b/machines/losurdo/fileSystems.nix index 7b9faac..782d5ff 100644 --- a/machines/losurdo/fileSystems.nix +++ b/machines/losurdo/fileSystems.nix @@ -73,4 +73,8 @@ fileSystems."/mnt/key" = options = [ "auto" "nofail" "uid=1000" "gid=users" "umask=111" "dmask=007" "utf8=yes" ]; }; +environment.systemPackages = [ + pkgs.jmtpfs +]; + } -- 2.44.1 From 3d293f743f504d58e5e566903fe903105f9cfeee Mon Sep 17 00:00:00 2001 From: Julien Moutinho Date: Fri, 6 Nov 2020 22:42:25 +0100 Subject: [PATCH 10/16] syncoid: fix keys rights and known_hosts --- flake.nix | 12 +++++++++++- machines/losurdo/sanoid.nix | 1 + machines/losurdo/syncoid.nix | 35 ++++++++++++++++++++++------------- machines/losurdo/users.nix | 1 - 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/flake.nix b/flake.nix index 1fbd9e2..477e1e2 100644 --- a/flake.nix +++ b/flake.nix @@ -52,7 +52,7 @@ outputs = inputs: let */ { meta.description = "nixos/syncoid: split in multiple systemd services"; url = "https://github.com/NixOS/nixpkgs/pull/98455.diff"; - sha256 = "sha256-xJoUYJGnU/Rb26+FCUTvPyiGdf0cj8mC3s/5cac03YU="; + sha256 = "sha256-vmPzvjwAOSWqfizgDk3l6FrMD2OsG+8UpIkQvOUcXNI="; } { meta.description = "zerobin: update to v1.0.5"; url = "https://github.com/NixOS/nixpkgs/pull/98734.diff"; @@ -111,6 +111,16 @@ outputs = inputs: let then inputs.self.rev else throw "Refusing to build from a dirty Git tree!"; */ + programs.ssh.knownHosts = { + mermet = { + hostNames = [ "mermet" "mermet.sourcephile.fr" ]; + publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFvKN2sIpH782MFjaOpcty1Hs/T/TPNJpXI08H3O3oxl"; + }; + losurdo = { + hostNames = [ "losurdo" "losurdo.sourcephile.fr" ]; + publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHJkAq1T0Dxozt4RPylvWrUmeuejiG+n/owb3ucnWP9F"; + }; + }; })]; })); in diff --git a/machines/losurdo/sanoid.nix b/machines/losurdo/sanoid.nix index bab39d8..d86089a 100644 --- a/machines/losurdo/sanoid.nix +++ b/machines/losurdo/sanoid.nix @@ -41,6 +41,7 @@ services.sanoid = { use_template = [ "remote" ]; hourly = 1; daily = 7; + monthly = 0; }; "${machineName}/backup/mermet/var/www" = { use_template = [ "remote" ]; diff --git a/machines/losurdo/syncoid.nix b/machines/losurdo/syncoid.nix index 4b00ea9..4c30fc7 100644 --- a/machines/losurdo/syncoid.nix +++ b/machines/losurdo/syncoid.nix @@ -1,17 +1,26 @@ { pkgs, lib, config, machineName, machines, ... }: let inherit (config) networking; + inherit (config.services) syncoid; inherit (config.security) gnupg; - user = "backup"; in { networking.nftables.ruleset = '' - add rule inet filter fw2net tcp dport 22 ip daddr ${machines.mermet.extraArgs.ipv4} counter accept comment "SSH to mermet" + add rule inet filter fw2net \ + skuid "${syncoid.user}" \ + tcp dport 22 \ + ip daddr ${machines.mermet.extraArgs.ipv4} \ + counter accept \ + comment "SSH to mermet" ''; +security.gnupg.secrets."ssh/backup.ssh-ed25519" = { + user = syncoid.user; +}; +users.groups.keys.members = [ syncoid.user ]; services.syncoid = { enable = true; interval = "*-*-* *:05:00"; - sshKey = gnupg.secrets."ssh/${user}.ssh-ed25519".path; + sshKey = gnupg.secrets."ssh/backup.ssh-ed25519".path; commonArgs = [ "--no-sync-snap" "--create-bookmark" @@ -19,39 +28,39 @@ services.syncoid = { #"--no-stream" ]; service = { - after = [ gnupg.secrets."ssh/${user}.ssh-ed25519".service ]; - wants = [ gnupg.secrets."ssh/${user}.ssh-ed25519".service ]; + after = [ gnupg.secrets."ssh/backup.ssh-ed25519".service ]; + wants = [ gnupg.secrets."ssh/backup.ssh-ed25519".service ]; }; commands = { "${machineName}/home/julm/work" = { sendOptions = "raw"; - target = "${user}@mermet.${networking.domain}:rpool/backup/${machineName}/home/julm/work"; + target = "backup@mermet.${networking.domain}:rpool/backup/${machineName}/home/julm/work"; }; - "${user}@mermet.${networking.domain}:rpool/var/mail" = { + "backup@mermet.${networking.domain}:rpool/var/mail" = { sendOptions = "raw"; target = "${machineName}/backup/mermet/var/mail"; }; - "${user}@mermet.${networking.domain}:rpool/var/public-inbox" = { + "backup@mermet.${networking.domain}:rpool/var/public-inbox" = { sendOptions = "raw"; target = "${machineName}/backup/mermet/var/public-inbox"; }; - "${user}@mermet.${networking.domain}:rpool/var/www" = { + "backup@mermet.${networking.domain}:rpool/var/www" = { sendOptions = "raw"; target = "${machineName}/backup/mermet/var/www"; }; - "${user}@mermet.${networking.domain}:rpool/var/git" = { + "backup@mermet.${networking.domain}:rpool/var/git" = { sendOptions = "raw"; target = "${machineName}/backup/mermet/var/git"; }; - "${user}@mermet.${networking.domain}:rpool/var/redis" = { + "backup@mermet.${networking.domain}:rpool/var/redis" = { sendOptions = "raw"; target = "${machineName}/backup/mermet/var/redis"; }; - "${user}@mermet.${networking.domain}:rpool/home/julm/mail" = { + "backup@mermet.${networking.domain}:rpool/home/julm/mail" = { sendOptions = "raw"; target = "${machineName}/backup/mermet/home/julm/mail"; }; - "${user}@mermet.${networking.domain}:rpool/home/julm/log" = { + "backup@mermet.${networking.domain}:rpool/home/julm/log" = { sendOptions = "raw"; target = "${machineName}/backup/mermet/home/julm/log"; }; diff --git a/machines/losurdo/users.nix b/machines/losurdo/users.nix index 11db6be..4190a96 100644 --- a/machines/losurdo/users.nix +++ b/machines/losurdo/users.nix @@ -44,7 +44,6 @@ users = { }; }; -security.gnupg.secrets."ssh/backup.ssh-ed25519" = {}; security.gnupg.secrets."/root/.ssh/id_ed25519" = { gpg = "${gnupg.store}/ssh/root.ssh-ed25519.gpg"; }; -- 2.44.1 From 5e9393c7f4ef15126f1cbe6ae1b67a7a9ad9e48b Mon Sep 17 00:00:00 2001 From: Julien Moutinho Date: Fri, 6 Nov 2020 22:57:41 +0100 Subject: [PATCH 11/16] unbound: no longer use nixos/profiles --- Makefile | 4 ++-- machines/losurdo/unbound.nix | 2 +- machines/mermet.nix | 2 +- .../services => machines/mermet}/unbound.nix | 12 +++--------- {nixos/profiles/services/unbound => var}/named.root | 4 ++-- 5 files changed, 9 insertions(+), 15 deletions(-) rename {nixos/profiles/services => machines/mermet}/unbound.nix (93%) rename {nixos/profiles/services/unbound => var}/named.root (97%) diff --git a/Makefile b/Makefile index 7d78b7c..bda7b86 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ all: init -.PHONY: nixos/profiles/services/unbound/named.root -nixos/profiles/services/unbound/named.root: +.PHONY: var/named.root +var/named.root: mkdir -p $(@D) curl >$@ -L https://www.internic.net/domain/named.root diff --git a/machines/losurdo/unbound.nix b/machines/losurdo/unbound.nix index 3b3c46f..ec59242 100644 --- a/machines/losurdo/unbound.nix +++ b/machines/losurdo/unbound.nix @@ -139,7 +139,7 @@ systemd.services.unbound = { }; preStart = '' install -m 444 -o unbound -g nogroup \ - ${../../nixos/profiles/services/unbound/named.root} \ + ${../../var/named.root} \ /var/lib/unbound/named.root ''; }; diff --git a/machines/mermet.nix b/machines/mermet.nix index 40509ae..74f4ae5 100644 --- a/machines/mermet.nix +++ b/machines/mermet.nix @@ -22,7 +22,6 @@ extraArgs = rec { modules = [ (inputs.nixpkgs + "/nixos/modules/profiles/hardened.nix") ../nixos/defaults.nix - ../nixos/profiles/services/unbound.nix mermet/acme.nix mermet/croc.nix mermet/coturn.nix @@ -44,6 +43,7 @@ modules = [ mermet/sanoid.nix mermet/security.nix mermet/system.nix + mermet/unbound.nix mermet/users.nix (inputs.secrets + "/machines/mermet/users.nix") ]; diff --git a/nixos/profiles/services/unbound.nix b/machines/mermet/unbound.nix similarity index 93% rename from nixos/profiles/services/unbound.nix rename to machines/mermet/unbound.nix index 3bdbcc5..ec59242 100644 --- a/nixos/profiles/services/unbound.nix +++ b/machines/mermet/unbound.nix @@ -17,6 +17,8 @@ services.unbound = { server: log-queries: no verbosity: 1 + interface: 127.0.0.1 + interface: ::1 port: 53 @@ -134,19 +136,11 @@ systemd.services.unbound = { serviceConfig = { RuntimeDirectory = "unbound"; RuntimeDirectoryMode = "0700"; - # FIXME: upstream service shouldn't overwrite ExecStopPost - # so that postStop can be used. - ExecStopPost = lib.mkForce (pkgs.writeShellScript "unit-script-unbound-post-stop" '' - ${pkgs.utillinux}/bin/umount ${stateDir}/dev/random - ${pkgs.utillinux}/bin/umount ${stateDir}/run/unbound - ''); }; preStart = '' install -m 444 -o unbound -g nogroup \ - ${unbound/named.root} \ + ${../../var/named.root} \ /var/lib/unbound/named.root - mkdir -p ${stateDir}/run/unbound - ${pkgs.utillinux}/bin/mount --bind -n /run/unbound ${stateDir}/run/unbound ''; }; } diff --git a/nixos/profiles/services/unbound/named.root b/var/named.root similarity index 97% rename from nixos/profiles/services/unbound/named.root rename to var/named.root index 1081f07..43d3c8c 100644 --- a/nixos/profiles/services/unbound/named.root +++ b/var/named.root @@ -9,8 +9,8 @@ ; on server FTP.INTERNIC.NET ; -OR- RS.INTERNIC.NET ; -; last update: December 05, 2019 -; related version of root zone: 2019120501 +; last update: October 22, 2020 +; related version of root zone: 2020102201 ; ; FORMERLY NS.INTERNIC.NET ; -- 2.44.1 From 46a142ae004e24722b92afaa3f5433e7bd60a56d Mon Sep 17 00:00:00 2001 From: Julien Moutinho Date: Thu, 12 Nov 2020 01:51:21 +0100 Subject: [PATCH 12/16] nginx: change paths and config on losurdo --- .../losurdo/nginx/sourcephile.fr/losurdo.nix | 14 +- .../modules/services/torrent/transmission.nix | 479 ++++++++++++++++++ 2 files changed, 488 insertions(+), 5 deletions(-) create mode 100644 nixos/modules/services/torrent/transmission.nix diff --git a/machines/losurdo/nginx/sourcephile.fr/losurdo.nix b/machines/losurdo/nginx/sourcephile.fr/losurdo.nix index 8df0448..48849cb 100644 --- a/machines/losurdo/nginx/sourcephile.fr/losurdo.nix +++ b/machines/losurdo/nginx/sourcephile.fr/losurdo.nix @@ -5,6 +5,7 @@ let inherit (config.security) gnupg; inherit (config.services) nginx; srv = "losurdo"; + root = "/var/lib/nginx"; onion = "dfc66yn2fundui5yvq2ndx4nmcmbxpho4ji32tlc4cncrjvs2b5yu4id"; in { @@ -34,20 +35,22 @@ services.nginx = { #addSSL = true; forceSSL = true; useACMEHost = domain; - root = "/var/lib/nginx"; + root = root; extraConfig = '' access_log /var/log/nginx/${domain}/${srv}/access.log json buffer=32k; error_log /var/log/nginx/${domain}/${srv}/error.log warn; ''; locations."/".extraConfig = '' - autoindex off; + #autoindex on; + return 444; ''; locations."/julm".extraConfig = '' autoindex on; fancyindex on; fancyindex_exact_size off; fancyindex_name_length 255; - open_file_cache_valid 1s; + open_file_cache off; + #open_file_cache_valid 1s; ''; locations."/sevy".extraConfig = '' auth_basic "sevy's area"; @@ -60,8 +63,9 @@ systemd.services.nginx = { serviceConfig = { LogsDirectory = lib.mkForce ["nginx/${domain}/${srv}"]; BindReadOnlyPaths = [ - "/home/julm/dl:/var/lib/nginx/julm/dl" - "/home/julm/work/sourcephile/haskell:/var/lib/nginx/julm/haskell" + "/home/julm/work/sourcephile/web:${root}/julm" + "/home/julm/dl:${root}/dl" + "/home/julm/work/sourcephile/haskell:${root}/haskell" ]; }; wants = [ gnupg.secrets."nginx/sevy/htpasswd".service ]; diff --git a/nixos/modules/services/torrent/transmission.nix b/nixos/modules/services/torrent/transmission.nix new file mode 100644 index 0000000..49c7de2 --- /dev/null +++ b/nixos/modules/services/torrent/transmission.nix @@ -0,0 +1,479 @@ +{ config, lib, pkgs, options, ... }: + +with lib; + +let + cfg = config.services.transmission; + inherit (config.environment) etc; + apparmor = config.security.apparmor; + rootDir = "/run/transmission"; + settingsDir = ".config/transmission-daemon"; + downloadsDir = "Downloads"; + incompleteDir = ".incomplete"; + watchDir = "watchdir"; + settingsFormat = pkgs.formats.json {}; + settingsFile = settingsFormat.generate "settings.json" cfg.settings; +in +{ + imports = [ + (mkRenamedOptionModule ["services" "transmission" "port"] + ["services" "transmission" "settings" "rpc-port"]) + (mkAliasOptionModule ["services" "transmission" "openFirewall"] + ["services" "transmission" "openPeerPorts"]) + ]; + options = { + services.transmission = { + enable = mkEnableOption ''the headless Transmission BitTorrent daemon. + + Transmission daemon can be controlled via the RPC interface using + transmission-remote, the WebUI (http://127.0.0.1:9091/ by default), + or other clients like stig or tremc. + + Torrents are downloaded to /${downloadsDir} by default and are + accessible to users in the "transmission" group''; + + settings = mkOption { + description = '' + Settings whose options overwrite fields in + .config/transmission-daemon/settings.json + (each time the service starts). + + See Transmission's Wiki + for documentation of settings not explicitely covered by this module. + ''; + default = {}; + type = types.submodule { + freeformType = settingsFormat.type; + options.download-dir = mkOption { + type = types.path; + default = "${cfg.home}/${downloadsDir}"; + description = "Directory where to download torrents."; + }; + options.incomplete-dir = mkOption { + type = types.path; + default = "${cfg.home}/${incompleteDir}"; + description = '' + When enabled with + services.transmission.home + , + new torrents will download the files to this directory. + When complete, the files will be moved to download-dir + . + ''; + }; + options.incomplete-dir-enabled = mkOption { + type = types.bool; + default = true; + description = ""; + }; + options.message-level = mkOption { + type = types.ints.between 0 2; + default = 2; + description = "Set verbosity of transmission messages."; + }; + options.peer-port = mkOption { + type = types.port; + default = 51413; + description = "The peer port to listen for incoming connections."; + }; + options.peer-port-random-high = mkOption { + type = types.port; + default = 65535; + description = '' + The maximum peer port to listen to for incoming connections + when is enabled. + ''; + }; + options.peer-port-random-low = mkOption { + type = types.port; + default = 65535; + description = '' + The minimal peer port to listen to for incoming connections + when is enabled. + ''; + }; + options.peer-port-random-on-start = mkOption { + type = types.bool; + default = false; + description = "Randomize the peer port."; + }; + options.rpc-bind-address = mkOption { + type = types.str; + default = "127.0.0.1"; + example = "0.0.0.0"; + description = '' + Where to listen for RPC connections. + Use \"0.0.0.0\" to listen on all interfaces. + ''; + }; + options.rpc-port = mkOption { + type = types.port; + default = 9091; + description = "The RPC port to listen to."; + }; + options.script-torrent-done-enabled = mkOption { + type = types.bool; + default = false; + description = '' + Whether to run + + at torrent completion. + ''; + }; + options.script-torrent-done-filename = mkOption { + type = types.nullOr types.path; + default = null; + description = "Executable to be run at torrent completion."; + }; + options.umask = mkOption { + type = types.int; + default = 2; + description = '' + Sets transmission's file mode creation mask. + See the umask(2) manpage for more information. + Users who want their saved torrents to be world-writable + may want to set this value to 0. + Bear in mind that the json markup language only accepts numbers in base 10, + so the standard umask(2) octal notation "022" is written in settings.json as 18. + ''; + }; + options.utp-enabled = mkOption { + type = types.bool; + default = true; + description = '' + Whether to enable Micro Transport Protocol (µTP). + ''; + }; + options.watch-dir = mkOption { + type = types.path; + default = "${cfg.home}/${watchDir}"; + description = "Watch a directory for torrent files and add them to transmission."; + }; + options.watch-dir-enabled = mkOption { + type = types.bool; + default = false; + description = ''Whether to enable the + . + ''; + }; + options.trash-original-torrent-files = mkOption { + type = types.bool; + default = false; + description = ''Whether to delete torrents added from the + . + ''; + }; + }; + }; + + downloadDirPermissions = mkOption { + type = types.str; + default = "770"; + example = "775"; + description = '' + The permissions set by systemd.activationScripts.transmission-daemon + on the directories + and . + Note that you may also want to change + . + ''; + }; + + home = mkOption { + type = types.path; + default = "/var/lib/transmission"; + description = '' + The directory where Transmission will create ${settingsDir}. + as well as ${downloadsDir}/ unless + is changed, + and ${incompleteDir}/ unless + is changed. + ''; + }; + + user = mkOption { + type = types.str; + default = "transmission"; + description = "User account under which Transmission runs."; + }; + + group = mkOption { + type = types.str; + default = "transmission"; + description = "Group account under which Transmission runs."; + }; + + credentialsFile = mkOption { + type = types.path; + description = '' + Path to a JSON file to be merged with the settings. + Useful to merge a file which is better kept out of the Nix store + because it contains sensible data like + . + ''; + default = "/dev/null"; + example = "/var/lib/secrets/transmission/settings.json"; + }; + + openPeerPorts = mkEnableOption "opening of the peer port(s) in the firewall"; + + openRPCPort = mkEnableOption "opening of the RPC port in the firewall"; + + performanceNetParameters = mkEnableOption ''tweaking of kernel parameters + to open many more connections at the same time. + + Note that you may also want to increase + . + And be aware that these settings are quite aggressive + and might not suite your regular desktop use. + For instance, SSH sessions may time out more easily''; + }; + }; + + config = mkIf cfg.enable { + # Note that using systemd.tmpfiles would not work here + # because it would fail when creating a directory + # with a different owner than its parent directory, by saying: + # Detected unsafe path transition /home/foo → /home/foo/Downloads during canonicalization of /home/foo/Downloads + # when /home/foo is not owned by cfg.user. + # Note also that using an ExecStartPre= wouldn't work either + # because BindPaths= needs these directories before. + system.activationScripts.transmission-daemon = '' + install -d -m 700 '${cfg.home}/${settingsDir}' + chown -R '${cfg.user}:${cfg.group}' ${cfg.home}/${settingsDir} + install -d -m '${cfg.downloadDirPermissions}' -o '${cfg.user}' -g '${cfg.group}' '${cfg.settings.download-dir}' + '' + optionalString cfg.settings.incomplete-dir-enabled '' + install -d -m '${cfg.downloadDirPermissions}' -o '${cfg.user}' -g '${cfg.group}' '${cfg.settings.incomplete-dir}' + '' + optionalString cfg.settings.watch-dir-enabled '' + install -d -m '${cfg.downloadDirPermissions}' -o '${cfg.user}' -g '${cfg.group}' '${cfg.settings.watch-dir}' + ''; + + systemd.services.transmission = { + description = "Transmission BitTorrent Service"; + after = [ "network.target" ] ++ optional apparmor.enable "apparmor.service"; + requires = optional apparmor.enable "apparmor.service"; + wantedBy = [ "multi-user.target" ]; + environment.CURL_CA_BUNDLE = etc."ssl/certs/ca-certificates.crt".source; + + serviceConfig = { + # Use "+" because credentialsFile may not be accessible to User= or Group=. + ExecStartPre = [("+" + pkgs.writeShellScript "transmission-prestart" '' + set -eu${lib.optionalString (cfg.settings.message-level >= 3) "x"} + ${pkgs.jq}/bin/jq --slurp add ${settingsFile} '${cfg.credentialsFile}' | + install -D -m 600 -o '${cfg.user}' -g '${cfg.group}' /dev/stdin \ + '${cfg.home}/${settingsDir}/settings.json' + '')]; + ExecStart="${pkgs.transmission}/bin/transmission-daemon -f"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + User = cfg.user; + Group = cfg.group; + # Create rootDir in the host's mount namespace. + RuntimeDirectory = [(baseNameOf rootDir)]; + RuntimeDirectoryMode = "755"; + # Avoid mounting rootDir in the own rootDir of ExecStart='s mount namespace. + InaccessiblePaths = ["-+${rootDir}"]; + # This is for BindPaths= and BindReadOnlyPaths= + # to allow traversal of directories they create in RootDirectory=. + UMask = "0066"; + # Using RootDirectory= makes it possible + # to use the same paths download-dir/incomplete-dir + # (which appear in user's interfaces) without requiring cfg.user + # to have access to their parent directories, + # by using BindPaths=/BindReadOnlyPaths=. + # Note that TemporaryFileSystem= could have been used instead + # but not without adding some BindPaths=/BindReadOnlyPaths= + # that would only be needed for ExecStartPre=, + # because RootDirectoryStartOnly=true would not help. + RootDirectory = rootDir; + RootDirectoryStartOnly = true; + MountAPIVFS = true; + BindPaths = + [ "${cfg.home}/${settingsDir}" + cfg.settings.download-dir + ] ++ + optional cfg.settings.incomplete-dir-enabled + cfg.settings.incomplete-dir ++ + optional (cfg.settings.watch-dir-enabled && cfg.settings.trash-original-torrent-files) + cfg.settings.watch-dir; + BindReadOnlyPaths = [ + # No confinement done of /nix/store here like in systemd-confinement.nix, + # an AppArmor profile is provided to get a confinement based upon paths and rights. + builtins.storeDir + "/etc" + "/run" + ] ++ + optional (cfg.settings.script-torrent-done-enabled && + cfg.settings.script-torrent-done-filename != null) + cfg.settings.script-torrent-done-filename ++ + optional (cfg.settings.watch-dir-enabled && !cfg.settings.trash-original-torrent-files) + cfg.settings.watch-dir; + # The following options are only for optimizing: + # systemd-analyze security transmission + AmbientCapabilities = ""; + CapabilityBoundingSet = ""; + # ProtectClock= adds DeviceAllow=char-rtc r + DeviceAllow = ""; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateMounts = true; + PrivateNetwork = mkDefault false; + PrivateTmp = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + # ProtectHome=true would not allow BindPaths= to work accross /home, + # and ProtectHome=tmpfs would break statfs(), + # preventing transmission-daemon to report the available free space. + # However, RootDirectory= is used, so this is not a security concern + # since there would be nothing in /home but any BindPaths= wanted by the user. + ProtectHome = "read-only"; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectSystem = "strict"; + RemoveIPC = true; + # AF_UNIX may become usable one day: + # https://github.com/transmission/transmission/issues/441 + RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallFilter = [ + "@system-service" + # Groups in @system-service which do not contain a syscall + # listed by perf stat -e 'syscalls:sys_enter_*' transmission-daemon -f + # in tests, and seem likely not necessary for transmission-daemon. + "~@aio" "~@chown" "~@keyring" "~@memlock" "~@resources" "~@setuid" "~@timer" + # In the @privileged group, but reached when querying infos through RPC (eg. with stig). + "quotactl" + ]; + SystemCallArchitectures = "native"; + SystemCallErrorNumber = "EPERM"; + }; + }; + + # It's useful to have transmission in path, e.g. for remote control + environment.systemPackages = [ pkgs.transmission ]; + + users.users = optionalAttrs (cfg.user == "transmission") ({ + transmission = { + group = cfg.group; + uid = config.ids.uids.transmission; + description = "Transmission BitTorrent user"; + home = cfg.home; + }; + }); + + users.groups = optionalAttrs (cfg.group == "transmission") ({ + transmission = { + gid = config.ids.gids.transmission; + }; + }); + + networking.firewall = mkMerge [ + (mkIf cfg.openPeerPorts ( + if cfg.settings.peer-port-random-on-start + then + { allowedTCPPortRanges = + [ { from = cfg.settings.peer-port-random-low; + to = cfg.settings.peer-port-random-high; + } + ]; + allowedUDPPortRanges = + [ { from = cfg.settings.peer-port-random-low; + to = cfg.settings.peer-port-random-high; + } + ]; + } + else + { allowedTCPPorts = [ cfg.settings.peer-port ]; + allowedUDPPorts = [ cfg.settings.peer-port ]; + } + )) + (mkIf cfg.openRPCPort { allowedTCPPorts = [ cfg.settings.rpc-port ]; }) + ]; + + boot.kernel.sysctl = mkMerge [ + # Transmission uses a single UDP socket in order to implement multiple uTP sockets, + # and thus expects large kernel buffers for the UDP socket, + # https://trac.transmissionbt.com/browser/trunk/libtransmission/tr-udp.c?rev=11956. + # at least up to the values hardcoded here: + (mkIf cfg.settings.utp-enabled { + "net.core.rmem_max" = mkDefault "4194304"; # 4MB + "net.core.wmem_max" = mkDefault "1048576"; # 1MB + }) + (mkIf cfg.performanceNetParameters { + # Increase the number of available source (local) TCP and UDP ports to 49151. + # Usual default is 32768 60999, ie. 28231 ports. + # Find out your current usage with: ss -s + "net.ipv4.ip_local_port_range" = mkDefault "16384 65535"; + # Timeout faster generic TCP states. + # Usual default is 600. + # Find out your current usage with: watch -n 1 netstat -nptuo + "net.netfilter.nf_conntrack_generic_timeout" = mkDefault 60; + # Timeout faster established but inactive connections. + # Usual default is 432000. + "net.netfilter.nf_conntrack_tcp_timeout_established" = mkDefault 600; + # Clear immediately TCP states after timeout. + # Usual default is 120. + "net.netfilter.nf_conntrack_tcp_timeout_time_wait" = mkDefault 1; + # Increase the number of trackable connections. + # Usual default is 262144. + # Find out your current usage with: conntrack -C + "net.netfilter.nf_conntrack_max" = mkDefault 1048576; + }) + ]; + + security.apparmor.policies."bin.transmission-daemon".profile = '' + include + ${pkgs.transmission}/bin/transmission-daemon { + include + include + include + include "${pkgs.apparmorRulesFromClosure {} [pkgs.transmission]}" + include + + r @{PROC}/sys/kernel/random/uuid, + r @{PROC}/sys/vm/overcommit_memory, + r @{PROC}/@{pid}/environ, + r @{PROC}/@{pid}/mounts, + rwk /tmp/tr_session_id_*, + r ${config.systemd.services.transmission.environment.CURL_CA_BUNDLE}, + r /run/systemd/resolve/stub-resolv.conf, + + owner rw ${cfg.home}/${settingsDir}/**, + rw ${cfg.settings.download-dir}/**, + ${optionalString cfg.settings.incomplete-dir-enabled '' + rw ${cfg.settings.incomplete-dir}/**, + ''} + ${optionalString cfg.settings.watch-dir-enabled '' + r${optionalString cfg.settings.trash-original-torrent-files "w"} ${cfg.settings.watch-dir}/**, + ''} + profile dirs { + rw ${cfg.settings.download-dir}/**, + ${optionalString cfg.settings.incomplete-dir-enabled '' + rw ${cfg.settings.incomplete-dir}/**, + ''} + ${optionalString cfg.settings.watch-dir-enabled '' + r${optionalString cfg.settings.trash-original-torrent-files "w"} ${cfg.settings.watch-dir}/**, + ''} + } + + ${optionalString (cfg.settings.script-torrent-done-enabled && + cfg.settings.script-torrent-done-filename != null) '' + # Stack transmission_directories profile on top of + # any existing profile for script-torrent-done-filename + # FIXME: to be tested as I'm not sure it works well with NoNewPrivileges= + # https://gitlab.com/apparmor/apparmor/-/wikis/AppArmorStacking#seccomp-and-no_new_privs + px ${cfg.settings.script-torrent-done-filename} -> &@{dirs}, + ''} + } + ''; + security.apparmor.includes."local/bin.transmission-daemon" = ""; + }; + + meta.maintainers = with lib.maintainers; [ julm ]; +} -- 2.44.1 From f15b724ea5ff81ca597db5a230a667e750564ac5 Mon Sep 17 00:00:00 2001 From: Julien Moutinho Date: Thu, 12 Nov 2020 01:52:44 +0100 Subject: [PATCH 13/16] nix: polish comments --- machines/mermet/networking/ssh.nix | 2 +- nixos/profiles/hardware/apu2e4.nix | 2 +- nixos/profiles/hardware/dl10j.nix | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/machines/mermet/networking/ssh.nix b/machines/mermet/networking/ssh.nix index 1be605e..8cfb261 100644 --- a/machines/mermet/networking/ssh.nix +++ b/machines/mermet/networking/ssh.nix @@ -1,7 +1,7 @@ { pkgs, lib, config, ... }: { networking.nftables.ruleset = '' - add rule inet filter net2fw tcp dport {10022} counter accept comment "Reverse SSH" + add rule inet filter net2fw tcp dport 10022 counter accept comment "SSH (reverse to losurdo)" ''; services.openssh.gatewayPorts = "clientspecified"; } diff --git a/nixos/profiles/hardware/apu2e4.nix b/nixos/profiles/hardware/apu2e4.nix index b8070a6..d5733b5 100644 --- a/nixos/profiles/hardware/apu2e4.nix +++ b/nixos/profiles/hardware/apu2e4.nix @@ -50,7 +50,7 @@ boot.initrd = { "uas" # Ethernet driver "igb" - # Made the AES modules available at initrd, + # Make the AES modules available at initrd, # to speedup the deciphering of the root. "aes_x86_64" "aesni_intel" diff --git a/nixos/profiles/hardware/dl10j.nix b/nixos/profiles/hardware/dl10j.nix index bb36a00..cd79383 100644 --- a/nixos/profiles/hardware/dl10j.nix +++ b/nixos/profiles/hardware/dl10j.nix @@ -53,7 +53,7 @@ boot.initrd = { "xhci_hcd" # USB #"i915" # VGA "igb" # Ethernet - # Made the AES modules available at initrd, + # Make the AES modules available at initrd, # to speedup the deciphering of the root. "aes_x86_64" "aesni_intel" -- 2.44.1 From 826e3168c4a8bb0f91d57abdad8d95cadf4f8b5f Mon Sep 17 00:00:00 2001 From: Julien Moutinho Date: Sat, 14 Nov 2020 05:40:13 +0100 Subject: [PATCH 14/16] murmur: add mumble server on mermet --- machines/mermet.nix | 1 + machines/mermet/knot/sourcephile.fr.nix | 1 + machines/mermet/murmur.nix | 39 +++++++++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 machines/mermet/murmur.nix diff --git a/machines/mermet.nix b/machines/mermet.nix index 74f4ae5..b914e90 100644 --- a/machines/mermet.nix +++ b/machines/mermet.nix @@ -33,6 +33,7 @@ modules = [ mermet/hardware.nix mermet/knot.nix #mermet/mlmmj.nix + mermet/murmur.nix mermet/networking.nix mermet/nginx.nix mermet/openldap.nix diff --git a/machines/mermet/knot/sourcephile.fr.nix b/machines/mermet/knot/sourcephile.fr.nix index 3a42b6e..7146cff 100644 --- a/machines/mermet/knot/sourcephile.fr.nix +++ b/machines/mermet/knot/sourcephile.fr.nix @@ -115,6 +115,7 @@ services.knot.zones."${domain}" = { cryptpad-api CNAME losurdo cryptpad-files CNAME losurdo cryptpad-sandbox CNAME losurdo + mumble CNAME mermet ; SPF (Sender Policy Framework) @ 3600 IN SPF "v=spf1 mx ip4:${machines.mermet.extraArgs.ipv4} -all" diff --git a/machines/mermet/murmur.nix b/machines/mermet/murmur.nix new file mode 100644 index 0000000..41a5e3e --- /dev/null +++ b/machines/mermet/murmur.nix @@ -0,0 +1,39 @@ +{ pkgs, lib, config, ... }: +let + inherit (config.users) users; + domain = config.networking.domain; +in +{ +networking.nftables.ruleset = '' + add rule inet filter net2fw udp dport 64738 counter accept comment "Murmur" + add rule inet filter net2fw tcp dport 64738 counter accept comment "Murmur" +''; +users.groups.acme.members = [ users."murmur".name ]; +security.acme.certs."${domain}" = { + postRun = "systemctl reload murmur"; +}; +systemd.services.postgresql = { + wants = [ "acme-selfsigned-${domain}.service" "acme-${domain}.service"]; + after = [ "acme-selfsigned-${domain}.service" ]; +}; +services.murmur = { + enable = true; + welcometext = '' + Bienvenue sur mumble.sourcephile.fr + Avant de commencer à parler, rejoignez un salon ou bien créez en un nouveau ! + ''; + bonjour = false; + registerName = "sourcephile"; + registerHostname = "mumble.${domain}"; + #registerUrl = "https://${domain}"; + #registerLocation = "FR"; + allowHtml = true; + users = 42; + sslKey = "/var/lib/acme/${domain}/full.pem"; + extraConfig = '' + username = "[A-Za-z0-9_-]{2,12}" + channelnestinglimit = 10 + opusthreshold = 50 + ''; +}; +} -- 2.44.1 From c77567f04329606a1755e07414d3178436b460ac Mon Sep 17 00:00:00 2001 From: Julien Moutinho Date: Sat, 14 Nov 2020 05:44:22 +0100 Subject: [PATCH 15/16] freeciv: add experimental service --- machines/losurdo.nix | 1 + machines/losurdo/freeciv.nix | 33 ++++ machines/mermet/knot/sourcephile.fr.nix | 1 + nixos/modules.nix | 2 + nixos/modules/services/freeciv.nix | 190 ++++++++++++++++++++++++ 5 files changed, 227 insertions(+) create mode 100644 machines/losurdo/freeciv.nix create mode 100644 nixos/modules/services/freeciv.nix diff --git a/machines/losurdo.nix b/machines/losurdo.nix index dec007b..742177c 100644 --- a/machines/losurdo.nix +++ b/machines/losurdo.nix @@ -25,6 +25,7 @@ modules = [ losurdo/debug.nix losurdo/fail2ban.nix losurdo/fileSystems.nix + losurdo/freeciv.nix losurdo/hardware.nix losurdo/networking.nix losurdo/nginx.nix diff --git a/machines/losurdo/freeciv.nix b/machines/losurdo/freeciv.nix new file mode 100644 index 0000000..1c2f0ac --- /dev/null +++ b/machines/losurdo/freeciv.nix @@ -0,0 +1,33 @@ +{ pkgs, lib, config, ... }: +let + inherit (config.users) users; + domain = config.networking.domain; + inherit (config.services) freeciv; +in +{ +networking.nftables.ruleset = '' + add rule inet filter net2fw tcp dport ${toString freeciv.settings.port} counter accept comment "Freeciv" +''; +users.users.freeciv.isSystemUser = true; +users.groups.acme.members = [ users."freeciv".name ]; +security.acme.certs."${domain}" = { + postRun = "systemctl reload freeciv"; +}; +systemd.services.postgresql = { + wants = [ "acme-selfsigned-${domain}.service" "acme-${domain}.service"]; + after = [ "acme-selfsigned-${domain}.service" ]; +}; +services.upnpc.redirections = [ + { port = freeciv.settings.port; protocol = "TCP"; } +]; +services.freeciv = { + enable = true; + settings = { + Announce = "none"; + Guests = true; + Newusers = true; + auth = true; + debug = 3; + }; +}; +} diff --git a/machines/mermet/knot/sourcephile.fr.nix b/machines/mermet/knot/sourcephile.fr.nix index 7146cff..ea03a69 100644 --- a/machines/mermet/knot/sourcephile.fr.nix +++ b/machines/mermet/knot/sourcephile.fr.nix @@ -116,6 +116,7 @@ services.knot.zones."${domain}" = { cryptpad-files CNAME losurdo cryptpad-sandbox CNAME losurdo mumble CNAME mermet + freeciv CNAME losurdo ; SPF (Sender Policy Framework) @ 3600 IN SPF "v=spf1 mx ip4:${machines.mermet.extraArgs.ipv4} -all" diff --git a/nixos/modules.nix b/nixos/modules.nix index a5d4400..c5eaa90 100644 --- a/nixos/modules.nix +++ b/nixos/modules.nix @@ -14,6 +14,7 @@ imports = [ #/home/julm/src/nix/nixpkgs/.git-worktree/transmission/nixos/modules/services/torrent/transmission.nix #/home/julm/src/nix/nixpkgs/nixos/modules/services/torrent/transmission.nix #modules/services/mail/mlmmj.nix + modules/services/freeciv.nix ]; disabledModules = [ "services/mail/mlmmj.nix" @@ -24,5 +25,6 @@ disabledModules = [ #"services/networking/biboumi.nix" #"services/networking/croc.nix" #"services/torrent/transmission.nix" + "services/freeciv.nix" ]; } diff --git a/nixos/modules/services/freeciv.nix b/nixos/modules/services/freeciv.nix new file mode 100644 index 0000000..e6fdbe8 --- /dev/null +++ b/nixos/modules/services/freeciv.nix @@ -0,0 +1,190 @@ +{ config, lib, pkgs, ... }: +with lib; +let + cfg = config.services.freeciv; + inherit (config.users) groups; + rootDir = "/run/freeciv"; + settingsFormat = { + type = with lib.types; let + valueType = nullOr (oneOf [ + bool int float str + (listOf valueType) + #(attrsOf valueType) + ]) // { + description = "freeciv-server params"; + }; + in valueType; + generate = name: value: + let mkParam = k: v: + if v == null then [] + else if isBool v then if v then [("--"+k)] else [] + else [("--"+k) v]; + mkParams = k: v: map (mkParam k) (if isList v then v else [v]); + in escapeShellArgs (concatLists (concatLists (mapAttrsToList mkParams value))); + }; +in +{ + options = { + services.freeciv = { + enable = mkEnableOption ''freeciv''; + settings = mkOption { + description = '' + Parameters of freeciv-server. + ''; + default = {}; + type = types.submodule { + freeformType = settingsFormat.type; + options.Announce = mkOption { + type = types.enum ["IPv4" "IPv6" "none"]; + default = "none"; + description = "Announce game in LAN using given protocol."; + }; + options.auth = mkEnableOption "server authentication"; + options.Database = mkOption { + type = types.nullOr types.str; + apply = pkgs.writeText "auth.conf"; + default = '' + [fcdb] + backend="sqlite" + database="/var/lib/freeciv/auth.sqlite" + ''; + description = "Enable database connection with given configuration."; + }; + options.debug = mkOption { + type = types.ints.between 0 3; + default = 0; + description = "Set debug log level."; + }; + options.exit-on-end = mkEnableOption "exit instead of restarting when a game ends."; + options.Guests = mkEnableOption "guests to login if auth is enabled"; + options.Newusers = mkEnableOption "new users to login if auth is enabled"; + options.port = mkOption { + type = types.port; + default = 5556; + description = "Listen for clients on given port"; + }; + options.quitidle = mkOption { + type = types.nullOr types.int; + default = null; + description = "Quit if no players for given time in seconds."; + }; + options.read = mkOption { + type = types.lines; + apply = v: pkgs.writeTextDir "read.serv" v + "/read"; + default = '' + /fcdb lua sqlite_createdb() + ''; + description = "Startup script."; + }; + options.saves = mkOption { + type = types.nullOr types.str; + default = "/var/lib/freeciv/saves/"; + description = '' + Save games to given directory, + a sub-directory named after the starting date of the service + will me inserted to preserve older saves. + ''; + }; + }; + }; + openFirewall = mkEnableOption "opening in the firewall of the port listening for clients"; + }; + }; + config = mkIf cfg.enable { + users.groups.freeciv = {}; + # Use with: + # journalctl -u freeciv.service -f -o cat & + # cat >/run/freeciv.stdin + # load saves/2020-11-14_05-22-27/freeciv-T0005-Y-3750-interrupted.sav.bz2 + systemd.sockets.freeciv = { + wantedBy = [ "sockets.target" ]; + socketConfig = { + ListenFIFO = "/run/freeciv.stdin"; + SocketGroup = groups.freeciv.name; + SocketMode = "660"; + RemoveOnStop = true; + }; + }; + systemd.services.freeciv = { + description = "Freeciv Service"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + environment.HOME = "/var/lib/freeciv"; + serviceConfig = { + Restart = "on-failure"; + RestartSec = "5s"; + #StandardInput = "fd:freeciv.socket"; + StandardInput = "socket"; + StandardOutput = "journal"; + StandardError = "journal"; + ExecStart = pkgs.writeShellScript "freeciv-server" ('' + set -eux + savedir=$(date +%Y-%m-%d_%H-%M-%S) + trap "rmdir -p ${escapeShellArg cfg.settings.saves}/$savedir" EXIT + '' + "${pkgs.freeciv}/bin/freeciv-server" + + " " + optionalString (cfg.settings.saves != null) + (concatStringsSep " " [ "--saves" "${escapeShellArg cfg.settings.saves}/$savedir" ]) + + " " + settingsFormat.generate "freeciv-server" (cfg.settings // { saves = null; })); + DynamicUser = true; + # Create rootDir in the host's mount namespace. + RuntimeDirectory = [(baseNameOf rootDir)]; + RuntimeDirectoryMode = "755"; + StateDirectory = [ "freeciv" ]; + WorkingDirectory = "/var/lib/freeciv"; + # Avoid mounting rootDir in the own rootDir of ExecStart='s mount namespace. + InaccessiblePaths = ["-+${rootDir}"]; + # This is for BindPaths= and BindReadOnlyPaths= + # to allow traversal of directories they create in RootDirectory=. + UMask = "0066"; + RootDirectory = rootDir; + RootDirectoryStartOnly = true; + MountAPIVFS = true; + BindReadOnlyPaths = [ + builtins.storeDir + "/etc" + "/run" + ]; + # The following options are only for optimizing: + # systemd-analyze security freeciv + AmbientCapabilities = ""; + CapabilityBoundingSet = ""; + # ProtectClock= adds DeviceAllow=char-rtc r + DeviceAllow = ""; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateMounts = true; + PrivateNetwork = mkDefault false; + PrivateTmp = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectSystem = "strict"; + RemoveIPC = true; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallFilter = [ + "@system-service" + # Groups in @system-service which do not contain a syscall listed by: + # perf stat -x, 2>perf.log -e 'syscalls:sys_enter_*' freeciv-server + # in tests, and seem likely not necessary for freeciv-server. + "~@aio" "~@chown" "~@ipc" "~@keyring" "~@memlock" + "~@resources" "~@setuid" "~@sync" "~@timer" + ]; + SystemCallArchitectures = "native"; + SystemCallErrorNumber = "EPERM"; + }; + }; + networking.firewall = mkIf cfg.openFirewall + { allowedTCPPorts = [ cfg.settings.port ]; }; + }; + meta.maintainers = with lib.maintainers; [ julm ]; +} -- 2.44.1 From 6719a3d80501fb83b44836c7dd84203e7d40ae8c Mon Sep 17 00:00:00 2001 From: Julien Moutinho Date: Mon, 16 Nov 2020 04:39:37 +0100 Subject: [PATCH 16/16] openvpn: add riseup in net namespace --- machines/losurdo/networking.nix | 1 + machines/losurdo/networking/nftables.nix | 179 +------------- machines/losurdo/networking/openvpn.nix | 5 + .../losurdo/networking/openvpn/riseup.nix | 194 +++++++++++++++ .../networking/openvpn/riseup/cacert.pem | 32 +++ .../networking/openvpn/riseup/client.pem | 54 ++++ machines/losurdo/transmission.nix | 26 +- machines/mermet/networking/nftables.nix | 104 +------- nixos/modules.nix | 4 + nixos/modules/services/networking/netns.nix | 14 ++ nixos/modules/services/networking/openvpn.nix | 233 ++++++++++++++++++ var/nftables/filter.txt | 175 +++++++++++++ 12 files changed, 737 insertions(+), 284 deletions(-) create mode 100644 machines/losurdo/networking/openvpn.nix create mode 100644 machines/losurdo/networking/openvpn/riseup.nix create mode 100644 machines/losurdo/networking/openvpn/riseup/cacert.pem create mode 100644 machines/losurdo/networking/openvpn/riseup/client.pem create mode 100644 nixos/modules/services/networking/netns.nix create mode 100644 nixos/modules/services/networking/openvpn.nix create mode 100644 var/nftables/filter.txt diff --git a/machines/losurdo/networking.nix b/machines/losurdo/networking.nix index 1c235cf..7f2bb67 100644 --- a/machines/losurdo/networking.nix +++ b/machines/losurdo/networking.nix @@ -17,6 +17,7 @@ imports = [ networking/nsupdate.nix networking/upnpc.nix networking/wireless.nix + networking/openvpn.nix ]; boot.initrd.network = { diff --git a/machines/losurdo/networking/nftables.nix b/machines/losurdo/networking/nftables.nix index f5cfff7..3b93121 100644 --- a/machines/losurdo/networking/nftables.nix +++ b/machines/losurdo/networking/nftables.nix @@ -14,58 +14,7 @@ networking.nftables = { enable = true; ruleset = lib.mkBefore '' table inet filter { - # A set containing the udp port(s) to which SSDP replies are allowed. - set ssdp_out { - type inet_service - timeout 5s - } - set lograte4 { type ipv4_addr; size 65535; flags dynamic; } - set lograte6 { type ipv6_addr; size 65535; flags dynamic; } - chain block { - add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "block: " - add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "block: " - counter drop - } - chain ping-flood { - add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "ping-flood: " - add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "ping-flood: " - counter drop - } - chain smurf { - add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "smurf: " - add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "smurf: " - counter drop - } - chain bogus-tcp { - add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "bogus-tcp: " - add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "bogus-tcp: " - counter drop - } - chain syn-flood { - add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "syn-flood: " - add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "syn-flood: " - counter drop - } - chain check-tcp { - tcp flags syn tcp option maxseg size != 536-65535 counter goto bogus-tcp - tcp flags & (ack|fin) == fin counter goto bogus-tcp - tcp flags & (ack|psh) == psh counter goto bogus-tcp - tcp flags & (ack|urg) == urg counter goto bogus-tcp - tcp flags & (fin|ack) == fin counter goto bogus-tcp - tcp flags & (fin|rst) == (fin|rst) counter goto bogus-tcp - tcp flags & (fin|psh|ack) == (fin|psh) counter goto bogus-tcp - tcp flags & (syn|fin) == (syn|fin) counter goto bogus-tcp comment "SYN-FIN scan" - tcp flags & (syn|rst) == (syn|rst) counter goto bogus-tcp comment "SYN-RST scan" - tcp flags == (fin|syn|rst|psh|ack|urg) counter goto bogus-tcp comment "XMAS scan" - tcp flags == 0x0 counter goto bogus-tcp comment "NULL scan" - tcp flags == (fin|urg|psh) counter goto bogus-tcp - tcp flags == (fin|urg|psh|syn) counter goto bogus-tcp comment "NMAP-ID" - tcp flags == (fin|urg|syn|rst|ack) counter goto bogus-tcp - - ct state new tcp flags != syn counter goto bogus-tcp - tcp sport 0 tcp flags & (fin|syn|rst|ack) == syn counter goto bogus-tcp - tcp flags & (fin|syn|rst|ack) == syn counter limit rate over 30/second burst 60 packets goto syn-flood - } + include "${../../../var/nftables/filter.txt}" chain net2fw { #udp dport mdns ip6 daddr ff02::fb counter accept comment "Accept mDNS" #udp dport mdns ip daddr 224.0.0.251 counter accept comment "Accept mDNS" @@ -104,43 +53,6 @@ networking.nftables = { chain extra2fw { # Some .nix append rules here with: add rule inet filter extra2fw ... } - chain accept-icmpv6 { - # Traffic That Must Not Be Dropped - # https://tools.ietf.org/html/rfc4890#section-4.4.1 - icmpv6 type destination-unreachable counter accept - icmpv6 type packet-too-big counter accept - icmpv6 type time-exceeded counter accept - icmpv6 type parameter-problem counter accept - - # Address Configuration and Router Selection messages - # (must be received with hop limit = 255) - icmpv6 type nd-router-solicit ip6 hoplimit 255 counter accept - ip6 nexthdr ipv6-icmp icmpv6 type nd-router-advert ip6 hoplimit 255 counter accept - icmpv6 type nd-neighbor-solicit ip6 hoplimit 255 counter accept - icmpv6 type nd-neighbor-advert ip6 hoplimit 255 counter accept - icmpv6 type nd-redirect ip6 hoplimit 255 log level warn prefix "icmpv6: nd-redirect: " counter drop - icmpv6 type ind-neighbor-solicit ip6 hoplimit 255 counter accept - icmpv6 type ind-neighbor-advert ip6 hoplimit 255 counter accept - - # Link-local multicast receiver notification messages - # (must have link-local source address) - icmpv6 type mld-listener-query ip6 saddr fe80::/10 counter accept - icmpv6 type mld-listener-report ip6 saddr fe80::/10 counter accept - icmpv6 type mld-listener-done ip6 saddr fe80::/10 counter accept - # https://tools.ietf.org/html/rfc3810 Multicast Listener Discovery Version 2 (MLDv2) for IPv6 - icmpv6 type mld2-listener-report ip6 saddr fe80::/10 counter accept - - # SEND Certificate Path notification messages - # (must be received with hop limit = 255) - icmpv6 type 148 ip6 hoplimit 255 counter accept comment "certificate-path-solicitation" - icmpv6 type 149 ip6 hoplimit 255 counter accept comment "certificate-path-advertisement" - - # Multicast Router Discovery messages - # (must have link-local source address and hop limit = 1) - icmpv6 type 151 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-advertisement" - icmpv6 type 152 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-solicitation" - icmpv6 type 153 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-termination" - } chain input { type filter hook input priority filter @@ -149,54 +61,10 @@ networking.nftables = { iifname lo accept jump check-tcp - ct state { established, related } accept - - # Connectivity checking messages - # (multicast) ping - ip protocol icmp icmp type echo-reply counter accept - - ${lib.optionalString networking.enableIPv6 '' - # drop packets with rh0 headers - rt type 0 jump block - rt type 0 jump block - rt type 0 jump block - - # (multicast) ping - ip6 nexthdr ipv6-icmp icmpv6 type echo-reply counter accept - - #ip6 daddr fe80::/64 udp dport 546 counter accept comment "DHCPv6" - ''} - + jump accept-connectivity-input ct state invalid counter drop - ip protocol icmp icmp type destination-unreachable counter accept - ip protocol icmp icmp type time-exceeded counter accept - ip protocol icmp icmp type parameter-problem counter accept - ip protocol icmp icmp type echo-request limit rate over 10/second burst 20 packets goto ping-flood - ip protocol icmp icmp type echo-request counter accept - # echo-reply is handled before invalid packets to allow multicast ping - # which do not have an associated connection. - - #ip daddr 224.0.0.251 udp dport 5353 counter accept comment "mDNS" - #ip saddr 0.0.0.0/32 counter accept comment "DHCP" - #ip udp sport 67 udp dport 68 counter accept comment "DHCP" - - ${lib.optionalString networking.enableIPv6 '' - ip6 nexthdr ipv6-icmp jump accept-icmpv6 - - # Connectivity checking messages - icmpv6 type echo-request counter accept - # echo-reply is handled before invalid because of multicast - - ip6 nexthdr ipv6-icmp log level err prefix "net2fw: icmpv6: catch all: " counter reject - - ip6 daddr ff02::fb udp dport 5353 counter accept comment "mDNS" - ''} - - ip saddr 224.0.0.0/4 counter goto smurf - fib saddr type broadcast counter goto smurf - # admin services tcp dport 22 counter accept comment "SSH" udp dport 60000-61000 counter accept comment "Mosh" @@ -208,31 +76,7 @@ networking.nftables = { policy drop ct state { related, established } accept - - ip protocol icmp icmp type destination-unreachable counter accept - ip protocol icmp icmp type time-exceeded counter accept - ip protocol icmp icmp type parameter-problem counter accept - ip protocol icmp icmp type echo-request counter accept - - ${lib.optionalString networking.enableIPv6 '' - # Traffic That Must Not Be Dropped - # https://tools.ietf.org/html/rfc4890#section-4.3.1 - ip6 nexthdr ipv6-icmp icmpv6 type destination-unreachable counter accept - ip6 nexthdr ipv6-icmp icmpv6 type packet-too-big counter accept - ip6 nexthdr ipv6-icmp icmpv6 type time-exceeded counter accept - ip6 nexthdr ipv6-icmp icmpv6 type parameter-problem counter accept - - # Connectivity checking messages - ip6 nexthdr ipv6-icmp icmpv6 type echo-request counter accept - ip6 nexthdr ipv6-icmp icmpv6 type echo-reply counter accept - - # Traffic That Normally Should Not Be Dropped - # https://tools.ietf.org/html/rfc4890#section-4.3.2 - ip6 nexthdr ipv6-icmp icmpv6 type 144 counter accept comment "home-agent-address-discovery-request" - ip6 nexthdr ipv6-icmp icmpv6 type 145 counter accept comment "home-agent-address-discovery-reply" - ip6 nexthdr ipv6-icmp icmpv6 type 146 counter accept comment "mobile-prefix-solicitation" - ip6 nexthdr ipv6-icmp icmpv6 type 147 counter accept comment "mobile-prefix-advertisement" - ''} + jump accept-connectivity-forward } chain output { type filter hook output priority filter @@ -241,22 +85,7 @@ networking.nftables = { oifname lo accept ct state { related, established } accept - - ip protocol icmp counter accept - meta skuid 0 udp dport 33434-33523 counter accept comment "traceroute" - - ${lib.optionalString networking.enableIPv6 '' - ip6 nexthdr ipv6-icmp jump accept-icmpv6 - - # Connectivity checking messages - ip6 nexthdr ipv6-icmp icmpv6 type echo-request counter accept - ip6 nexthdr ipv6-icmp icmpv6 type echo-reply counter accept - ip6 nexthdr ipv6-icmp log level err prefix "fw2net: icmpv6: catch all: " counter reject - - ip6 daddr ff02::1:2/64 udp dport 547 counter accept comment "DHCPv6" - ''} - - ct state invalid log level warn prefix "fw2net: invalid: " counter drop + jump accept-connectivity-output tcp dport 22 counter accept comment "SSH" diff --git a/machines/losurdo/networking/openvpn.nix b/machines/losurdo/networking/openvpn.nix new file mode 100644 index 0000000..19c65b6 --- /dev/null +++ b/machines/losurdo/networking/openvpn.nix @@ -0,0 +1,5 @@ +{ +imports = [ + openvpn/riseup.nix +]; +} diff --git a/machines/losurdo/networking/openvpn/riseup.nix b/machines/losurdo/networking/openvpn/riseup.nix new file mode 100644 index 0000000..01f4733 --- /dev/null +++ b/machines/losurdo/networking/openvpn/riseup.nix @@ -0,0 +1,194 @@ +{ pkgs, lib, config, ... }: +let + ns = "riseup"; + dev = "ov-${ns}"; + inherit (config.services) openvpn; +in +{ +networking.nftables.ruleset = '' + add rule inet filter fw2net tcp dport {443,1194} counter accept comment "OpenVPN" +''; +systemd.services."openvpn-${ns}" = { + bindsTo = [ "netns@${ns}.service" ]; + requires = [ "netns@${ns}.service" ]; +}; +services.openvpn.servers = { + "${ns}" = { + config = '' + verb 3 + ca ${riseup/cacert.pem} + cert ${riseup/client.pem} + client + dev ov-${ns} + dev-type tun + persist-tun + nobind + # Useless to setup the interface + # because moving it to ${ns} will reset it + ifconfig-noexec + route-noexec + persist-key + key ${riseup/client.pem} + tls-client + remote-cert-tls server + remote 37.218.241.7 1194 tcp4 + remote 37.218.241.106 443 tcp4 + remote 163.172.126.44 443 tcp4 + remote 198.252.153.28 443 tcp4 + remote 199.58.81.143 443 tcp4 + remote 199.58.81.145 443 tcp4 + remote 212.83.143.67 443 tcp4 + remote 212.83.144.12 443 tcp4 + remote 212.83.146.228 443 tcp4 + remote 212.83.165.160 443 tcp4 + remote 212.83.182.127 443 tcp4 + remote 212.129.62.247 443 tcp4 + reneg-sec 0 + script-security 2 + up-restart + ''; + up = let dev = "ov-${ns}"; in '' + set -eux + PATH=${lib.makeBinPath [pkgs.iproute]} + ip link set dev "${dev}" up netns "${ns}" mtu "$tun_mtu" + ip netns exec "${ns}" ${pkgs.writeShellScript "route-up.sh" '' + set -eux + PATH=${lib.makeBinPath [pkgs.iproute pkgs.coreutils]} + + ip link set dev lo up + + mkdir -p /etc/netns/"${ns}" + foreign_opt_domains= + process_foreign_option () { + case "$1:$2" in + dhcp-option:DNS) echo "nameserver $3" >>/etc/netns/"${ns}"/resolv.conf ;; + dhcp-option:DOMAIN) foreign_opt_domains="$foreign_opt_domains $3" ;; + esac + } + if test ! -e /etc/netns/"${ns}"/resolv.conf; then + # add DNS settings if given in foreign options + i=1 + while + eval opt=\"\''${foreign_option_$i-}\" + [ -n "$opt" ] + do + process_foreign_option $opt + i=$(( i + 1 )) + done + for d in $foreign_opt_domains; do + printf '%s\n' "domain $1" "search $*" \ + >>/etc/netns/"${ns}"/resolv.conf + done + fi + + netmask4="''${ifconfig_netmask:-30}" + netbits6="''${ifconfig_ipv6_netbits:-112}" + if [ -n "''${ifconfig_local-}" ]; then + if [ -n "''${ifconfig_remote-}" ]; then + ip -4 addr replace \ + local "$ifconfig_local" \ + peer "$ifconfig_remote/$netmask4" \ + ''${ifconfig_broadcast:+broadcast "$ifconfig_broadcast"} \ + dev "${dev}" + else + ip -4 addr replace \ + local "$ifconfig_local/$netmask4" \ + ''${ifconfig_broadcast:+broadcast "$ifconfig_broadcast"} \ + dev "${dev}" + fi + fi + if [ -n "''${ifconfig_ipv6_local-}" ]; then + if [ -n "''${ifconfig_ipv6_remote-}" ]; then + ip -6 addr replace \ + local "$ifconfig_ipv6_local" \ + peer "$ifconfig_ipv6_remote/$netbits6" \ + dev "${dev}" + else + ip -6 addr replace \ + local "$ifconfig_ipv6_local/$netbits6" \ + dev "${dev}" + fi + fi + + ${pkgs.writeScript "ruleset" openvpn.servers.${ns}.nftables} + ''} + ''; + routeUp = '' + set -eux + PATH=${lib.makeBinPath [pkgs.iproute]} + ${pkgs.coreutils}/bin/env + ip netns exec "${ns}" ${pkgs.writeShellScript "route-up.sh" '' + set -eux + PATH=${lib.makeBinPath [pkgs.iproute]} + i=1 + while + eval net=\"\''${route_network_$i-}\" + eval mask=\"\''${route_netmask_$i-}\" + eval gw=\"\''${route_gateway_$i-}\" + eval mtr=\"\''${route_metric_$i-}\" + [ -n "$net" ] + do + ip -4 route replace "$net/$mask" via "$gw" ''${mtr:+metric "$mtr"} + i=$(( i + 1 )) + done + + if [ -n "''${route_vpn_gateway-}" ]; then + ip -4 route replace default via "$route_vpn_gateway" + fi + + i=1 + while + # There doesn't seem to be $route_ipv6_metric_ + # according to the manpage. + eval net=\"\''${route_ipv6_network_$i-}\" + eval gw=\"\''${route_ipv6_gateway_$i-}\" + [ -n "$net" ] + do + ip -6 route replace "$net" via "$gw" metric 100 + i=$(( i + 1 )) + done + + # There's no $route_vpn_gateway for IPv6. It's not + # documented if OpenVPN includes default route in + # $route_ipv6_*. Set default route to remote VPN + # endpoint address if there is one. Use higher metric + # than $route_ipv6_* routes to give preference to a + # possible default route in them. + if [ -n "''${ifconfig_ipv6_remote-}" ]; then + ip -6 route replace default \ + via "$ifconfig_ipv6_remote" metric 200 + fi + ''} + ''; + nftables = lib.mkBefore '' + #!${pkgs.nftables}/bin/nft -f + flush ruleset + table inet filter { + include "${../../../../var/nftables/filter.txt}" + chain input { + type filter hook input priority filter + policy drop + iifname lo accept + jump check-tcp + ct state { established, related } accept + jump accept-connectivity-input + jump check-broadcast + ct state invalid drop + } + chain forward { + type filter hook forward priority filter + policy drop + jump accept-connectivity-forward + } + chain output { + type filter hook output priority filter + policy drop + oifname lo accept + ct state { related, established } accept + jump accept-connectivity-output + } + } + ''; + }; +}; +} diff --git a/machines/losurdo/networking/openvpn/riseup/cacert.pem b/machines/losurdo/networking/openvpn/riseup/cacert.pem new file mode 100644 index 0000000..cbec39c --- /dev/null +++ b/machines/losurdo/networking/openvpn/riseup/cacert.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIBATANBgkqhkiG9w0BAQ0FADBZMRgwFgYDVQQKDA9SaXNl +dXAgTmV0d29ya3MxGzAZBgNVBAsMEmh0dHBzOi8vcmlzZXVwLm5ldDEgMB4GA1UE +AwwXUmlzZXVwIE5ldHdvcmtzIFJvb3QgQ0EwHhcNMTQwNDI4MDAwMDAwWhcNMjQw +NDI4MDAwMDAwWjBZMRgwFgYDVQQKDA9SaXNldXAgTmV0d29ya3MxGzAZBgNVBAsM +Emh0dHBzOi8vcmlzZXVwLm5ldDEgMB4GA1UEAwwXUmlzZXVwIE5ldHdvcmtzIFJv +b3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC76J4ciMJ8Sg0m +TP7DF2DT9zNe0Csk4myoMFC57rfJeqsAlJCv1XMzBmXrw8wq/9z7XHv6n/0sWU7a +7cF2hLR33ktjwODlx7vorU39/lXLndo492ZBhXQtG1INMShyv+nlmzO6GT7ESfNE +LliFitEzwIegpMqxCIHXFuobGSCWF4N0qLHkq/SYUMoOJ96O3hmPSl1kFDRMtWXY +iw1SEKjUvpyDJpVs3NGxeLCaA7bAWhDY5s5Yb2fA1o8ICAqhowurowJpW7n5ZuLK +5VNTlNy6nZpkjt1QycYvNycffyPOFm/Q/RKDlvnorJIrihPkyniV3YY5cGgP+Qkx +HUOT0uLA6LHtzfiyaOqkXwc4b0ZcQD5Vbf6Prd20Ppt6ei0zazkUPwxld3hgyw58 +m/4UIjG3PInWTNf293GngK2Bnz8Qx9e/6TueMSAn/3JBLem56E0WtmbLVjvko+LF +PM5xA+m0BmuSJtrD1MUCXMhqYTtiOvgLBlUm5zkNxALzG+cXB28k6XikXt6MRG7q +hzIPG38zwkooM55yy5i1YfcIi5NjMH6A+t4IJxxwb67MSb6UFOwg5kFokdONZcwj +shczHdG9gLKSBIvrKa03Nd3W2dF9hMbRu//STcQxOailDBQCnXXfAATj9pYzdY4k +ha8VCAREGAKTDAex9oXf1yRuktES4QIDAQABo2AwXjAdBgNVHQ4EFgQUC4tdmLVu +f9hwfK4AGliaet5KkcgwDgYDVR0PAQH/BAQDAgIEMAwGA1UdEwQFMAMBAf8wHwYD +VR0jBBgwFoAUC4tdmLVuf9hwfK4AGliaet5KkcgwDQYJKoZIhvcNAQENBQADggIB +AGzL+GRnYu99zFoy0bXJKOGCF5XUXP/3gIXPRDqQf5g7Cu/jYMID9dB3No4Zmf7v +qHjiSXiS8jx1j/6/Luk6PpFbT7QYm4QLs1f4BlfZOti2KE8r7KRDPIecUsUXW6P/ +3GJAVYH/+7OjA39za9AieM7+H5BELGccGrM5wfl7JeEz8in+V2ZWDzHQO4hMkiTQ +4ZckuaL201F68YpiItBNnJ9N5nHr1MRiGyApHmLXY/wvlrOpclh95qn+lG6/2jk7 +3AmihLOKYMlPwPakJg4PYczm3icFLgTpjV5sq2md9bRyAg3oPGfAuWHmKj2Ikqch +Td5CHKGxEEWbGUWEMP0s1A/JHWiCbDigc4Cfxhy56CWG4q0tYtnc2GMw8OAUO6Wf +Xu5pYKNkzKSEtT/MrNJt44tTZWbKV/Pi/N2Fx36my7TgTUj7g3xcE9eF4JV2H/sg +tsK3pwE0FEqGnT4qMFbixQmc8bGyuakr23wjMvfO7eZUxBuWYR2SkcP26sozF9PF +tGhbZHQVGZUTVPyvwahMUEhbPGVerOW0IYpxkm0x/eaWdTc4vPpf/rIlgbAjarnJ +UN9SaWRlWKSdP4haujnzCoJbM7dU9bjvlGZNyXEekgeT0W2qFeGGp+yyUWw8tNsp +0BuC1b7uW/bBn/xKm319wXVDvBgZgcktMolak39V7DVO +-----END CERTIFICATE----- diff --git a/machines/losurdo/networking/openvpn/riseup/client.pem b/machines/losurdo/networking/openvpn/riseup/client.pem new file mode 100644 index 0000000..cb391bb --- /dev/null +++ b/machines/losurdo/networking/openvpn/riseup/client.pem @@ -0,0 +1,54 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAs4V9VZQSh1xSjk0tIUc3B6nEu8uLht/WDp+LU/RzPdjLDMXc +irpRKzBAuhqJwWB0SBw8LoaNp1DnIVetEa1RmuWkD+VVTtDwaPwst36T64BHrKzP +yiK/vXs5mzhm4KbLKFlcwOYGysNrORVrMJtSsK6TD9TpoPEeELTJt8gJ1mFGZBjY +HHRMGvYOvZwFhtsMDNSj5b48KwxIIiiPfrkYElNRU35NQcZfT8ETvRCM+R98E+3E +YFY017Lhfzdgak5LWttYB/AVruOMbmSv50WKT6rhZFeG6llelEcPaRb1aT6IR3uq +nhQLn/xXsUKEO+pAvOUb6p+GyOwcQMMAHDLkOQIDAQABAoIBAB31hBIZEPKIBLr8 +xDBOiy97NHrGoDVU+4sbMwxCukyy9kfeaUy5hTw45ERqk1yzNRSnqZ92EwO+K6RT +1m0hyIGaG0QP2Km7krNiii/hLtxZXxzBBjhMjkUX4Gg4BGsvSq4kI6eJe86wyB8R +pP7KnQUhTSeSN58FPig5k4RZHNMqxwIjWLBWoz3qy82CtICcJLWDd0ro/rNZFW8h +LAteXA7DuOlbyFHcC0SG8kctB9ZRPkasdwrF6swyBOTTtwabsMXfat8f+mqM6Efo +VZ3Xp2wN0UXEFVjJXMEDDeQH+q0kGE7H6MQE/0FiOt98wLuC5bBYQC0HxMSlWdz1 +USbPDVUCgYEA4vlA29mvSffe4iqDC83VtawMt4lC5m2Zqs8+D4BV1kUnnA9OO1zu +ZPmof4eWj6K17k7YXO8Xd8je794s4iTmZvO5Ig76bZk43N8aXSr0M+WmMMLRKAbC +EsJlVOwwwwmu2sQLHBEeS+9vsnA1tlslvtqsq5/fEBOFXGMvMrS9be8CgYEAynq6 +hTKodj7BpvwipGXLa+uaPN8ttCesOUc+yKK9nuMnpJNPU1MCyTEtskijsz823Tzi +ti1dyTQSiBFtFgh8D1dUYKdd98u3ljzoToSsaDvIyMvn/2pxvTGMvZ9VaMSRHlZI +bMC9xtfchuDzVR3APh2I4CV9UHnCEiIVtRrd+FcCgYEA0wdWI1KI5Kf+ZZ+LCf2N +toTJqheHyQCcADEBjZ4PsNHJWxLr9MuZpu5smG3zMYbhyjkqd3WhBzEO/kw+xN/0 +DEKMnbr5Yc81DD6un3Mha+MYGnv3xVRLOu/dEREs4Rnupd3iSm0sEwQCgRBNEEg8 +lu9v3X4eAi90LgrVxjo/aacCgYEAqCOeO/nDNt4KRbZethHqCKZPIHlcJJxFQhNN +qaKqwAR16Q6C8vid+aCjB8eWWMUHtFRZF1s45FofgWqnIYLOMpccdF7Hg3xh6ZqO +dpVp7eynYUciUlF8PdWlv9lOPX/t2jlgTx8G+NZMRJ0MtAPOnkY8YZYAKBHT/Obd +C9VRumUCgYB5njH4P8PNeBA/H/vYF17a9F6ulDYHB5/BZnFcPfuxiov/aNepVyvt +Z+QY6SmFdmak00YLh3qOGT5ek6iMODfKBe625VIr4p3akwzr/bu/LWHWNpfffaET +bvJ4nzplqyYkMV9nLr+9N/iUjtRXQ0yHJp+cBRu2cS032TDyzplc7A== +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIEmzCCAoOgAwIBAgIQT9fuPod6b6yND5zUoXK38TANBgkqhkiG9w0BAQsFADB1 +MRgwFgYDVQQKDA9SaXNldXAgTmV0d29ya3MxGzAZBgNVBAsMEmh0dHBzOi8vcmlz +ZXVwLm5ldDE8MDoGA1UEAwwzUmlzZXVwIE5ldHdvcmtzIFJvb3QgQ0EgKGNsaWVu +dCBjZXJ0aWZpY2F0ZXMgb25seSEpMB4XDTIwMDgyMjAwMDAwMFoXDTIwMTEyMjAw +MDAwMFowLTErMCkGA1UEAwwiVU5MSU1JVEVEODE5a3Rxa3ZhNGkyeDEzbW5wNnJ2 +MmswYzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALOFfVWUEodcUo5N +LSFHNwepxLvLi4bf1g6fi1P0cz3YywzF3Iq6USswQLoaicFgdEgcPC6GjadQ5yFX +rRGtUZrlpA/lVU7Q8Gj8LLd+k+uAR6ysz8oiv717OZs4ZuCmyyhZXMDmBsrDazkV +azCbUrCukw/U6aDxHhC0ybfICdZhRmQY2Bx0TBr2Dr2cBYbbDAzUo+W+PCsMSCIo +j365GBJTUVN+TUHGX0/BE70QjPkffBPtxGBWNNey4X83YGpOS1rbWAfwFa7jjG5k +r+dFik+q4WRXhupZXpRHD2kW9Wk+iEd7qp4UC5/8V7FChDvqQLzlG+qfhsjsHEDD +ABwy5DkCAwEAAaNvMG0wHQYDVR0OBBYEFCRYWXXaTEtq6EbvKXTDkTNTOf70MAsG +A1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAjAJBgNVHRMEAjAAMB8GA1Ud +IwQYMBaAFBf0G9XlKgEBTWuiXTYKKQmWZYBGMA0GCSqGSIb3DQEBCwUAA4ICAQCV +sL/zmlK0f8conYDz2d5uZ0qIcJjtsb1DtE3vHULrei0cVgFuAX/y7XT4ddzj64r6 +PzkoHSZ5FhVbg/ZN0olpEed25kt6bp4m2QvfRNd/qctcYmnqsSZdC5vb7NByBWQE +a7by2zvG281W0J+PRrXcnbPB2dTUMw7/mEJ9MIh5KfHWoPQl+KKYJorOgkoUACMS +L1k+0xxKGOE7DDwALGa/Uh8KSEZ2tF3OrYTNfweaOmdjn6UBzii1Jn54aU4dhwea +I5WFWDQ3TxOdtSrOWHuyVLNGE61iwMAhqLmPlBl3tqci/BHe5/bAKWx4FkS6GcZ6 ++i6mCqJG93rT+XLmePqFd9WQKd5Ff9kG104X3Fv5qnVRxR+eYRqZjDg6kySFyj3G +ZM9SXYH0dMl3oxMjroIBlIKIW3A+VFjWpM2W49eib+wVL0YL5wMTCNpK7ZM84amz +b1Q1A9jKgPMmbIL9HFWDjJigMBC6SYu3vfNUsXQzimrRvho6HBpQ63X3FcOOAlZ3 +5z/3OFWwwRvI/S7SENgRj7QB6mTc0z18BdwYKB7UZX8xhoZWYr9UaKeo/OGoSi1K +LqEe6R30A8PYGYgnXxeOe0adZHiIIElE9ypZccy2qAcak1BYdoHjQqoY96Amqi37 +J24ftvwhm5GUwYFRecUP7Ll/NI6AjcgxxDxU5v2viA== +-----END CERTIFICATE----- diff --git a/machines/losurdo/transmission.nix b/machines/losurdo/transmission.nix index 81eb9e2..b8a93cb 100644 --- a/machines/losurdo/transmission.nix +++ b/machines/losurdo/transmission.nix @@ -3,23 +3,31 @@ let inherit (config.services) transmission; inherit (config.users) users; inherit (config.security) gnupg; + netns = "riseup"; in { users.groups.transmission.members = [ users."julm".name ]; -networking.nftables.ruleset = '' - add rule inet filter net2fw tcp dport ${toString transmission.settings.peer-port} counter accept comment "Transmission" - add rule inet filter net2fw udp dport ${toString transmission.settings.peer-port} counter accept comment "Transmission" - add rule inet filter fw2net meta skuid ${transmission.user} counter accept comment "Transmission" +services.openvpn.servers.${netns}.nftables = '' + add rule inet filter input tcp dport ${toString transmission.settings.peer-port} counter accept comment "Transmission" + add rule inet filter input udp dport ${toString transmission.settings.peer-port} counter accept comment "Transmission" + add rule inet filter output meta skuid ${transmission.user} counter accept comment "Transmission" ''; #users.groups.keys.members = [ transmission.user ]; security.gnupg.secrets."transmission/settings.json" = { user = transmission.user; }; systemd.services.transmission = { - after = [ gnupg.secrets."transmission/settings.json".service ]; - requires = [ gnupg.secrets."transmission/settings.json".service ]; + after = [ + gnupg.secrets."transmission/settings.json".service + "netns@${netns}.service" + ]; + requires = [ + gnupg.secrets."transmission/settings.json".service + "netns@${netns}.service" + ]; + serviceConfig.NetworkNamespacePath = "/var/run/netns/${netns}"; }; services.transmission = { enable = true; @@ -51,12 +59,12 @@ services.transmission = { queue-stalled-enabled = true; queue-stalled-minutes = 30; speed-limit-down-enabled = false; - speed-limit-up = 500; + speed-limit-up = 50; speed-limit-up-enabled = true; alt-speed-enabled = true; alt-speed-time-enabled = true; - alt-speed-down = 5000; - alt-speed-up = 50; + alt-speed-down = 1000; + alt-speed-up = 0; alt-speed-time-day = 127; # all days. 65; # weekend only alt-speed-time-begin = 360; # 06h00 local time alt-speed-time-end = 1320; # 22h00 local time diff --git a/machines/mermet/networking/nftables.nix b/machines/mermet/networking/nftables.nix index b0b2cb2..1c44011 100644 --- a/machines/mermet/networking/nftables.nix +++ b/machines/mermet/networking/nftables.nix @@ -14,72 +14,7 @@ networking.nftables = { enable = true; ruleset = lib.mkBefore '' table inet filter { - set lograte4 { type ipv4_addr; size 65535; flags dynamic; } - #set lograte6 { type ipv6_addr; size 65535; flags dynamic; } - chain ping-flood { - add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "ping-flood: " - #add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "ping-flood: " - counter drop - } - chain check-ping { - ip protocol icmp icmp type echo-request limit rate over 10/second burst 20 packets goto ping-flood - #ip6 nexthdr ipv6-icmp icmpv6 type echo-request limit rate over 10/second burst 20 packets goto ping-flood - } - chain smurf { - add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "smurf: " - #add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "smurf: " - counter drop - } - chain check-broadcast { - #ip saddr 0.0.0.0/32 counter accept comment "DHCP broadcast" - fib saddr type broadcast counter goto smurf - ip saddr 224.0.0.0/4 counter goto smurf - } - chain bogus-tcp { - add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "bogus-tcp: " - #add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "bogus-tcp: " - counter drop - } - chain syn-flood { - add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "syn-flood: " - #add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "syn-flood: " - counter drop - } - chain check-tcp { - tcp flags syn tcp option maxseg size != 536-65535 counter goto bogus-tcp - tcp flags & (ack|fin) == fin counter goto bogus-tcp - tcp flags & (ack|psh) == psh counter goto bogus-tcp - tcp flags & (ack|urg) == urg counter goto bogus-tcp - tcp flags & (fin|ack) == fin counter goto bogus-tcp - tcp flags & (fin|rst) == (fin|rst) counter goto bogus-tcp - tcp flags & (fin|psh|ack) == (fin|psh) counter goto bogus-tcp - tcp flags & (syn|fin) == (syn|fin) counter goto bogus-tcp comment "SYN-FIN scan" - tcp flags & (syn|rst) == (syn|rst) counter goto bogus-tcp comment "SYN-RST scan" - tcp flags == (fin|syn|rst|psh|ack|urg) counter goto bogus-tcp comment "XMAS scan" - tcp flags == 0x0 counter goto bogus-tcp comment "NULL scan" - tcp flags == (fin|urg|psh) counter goto bogus-tcp - tcp flags == (fin|urg|psh|syn) counter goto bogus-tcp comment "NMAP-ID" - tcp flags == (fin|urg|syn|rst|ack) counter goto bogus-tcp - - ct state new tcp flags != syn counter goto bogus-tcp - tcp sport 0 tcp flags & (fin|syn|rst|ack) == syn counter goto bogus-tcp - tcp flags & (fin|syn|rst|ack) == syn counter limit rate over 30/second burst 60 packets goto syn-flood - } - chain spoofing { - add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "spoofing: " - counter drop - } - chain check-public { - ip saddr 0.0.0.0/8 counter goto spoofing - ip saddr 10.0.0.0/8 counter goto spoofing - ip saddr 127.0.0.0/8 counter goto spoofing - ip saddr 169.254.0.0/16 counter goto spoofing - ip saddr 172.16.0.0/12 counter goto spoofing - ip saddr 192.0.2.0/24 counter goto spoofing - ip saddr 192.168.0.0/16 counter goto spoofing - ip saddr 224.0.0.0/3 counter goto spoofing - ip saddr 240.0.0.0/5 counter goto spoofing - } + include "${../../../var/nftables/filter.txt}" chain net2fw { jump check-public # Some .nix append rules here with: add rule inet filter net2fw ... @@ -118,44 +53,14 @@ networking.nftables = { # accept traffic already established ct state { established, related } accept + jump accept-connectivity-input + jump check-broadcast ct state invalid drop # admin services tcp dport 22 counter accept comment "SSH" udp dport 60000-61000 counter accept comment "Mosh" - # ICMP - ip protocol icmp icmp type echo-request counter accept - ip protocol icmp icmp type destination-unreachable counter accept - ip protocol icmp icmp type router-solicitation counter accept - ip protocol icmp icmp type router-advertisement counter accept - ip protocol icmp icmp type time-exceeded counter accept - ip protocol icmp icmp type parameter-problem counter accept - ip protocol icmp log level warn prefix "net2fw: icmpv: " counter accept - #ip protocol icmp icmp type { echo-request, destination-unreachable, router-solicitation, router-advertisement, time-exceeded, parameter-problem } counter accept - - #ip6 nexthdr ipv6-icmp icmpv6 type echo-request counter accept - #ip6 nexthdr ipv6-icmp icmpv6 type nd-neighbor-solicit counter accept - #ip6 nexthdr ipv6-icmp icmpv6 type nd-neighbor-advert counter accept - #ip6 nexthdr ipv6-icmp icmpv6 type nd-router-solicit counter accept - #ip6 nexthdr ipv6-icmp icmpv6 type nd-router-advert counter accept - #ip6 nexthdr ipv6-icmp icmpv6 type mld-listener-query counter accept - #ip6 nexthdr ipv6-icmp icmpv6 type mld-listener-report counter accept - #ip6 nexthdr ipv6-icmp icmpv6 type mld-listener-reduction counter accept - #ip6 nexthdr ipv6-icmp icmpv6 type destination-unreachable counter accept - #ip6 nexthdr ipv6-icmp icmpv6 type packet-too-big counter accept - #ip6 nexthdr ipv6-icmp icmpv6 type time-exceeded counter accept - #ip6 nexthdr ipv6-icmp icmpv6 type parameter-problem counter accept - #ip6 nexthdr ipv6-icmp icmpv6 type ind-neighbor-solicit counter accept - #ip6 nexthdr ipv6-icmp icmpv6 type ind-neighbor-advert counter accept - #ip6 nexthdr ipv6-icmp icmpv6 type mld2-listener-report counter accept - #ip6 nexthdr ipv6-icmp log level warn prefix "net2fw: icmpv6: " counter accept - #ip6 nexthdr ipv6-icmp icmpv6 type { echo-request, nd-neighbor-solicit, nd-neighbor-advert, nd-router-solicit, nd-router-advert, mld-listener-query, mld-listener-report, mld-listener-reduction, destination-unreachable, packet-too-big, time-exceeded, parameter-problem, ind-neighbor-solicit, ind-neighbor-advert, mld2-listener-report } counter accept - - # ICMP - ip protocol icmp icmp type echo-request accept - #ip6 nexthdr ipv6-icmp icmpv6 type echo-request accept - # Some .nix append gotos here with: add rule inet filter input iffname ... goto ... } chain output { @@ -165,9 +70,8 @@ networking.nftables = { oifname lo accept ct state { established, related } accept - ct state invalid drop + jump accept-connectivity-output - icmp type echo-request counter accept comment "Ping" tcp dport 22 counter accept comment "SSH" # Some .nix append gotos here with: add rule inet filter output oifname ... goto ... diff --git a/nixos/modules.nix b/nixos/modules.nix index c5eaa90..d743e23 100644 --- a/nixos/modules.nix +++ b/nixos/modules.nix @@ -11,6 +11,8 @@ imports = [ #modules/security/gnupg.nix #modules/services/networking/biboumi.nix #modules/services/networking/croc.nix + modules/services/networking/netns.nix + modules/services/networking/openvpn.nix #/home/julm/src/nix/nixpkgs/.git-worktree/transmission/nixos/modules/services/torrent/transmission.nix #/home/julm/src/nix/nixpkgs/nixos/modules/services/torrent/transmission.nix #modules/services/mail/mlmmj.nix @@ -24,6 +26,8 @@ disabledModules = [ #"security/gnupg.nix" #"services/networking/biboumi.nix" #"services/networking/croc.nix" + "services/networking/netns.nix" + "services/networking/openvpn.nix" #"services/torrent/transmission.nix" "services/freeciv.nix" ]; diff --git a/nixos/modules/services/networking/netns.nix b/nixos/modules/services/networking/netns.nix new file mode 100644 index 0000000..cefcc43 --- /dev/null +++ b/nixos/modules/services/networking/netns.nix @@ -0,0 +1,14 @@ +{ pkgs, lib, config, ... }: +{ +systemd.services."netns@" = { + description = "%I network namespace"; + before = [ "network.target" ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + PrivateNetwork = true; + ExecStart = "${pkgs.iproute}/bin/ip netns add %i"; + ExecStop = "${pkgs.iproute}/bin/ip netns del %i"; + }; +}; +} diff --git a/nixos/modules/services/networking/openvpn.nix b/nixos/modules/services/networking/openvpn.nix new file mode 100644 index 0000000..8b9cdd7 --- /dev/null +++ b/nixos/modules/services/networking/openvpn.nix @@ -0,0 +1,233 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.openvpn; + + inherit (pkgs) openvpn; + + makeOpenVPNJob = cfg: name: + let + + path = makeBinPath (getAttr "openvpn-${name}" config.systemd.services).path; + + upScript = '' + export PATH=${path} + + # For convenience in client scripts, extract the remote domain + # name and name server. + for var in ''${!foreign_option_*}; do + x=(''${!var}) + if [ "''${x[0]}" = dhcp-option ]; then + if [ "''${x[1]}" = DOMAIN ]; then domain="''${x[2]}" + elif [ "''${x[1]}" = DNS ]; then nameserver="''${x[2]}" + fi + fi + done + + ${cfg.up} + ${optionalString cfg.updateResolvConf + "${pkgs.update-resolv-conf}/libexec/openvpn/update-resolv-conf"} + ''; + + downScript = '' + export PATH=${path} + ${optionalString cfg.updateResolvConf + "${pkgs.update-resolv-conf}/libexec/openvpn/update-resolv-conf"} + ${cfg.down} + ''; + + configFile = pkgs.writeText "openvpn-config-${name}" + '' + errors-to-stderr + ${optionalString (cfg.up != "" || cfg.down != "" || cfg.updateResolvConf) "script-security 2"} + ${cfg.config} + ${optionalString (cfg.up != "" || cfg.updateResolvConf) + "up ${pkgs.writeShellScript "openvpn-${name}-up" upScript}"} + ${optionalString (cfg.routeUp != "") + "route-up ${pkgs.writeShellScript "openvpn-${name}-up" cfg.routeUp}"} + ${optionalString (cfg.down != "" || cfg.updateResolvConf) + "down ${pkgs.writeShellScript "openvpn-${name}-down" downScript}"} + ${optionalString (cfg.authUserPass != null) + "auth-user-pass ${pkgs.writeText "openvpn-credentials-${name}" '' + ${cfg.authUserPass.username} + ${cfg.authUserPass.password} + ''}"} + ''; + + in { + description = "OpenVPN instance ‘${name}’"; + + wantedBy = optional cfg.autoStart "multi-user.target"; + after = [ "network.target" ]; + + path = [ pkgs.iptables pkgs.iproute pkgs.nettools ]; + + serviceConfig.ExecStart = "@${openvpn}/sbin/openvpn openvpn --suppress-timestamps --config ${configFile}"; + serviceConfig.Restart = "always"; + serviceConfig.Type = "notify"; + }; + +in + +{ + imports = [ + (mkRemovedOptionModule [ "services" "openvpn" "enable" ] "") + ]; + + ###### interface + + options = { + + services.openvpn.servers = mkOption { + default = {}; + + example = literalExample '' + { + server = { + config = ''' + # Simplest server configuration: https://community.openvpn.net/openvpn/wiki/StaticKeyMiniHowto + # server : + dev tun + ifconfig 10.8.0.1 10.8.0.2 + secret /root/static.key + '''; + up = "ip route add ..."; + down = "ip route del ..."; + }; + + client = { + config = ''' + client + remote vpn.example.org + dev tun + proto tcp-client + port 8080 + ca /root/.vpn/ca.crt + cert /root/.vpn/alice.crt + key /root/.vpn/alice.key + '''; + up = "echo nameserver $nameserver | ''${pkgs.openresolv}/sbin/resolvconf -m 0 -a $dev"; + down = "''${pkgs.openresolv}/sbin/resolvconf -d $dev"; + }; + } + ''; + + description = '' + Each attribute of this option defines a systemd service that + runs an OpenVPN instance. These can be OpenVPN servers or + clients. The name of each systemd service is + openvpn-name.service, + where name is the corresponding + attribute name. + ''; + + type = with types; attrsOf (submodule { + + options = { + + config = mkOption { + type = types.lines; + description = '' + Configuration of this OpenVPN instance. See + openvpn8 + for details. + + To import an external config file, use the following definition: + config = "config /path/to/config.ovpn" + ''; + }; + + up = mkOption { + default = ""; + type = types.lines; + description = '' + Shell commands executed when the instance is starting. + ''; + }; + + routeUp = mkOption { + default = ""; + type = types.lines; + description = '' + ''; + }; + + down = mkOption { + default = ""; + type = types.lines; + description = '' + Shell commands executed when the instance is shutting down. + ''; + }; + + nftables = mkOption { + default = ""; + type = types.lines; + description = '' + ''; + }; + + autoStart = mkOption { + default = true; + type = types.bool; + description = "Whether this OpenVPN instance should be started automatically."; + }; + + updateResolvConf = mkOption { + default = false; + type = types.bool; + description = '' + Use the script from the update-resolv-conf package to automatically + update resolv.conf with the DNS information provided by openvpn. The + script will be run after the "up" commands and before the "down" commands. + ''; + }; + + authUserPass = mkOption { + default = null; + description = '' + This option can be used to store the username / password credentials + with the "auth-user-pass" authentication method. + + WARNING: Using this option will put the credentials WORLD-READABLE in the Nix store! + ''; + type = types.nullOr (types.submodule { + + options = { + username = mkOption { + description = "The username to store inside the credentials file."; + type = types.str; + }; + + password = mkOption { + description = "The password to store inside the credentials file."; + type = types.str; + }; + }; + }); + }; + }; + + }); + + }; + + }; + + + ###### implementation + + config = mkIf (cfg.servers != {}) { + + systemd.services = listToAttrs (mapAttrsFlatten (name: value: nameValuePair "openvpn-${name}" (makeOpenVPNJob value name)) cfg.servers); + + environment.systemPackages = [ openvpn ]; + + boot.kernelModules = [ "tun" ]; + + }; + +} diff --git a/var/nftables/filter.txt b/var/nftables/filter.txt new file mode 100644 index 0000000..a96e9c4 --- /dev/null +++ b/var/nftables/filter.txt @@ -0,0 +1,175 @@ +# A set containing the udp port(s) to which SSDP replies are allowed. +set ssdp_out { + type inet_service + timeout 5s +} +set lograte4 { type ipv4_addr; size 65535; flags dynamic; } +set lograte6 { type ipv6_addr; size 65535; flags dynamic; } +chain block { + add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "block: " + add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "block: " + counter drop +} +chain ping-flood { + add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "ping-flood: " + add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "ping-flood: " + counter drop +} +chain smurf { + add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "smurf: " + add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "smurf: " + counter drop +} +chain bogus-tcp { + add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "bogus-tcp: " + add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "bogus-tcp: " + counter drop +} +chain syn-flood { + add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "syn-flood: " + add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "syn-flood: " + counter drop +} +chain check-tcp { + tcp flags syn tcp option maxseg size != 536-65535 counter goto bogus-tcp + tcp flags & (ack|fin) == fin counter goto bogus-tcp + tcp flags & (ack|psh) == psh counter goto bogus-tcp + tcp flags & (ack|urg) == urg counter goto bogus-tcp + tcp flags & (fin|ack) == fin counter goto bogus-tcp + tcp flags & (fin|rst) == (fin|rst) counter goto bogus-tcp + tcp flags & (fin|psh|ack) == (fin|psh) counter goto bogus-tcp + tcp flags & (syn|fin) == (syn|fin) counter goto bogus-tcp comment "SYN-FIN scan" + tcp flags & (syn|rst) == (syn|rst) counter goto bogus-tcp comment "SYN-RST scan" + tcp flags == (fin|syn|rst|psh|ack|urg) counter goto bogus-tcp comment "XMAS scan" + tcp flags == 0x0 counter goto bogus-tcp comment "NULL scan" + tcp flags == (fin|urg|psh) counter goto bogus-tcp + tcp flags == (fin|urg|psh|syn) counter goto bogus-tcp comment "NMAP-ID" + tcp flags == (fin|urg|syn|rst|ack) counter goto bogus-tcp + + ct state new tcp flags != syn counter goto bogus-tcp + tcp sport 0 tcp flags & (fin|syn|rst|ack) == syn counter goto bogus-tcp + tcp flags & (fin|syn|rst|ack) == syn counter limit rate over 30/second burst 60 packets goto syn-flood +} +chain spoofing { + add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "spoofing: " + counter drop +} +chain check-broadcast { + #ip saddr 0.0.0.0/32 counter accept comment "DHCP broadcast" + fib saddr type broadcast counter goto smurf + #ip saddr 224.0.0.0/4 counter goto smurf +} +chain check-ping { + ip protocol icmp icmp type echo-request limit rate over 10/second burst 20 packets goto ping-flood + ip6 nexthdr ipv6-icmp icmpv6 type echo-request limit rate over 10/second burst 20 packets goto ping-flood +} +chain check-public { + ip saddr 0.0.0.0/8 counter goto spoofing + ip saddr 10.0.0.0/8 counter goto spoofing + ip saddr 127.0.0.0/8 counter goto spoofing + ip saddr 169.254.0.0/16 counter goto spoofing + ip saddr 172.16.0.0/12 counter goto spoofing + ip saddr 192.0.2.0/24 counter goto spoofing + ip saddr 192.168.0.0/16 counter goto spoofing + ip saddr 224.0.0.0/3 counter goto spoofing + ip saddr 240.0.0.0/5 counter goto spoofing +} +chain accept-icmpv6 { + # Traffic That Must Not Be Dropped + # https://tools.ietf.org/html/rfc4890#section-4.4.1 + icmpv6 type destination-unreachable counter accept + icmpv6 type packet-too-big counter accept + icmpv6 type time-exceeded counter accept + icmpv6 type parameter-problem counter accept + + # Address Configuration and Router Selection messages + # (must be received with hop limit = 255) + icmpv6 type nd-router-solicit ip6 hoplimit 255 counter accept + ip6 nexthdr ipv6-icmp icmpv6 type nd-router-advert ip6 hoplimit 255 counter accept + icmpv6 type nd-neighbor-solicit ip6 hoplimit 255 counter accept + icmpv6 type nd-neighbor-advert ip6 hoplimit 255 counter accept + icmpv6 type nd-redirect ip6 hoplimit 255 log level warn prefix "icmpv6: nd-redirect: " counter drop + icmpv6 type ind-neighbor-solicit ip6 hoplimit 255 counter accept + icmpv6 type ind-neighbor-advert ip6 hoplimit 255 counter accept + + # Link-local multicast receiver notification messages + # (must have link-local source address) + icmpv6 type mld-listener-query ip6 saddr fe80::/10 counter accept + icmpv6 type mld-listener-report ip6 saddr fe80::/10 counter accept + icmpv6 type mld-listener-done ip6 saddr fe80::/10 counter accept + # https://tools.ietf.org/html/rfc3810 Multicast Listener Discovery Version 2 (MLDv2) for IPv6 + icmpv6 type mld2-listener-report ip6 saddr fe80::/10 counter accept + + # SEND Certificate Path notification messages + # (must be received with hop limit = 255) + icmpv6 type 148 ip6 hoplimit 255 counter accept comment "certificate-path-solicitation" + icmpv6 type 149 ip6 hoplimit 255 counter accept comment "certificate-path-advertisement" + + # Multicast Router Discovery messages + # (must have link-local source address and hop limit = 1) + icmpv6 type 151 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-advertisement" + icmpv6 type 152 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-solicitation" + icmpv6 type 153 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-termination" +} +chain accept-connectivity-input { + # Connectivity checking messages + # (multicast) ping + ip protocol icmp icmp type echo-reply counter accept + + # drop packets with rh0 headers + rt type 0 jump block + rt type 0 jump block + rt type 0 jump block + + # (multicast) ping + ip6 nexthdr ipv6-icmp icmpv6 type echo-reply counter accept + #ct state invalid counter drop + + ip protocol icmp icmp type destination-unreachable counter accept + ip protocol icmp icmp type time-exceeded counter accept + ip protocol icmp icmp type parameter-problem counter accept + ip protocol icmp icmp type echo-request limit rate over 10/second burst 20 packets goto ping-flood + ip protocol icmp icmp type echo-request counter accept + # echo-reply is handled before invalid packets to allow multicast ping + # which do not have an associated connection. + + ip6 nexthdr ipv6-icmp jump accept-icmpv6 + + # Connectivity checking messages + icmpv6 type echo-request counter accept + # echo-reply is handled before invalid because of multicast +} +chain accept-connectivity-output { + ip protocol icmp counter accept + meta skuid 0 udp dport 33434-33523 counter accept comment "traceroute" + + ip6 nexthdr ipv6-icmp jump accept-icmpv6 + + # Connectivity checking messages + ip6 nexthdr ipv6-icmp icmpv6 type echo-request counter accept + ip6 nexthdr ipv6-icmp icmpv6 type echo-reply counter accept +} +chain accept-connectivity-forward { + ip protocol icmp icmp type destination-unreachable counter accept + ip protocol icmp icmp type time-exceeded counter accept + ip protocol icmp icmp type parameter-problem counter accept + ip protocol icmp icmp type echo-request counter accept + + # Traffic That Must Not Be Dropped + # https://tools.ietf.org/html/rfc4890#section-4.3.1 + ip6 nexthdr ipv6-icmp icmpv6 type destination-unreachable counter accept + ip6 nexthdr ipv6-icmp icmpv6 type packet-too-big counter accept + ip6 nexthdr ipv6-icmp icmpv6 type time-exceeded counter accept + ip6 nexthdr ipv6-icmp icmpv6 type parameter-problem counter accept + + # Connectivity checking messages + ip6 nexthdr ipv6-icmp icmpv6 type echo-request counter accept + ip6 nexthdr ipv6-icmp icmpv6 type echo-reply counter accept + + # Traffic That Normally Should Not Be Dropped + # https://tools.ietf.org/html/rfc4890#section-4.3.2 + ip6 nexthdr ipv6-icmp icmpv6 type 144 counter accept comment "home-agent-address-discovery-request" + ip6 nexthdr ipv6-icmp icmpv6 type 145 counter accept comment "home-agent-address-discovery-reply" + ip6 nexthdr ipv6-icmp icmpv6 type 146 counter accept comment "mobile-prefix-solicitation" + ip6 nexthdr ipv6-icmp icmpv6 type 147 counter accept comment "mobile-prefix-advertisement" +} -- 2.44.1