nix-conf/system/dev/dn-server/options/network.nix
2026-01-10 12:46:40 +08:00

102 lines
2.4 KiB
Nix
Executable file

{
lib,
pkgs,
config,
...
}:
let
inherit (lib)
mkOption
types
concatStringsSep
unique
;
cfg = config.systemConf.security;
in
{
options.systemConf.security = {
allowedDomains = mkOption {
type = with types; listOf str;
description = "Domains that allowed to query dns.";
default = [ ];
apply = v: unique v;
};
rules = {
setName = mkOption {
type = with types; str;
default = "allowed_output_ips";
readOnly = true;
};
setNameV6 = mkOption {
type = with types; str;
default = "allowed_output_ipv6";
readOnly = true;
};
};
dnsIPs = mkOption {
type = with types; listOf str;
description = "External DNS server to use";
default = [ "8.8.8.8" ];
};
allowedIPs = mkOption {
type = with types; listOf str;
description = "IPv4 that allowed to request.";
default = [ ];
};
allowedIPv6 = mkOption {
type = with types; listOf str;
description = "IPv6 that allowed to request.";
default = [ ];
};
sourceIPs = mkOption {
type = with types; listOf str;
description = "Source IPs to restrict.";
default = [ ];
};
};
config = {
environment.systemPackages = with pkgs; [
ipset
];
systemd.timers.fetch-allowed-domains = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnBootSec = 10;
OnUnitActiveSec = 360;
};
};
systemd.services.fetch-allowed-domains =
let
script = pkgs.writeShellScript "fetch-allowed-domains" ''
DOMAINS=(${toString (map (x: ''"${x}"'') cfg.allowedDomains)})
SETNAME="inet filter ${cfg.rules.setName}"
nft flush set $SETNAME
nft add element $SETNAME { ${concatStringsSep "," cfg.allowedIPs} }
for domain in "''${DOMAINS[@]}"; do
ips=$(dig +short A $domain | grep -E '^[0-9.]+$')
for ip in $ips; do
nft add element $SETNAME { $ip }
echo "Added $ip for $domain"
done
done
'';
in
{
path = with pkgs; [
nftables
dig.dnsutils
];
after = [ "network.target" ];
serviceConfig = {
ExecStart = "${script}";
Type = "oneshot";
};
restartTriggers = [ script ];
};
};
}