summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/default.nix1
-rw-r--r--modules/firewall.nix132
-rw-r--r--modules/prometheus.nix185
3 files changed, 249 insertions, 69 deletions
diff --git a/modules/default.nix b/modules/default.nix
index 6cc52d8..39915dd 100644
--- a/modules/default.nix
+++ b/modules/default.nix
@@ -17,6 +17,7 @@
./test_endpoint.nix
./prometheus.nix
./mjmap.nix
+ ./firewall.nix
];
nixpkgs.overlays = [
diff --git a/modules/firewall.nix b/modules/firewall.nix
new file mode 100644
index 0000000..575de7d
--- /dev/null
+++ b/modules/firewall.nix
@@ -0,0 +1,132 @@
+{
+ config,
+ inventory,
+ self_name,
+ lib,
+ ...
+}:
+let
+ inherit (lib)
+ mkOption
+ types
+ mkIf
+ mkEnableOption
+ mkDefault
+ ;
+ inv = inventory.${self_name};
+ net = inv.interfaces;
+ cfg = config.wilkuu.firewall;
+
+ portRangeType = types.addCheck (types.submodule {
+ options = {
+ from = mkOption {
+ type = types.port;
+ example = 100;
+ description = "lowest part of the range (inclusive)";
+ };
+ to = mkOption {
+ type = types.port;
+ example = 200;
+ description = "highest part of the range (inclusive)";
+ };
+ };
+ }) (range: range.from < range.to);
+
+ mkPortsOption =
+ protocol:
+ mkOption {
+ type = types.listOf types.port;
+ default = [ ];
+ example = [ 1234 ];
+ description = "List of ${protocol} ports to accept";
+ };
+
+ mkPortRangesOption =
+ protocol:
+ mkOption {
+ type = types.listOf portRangeType;
+ default = [ ];
+ example = [ 1234 ];
+ description = "List of ${protocol} port ranges to accept";
+ };
+
+ layerAssertions = lib.mapAttrsToList (
+ layerName: layerConfig:
+ let
+ missing = builtins.filter (importLayer: !(cfg.layers ? ${importLayer})) layerConfig.import-layer;
+ in
+ {
+ assertion = missing == [ ];
+ message = "Layer ${layerName} imports undefined layer(s): ${toString missing}";
+ }
+ ) cfg.layers;
+in
+{
+ options.wilkuu.firewall = {
+ enable = mkEnableOption "firewall module";
+ defaultLayer = lib.mkOption {
+ type = types.str;
+ default = "external";
+ example = "eth";
+ };
+ layers = mkOption {
+ default = { };
+ description = "Layers and which ports should be open";
+ type = types.attrsOf (
+ types.submodule {
+ options = {
+ import-layer = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ example = [ "external" ];
+ description = "Layer names which ports will also be opened on this layer";
+ };
+ allowedTCPPorts = mkPortsOption "TCP";
+ allowedUDPPorts = mkPortsOption "UDP";
+ allowedTCPPortRanges = mkPortRangesOption "TCP";
+ allowedUDPPortRanges = mkPortRangesOption "UDP";
+ };
+ }
+ );
+ };
+ };
+
+ config = mkIf cfg.enable {
+ assertions = layerAssertions;
+ networking.nftables.enable = true;
+ networking.firewall =
+ let
+ # TODO: reconsider doing this as this will only do a flat-import anything more complex would require building an import tree.
+ resolvedLayers = lib.mapAttrs (
+ _: l1:
+ lib.foldl' (acc: set2: {
+ allowedTCPPorts = acc.allowedTCPPorts ++ set2.allowedTCPPorts;
+ allowedUDPPorts = acc.allowedUDPPorts ++ set2.allowedUDPPorts;
+ allowedTCPPortRanges = acc.allowedTCPPortRanges ++ set2.allowedTCPPortRanges;
+ allowedUDPPortRanges = acc.allowedUDPPortRanges ++ set2.allowedUDPPortRanges;
+ }) l1 (map (lk: cfg.layers.${lk}) l1.import-layer)
+ ) cfg.layers;
+
+ interfaces = lib.mapAttrs (_n: interface: {
+ inherit (resolvedLayers.${interface.layer})
+ allowedTCPPorts
+ allowedUDPPorts
+ allowedTCPPortRanges
+ allowedUDPPortRanges
+ ;
+ }) (lib.filterAttrs (_n: interface: !(builtins.elem interface.type [ "roaming" ])) net);
+
+ in
+ {
+ enable = true;
+ checkReversePath = mkDefault false;
+ inherit interfaces;
+ inherit (resolvedLayers.${cfg.defaultLayer})
+ allowedTCPPorts
+ allowedUDPPorts
+ allowedTCPPortRanges
+ allowedUDPPortRanges
+ ;
+ };
+ };
+}
diff --git a/modules/prometheus.nix b/modules/prometheus.nix
index 63b761f..83eda86 100644
--- a/modules/prometheus.nix
+++ b/modules/prometheus.nix
@@ -1,11 +1,18 @@
-{ lib, config, ... }:
+{
+ lib,
+ config,
+ inventory,
+ self_name,
+ options,
+ ...
+}:
let
cfg = config.wilkuu.services.prometheus;
+ mon = inventory.${self_name}.monitoring;
inherit (lib)
mkEnableOption
mkIf
mkMerge
- mkDefault
;
in
{
@@ -15,16 +22,45 @@ in
};
config = mkMerge [
- (mkIf cfg.enableExporters {
- services.prometheus.exporters = {
- wireguard.enable = mkDefault config.networking.wireguard.enable;
- fail2ban.enable = mkDefault config.services.fail2ban.enable;
- node = {
+ (mkIf cfg.enableExporters (
+ let
+ data = lib.mapAttrs (
+ _name: mn:
+ let
+ default = (builtins.filter (a: builtins.isString a) mn);
+ custom = (builtins.filter (a: builtins.isAttrs a) mn);
+ in
+ {
+ ports =
+ builtins.map (n: options.services.prometheus.exporters.value.${n}.port) default
+ ++ (builtins.map (a: a.port) custom);
+ custom_port_mappings = builtins.listToAttrs (
+ map ({ name, port, ... }: {
+ inherit name;
+ value = port;
+ }) custom
+ );
+ exporter_services =
+ default
+ ++ (builtins.map (a: a.name) (builtins.filter ((a: !(a.skipExporterConfig or false))) custom));
+ }
+ ) mon;
+ data_all = (lib.foldl lib.recursiveUpdate { } (lib.attrValues data));
+ in
+ {
+ # Enable all the exporters outlined in the inventory
+ services.prometheus.exporters = lib.genAttrs data_all.exporter_services (name: {
enable = true;
- };
- };
+ port = lib.mkIf (data_all.custom_port_mappings ? name) data_all.custom_port_mappings.${name};
+
+ });
+ # Let all the exporters export on all layers
+ wilkuu.firewall.layers = lib.mapAttrs (_n: a: {
+ allowedTCPPorts = a.ports;
+ }) data;
+ }
+ ))
- })
(mkIf cfg.enableScraper {
sops.secrets = {
"prometheus/stalwart-pass" = {
@@ -52,76 +88,87 @@ in
services.prometheus =
let
- omega-relay-ip = "192.168.80.100";
+ nets_in_layer = inv: layer: lib.filterAttrs (_n: ifi: (ifi.layer or "") == layer) inv.interfaces;
+ dests_in_layer =
+ inv: layer: port:
+ (map (net: "${net.ip}:${toString port}") (lib.attrValues (nets_in_layer inv layer)));
+
+ job_destinations = (
+ builtins.foldl'
+ (
+ acc: perHost:
+ (builtins.foldl' (
+ acc2: hostMonitorName:
+ let
+ current = acc2.${hostMonitorName} or [ ];
+ new = perHost.${hostMonitorName};
+ in
+ acc2 // { ${hostMonitorName} = current ++ new; }
+ ) acc (lib.attrNames perHost))
+ )
+ { }
+ (
+ lib.mapAttrsToList (
+ _host: inv:
+ (lib.foldl' (a: b: a // b) { } (
+ lib.mapAttrsToList (
+
+ layer: lst:
+ (lib.listToAttrs (
+ builtins.map (
+ a:
+ let
+ ifSimple =
+ a: t: f:
+ if builtins.isString a then t else f;
+ name = ifSimple a a a.name;
+ port = ifSimple a options.services.prometheus.exporters.value.${a}.port (
+ a.port or options.services.prometheus.exporters.${a.name}.port.default
+ );
+ in
+ {
+ inherit name;
+ value = (dests_in_layer inv layer port);
+ }
+ ) lst
+ ))
+ ) inv.monitoring
+ ))
+ ) inventory
+ )
+ );
+
in
{
enable = true;
globalConfig = {
scrape_interval = "10s";
};
- scrapeConfigs = [
- {
- job_name = "node";
- static_configs =
- let
- port = toString config.services.prometheus.exporters.node.port;
- in
- [
- {
- targets = [
- "localhost:${port}"
- "${omega-relay-ip}:${port}"
- ];
- }
- ];
- }
- {
- job_name = "wireguard";
- static_configs =
- let
- port = toString config.services.prometheus.exporters.wireguard.port;
- in
- [
- { targets = [ "${omega-relay-ip}:${port}" ]; }
- ];
- }
- {
- job_name = "fail2ban";
- static_configs =
- let
- port = toString config.services.prometheus.exporters.fail2ban.port;
- in
- [
- { targets = [ "${omega-relay-ip}:${port}" ]; }
- ];
-
- }
- {
- job_name = "stalwart";
- metrics_path = "/metrics/prometheus";
- scheme = "https";
- basic_auth = {
- username = "prometheus_wilkuu";
- password_file = config.sops.secrets."prometheus/stalwart-pass".path;
- };
+ scrapeConfigs =
+ (lib.mapAttrsToList (name: dests: {
+ job_name = name;
static_configs = [
{
- targets = [ "mail.wilkuu.xyz:443" ];
+ targets = dests;
}
];
- }
- {
- job_name = "mikrotik";
- static_configs =
- let
- port = toString config.services.prometheus.exporters.mikrotik.port;
- in
- [
- { targets = [ "localhost:${port}" ]; }
+ }) job_destinations)
+ ++ [
+ {
+ job_name = "stalwart";
+ metrics_path = "/metrics/prometheus";
+ scheme = "https";
+ basic_auth = {
+ username = "prometheus_wilkuu";
+ password_file = config.sops.secrets."prometheus/stalwart-pass".path;
+ };
+ static_configs = [
+ {
+ targets = [ "mail.wilkuu.xyz:443" ];
+ }
];
-
- }
- ];
+ }
+ ];
};
})
];