services: wireguard: set up DNS server on clients
This makes use of my newly written adblocking DNS service, it does assume that the server would have both wireguard and DNS enabled. I would also like to move to using my ip-related library functions, however it does not support IPv6 and is unlikely to be easily added... But I am not sure that I *need* IPv6 support for my use-case. Finally, I find this module a bit too heavy, it could be improved by having specific 'server' and 'client' roles, instead of implicit roles depending on whether an external IP exists.
This commit is contained in:
parent
3696471201
commit
f79fcd020b
|
@ -9,7 +9,14 @@ let
|
||||||
|
|
||||||
peers = config.my.secrets.wireguard.peers;
|
peers = config.my.secrets.wireguard.peers;
|
||||||
thisPeer = peers."${hostName}";
|
thisPeer = peers."${hostName}";
|
||||||
otherPeers = lib.filterAttrs (name: _: name != hostName) peers;
|
thisPeerIsServer = thisPeer ? externalIp;
|
||||||
|
# Only connect to clients from server, and only connect to server from clients
|
||||||
|
otherPeers =
|
||||||
|
let
|
||||||
|
allOthers = lib.filterAttrs (name: _: name != hostName) peers;
|
||||||
|
shouldConnectToPeer = _: peer: thisPeerIsServer != (peer ? externalIp);
|
||||||
|
in
|
||||||
|
lib.filterAttrs shouldConnectToPeer allOthers;
|
||||||
|
|
||||||
extIface = config.my.networking.externalInterface;
|
extIface = config.my.networking.externalInterface;
|
||||||
in
|
in
|
||||||
|
@ -31,7 +38,27 @@ in
|
||||||
description = "Port to configure for Wireguard";
|
description = "Port to configure for Wireguard";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
dns = {
|
||||||
|
useInternal = my.mkDisableOption ''
|
||||||
|
Use internal DNS servers from wireguard 'server'
|
||||||
|
'';
|
||||||
|
|
||||||
|
additionalServers = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [
|
||||||
|
"1.0.0.1"
|
||||||
|
"1.1.1.1"
|
||||||
|
];
|
||||||
|
example = [
|
||||||
|
"8.8.4.4"
|
||||||
|
"8.8.8.8"
|
||||||
|
];
|
||||||
|
description = "Which DNS servers to use in addition to adblock ones";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
net = {
|
net = {
|
||||||
|
# FIXME: use new ip library to handle this more cleanly
|
||||||
v4 = {
|
v4 = {
|
||||||
subnet = mkOption {
|
subnet = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
@ -46,6 +73,7 @@ in
|
||||||
description = "The CIDR mask to use on internal IPs";
|
description = "The CIDR mask to use on internal IPs";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
# FIXME: extend library for IPv6
|
||||||
v6 = {
|
v6 = {
|
||||||
subnet = mkOption {
|
subnet = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
@ -76,7 +104,7 @@ in
|
||||||
peers = lib.mapAttrsToList
|
peers = lib.mapAttrsToList
|
||||||
(_: peer: {
|
(_: peer: {
|
||||||
inherit (peer) publicKey;
|
inherit (peer) publicKey;
|
||||||
} // lib.optionalAttrs (thisPeer ? externalIp) {
|
} // lib.optionalAttrs thisPeerIsServer {
|
||||||
# Only forward from server to clients
|
# Only forward from server to clients
|
||||||
allowedIPs = with cfg.net; [
|
allowedIPs = with cfg.net; [
|
||||||
"${v4.subnet}.${toString peer.clientNum}/32"
|
"${v4.subnet}.${toString peer.clientNum}/32"
|
||||||
|
@ -85,7 +113,7 @@ in
|
||||||
} // lib.optionalAttrs (peer ? externalIp) {
|
} // lib.optionalAttrs (peer ? externalIp) {
|
||||||
# Known addresses
|
# Known addresses
|
||||||
endpoint = "${peer.externalIp}:${toString cfg.port}";
|
endpoint = "${peer.externalIp}:${toString cfg.port}";
|
||||||
} // lib.optionalAttrs (!(thisPeer ? externalIp)) {
|
} // lib.optionalAttrs (!thisPeerIsServer) {
|
||||||
# Forward all traffic to server
|
# Forward all traffic to server
|
||||||
allowedIPs = with cfg.net; [
|
allowedIPs = with cfg.net; [
|
||||||
"0.0.0.0/0"
|
"0.0.0.0/0"
|
||||||
|
@ -93,10 +121,9 @@ in
|
||||||
];
|
];
|
||||||
# Roaming clients need to keep NAT-ing active
|
# Roaming clients need to keep NAT-ing active
|
||||||
persistentKeepalive = 10;
|
persistentKeepalive = 10;
|
||||||
# Use server DNS
|
|
||||||
})
|
})
|
||||||
otherPeers;
|
otherPeers;
|
||||||
} // lib.optionalAttrs (thisPeer ? externalIp) {
|
} // lib.optionalAttrs thisPeerIsServer {
|
||||||
# Setup forwarding on server
|
# Setup forwarding on server
|
||||||
postUp = with cfg.net; ''
|
postUp = with cfg.net; ''
|
||||||
${pkgs.iptables}/bin/iptables -A FORWARD -i ${cfg.iface} -j ACCEPT
|
${pkgs.iptables}/bin/iptables -A FORWARD -i ${cfg.iface} -j ACCEPT
|
||||||
|
@ -110,10 +137,24 @@ in
|
||||||
${pkgs.iptables}/bin/ip6tables -D FORWARD -i ${cfg.iface} -j ACCEPT
|
${pkgs.iptables}/bin/ip6tables -D FORWARD -i ${cfg.iface} -j ACCEPT
|
||||||
${pkgs.iptables}/bin/ip6tables -t nat -D POSTROUTING -s ${v6.subnet}::1/${toString v6.mask} -o ${extIface} -j MASQUERADE
|
${pkgs.iptables}/bin/ip6tables -t nat -D POSTROUTING -s ${v6.subnet}::1/${toString v6.mask} -o ${extIface} -j MASQUERADE
|
||||||
'';
|
'';
|
||||||
|
} // lib.optionalAttrs (!thisPeerIsServer) {
|
||||||
|
# Use DNS servers hosted on wireguard servers
|
||||||
|
dns =
|
||||||
|
let
|
||||||
|
isServer = _: peer: peer ? externalIp;
|
||||||
|
toInternalIps = peer: [
|
||||||
|
"${cfg.net.v4.subnet}.${toString peer.clientNum}"
|
||||||
|
"${cfg.net.v6.subnet}::${toString peer.clientNum}"
|
||||||
|
];
|
||||||
|
servers = lib.filterAttrs isServer otherPeers;
|
||||||
|
internalIps = lib.flatten
|
||||||
|
(lib.mapAttrsToList (_: peer: toInternalIps peer) servers);
|
||||||
|
internalServers = lib.optionals cfg.dns.useInternal internalIps;
|
||||||
|
in
|
||||||
|
internalServers ++ cfg.dns.additionalServers;
|
||||||
};
|
};
|
||||||
|
|
||||||
nat = lib.optionalAttrs (thisPeer ? externalIp) {
|
nat = lib.optionalAttrs thisPeerIsServer {
|
||||||
enable = true;
|
enable = true;
|
||||||
externalInterface = extIface;
|
externalInterface = extIface;
|
||||||
internalInterfaces = [ cfg.iface ];
|
internalInterfaces = [ cfg.iface ];
|
||||||
|
|
Loading…
Reference in a new issue