Update headscale configuration

This commit is contained in:
Fabian Hauser 2024-12-06 19:08:11 +02:00
parent 52bc3cc708
commit 2fb1a1bec8
2 changed files with 69 additions and 56 deletions

View file

@ -15,7 +15,7 @@
id = "100.64.0.0"; id = "100.64.0.0";
prefixLength = 10; prefixLength = 10;
}; };
domain = "vpn.qo.is"; domain = "vpn.net.qo.is";
hosts = { }; hosts = { };
}; };

View file

@ -16,6 +16,11 @@ in
options.qois.vpn-server = { options.qois.vpn-server = {
enable = mkEnableOption "Enable vpn server services"; enable = mkEnableOption "Enable vpn server services";
domain = mkOption {
description = "Domain for the VPN admin server";
type = types.str;
default = "vpn.qo.is";
};
dnsRecords = mkOption { dnsRecords = mkOption {
description = "DNS records to add to Hosts"; description = "DNS records to add to Hosts";
type = with types; attrsOf str; type = with types; attrsOf str;
@ -36,8 +41,8 @@ in
with config.services.headscale.settings; with config.services.headscale.settings;
( (
[ [
db_path database.sqlite.path
private_key_path derp.server.private_key_path
noise.private_key_path noise.private_key_path
] ]
++ derp.paths ++ derp.paths
@ -56,22 +61,22 @@ in
in in
{ {
enable = true; enable = true;
address = vnet.backplane.hosts.cyprianspitz.v4.ip; address = vnet.backplane.hosts.cyprianspitz.v4.ip; # TODO: This entails that the backplane interface is up.
port = 46084; port = 46084;
settings = { settings = {
server_url = "https://${vpnNet.domain}:443"; server_url = "https://${cfg.domain}:443";
tls_letsencrypt_challenge_type = "TLS-ALPN-01"; tls_letsencrypt_challenge_type = "TLS-ALPN-01";
tls_letsencrypt_hostname = vpnNet.domain; tls_letsencrypt_hostname = vpnNet.domain;
dns_config = { dns = {
nameservers = [ vnet.backplane.hosts.calanda.v4.ip ]; base_domain = vpnNet.domain;
domains = [ magic_dns = true;
vpnNet.domain nameservers.global = [ vnet.backplane.hosts.calanda.v4.ip ];
search_domains = [
# vpnNet.domain # First by default with magic_dns
vnet.backplane.domain vnet.backplane.domain
]; ];
magic_dns = true;
base_domain = vpnNet.domain;
extra_records = pipe cfg.dnsRecords [ extra_records = pipe cfg.dnsRecords [
attrsToList attrsToList
(map (val: val // { type = "A"; })) (map (val: val // { type = "A"; }))
@ -80,56 +85,64 @@ in
ip_prefixes = [ vpnNetPrefix ]; ip_prefixes = [ vpnNetPrefix ];
acl_policy_path = pkgs.writeTextFile { policy =
name = "acls"; let
text = builtins.toJSON { # Note: headscale has limited acl support currently. This might change in the future.
hosts = { aclPolicy = {
"clients" = vpnNetPrefix; hosts = {
}; "clients" = vpnNetPrefix;
groups = {
"group:wheel" = cfg.wheelUsers;
};
tagOwners = {
"tag:srv" = [ "srv" ]; # srv tag ist owned by srv user
};
autoApprovers = {
exitNode = [
"tag:srv"
"group:wheel"
];
routes = {
${backplaneNetPrefix} = [ "tag:srv" ];
}; };
}; groups = {
"group:wheel" = cfg.wheelUsers;
acls = [ };
# Allow all communication from and to srv tagged hosts tagOwners = {
{ "tag:srv" = [ "srv" ]; # srv tag ist owned by srv user
action = "accept"; };
src = [ autoApprovers = {
exitNode = [
"tag:srv" "tag:srv"
"srv" "group:wheel"
]; ];
dst = [ "*:*" ]; routes = {
} ${backplaneNetPrefix} = [ "tag:srv" ];
{ };
action = "accept"; };
src = [ "*" ];
dst = [
"tag:srv:*"
"srv:*"
];
}
# Allow access to all connected hosts for wheels acls = [
{ # Allow all communication from and to srv tagged hosts
action = "accept"; {
src = [ "group:wheel" ]; action = "accept";
dst = [ "*:*" ]; src = [
} "tag:srv"
]; "srv"
];
dst = [ "*:*" ];
}
{
action = "accept";
src = [ "*" ];
dst = [
"tag:srv:*"
"srv:*"
];
}
# Allow access to all connected hosts for wheels
{
action = "accept";
src = [ "group:wheel" ];
dst = [ "*:*" ];
}
];
};
in
{
mode = "file";
path = pkgs.writeTextFile {
name = "acls";
text = builtins.toJSON aclPolicy;
};
}; };
};
}; };
}; };
}); });