added stuff

This commit is contained in:
vali 2024-04-09 23:11:33 +02:00
commit 236b8c2a6b
907 changed files with 70990 additions and 0 deletions

140
nyx/lib/network/dag.nix Normal file
View file

@ -0,0 +1,140 @@
# Adjusted from https://gitlab.com/rycee/nur-expressions/blob/b34e2e548da574c7bd4da14d1779c95b62349a3a/lib/dag.nix (MIT)
# A generalization of Nixpkgs's `strings-with-deps.nix`.
#
# The main differences from the Nixpkgs version are
#
# - not specific to strings, i.e., any payload is OK,
#
# - the addition of the function `entryBefore` indicating a
# "wanted by" relationship.
{lib, ...}: let
inherit (lib) mkOption filterAttrs mapAttrsToList toposort mapAttrs any types;
types' =
types
// {
dagOf = subType:
types.attrsOf (types.submodule {
options = {
data = mkOption {
type = subType;
description = "Entry value.";
};
before = mkOption {
type = types.listOf types.str;
default = [];
description = "Entries to guarantee before.";
};
after = mkOption {
type = types.listOf types.str;
default = [];
description = "Entries to guarantee after.";
};
};
});
};
dag = {
# Takes an attribute set containing entries built by
# entryAnywhere, entryAfter, and entryBefore to a
# topologically sorted list of entries.
#
# Internally this function uses the `toposort` function in
# `<nixpkgs/lib/lists.nix>` and its value is accordingly.
#
# Specifically, the result on success is
#
# { result = [{name = ?; data = ?;} …] }
#
# For example
#
# nix-repl> topoSort {
# a = entryAnywhere "1";
# b = entryAfter ["a" "c"] "2";
# c = entryBefore ["d"] "3";
# d = entryBefore ["e"] "4";
# e = entryAnywhere "5";
# } == {
# result = [
# { data = "1"; name = "a"; }
# { data = "3"; name = "c"; }
# { data = "2"; name = "b"; }
# { data = "4"; name = "d"; }
# { data = "5"; name = "e"; }
# ];
# }
# true
#
# And the result on error is
#
# {
# cycle = [ {after = ?; name = ?; data = ?} … ];
# loops = [ {after = ?; name = ?; data = ?} … ];
# }
#
# For example
#
# nix-repl> topoSort {
# a = entryAnywhere "1";
# b = entryAfter ["a" "c"] "2";
# c = entryAfter ["d"] "3";
# d = entryAfter ["b"] "4";
# e = entryAnywhere "5";
# } == {
# cycle = [
# { after = ["a" "c"]; data = "2"; name = "b"; }
# { after = ["d"]; data = "3"; name = "c"; }
# { after = ["b"]; data = "4"; name = "d"; }
# ];
# loops = [
# { after = ["a" "c"]; data = "2"; name = "b"; }
# ];
# } == {}
# true
topoSort = dag: let
dagBefore = dag: name:
mapAttrsToList (n: v: n) (
filterAttrs (n: v: any (a: a == name) v.before) dag
);
normalizedDag =
mapAttrs (n: v: {
name = n;
data = v.data;
after = v.after ++ dagBefore dag n;
})
dag;
before = a: b: any (c: a.name == c) b.after;
sorted = toposort before (mapAttrsToList (n: v: v) normalizedDag);
in
if sorted ? result
then {result = map (v: {inherit (v) name data;}) sorted.result;}
else sorted;
# Create a DAG entry with no particular dependency information.
entryAnywhere = data: {
inherit data;
before = [];
after = [];
};
# Ordering of after and before flipped from the original
entryBetween = after: before: data: {
inherit data before after;
};
entryAfter = after: data: {
inherit data after;
before = [];
};
entryBefore = before: data: {
inherit data before;
after = [];
};
};
in {
inherit (dag) entryBefore entryBetween entryAfter entryAnywhere topoSort;
inherit (types') dagOf;
}

View file

@ -0,0 +1,177 @@
{
dag,
lib,
...
}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.strings) optionalString concatMapStringsSep concatStringsSep;
inherit (lib.attrsets) filterAttrs mapAttrsToList;
inherit (lib.lists) concatLists;
inherit (lib) types;
inherit (dag) dagOf topoSort;
mkTable = desc: body:
mkOption {
default = {};
description = "Containers for chains, sets, and other stateful objects.";
type = types.submodule ({config, ...}: {
options =
{
enable = mkEnableOption desc;
objects = mkOption {
type = with types; listOf str;
description = "Objects associated with this table.";
default = [];
};
}
// body;
config = let
buildChainDag = chain:
concatMapStringsSep "\n" ({
name,
data,
}: let
protocol =
if builtins.isNull data.protocol
then ""
else data.protocol;
field =
if builtins.isNull data.field
then ""
else data.field;
inherit (data) policy;
values = map toString data.value;
value =
if builtins.isNull data.value
then ""
else
(
if builtins.length data.value == 1
then builtins.head values
else "{ ${concatStringsSep ", " values} }"
);
in ''
${protocol} ${field} ${value} ${policy} comment ${name}
'') ((topoSort chain).result or (throw "Cycle in DAG"));
buildChain = chainType: chain:
mapAttrsToList (chainName: chainDag: ''
chain ${chainName} {
type ${chainType} hook ${chainName} priority 0;
${buildChainDag chainDag}
}
'') (filterAttrs (_: g: builtins.length (builtins.attrNames g) > 0) chain);
in {
objects = let
chains = concatLists [
(
if config ? filter
then buildChain "filter" config.filter
else []
)
(
if config ? nat
then buildChain "nat" config.nat
else []
)
(
if config ? route
then buildChain "route" config.route
else []
)
];
in
chains;
};
});
};
mkChain = _: description:
mkOption {
inherit description;
default = {};
type = dagOf (types.submodule {
options = {
protocol = mkOption {
default = null;
description = "Protocol to match.";
type = with types;
nullOr (either (enum [
"ether"
"vlan"
"arp"
"ip"
"icmp"
"igmp"
"ip6"
"icmpv6"
"tcp"
"udp"
"udplite"
"sctp"
"dccp"
"ah"
"esp"
"comp"
])
str);
};
field = mkOption {
default = null;
description = "Field value to match.";
type = with types;
nullOr (enum [
"dport"
"sport"
"daddr"
"saddr"
"type"
"state"
"iifname"
"pkttype"
]);
};
value = mkOption {
default = null;
description = "Associated value.";
type = with types; let
valueType = oneOf [port str];
in
nullOr (coercedTo valueType (value: [value]) (listOf valueType));
};
policy = mkOption {
description = "What to do with matching packets.";
type = types.enum [
"accept"
"reject"
"drop"
"log"
];
};
};
});
};
mkRuleset = ruleset:
concatStringsSep "\n" (mapAttrsToList (name: table:
optionalString (builtins.length table.objects > 0) ''
table ${name} nixos {
${concatStringsSep "\n" table.objects}
}
'')
ruleset);
mkIngressChain = mkChain "Process all packets before they enter the system";
mkPrerouteChain = mkChain "Process all packets entering the system";
mkInputChain = mkChain "Process packets delivered to the local system";
mkForwardChain = mkChain "Process packets forwarded to a different host";
mkOutputChain = mkChain "Process packets sent by local processes";
mkPostrouteChain = mkChain "Process all packets leaving the system";
in {
inherit mkTable mkRuleset mkIngressChain mkPrerouteChain mkInputChain mkForwardChain mkOutputChain mkPostrouteChain;
}

View file

@ -0,0 +1,13 @@
_: let
makeServiceNsPhysical = name: {
systemd.services."${name}".serviceConfig.NetworkNamespacePath = "/var/run/netns/physical";
};
makeSocketNsPhysical = name: {
systemd.sockets."${name}".socketConfig.NetworkNamespacePath = "/var/run/netns/physical";
};
unRestrictNamespaces = name: {
systemd.sockets."${name}".socketConfig.RestrictNamespaces = "~net";
};
in {
inherit makeSocketNsPhysical makeServiceNsPhysical unRestrictNamespaces;
}