Copy in current modules from my personal nix config
d17ef00e1c/services/birdsong
This commit is contained in:
parent
e4b56fe024
commit
04e5519bf3
3 changed files with 231 additions and 0 deletions
91
peering.nix
Normal file
91
peering.nix
Normal file
|
@ -0,0 +1,91 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.birdsong.peering;
|
||||
hostName = if null != cfg.hostName then cfg.hostName else config.networking.hostName;
|
||||
hosts = config.birdsong.hosts;
|
||||
host = hosts.${hostName};
|
||||
in
|
||||
{
|
||||
options.birdsong.peering = {
|
||||
enable = mkEnableOption "WireGuard peering with the birdsong network";
|
||||
hostName = mkOption {
|
||||
default = null;
|
||||
description = ''
|
||||
The hostname of this peer within the network. Must be listed in
|
||||
{option}`birdsong.hosts`. If not set, defaults to
|
||||
{option}`networking.hostName`.
|
||||
'';
|
||||
type = with types; nullOr str;
|
||||
};
|
||||
interface = mkOption {
|
||||
default = "birdsong";
|
||||
example = "wg0";
|
||||
description = "The name of the network interface to use for WireGuard.";
|
||||
type = types.str;
|
||||
};
|
||||
openPorts = mkOption {
|
||||
default = true;
|
||||
description = "Whether to automatically open firewall ports.";
|
||||
type = types.bool;
|
||||
};
|
||||
privateKeyFile = mkOption {
|
||||
description = "Path to the private key for this peer, as generated by `wg genkey`.";
|
||||
type = types.path;
|
||||
};
|
||||
persistentKeepalive = mkOption {
|
||||
default = null;
|
||||
example = 23;
|
||||
description = ''
|
||||
Constantly ping each peer outside the LAN this often, in seconds, in
|
||||
order to keep the WireGuard tunnel open. Set this if you are behind NAT
|
||||
to keep the NAT session active, or if you have a dynamic IP to keep the
|
||||
other peers aware when your IP changes. To avoid syncing, this should
|
||||
ideally be a prime number that is not shared by another peer in the same
|
||||
LAN.
|
||||
'';
|
||||
type = with types; nullOr int;
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg ? privateKeyFile;
|
||||
message = "birdsong.peering.privateKeyFile must be set";
|
||||
}
|
||||
{
|
||||
assertion = hostName != null;
|
||||
message = "birdsong.peering.hostName or networking.hostName must be set";
|
||||
}
|
||||
];
|
||||
|
||||
networking = {
|
||||
firewall.allowedUDPPorts = mkIf cfg.openPorts [ host.port ];
|
||||
|
||||
wireguard.interfaces.${cfg.interface} = {
|
||||
ips = [ "${host.ipv4}/16" "${host.ipv6}/48" ]
|
||||
++ optionals host.isRouter [ "10.127.0.0/16" "fd70:81ca:0f8f::/48" ];
|
||||
privateKeyFile = cfg.privateKeyFile;
|
||||
listenPort = host.port;
|
||||
|
||||
peers =
|
||||
let
|
||||
canDirectPeer = host: peer: peer.subnet == "internet" || (host.subnet != "roaming" && peer.subnet == host.subnet);
|
||||
in
|
||||
mapAttrsToList
|
||||
(name: peer: {
|
||||
name = name;
|
||||
publicKey = peer.wireguardKey;
|
||||
allowedIPs = [ peer.ipv4 peer.ipv6 ]
|
||||
++ optionals peer.isRouter [ "10.127.0.0/16" "fd70:81ca:0f8f::/48" ];
|
||||
endpoint = mkIf (canDirectPeer host peer) "${peer.endpoint}:${toString peer.port}";
|
||||
dynamicEndpointRefreshSeconds = mkIf (canDirectPeer host peer) 5;
|
||||
persistentKeepalive = mkIf (peer.subnet != host.subnet) cfg.persistentKeepalive;
|
||||
})
|
||||
(filterAttrs (name: peer: peer != host && (host.subnet == "internet" || canDirectPeer host peer)) hosts);
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue