{ pkgs, lib, config, hosts, ... }:
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 ||
        ${pkgs.curl}/bin/curl -s4L https://icanhazip.com || 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} <<EOF
      server ns.sourcephile.fr
      zone sourcephile.fr
      origin sourcephile.fr
      update delete bureau1 A
      ''${publicIPv4:+update add bureau1 300 A $publicIPv4}
      update delete bureau1 AAAA
      ''${publicIPv6:+update add bureau1 300 AAAA $publicIPv6}
      update delete lan.losurdo A
      ''${privateIPv4:+update add lan.losurdo 300 A $privateIPv4}
      show
      send
      EOF
    '';
    Restart = "on-failure";
    RestartSec = "30s";
    DynamicUser = true;
    User = users."nsupdate".name;
  };
};
users.users."nsupdate".isSystemUser = true;
users.groups."keys".members = [users."nsupdate".name];
security.gnupg.secrets."knot/tsig/${domain}/bureau1.key" = {
  user = users."nsupdate".name;
};
networking.nftables.ruleset =
  lib.optionalString (config.services.upnpc.redirections != []) ''
  # Create a rule for accepting any SSDP packets going to a remembered port.
  add rule inet filter net2fw udp dport @ssdp_out \
    counter accept comment "SSDP answer"
  add rule inet filter fw2net \
    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},${users.nsupdate.name}} \
    ip daddr 239.255.255.250 udp dport 1900 \
    counter accept comment "SSDP"
  '' + lib.optionalString config.networking.enableIPv6 ''
  add rule inet filter fw2net \
    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},${users.nsupdate.name}} \
    ip6 daddr {FF02::C, FF05::C, FF08::C, FF0E::C} udp dport 1900 \
    counter accept comment "SSDP"
  '';
}