{
  pkgs,
  config,
  factsGenerator,
  clanLib,
  lib,
  ...
}:
let
  otherMachines = lib.filterAttrs (name: _value: name != "orbi") (
    clanLib.readFactsFromAllMachines [
      "wireguard.wg0.pub"
      "wireguard.wg0.cidr"
    ]
  );
  peers = lib.mapAttrsToList (_machine: facts: {
    publicKey = facts."wireguard.wg0.pub";
    allowedIPs = [ facts."wireguard.wg0.cidr" ];
  }) otherMachines;
in
{
  networking.firewall.allowedUDPPorts = [ 51820 ];
  clan.core.facts.services.wireguard = factsGenerator.wireguard { name = "wg0"; };
  clan.core.facts.services.wireguard_ip = factsGenerator.public {
    "wireguard.wg0.endpoint" = "95.216.66.212:51820";
    "wireguard.wg0.cidr" = "10.100.0.1/24";
    "wireguard.wg0.ip" = "10.100.0.1";
  };

  healthchecks.localCommands.ping-wg0 = pkgs.writers.writeBash "ping-wg0" ''
    ping -c 1 -W 5 ${config.clan.core.facts.services.wireguard_ip.public."wireguard.wg0.ip".value}
  '';

  boot.kernel.sysctl."net.ipv4.conf.wg0.forwarding" = true;

  # Enable WireGuard
  networking.wg-quick.interfaces = {
    # Hub and Spoke Setup
    # https://www.procustodibus.com/blog/2020/11/wireguard-hub-and-spoke-config/
    wg0 = {
      address = [ "10.100.0.1/32" ];
      listenPort = 51820; # to match firewall allowedUDPPorts (without this wg uses random port numbers)
      privateKeyFile = config.clan.core.facts.services.wireguard.secret."wireguard.wg0.key".path;
      mtu = 1280;

      postUp = ''
        ${pkgs.iptables}/bin/iptables -A FORWARD -i wg0 -j ACCEPT
      '';
      postDown = ''
        ${pkgs.iptables}/bin/iptables -D FORWARD -i wg0 -j ACCEPT
      '';

      peers = peers ++ [
        # mobil devices
        # -------------
        # start at 100
        {
          # iphone palo
          publicKey = "ICeZLWYzF+nTffMV0+8yfW1WJsUQNhNbKQ4rRbn5hDs=";
          allowedIPs = [ "10.100.0.101/32" ];
        }
        {
          # ipad palo
          publicKey = "wN81/4K2d5tcxqrxnjOpKw9YpAkPdp0/8cCN1B7icVo=";
          allowedIPs = [ "10.100.0.102/32" ];
        }
        {
          # iphone tina
          publicKey = "8f8fYGymH3Tq8d14B2+ijMiHwocEbUIXSZji3U29IhA=";
          allowedIPs = [ "10.100.0.103/32" ];
        }
        {
          # ipad tina
          publicKey = "kuzUJn+lROh7ttA0qMc2p1abpfxjDGeYA+Ryzm88+AE=";
          allowedIPs = [ "10.100.0.104/32" ];
        }
      ];
    };
  };
}