turn nftables firewall into a service-providing module
This commit is contained in:
parent
73e5916cc5
commit
d7f3e05063
4 changed files with 114 additions and 56 deletions
|
@ -35,39 +35,13 @@ in rec {
|
||||||
../modules/standard.nix
|
../modules/standard.nix
|
||||||
../modules/ppp
|
../modules/ppp
|
||||||
../modules/dnsmasq
|
../modules/dnsmasq
|
||||||
|
../modules/firewall
|
||||||
];
|
];
|
||||||
rootfsType = "jffs2";
|
rootfsType = "jffs2";
|
||||||
hostname = "rotuer";
|
hostname = "rotuer";
|
||||||
kernel = {
|
kernel = {
|
||||||
config = {
|
config = {
|
||||||
BRIDGE = "y";
|
BRIDGE = "y";
|
||||||
|
|
||||||
NETFILTER_XT_MATCH_CONNTRACK = "y";
|
|
||||||
|
|
||||||
IP6_NF_IPTABLES= "y"; # do we still need these
|
|
||||||
IP_NF_IPTABLES= "y"; # if using nftables directly
|
|
||||||
|
|
||||||
IP_NF_NAT = "y";
|
|
||||||
IP_NF_TARGET_MASQUERADE = "y";
|
|
||||||
NETFILTER = "y";
|
|
||||||
NETFILTER_ADVANCED = "y";
|
|
||||||
NETFILTER_XTABLES = "y";
|
|
||||||
|
|
||||||
NFT_COMPAT = "y";
|
|
||||||
NFT_CT = "y";
|
|
||||||
NFT_LOG = "y";
|
|
||||||
NFT_MASQ = "y";
|
|
||||||
NFT_NAT = "y";
|
|
||||||
NFT_REJECT = "y";
|
|
||||||
NFT_REJECT_INET = "y";
|
|
||||||
|
|
||||||
NF_CONNTRACK = "y";
|
|
||||||
NF_NAT = "y";
|
|
||||||
NF_NAT_MASQUERADE = "y";
|
|
||||||
NF_TABLES= "y";
|
|
||||||
NF_TABLES_INET = "y";
|
|
||||||
NF_TABLES_IPV4 = "y";
|
|
||||||
NF_TABLES_IPV6 = "y";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -221,33 +195,9 @@ in rec {
|
||||||
};
|
};
|
||||||
|
|
||||||
services.firewall =
|
services.firewall =
|
||||||
let
|
let ruleset = import ./rotuer-firewall.nix;
|
||||||
script= pkgs.firewallgen "firewall.nft" (import ./rotuer-firewall.nix);
|
in config.system.service.firewall {
|
||||||
kmodules = pkgs.kernel-modules.override {
|
inherit ruleset;
|
||||||
kernelSrc = config.system.outputs.kernel.src;
|
|
||||||
modulesupport = config.system.outputs.kernel.modulesupport;
|
|
||||||
kconfig = {
|
|
||||||
NFT_FIB_IPV4 = "m";
|
|
||||||
NFT_FIB_IPV6 = "m";
|
|
||||||
NF_TABLES = "m";
|
|
||||||
NF_CT_PROTO_DCCP = "y";
|
|
||||||
NF_CT_PROTO_SCTP = "y";
|
|
||||||
NF_CT_PROTO_UDPLITE = "y";
|
|
||||||
# NF_CONNTRACK_FTP = "m";
|
|
||||||
NFT_CT = "m";
|
|
||||||
};
|
|
||||||
targets = [
|
|
||||||
"nft_fib_ipv4"
|
|
||||||
"nft_fib_ipv6"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
in oneshot {
|
|
||||||
name = "firewall";
|
|
||||||
up = ''
|
|
||||||
sh ${kmodules}/load.sh
|
|
||||||
${script};
|
|
||||||
'';
|
|
||||||
down = "${pkgs.nftables}/bin/nft flush ruleset";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
services.packet_forwarding =
|
services.packet_forwarding =
|
||||||
|
|
|
@ -26,6 +26,11 @@ in {
|
||||||
};
|
};
|
||||||
kernel = {
|
kernel = {
|
||||||
src = mkOption { type = types.package; } ;
|
src = mkOption { type = types.package; } ;
|
||||||
|
modular = mkOption {
|
||||||
|
type = types.boolean;
|
||||||
|
default = true;
|
||||||
|
description = "support loadable kernel modules";
|
||||||
|
};
|
||||||
extraPatchPhase = mkOption {
|
extraPatchPhase = mkOption {
|
||||||
default = "true";
|
default = "true";
|
||||||
type = types.lines;
|
type = types.lines;
|
||||||
|
@ -67,14 +72,15 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
kernel = rec {
|
kernel = rec {
|
||||||
|
modular = true; # disabling this is not yet supported
|
||||||
config = {
|
config = {
|
||||||
IKCONFIG = "y";
|
IKCONFIG = "y";
|
||||||
IKCONFIG_PROC = "y";
|
IKCONFIG_PROC = "y";
|
||||||
PROC_FS = "y";
|
PROC_FS = "y";
|
||||||
|
|
||||||
KEXEC = "y";
|
KEXEC = "y";
|
||||||
MODULES = "y";
|
MODULES = if modular then "y" else "n";
|
||||||
MODULE_SIG = "y";
|
MODULE_SIG = if modular then "y" else "n";
|
||||||
DEBUG_FS = "y";
|
DEBUG_FS = "y";
|
||||||
|
|
||||||
MIPS_BOOTLOADER_CMDLINE_REQUIRE_COOKIE = "y";
|
MIPS_BOOTLOADER_CMDLINE_REQUIRE_COOKIE = "y";
|
||||||
|
|
76
modules/firewall/default.nix
Normal file
76
modules/firewall/default.nix
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
{ lib, pkgs, config, ...}:
|
||||||
|
let
|
||||||
|
inherit (lib) mkOption types;
|
||||||
|
inherit (pkgs.liminix.services) oneshot;
|
||||||
|
|
||||||
|
kconf = isModule :
|
||||||
|
# setting isModule false is utterly untested and mostly
|
||||||
|
# unimplemented: I say this to preempt any "how on earth is this
|
||||||
|
# even supposed to work?" questions
|
||||||
|
let yes = if isModule then "m" else "y";
|
||||||
|
in {
|
||||||
|
NFT_FIB_IPV4 = yes;
|
||||||
|
NFT_FIB_IPV6 = yes;
|
||||||
|
NF_TABLES = yes;
|
||||||
|
NF_CT_PROTO_DCCP = "y";
|
||||||
|
NF_CT_PROTO_SCTP = "y";
|
||||||
|
NF_CT_PROTO_UDPLITE = "y";
|
||||||
|
# NF_CONNTRACK_FTP = yes;
|
||||||
|
NFT_CT = yes;
|
||||||
|
};
|
||||||
|
kmodules = pkgs.kernel-modules.override {
|
||||||
|
kernelSrc = config.system.outputs.kernel.src;
|
||||||
|
modulesupport = config.system.outputs.kernel.modulesupport;
|
||||||
|
targets = [
|
||||||
|
"nft_fib_ipv4"
|
||||||
|
"nft_fib_ipv6"
|
||||||
|
];
|
||||||
|
kconfig = kconf true;
|
||||||
|
};
|
||||||
|
loadModules = oneshot {
|
||||||
|
name = "firewall-modules";
|
||||||
|
up = "sh ${kmodules}/load.sh";
|
||||||
|
down = "sh ${kmodules}/unload.sh";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
system.service.firewall = mkOption {
|
||||||
|
type = types.anything; # types.functionTo pkgs.liminix.lib.types.service;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
system.service.firewall = params :
|
||||||
|
let svc = (pkgs.callPackage ./service.nix {}) params;
|
||||||
|
in svc // { dependencies = svc.dependencies ++ [loadModules]; };
|
||||||
|
|
||||||
|
kernel.config = {
|
||||||
|
NETFILTER_XT_MATCH_CONNTRACK = "y";
|
||||||
|
|
||||||
|
IP6_NF_IPTABLES= "y"; # do we still need these
|
||||||
|
IP_NF_IPTABLES= "y"; # if using nftables directly
|
||||||
|
|
||||||
|
IP_NF_NAT = "y";
|
||||||
|
IP_NF_TARGET_MASQUERADE = "y";
|
||||||
|
NETFILTER = "y";
|
||||||
|
NETFILTER_ADVANCED = "y";
|
||||||
|
NETFILTER_XTABLES = "y";
|
||||||
|
|
||||||
|
NFT_COMPAT = "y";
|
||||||
|
NFT_CT = "y";
|
||||||
|
NFT_LOG = "y";
|
||||||
|
NFT_MASQ = "y";
|
||||||
|
NFT_NAT = "y";
|
||||||
|
NFT_REJECT = "y";
|
||||||
|
NFT_REJECT_INET = "y";
|
||||||
|
|
||||||
|
NF_CONNTRACK = "y";
|
||||||
|
NF_NAT = "y";
|
||||||
|
NF_NAT_MASQUERADE = "y";
|
||||||
|
NF_TABLES= "y";
|
||||||
|
NF_TABLES_INET = "y";
|
||||||
|
NF_TABLES_IPV4 = "y";
|
||||||
|
NF_TABLES_IPV6 = "y";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
26
modules/firewall/service.nix
Normal file
26
modules/firewall/service.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
liminix
|
||||||
|
, lib
|
||||||
|
, firewallgen
|
||||||
|
, nftables
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (liminix.services) oneshot;
|
||||||
|
inherit (liminix.lib) typeChecked;
|
||||||
|
inherit (lib) mkOption types;
|
||||||
|
t = {
|
||||||
|
ruleset = mkOption {
|
||||||
|
type = types.anything; # we could usefully define this more tightly
|
||||||
|
description = "firewall ruleset";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
params:
|
||||||
|
let
|
||||||
|
inherit (typeChecked "firewall" t params) ruleset;
|
||||||
|
script = firewallgen "firewall.nft" ruleset;
|
||||||
|
in oneshot {
|
||||||
|
name = "firewall";
|
||||||
|
up = script;
|
||||||
|
down = "${nftables}/bin/nft flush ruleset";
|
||||||
|
}
|
Loading…
Reference in a new issue