3 lass.iptables: init
This commit is contained in:
parent
939ab63ca2
commit
8e2afa35d9
166
3modules/lass/iptables.nix
Normal file
166
3modules/lass/iptables.nix
Normal file
@ -0,0 +1,166 @@
|
||||
arg@{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (pkgs) writeScript writeText;
|
||||
inherit (lib) concatMapStringsSep concatStringsSep attrNames unique fold any attrValues catAttrs filter flatten length hasAttr mkEnableOption mkOption mkIf types;
|
||||
|
||||
cfg = config.lass.iptables;
|
||||
|
||||
out = {
|
||||
options.lass.iptables = api;
|
||||
config = mkIf cfg.enable imp;
|
||||
};
|
||||
|
||||
api = {
|
||||
enable = mkEnableOption "iptables";
|
||||
|
||||
#tables.filter.INPUT = {
|
||||
# policy = "DROP";
|
||||
# rules = [
|
||||
# { predicate = "-i retiolum"; target = "ACCEPT"; priority = -10; }
|
||||
# ];
|
||||
#};
|
||||
#new api
|
||||
tables = mkOption {
|
||||
type = with types; attrsOf (attrsOf (submodule ({
|
||||
options = {
|
||||
policy = mkOption {
|
||||
type = str;
|
||||
default = "-";
|
||||
};
|
||||
rules = mkOption {
|
||||
type = nullOr (listOf (submodule ({
|
||||
options = {
|
||||
predicate = mkOption {
|
||||
type = str;
|
||||
};
|
||||
target = mkOption {
|
||||
type = str;
|
||||
};
|
||||
precedence = mkOption {
|
||||
type = int;
|
||||
default = 0;
|
||||
};
|
||||
};
|
||||
})));
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
})));
|
||||
};
|
||||
};
|
||||
|
||||
imp = {
|
||||
networking.firewall.enable = false;
|
||||
|
||||
systemd.services.lass-iptables = {
|
||||
description = "lass-iptables";
|
||||
wantedBy = [ "network-pre.target" ];
|
||||
before = [ "network-pre.target" ];
|
||||
after = [ "systemd-modules-load.service" ];
|
||||
|
||||
path = with pkgs; [
|
||||
iptables
|
||||
];
|
||||
|
||||
restartIfChanged = true;
|
||||
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
RemainAfterExit = true;
|
||||
Restart = "always";
|
||||
ExecStart = "@${startScript} lass-iptables_start";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#buildTable :: iptablesAttrSet` -> str
|
||||
#todo: differentiate by iptables-version
|
||||
buildTables = iptv: ts:
|
||||
let
|
||||
declareChain = t: cn:
|
||||
#TODO: find out what to do whit these count numbers
|
||||
":${cn} ${t."${cn}".policy} [0:0]";
|
||||
|
||||
buildChain = tn: cn:
|
||||
#"${concatStringsSep " " ((attrNames t."${cn}") ++ [cn])}";
|
||||
|
||||
#TODO: sort by precedence
|
||||
#TODO: double check should be unneccessary, refactor!
|
||||
if (hasAttr "rules" ts."${tn}"."${cn}") then
|
||||
if (ts."${tn}"."${cn}".rules == null) then
|
||||
""
|
||||
else
|
||||
concatMapStringsSep "\n" (rule: "\n-A ${cn} ${rule}") ([]
|
||||
++ map buildRule ts."${tn}"."${cn}".rules
|
||||
)
|
||||
else
|
||||
""
|
||||
;
|
||||
|
||||
|
||||
buildRule = rule:
|
||||
#TODO implement rule validation-test here
|
||||
#
|
||||
#target:
|
||||
#target needs to be an existing chain (in the same table) or ACCEPT, REJECT, DROP, LOG, QUEUE, RETURN
|
||||
|
||||
#predicate:
|
||||
#maybe use iptables-test
|
||||
#TODO: howto exit with evaluation error by shellscript?
|
||||
#apperantly not possible from nix because evalatution wouldn't be deterministic.
|
||||
"${rule.predicate} -j ${rule.target}";
|
||||
|
||||
buildTable = tn:
|
||||
"*${tn}\n" +
|
||||
concatStringsSep "\n" ([]
|
||||
++ map (declareChain ts."${tn}") (attrNames ts."${tn}")
|
||||
) +
|
||||
#this looks dirty, find a better way to do this (maybe optionalString)
|
||||
concatStringsSep "" ([]
|
||||
++ map (buildChain tn) (attrNames ts."${tn}")
|
||||
) +
|
||||
"\nCOMMIT";
|
||||
in
|
||||
concatStringsSep "\n" ([]
|
||||
++ map buildTable (attrNames ts)
|
||||
);
|
||||
|
||||
#=====
|
||||
|
||||
rules4 = iptables-version:
|
||||
let
|
||||
#TODO: find out good defaults.
|
||||
tables-defaults = {
|
||||
nat.PREROUTING.policy = "ACCEPT";
|
||||
nat.INPUT.policy = "ACCEPT";
|
||||
nat.OUTPUT.policy = "ACCEPT";
|
||||
nat.POSTROUTING.policy = "ACCEPT";
|
||||
filter.INPUT.policy = "ACCEPT";
|
||||
filter.FORWARD.policy = "ACCEPT";
|
||||
filter.OUTPUT.policy = "ACCEPT";
|
||||
|
||||
#if someone specifies any other rules on this chain, the default rules get lost.
|
||||
#is this wanted beahiviour or a bug?
|
||||
#TODO: implement abstraction of rules
|
||||
filter.INPUT.rules = [
|
||||
{ predicate = "-m conntrack --ctstate RELATED,ESTABLISHED"; target = "ACCEPT"; }
|
||||
];
|
||||
};
|
||||
tables = tables-defaults // cfg.tables;
|
||||
|
||||
in
|
||||
writeText "lass-iptables-rules${toString iptables-version}" ''
|
||||
${buildTables iptables-version tables}
|
||||
'';
|
||||
|
||||
startScript = writeScript "lass-iptables_start" ''
|
||||
#! /bin/sh
|
||||
set -euf
|
||||
iptables-restore < ${rules4 4}
|
||||
ip6tables-restore < ${rules4 6}
|
||||
'';
|
||||
|
||||
in
|
||||
out
|
||||
|
Loading…
Reference in New Issue
Block a user