allow multiple devs for same subnet
parent
45b70c9063
commit
1e697eb859
@ -0,0 +1 @@
|
||||
/result
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
{lib, devNameMethod ? "short", ...}@inputs: keyProviders: intermediateConfig: localPeerName:
|
||||
let wnlib = import ../lib.nix {inherit lib;}; in
|
||||
with wnlib;
|
||||
with lib;
|
||||
let
|
||||
thisPeer = intermediateConfig.peers."${localPeerName}";
|
||||
# these aren't really important, I just wanted to reverse the argument order
|
||||
forEachAttr' = flip mapAttrs';
|
||||
forEachAttrToList = flip mapAttrsToList;
|
||||
devName = getDevName devNameMethod localPeerName;
|
||||
in
|
||||
with getKeyProviderFuncs keyProviders inputs intermediateConfig localPeerName;
|
||||
{
|
||||
networking.hosts = foldl' (mergeAttrs) {} (concatLists ( concatLists (forEachAttrToList thisPeer.subnetConnections (subnetName: subnetConnection:
|
||||
forEachAttrToList subnetConnection.peerConnections (remotePeerName: peerConnection: forEach peerConnection.ipAddresses (ip: {"${asIp ip}" = ["${remotePeerName}.${subnetName}"];}))
|
||||
))));
|
||||
systemd.network = {
|
||||
netdevs = forEachAttr' thisPeer.subnetConnections (subnetName: subnetConnection: nameValuePair "50-${devName subnetName}" {
|
||||
netdevConfig = {
|
||||
Kind = "wireguard";
|
||||
Name = "${devName subnetName}";
|
||||
};
|
||||
wireguardConfig = {
|
||||
ListenPort = subnetConnection.listenPort;
|
||||
PrivateKeyFile = getPrivKeyFile;
|
||||
};
|
||||
wireguardPeers = forEachAttrToList subnetConnection.peerConnections (remotePeerName: peerConnection: {
|
||||
wireguardPeerConfig = {
|
||||
Endpoint = "${peerConnection.endpoint.ip}:${builtins.toString peerConnection.endpoint.port}";
|
||||
PublicKey = getPeerPubKey remotePeerName;
|
||||
AllowedIPs = map (ip: asCidr ip) peerConnection.ipAddresses;
|
||||
PresharedKeyFile = getSubnetPSKFile subnetName;
|
||||
};
|
||||
}
|
||||
// (if peerConnection.endpoint ? persistentKeepalive then {PersistentKeepalive = peerConnection.endpoint.persistentKeepalive;} else {})
|
||||
// (warnIf (peerConnection.endpoint ? dynamicEndpointRefreshSeconds) "dynamicEndpointRefreshSeconds not supported for networkd" {})
|
||||
// (warnIf (peerConnection.endpoint ? dynamicEndpointRefreshRestartSeconds) "dynamicEndpointRefreshRestartSeconds not supported for networkd" {})
|
||||
);
|
||||
});
|
||||
};
|
||||
} // getProviderConfig
|
@ -0,0 +1,104 @@
|
||||
{
|
||||
version = "v1";
|
||||
subnets = [
|
||||
{
|
||||
name = "ring";
|
||||
endpoints = [
|
||||
{}
|
||||
];
|
||||
}
|
||||
];
|
||||
groups = [
|
||||
# groups field is expected, but can be empty
|
||||
];
|
||||
peers = [
|
||||
{
|
||||
name = "peer1";
|
||||
subnets = {
|
||||
ring = {
|
||||
listenPort = 51820;
|
||||
# empty ipAddresses will auto generate an IPv6 address
|
||||
};
|
||||
};
|
||||
publicKey = "kdyzqV8cBQtDYeW6R1vUug0Oe+KaytHHDS7JoCp/kTE=";
|
||||
privateKeyFile = "/etc/wg-key1";
|
||||
endpoints = [
|
||||
{
|
||||
# no match can be any
|
||||
ip = "node1";
|
||||
port = 51820;
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
name = "peer2";
|
||||
subnets = {
|
||||
ring = {
|
||||
listenPort = 51820;
|
||||
};
|
||||
};
|
||||
publicKey = "ztdAXTspQEZUNpxUbUdAhhRWbiL3YYWKSK0ZGdcsMHE=";
|
||||
privateKeyFile = "/etc/wg-key2";
|
||||
endpoints = [
|
||||
{
|
||||
# no match can be any
|
||||
ip = "node2";
|
||||
port = 51820;
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
name = "peer3";
|
||||
subnets = {
|
||||
ring = {
|
||||
listenPort = 51821;
|
||||
# empty ipAddresses will auto generate an IPv6 address
|
||||
};
|
||||
};
|
||||
publicKey = "43tP6JgckdTFrnbYuy8a42jdNt3+wwVcb4+ae5U4ez4=";
|
||||
privateKeyFile = "/etc/wg-key3";
|
||||
endpoints = [
|
||||
{
|
||||
# no match can be any
|
||||
ip = "node1";
|
||||
port = 51821;
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
name = "peer4";
|
||||
subnets = {
|
||||
ring = {
|
||||
listenPort = 51821;
|
||||
};
|
||||
};
|
||||
publicKey = "g6+Tq9aeVfm5CXPIwZDqoTxGmsQ/TlLtxcxVn2aSiVA=";
|
||||
privateKeyFile = "/etc/wg-key4";
|
||||
endpoints = [
|
||||
{
|
||||
# no match can be any
|
||||
ip = "node2";
|
||||
port = 51821;
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
connections = [
|
||||
{
|
||||
a = [{type= "peer"; rule = "is"; value = "peer1";}];
|
||||
b = [{type= "peer"; rule = "is"; value = "peer2";}];
|
||||
}
|
||||
{
|
||||
a = [{type= "peer"; rule = "is"; value = "peer2";}];
|
||||
b = [{type= "peer"; rule = "is"; value = "peer3";}];
|
||||
}
|
||||
{
|
||||
a = [{type= "peer"; rule = "is"; value = "peer3";}];
|
||||
b = [{type= "peer"; rule = "is"; value = "peer4";}];
|
||||
}
|
||||
{
|
||||
a = [{type= "peer"; rule = "is"; value = "peer4";}];
|
||||
b = [{type= "peer"; rule = "is"; value = "peer1";}];
|
||||
}
|
||||
];
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
(import ./lib.nix) ({wnlib}:
|
||||
{
|
||||
name = "double dev ring connection";
|
||||
nodes = {
|
||||
# `self` here is set by using specialArgs in `lib.nix`
|
||||
node1 = { self, pkgs, ... }: {
|
||||
virtualisation.vlans = [ 1 ];
|
||||
imports = [ self.nixosModules.default ];
|
||||
systemd.network.enable = true;
|
||||
wirenix = {
|
||||
configurer = "networkd";
|
||||
devNameMethod = "hash";
|
||||
enable = true;
|
||||
aclConfig = import ./acls/double-dev-ring.nix;
|
||||
peerNames = ["peer1" "peer3"];
|
||||
};
|
||||
environment.etc."wg-key1" = {
|
||||
text = "MIELhEc0I7BseAanhk/+LlY/+Yf7GK232vKWITExnEI=";
|
||||
};
|
||||
environment.etc."wg-key3" = {
|
||||
text = "yPcTvQOK9eVXQjLNapOsv2iAkbOeSzCCxlrWPMe1o0g=";
|
||||
};
|
||||
environment.systemPackages = [pkgs.wireguard-tools];
|
||||
networking.firewall.enable = false;
|
||||
};
|
||||
|
||||
node2 = { self, pkgs, ... }: {
|
||||
virtualisation.vlans = [ 1 ];
|
||||
imports = [ self.nixosModules.default ];
|
||||
systemd.network.enable = true;
|
||||
wirenix = {
|
||||
configurer = "networkd";
|
||||
devNameMethod = "hash";
|
||||
enable = true;
|
||||
keyProviders = ["acl"];
|
||||
aclConfig = import ./acls/double-dev-ring.nix;
|
||||
peerNames = ["peer2" "peer4"];
|
||||
};
|
||||
environment.etc."wg-key2" = {
|
||||
text = "yG4mJiduoAvzhUJMslRbZwOp1gowSfC+wgY8B/Mul1M=";
|
||||
};
|
||||
environment.etc."wg-key4" = {
|
||||
text = "CLREBQ+oGXsGxhlQc3ufSoBd7MNFoM6KmMnNyuQ9S0E=";
|
||||
};
|
||||
environment.systemPackages = [pkgs.wireguard-tools];
|
||||
networking.firewall.enable = false;
|
||||
};
|
||||
};
|
||||
# This is the test code that will check if our service is running correctly:
|
||||
testScript = ''
|
||||
start_all()
|
||||
nodes = {
|
||||
"peer1": node1,
|
||||
"peer2": node2,
|
||||
"peer3": node1,
|
||||
"peer4": node2
|
||||
}
|
||||
ifaces = {
|
||||
"peer1": "${wnlib.getDevName "hash" "peer1" "ring"}",
|
||||
"peer2": "${wnlib.getDevName "hash" "peer2" "ring"}",
|
||||
"peer3": "${wnlib.getDevName "hash" "peer3" "ring"}",
|
||||
"peer4": "${wnlib.getDevName "hash" "peer4" "ring"}"
|
||||
}
|
||||
connections = {
|
||||
"peer1": ["peer2", "peer4"],
|
||||
"peer2": ["peer3", "peer1"],
|
||||
"peer3": ["peer4", "peer2"],
|
||||
"peer4": ["peer1", "peer3"]
|
||||
}
|
||||
node1.wait_for_unit("systemd-networkd-wait-online")
|
||||
node2.wait_for_unit("systemd-networkd-wait-online")
|
||||
node1.succeed("ping -c 3 node2 >&2")
|
||||
node2.succeed("ping -c 3 node1 >&2")
|
||||
for local_name, local_node in nodes.items():
|
||||
for remote_name in set(nodes.keys()) - set([local_name]):
|
||||
if remote_name in connections[local_name]:
|
||||
local_node.succeed(f"ping -c 3 -I {ifaces[local_name]} {remote_name}.ring >&2")
|
||||
else:
|
||||
local_node.fail(f"ping -c 3 -W 1 -I {ifaces[local_name]} {remote_name}.ring")
|
||||
'';
|
||||
})
|
Loading…
Reference in New Issue