Skip to content

Instantly share code, notes, and snippets.

@ivan
Created January 8, 2019 11:34
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ivan/05845e04a469f081f7cea55e28b7180e to your computer and use it in GitHub Desktop.
Save ivan/05845e04a469f081f7cea55e28b7180e to your computer and use it in GitHub Desktop.
WireGuard configuration generator for NixOS
{ lib }:
rec {
machines = [
{ hostname = "ra"; ip = "10.10.0.1"; publicKey = "qJ+QobVpqLT7F4fafhrvZgjzzeiSlg6OjQMqdX27PXo="; endpoints = { home = "192.168.10.3:904"; internet = "101.21.7.172:906"; }; }
{ hostname = "plato"; ip = "10.10.0.2"; publicKey = "MBcQj0qf4swKzn1Y3md2Vmtk62HZWi2eN/S4Jeif9lE="; endpoints = { home = "192.168.10.4:904"; internet = "101.21.7.172:905"; }; }
{ hostname = "mojave"; ip = "10.10.0.7"; publicKey = "AKv7fMWxRAH/XPixBon+Ye1keJqiEI8ZD2ArhN1i+2k="; endpoints = { work_vmware_nat = "192.168.27.129:904"; }; }
{ hostname = "paris2"; ip = "10.10.0.11"; publicKey = "QAhGefXPglpLHR/NWK9Sl6M2YMJ9m7h3iFx8lfl9HVY="; endpoints = { internet = "6.21.7.51:904"; }; subdomains = [ "grab-site" ]; }
{ hostname = "icvm"; ip = "10.10.0.20"; publicKey = "uJsqDBJNJpeJAkq3+stcmsYd86l+A3pw3RPNkuBMmmE="; endpoints = { work_vmware_nat = "192.168.27.128:904"; }; subdomains = [ "hydra" ]; }
{ hostname = "bhsvps1"; ip = "10.10.0.9"; publicKey = "OKLXA4s6UqnYXrwMDqXyv3tVFvVAsEAG5eU+QiL2cVA="; endpoints = { internet = "14.2.14.18:904"; }; subdomains = [ "znc" "thelounge" ]; }
{ hostname = "do11"; ip = "10.10.0.24"; publicKey = "iNFYZPufq9TiWjkgWaM3ZtLNly5/A5100KlXF5NW03o="; endpoints = { internet = "62.27.16.16:904"; }; }
{ hostname = "ipad"; ip = "10.10.0.30"; publicKey = "8OA3VRU9HlkhlJCRlpJC6VHCH1t5dR2oDJGx1YovEW4="; endpoints = { }; }
];
__peers = networks: keepaliveTo:
map (machine:
let
firstNetwork = lib.findFirst (network: builtins.hasAttr network machine.endpoints) null networks;
hasKeepalive = builtins.hasAttr machine.hostname keepaliveTo;
in
{
allowedIPs = [ 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;
/* 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.
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:
{
interfaces = {
wg0 = {
ips = [ (ip hostname) ];
listenPort = 904;
privateKeyFile = "/var/secrets/wireguard/wg0/private_key";
peers = __peers networks keepaliveTo;
};
};
};
/* 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