Files
NAHO a2ed7e8d88 nixos: remove optional builtins prefixes from prelude functions
Remove optional builtins prefixes from prelude functions by running:

    builtins=(
      abort
      baseNameOf
      break
      derivation
      derivationStrict
      dirOf
      false
      fetchGit
      fetchMercurial
      fetchTarball
      fetchTree
      fromTOML
      import
      isNull
      map
      null
      placeholder
      removeAttrs
      scopedImport
      throw
      toString
      true
    )

    fd \
      --exclude doc/manual/release-notes \
      --type file \
      . \
      nixos \
      --exec-batch sed --in-place --regexp-extended "
        s/\<builtins\.($(
          printf '%s\n' "${builtins[@]}" |
            paste --delimiter '|' --serial -
        ))\>/\1/g
      "

    nix fmt
2026-01-15 16:07:55 +01:00

282 lines
7.8 KiB
Nix

{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.firewalld;
format = pkgs.formats.xml { };
lib' = import ./lib.nix { inherit lib; };
inherit (lib')
filterNullAttrs
mkPortOption
mkXmlAttr
portProtocolOptions
protocolOption
toXmlAttrs
;
inherit (lib) mkOption;
inherit (lib.types)
attrTag
attrsOf
bool
enum
ints
listOf
nonEmptyStr
nullOr
strMatching
submodule
;
in
{
options.services.firewalld.zones = mkOption {
description = ''
firewalld zone configuration files.
See {manpage}`firewalld.zone(5)`.
'';
default = { };
example = {
public = {
forward = true;
services = [
"ssh"
"dhcpv6-client"
];
};
external = {
forward = true;
services = [
"ssh"
];
masquerade = true;
};
dmz = {
forward = true;
services = [
"ssh"
];
};
work = {
forward = true;
services = [
"ssh"
"dhcpv6-client"
];
};
home = {
forward = true;
services = [
"ssh"
"mdns"
"samba-client"
"dhcpv6-client"
];
};
internal = {
forward = true;
services = [
"ssh"
"mdns"
"samba-client"
"dhcpv6-client"
];
};
};
type = attrsOf (submodule {
options = {
version = mkOption {
type = nullOr nonEmptyStr;
description = "Version of the zone.";
default = null;
};
target = mkOption {
type = enum [
"ACCEPT"
"%%REJECT%%"
"DROP"
];
description = "Action for packets that doesn't match any rules.";
default = "%%REJECT%%";
};
ingressPriority = mkOption {
type = nullOr ints.s16;
description = ''
Priority for inbound traffic.
Lower values have higher priority.
'';
default = null;
};
egressPriority = mkOption {
type = nullOr ints.s16;
description = ''
Priority for outbound traffic.
Lower values have higher priority.
'';
default = null;
};
interfaces = mkOption {
type = listOf nonEmptyStr;
description = "Interfaces to bind.";
default = [ ];
};
sources = mkOption {
type = listOf (attrTag {
address = mkOption {
type = nonEmptyStr;
description = ''
An IP address or a network IP address with a mask for IPv4 or IPv6.
For IPv4, the mask can be a network mask or a plain number.
For IPv6 the mask is a plain number.
The use of host names is not supported.
'';
};
mac = mkOption {
type = strMatching "([[:xdigit:]]{2}:){5}[[:xdigit:]]{2}";
description = "A MAC address.";
};
ipset = mkOption {
type = nonEmptyStr;
description = "An ipset.";
};
});
description = "Source addresses, address ranges, MAC addresses or ipsets to bind.";
default = [ ];
};
icmpBlockInversion = mkOption {
type = bool;
description = ''
Whether to invert the icmp block handling.
Only enabled ICMP types are accepted and all others are rejected in the zone.
'';
default = false;
};
forward = mkOption {
type = bool;
description = ''
Whether to enable intra-zone forwarding.
When enabled, packets will be forwarded between interfaces or sources within a zone, even if the zone's target is not set to ACCEPT.
'';
default = false;
};
short = mkOption {
type = nullOr nonEmptyStr;
description = "Short description for the zone.";
default = null;
};
description = mkOption {
type = nullOr nonEmptyStr;
description = "Description for the zone.";
default = null;
};
services = mkOption {
type = listOf nonEmptyStr;
description = "Services to allow in the zone.";
default = [ ];
};
ports = mkOption {
type = listOf (submodule portProtocolOptions);
description = "Ports to allow in the zone.";
default = [ ];
};
protocols = mkOption {
type = listOf nonEmptyStr;
description = "Protocols to allow in the zone.";
default = [ ];
};
icmpBlocks = mkOption {
type = listOf nonEmptyStr;
description = "ICMP types to block in the zone.";
default = [ ];
};
masquerade = mkOption {
type = bool;
description = "Whether to enable masquerading in the zone.";
default = false;
};
forwardPorts = mkOption {
type = listOf (submodule {
options = {
port = mkPortOption { };
protocol = protocolOption;
to-port = (mkPortOption { optional = true; }) // {
default = null;
};
to-addr = mkOption {
type = nullOr nonEmptyStr;
description = "Destination IP address.";
default = null;
};
};
});
description = "Ports to forward in the zone.";
default = [ ];
};
sourcePorts = mkOption {
type = listOf (submodule portProtocolOptions);
description = "Source ports to allow in the zone.";
default = [ ];
};
rules = mkOption {
type = listOf (format.type);
description = "Rich rules for the zone.";
default = [ ];
};
};
});
};
config = lib.mkIf cfg.enable {
services.firewalld.zones = {
drop = {
target = "DROP";
forward = true;
};
block = {
forward = true;
};
trusted = {
target = "ACCEPT";
forward = true;
};
};
environment.etc = lib.mapAttrs' (
name: value:
lib.nameValuePair "firewalld/zones/${name}.xml" {
source = format.generate "firewalld-zone-${name}.xml" {
zone =
let
mkXmlAttrList = name: map (mkXmlAttr name);
mkXmlTag = value: if value then "" else null;
in
filterNullAttrs (
lib.mergeAttrsList [
(toXmlAttrs { inherit (value) version target; })
(mkXmlAttr "ingress-priority" value.ingressPriority)
(mkXmlAttr "egress-priority" value.egressPriority)
{
interface = mkXmlAttrList "name" value.interfaces;
source = map toXmlAttrs value.sources;
icmp-block-inversion = mkXmlTag value.icmpBlockInversion;
forward = mkXmlTag value.forward;
inherit (value) short description;
service = mkXmlAttrList "name" value.services;
port = map toXmlAttrs value.ports;
protocol = mkXmlAttrList "value" value.protocols;
icmp-block = mkXmlAttrList "name" value.icmpBlocks;
masquerade = mkXmlTag value.masquerade;
forward-port = map toXmlAttrs (map filterNullAttrs value.forwardPorts);
source-port = map toXmlAttrs value.sourcePorts;
rule = value.rules;
}
]
);
};
}
) cfg.zones;
};
}