Skip to content

Instantly share code, notes, and snippets.

@ivan ivan/wireguard.nix Secret

Created May 20, 2019
Embed
What would you like to do?
{ lib }:
rec {
machines = [
{ hostname = "ra"; ip = "10.10.0.1"; port = 906; publicKey = "..."; endpoints = { home = "192.168.10.3:906"; internet = "1.2.44.179:906"; }; subdomains = [ "torrent" ]; }
{ hostname = "plato"; ip = "10.10.0.2"; port = 905; publicKey = "..."; endpoints = { home = "192.168.10.4:905"; internet = "1.2.44.179:905"; }; }
{ hostname = "scale8"; ip = "10.10.0.6"; port = 904; publicKey = "..."; endpoints = { internet = "1.2.133.251:904"; }; }
{ hostname = "scale9"; ip = "10.10.0.12"; port = 904; publicKey = "..."; endpoints = { internet = "1.2.242.195:904"; }; }
{ hostname = "scale10"; ip = "10.10.0.13"; port = 904; publicKey = "..."; endpoints = { internet = "1.2.196.64:904"; }; }
{ hostname = "scale11"; ip = "10.10.0.15"; port = 904; publicKey = "..."; endpoints = { internet = "1.2.145.234:904"; }; }
{ hostname = "bhsvps1"; ip = "10.10.0.9"; port = 904; publicKey = "..."; endpoints = { internet = "1.2.14.68:904"; }; subdomains = [ "znc" "thelounge" ]; }
{ hostname = "iphone"; ip = "10.10.0.21"; port = 904; publicKey = "..."; endpoints = { }; }
{ hostname = "ipadmini4"; ip = "10.10.0.22"; port = 904; publicKey = "..."; endpoints = { }; }
{ hostname = "do11"; ip = "10.10.0.24"; port = 904; publicKey = "..."; endpoints = { internet = "1.2.16.69:904"; }; }
{ hostname = "icvm"; ip = "10.10.0.20"; port = 904; publicKey = "..."; endpoints = { work_vmware_nat = "192.168.197.128:904"; }; }
{ hostname = "mojave"; ip = "10.10.0.23"; port = 904; publicKey = "..."; endpoints = { work_vmware_nat = "192.168.197.129:904"; }; }
{ hostname = "almac"; ip = "10.10.0.30"; port = 904; publicKey = "..."; endpoints = { }; }
{ hostname = "alphone"; ip = "10.10.0.31"; port = 904; publicKey = "..."; endpoints = { }; }
{ hostname = "alpad"; ip = "10.10.0.32"; port = 904; publicKey = "..."; endpoints = { }; }
{ hostname = "windows10"; ip = "10.10.0.3"; port = 907; publicKey = "..."; endpoints = { home = "192.168.10.5:907"; }; }
{ hostname = "work"; ip = "10.10.0.4"; port = 905; publicKey = "..."; endpoints = { work_vmware_nat = "192.168.197.1:905"; }; }
{ hostname = "finssd1"; ip = "10.10.0.8"; port = 904; publicKey = "..."; endpoints = { internet = "1.2.46.171:904"; }; subdomains = [ "grab-site" "torrent" "grafana" "prometheus" "hydra" ]; }
{ hostname = "finhdd1"; ip = "10.10.0.7"; port = 904; publicKey = "..."; endpoints = { internet = "1.2.226.236:904"; }; subdomains = [ "grab-site" "torrent" ]; }
];
__peers = networks: keepaliveTo: routeThrough:
map (machine:
let
firstNetwork = lib.findFirst (network: builtins.hasAttr network machine.endpoints) null networks;
hasKeepalive = builtins.hasAttr machine.hostname keepaliveTo;
in
{
allowedIPs = if routeThrough == machine.hostname then [ "0.0.0.0/0" ] else [ machine.ip ];
publicKey = machine.publicKey;
} // (if firstNetwork == null then { } else { endpoint = machine.endpoints.${firstNetwork}; })
// (if !hasKeepalive then { } else { persistentKeepalive = keepaliveTo.${machine.hostname}; })
) machines;
/* Get WireGuard IP for a hostname */
ip = hostname:
let
row = lib.findFirst (machine: machine.hostname == hostname) null machines;
in
row.ip;
/* Get WireGuard port for a hostname */
port = hostname:
let
row = lib.findFirst (machine: machine.hostname == hostname) null machines;
in
row.port;
/* A wireguard configuration for config.networking.wireguard
`hostName` is this machine's hostname.
`networks` is this machine's networks.
`keepaliveTo` is an attrset of machines { machine = INTERVAL; } to send
keepalive pings to; this will allow the peer machines to connect to a
machine that is behind a NAT on which port forwards cannot be set up.
`routeThrough` is the hostname of the machine to route all non-specific
traffic through (this will set AllowedIPs to 0.0.0.0/0 instead of the
machine's WireGuard IP address).
Each peer's endpoint is chosen based on the closest network, i.e. the
first-matching network in the `networks` list for which a peer endpoint
is available.
Example:
config "icvm" [ "work_vmware_nat" "internet" ] { ra = 25; plato = 25; }
*/
config = { hostName, networks, keepaliveTo ? { }, routeThrough ? null }:
{
interfaces = {
wg0 = {
ips = [ (ip hostName) ];
listenPort = (port hostName);
privateKeyFile = "/var/secrets/wireguard/wg0/private_key";
peers = __peers networks keepaliveTo routeThrough;
};
};
};
/* A list of wireguard hosts that can be added to config.networking.hosts */
hosts =
builtins.listToAttrs (
map (machine:
{
name = machine.ip;
value = [ "${machine.hostname}.wg" ] ++ map (subdomain: "${subdomain}.${machine.hostname}.wg") (machine.subdomains or []);
}
) machines
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.