mirror of
https://git.sr.ht/~magic_rb/dotfiles
synced 2024-11-25 17:46:14 +01:00
Possibly functional blowhole configuration
Signed-off-by: Magic_RB <magic_rb@redalder.org>
This commit is contained in:
parent
558a6e4168
commit
fed32ecfca
223
flake.lock
223
flake.lock
|
@ -1,5 +1,24 @@
|
||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
"deploy-rs": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-compat": "flake-compat",
|
||||||
|
"nixpkgs": "nixpkgs_7",
|
||||||
|
"utils": "utils"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1648475189,
|
||||||
|
"narHash": "sha256-gAGAS6IagwoUr1B0ohE3iR6sZ8hP4LSqzYLC8Mq3WGU=",
|
||||||
|
"owner": "serokell",
|
||||||
|
"repo": "deploy-rs",
|
||||||
|
"rev": "83e0c78291cd08cb827ba0d553ad9158ae5a95c3",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "deploy-rs",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dwarffs": {
|
"dwarffs": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nix": "nix",
|
"nix": "nix",
|
||||||
|
@ -40,6 +59,37 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-compat": {
|
"flake-compat": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1648199409,
|
||||||
|
"narHash": "sha256-JwPKdC2PoVBkG6E+eWw3j6BMR6sL3COpYWfif7RVb8Y=",
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"rev": "64a525ee38886ab9028e6f61790de0832aa3ef03",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-compat_2": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1627913399,
|
||||||
|
"narHash": "sha256-hY8g6H2KFL8ownSiFeMOjwPC8P0ueXpCVEbxgda3pko=",
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"rev": "12c64ca55c1014cdc1b16ed5a804aa8576601ff2",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "flake-compat",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-compat_3": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1673956053,
|
"lastModified": 1673956053,
|
||||||
|
@ -55,7 +105,7 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-compat_2": {
|
"flake-compat_4": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1673956053,
|
"lastModified": 1673956053,
|
||||||
|
@ -126,6 +176,20 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-utils_2": {
|
"flake-utils_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1631561581,
|
||||||
|
"narHash": "sha256-3VQMV5zvxaVLvqqUrNz3iJelLw30mIVSfZmAaauM3dA=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "7e5bf3925f6fbdfaf50a2a7ca0be2879c4261d19",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "flake-utils",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-utils_3": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": "systems_2"
|
"systems": "systems_2"
|
||||||
},
|
},
|
||||||
|
@ -143,7 +207,7 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-utils_3": {
|
"flake-utils_4": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1667395993,
|
"lastModified": 1667395993,
|
||||||
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
||||||
|
@ -180,6 +244,22 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"gitignore-nix": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1611672876,
|
||||||
|
"narHash": "sha256-qHu3uZ/o9jBHiA3MEKHJ06k7w4heOhA+4HCSIvflRxo=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "gitignore.nix",
|
||||||
|
"rev": "211907489e9f198594c0eb0ca9256a1949c9d412",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "gitignore.nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"home-manager": {
|
"home-manager": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": "nixpkgs_2"
|
"nixpkgs": "nixpkgs_2"
|
||||||
|
@ -231,6 +311,22 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"lowdown-src_2": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1632468475,
|
||||||
|
"narHash": "sha256-NNOm9CbdA8cuwbvaBHslGbPTiU6bh1Ao+MpEPx4rSGo=",
|
||||||
|
"owner": "kristapsdz",
|
||||||
|
"repo": "lowdown",
|
||||||
|
"rev": "6bd668af3fd098bdd07a1bedd399564141e275da",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "kristapsdz",
|
||||||
|
"repo": "lowdown",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nil": {
|
"nil": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": "flake-utils",
|
"flake-utils": "flake-utils",
|
||||||
|
@ -270,6 +366,24 @@
|
||||||
"type": "indirect"
|
"type": "indirect"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nix_2": {
|
||||||
|
"inputs": {
|
||||||
|
"lowdown-src": "lowdown-src_2",
|
||||||
|
"nixpkgs": "nixpkgs_8"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1633098935,
|
||||||
|
"narHash": "sha256-UtuBczommNLwUNEnfRI7822z4vPA7OoRKsgAZ8zsHQI=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nix",
|
||||||
|
"rev": "4f496150eb4e0012914c11f0a3ff4df2412b1d09",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nix",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixinate": {
|
"nixinate": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": "nixpkgs_4"
|
"nixpkgs": "nixpkgs_4"
|
||||||
|
@ -406,6 +520,19 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nixpkgs_10": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1676569297,
|
||||||
|
"narHash": "sha256-2n4C4H3/U+3YbDrQB6xIw7AaLdFISCCFwOkcETAigqU=",
|
||||||
|
"path": "/nix/store/qhj65h4klgmnkblfly0apznnl3qdir6x-source",
|
||||||
|
"rev": "ac1f5b72a9e95873d1de0233fddcb56f99884b37",
|
||||||
|
"type": "path"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1684570954,
|
"lastModified": 1684570954,
|
||||||
|
@ -488,11 +615,43 @@
|
||||||
},
|
},
|
||||||
"nixpkgs_7": {
|
"nixpkgs_7": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1676569297,
|
"lastModified": 1648219316,
|
||||||
"narHash": "sha256-2n4C4H3/U+3YbDrQB6xIw7AaLdFISCCFwOkcETAigqU=",
|
"narHash": "sha256-Ctij+dOi0ZZIfX5eMhgwugfvB+WZSrvVNAyAuANOsnQ=",
|
||||||
"path": "/nix/store/qhj65h4klgmnkblfly0apznnl3qdir6x-source",
|
"owner": "NixOS",
|
||||||
"rev": "ac1f5b72a9e95873d1de0233fddcb56f99884b37",
|
"repo": "nixpkgs",
|
||||||
"type": "path"
|
"rev": "30d3d79b7d3607d56546dd2a6b49e156ba0ec634",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_8": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1632864508,
|
||||||
|
"narHash": "sha256-d127FIvGR41XbVRDPVvozUPQ/uRHbHwvfyKHwEt5xFM=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "82891b5e2c2359d7e58d08849e4c89511ab94234",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"ref": "nixos-21.05-small",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_9": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1632495107,
|
||||||
|
"narHash": "sha256-4NGE56r+FJGBaCYu3CTH4O83Ys4TrtnEPXrvdwg1TDs=",
|
||||||
|
"owner": "serokell",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "be220b2dc47092c1e739bf6aaf630f29e71fe1c4",
|
||||||
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"id": "nixpkgs",
|
"id": "nixpkgs",
|
||||||
|
@ -501,8 +660,8 @@
|
||||||
},
|
},
|
||||||
"pre-commit-hooks": {
|
"pre-commit-hooks": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-compat": "flake-compat_2",
|
"flake-compat": "flake-compat_4",
|
||||||
"flake-utils": "flake-utils_3",
|
"flake-utils": "flake-utils_4",
|
||||||
"gitignore": "gitignore",
|
"gitignore": "gitignore",
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"tuxedo-rs",
|
"tuxedo-rs",
|
||||||
|
@ -537,6 +696,7 @@
|
||||||
"nixpkgs": "nixpkgs_6",
|
"nixpkgs": "nixpkgs_6",
|
||||||
"nixpkgs-hashicorp": "nixpkgs-hashicorp",
|
"nixpkgs-hashicorp": "nixpkgs-hashicorp",
|
||||||
"secret": "secret",
|
"secret": "secret",
|
||||||
|
"serokell-nix": "serokell-nix",
|
||||||
"tuxedo-nixos": "tuxedo-nixos",
|
"tuxedo-nixos": "tuxedo-nixos",
|
||||||
"tuxedo-rs": "tuxedo-rs",
|
"tuxedo-rs": "tuxedo-rs",
|
||||||
"udp-over-tcp": "udp-over-tcp",
|
"udp-over-tcp": "udp-over-tcp",
|
||||||
|
@ -582,6 +742,30 @@
|
||||||
"type": "path"
|
"type": "path"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"serokell-nix": {
|
||||||
|
"inputs": {
|
||||||
|
"deploy-rs": "deploy-rs",
|
||||||
|
"flake-compat": "flake-compat_2",
|
||||||
|
"flake-utils": "flake-utils_2",
|
||||||
|
"gitignore-nix": "gitignore-nix",
|
||||||
|
"nix": "nix_2",
|
||||||
|
"nixpkgs": "nixpkgs_9"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1665438610,
|
||||||
|
"narHash": "sha256-s8/jYo5qseJ4ilyAM2sz1mD5DBybSTrkfd4b9pkgdcU=",
|
||||||
|
"owner": "serokell",
|
||||||
|
"repo": "serokell.nix",
|
||||||
|
"rev": "a4def0b297a0ec69066747df909251a6a7555b1d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "serokell",
|
||||||
|
"ref": "magicrb-allow-wildcards-with-no-main",
|
||||||
|
"repo": "serokell.nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"systems": {
|
"systems": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1681028828,
|
"lastModified": 1681028828,
|
||||||
|
@ -630,7 +814,7 @@
|
||||||
},
|
},
|
||||||
"tuxedo-nixos": {
|
"tuxedo-nixos": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-compat": "flake-compat",
|
"flake-compat": "flake-compat_3",
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
]
|
]
|
||||||
|
@ -651,7 +835,7 @@
|
||||||
},
|
},
|
||||||
"tuxedo-rs": {
|
"tuxedo-rs": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": "flake-utils_2",
|
"flake-utils": "flake-utils_3",
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
|
@ -690,7 +874,7 @@
|
||||||
"uterranix": {
|
"uterranix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-parts": "flake-parts_2",
|
"flake-parts": "flake-parts_2",
|
||||||
"nixpkgs": "nixpkgs_7",
|
"nixpkgs": "nixpkgs_10",
|
||||||
"terranix": "terranix"
|
"terranix": "terranix"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
|
@ -704,6 +888,21 @@
|
||||||
"type": "path"
|
"type": "path"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"utils": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1648297722,
|
||||||
|
"narHash": "sha256-W+qlPsiZd8F3XkzXOzAoR+mpFqzm3ekQkJNa+PIh1BQ=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "0f8662f1319ad6abf89b3380dd2722369fc51ade",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"vtermModule": {
|
"vtermModule": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
|
|
10
flake.nix
10
flake.nix
|
@ -12,6 +12,7 @@
|
||||||
nil.url = "github:oxalica/nil";
|
nil.url = "github:oxalica/nil";
|
||||||
uterranix.url = "path:///home/main/uterranix";
|
uterranix.url = "path:///home/main/uterranix";
|
||||||
dwarffs.url = "github:edolstra/dwarffs";
|
dwarffs.url = "github:edolstra/dwarffs";
|
||||||
|
serokell-nix.url = "github:serokell/serokell.nix?ref=magicrb-allow-wildcards-with-no-main";
|
||||||
|
|
||||||
tuxedo-rs.url = "github:AaronErhardt/tuxedo-rs";
|
tuxedo-rs.url = "github:AaronErhardt/tuxedo-rs";
|
||||||
tuxedo-rs.inputs.nixpkgs.follows = "nixpkgs";
|
tuxedo-rs.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
@ -42,6 +43,7 @@
|
||||||
nixos/systems/heater
|
nixos/systems/heater
|
||||||
nixos/systems/toothpick
|
nixos/systems/toothpick
|
||||||
nixos/systems/liveusb
|
nixos/systems/liveusb
|
||||||
|
nixos/systems/blowhole
|
||||||
|
|
||||||
overlays/udp-over-tcp.nix
|
overlays/udp-over-tcp.nix
|
||||||
overlays/emacsclient-remote
|
overlays/emacsclient-remote
|
||||||
|
@ -49,10 +51,15 @@
|
||||||
overlays/emacs-rofi
|
overlays/emacs-rofi
|
||||||
overlays/tree-sitter-grammars.nix
|
overlays/tree-sitter-grammars.nix
|
||||||
overlays/emacs-master-nativecomp
|
overlays/emacs-master-nativecomp
|
||||||
|
overlays/zfs-relmount
|
||||||
|
overlays/ical2org.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
flake.nixosModules = {
|
flake.nixosModules = {
|
||||||
hashicorp = nixos/modules/hashicorp.nix;
|
hashicorp = nixos/modules/hashicorp.nix;
|
||||||
|
hashicorp-envoy = nixos/modules/hashicorp-envoy.nix;
|
||||||
|
telegraf = nixos/modules/telegraf.nix;
|
||||||
|
grafana = nixos/modules/grafana.nix;
|
||||||
};
|
};
|
||||||
|
|
||||||
flake.apps = inputs.nixpkgs.lib.genAttrs config.systems (system: {
|
flake.apps = inputs.nixpkgs.lib.genAttrs config.systems (system: {
|
||||||
|
@ -62,6 +69,9 @@
|
||||||
flake.patches = {
|
flake.patches = {
|
||||||
hashicorp-nomad.revert-change-consul-si-tokens-to-be-local = patches/0001-Revert-Change-consul-SI-tokens-to-be-local.patch;
|
hashicorp-nomad.revert-change-consul-si-tokens-to-be-local = patches/0001-Revert-Change-consul-SI-tokens-to-be-local.patch;
|
||||||
hashicorp-nomad.add-nix-integration = patches/0001-Add-Nix-integration.patch;
|
hashicorp-nomad.add-nix-integration = patches/0001-Add-Nix-integration.patch;
|
||||||
|
hostapd.intel_lar-and-noscan = patches/0001-intel_lar-and-noscan.patch;
|
||||||
|
hostapd.hostapd-2_10-lar = patches/999-hostapd-2.10-lar.patch;
|
||||||
|
hostapd.hostapd-2_10-lar-2 = patches/hostapd-2.10-lar.patch;
|
||||||
};
|
};
|
||||||
|
|
||||||
systems = [
|
systems = [
|
||||||
|
|
181
nixos/modules/grafana.nix
Normal file
181
nixos/modules/grafana.nix
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
{ options, config, lib, pkgs, ... }:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
mkEnableOption
|
||||||
|
mkOption
|
||||||
|
literalExpression
|
||||||
|
types
|
||||||
|
mkDefault
|
||||||
|
mkIf
|
||||||
|
recursiveUpdate
|
||||||
|
;
|
||||||
|
|
||||||
|
cfg = config.services.grafana-magic;
|
||||||
|
settingsFile = settingsFormatIni.generate "config.ini" (recursiveUpdate cfg.settings {
|
||||||
|
paths.provisioning = "/etc/grafana.d/provisioning";
|
||||||
|
});
|
||||||
|
|
||||||
|
provisioningSettingsFormat = pkgs.formats.yaml {};
|
||||||
|
settingsFormatIni = pkgs.formats.ini {};
|
||||||
|
in {
|
||||||
|
options.services.grafana-magic = {
|
||||||
|
enable = mkEnableOption (lib.mdDoc "grafana");
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
description = lib.mdDoc "Package to use.";
|
||||||
|
default = pkgs.grafana;
|
||||||
|
defaultText = literalExpression "pkgs.grafana";
|
||||||
|
type = types.package;
|
||||||
|
};
|
||||||
|
|
||||||
|
dataDir = mkOption {
|
||||||
|
description = lib.mdDoc "Data directory.";
|
||||||
|
default = "/var/lib/grafana";
|
||||||
|
type = types.path;
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Grafana settings. See <https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/>
|
||||||
|
for available options. INI format is used.
|
||||||
|
'';
|
||||||
|
|
||||||
|
type = types.submodule {
|
||||||
|
freeformType = settingsFormatIni.type;
|
||||||
|
|
||||||
|
options = {
|
||||||
|
paths.provisioning = mkOption {
|
||||||
|
type = types.submodule {
|
||||||
|
options =
|
||||||
|
let
|
||||||
|
provisioningOption = name: cname:
|
||||||
|
mkOption {
|
||||||
|
type = types.submodule {
|
||||||
|
options = {
|
||||||
|
apiVersion = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
"delete${cname}" = mkOption {
|
||||||
|
type = provisioningSettingsFormat.type;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
"${name}" = mkOption {
|
||||||
|
type = provisioningSettingsFormat.type;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
datasources = provisioningOption "datasources" "Datasources";
|
||||||
|
plugins = provisioningOption "plugins" "Plugins";
|
||||||
|
dashboards = provisioningOption "dashboards" "Dashboards";
|
||||||
|
notifiers = provisioningOption "notifiers" "Notifiers";
|
||||||
|
alerting = provisioningOption "alerting" "Alerting";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
default = {};
|
||||||
|
apply = x:
|
||||||
|
let
|
||||||
|
ln = name:
|
||||||
|
''
|
||||||
|
mkdir -p $out/${name}
|
||||||
|
ln -s ${provisioningSettingsFormat.generate "config.yaml" x.${name}} $out/${name}/config.yaml
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
pkgs.runCommand "grafana-provisioning" {} ''
|
||||||
|
${ln "datasources"}
|
||||||
|
${ln "notifiers"}
|
||||||
|
${ln "alerting"}
|
||||||
|
${ln "plugins"}
|
||||||
|
${ln "dashboards"}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
|
||||||
|
services.grafana-magic.settings = {
|
||||||
|
server = {
|
||||||
|
static_root_path = "${cfg.package}/share/grafana/public";
|
||||||
|
http_port = mkDefault 3000;
|
||||||
|
protocol = mkDefault "http";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.etc."grafana.d/main.ini" = {
|
||||||
|
source = settingsFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.etc."grafana.d/provisioning" = {
|
||||||
|
source = cfg.settings.paths.provisioning;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.grafana = {
|
||||||
|
description = "Grafana Service Daemon";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "networking.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${cfg.package}/bin/grafana-server -homepath ${cfg.dataDir} -config ${settingsFile}";
|
||||||
|
WorkingDirectory = cfg.dataDir;
|
||||||
|
User = "grafana";
|
||||||
|
RuntimeDirectory = "grafana";
|
||||||
|
RuntimeDirectoryMode = "0755";
|
||||||
|
# Hardening
|
||||||
|
AmbientCapabilities = lib.mkIf (cfg.settings.server.http_port < 1024) [ "CAP_NET_BIND_SERVICE" ];
|
||||||
|
CapabilityBoundingSet = if (cfg.settings.server.http_port < 1024) then [ "CAP_NET_BIND_SERVICE" ] else [ "" ];
|
||||||
|
DeviceAllow = [ "" ];
|
||||||
|
LockPersonality = true;
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
PrivateDevices = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
ProtectClock = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
ProtectHome = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectProc = "invisible";
|
||||||
|
ProtectSystem = "full";
|
||||||
|
RemoveIPC = true;
|
||||||
|
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ];
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
SystemCallArchitectures = "native";
|
||||||
|
# Upstream grafana is not setting SystemCallFilter for compatibility
|
||||||
|
# reasons, see https://github.com/grafana/grafana/pull/40176
|
||||||
|
SystemCallFilter = [
|
||||||
|
"@system-service"
|
||||||
|
"~@privileged"
|
||||||
|
] ++ lib.optional (cfg.settings.server.protocol == "socket") [ "@chown" ];
|
||||||
|
UMask = "0027";
|
||||||
|
};
|
||||||
|
preStart = ''
|
||||||
|
ln -fs ${cfg.package}/share/grafana/conf ${cfg.dataDir}
|
||||||
|
ln -fs ${cfg.package}/share/grafana/tools ${cfg.dataDir}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.grafana = {
|
||||||
|
uid = config.ids.uids.grafana;
|
||||||
|
description = "Grafana user";
|
||||||
|
home = cfg.dataDir;
|
||||||
|
createHome = true;
|
||||||
|
group = "grafana";
|
||||||
|
};
|
||||||
|
users.groups.grafana = {};
|
||||||
|
};
|
||||||
|
}
|
173
nixos/modules/hashicorp-envoy.nix
Normal file
173
nixos/modules/hashicorp-envoy.nix
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.services.hashicorp-envoy;
|
||||||
|
|
||||||
|
serviceFormat = pkgs.formats.json {};
|
||||||
|
serviceFile = name: value:
|
||||||
|
if value.type == "normal" then
|
||||||
|
serviceFormat.generate "${name}-service.json" { service = value.service; }
|
||||||
|
else
|
||||||
|
serviceFormat.generate "${name}-service.json" value.service;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.hashicorp-envoy = mkOption {
|
||||||
|
description = mdDoc ''
|
||||||
|
'';
|
||||||
|
type = types.attrsOf (types.submodule {
|
||||||
|
options = {
|
||||||
|
service = mkOption {
|
||||||
|
description = mdDoc ''
|
||||||
|
'';
|
||||||
|
type = with types; oneOf [ serviceFormat.type (listOf serviceFormat.type) ];
|
||||||
|
};
|
||||||
|
|
||||||
|
type = mkOption {
|
||||||
|
description = mdDoc ''
|
||||||
|
'';
|
||||||
|
type = with types; enum [ "ingress" "terminating" "normal" ];
|
||||||
|
default = "normal";
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = mkOption {
|
||||||
|
description = mdDoc ''
|
||||||
|
'';
|
||||||
|
type = with types; attrsOf str;
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
adminBind = mkOption {
|
||||||
|
description = mdDoc ''
|
||||||
|
'';
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
address = mkOption {
|
||||||
|
description = mdDoc ''
|
||||||
|
'';
|
||||||
|
type = types.str;
|
||||||
|
default = "0.0.0.0:19000";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
drainTime = mkOption {
|
||||||
|
description = mdDoc ''
|
||||||
|
'';
|
||||||
|
type = types.int;
|
||||||
|
default = 15;
|
||||||
|
};
|
||||||
|
|
||||||
|
parentShutdownTime = mkOption {
|
||||||
|
description = mdDoc ''
|
||||||
|
'';
|
||||||
|
type = types.int;
|
||||||
|
default = 20;
|
||||||
|
};
|
||||||
|
|
||||||
|
hotRestart = mkOption {
|
||||||
|
description = mdDoc ''
|
||||||
|
'';
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
consulPackage = mkOption {
|
||||||
|
description = mdDoc ''
|
||||||
|
'';
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.consul;
|
||||||
|
};
|
||||||
|
|
||||||
|
envoyPackage = mkOption {
|
||||||
|
description = mdDoc ''
|
||||||
|
'';
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.envoy;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
systemd.services = flip mapAttrs' cfg (name: value:
|
||||||
|
nameValuePair
|
||||||
|
"hashicorp-envoy-${name}"
|
||||||
|
{
|
||||||
|
description = name;
|
||||||
|
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
|
||||||
|
path = [ value.envoyPackage ];
|
||||||
|
|
||||||
|
restartIfChanged = true;
|
||||||
|
|
||||||
|
preStart =
|
||||||
|
if value.type == "normal" then
|
||||||
|
''
|
||||||
|
${value.consulPackage}/bin/consul services register ${serviceFile name value}
|
||||||
|
''
|
||||||
|
else
|
||||||
|
''
|
||||||
|
${value.consulPackage}/bin/consul config write ${serviceFile name value}
|
||||||
|
'';
|
||||||
|
postStop =
|
||||||
|
if value.type == "normal" then
|
||||||
|
''
|
||||||
|
${value.consulPackage}/bin/consul services deregister -id=${value.service.id}
|
||||||
|
''
|
||||||
|
else
|
||||||
|
''
|
||||||
|
${value.consulPackage}/bin/consul config delete -filename ${serviceFile name value}
|
||||||
|
'';
|
||||||
|
script =
|
||||||
|
let
|
||||||
|
startEnvoy = pkgs.writeShellScript "start_envoy_${name}.sh"
|
||||||
|
''
|
||||||
|
exec ${value.consulPackage}/bin/consul connect envoy \
|
||||||
|
${optionalString (value.type == "normal") ''
|
||||||
|
-sidecar-for ${value.service.id} \
|
||||||
|
''} \
|
||||||
|
${optionalString (value.type == "ingress") ''
|
||||||
|
-gateway=ingress \
|
||||||
|
-register \
|
||||||
|
-service ${value.service.name} \
|
||||||
|
''} \
|
||||||
|
-admin-bind ${value.adminBind} \
|
||||||
|
-address ${value.address} \
|
||||||
|
${optionalString value.hotRestart ''
|
||||||
|
-- \
|
||||||
|
$([[ $RESTART_EPOCH == 0 ]] && printf -- "--use-dynamic-base-id --base-id-path $RUNTIME_DIRECTORY/id") \
|
||||||
|
$([[ $RESTART_EPOCH == 0 ]] || printf -- "--base-id $(cat $RUNTIME_DIRECTORY/id)") \
|
||||||
|
--restart-epoch $RESTART_EPOCH \
|
||||||
|
--drain-time-s ${toString value.drainTime} \
|
||||||
|
--parent-shutdown-time-s ${toString value.parentShutdownTime}
|
||||||
|
''}
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
if value.hotRestart then
|
||||||
|
"exec ${pkgs.python3}/bin/python ${value.envoyPackage.src}/restarter/hot-restarter.py ${startEnvoy}"
|
||||||
|
else
|
||||||
|
"exec ${startEnvoy}";
|
||||||
|
|
||||||
|
environment = value.environment;
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
ExecReload = if value.hotRestart then "${pkgs.coreutils}/bin/kill -HUP $MAINPID" else null;
|
||||||
|
KillMode = "control-group";
|
||||||
|
KillSignal = "SIGINT";
|
||||||
|
LimitNOFILE = 65536;
|
||||||
|
LimitNPROC = "infinity";
|
||||||
|
OOMScoreAdjust = -1000;
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = 2;
|
||||||
|
TasksMax = "infinity";
|
||||||
|
|
||||||
|
RuntimeDirectory = name;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
72
nixos/modules/telegraf.nix
Normal file
72
nixos/modules/telegraf.nix
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.services.telegraf-magic;
|
||||||
|
|
||||||
|
settingsFormat = pkgs.formats.toml {};
|
||||||
|
configFile = settingsFormat.generate "config.toml" cfg.settings;
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
services.telegraf-magic = {
|
||||||
|
enable = mkEnableOption (lib.mdDoc "telegraf server");
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
default = pkgs.telegraf;
|
||||||
|
defaultText = literalExpression "pkgs.telegraf";
|
||||||
|
description = lib.mdDoc "Which telegraf derivation to use";
|
||||||
|
type = types.package;
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
default = {};
|
||||||
|
description = lib.mdDoc "Extra configuration options for telegraf";
|
||||||
|
type = settingsFormat.type;
|
||||||
|
example = {
|
||||||
|
outputs.influxdb = {
|
||||||
|
urls = ["http://localhost:8086"];
|
||||||
|
database = "telegraf";
|
||||||
|
};
|
||||||
|
inputs.statsd = {
|
||||||
|
service_address = ":8125";
|
||||||
|
delete_timings = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd = mkOption {
|
||||||
|
default = {};
|
||||||
|
description = lib.mdDoc "Applied to `systemd.services.telegraf`.";
|
||||||
|
type = types.unspecified;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
systemd.services.telegraf = mkMerge [
|
||||||
|
(cfg.systemd)
|
||||||
|
{
|
||||||
|
description = "Telegraf Agent";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart="${cfg.package}/bin/telegraf -config ${configFile}";
|
||||||
|
ExecReload="${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||||
|
RuntimeDirectory = "telegraf";
|
||||||
|
User = "telegraf";
|
||||||
|
Group = "telegraf";
|
||||||
|
Restart = "on-failure";
|
||||||
|
# for ping probes
|
||||||
|
AmbientCapabilities = [ "CAP_NET_RAW" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
users.users.telegraf = {
|
||||||
|
uid = config.ids.uids.telegraf;
|
||||||
|
group = "telegraf";
|
||||||
|
description = "telegraf daemon user";
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups.telegraf = {};
|
||||||
|
};
|
||||||
|
}
|
81
nixos/systems/blowhole/bind.nix
Normal file
81
nixos/systems/blowhole/bind.nix
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
{ lib, pkgs, secret, ... }:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
concatMapStringsSep;
|
||||||
|
|
||||||
|
loggingConfig = ''
|
||||||
|
logging {
|
||||||
|
${concatMapStringsSep "\n" (x:
|
||||||
|
''
|
||||||
|
channel ${x}_file {
|
||||||
|
file "/var/log/named/${x}.log" versions 3 size 5m;
|
||||||
|
severity dynamic;
|
||||||
|
print-time yes;
|
||||||
|
};
|
||||||
|
category ${x} { ${x}_file; };
|
||||||
|
'') [
|
||||||
|
"default"
|
||||||
|
"database"
|
||||||
|
"security"
|
||||||
|
"config"
|
||||||
|
"resolver"
|
||||||
|
"xfer-in"
|
||||||
|
"xfer-out"
|
||||||
|
"notify"
|
||||||
|
"client"
|
||||||
|
"unmatched"
|
||||||
|
"queries"
|
||||||
|
"network"
|
||||||
|
"update"
|
||||||
|
"network"
|
||||||
|
"dispatch"
|
||||||
|
"dnssec"
|
||||||
|
"lame-servers"
|
||||||
|
]}
|
||||||
|
};
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d /var/log/named 0750 named named - -"
|
||||||
|
];
|
||||||
|
|
||||||
|
services.bind = {
|
||||||
|
enable = true;
|
||||||
|
forward = "only";
|
||||||
|
forwarders = [
|
||||||
|
"127.0.0.1 port 5353"
|
||||||
|
];
|
||||||
|
|
||||||
|
directory = "/var/lib/bind";
|
||||||
|
zones = {
|
||||||
|
"in.redalder.org" = {
|
||||||
|
file = ./zones/in.redalder.org.zone;
|
||||||
|
master = true;
|
||||||
|
};
|
||||||
|
"hosts.in.redalder.org" = {
|
||||||
|
file = ./zones/hosts.in.redalder.org.zone;
|
||||||
|
master = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
cacheNetworks = [
|
||||||
|
"127.0.0.0/8"
|
||||||
|
(secret.network.networks.home.wireless or "")
|
||||||
|
(secret.network.networks.home.mine or "")
|
||||||
|
"10.64.99.0/24"
|
||||||
|
(secret.network.networks.home.amsterdam or "")
|
||||||
|
(secret.network.networks.vpn or "")
|
||||||
|
"172.26.64.0/20"
|
||||||
|
];
|
||||||
|
extraConfig = loggingConfig;
|
||||||
|
extraOptions = ''
|
||||||
|
# recursion yes;
|
||||||
|
dnssec-validation auto;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.bind = {
|
||||||
|
before = [ "network-online.target" ];
|
||||||
|
};
|
||||||
|
}
|
80
nixos/systems/blowhole/consul.nix
Normal file
80
nixos/systems/blowhole/consul.nix
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
{inputs', lib, config, pkgs, secret, ...}:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
singleton
|
||||||
|
mkForce;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
services.hashicorp.vault-agent = {
|
||||||
|
settings.template = singleton {
|
||||||
|
source = pkgs.writeText "consul.json.vtmpl"
|
||||||
|
''
|
||||||
|
{
|
||||||
|
"encrypt": "{{ with secret "kv/data/homelab-1/blowhole/consul/encryption_key" }}{{ or .Data.data.key "" }}{{ end }}",
|
||||||
|
"acl": {
|
||||||
|
"tokens": {
|
||||||
|
"agent": "{{ with secret "kv/data/homelab-1/blowhole/consul/agent_token" }}{{ or .Data.data.secret "" }}{{ end }}",
|
||||||
|
"default": "{{ with secret "kv/data/homelab-1/blowhole/consul/anonymous_token" }}{{ or .Data.data.secret "" }}{{ end }}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
destination = "/run/secrets/consul.json";
|
||||||
|
command = pkgs.writeShellScript "consul-command" ''
|
||||||
|
sudo systemctl try-reload-or-restart hashicorp-consul.service
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.hashicorp-consul.unitConfig = {
|
||||||
|
ConditionPathExists = "/run/secrets/consul.json";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.hashicorp.consul = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
extraSettingsPaths = singleton "/run/secrets/consul.json";
|
||||||
|
package = inputs'.nixpkgs-hashicorp.legacyPackages.${pkgs.stdenv.system}.consul;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
datacenter = "homelab-1";
|
||||||
|
data_dir = "/var/lib/consul";
|
||||||
|
log_level = "INFO";
|
||||||
|
|
||||||
|
server = true;
|
||||||
|
|
||||||
|
bind_addr = secret.network.ips.blowhole.ip or "";
|
||||||
|
client_addr = secret.network.ips.blowhole.ip or "";
|
||||||
|
|
||||||
|
primary_datacenter = "homelab-1";
|
||||||
|
|
||||||
|
acl = {
|
||||||
|
enabled = true;
|
||||||
|
default_policy = "deny";
|
||||||
|
enable_token_persistence = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
ports = {
|
||||||
|
http = 8500;
|
||||||
|
grpc = 8502;
|
||||||
|
};
|
||||||
|
|
||||||
|
connect.enabled = true;
|
||||||
|
|
||||||
|
ca_file = "/var/secrets/consul-ca.crt";
|
||||||
|
# cert_file = ""
|
||||||
|
# key_file = ""
|
||||||
|
verify_incoming = false;
|
||||||
|
verify_outgoing = false;
|
||||||
|
verify_server_hostname = false;
|
||||||
|
|
||||||
|
ui_config.enabled = true;
|
||||||
|
domain = "consul.in.redalder.org";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.hashicorp-consul.serviceConfig = {
|
||||||
|
LimitNOFILE = mkForce "infinity";
|
||||||
|
LimitNPROC = mkForce "infinity";
|
||||||
|
};
|
||||||
|
}
|
73
nixos/systems/blowhole/default.nix
Normal file
73
nixos/systems/blowhole/default.nix
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
{ inputs, lib, config, ... }:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
flip
|
||||||
|
mapAttrs
|
||||||
|
singleton;
|
||||||
|
|
||||||
|
config' = config;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
flake.nixosConfigurations.blowhole = inputs.nixpkgs.lib.nixosSystem {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
|
||||||
|
specialArgs = {
|
||||||
|
config' = config';
|
||||||
|
inputs' = inputs;
|
||||||
|
secret =
|
||||||
|
if builtins.pathExists "${inputs.secret}/default.nix" then
|
||||||
|
import inputs.secret { inherit lib; }
|
||||||
|
else
|
||||||
|
{};
|
||||||
|
};
|
||||||
|
|
||||||
|
modules = singleton
|
||||||
|
({ pkgs, config, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./bind.nix
|
||||||
|
./consul.nix
|
||||||
|
./filesystems.nix
|
||||||
|
./firewall.nix
|
||||||
|
./grub.nix
|
||||||
|
./hardware.nix
|
||||||
|
./hostapd.nix
|
||||||
|
./ical2org.nix
|
||||||
|
./klipper.nix
|
||||||
|
./monitoring.nix
|
||||||
|
./nas.nix
|
||||||
|
./networking.nix
|
||||||
|
./nfs.nix
|
||||||
|
./nomad.nix
|
||||||
|
./uterranix.nix
|
||||||
|
./vault-agent.nix
|
||||||
|
./vault.nix
|
||||||
|
./watchdog.nix
|
||||||
|
./nixpkgs.nix
|
||||||
|
./users.nix
|
||||||
|
../../common/remote_access.nix
|
||||||
|
inputs.serokell-nix.nixosModules.acme-sh
|
||||||
|
config'.flake.nixosModules.hashicorp
|
||||||
|
config'.flake.nixosModules.hashicorp-envoy
|
||||||
|
config'.flake.nixosModules.telegraf
|
||||||
|
config'.flake.nixosModules.grafana
|
||||||
|
];
|
||||||
|
|
||||||
|
_module.args.nixinate = {
|
||||||
|
host = "blowhole.hosts.in.redalder.org";
|
||||||
|
sshUser = "main";
|
||||||
|
buildOn = "local";
|
||||||
|
substituteOnTarget = true;
|
||||||
|
hermetic = false;
|
||||||
|
nixOptions = [
|
||||||
|
"--override-input secret path://$HOME/dotfiles/secret"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
system.stateVersion = "21.05";
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
77
nixos/systems/blowhole/filesystems.nix
Normal file
77
nixos/systems/blowhole/filesystems.nix
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
{ pkgs, lib, secret, ... }:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
singleton;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
sshfs
|
||||||
|
];
|
||||||
|
|
||||||
|
fileSystems =
|
||||||
|
{
|
||||||
|
"/boot" = {
|
||||||
|
device = "/dev/disk/by-uuid/738acc32-3e2e-4986-987c-40264153d5bf";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
"/" = {
|
||||||
|
device = "blowhole-zpool/local/root";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
"/nix" = {
|
||||||
|
device = "blowhole-zpool/local/nix";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
"/var/nfs" = {
|
||||||
|
device = "/dev/disk/by-uuid/e06f6d2c-e434-4eec-b00d-b13c1ecc96f0";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = [
|
||||||
|
"subvol=/nfs"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
"/mnt/cctv" = {
|
||||||
|
device = "camera@${secret.network.ips.woodchip or ""}:/";
|
||||||
|
fsType = "fuse.sshfs";
|
||||||
|
noCheck = true;
|
||||||
|
options = [
|
||||||
|
"_netdev"
|
||||||
|
"noauto"
|
||||||
|
"x-systemd.automount"
|
||||||
|
"IdentityFile=/run/secrets/id_ed_camera"
|
||||||
|
"StrictHostKeyChecking=no"
|
||||||
|
"allow_other"
|
||||||
|
"reconnect"
|
||||||
|
"Port=2522"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
"/old-root" = {
|
||||||
|
device = "/dev/disk/by-uuid/e06f6d2c-e434-4eec-b00d-b13c1ecc96f0";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = [
|
||||||
|
"subvol=/arch"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"/var/lib/nomad" = {
|
||||||
|
device = "blowhole-zpool/persist/nomad";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
"/var/secrets" = {
|
||||||
|
device = "blowhole-zpool/persist/secrets";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
"/var/lib/consul" = {
|
||||||
|
device = "/old-root/var/lib/consul";
|
||||||
|
options = singleton "bind";
|
||||||
|
};
|
||||||
|
"/var/lib/vault" = {
|
||||||
|
device = "/old-root/var/lib/vault";
|
||||||
|
options = singleton "bind";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// secret.mounts.blowhole or {};
|
||||||
|
}
|
303
nixos/systems/blowhole/firewall.nix
Normal file
303
nixos/systems/blowhole/firewall.nix
Normal file
|
@ -0,0 +1,303 @@
|
||||||
|
{ pkgs, secret, config, lib, ... }:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
mapAttrs
|
||||||
|
const
|
||||||
|
mkForce
|
||||||
|
singleton;
|
||||||
|
|
||||||
|
wlan = "wlp10s0";
|
||||||
|
lan = "enp8s0f1";
|
||||||
|
wan = "enp3s0";
|
||||||
|
doVPN = "do_vpn0";
|
||||||
|
|
||||||
|
nomad = mapAttrs (const toString) {
|
||||||
|
inherit (config.services.hashicorp.nomad.settings.client)
|
||||||
|
min_dynamic_port
|
||||||
|
max_dynamic_port;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
boot.kernel.sysctl = {
|
||||||
|
# Enable forwarding on IPv4 but disable on IPv6
|
||||||
|
"net.ipv4.conf.all.forwarding" = true;
|
||||||
|
"net.ipv6.conf.all.forwarding" = false;
|
||||||
|
|
||||||
|
# source: https://github.com/mdlayher/homelab/blob/master/nixos/routnerr-2/configuration.nix#L52
|
||||||
|
# By default, not automatically configure any IPv6 addresses.
|
||||||
|
"net.ipv6.conf.all.accept_ra" = 0;
|
||||||
|
"net.ipv6.conf.all.autoconf" = 0;
|
||||||
|
"net.ipv6.conf.all.use_tempaddr" = 0;
|
||||||
|
|
||||||
|
# On WAN, allow IPv6 autoconfiguration and tempory address use.
|
||||||
|
# "net.ipv6.conf.${name}.accept_ra" = 2;
|
||||||
|
# "net.ipv6.conf.${name}.autoconf" = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.dnscrypt-proxy2 = {
|
||||||
|
enable = true;
|
||||||
|
upstreamDefaults = true;
|
||||||
|
settings = {
|
||||||
|
listen_addresses = singleton "127.0.0.1:5353";
|
||||||
|
|
||||||
|
dnscrypt_servers = false;
|
||||||
|
doh_servers = true;
|
||||||
|
odoh_servers = false;
|
||||||
|
|
||||||
|
block_ipv6 = true;
|
||||||
|
|
||||||
|
static."mullvad".stamp = "sdns://AgcAAAAAAAAAAAAPZG9oLm11bGx2YWQubmV0Ci9kbnMtcXVlcnk";
|
||||||
|
static."meganerd".stamp = "sdns://AQcAAAAAAAAADjEzNi4yNDQuOTcuMTE0ICif6V9M6EF_9Xo_MHwkDN4ZJjERopSJN8hBuUWg9YeMJTIuZG5zY3J5cHQtY2VydC5jaGV3YmFjY2EubWVnYW5lcmQubmw";
|
||||||
|
sources = {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.dnscrypt-proxy2 = {
|
||||||
|
before = [ "network-online.target" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.dhcpd4 = {
|
||||||
|
enable = true;
|
||||||
|
interfaces = [ "${lan}" "${wlan}" ];
|
||||||
|
extraConfig = ''
|
||||||
|
option domain-name-servers ${secret.network.ips.blowhole.ip or ""};
|
||||||
|
option subnet-mask 255.255.255.0;
|
||||||
|
|
||||||
|
${secret.dhcp.blowhole.zones or (const "") { inherit wlan lan; }}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
useDHCP = false;
|
||||||
|
hostName = "blowhole";
|
||||||
|
|
||||||
|
resolvconf.useLocalResolver = false;
|
||||||
|
nameservers = singleton (secret.network.ips.blowhole.ip or "");
|
||||||
|
|
||||||
|
# Disable the in-built iptable based firewall
|
||||||
|
firewall.enable = mkForce false;
|
||||||
|
|
||||||
|
localCommands = ''
|
||||||
|
ip link add enp4s0 type dummy || true
|
||||||
|
ip link set enp4s0 up || true
|
||||||
|
ip addr add ${secret.network.ips.blowhole.ip}/24 dev enp4s0 || true
|
||||||
|
'';
|
||||||
|
|
||||||
|
interfaces = {
|
||||||
|
# Don't do DHCP on the LAN interface
|
||||||
|
"${lan}" = {
|
||||||
|
useDHCP = false;
|
||||||
|
ipv4.addresses = [{
|
||||||
|
address = secret.network.ips.blowhole.ip or "";
|
||||||
|
prefixLength = 24;
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
"${wlan}" = {
|
||||||
|
useDHCP = false;
|
||||||
|
ipv4.addresses = [{
|
||||||
|
address = secret.network.ips.blowhole.wlan or "";
|
||||||
|
prefixLength = 24;
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
# But do DHCP on the WAN interface
|
||||||
|
"${wan}".useDHCP = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
wireguard = {
|
||||||
|
enable = true;
|
||||||
|
interfaces."${doVPN}" =
|
||||||
|
secret.wireguard."${config.networking.hostName}" or {} // {
|
||||||
|
listenPort = 6666;
|
||||||
|
privateKeyFile = "/var/secrets/${doVPN}.key";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nftables = {
|
||||||
|
enable = true;
|
||||||
|
ruleset = ''
|
||||||
|
table ip nf_filter {
|
||||||
|
chain input_out {
|
||||||
|
ct state { established, related } accept comment "Allow established traffic"
|
||||||
|
icmp type { echo-request, destination-unreachable, time-exceeded } counter accept comment "Allow select ICMP"
|
||||||
|
}
|
||||||
|
|
||||||
|
chain input_doVPN {
|
||||||
|
tcp dport { 4646, 4647, 4648 } accept comment "Nomad traffic"
|
||||||
|
tcp dport { 8600, 8500, 8502, 8300, 8301, 8302 } accept comment "Consul traffic"
|
||||||
|
tcp dport { 8200 } accept comment "Vault traffic"
|
||||||
|
tcp dport { 111, 2049, 4000, 4001, 4002, 20048 } accept comment "NFS traffic"
|
||||||
|
tcp dport ${nomad.min_dynamic_port}-${nomad.max_dynamic_port} accept comment "Consul Connect sidecar traffic"
|
||||||
|
tcp dport { 53 } accept comment "DNS traffic"
|
||||||
|
tcp dport { 80 } accept comment "HTTP traffic"
|
||||||
|
|
||||||
|
udp dport { 8600, 8301, 8302 } comment "Consul traffic"
|
||||||
|
udp dport { 111, 2049, 4000, 4001, 4002, 20048 } accept comment "NFS traffic"
|
||||||
|
udp dport ${nomad.min_dynamic_port}-${nomad.max_dynamic_port} accept comment "Consul Connect sidecar traffic"
|
||||||
|
udp dport { 53 } accept comment "DNS traffic"
|
||||||
|
}
|
||||||
|
|
||||||
|
chain input {
|
||||||
|
type filter hook input priority 0; policy drop;
|
||||||
|
|
||||||
|
tcp dport 22 accept comment "Accept SSH traffic always"
|
||||||
|
iifname != "lo" tcp dport 5353 drop comment "Drop traffic to dnscrypt-proxy always except for localhost to localhost traffic"
|
||||||
|
|
||||||
|
iifname { "nomad", "ve-monitor", "ve-klipper" } oifname { "nomad", "ve-monitor", "ve-klipper" } accept comment "Allow Nomad to do whatever it wants in its interface"
|
||||||
|
iifname { "${wlan}", "${lan}", "lo" } accept comment "Allow local network to access the router"
|
||||||
|
iifname { "${wan}", "${doVPN}", "nomad", "docker0", "ve-monitor", "ve-klipper" } jump input_out
|
||||||
|
iifname { "${doVPN}" } jump input_doVPN
|
||||||
|
|
||||||
|
# Allow containers to reach the DNS server
|
||||||
|
iifname { "nomad", "docker0", "ve-monitor", "ve-klipper" } tcp dport 53 accept
|
||||||
|
iifname { "nomad", "docker0", "ve-monitor", "ve-klipper" } udp dport 53 accept
|
||||||
|
|
||||||
|
# Allow Nomad Containers to reach Nomad
|
||||||
|
iifname { "nomad" } tcp dport 4646 accept
|
||||||
|
|
||||||
|
# Allow proxies to reach consul
|
||||||
|
iifname { "nomad", "ve-monitor", "ve-klipper" } tcp dport 8500 accept
|
||||||
|
iifname { "ve-monitor", "ve-klipper" } tcp dport 8502 accept
|
||||||
|
|
||||||
|
# Allow containers to reach the NFS server
|
||||||
|
iifname { "docker0" } tcp dport { 111, 2049, 4000, 4001, 4002, 20048 } accept comment "NFS traffic"
|
||||||
|
iifname { "docker0" } udp dport { 111, 2049, 4000, 4001, 4002, 20048 } accept comment "NFS traffic"
|
||||||
|
|
||||||
|
meta nftrace set 1
|
||||||
|
}
|
||||||
|
|
||||||
|
chain output {
|
||||||
|
type filter hook output priority 0; policy accept;
|
||||||
|
|
||||||
|
# Drop all DNS traffic if leaving through "wan"
|
||||||
|
# oifname { "${wan}" } tcp dport 53 drop
|
||||||
|
# oifname { "${wan}" } udp dport 53 drop
|
||||||
|
# Allow DoT traffic to leave through "wan" if it comes from "lo"
|
||||||
|
# iifname != { "lo" } oifname { "${wan}" } tcp dport 853 drop
|
||||||
|
}
|
||||||
|
|
||||||
|
chain forward {
|
||||||
|
type filter hook forward priority 10; policy drop;
|
||||||
|
|
||||||
|
# Enable flow offloading for better throughput
|
||||||
|
# ip protocol { tcp, udp } flow offload @f
|
||||||
|
|
||||||
|
# Drop all DNS or DoT traffic if forwarded through "wan"
|
||||||
|
oifname { "${wan}" } tcp dport 853 drop
|
||||||
|
oifname { "${wan}" } tcp dport 53 drop
|
||||||
|
oifname { "${wan}" } udp dport 53 drop
|
||||||
|
|
||||||
|
# Allow trusted LAN to WAN"
|
||||||
|
iifname { "${lan}", "${wlan}" } oifname { "${wan}" } accept
|
||||||
|
iifname { "${wan}" } oifname { "${lan}", "${wlan}" } ct state established, related accept
|
||||||
|
|
||||||
|
|
||||||
|
iifname { "nomad" } oifname { "${doVPN}", "${lan}", "${wlan}" } accept
|
||||||
|
iifname { "${doVPN}", "${lan}", "${wlan}" } oifname { "nomad" } accept
|
||||||
|
iifname { "${doVPN}" } oifname { "${lan}", "${wlan}" } accept
|
||||||
|
iifname { "${lan}", "${wlan}" } oifname { "${doVPN}" } accept
|
||||||
|
|
||||||
|
# Allow containers to reach WAN
|
||||||
|
iifname { "nomad", "docker0", "ve-monitor", "ve-klipper" } oifname { "${wan}" } accept
|
||||||
|
iifname { "${wan}" } oifname { "nomad", "docker0", "ve-monitor", "ve-klipper" } ct state established, related accept
|
||||||
|
|
||||||
|
# Allow containers to reach the DNS and NFS server
|
||||||
|
iifname { "nomad", "docker0", "ve-monitor", "ve-klipper" } oifname { "${lan}" } ip daddr 10.64.2.1 tcp dport { 53 } accept
|
||||||
|
iifname { "nomad", "docker0", "ve-monitor", "ve-klipper" } oifname { "${lan}" } ip saddr 10.64.2.1 tcp sport { 53 } accept
|
||||||
|
iifname { "nomad", "docker0", "ve-monitor", "ve-klipper" } oifname { "${lan}" } ip daddr 10.64.2.1 tcp dport { 111, 2049, 4000, 4001, 4002, 20048 } accept
|
||||||
|
iifname { "nomad", "docker0", "ve-monitor", "ve-klipper" } oifname { "${lan}" } ip saddr 10.64.2.1 tcp sport { 111, 2049, 4000, 4001, 4002, 20048 } accept
|
||||||
|
iifname { "nomad", "docker0", "ve-monitor", "ve-klipper" } oifname { "${lan}" } ip daddr 10.64.2.1 udp dport { 53 } accept
|
||||||
|
iifname { "nomad", "docker0", "ve-monitor", "ve-klipper" } oifname { "${lan}" } ip saddr 10.64.2.1 udp sport { 53 } accept
|
||||||
|
iifname { "nomad", "docker0", "ve-monitor", "ve-klipper" } oifname { "${lan}" } ip daddr 10.64.2.1 udp dport { 111, 2049, 4000, 4001, 4002, 20048 } accept
|
||||||
|
iifname { "nomad", "docker0", "ve-monitor", "ve-klipper" } oifname { "${lan}" } ip saddr 10.64.2.1 udp sport { 111, 2049, 4000, 4001, 4002, 20048 } accept
|
||||||
|
|
||||||
|
|
||||||
|
# Rules to make CNI happy
|
||||||
|
meta mark and 0x01 == 0x01 accept
|
||||||
|
|
||||||
|
meta nftrace set 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table ip nf_nat {
|
||||||
|
chain postrouting {
|
||||||
|
type nat hook postrouting priority 100; policy accept;
|
||||||
|
oifname "${wan}" masquerade
|
||||||
|
}
|
||||||
|
|
||||||
|
chain prerouting {
|
||||||
|
type nat hook prerouting priority 100; policy accept;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table ip6 nf_filter {
|
||||||
|
chain output {
|
||||||
|
type filter hook output priority 0; policy drop;
|
||||||
|
|
||||||
|
meta nftrace set 1
|
||||||
|
|
||||||
|
oifname "lo" icmpv6 type { echo-request, destination-unreachable, time-exceeded } counter accept comment "Allow select ICMP"
|
||||||
|
oifname "lo" ip6 saddr "::1" ip6 daddr "::1" reject
|
||||||
|
}
|
||||||
|
chain input {
|
||||||
|
type filter hook input priority 0; policy drop;
|
||||||
|
|
||||||
|
meta nftrace set 1
|
||||||
|
|
||||||
|
iifname "lo" icmpv6 type { echo-request, destination-unreachable, time-exceeded } counter accept comment "Allow select ICMP"
|
||||||
|
}
|
||||||
|
chain forward {
|
||||||
|
type filter hook forward priority 0; policy drop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.nftables = {
|
||||||
|
serviceConfig =
|
||||||
|
let
|
||||||
|
rulesScript = pkgs.writeShellScript "nftables-rules" ''
|
||||||
|
set -ex
|
||||||
|
export PATH=${pkgs.nftables}/bin:${pkgs.iptables}/bin:${pkgs.bash}/bin:$PATH
|
||||||
|
|
||||||
|
tmpfile="$(mktemp)"
|
||||||
|
iptables-save -t filter >> $tmpfile
|
||||||
|
iptables-save -t nat >> $tmpfile
|
||||||
|
|
||||||
|
nft flush ruleset
|
||||||
|
|
||||||
|
cat $tmpfile | iptables-restore
|
||||||
|
nft -f "${pkgs.writeText "nftables-rules" config.networking.nftables.ruleset}"
|
||||||
|
rm $tmpfile
|
||||||
|
|
||||||
|
iptables -D FORWARD -j MARK --set-mark 0x01 || true
|
||||||
|
iptables -D FORWARD -j MARK --set-mark 0x00 || true
|
||||||
|
|
||||||
|
iptables -I FORWARD -j MARK --set-mark 0x01
|
||||||
|
iptables -A FORWARD -j MARK --set-mark 0x00
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
ExecStart = mkForce rulesScript;
|
||||||
|
ExecReload = mkForce rulesScript;
|
||||||
|
ExecStop = mkForce (pkgs.writeShellScript "nftables-flush" ''
|
||||||
|
set -ex
|
||||||
|
export PATH=${pkgs.nftables}/bin:${pkgs.iptables}/bin:${pkgs.bash}/bin:$PATH
|
||||||
|
|
||||||
|
tmpfile="$(mktemp)"
|
||||||
|
iptables-save -t filter >> $tmpfile
|
||||||
|
iptables-save -t nat >> $tmpfile
|
||||||
|
|
||||||
|
nft flush ruleset
|
||||||
|
|
||||||
|
cat $tmpfile | iptables-restore
|
||||||
|
rm $tmpfile
|
||||||
|
|
||||||
|
iptables -D FORWARD -j MARK --set-mark 0x01 || true
|
||||||
|
iptables -D FORWARD -j MARK --set-mark 0x00 || true
|
||||||
|
|
||||||
|
iptables -I FORWARD -j MARK --set-mark 0x01
|
||||||
|
iptables -A FORWARD -j MARK --set-mark 0x00
|
||||||
|
'');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
10
nixos/systems/blowhole/grub.nix
Normal file
10
nixos/systems/blowhole/grub.nix
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
boot.loader = {
|
||||||
|
systemd-boot.enable = false;
|
||||||
|
grub = {
|
||||||
|
enable = true;
|
||||||
|
devices = [ "/dev/disk/by-id/usb-Verbatim_STORE_N_GO_072124E3712B7287-0:0" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
18
nixos/systems/blowhole/hardware.nix
Normal file
18
nixos/systems/blowhole/hardware.nix
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
boot = {
|
||||||
|
supportedFilesystems = ["zfs"];
|
||||||
|
initrd.availableKernelModules = [
|
||||||
|
"xhci_pci"
|
||||||
|
"ahci"
|
||||||
|
"usbhid"
|
||||||
|
"usb_storage"
|
||||||
|
"sd_mod"
|
||||||
|
"nvme"
|
||||||
|
];
|
||||||
|
zfs.enableUnstable = true;
|
||||||
|
kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;
|
||||||
|
};
|
||||||
|
|
||||||
|
hardware.enableRedistributableFirmware = true;
|
||||||
|
}
|
539
nixos/systems/blowhole/hostapd.nix
Normal file
539
nixos/systems/blowhole/hostapd.nix
Normal file
|
@ -0,0 +1,539 @@
|
||||||
|
{ pkgs, config, lib, config', ... }:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
singleton;
|
||||||
|
|
||||||
|
openwrtRepo = pkgs.fetchFromGitHub {
|
||||||
|
owner = "openwrt";
|
||||||
|
repo = "openwrt";
|
||||||
|
rev = "67e8cc07f9bb95984624198ccf02123f348246df";
|
||||||
|
sha256 = "sha256-rBQDTUG9fqwSLrj+LZ6L1x55Y3gkfUubY5zwX9XK3+s=";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# giturl="https://raw.githubusercontent.com/openwrt/openwrt/75b83e94a395fedeb4d308f42013a72c6fee2df4/package/network/services/hostapd/patches/"
|
||||||
|
# for patch in *.patch
|
||||||
|
# do
|
||||||
|
# nix-prefetch-url "$giturl$patch" 2>/dev/null | \
|
||||||
|
# sed -e 's~^~{ url = "'"$giturl$patch"'"; sha256 = "~' | sed -e 's~$~"; \}~'
|
||||||
|
# done
|
||||||
|
|
||||||
|
services.hashicorp.vault-agent.settings.template = singleton {
|
||||||
|
source = pkgs.writeText "hostapd_wpa_psk.vtmpl" ''
|
||||||
|
{{ with secret "kv/data/homelab-1/blowhole/hostapd/wpa_psk" -}}
|
||||||
|
{{ range $key, $value := .Data.data -}}
|
||||||
|
{{ with $data := $value -}}
|
||||||
|
{{ $data.mac_address }} {{ $data.psk }}
|
||||||
|
{{ end -}}
|
||||||
|
{{ end -}}
|
||||||
|
{{ end -}}
|
||||||
|
'';
|
||||||
|
destination = "/run/secrets/hostapd_wpa_psk";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.hostapd.unitConfig = {
|
||||||
|
ConditionPathExists = "/run/secrets/hostapd_wpa_psk";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.hostapd = {
|
||||||
|
interface = "wlp10s0";
|
||||||
|
driver = "nl80211";
|
||||||
|
ssid = "nothing";
|
||||||
|
wpa = false;
|
||||||
|
hwMode = "g";
|
||||||
|
channel = 14;
|
||||||
|
countryCode = "NL";
|
||||||
|
enable = true;
|
||||||
|
extraConfig = ''
|
||||||
|
wpa_psk_file=/run/secrets/hostapd_wpa_psk
|
||||||
|
|
||||||
|
#ieee80211d=1
|
||||||
|
#ieee80211h=1
|
||||||
|
#ieee80211n=1
|
||||||
|
# ieee80211ac=1
|
||||||
|
|
||||||
|
# intel_lar=1
|
||||||
|
noscan=0
|
||||||
|
beacon_int=100
|
||||||
|
channel=14
|
||||||
|
# channel=149
|
||||||
|
# chanlist=149
|
||||||
|
|
||||||
|
#ht_capab=[HT40+][LDPC][SHORT-GI-20][SHORT-GI-40][TX-STBC][RX-STBC1][MAX-AMSDU-7935][DSSS_CCK-40]
|
||||||
|
#ht_capab=[VHT_IBSS][RRM][MU_MIMO_AIR_SNIFFER][SCAN_START_TIME][BSS_PARENT_TSF][FILS_STA][FILS_MAX_CHANNEL_TIME][ACCEPT_BCAST_PROBE_RESP][OCE_PROBE_REQ_HIGH_TX_RATE][CONTROL_PORT_OVER_NL80211][TXQS][ENABLE_FTM_RESPONDER][CONTROL_PORT_NO_PREAUTH][PROTECTED_TWT][DEL_IBSS_STA][BEACON_PROTECTION_CLIENT][SCAN_FREQ_KHZ][CONTROL_PORT_OVER_NL80211_TX_STATUS]
|
||||||
|
|
||||||
|
ap_isolate=1
|
||||||
|
preamble=1
|
||||||
|
wmm_enabled=1
|
||||||
|
utf8_ssid=1
|
||||||
|
|
||||||
|
auth_algs=1
|
||||||
|
wpa=2
|
||||||
|
wpa_pairwise=CCMP
|
||||||
|
wpa_disable_eapol_key_retries=0
|
||||||
|
wpa_key_mgmt=WPA-PSK
|
||||||
|
okc=0
|
||||||
|
disable_pmksa_caching=1
|
||||||
|
|
||||||
|
bssid=e0:d0:45:81:50:00
|
||||||
|
|
||||||
|
# bss=wlp10s1
|
||||||
|
# ssid=nothing2
|
||||||
|
# bssid=e0:d0:45:81:50:01
|
||||||
|
|
||||||
|
# hw_mode=g
|
||||||
|
# channel=9
|
||||||
|
# vht_capab=
|
||||||
|
# ht_capab=
|
||||||
|
|
||||||
|
# auth_algs=1
|
||||||
|
# wpa=2
|
||||||
|
# wpa_pairwise=CCMP
|
||||||
|
# wpa_disable_eapol_key_retries=0
|
||||||
|
# wpa_key_mgmt=WPA-PSK
|
||||||
|
# okc=0
|
||||||
|
# disable_pmksa_caching=1
|
||||||
|
# wpa_passphrase=${config.services.hostapd.wpaPassphrase}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
nixpkgs.overlays = singleton
|
||||||
|
(final: prev:
|
||||||
|
{
|
||||||
|
hostapd = prev.hostapd.overrideAttrs (old: {
|
||||||
|
buildInputs = old.buildInputs ++ (with pkgs; [
|
||||||
|
libubox
|
||||||
|
ubus
|
||||||
|
]);
|
||||||
|
|
||||||
|
src = pkgs.fetchgit {
|
||||||
|
url = "http://w1.fi/hostap.git";
|
||||||
|
rev = "bb945b98fefc64887dffb40773a19d77585cee42";
|
||||||
|
sha256 = "sha256-bDxMWjvgyNdBUH8pXJ+yMl3vBBoz57LOJEZHAGSDyS0=";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = ''
|
||||||
|
# Example hostapd build time configuration
|
||||||
|
#
|
||||||
|
# This file lists the configuration options that are used when building the
|
||||||
|
# hostapd binary. All lines starting with # are ignored. Configuration option
|
||||||
|
# lines must be commented out complete, if they are not to be included, i.e.,
|
||||||
|
# just setting VARIABLE=n is not disabling that variable.
|
||||||
|
#
|
||||||
|
# This file is included in Makefile, so variables like CFLAGS and LIBS can also
|
||||||
|
# be modified from here. In most cass, these lines should use += in order not
|
||||||
|
# to override previous values of the variables.
|
||||||
|
|
||||||
|
# Driver interface for Host AP driver
|
||||||
|
#CONFIG_DRIVER_HOSTAP=y
|
||||||
|
|
||||||
|
# Driver interface for wired authenticator
|
||||||
|
CONFIG_DRIVER_WIRED=y
|
||||||
|
|
||||||
|
# Driver interface for drivers using the nl80211 kernel interface
|
||||||
|
CONFIG_DRIVER_NL80211=y
|
||||||
|
|
||||||
|
# QCA vendor extensions to nl80211
|
||||||
|
#CONFIG_DRIVER_NL80211_QCA=y
|
||||||
|
|
||||||
|
# driver_nl80211.c requires libnl. If you are compiling it yourself
|
||||||
|
# you may need to point hostapd to your version of libnl.
|
||||||
|
#
|
||||||
|
#CFLAGS += -I$<path to libnl include files>
|
||||||
|
#LIBS += -L$<path to libnl library files>
|
||||||
|
|
||||||
|
# Use libnl v2.0 (or 3.0) libraries.
|
||||||
|
#CONFIG_LIBNL20=y
|
||||||
|
|
||||||
|
# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored)
|
||||||
|
#CONFIG_LIBNL32=y
|
||||||
|
|
||||||
|
|
||||||
|
# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
|
||||||
|
#CONFIG_DRIVER_BSD=y
|
||||||
|
#CFLAGS += -I/usr/local/include
|
||||||
|
#LIBS += -L/usr/local/lib
|
||||||
|
#LIBS_p += -L/usr/local/lib
|
||||||
|
#LIBS_c += -L/usr/local/lib
|
||||||
|
|
||||||
|
# Driver interface for no driver (e.g., RADIUS server only)
|
||||||
|
#CONFIG_DRIVER_NONE=y
|
||||||
|
|
||||||
|
# IEEE 802.11F/IAPP
|
||||||
|
CONFIG_IAPP=y
|
||||||
|
|
||||||
|
# WPA2/IEEE 802.11i RSN pre-authentication
|
||||||
|
CONFIG_RSN_PREAUTH=y
|
||||||
|
|
||||||
|
# IEEE 802.11w (management frame protection)
|
||||||
|
#CONFIG_IEEE80211W=y
|
||||||
|
|
||||||
|
# Support Operating Channel Validation
|
||||||
|
#CONFIG_OCV=y
|
||||||
|
|
||||||
|
# Integrated EAP server
|
||||||
|
CONFIG_EAP=y
|
||||||
|
|
||||||
|
# EAP Re-authentication Protocol (ERP) in integrated EAP server
|
||||||
|
CONFIG_ERP=y
|
||||||
|
|
||||||
|
# EAP-MD5 for the integrated EAP server
|
||||||
|
CONFIG_EAP_MD5=y
|
||||||
|
|
||||||
|
# EAP-TLS for the integrated EAP server
|
||||||
|
CONFIG_EAP_TLS=y
|
||||||
|
|
||||||
|
# EAP-MSCHAPv2 for the integrated EAP server
|
||||||
|
CONFIG_EAP_MSCHAPV2=y
|
||||||
|
|
||||||
|
# EAP-PEAP for the integrated EAP server
|
||||||
|
CONFIG_EAP_PEAP=y
|
||||||
|
|
||||||
|
# EAP-GTC for the integrated EAP server
|
||||||
|
CONFIG_EAP_GTC=y
|
||||||
|
|
||||||
|
# EAP-TTLS for the integrated EAP server
|
||||||
|
CONFIG_EAP_TTLS=y
|
||||||
|
|
||||||
|
# EAP-SIM for the integrated EAP server
|
||||||
|
#CONFIG_EAP_SIM=y
|
||||||
|
|
||||||
|
# EAP-AKA for the integrated EAP server
|
||||||
|
#CONFIG_EAP_AKA=y
|
||||||
|
|
||||||
|
# EAP-AKA' for the integrated EAP server
|
||||||
|
# This requires CONFIG_EAP_AKA to be enabled, too.
|
||||||
|
#CONFIG_EAP_AKA_PRIME=y
|
||||||
|
|
||||||
|
# EAP-PAX for the integrated EAP server
|
||||||
|
#CONFIG_EAP_PAX=y
|
||||||
|
|
||||||
|
# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK)
|
||||||
|
#CONFIG_EAP_PSK=y
|
||||||
|
|
||||||
|
# EAP-pwd for the integrated EAP server (secure authentication with a password)
|
||||||
|
#CONFIG_EAP_PWD=y
|
||||||
|
|
||||||
|
# EAP-SAKE for the integrated EAP server
|
||||||
|
#CONFIG_EAP_SAKE=y
|
||||||
|
|
||||||
|
# EAP-GPSK for the integrated EAP server
|
||||||
|
#CONFIG_EAP_GPSK=y
|
||||||
|
# Include support for optional SHA256 cipher suite in EAP-GPSK
|
||||||
|
#CONFIG_EAP_GPSK_SHA256=y
|
||||||
|
|
||||||
|
# EAP-FAST for the integrated EAP server
|
||||||
|
CONFIG_EAP_FAST=y
|
||||||
|
|
||||||
|
# EAP-TEAP for the integrated EAP server
|
||||||
|
# Note: The current EAP-TEAP implementation is experimental and should not be
|
||||||
|
# enabled for production use. The IETF RFC 7170 that defines EAP-TEAP has number
|
||||||
|
# of conflicting statements and missing details and the implementation has
|
||||||
|
# vendor specific workarounds for those and as such, may not interoperate with
|
||||||
|
# any other implementation. This should not be used for anything else than
|
||||||
|
# experimentation and interoperability testing until those issues has been
|
||||||
|
# resolved.
|
||||||
|
#CONFIG_EAP_TEAP=y
|
||||||
|
|
||||||
|
# Wi-Fi Protected Setup (WPS)
|
||||||
|
CONFIG_WPS=y
|
||||||
|
# Enable UPnP support for external WPS Registrars
|
||||||
|
#CONFIG_WPS_UPNP=y
|
||||||
|
# Enable WPS support with NFC config method
|
||||||
|
#CONFIG_WPS_NFC=y
|
||||||
|
|
||||||
|
# EAP-IKEv2
|
||||||
|
#CONFIG_EAP_IKEV2=y
|
||||||
|
|
||||||
|
# Trusted Network Connect (EAP-TNC)
|
||||||
|
#CONFIG_EAP_TNC=y
|
||||||
|
|
||||||
|
# EAP-EKE for the integrated EAP server
|
||||||
|
#CONFIG_EAP_EKE=y
|
||||||
|
|
||||||
|
# PKCS#12 (PFX) support (used to read private key and certificate file from
|
||||||
|
# a file that usually has extension .p12 or .pfx)
|
||||||
|
CONFIG_PKCS12=y
|
||||||
|
|
||||||
|
# RADIUS authentication server. This provides access to the integrated EAP
|
||||||
|
# server from external hosts using RADIUS.
|
||||||
|
#CONFIG_RADIUS_SERVER=y
|
||||||
|
|
||||||
|
# Build IPv6 support for RADIUS operations
|
||||||
|
CONFIG_IPV6=y
|
||||||
|
|
||||||
|
# IEEE Std 802.11r-2008 (Fast BSS Transition)
|
||||||
|
CONFIG_IEEE80211R=y
|
||||||
|
|
||||||
|
# Use the hostapd's IEEE 802.11 authentication (ACL), but without
|
||||||
|
# the IEEE 802.11 Management capability (e.g., FreeBSD/net80211)
|
||||||
|
#CONFIG_DRIVER_RADIUS_ACL=y
|
||||||
|
|
||||||
|
# IEEE 802.11n (High Throughput) support
|
||||||
|
CONFIG_IEEE80211N=y
|
||||||
|
|
||||||
|
# Wireless Network Management (IEEE Std 802.11v-2011)
|
||||||
|
# Note: This is experimental and not complete implementation.
|
||||||
|
CONFIG_WNM=y
|
||||||
|
|
||||||
|
# IEEE 802.11ac (Very High Throughput) support
|
||||||
|
CONFIG_IEEE80211AC=y
|
||||||
|
|
||||||
|
# IEEE 802.11ax HE support
|
||||||
|
# Note: This is experimental and work in progress. The definitions are still
|
||||||
|
# subject to change and this should not be expected to interoperate with the
|
||||||
|
# final IEEE 802.11ax version.
|
||||||
|
CONFIG_IEEE80211AX=y
|
||||||
|
|
||||||
|
# Remove debugging code that is printing out debug messages to stdout.
|
||||||
|
# This can be used to reduce the size of the hostapd considerably if debugging
|
||||||
|
# code is not needed.
|
||||||
|
#CONFIG_NO_STDOUT_DEBUG=y
|
||||||
|
|
||||||
|
# Add support for writing debug log to a file: -f /tmp/hostapd.log
|
||||||
|
# Disabled by default.
|
||||||
|
#CONFIG_DEBUG_FILE=y
|
||||||
|
|
||||||
|
# Send debug messages to syslog instead of stdout
|
||||||
|
CONFIG_DEBUG_SYSLOG=y
|
||||||
|
|
||||||
|
# Add support for sending all debug messages (regardless of debug verbosity)
|
||||||
|
# to the Linux kernel tracing facility. This helps debug the entire stack by
|
||||||
|
# making it easy to record everything happening from the driver up into the
|
||||||
|
# same file, e.g., using trace-cmd.
|
||||||
|
#CONFIG_DEBUG_LINUX_TRACING=y
|
||||||
|
|
||||||
|
# Remove support for RADIUS accounting
|
||||||
|
#CONFIG_NO_ACCOUNTING=y
|
||||||
|
|
||||||
|
# Remove support for RADIUS
|
||||||
|
#CONFIG_NO_RADIUS=y
|
||||||
|
|
||||||
|
# Remove support for VLANs
|
||||||
|
#CONFIG_NO_VLAN=y
|
||||||
|
|
||||||
|
# Enable support for fully dynamic VLANs. This enables hostapd to
|
||||||
|
# automatically create bridge and VLAN interfaces if necessary.
|
||||||
|
CONFIG_FULL_DYNAMIC_VLAN=y
|
||||||
|
|
||||||
|
# Use netlink-based kernel API for VLAN operations instead of ioctl()
|
||||||
|
# Note: This requires libnl 3.1 or newer.
|
||||||
|
#CONFIG_VLAN_NETLINK=y
|
||||||
|
|
||||||
|
# Remove support for dumping internal state through control interface commands
|
||||||
|
# This can be used to reduce binary size at the cost of disabling a debugging
|
||||||
|
# option.
|
||||||
|
CONFIG_NO_DUMP_STATE=y
|
||||||
|
|
||||||
|
# Enable tracing code for developer debugging
|
||||||
|
# This tracks use of memory allocations and other registrations and reports
|
||||||
|
# incorrect use with a backtrace of call (or allocation) location.
|
||||||
|
#CONFIG_WPA_TRACE=y
|
||||||
|
# For BSD, comment out these.
|
||||||
|
#LIBS += -lexecinfo
|
||||||
|
#LIBS_p += -lexecinfo
|
||||||
|
#LIBS_c += -lexecinfo
|
||||||
|
|
||||||
|
# Use libbfd to get more details for developer debugging
|
||||||
|
# This enables use of libbfd to get more detailed symbols for the backtraces
|
||||||
|
# generated by CONFIG_WPA_TRACE=y.
|
||||||
|
#CONFIG_WPA_TRACE_BFD=y
|
||||||
|
# For BSD, comment out these.
|
||||||
|
#LIBS += -lbfd -liberty -lz
|
||||||
|
#LIBS_p += -lbfd -liberty -lz
|
||||||
|
#LIBS_c += -lbfd -liberty -lz
|
||||||
|
|
||||||
|
# hostapd depends on strong random number generation being available from the
|
||||||
|
# operating system. os_get_random() function is used to fetch random data when
|
||||||
|
# needed, e.g., for key generation. On Linux and BSD systems, this works by
|
||||||
|
# reading /dev/urandom. It should be noted that the OS entropy pool needs to be
|
||||||
|
# properly initialized before hostapd is started. This is important especially
|
||||||
|
# on embedded devices that do not have a hardware random number generator and
|
||||||
|
# may by default start up with minimal entropy available for random number
|
||||||
|
# generation.
|
||||||
|
#
|
||||||
|
# As a safety net, hostapd is by default trying to internally collect
|
||||||
|
# additional entropy for generating random data to mix in with the data
|
||||||
|
# fetched from the OS. This by itself is not considered to be very strong, but
|
||||||
|
# it may help in cases where the system pool is not initialized properly.
|
||||||
|
# However, it is very strongly recommended that the system pool is initialized
|
||||||
|
# with enough entropy either by using hardware assisted random number
|
||||||
|
# generator or by storing state over device reboots.
|
||||||
|
#
|
||||||
|
# hostapd can be configured to maintain its own entropy store over restarts to
|
||||||
|
# enhance random number generation. This is not perfect, but it is much more
|
||||||
|
# secure than using the same sequence of random numbers after every reboot.
|
||||||
|
# This can be enabled with -e<entropy file> command line option. The specified
|
||||||
|
# file needs to be readable and writable by hostapd.
|
||||||
|
#
|
||||||
|
# If the os_get_random() is known to provide strong random data (e.g., on
|
||||||
|
# Linux/BSD, the board in question is known to have reliable source of random
|
||||||
|
# data from /dev/urandom), the internal hostapd random pool can be disabled.
|
||||||
|
# This will save some in binary size and CPU use. However, this should only be
|
||||||
|
# considered for builds that are known to be used on devices that meet the
|
||||||
|
# requirements described above.
|
||||||
|
CONFIG_NO_RANDOM_POOL=y
|
||||||
|
|
||||||
|
# Should we attempt to use the getrandom(2) call that provides more reliable
|
||||||
|
# yet secure randomness source than /dev/random on Linux 3.17 and newer.
|
||||||
|
# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
|
||||||
|
CONFIG_GETRANDOM=y
|
||||||
|
|
||||||
|
# Should we use poll instead of select? Select is used by default.
|
||||||
|
#CONFIG_ELOOP_POLL=y
|
||||||
|
|
||||||
|
# Should we use epoll instead of select? Select is used by default.
|
||||||
|
CONFIG_ELOOP_EPOLL=y
|
||||||
|
|
||||||
|
# Should we use kqueue instead of select? Select is used by default.
|
||||||
|
#CONFIG_ELOOP_KQUEUE=y
|
||||||
|
|
||||||
|
# Select TLS implementation
|
||||||
|
# openssl = OpenSSL (default)
|
||||||
|
# gnutls = GnuTLS
|
||||||
|
# internal = Internal TLSv1 implementation (experimental)
|
||||||
|
# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental)
|
||||||
|
# none = Empty template
|
||||||
|
CONFIG_TLS=openssl
|
||||||
|
|
||||||
|
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1)
|
||||||
|
# can be enabled to get a stronger construction of messages when block ciphers
|
||||||
|
# are used.
|
||||||
|
#CONFIG_TLSV11=y
|
||||||
|
|
||||||
|
# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2)
|
||||||
|
# can be enabled to enable use of stronger crypto algorithms.
|
||||||
|
#CONFIG_TLSV12=y
|
||||||
|
|
||||||
|
# Select which ciphers to use by default with OpenSSL if the user does not
|
||||||
|
# specify them.
|
||||||
|
#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW"
|
||||||
|
|
||||||
|
# If CONFIG_TLS=internal is used, additional library and include paths are
|
||||||
|
# needed for LibTomMath. Alternatively, an integrated, minimal version of
|
||||||
|
# LibTomMath can be used. See beginning of libtommath.c for details on benefits
|
||||||
|
# and drawbacks of this option.
|
||||||
|
CONFIG_INTERNAL_LIBTOMMATH=y
|
||||||
|
#ifndef CONFIG_INTERNAL_LIBTOMMATH
|
||||||
|
#LTM_PATH=/usr/src/libtommath-0.39
|
||||||
|
#CFLAGS += -I$(LTM_PATH)
|
||||||
|
#LIBS += -L$(LTM_PATH)
|
||||||
|
#LIBS_p += -L$(LTM_PATH)
|
||||||
|
#endif
|
||||||
|
# At the cost of about 4 kB of additional binary size, the internal LibTomMath
|
||||||
|
# can be configured to include faster routines for exptmod, sqr, and div to
|
||||||
|
# speed up DH and RSA calculation considerably
|
||||||
|
#CONFIG_INTERNAL_LIBTOMMATH_FAST=y
|
||||||
|
|
||||||
|
# Interworking (IEEE 802.11u)
|
||||||
|
# This can be used to enable functionality to improve interworking with
|
||||||
|
# external networks.
|
||||||
|
CONFIG_INTERWORKING=y
|
||||||
|
|
||||||
|
# Hotspot 2.0
|
||||||
|
#CONFIG_HS20=y
|
||||||
|
|
||||||
|
# Enable SQLite database support in hlr_auc_gw, EAP-SIM DB, and eap_user_file
|
||||||
|
#CONFIG_SQLITE=y
|
||||||
|
|
||||||
|
# Enable Fast Session Transfer (FST)
|
||||||
|
#CONFIG_FST=y
|
||||||
|
|
||||||
|
# Enable CLI commands for FST testing
|
||||||
|
#CONFIG_FST_TEST=y
|
||||||
|
|
||||||
|
# Testing options
|
||||||
|
# This can be used to enable some testing options (see also the example
|
||||||
|
# configuration file) that are really useful only for testing clients that
|
||||||
|
# connect to this hostapd. These options allow, for example, to drop a
|
||||||
|
# certain percentage of probe requests or auth/(re)assoc frames.
|
||||||
|
#
|
||||||
|
#CONFIG_TESTING_OPTIONS=y
|
||||||
|
|
||||||
|
# Automatic Channel Selection
|
||||||
|
# This will allow hostapd to pick the channel automatically when channel is set
|
||||||
|
# to "acs_survey" or "0". Eventually, other ACS algorithms can be added in
|
||||||
|
# similar way.
|
||||||
|
#
|
||||||
|
# Automatic selection is currently only done through initialization, later on
|
||||||
|
# we hope to do background checks to keep us moving to more ideal channels as
|
||||||
|
# time goes by. ACS is currently only supported through the nl80211 driver and
|
||||||
|
# your driver must have survey dump capability that is filled by the driver
|
||||||
|
# during scanning.
|
||||||
|
#
|
||||||
|
# You can customize the ACS survey algorithm with the hostapd.conf variable
|
||||||
|
# acs_num_scans.
|
||||||
|
#
|
||||||
|
# Supported ACS drivers:
|
||||||
|
# * ath9k
|
||||||
|
# * ath5k
|
||||||
|
# * ath10k
|
||||||
|
#
|
||||||
|
# For more details refer to:
|
||||||
|
# http://wireless.kernel.org/en/users/Documentation/acs
|
||||||
|
#
|
||||||
|
#CONFIG_ACS=y
|
||||||
|
|
||||||
|
# Multiband Operation support
|
||||||
|
# These extentions facilitate efficient use of multiple frequency bands
|
||||||
|
# available to the AP and the devices that may associate with it.
|
||||||
|
#CONFIG_MBO=y
|
||||||
|
|
||||||
|
# Client Taxonomy
|
||||||
|
# Has the AP retain the Probe Request and (Re)Association Request frames from
|
||||||
|
# a client, from which a signature can be produced which can identify the model
|
||||||
|
# of client device like "Nexus 6P" or "iPhone 5s".
|
||||||
|
CONFIG_TAXONOMY=y
|
||||||
|
|
||||||
|
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
|
||||||
|
#CONFIG_FILS=y
|
||||||
|
# FILS shared key authentication with PFS
|
||||||
|
#CONFIG_FILS_SK_PFS=y
|
||||||
|
|
||||||
|
# Include internal line edit mode in hostapd_cli. This can be used to provide
|
||||||
|
# limited command line editing and history support.
|
||||||
|
#CONFIG_WPA_CLI_EDIT=y
|
||||||
|
|
||||||
|
# Opportunistic Wireless Encryption (OWE)
|
||||||
|
# Experimental implementation of draft-harkins-owe-07.txt
|
||||||
|
#CONFIG_OWE=y
|
||||||
|
|
||||||
|
# Airtime policy support
|
||||||
|
CONFIG_AIRTIME_POLICY=y
|
||||||
|
|
||||||
|
# Proxy ARP support
|
||||||
|
CONFIG_PROXYARP=y
|
||||||
|
|
||||||
|
# Override default value for the wpa_disable_eapol_key_retries configuration
|
||||||
|
# parameter. See that parameter in hostapd.conf for more details.
|
||||||
|
#CFLAGS += -DDEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES=1
|
||||||
|
|
||||||
|
# uBus IPC/RPC System
|
||||||
|
# Services can connect to the bus and provide methods
|
||||||
|
# that can be called by other services or clients.
|
||||||
|
CONFIG_UBUS=y
|
||||||
|
|
||||||
|
# OpenWrt patch 380-disable-ctrl-iface-mib.patch
|
||||||
|
# leads to the MIB only being compiled in if
|
||||||
|
# CONFIG_CTRL_IFACE_MIB is enabled.
|
||||||
|
CONFIG_CTRL_IFACE_MIB=y
|
||||||
|
'';
|
||||||
|
|
||||||
|
patches = singleton config'.flake.patches.hostapd.intel_lar-and-noscan;
|
||||||
|
|
||||||
|
prePatch = ''
|
||||||
|
patchFolder="${openwrtRepo}/package/network/services/hostapd/patches"
|
||||||
|
for file in $(ls $patchFolder) ; do
|
||||||
|
if [ $file != "300-noscan.patch" ] ; then
|
||||||
|
patches+=" $patchFolder/$file"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
|
||||||
|
postPatch = ''
|
||||||
|
cp -RT ${openwrtRepo}/package/network/services/hostapd/src .
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
32
nixos/systems/blowhole/ical2org.nix
Normal file
32
nixos/systems/blowhole/ical2org.nix
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{ pkgs, secret, ... }:
|
||||||
|
{
|
||||||
|
systemd.services.ical-vu-sync = {
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
path = with pkgs; [
|
||||||
|
bash
|
||||||
|
ical2orgpy
|
||||||
|
curl
|
||||||
|
];
|
||||||
|
script = ''
|
||||||
|
rm "${secret.ical2org.orgPath or ""}"
|
||||||
|
cat <<EOF > "${secret.ical2org.orgPath or ""}"
|
||||||
|
:PROPERTIES:
|
||||||
|
:ID: 56ed0bf0-c6d0-4a86-980a-905ccab89345
|
||||||
|
:END:
|
||||||
|
#+title: VU Calendar
|
||||||
|
#+filetags: :project-forced:
|
||||||
|
EOF
|
||||||
|
curl '${secret.ical2org.icalUrlRooster or ""}' -o - | ical2orgpy - - >> "${secret.ical2org.orgPath or ""}"
|
||||||
|
curl '${secret.ical2org.icalUrlCanvas or ""}' -o - | CANVAS_TODO=1 ical2orgpy - - >> "${secret.ical2org.orgPath or ""}"
|
||||||
|
chown 404:404 "${secret.ical2org.orgPath or ""}"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
# systemd.timers.ical-vu-sync = {
|
||||||
|
# wantedBy = [ "timers.target" ];
|
||||||
|
# partOf = [ "ical-vu-sync.service" ];
|
||||||
|
# timerConfig = {
|
||||||
|
# OnCalendar = "*-*-* 3:00:00";
|
||||||
|
# Unit = "ical-vu-sync.service";
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
}
|
534
nixos/systems/blowhole/klipper.nix
Normal file
534
nixos/systems/blowhole/klipper.nix
Normal file
|
@ -0,0 +1,534 @@
|
||||||
|
{ inputs, lib, pkgs, secret, config, config', ...}:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
concatStringsSep
|
||||||
|
singleton
|
||||||
|
concatMapStringsSep
|
||||||
|
splitString;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
uterranix.config = { tflib, ... }:
|
||||||
|
let
|
||||||
|
inherit (tflib)
|
||||||
|
tf;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
output."envoy_klipper".value = tf "vault_consul_secret_backend_role.envoy-klipper";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.hashicorp.vault-agent =
|
||||||
|
{
|
||||||
|
settings.template = [
|
||||||
|
{
|
||||||
|
source = pkgs.writeText "envoy-klipper.token.vtmpl" ''
|
||||||
|
{{ with secret "consul/creds/envoy-klipper" }}{{ .Data.token }}{{ end }}
|
||||||
|
'';
|
||||||
|
destination = "/run/secrets/klipper/envoy-klipper.token";
|
||||||
|
command =
|
||||||
|
let
|
||||||
|
serviceList =
|
||||||
|
[ "hashicorp-envoy-mainsail" ];
|
||||||
|
in
|
||||||
|
pkgs.writeShellScript "envoy-mainsail-reload.sh"
|
||||||
|
''
|
||||||
|
sudo systemd-run -P --machine klipper /run/current-system/sw/bin/bash -l -c \
|
||||||
|
'systemctl try-reload-or-restart ${concatStringsSep " " serviceList}'
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/var/lib/klipper" = {
|
||||||
|
device = "blowhole-zpool/persist/klipper";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services."container@klipper" = {
|
||||||
|
restartIfChanged = lib.mkForce false;
|
||||||
|
};
|
||||||
|
|
||||||
|
containers.klipper = {
|
||||||
|
ephemeral = true;
|
||||||
|
autoStart = true;
|
||||||
|
privateNetwork = true;
|
||||||
|
|
||||||
|
localAddress = "10.64.99.6";
|
||||||
|
hostAddress = "10.64.99.5";
|
||||||
|
|
||||||
|
bindMounts = {
|
||||||
|
"/run/secrets" = {
|
||||||
|
hostPath = "/run/secrets/klipper";
|
||||||
|
isReadOnly = true;
|
||||||
|
};
|
||||||
|
"/var/lib/klipper" = {
|
||||||
|
hostPath = "/var/lib/klipper";
|
||||||
|
isReadOnly = false;
|
||||||
|
};
|
||||||
|
"/var/lib/moonraker/gcodes" = {
|
||||||
|
hostPath = "/var/lib/klipper/gcodes";
|
||||||
|
isReadOnly = false;
|
||||||
|
};
|
||||||
|
"/dev/serial/by-id/" = {
|
||||||
|
hostPath = "/dev/serial/by-id/";
|
||||||
|
isReadOnly = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
allowedDevices = singleton {
|
||||||
|
node = "/dev/serial/by-id/usb-Klipper_lpc1768_13E0FF0C469027AEBAA84A52871E00F5-if00";
|
||||||
|
modifier = "rwm";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
nixpkgs.overlays = config.nixpkgs.overlays;
|
||||||
|
|
||||||
|
imports = with config'.flake.nixosModules; [
|
||||||
|
hashicorp
|
||||||
|
hashicorp-envoy
|
||||||
|
];
|
||||||
|
|
||||||
|
services.hashicorp-envoy.mainsail = {
|
||||||
|
service = {
|
||||||
|
name = "mainsail";
|
||||||
|
id = "mainsail";
|
||||||
|
address = "10.64.99.6";
|
||||||
|
port = 80;
|
||||||
|
|
||||||
|
connect.sidecar_service = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
"CONSUL_HTTP_ADDR" = "http://${secret.network.ips.blowhole.ip or ""}:8500";
|
||||||
|
"CONSUL_GRPC_ADDR" = "http://${secret.network.ips.blowhole.ip or ""}:8502";
|
||||||
|
"CONSUL_HTTP_TOKEN_FILE" = "/run/secrets/envoy-klipper.token";
|
||||||
|
};
|
||||||
|
|
||||||
|
address = "10.64.99.6:19000";
|
||||||
|
adminBind = "127.0.0.1:19100";
|
||||||
|
hotRestart = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.klipper = {
|
||||||
|
home = "/var/lib/klipper";
|
||||||
|
isSystemUser = true;
|
||||||
|
group = "klipper";
|
||||||
|
uid = 321;
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups.klipper = {
|
||||||
|
gid = 321;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.klipper = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
user = "klipper";
|
||||||
|
group = "klipper";
|
||||||
|
|
||||||
|
package = pkgs.klipper;
|
||||||
|
|
||||||
|
settings =
|
||||||
|
let
|
||||||
|
indentGcode = gcode:
|
||||||
|
"\n" + (concatMapStringsSep "\n" (x: " " + x) (splitString "\n" gcode));
|
||||||
|
in
|
||||||
|
{
|
||||||
|
stepper_x = {
|
||||||
|
step_pin = "P2.2";
|
||||||
|
dir_pin = "!P2.6";
|
||||||
|
enable_pin = "!P2.1";
|
||||||
|
rotation_distance = "40";
|
||||||
|
microsteps = "16";
|
||||||
|
endstop_pin = "P1.29"; # P1.28 for X-max
|
||||||
|
position_endstop = "0";
|
||||||
|
position_max = "235";
|
||||||
|
homing_speed = "50";
|
||||||
|
};
|
||||||
|
|
||||||
|
stepper_y = {
|
||||||
|
step_pin = "P0.19";
|
||||||
|
dir_pin = "!P0.20";
|
||||||
|
enable_pin = "!P2.8";
|
||||||
|
rotation_distance = "40";
|
||||||
|
microsteps = "16";
|
||||||
|
endstop_pin = "P1.27"; # P1.26 for Y-max
|
||||||
|
position_endstop = "0";
|
||||||
|
position_max = "235";
|
||||||
|
homing_speed = "50";
|
||||||
|
};
|
||||||
|
|
||||||
|
stepper_z = {
|
||||||
|
step_pin = "P0.22";
|
||||||
|
dir_pin = "P2.11";
|
||||||
|
enable_pin = "!P0.21";
|
||||||
|
rotation_distance = "8";
|
||||||
|
microsteps = "16";
|
||||||
|
endstop_pin = "P1.25"; # P1.24 for Z-max"
|
||||||
|
position_min = "-4.5";
|
||||||
|
position_endstop = "1.290";
|
||||||
|
position_max = "250";
|
||||||
|
};
|
||||||
|
|
||||||
|
extruder = {
|
||||||
|
step_pin = "P2.13";
|
||||||
|
dir_pin = "!P0.11";
|
||||||
|
enable_pin = "!P2.12";
|
||||||
|
rotation_distance = "23.291";
|
||||||
|
gear_ratio = "3:1";
|
||||||
|
microsteps = "16";
|
||||||
|
nozzle_diameter = "0.400";
|
||||||
|
filament_diameter = "1.750";
|
||||||
|
heater_pin = "P2.7";
|
||||||
|
sensor_type = "PT1000";
|
||||||
|
sensor_pin = "P0.24";
|
||||||
|
control = "pid";
|
||||||
|
pid_Kp = "22.2";
|
||||||
|
pid_Ki = "1.08";
|
||||||
|
pid_Kd = "114";
|
||||||
|
min_temp = "0";
|
||||||
|
max_temp = "260";
|
||||||
|
pressure_advance = "0.92";
|
||||||
|
};
|
||||||
|
|
||||||
|
bed_screws = {
|
||||||
|
screw1 = "30,35";
|
||||||
|
screw2 = "200,35";
|
||||||
|
screw3 = "200,205";
|
||||||
|
screw4 = "30,205";
|
||||||
|
};
|
||||||
|
|
||||||
|
"heater_fan my_nozzle_fan" = {
|
||||||
|
pin = "P2.4";
|
||||||
|
heater = "extruder";
|
||||||
|
heater_temp = "50.0";
|
||||||
|
fan_speed = "1.0";
|
||||||
|
};
|
||||||
|
|
||||||
|
heater_bed = {
|
||||||
|
heater_pin = "P2.5";
|
||||||
|
sensor_type = "ATC Semitec 104GT-2";
|
||||||
|
sensor_pin = "P0.23";
|
||||||
|
control = "watermark";
|
||||||
|
min_temp = "0";
|
||||||
|
max_temp = "80";
|
||||||
|
};
|
||||||
|
|
||||||
|
fan = {
|
||||||
|
pin = "P2.3";
|
||||||
|
};
|
||||||
|
|
||||||
|
mcu = {
|
||||||
|
serial = "/dev/serial/by-id/usb-Klipper_lpc1768_13E0FF0C469027AEBAA84A52871E00F5-if00";
|
||||||
|
};
|
||||||
|
|
||||||
|
printer = {
|
||||||
|
kinematics = "cartesian";
|
||||||
|
max_velocity = "200";
|
||||||
|
max_accel = "2000";
|
||||||
|
max_z_velocity = "25";
|
||||||
|
max_z_accel = "100";
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual_sdcard = {
|
||||||
|
path = "/var/lib/moonraker/gcodes";
|
||||||
|
};
|
||||||
|
|
||||||
|
### Mainsail
|
||||||
|
pause_resume = {};
|
||||||
|
display_status = {};
|
||||||
|
endstop_phase = {};
|
||||||
|
|
||||||
|
"tmc2208 stepper_x" = {
|
||||||
|
uart_pin = "P1.17";
|
||||||
|
run_current = "0.475";
|
||||||
|
hold_current = "0.275";
|
||||||
|
stealthchop_threshold = "250";
|
||||||
|
};
|
||||||
|
|
||||||
|
"tmc2208 stepper_y" = {
|
||||||
|
uart_pin = "P1.15";
|
||||||
|
run_current = "0.475";
|
||||||
|
hold_current = "0.275";
|
||||||
|
stealthchop_threshold = "250";
|
||||||
|
};
|
||||||
|
|
||||||
|
"tmc2208 stepper_z" = {
|
||||||
|
uart_pin = "P1.10";
|
||||||
|
run_current = "0.475";
|
||||||
|
hold_current = "0.275";
|
||||||
|
stealthchop_threshold = "30";
|
||||||
|
};
|
||||||
|
|
||||||
|
"tmc2208 extruder" = {
|
||||||
|
uart_pin = "P1.8";
|
||||||
|
run_current = "0.560";
|
||||||
|
hold_current = "0.360";
|
||||||
|
stealthchop_threshold = "5";
|
||||||
|
};
|
||||||
|
|
||||||
|
board_pins = {
|
||||||
|
aliases =
|
||||||
|
indentGcode
|
||||||
|
''
|
||||||
|
# EXP1 header
|
||||||
|
EXP1_1=P1.30, EXP1_3=P1.18, EXP1_5=P1.20, EXP1_7=P1.22, EXP1_9=<GND>,
|
||||||
|
EXP1_2=P0.28, EXP1_4=P1.19, EXP1_6=P1.21, EXP1_8=P1.23, EXP1_10=<5V>,
|
||||||
|
# EXP2 header
|
||||||
|
EXP2_1=P0.17, EXP2_3=P3.26, EXP2_5=P3.25, EXP2_7=P1.31, EXP2_9=<GND>,
|
||||||
|
EXP2_2=P0.15, EXP2_4=P0.16, EXP2_6=P0.18, EXP2_8=<RST>, EXP2_10=<NC>
|
||||||
|
# Pins EXP2_1, EXP2_6, EXP2_2 are also MISO, MOSI, SCK of bus "ssp0"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
display = {
|
||||||
|
lcd_type = "st7920";
|
||||||
|
cs_pin = "EXP1_7";
|
||||||
|
sclk_pin = "EXP1_6";
|
||||||
|
sid_pin = "EXP1_8";
|
||||||
|
encoder_pins = "^EXP1_5, ^EXP1_3";
|
||||||
|
click_pin = "^!EXP1_2";
|
||||||
|
};
|
||||||
|
|
||||||
|
# "endstop_phase stepper_z" =
|
||||||
|
# { endstop_phase = "29";
|
||||||
|
# };
|
||||||
|
|
||||||
|
# "endstop_phase stepper_y" =
|
||||||
|
# { endstop_phase = "57";
|
||||||
|
# };
|
||||||
|
|
||||||
|
# "endstop_phase stepper_x" =
|
||||||
|
# { endstop_phase = "3";
|
||||||
|
# };
|
||||||
|
|
||||||
|
"gcode_macro M600" = {
|
||||||
|
gcode =
|
||||||
|
indentGcode
|
||||||
|
''
|
||||||
|
{% set x = params.X|default(50)|float %}
|
||||||
|
{% set y = params.Y|default(0)|float %}
|
||||||
|
{% set z = params.Z|default(10)|float %}
|
||||||
|
SAVE_GCODE_STATE NAME=M600_state
|
||||||
|
PAUSE
|
||||||
|
G91
|
||||||
|
G1 E-.8 F2700
|
||||||
|
G1 Z{z}
|
||||||
|
G90
|
||||||
|
G1 X{x} Y{y} F3000
|
||||||
|
G91
|
||||||
|
G1 E-50 F1000
|
||||||
|
G1 X0.1 F3000
|
||||||
|
G1 E-50 F1000
|
||||||
|
G1 X-0.1 F3000
|
||||||
|
G1 E-50 F1000
|
||||||
|
G1 X0.1 F3000
|
||||||
|
G1 E-50 F1000
|
||||||
|
G1 X-0.1 F3000
|
||||||
|
G1 E-50 F1000
|
||||||
|
G1 X0.1 F3000
|
||||||
|
G1 E-50 F1000
|
||||||
|
G1 X-0.1 F3000
|
||||||
|
RESTORE_GCODE_STATE NAME=M600_state
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"gcode_macro CANCEL_PRINT" = {
|
||||||
|
rename_existing = "BASE_CANCEL_PRINT";
|
||||||
|
gcode =
|
||||||
|
indentGcode
|
||||||
|
''
|
||||||
|
TURN_OFF_HEATERS
|
||||||
|
CLEAR_PAUSE
|
||||||
|
SDCARD_RESET_FILE
|
||||||
|
BASE_CANCEL_PRINT
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"gcode_macro PARK_WAIT" = {
|
||||||
|
gcode =
|
||||||
|
indentGcode
|
||||||
|
''
|
||||||
|
{% set x = params.X|default(0)|float %}
|
||||||
|
{% set y = params.Y|default(230)|float %}
|
||||||
|
{% set z = params.Z|default(10)|float %}
|
||||||
|
{% set e = params.Z|default(20)|float %}
|
||||||
|
{% set millis = params.MILLIS|default(5)|float %}
|
||||||
|
|
||||||
|
SAVE_GCODE_STATE NAME=PAUSE_state
|
||||||
|
G91
|
||||||
|
G1 E-{e} F2100
|
||||||
|
G1 Z{z}
|
||||||
|
G90
|
||||||
|
G1 X{x} Y{y} F6000
|
||||||
|
|
||||||
|
G4 P{millis}
|
||||||
|
|
||||||
|
G91
|
||||||
|
G1 E{e} F2100
|
||||||
|
G90
|
||||||
|
RESTORE_GCODE_STATE NAME=PAUSE_state MOVE=1
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"gcode_macro PAUSE" = {
|
||||||
|
rename_existing = "BASE_PAUSE";
|
||||||
|
gcode =
|
||||||
|
indentGcode
|
||||||
|
''
|
||||||
|
{% set x = params.X|default(0)|float %}
|
||||||
|
{% set y = params.Y|default(230)|float %}
|
||||||
|
{% set z = params.Z|default(10)|float %}
|
||||||
|
{% set e = params.E|default(20)|float %}
|
||||||
|
|
||||||
|
SAVE_GCODE_STATE NAME=PAUSE_state
|
||||||
|
BASE_PAUSE
|
||||||
|
G91
|
||||||
|
G1 E-{e} F2100
|
||||||
|
G1 Z{z}
|
||||||
|
G90
|
||||||
|
G1 X{x} Y{y} F6000
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"gcode_macro RESUME" = {
|
||||||
|
rename_existing = "BASE_RESUME";
|
||||||
|
gcode =
|
||||||
|
indentGcode
|
||||||
|
''
|
||||||
|
{% set e = params.Z|default(20)|float %}
|
||||||
|
|
||||||
|
G91
|
||||||
|
G1 E{e} F2100
|
||||||
|
G90
|
||||||
|
RESTORE_GCODE_STATE NAME=PAUSE_state MOVE=1
|
||||||
|
BASE_RESUME
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"gcode_macro PRIME_LINE" = {
|
||||||
|
gcode =
|
||||||
|
indentGcode
|
||||||
|
''
|
||||||
|
G92 E0 # Reset Extruder
|
||||||
|
G1 Z2.0 F3000 # Move Z Axis up little to prevent scratching of Heat Bed
|
||||||
|
G1 X0.1 Y20 Z0.3 F5000.0 # Move to start position
|
||||||
|
G1 X0.1 Y200.0 Z0.3 F1500.0 E15 # Draw the first line
|
||||||
|
G1 X0.4 Y200.0 Z0.3 F5000.0 # Move to side a little
|
||||||
|
G1 X0.4 Y20 Z0.3 F1500.0 E30 # Draw the second line
|
||||||
|
G92 E0 # Reset Extruder
|
||||||
|
G1 Z2.0 F3000 # Move Z Axis up little to prevent scratching of Heat Bed
|
||||||
|
G1 X5 Y20 Z0.3 F5000.0 # Move over to prevent blob squish
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"gcode_macro START_PRINT" = {
|
||||||
|
gcode =
|
||||||
|
indentGcode
|
||||||
|
''
|
||||||
|
{% set z = params.Z|default(0)|float %}
|
||||||
|
|
||||||
|
# Use absolute coordinates
|
||||||
|
G90
|
||||||
|
# Reset the G-Code Z offset (adjust Z offset if needed)
|
||||||
|
SET_GCODE_OFFSET Z={z}
|
||||||
|
# Home the printer
|
||||||
|
G28
|
||||||
|
# Prime line
|
||||||
|
G0 Z0
|
||||||
|
PRIME_LINE
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"gcode_macro END_PRINT" = {
|
||||||
|
gcode =
|
||||||
|
indentGcode
|
||||||
|
''
|
||||||
|
G91 # Relative positioning
|
||||||
|
G1 E-2 F2700 # Retract a bit
|
||||||
|
G1 E-2 Z0.2 F2400 # Retract and raise Z
|
||||||
|
G1 X5 Y5 F3000 # Wipe out
|
||||||
|
G1 Z10 #Raise Z more
|
||||||
|
G90 # Absolute positionning
|
||||||
|
|
||||||
|
G1 X0 Y200 # Present print
|
||||||
|
M106 S0 # Turn-off fan
|
||||||
|
M104 S0 # Turn-off hotend
|
||||||
|
M140 S0 # Turn-off bed
|
||||||
|
|
||||||
|
M84 X Y E # Disable all steppers but Z
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.moonraker = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
group = "klipper";
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
authorization.trusted_clients = [
|
||||||
|
"127.0.0.1"
|
||||||
|
(secret.network.ips.heater or "")
|
||||||
|
(secret.network.ips.edge.vpn or "")
|
||||||
|
(secret.network.ips.omen.vpn or "")
|
||||||
|
];
|
||||||
|
|
||||||
|
octoprint_compat = {};
|
||||||
|
history = {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
recommendedGzipSettings = true;
|
||||||
|
recommendedProxySettings = true;
|
||||||
|
recommendedOptimisation = true;
|
||||||
|
|
||||||
|
upstreams."apiserver" = {
|
||||||
|
servers."127.0.0.1:7125" = {};
|
||||||
|
extraConfig = ''
|
||||||
|
ip_hash;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
virtualHosts.${secret.network.ips.blowhole.dns or ""} = {
|
||||||
|
root = pkgs.mainsail;
|
||||||
|
|
||||||
|
locations."/".extraConfig = ''
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
'';
|
||||||
|
|
||||||
|
locations."/index.html".extraConfig = ''
|
||||||
|
add_header Cache-Control "no-store, no-cache, must-revalidate";
|
||||||
|
'';
|
||||||
|
|
||||||
|
locations."/websocket".extraConfig = ''
|
||||||
|
proxy_pass http://apiserver/websocket;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_read_timeout 86400;
|
||||||
|
'';
|
||||||
|
|
||||||
|
|
||||||
|
locations."~ ^/(printer|api|access|machine|server)/".extraConfig = ''
|
||||||
|
proxy_pass http://apiserver$request_uri;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Scheme $scheme;
|
||||||
|
'';
|
||||||
|
|
||||||
|
extraConfig = ''
|
||||||
|
client_max_body_size 512M;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
533
nixos/systems/blowhole/monitoring.nix
Normal file
533
nixos/systems/blowhole/monitoring.nix
Normal file
|
@ -0,0 +1,533 @@
|
||||||
|
# SPDX-FileCopyrightText: 2023 Richard Brežák <richard@brezak.sk>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
{ pkgs, roots, lib, inputs', config, secret, config', ... }:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
singleton
|
||||||
|
nixosTests
|
||||||
|
concatStringsSep;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
uterranix.config = { tflib, ... }:
|
||||||
|
let
|
||||||
|
inherit (tflib)
|
||||||
|
tf;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
output."envoy_grafana".value = tf "vault_consul_secret_backend_role.envoy-grafana";
|
||||||
|
output."envoy_blowhole".value = tf "vault_consul_secret_backend_role.envoy-blowhole";
|
||||||
|
|
||||||
|
data."influxdb-v2_organization"."redalder" = {
|
||||||
|
name = "redalder";
|
||||||
|
};
|
||||||
|
|
||||||
|
resource."influxdb-v2_bucket"."metrics_bucket" = {
|
||||||
|
name = "metrics";
|
||||||
|
description = "Metrics bucket";
|
||||||
|
org_id = "\${data.influxdb-v2_organization.redalder.id}";
|
||||||
|
retention_rules = {
|
||||||
|
every_seconds = 30 * 24 * 60 * 60; # days * h/d * m/h * s/m
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
resource."influxdb-v2_bucket"."logs_bucket" = {
|
||||||
|
org_id = "\${data.influxdb-v2_organization.redalder.id}";
|
||||||
|
name = "logs";
|
||||||
|
description = "Logs bucket";
|
||||||
|
retention_rules = {
|
||||||
|
every_seconds = 30 * 24 * 60 * 60; # days * h/d * m/h * s/m
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
resource."influxdb-v2_authorization"."telegraf_authorization" = {
|
||||||
|
org_id = "\${data.influxdb-v2_organization.redalder.id}";
|
||||||
|
description = "Token for telegraf ingestion";
|
||||||
|
status = "active";
|
||||||
|
permissions = [
|
||||||
|
{
|
||||||
|
action = "write";
|
||||||
|
resource = {
|
||||||
|
id = "\${influxdb-v2_bucket.logs_bucket.id}";
|
||||||
|
org_id = "\${data.influxdb-v2_organization.redalder.id}";
|
||||||
|
type = "buckets";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
action = "write";
|
||||||
|
resource = {
|
||||||
|
id = "\${influxdb-v2_bucket.metrics_bucket.id}";
|
||||||
|
org_id = "\${data.influxdb-v2_organization.redalder.id}";
|
||||||
|
type = "buckets";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
resource."influxdb-v2_authorization"."grafana_authorization" = {
|
||||||
|
org_id = "\${data.influxdb-v2_organization.redalder.id}";
|
||||||
|
description = "Token for Grefana";
|
||||||
|
status = "active";
|
||||||
|
permissions = [
|
||||||
|
{
|
||||||
|
action = "read";
|
||||||
|
resource = {
|
||||||
|
id = "\${influxdb-v2_bucket.logs_bucket.id}";
|
||||||
|
org_id = "\${data.influxdb-v2_organization.redalder.id}";
|
||||||
|
type = "buckets";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
action = "read";
|
||||||
|
resource = {
|
||||||
|
id = "\${influxdb-v2_bucket.metrics_bucket.id}";
|
||||||
|
org_id = "\${data.influxdb-v2_organization.redalder.id}";
|
||||||
|
type = "buckets";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
resource."vault_mount"."kv" = {
|
||||||
|
path = "kv";
|
||||||
|
type = "kv";
|
||||||
|
options = { version = 2; };
|
||||||
|
description = "KV Version 2 secret engine mount";
|
||||||
|
};
|
||||||
|
|
||||||
|
resource."vault_kv_secret_v2"."telegraf_secret" = {
|
||||||
|
mount = "\${vault_mount.kv.path}";
|
||||||
|
name = "homelab-1/blowhole/monitor/telegraf";
|
||||||
|
options = { version = 2; };
|
||||||
|
data_json = builtins.toJSON {
|
||||||
|
influxdb_token = "\${influxdb-v2_authorization.telegraf_authorization.token}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
resource."vault_kv_secret_v2"."grafana_secret" = {
|
||||||
|
mount = "\${vault_mount.kv.path}";
|
||||||
|
name = "homelab-1/blowhole/monitor/grafana";
|
||||||
|
options = { version = 2; };
|
||||||
|
data_json = builtins.toJSON {
|
||||||
|
influxdb_token = "\${influxdb-v2_authorization.grafana_authorization.token}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nixpkgs.overlays = singleton (_: _:
|
||||||
|
{
|
||||||
|
telegraf =
|
||||||
|
pkgs.buildGoModule rec {
|
||||||
|
pname = "telegraf";
|
||||||
|
version = "1.25.3";
|
||||||
|
|
||||||
|
excludedPackages = "test";
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
|
subPackages = singleton "cmd/telegraf";
|
||||||
|
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "influxdata";
|
||||||
|
repo = "telegraf";
|
||||||
|
rev = "v${version}";
|
||||||
|
sha256 = "sha256-FUZDS4As9qP2Dn0NSBM/e8udDLMk5OZol4CQSI39T4s=";
|
||||||
|
};
|
||||||
|
|
||||||
|
vendorHash = "sha256-uWoWvS9ZZzhpE+PiJv0fqblMLOAGIrhCdi0ugvF/lQI=";
|
||||||
|
proxyVendor = true;
|
||||||
|
|
||||||
|
ldflags = [
|
||||||
|
"-w" "-s" "-X main.version=${version}"
|
||||||
|
];
|
||||||
|
|
||||||
|
passthru.tests = { inherit (nixosTests) telegraf; };
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "The plugin-driven server agent for collecting & reporting metrics";
|
||||||
|
license = licenses.mit;
|
||||||
|
homepage = "https://www.influxdata.com/time-series-platform/telegraf/";
|
||||||
|
maintainers = with maintainers; [ mic92 roblabla timstott ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
services.hashicorp.vault-agent =
|
||||||
|
{
|
||||||
|
settings.template = [
|
||||||
|
{
|
||||||
|
source = pkgs.writeText "envoy-grafana.token.vtmpl" ''
|
||||||
|
{{ with secret "consul/creds/envoy-grafana" }}{{ .Data.token }}{{ end }}
|
||||||
|
'';
|
||||||
|
destination = "/run/secrets/monitor/envoy-grafana.token";
|
||||||
|
command =
|
||||||
|
let
|
||||||
|
serviceList =
|
||||||
|
[ "hashicorp-envoy-grafana" "hashicorp-envoy-influx" "hashicorp-envoy-telegraf" ];
|
||||||
|
in
|
||||||
|
pkgs.writeShellScript "envoy-grafana-reload.sh" ''
|
||||||
|
sudo systemd-run -P --machine monitor /run/current-system/sw/bin/bash -l -c \
|
||||||
|
'systemctl try-reload-or-restart ${concatStringsSep " " serviceList}'
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
source = pkgs.writeText "envoy-blowhole.token.vtmpl" ''
|
||||||
|
{{ with secret "consul/creds/envoy-blowhole" }}{{ .Data.token }}{{ end }}
|
||||||
|
'';
|
||||||
|
destination = "/run/secrets/envoy-blowhole.token";
|
||||||
|
command = pkgs.writeShellScript "envoy-blowhole-reload.sh" ''
|
||||||
|
sudo systemctl try-reload-or-restart hashicorp-envoy-telegraf
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
source = pkgs.writeText "telegraf.env.vtmpl" ''
|
||||||
|
INFLUXDB_TOKEN={{ with secret "kv/data/homelab-1/blowhole/monitor/telegraf" }}{{ .Data.data.influxdb_token }}{{ end }}
|
||||||
|
'';
|
||||||
|
destination = "/run/secrets/monitor/telegraf.env";
|
||||||
|
command = pkgs.writeShellScript "monitor-telegraf-reload.sh" ''
|
||||||
|
sudo systemd-run -P --machine monitor /run/current-system/sw/bin/bash -l -c \
|
||||||
|
'systemctl try-reload-or-restart telegraf'
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
{
|
||||||
|
source = pkgs.writeText "grafana-influx.token.vtmpl" ''
|
||||||
|
{{ with secret "kv/data/homelab-1/blowhole/monitor/grafana" }}
|
||||||
|
{{ .Data.data.influxdb_token }}
|
||||||
|
{{ end }}
|
||||||
|
'';
|
||||||
|
destination = "/run/secrets/monitor/grafana-influx.token";
|
||||||
|
perms = "0644";
|
||||||
|
command = pkgs.writeShellScript "monitor-telegraf-reload.sh" ''
|
||||||
|
sudo systemd-run -P --machine monitor /run/current-system/sw/bin/bash -l -c \
|
||||||
|
'systemctl try-reload-or-restart grafana'
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
## There is no way to say, hey, listen on localhost. The listeners option is missing the `address` field
|
||||||
|
## and the `name` field so it's impossible to configure....
|
||||||
|
services.hashicorp-envoy.telegraf = {
|
||||||
|
type = "ingress";
|
||||||
|
address = "${secret.network.ips.blowhole.ip or ""}:19000";
|
||||||
|
service = {
|
||||||
|
kind = "ingress-gateway";
|
||||||
|
name = "telegraf-blowhole";
|
||||||
|
|
||||||
|
listeners = singleton {
|
||||||
|
port = 8086;
|
||||||
|
protocol = "tcp";
|
||||||
|
services = singleton {
|
||||||
|
name = "telegraf";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
"CONSUL_HTTP_ADDR" = "http://${secret.network.ips.blowhole.ip or ""}:8500";
|
||||||
|
"CONSUL_GRPC_ADDR" = "http://${secret.network.ips.blowhole.ip or ""}:8502";
|
||||||
|
"CONSUL_HTTP_TOKEN_FILE" = "/run/secrets/envoy-blowhole.token";
|
||||||
|
};
|
||||||
|
|
||||||
|
adminBind = "127.0.0.1:19100";
|
||||||
|
hotRestart = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.telegraf-magic = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
inputs.cpu = {
|
||||||
|
percpu = true;
|
||||||
|
totalcpu = true;
|
||||||
|
tags.host = "blowhole";
|
||||||
|
tags.bucket = "metrics";
|
||||||
|
};
|
||||||
|
|
||||||
|
inputs.mem = {
|
||||||
|
tags.host = "blowhole";
|
||||||
|
tags.bucket = "metrics";
|
||||||
|
};
|
||||||
|
|
||||||
|
inputs.nomad = {
|
||||||
|
url = "http://${secret.network.ips.blowhole.ip or ""}:4646";
|
||||||
|
tags.host = "blowhole";
|
||||||
|
tags.bucket = "metrics";
|
||||||
|
};
|
||||||
|
|
||||||
|
# aggregators.minmax = {
|
||||||
|
# period = "30s";
|
||||||
|
# drop_original = true;
|
||||||
|
# namepass = [ "nomad" ];
|
||||||
|
# };
|
||||||
|
|
||||||
|
inputs.zfs = {
|
||||||
|
tags.host = "blowhole";
|
||||||
|
tags.bucket = "metrics";
|
||||||
|
};
|
||||||
|
|
||||||
|
# inputs.tail = [
|
||||||
|
# {
|
||||||
|
# files = ["/var/lib/nomad/alloc/*/alloc/logs/*.stdout.*"];
|
||||||
|
# data_format = "value";
|
||||||
|
# data_type = "string";
|
||||||
|
|
||||||
|
# name_override = "nomad_alloc_log";
|
||||||
|
# tags.bucket = "logs";
|
||||||
|
# }
|
||||||
|
# {
|
||||||
|
# files = ["/var/lib/nomad/alloc/*/alloc/logs/*.stderr.*"];
|
||||||
|
# data_format = "value";
|
||||||
|
# data_type = "string";
|
||||||
|
|
||||||
|
# name_override = "nomad_alloc_log";
|
||||||
|
# tags.bucket = "logs";
|
||||||
|
# }
|
||||||
|
# ];
|
||||||
|
|
||||||
|
inputs.docker_log = {
|
||||||
|
tags.bucket = "logs";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs.influxdb_v2 = [
|
||||||
|
{
|
||||||
|
urls = singleton "http://${secret.network.ips.blowhole.ip or ""}:8086";
|
||||||
|
bucket = "metrics";
|
||||||
|
tagpass.bucket = singleton "metrics";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
urls = singleton "http://${secret.network.ips.blowhole.ip or ""}:8086";
|
||||||
|
bucket = "logs";
|
||||||
|
tagpass.bucket = singleton "logs";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd = {
|
||||||
|
serviceConfig.SupplementaryGroups = [ "docker" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/var/lib/grafana" = {
|
||||||
|
device = "blowhole-zpool/persist/grafana";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/var/lib/grafana-postgres" = {
|
||||||
|
device = "blowhole-zpool/persist/grafana-postgres";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/var/lib/grafana-influxdb2" = {
|
||||||
|
device = "blowhole-zpool/persist/grafana-influxdb2";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services."container@monitor".serviceConfig.LimitNOFILE = "infinity";
|
||||||
|
|
||||||
|
# TODO: split interface name and container name, i.e. rewrite the container module....... again
|
||||||
|
containers.monitor = {
|
||||||
|
ephemeral = true;
|
||||||
|
autoStart = true;
|
||||||
|
privateNetwork = true;
|
||||||
|
|
||||||
|
localAddress = "10.64.99.2";
|
||||||
|
hostAddress = "10.64.99.1";
|
||||||
|
|
||||||
|
extraFlags = [
|
||||||
|
"--capability=CAP_IPC_LOCK"
|
||||||
|
];
|
||||||
|
|
||||||
|
bindMounts = {
|
||||||
|
"/run/secrets" = {
|
||||||
|
hostPath = "/run/secrets/monitor";
|
||||||
|
isReadOnly = true;
|
||||||
|
};
|
||||||
|
"/var/lib/grafana" = {
|
||||||
|
hostPath = "/var/lib/grafana";
|
||||||
|
isReadOnly = false;
|
||||||
|
};
|
||||||
|
"/var/lib/postgresql" = {
|
||||||
|
hostPath = "/var/lib/grafana-postgres";
|
||||||
|
isReadOnly = false;
|
||||||
|
};
|
||||||
|
"/var/lib/influxdb2" = {
|
||||||
|
hostPath = "/var/lib/grafana-influxdb2";
|
||||||
|
isReadOnly = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
nixpkgs.overlays = config.nixpkgs.overlays;
|
||||||
|
|
||||||
|
imports = with config'.flake.nixosModules; [
|
||||||
|
hashicorp
|
||||||
|
hashicorp-envoy
|
||||||
|
telegraf
|
||||||
|
grafana
|
||||||
|
];
|
||||||
|
|
||||||
|
services.hashicorp-envoy.grafana = {
|
||||||
|
service = {
|
||||||
|
name = "grafana";
|
||||||
|
id = "grafana";
|
||||||
|
address = "10.64.99.2";
|
||||||
|
port = 3000;
|
||||||
|
|
||||||
|
connect.sidecar_service = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
"CONSUL_HTTP_ADDR" = "http://${secret.network.ips.blowhole.ip or ""}:8500";
|
||||||
|
"CONSUL_GRPC_ADDR" = "http://${secret.network.ips.blowhole.ip or ""}:8502";
|
||||||
|
"CONSUL_HTTP_TOKEN_FILE" = "/run/secrets/envoy-grafana.token";
|
||||||
|
};
|
||||||
|
|
||||||
|
address = "10.64.99.2:19000";
|
||||||
|
adminBind = "127.0.0.1:19100";
|
||||||
|
hotRestart = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.postgresql = {
|
||||||
|
enable = true;
|
||||||
|
ensureDatabases = singleton "grafana";
|
||||||
|
ensureUsers = singleton {
|
||||||
|
name = "grafana";
|
||||||
|
ensurePermissions."DATABASE grafana" = "ALL PRIVILEGES";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.grafana = {
|
||||||
|
serviceConfig = {
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = "10s";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.grafana-magic = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
security = {
|
||||||
|
content_security_policy = true;
|
||||||
|
disable_gravatar = true;
|
||||||
|
data_source_proxy_whitelist = concatStringsSep " " [
|
||||||
|
"127.0.0.1:8086"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
server = {
|
||||||
|
domain = "grafana.in.redalder.org";
|
||||||
|
};
|
||||||
|
system = {
|
||||||
|
http_addr = "127.0.0.1";
|
||||||
|
};
|
||||||
|
database = {
|
||||||
|
type = "postgres";
|
||||||
|
host = "/var/run/postgresql";
|
||||||
|
name = "grafana";
|
||||||
|
user = "grafana";
|
||||||
|
};
|
||||||
|
|
||||||
|
paths.provisioning = {
|
||||||
|
datasources.datasources = [
|
||||||
|
{
|
||||||
|
name = "InfluxDB";
|
||||||
|
type = "influxdb";
|
||||||
|
access = "proxy";
|
||||||
|
orgId = 1;
|
||||||
|
uid = "influxdb";
|
||||||
|
url = "http://127.0.0.1:8086";
|
||||||
|
jsonData = {
|
||||||
|
version = "Flux";
|
||||||
|
organization = "redalder";
|
||||||
|
defaultBucket = "bucket";
|
||||||
|
};
|
||||||
|
secureJsonData = {
|
||||||
|
token = "$__file{/run/secrets/grafana-influx.token}";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.hashicorp-envoy.influx = {
|
||||||
|
service = {
|
||||||
|
name = "influx";
|
||||||
|
id = "influx";
|
||||||
|
address = "10.64.99.2";
|
||||||
|
port = 8086;
|
||||||
|
|
||||||
|
connect.sidecar_service = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
"CONSUL_HTTP_ADDR" = "http://${secret.network.ips.blowhole.ip or ""}:8500";
|
||||||
|
"CONSUL_GRPC_ADDR" = "http://${secret.network.ips.blowhole.ip or ""}:8502";
|
||||||
|
"CONSUL_HTTP_TOKEN_FILE" = "/run/secrets/envoy-grafana.token";
|
||||||
|
};
|
||||||
|
|
||||||
|
address = "10.64.99.2:19001";
|
||||||
|
adminBind = "127.0.0.1:19101";
|
||||||
|
hotRestart = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.influxdb2 = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
http-bind-address = "127.0.0.1:8086";
|
||||||
|
hardening-enabled = true;
|
||||||
|
reporting-disabled = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.hashicorp-envoy.telegraf = {
|
||||||
|
service = {
|
||||||
|
name = "telegraf";
|
||||||
|
id = "telegraf";
|
||||||
|
address = "10.64.99.2";
|
||||||
|
port = 8087;
|
||||||
|
|
||||||
|
connect.sidecar_service = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
"CONSUL_HTTP_ADDR" = "http://${secret.network.ips.blowhole.ip or ""}:8500";
|
||||||
|
"CONSUL_GRPC_ADDR" = "http://${secret.network.ips.blowhole.ip or ""}:8502";
|
||||||
|
"CONSUL_HTTP_TOKEN_FILE" = "/run/secrets/envoy-grafana.token";
|
||||||
|
};
|
||||||
|
|
||||||
|
address = "10.64.99.2:19002";
|
||||||
|
adminBind = "127.0.0.1:19102";
|
||||||
|
hotRestart = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.telegraf-magic = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
inputs.influxdb_v2_listener = {
|
||||||
|
service_address = "127.0.0.1:8087";
|
||||||
|
bucket_tag = "bucket";
|
||||||
|
parser_type = "upstream";
|
||||||
|
};
|
||||||
|
|
||||||
|
inputs.systemd_units = {
|
||||||
|
unittype = "service";
|
||||||
|
tags = {
|
||||||
|
host = "blowhole#monitoring";
|
||||||
|
bucket = "metrics";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs.influxdb_v2 = singleton {
|
||||||
|
urls = [ "http://127.0.0.1:8086" ];
|
||||||
|
token = "\${INFLUXDB_TOKEN}";
|
||||||
|
organization = "redalder";
|
||||||
|
bucket_tag = "bucket";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.serviceConfig = {
|
||||||
|
EnvironmentFile = "/run/secrets/telegraf.env";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
108
nixos/systems/blowhole/nas.nix
Normal file
108
nixos/systems/blowhole/nas.nix
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
fileSystems."/mnt/cartman" = {
|
||||||
|
device = "storfa/ds1/cartman";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.mnt-kyle-zfs-relmount = {
|
||||||
|
requires = ["mnt-kyle.mount"];
|
||||||
|
after = ["mnt-kyle.mount"];
|
||||||
|
requiredBy = ["local-fs.target"];
|
||||||
|
|
||||||
|
path = with pkgs; [zfs util-linux];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
RemainAfterExit = true;
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = "${pkgs.zfs-relmount}/bin/zfs-relmount mount storfa/ds1/kyle /mnt/kyle";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/mnt/kyle" = {
|
||||||
|
device = "storfa/ds1/kyle";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.mnt-cartman-zfs-relmount = {
|
||||||
|
requires = ["mnt-cartman.mount"];
|
||||||
|
after = ["mnt-cartman.mount"];
|
||||||
|
requiredBy = ["local-fs.target"];
|
||||||
|
|
||||||
|
path = with pkgs; [zfs util-linux];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
RemainAfterExit = true;
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = "${pkgs.zfs-relmount}/bin/zfs-relmount mount storfa/ds1/cartman /mnt/cartman";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/mnt/stan" = {
|
||||||
|
device = "storfa/ds1/stan";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.mnt-stan-zfs-relmount = {
|
||||||
|
requires = ["mnt-stan.mount"];
|
||||||
|
after = ["mnt-stan.mount"];
|
||||||
|
requiredBy = ["local-fs.target"];
|
||||||
|
|
||||||
|
path = with pkgs; [zfs util-linux];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
RemainAfterExit = true;
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = "${pkgs.zfs-relmount}/bin/zfs-relmount mount storfa/ds1/stan /mnt/stan";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/run/restic" = {
|
||||||
|
fsType = "tmpfs";
|
||||||
|
options = [ "size=64M" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.restic.backups.cartman = {
|
||||||
|
initialize = true;
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = "03:00";
|
||||||
|
};
|
||||||
|
|
||||||
|
paths = [ "/run/restic/cartman" ];
|
||||||
|
backupPrepareCommand = ''
|
||||||
|
snapshot="$(date +restic%+4Y_%U_%u)"
|
||||||
|
${pkgs.zfs-relmount}/bin/zfs-relmount snapshot storfa/ds1/cartman "''${snapshot}"
|
||||||
|
|
||||||
|
mkdir /run/restic/cartman
|
||||||
|
${pkgs.zfs-relmount}/bin/zfs-relmount mount-snapshot storfa/ds1/cartman /run/restic/cartman "''${snapshot}"
|
||||||
|
|
||||||
|
export RESTIC_PROGRESS_FPS=1
|
||||||
|
'';
|
||||||
|
backupCleanupCommand = ''
|
||||||
|
${pkgs.zfs-relmount}/bin/zfs-relmount umount storfa/ds1/cartman /run/restic/cartman
|
||||||
|
rm -r /run/restic/cartman
|
||||||
|
'';
|
||||||
|
|
||||||
|
passwordFile = "";
|
||||||
|
repository = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.timers."restic-backups-cartman" = {
|
||||||
|
timerConfig = {
|
||||||
|
Persistent = true;
|
||||||
|
WakeSystem = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services."restic-backups-cartman" = {
|
||||||
|
path = with pkgs; [
|
||||||
|
util-linux
|
||||||
|
zfs
|
||||||
|
];
|
||||||
|
serviceConfig = {
|
||||||
|
Nice = 19;
|
||||||
|
IOSchedulingClass = "idle";
|
||||||
|
EnvironmentFile = "/var/secrets/restic-b2";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
14
nixos/systems/blowhole/networking.nix
Normal file
14
nixos/systems/blowhole/networking.nix
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# SPDX-FileCopyrightText: 2023 Richard Brežák <richard@brezak.sk>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
networking = {
|
||||||
|
hostName = "blowhole";
|
||||||
|
useDHCP = false;
|
||||||
|
interfaces.enp7s0f1.useDHCP = true;
|
||||||
|
|
||||||
|
firewall.enable = false;
|
||||||
|
hostId = "2cb135ac";
|
||||||
|
};
|
||||||
|
}
|
62
nixos/systems/blowhole/nfs.nix
Normal file
62
nixos/systems/blowhole/nfs.nix
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
# SPDX-FileCopyrightText: 2023 Richard Brežák <richard@brezak.sk>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
{ lib, ... }:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
systemd.services.nfs-mountd.serviceConfig = {
|
||||||
|
LimitNOFILE = 8192;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nfs.server = {
|
||||||
|
enable = true;
|
||||||
|
lockdPort = 4001;
|
||||||
|
mountdPort = 4002;
|
||||||
|
statdPort = 4000;
|
||||||
|
exports = ''
|
||||||
|
/var/nfs/jellyfin/cache 10.64.2.1/32(rw,subtree_check,async,no_root_squash,crossmnt)
|
||||||
|
/var/nfs/jellyfin/config 10.64.2.1/32(rw,subtree_check,async,no_root_squash,crossmnt)
|
||||||
|
/var/nfs/jellyfin/media 10.64.2.1/32(rw,subtree_check,async,no_root_squash,crossmnt)
|
||||||
|
|
||||||
|
/var/nfs/gitea-data 10.64.2.1/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
/var/nfs/gitea-db 10.64.2.1/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
|
||||||
|
/var/nfs/hydra-data 10.64.2.1/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
/var/nfs/hydra-nix 10.64.2.1/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
/var/nfs/hydra-db 10.64.2.1/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
|
||||||
|
/var/nfs/minecraft/atm6 10.64.2.1/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
|
||||||
|
/var/nfs/ingress-letsencrypt 10.64.0.1(rw,subtree_check,async,no_root_squash)
|
||||||
|
|
||||||
|
/var/nfs/Magic_RB 10.64.2.129(rw,subtree_check,async)
|
||||||
|
/mnt/cartman 10.64.0.8/32(rw,subtree_check,async,no_root_squash,crossmnt) 10.64.2.129(rw,subtree_check,async,crossmnt)
|
||||||
|
/mnt/kyle 10.64.0.8/32(rw,subtree_check,async,no_root_squash,crossmnt) 10.64.2.129(rw,subtree_check,async,crossmnt)
|
||||||
|
/mnt/stan 10.64.0.8/32(rw,subtree_check,async,no_root_squash,crossmnt) 10.64.2.129(rw,subtree_check,async,crossmnt)
|
||||||
|
|
||||||
|
/var/nfs/home-assistant_hass 10.64.2.1/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
/var/nfs/home-assistant_db 10.64.2.1/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
/var/nfs/home-assistant_mosquitto 10.64.2.1/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
/var/nfs/home-assistant_zigbee2mqtt 10.64.2.1/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
|
||||||
|
/var/nfs/syncthing/data 10.64.2.1/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
/var/nfs/syncthing/config 10.64.2.1/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
/var/nfs/syncthing/storage 10.64.2.1/32(rw,subtree_check,async,crossmnt)
|
||||||
|
|
||||||
|
/var/nfs/dovecot/maildir 10.64.0.8/32(rw,subtree_check,async,no_root_squash) 10.64.2.1/32(rw,subtree_check,async,no_root_squash) 10.64.3.20/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
/var/nfs/getmail/getmail.d 10.64.0.8/32(rw,subtree_check,async,no_root_squash) 10.64.2.1/32(rw,subtree_check,async,no_root_squash) 10.64.3.20/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
/var/nfs/mail-configuration 10.64.0.8/32(rw,subtree_check,async,no_root_squash) 10.64.2.1/32(rw,subtree_check,async,no_root_squash) 10.64.3.20/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
|
||||||
|
/var/nfs/baikal/specific 10.64.2.1/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
/var/nfs/baikal/config 10.64.2.1/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
|
||||||
|
/var/nfs/matrix/synapse 10.64.2.1/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
/var/nfs/matrix/postgresql 10.64.2.1/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
/var/nfs/matrix/mautrix-facebook 10.64.2.1/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
/var/nfs/matrix/registrations 10.64.2.1/32(rw,subtree_check,async,no_root_squash)
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
18
nixos/systems/blowhole/nixpkgs.nix
Normal file
18
nixos/systems/blowhole/nixpkgs.nix
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{ inputs', config', config, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
../../common/nixpkgs.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
nixpkgs.overlays =
|
||||||
|
(with config'.flake.overlays; [
|
||||||
|
udp-over-tcp
|
||||||
|
emacsclient-remote
|
||||||
|
zfs-relmount
|
||||||
|
ical2org
|
||||||
|
])
|
||||||
|
++
|
||||||
|
(with inputs'.nixng.overlays; [
|
||||||
|
default
|
||||||
|
]);
|
||||||
|
}
|
161
nixos/systems/blowhole/nomad.nix
Normal file
161
nixos/systems/blowhole/nomad.nix
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
{inputs', lib, config, pkgs, secret, config', ...}:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
singleton;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
services.hashicorp.vault-agent = {
|
||||||
|
settings.template = singleton {
|
||||||
|
source = pkgs.writeText "nomad.json.vtmpl" ''
|
||||||
|
{
|
||||||
|
"server": {
|
||||||
|
"encrypt": "{{ with secret "kv/data/homelab-1/blowhole/nomad/encryption_key" }}{{ or .Data.data.key "" }}{{ end }}"
|
||||||
|
},
|
||||||
|
"vault": {
|
||||||
|
"token": "{{ with secret "kv/data/homelab-1/blowhole/nomad/vault_token" }}{{ or .Data.data.secret "" }}{{ end }}"
|
||||||
|
},
|
||||||
|
"consul": {
|
||||||
|
"token": "{{ with secret "kv/data/homelab-1/blowhole/nomad/consul_token" }}{{ or .Data.data.secret "" }}{{ end }}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
destination = "/run/secrets/nomad.json";
|
||||||
|
command = pkgs.writeShellScript "nomad-command" ''
|
||||||
|
sudo systemctl try-reload-or-restart hashicorp-nomad.service
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.hashicorp-nomad.unitConfig = {
|
||||||
|
ConditionPathExists = "/run/secrets/nomad.json";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.hashicorp.nomad = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
extraPackages = with pkgs; [
|
||||||
|
coreutils
|
||||||
|
iproute2
|
||||||
|
iptables
|
||||||
|
consul
|
||||||
|
glibc
|
||||||
|
config.nix.package
|
||||||
|
git
|
||||||
|
];
|
||||||
|
extraSettingsPaths = [
|
||||||
|
"/run/secrets/nomad.json"
|
||||||
|
];
|
||||||
|
package = inputs'.nixpkgs-hashicorp.legacyPackages.${pkgs.stdenv.system}.nomad_1_5.overrideAttrs (old:
|
||||||
|
{
|
||||||
|
patches = with config'.flake.patches; [
|
||||||
|
hashicorp-nomad.revert-change-consul-si-tokens-to-be-local
|
||||||
|
hashicorp-nomad.add-nix-integration
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
bind_addr = secret.network.ips.blowhole.ip or "";
|
||||||
|
server.enabled = true;
|
||||||
|
|
||||||
|
tls = {
|
||||||
|
# http = false # true
|
||||||
|
# rpc = true
|
||||||
|
|
||||||
|
# ca_file = "nomad-ca.pem"
|
||||||
|
# cert_file = "client.pem"
|
||||||
|
# key_file = "client-key.pem"
|
||||||
|
|
||||||
|
# verify_server_hostname = true
|
||||||
|
# verify_https_client = true
|
||||||
|
};
|
||||||
|
|
||||||
|
vault = {
|
||||||
|
enabled = true;
|
||||||
|
address = "https://${secret.network.ips.vault.dns or ""}:8200";
|
||||||
|
allow_unauthenticated = true;
|
||||||
|
create_from_role = "nomad-cluster";
|
||||||
|
};
|
||||||
|
|
||||||
|
consul = {
|
||||||
|
address = "${secret.network.ips.blowhole.ip or ""}:8500";
|
||||||
|
auto_advertise = true;
|
||||||
|
server_auto_join = true;
|
||||||
|
client_auto_join = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
acl.enabled = true;
|
||||||
|
|
||||||
|
telemetry = {
|
||||||
|
publish_allocation_metrics = true;
|
||||||
|
publish_node_metrics = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
client = {
|
||||||
|
cni_path = "${pkgs.cni-plugins}/bin";
|
||||||
|
|
||||||
|
min_dynamic_port = 20000;
|
||||||
|
max_dynamic_port = 32000;
|
||||||
|
|
||||||
|
options = {
|
||||||
|
"docker.privileged.enabled" = "true";
|
||||||
|
};
|
||||||
|
|
||||||
|
host_network."default".cidr = secret.network.networks.home.mine or "";
|
||||||
|
host_network."mesh".cidr = secret.network.networks.home.mine or "";
|
||||||
|
|
||||||
|
network_interface = "enp4s0";
|
||||||
|
|
||||||
|
host_volume."jellyfin-mount".path = "/mnt/jellyfin-mount";
|
||||||
|
host_volume."cctv" = {
|
||||||
|
path = "/mnt/cctv";
|
||||||
|
read_only = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
enabled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
plugin."docker" = {
|
||||||
|
config = {
|
||||||
|
allow_caps = [
|
||||||
|
"CHOWN"
|
||||||
|
"DAC_OVERRIDE"
|
||||||
|
"FSETID"
|
||||||
|
"FOWNER"
|
||||||
|
"MKNOD"
|
||||||
|
"NET_RAW"
|
||||||
|
"SETGID"
|
||||||
|
"SETUID"
|
||||||
|
"SETFCAP"
|
||||||
|
"SETPCAP"
|
||||||
|
"NET_BIND_SERVICE"
|
||||||
|
"SYS_CHROOT"
|
||||||
|
"KILL"
|
||||||
|
"AUDIT_WRITE"
|
||||||
|
"SYS_ADMIN"
|
||||||
|
];
|
||||||
|
allow_privileged = true;
|
||||||
|
extra_labels = [
|
||||||
|
"job_name"
|
||||||
|
"job_id"
|
||||||
|
"task_group_name"
|
||||||
|
"task_name"
|
||||||
|
"namespace"
|
||||||
|
"node_name"
|
||||||
|
"node_id"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
disable_update_check = true;
|
||||||
|
data_dir = "/var/lib/nomad";
|
||||||
|
|
||||||
|
datacenter = "homelab-1";
|
||||||
|
region = "homelab-1";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
virtualisation.docker.enable = true;
|
||||||
|
virtualisation.docker.daemon.settings.dns = [
|
||||||
|
(secret.network.ips.blowhole or "")
|
||||||
|
];
|
||||||
|
}
|
19
nixos/systems/blowhole/users.nix
Normal file
19
nixos/systems/blowhole/users.nix
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{ inputs', config', secret, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
inputs'.home-manager.nixosModules.default
|
||||||
|
../../common/users.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
home-manager.useGlobalPkgs = true;
|
||||||
|
home-manager.extraSpecialArgs = {
|
||||||
|
config' = config';
|
||||||
|
inputs' = inputs';
|
||||||
|
secret = secret;
|
||||||
|
};
|
||||||
|
home-manager.users.main = {
|
||||||
|
imports = [ (inputs'.self + "/home-manager/modules/profiles/server.nix") ];
|
||||||
|
|
||||||
|
home.stateVersion = "21.05";
|
||||||
|
};
|
||||||
|
}
|
66
nixos/systems/blowhole/uterranix.nix
Normal file
66
nixos/systems/blowhole/uterranix.nix
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
{ config, inputs', lib, config', pkgs, ... }:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
singleton;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [ inputs'.uterranix.nixosModules.default ];
|
||||||
|
|
||||||
|
uterranix.config = { config, tflib, ... }:
|
||||||
|
let
|
||||||
|
inherit (tflib)
|
||||||
|
tf;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
terraform.required_providers =
|
||||||
|
config'.flake.uterranix.config.${pkgs.stdenv.system}.terraform.required_providers;
|
||||||
|
|
||||||
|
imports = config'.uterranix.modules;
|
||||||
|
|
||||||
|
resource."vault_consul_secret_backend_role"."envoy-grafana" = {
|
||||||
|
name = "envoy-grafana";
|
||||||
|
|
||||||
|
backend = "consul";
|
||||||
|
|
||||||
|
service_identities = [
|
||||||
|
"grafana"
|
||||||
|
"influx"
|
||||||
|
"telegraf"
|
||||||
|
];
|
||||||
|
|
||||||
|
node_identities = singleton "blowhole:homelab-1";
|
||||||
|
};
|
||||||
|
|
||||||
|
resource."consul_acl_policy"."envoy-blowhole" = {
|
||||||
|
name = "envoy-blowhole";
|
||||||
|
datacenters = singleton "homelab-1";
|
||||||
|
|
||||||
|
rules = ''
|
||||||
|
mesh = "write"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
resource."vault_consul_secret_backend_role"."envoy-blowhole" = {
|
||||||
|
name = "envoy-blowhole";
|
||||||
|
backend = "consul";
|
||||||
|
|
||||||
|
consul_policies = singleton (tf "consul_acl_policy.envoy-blowhole.name");
|
||||||
|
|
||||||
|
service_identities = singleton "telegraf-blowhole";
|
||||||
|
|
||||||
|
node_identities = [
|
||||||
|
"blowhole:homelab-1"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
resource."vault_consul_secret_backend_role"."envoy-klipper" = {
|
||||||
|
name = "envoy-klipper";
|
||||||
|
|
||||||
|
backend = "consul";
|
||||||
|
|
||||||
|
service_identities = singleton "mainsail";
|
||||||
|
|
||||||
|
node_identities = singleton "blowhole:homelab-1";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
76
nixos/systems/blowhole/vault-agent.nix
Normal file
76
nixos/systems/blowhole/vault-agent.nix
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
{ pkgs, lib, config, tf, inputs', ... }:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
singleton;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
systemd.services.hashicorp-vault-agent =
|
||||||
|
let
|
||||||
|
config = pkgs.writeText "hashicorp-vault-agent-tmpfiles.d" ''
|
||||||
|
d /run/secrets 0750 root root 0
|
||||||
|
x /run/secrets/monitor 0755 root root -
|
||||||
|
d /run/secrets/monitor 0755 root root 0
|
||||||
|
x /run/secrets/klipper 0755 root root -
|
||||||
|
d /run/secrets/klipper 0755 root root 0
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
preStart = "systemd-tmpfiles --create " + config;
|
||||||
|
postStop = "systemd-tmpfiles --clean " + config;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.hashicorp.vault-agent = {
|
||||||
|
enable = true;
|
||||||
|
package = inputs'.nixpkgs-hashicorp.legacyPackages.${pkgs.stdenv.system}.vault;
|
||||||
|
|
||||||
|
command = "agent";
|
||||||
|
|
||||||
|
extraPackages = with pkgs; [
|
||||||
|
sudo
|
||||||
|
getent
|
||||||
|
];
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
vault = {
|
||||||
|
address = "https://vault.in.redalder.org:8200";
|
||||||
|
retry = {
|
||||||
|
num_retries = 5;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
auto_auth = {
|
||||||
|
method = singleton {
|
||||||
|
"approle" = {
|
||||||
|
mount_path = "auth/approle";
|
||||||
|
config = {
|
||||||
|
role_id_file_path = "/var/secrets/approle.roleid";
|
||||||
|
secret_id_file_path = "/var/secrets/approle.secretid";
|
||||||
|
remove_secret_id_file_after_reading = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
sink = singleton {
|
||||||
|
type = "file";
|
||||||
|
config = {
|
||||||
|
path = "/run/secrets/vault-token";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template = [
|
||||||
|
{
|
||||||
|
source = pkgs.writeText "id_ed_camera" ''
|
||||||
|
{{ with secret "kv/data/homelab-1/blowhole/id_ed_camera" }}{{ .Data.data.private }}{{ end }}
|
||||||
|
'';
|
||||||
|
destination = "/run/secrets/id_ed_camera";
|
||||||
|
command = pkgs.writeShellScript "id_ed_camera-command" ''
|
||||||
|
export PATH=${pkgs.util-linux}/bin:$PATH
|
||||||
|
chown root:root /run/secrets/id_ed_camera
|
||||||
|
chmod 600 /run/secrets/id_ed_camera
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
80
nixos/systems/blowhole/vault.nix
Normal file
80
nixos/systems/blowhole/vault.nix
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
{lib, config, pkgs, secret, inputs', ...}:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
mkForce;
|
||||||
|
certs = config.services.acme-sh.certs;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
services.hashicorp.vault = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
package = inputs'.nixpkgs-hashicorp.legacyPackages.${pkgs.stdenv.system}.vault-bin;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
backend."file".path = "/var/lib/vault";
|
||||||
|
|
||||||
|
ui = true;
|
||||||
|
|
||||||
|
listener = [
|
||||||
|
{
|
||||||
|
"tcp" = {
|
||||||
|
address = "localhost:8200";
|
||||||
|
tls_cert_file = "${certs.vault.certPath}";
|
||||||
|
tls_key_file = "${certs.vault.keyPath}";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"tcp" = {
|
||||||
|
address = "${secret.network.ips.blowhole.ip or ""}:8200";
|
||||||
|
tls_cert_file = "${certs.vault.certPath}";
|
||||||
|
tls_key_file = "${certs.vault.keyPath}";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
storage."raft" = {
|
||||||
|
path = "/var/lib/vault";
|
||||||
|
node_id = "blowhole";
|
||||||
|
};
|
||||||
|
cluster_addr = "https://${secret.network.ips.blowhole.ip or ""}:8201";
|
||||||
|
api_addr = "http://${secret.network.ips.blowhole.ip or ""}:8200";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.acme-sh.certs.vault = {
|
||||||
|
production = true;
|
||||||
|
user = "root";
|
||||||
|
domains."vault.in.redalder.org" = "dns_hetzner";
|
||||||
|
mainDomain = "vault.in.redalder.org";
|
||||||
|
postRun = "systemctl try-reload-or-restart --no-block hashicorp-vault.service";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services."acme-sh-vault" = {
|
||||||
|
serviceConfig.EnvironmentFile = mkForce "/var/secrets/hetzner.env";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.acme-sh.certs.vault-wildcard = {
|
||||||
|
production = true;
|
||||||
|
user = "root";
|
||||||
|
domains."*.in.redalder.org" = "dns_hetzner";
|
||||||
|
mainDomain = "*.in.redalder.org";
|
||||||
|
# Trigger vault to reread certificate files.
|
||||||
|
postRun = ''
|
||||||
|
PEM_BUNDLE=$(cat <<EOF
|
||||||
|
$(cat '${certs.vault-wildcard.statePath}/*.in.redalder.org/ca.cer')
|
||||||
|
$(cat '${certs.vault-wildcard.keyPath}')
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
(
|
||||||
|
exec 44<<<"$PEM_BUNDLE"
|
||||||
|
VAULT_ADDR="https://vault.in.redalder.org:8200" \
|
||||||
|
VAULT_TOKEN="$(cat /run/secrets/vault-token)" \
|
||||||
|
${pkgs.vault}/bin/vault write pki-inra/config/ca pem_bundle=@/proc/self/fd/44
|
||||||
|
)
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services."acme-sh-vault-wildcard" = {
|
||||||
|
serviceConfig.EnvironmentFile = mkForce "/var/secrets/hetzner.env";
|
||||||
|
};
|
||||||
|
}
|
7
nixos/systems/blowhole/watchdog.nix
Normal file
7
nixos/systems/blowhole/watchdog.nix
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
systemd.watchdog.runtimeTime = "60s";
|
||||||
|
systemd.watchdog.rebootTime = "10m";
|
||||||
|
systemd.watchdog.kexecTime = "5m";
|
||||||
|
systemd.services."emergency".serviceConfig.ExecStartPre = "/bin/sh -c \"read -t 30 || /run/current-system/sw/bin/systemctl reboot\"";
|
||||||
|
}
|
15
nixos/systems/blowhole/zones/blocked.zone
Normal file
15
nixos/systems/blowhole/zones/blocked.zone
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
;
|
||||||
|
; BIND data file for example.local
|
||||||
|
;
|
||||||
|
$TTL 3600
|
||||||
|
@ IN SOA ns1.example.local. info.example.local. (
|
||||||
|
2022092600 ; Serial
|
||||||
|
7200 ; Refresh
|
||||||
|
120 ; Retry
|
||||||
|
2419200 ; Expire
|
||||||
|
3600) ; Default TTL
|
||||||
|
;
|
||||||
|
A 10.64.2.1 ; This means that naughydomain.com gets directed to the designated address
|
||||||
|
* IN A 10.64.2.1 ; This wildcard entry means that any permutation of xxx.naughtydomain.com gets directed to the designated address
|
||||||
|
AAAA ::1 ; This means that naughydomain.com gets directed to IPv6 localhost
|
||||||
|
* IN AAAA ::1 ; This wildcard entry means that any permutation of xxx.naughtydomain.com gets directed to IPv6 localhost
|
16
nixos/systems/blowhole/zones/hosts.in.redalder.org.zone
Normal file
16
nixos/systems/blowhole/zones/hosts.in.redalder.org.zone
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
$ORIGIN in.redalder.org.
|
||||||
|
$TTL 5m
|
||||||
|
|
||||||
|
hosts IN SOA ns.in.redalder.org. root.redalder.org. (
|
||||||
|
14 ; serial
|
||||||
|
4h ; refresh
|
||||||
|
15m ; retry
|
||||||
|
8h ; expire
|
||||||
|
4m) ; negativa caching TTL
|
||||||
|
IN NS ns.redalder.org
|
||||||
|
IN A 10.64.2.1
|
||||||
|
|
||||||
|
$ORIGIN hosts.in.redalder.org.
|
||||||
|
|
||||||
|
blowhole IN A 10.64.2.1
|
||||||
|
toothpick IN A 10.64.0.1
|
26
nixos/systems/blowhole/zones/in.redalder.org.zone
Normal file
26
nixos/systems/blowhole/zones/in.redalder.org.zone
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
$ORIGIN redalder.org.
|
||||||
|
$TTL 5m
|
||||||
|
|
||||||
|
in IN SOA ns.redalder.org. root.redalder.org. (
|
||||||
|
24 ; serial
|
||||||
|
4h ; refresh
|
||||||
|
15m ; retry
|
||||||
|
8h ; expire
|
||||||
|
4m) ; negativa caching TTL
|
||||||
|
IN NS ns.redalder.org
|
||||||
|
IN A 10.64.2.1
|
||||||
|
|
||||||
|
$ORIGIN in.redalder.org.
|
||||||
|
|
||||||
|
vault IN A 10.64.2.1
|
||||||
|
consul IN A 10.64.2.1
|
||||||
|
nomad IN A 10.64.2.1
|
||||||
|
grafana IN A 10.64.2.1
|
||||||
|
hass IN A 10.64.2.1
|
||||||
|
jellyfin IN A 10.64.2.1
|
||||||
|
zigbee2mqtt IN A 10.64.2.1
|
||||||
|
syncthing IN A 10.64.2.1
|
||||||
|
influx IN A 10.64.2.1
|
||||||
|
mainsail IN A 10.64.2.1
|
||||||
|
matrix IN A 10.64.2.1
|
||||||
|
|
|
@ -101,7 +101,7 @@ in
|
||||||
powerManagement.enable = true;
|
powerManagement.enable = true;
|
||||||
powerManagement.finegrained = true;
|
powerManagement.finegrained = true;
|
||||||
|
|
||||||
prime.reverseSync.enable = true;
|
prime.reverseSync.enable = false;
|
||||||
prime.offload.enable = true;
|
prime.offload.enable = true;
|
||||||
|
|
||||||
modesetting.enable = true;
|
modesetting.enable = true;
|
||||||
|
|
71
overlays/ical2org.nix
Normal file
71
overlays/ical2org.nix
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
{ inputs, ... }:
|
||||||
|
{
|
||||||
|
flake.overlays.ical2org =
|
||||||
|
final: prev: {
|
||||||
|
x-wr-timezone = with prev;
|
||||||
|
python3.pkgs.buildPythonPackage rec {
|
||||||
|
pname = "x_wr_timezone";
|
||||||
|
version = "0.0.5";
|
||||||
|
|
||||||
|
src = python3.pkgs.fetchPypi {
|
||||||
|
inherit pname version;
|
||||||
|
sha256 = "sha256-wFyzS5tYpGB6eI2whtyuV2ZyjkuU4GcocNxVk6bhP+Y=";
|
||||||
|
};
|
||||||
|
|
||||||
|
propagatedBuildInputs = with python3.pkgs; [
|
||||||
|
pytz
|
||||||
|
icalendar
|
||||||
|
pygments
|
||||||
|
restructuredtext_lint
|
||||||
|
pytest
|
||||||
|
];
|
||||||
|
|
||||||
|
meta = with lib; {};
|
||||||
|
};
|
||||||
|
|
||||||
|
recurring-ical-events = with prev;
|
||||||
|
python3.pkgs.buildPythonPackage rec {
|
||||||
|
pname = "recurring_ical_events";
|
||||||
|
version = "1.0.2b0";
|
||||||
|
|
||||||
|
src = python3.pkgs.fetchPypi {
|
||||||
|
inherit pname version;
|
||||||
|
sha256 = "sha256-aoQU7rxRJvqe3PLHPto5T2rCvFSkmqfiClwCL6SRjk0=";
|
||||||
|
};
|
||||||
|
|
||||||
|
propagatedBuildInputs = with python3.pkgs; [
|
||||||
|
pytz
|
||||||
|
python-dateutil
|
||||||
|
final.x-wr-timezone
|
||||||
|
tzdata
|
||||||
|
pytest-cov
|
||||||
|
pbr
|
||||||
|
];
|
||||||
|
|
||||||
|
meta = with lib; {};
|
||||||
|
};
|
||||||
|
|
||||||
|
ical2orgpy = with prev;
|
||||||
|
python3.pkgs.buildPythonApplication rec {
|
||||||
|
pname = "ical2orgpy";
|
||||||
|
version = "0.4.0";
|
||||||
|
|
||||||
|
src = inputs.ical2org;
|
||||||
|
|
||||||
|
PBR_VERSION="1.2.3";
|
||||||
|
propagatedBuildInputs = with python3.pkgs; [
|
||||||
|
click
|
||||||
|
future
|
||||||
|
icalendar
|
||||||
|
pytz
|
||||||
|
tzlocal
|
||||||
|
final.recurring-ical-events
|
||||||
|
];
|
||||||
|
|
||||||
|
meta = with prev.lib; {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
11
overlays/zfs-relmount/default.nix
Normal file
11
overlays/zfs-relmount/default.nix
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
{
|
||||||
|
flake.overlays.zfs-relmount =
|
||||||
|
final: prev: {
|
||||||
|
zfs-relmount =
|
||||||
|
prev.writeShellScriptBin "zfs-relmount"
|
||||||
|
(builtins.readFile ./zfs-relmount.sh);
|
||||||
|
};
|
||||||
|
}
|
82
overlays/zfs-relmount/zfs-relmount.sh
Normal file
82
overlays/zfs-relmount/zfs-relmount.sh
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# SPDX-FileCopyrightText: 2022 Richard Brežák <richard@brezak.sk>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
|
||||||
|
function recurse_children()
|
||||||
|
{
|
||||||
|
local volume="${1}"
|
||||||
|
local dir="${2}"
|
||||||
|
local relmount="${3}"
|
||||||
|
local children="${4}"
|
||||||
|
local action="${5}"
|
||||||
|
|
||||||
|
for child in $children
|
||||||
|
do
|
||||||
|
if [ "${child}" == "${volume}" ]
|
||||||
|
then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
recursive_perform "${child}" "${dir}/$(basename "${child}")" "${action}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function recursive_perform()
|
||||||
|
{
|
||||||
|
local volume="${1}"
|
||||||
|
local dir="${2}"
|
||||||
|
local action="${3}"
|
||||||
|
|
||||||
|
local relmount="$(zfs get -Ho value :relmount "${volume}")"
|
||||||
|
local children="$(zfs list -Hrd 1 "${volume}" -o name | tr '\n' ' ')"
|
||||||
|
|
||||||
|
if ! [ -z "${relmount}" ] && [ "${relmount}" != "-" ]
|
||||||
|
then
|
||||||
|
case "${relmount}" in
|
||||||
|
"yes")
|
||||||
|
eval "${action}"
|
||||||
|
recurse_children "${volume}" "${dir}" "${relmount}" "${children}" "${action}"
|
||||||
|
;;
|
||||||
|
"pass")
|
||||||
|
recurse_children "${volume}" "${dir}" "${relmount}" "${children}" "${action}"
|
||||||
|
;;
|
||||||
|
"*")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
action="${1}"
|
||||||
|
shift 1
|
||||||
|
|
||||||
|
case $action in
|
||||||
|
"mount")
|
||||||
|
zfs_src="${1}"
|
||||||
|
dst_dir="${2}"
|
||||||
|
|
||||||
|
recursive_perform "${zfs_src}" "${dst_dir}" 'mount -o X-mount.mkdir -t zfs "${volume}" "${dir}"'
|
||||||
|
;;
|
||||||
|
"mount-snapshot")
|
||||||
|
zfs_src="${1}"
|
||||||
|
dst_dir="${2}"
|
||||||
|
snapshot="${3}"
|
||||||
|
|
||||||
|
recursive_perform "${zfs_src}" "${dst_dir}" 'mount -o X-mount.mkdir -t zfs "${volume}"@'"${snapshot}"' "${dir}"'
|
||||||
|
;;
|
||||||
|
"umount")
|
||||||
|
zfs_src="${1}"
|
||||||
|
dst_dir="${2}"
|
||||||
|
|
||||||
|
recursive_perform "${zfs_src}" "${dst_dir}" 'umount -t zfs "${dir}"'
|
||||||
|
;;
|
||||||
|
"snapshot")
|
||||||
|
root="${1}"
|
||||||
|
snapshot="${2}"
|
||||||
|
|
||||||
|
recursive_perform "${root}" "${root}" 'zfs snapshot "${volume}"@'"${snapshot}"
|
||||||
|
;;
|
||||||
|
"*")
|
||||||
|
;;
|
||||||
|
esac
|
159
patches/0001-intel_lar-and-noscan.patch
Normal file
159
patches/0001-intel_lar-and-noscan.patch
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
From 3590d38c853ce2fd7c2397f6421171234fb9d0a6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Magic_RB <magic_rb@redalder.org>
|
||||||
|
Date: Sat, 27 May 2023 18:11:58 +0200
|
||||||
|
Subject: [PATCH] intel_lar and noscan
|
||||||
|
|
||||||
|
Signed-off-by: Magic_RB <magic_rb@redalder.org>
|
||||||
|
---
|
||||||
|
hostapd/config_file.c | 4 ++++
|
||||||
|
src/ap/ap_config.h | 1 +
|
||||||
|
src/ap/hw_features.c | 45 +++++++++++++++++++++++++++++++++++++++---
|
||||||
|
src/ap/ieee802_11_ht.c | 6 ++++++
|
||||||
|
4 files changed, 53 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
|
||||||
|
index 8e179d151..6fa0849a0 100644
|
||||||
|
--- a/hostapd/config_file.c
|
||||||
|
+++ b/hostapd/config_file.c
|
||||||
|
@@ -2874,6 +2874,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
||||||
|
line, bss->wpa_deny_ptk0_rekey);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
+ } else if (os_strcmp(buf, "noscan") == 0) {
|
||||||
|
+ conf->noscan = atoi(pos);
|
||||||
|
} else if (os_strcmp(buf, "wpa_group_update_count") == 0) {
|
||||||
|
char *endp;
|
||||||
|
unsigned long val = strtoul(pos, &endp, 0);
|
||||||
|
@@ -3446,6 +3448,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
||||||
|
if (bss->ocv && !bss->ieee80211w)
|
||||||
|
bss->ieee80211w = 1;
|
||||||
|
#endif /* CONFIG_OCV */
|
||||||
|
+ } else if (os_strcmp(buf, "noscan") == 0) {
|
||||||
|
+ conf->noscan = atoi(pos);
|
||||||
|
} else if (os_strcmp(buf, "ieee80211n") == 0) {
|
||||||
|
conf->ieee80211n = atoi(pos);
|
||||||
|
} else if (os_strcmp(buf, "ht_capab") == 0) {
|
||||||
|
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
|
||||||
|
index 8598602b1..a25cf2cbe 100644
|
||||||
|
--- a/src/ap/ap_config.h
|
||||||
|
+++ b/src/ap/ap_config.h
|
||||||
|
@@ -1061,6 +1061,7 @@ struct hostapd_config {
|
||||||
|
|
||||||
|
int ht_op_mode_fixed;
|
||||||
|
u16 ht_capab;
|
||||||
|
+ int noscan;
|
||||||
|
int ieee80211n;
|
||||||
|
int secondary_channel;
|
||||||
|
int no_pri_sec_switch;
|
||||||
|
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
|
||||||
|
index 842d9f5ba..30ff7b496 100644
|
||||||
|
--- a/src/ap/hw_features.c
|
||||||
|
+++ b/src/ap/hw_features.c
|
||||||
|
@@ -24,6 +24,17 @@
|
||||||
|
#include "beacon.h"
|
||||||
|
#include "hw_features.h"
|
||||||
|
|
||||||
|
+static void ieee80211n_do_nothing(struct hostapd_iface *iface)
|
||||||
|
+{
|
||||||
|
+ wpa_printf(MSG_DEBUG,
|
||||||
|
+ "Scan finished!");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void ieee80211n_scan_channels_2g4(struct hostapd_iface *iface,
|
||||||
|
+ struct wpa_driver_scan_params *params);
|
||||||
|
+static void ieee80211n_scan_channels_5g(struct hostapd_iface *iface,
|
||||||
|
+ struct wpa_driver_scan_params *params);
|
||||||
|
+
|
||||||
|
|
||||||
|
void hostapd_free_hw_features(struct hostapd_hw_modes *hw_features,
|
||||||
|
size_t num_hw_features)
|
||||||
|
@@ -82,6 +93,33 @@ int hostapd_get_hw_features(struct hostapd_iface *iface)
|
||||||
|
|
||||||
|
if (hostapd_drv_none(hapd))
|
||||||
|
return -1;
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ // scan
|
||||||
|
+ struct wpa_driver_scan_params params;
|
||||||
|
+ int ret1;
|
||||||
|
+
|
||||||
|
+ os_memset(¶ms, 0, sizeof(params));
|
||||||
|
+ ieee80211n_scan_channels_5g(iface, ¶ms);
|
||||||
|
+
|
||||||
|
+ ret1 = hostapd_driver_scan(iface->bss[0], ¶ms);
|
||||||
|
+
|
||||||
|
+ if (ret1 == -EBUSY) {
|
||||||
|
+ wpa_printf(MSG_ERROR,
|
||||||
|
+ "Failed to request a scan of neighboring BSSes ret=%d (%s)!",
|
||||||
|
+ ret1, strerror(-ret1));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (ret1 == 0) {
|
||||||
|
+ iface->scan_cb = ieee80211n_do_nothing;
|
||||||
|
+ wpa_printf(MSG_DEBUG,
|
||||||
|
+ "Sleeping...");
|
||||||
|
+ for (int i=0; i<110; i++) {
|
||||||
|
+ usleep(100000);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
modes = hostapd_get_hw_feature_data(hapd, &num_modes, &flags,
|
||||||
|
&dfs_domain);
|
||||||
|
if (modes == NULL) {
|
||||||
|
@@ -308,7 +346,6 @@ static int ieee80211n_check_40mhz_2g4(struct hostapd_iface *iface,
|
||||||
|
sec_chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
-
|
||||||
|
static void ieee80211n_check_scan(struct hostapd_iface *iface)
|
||||||
|
{
|
||||||
|
struct wpa_scan_results *scan_res;
|
||||||
|
@@ -517,8 +554,10 @@ static int ieee80211n_check_40mhz(struct hostapd_iface *iface)
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Check that HT40 is used and PRI / SEC switch is allowed */
|
||||||
|
- if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch)
|
||||||
|
+ if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch || iface->conf->noscan) {
|
||||||
|
+ wpa_printf(MSG_DEBUG, "Not scanning due to noscan?");
|
||||||
|
return 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
hostapd_set_state(iface, HAPD_IFACE_HT_SCAN);
|
||||||
|
wpa_printf(MSG_DEBUG, "Scan for neighboring BSSes prior to enabling "
|
||||||
|
@@ -967,7 +1006,7 @@ static int hostapd_is_usable_chans(struct hostapd_iface *iface)
|
||||||
|
if (!hostapd_is_usable_punct_bitmap(iface))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- if (!iface->conf->secondary_channel)
|
||||||
|
+ if (!iface->conf->secondary_channel || iface->conf->noscan)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (hostapd_is_usable_chan(iface, iface->freq +
|
||||||
|
diff --git a/src/ap/ieee802_11_ht.c b/src/ap/ieee802_11_ht.c
|
||||||
|
index 59ecbdce7..99d6e82bc 100644
|
||||||
|
--- a/src/ap/ieee802_11_ht.c
|
||||||
|
+++ b/src/ap/ieee802_11_ht.c
|
||||||
|
@@ -230,6 +230,9 @@ void hostapd_2040_coex_action(struct hostapd_data *hapd,
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (iface->conf->noscan)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
if (len < IEEE80211_HDRLEN + 2 + sizeof(*bc_ie)) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"Ignore too short 20/40 BSS Coexistence Management frame");
|
||||||
|
@@ -390,6 +393,9 @@ void ht40_intolerant_add(struct hostapd_iface *iface, struct sta_info *sta)
|
||||||
|
if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
|
||||||
|
return;
|
||||||
|
|
||||||
|
+ if (iface->conf->noscan)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
wpa_printf(MSG_INFO, "HT: Forty MHz Intolerant is set by STA " MACSTR
|
||||||
|
" in Association Request", MAC2STR(sta->addr));
|
||||||
|
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
106
patches/999-hostapd-2.10-lar.patch
Normal file
106
patches/999-hostapd-2.10-lar.patch
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
--- a/hostapd/config_file.c
|
||||||
|
+++ b/hostapd/config_file.c
|
||||||
|
@@ -3459,6 +3459,8 @@
|
||||||
|
conf->noscan = atoi(pos);
|
||||||
|
} else if (os_strcmp(buf, "ht_coex") == 0) {
|
||||||
|
conf->no_ht_coex = !atoi(pos);
|
||||||
|
+ } else if (os_strcmp(buf, "intel_lar") == 0) {
|
||||||
|
+ conf->intel_lar = atoi(pos);
|
||||||
|
} else if (os_strcmp(buf, "ieee80211n") == 0) {
|
||||||
|
conf->ieee80211n = atoi(pos);
|
||||||
|
} else if (os_strcmp(buf, "ht_capab") == 0) {
|
||||||
|
--- a/src/ap/ap_config.h
|
||||||
|
+++ b/src/ap/ap_config.h
|
||||||
|
@@ -1050,6 +1050,7 @@
|
||||||
|
u16 ht_capab;
|
||||||
|
int noscan;
|
||||||
|
int no_ht_coex;
|
||||||
|
+ int intel_lar;
|
||||||
|
int ieee80211n;
|
||||||
|
int secondary_channel;
|
||||||
|
int no_pri_sec_switch;
|
||||||
|
--- a/src/ap/hw_features.c
|
||||||
|
+++ b/src/ap/hw_features.c
|
||||||
|
@@ -26,6 +26,17 @@
|
||||||
|
#include "beacon.h"
|
||||||
|
#include "hw_features.h"
|
||||||
|
|
||||||
|
+static void ieee80211n_do_nothing(struct hostapd_iface *iface)
|
||||||
|
+{
|
||||||
|
+ wpa_printf(MSG_DEBUG,
|
||||||
|
+ "Scan finished!");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void ieee80211n_scan_channels_2g4(struct hostapd_iface *iface,
|
||||||
|
+ struct wpa_driver_scan_params *params);
|
||||||
|
+static void ieee80211n_scan_channels_5g(struct hostapd_iface *iface,
|
||||||
|
+ struct wpa_driver_scan_params *params);
|
||||||
|
+
|
||||||
|
|
||||||
|
void hostapd_free_hw_features(struct hostapd_hw_modes *hw_features,
|
||||||
|
size_t num_hw_features)
|
||||||
|
@@ -82,6 +93,33 @@
|
||||||
|
|
||||||
|
if (hostapd_drv_none(hapd))
|
||||||
|
return -1;
|
||||||
|
+
|
||||||
|
+ //if (!iface->conf->noscan) {
|
||||||
|
+ if (iface->conf->intel_lar && !iface->conf->noscan) {
|
||||||
|
+ // scan
|
||||||
|
+ struct wpa_driver_scan_params params;
|
||||||
|
+ int ret1;
|
||||||
|
+
|
||||||
|
+ os_memset(¶ms, 0, sizeof(params));
|
||||||
|
+ ieee80211n_scan_channels_5g(iface, ¶ms);
|
||||||
|
+
|
||||||
|
+ ret1 = hostapd_driver_scan(iface->bss[0], ¶ms);
|
||||||
|
+
|
||||||
|
+ if (ret1 == -EBUSY) {
|
||||||
|
+ wpa_printf(MSG_ERROR,
|
||||||
|
+ "Failed to request a scan of neighboring BSSes ret=%d (%s)!",
|
||||||
|
+ ret1, strerror(-ret1));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (ret1 == 0) {
|
||||||
|
+ iface->scan_cb = ieee80211n_do_nothing;
|
||||||
|
+ wpa_printf(MSG_DEBUG,
|
||||||
|
+ "Sleeping...");
|
||||||
|
+ for (int i=0; i<110; i++) {
|
||||||
|
+ usleep(100000);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
modes = hostapd_get_hw_feature_data(hapd, &num_modes, &flags,
|
||||||
|
&dfs_domain);
|
||||||
|
if (modes == NULL) {
|
||||||
|
|
||||||
|
@@ -308,7 +346,6 @@
|
||||||
|
sec_chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
-
|
||||||
|
static void ieee80211n_check_scan(struct hostapd_iface *iface)
|
||||||
|
{
|
||||||
|
struct wpa_scan_results *scan_res;
|
||||||
|
@@ -517,8 +554,10 @@
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Check that HT40 is used and PRI / SEC switch is allowed */
|
||||||
|
- if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch)
|
||||||
|
+ if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch || iface->conf->noscan) {
|
||||||
|
+ wpa_printf(MSG_DEBUG, "Not scanning due to noscan?");
|
||||||
|
return 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
hostapd_set_state(iface, HAPD_IFACE_HT_SCAN);
|
||||||
|
wpa_printf(MSG_DEBUG, "Scan for neighboring BSSes prior to enabling "
|
||||||
|
@@ -916,7 +954,7 @@
|
||||||
|
if (!hostapd_is_usable_edmg(iface))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- if (!iface->conf->secondary_channel)
|
||||||
|
+ if (!iface->conf->secondary_channel || iface->conf->noscan)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (hostapd_is_usable_chan(iface, iface->freq +
|
||||||
|
|
139
patches/hostapd-2.10-lar.patch
Normal file
139
patches/hostapd-2.10-lar.patch
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
diff -ru a/hostapd/config_file.c b/hostapd/config_file.c
|
||||||
|
--- a/hostapd/config_file.c 2022-01-16 15:51:29.000000000 -0500
|
||||||
|
+++ b/hostapd/config_file.c 2022-07-06 15:58:31.206322430 -0500
|
||||||
|
@@ -2906,6 +2906,8 @@
|
||||||
|
line, bss->wpa_deny_ptk0_rekey);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
+ } else if (os_strcmp(buf, "noscan") == 0) {
|
||||||
|
+ conf->noscan = atoi(pos);
|
||||||
|
} else if (os_strcmp(buf, "wpa_group_update_count") == 0) {
|
||||||
|
char *endp;
|
||||||
|
unsigned long val = strtoul(pos, &endp, 0);
|
||||||
|
@@ -3474,6 +3476,8 @@
|
||||||
|
if (bss->ocv && !bss->ieee80211w)
|
||||||
|
bss->ieee80211w = 1;
|
||||||
|
#endif /* CONFIG_OCV */
|
||||||
|
+ } else if (os_strcmp(buf, "noscan") == 0) {
|
||||||
|
+ conf->noscan = atoi(pos);
|
||||||
|
} else if (os_strcmp(buf, "ieee80211n") == 0) {
|
||||||
|
conf->ieee80211n = atoi(pos);
|
||||||
|
} else if (os_strcmp(buf, "ht_capab") == 0) {
|
||||||
|
diff -ru a/src/ap/ap_config.h b/src/ap/ap_config.h
|
||||||
|
--- a/src/ap/ap_config.h 2022-01-16 15:51:29.000000000 -0500
|
||||||
|
+++ b/src/ap/ap_config.h 2022-07-06 15:58:31.206322430 -0500
|
||||||
|
@@ -1014,6 +1014,7 @@
|
||||||
|
|
||||||
|
int ht_op_mode_fixed;
|
||||||
|
u16 ht_capab;
|
||||||
|
+ int noscan;
|
||||||
|
int ieee80211n;
|
||||||
|
int secondary_channel;
|
||||||
|
int no_pri_sec_switch;
|
||||||
|
diff -ru a/src/ap/hw_features.c b/src/ap/hw_features.c
|
||||||
|
--- a/src/ap/hw_features.c 2022-01-16 15:51:29.000000000 -0500
|
||||||
|
+++ b/src/ap/hw_features.c 2022-07-06 22:57:53.007315518 -0500
|
||||||
|
@@ -24,6 +24,17 @@
|
||||||
|
#include "beacon.h"
|
||||||
|
#include "hw_features.h"
|
||||||
|
|
||||||
|
+static void ieee80211n_do_nothing(struct hostapd_iface *iface)
|
||||||
|
+{
|
||||||
|
+ wpa_printf(MSG_DEBUG,
|
||||||
|
+ "Scan finished!");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void ieee80211n_scan_channels_2g4(struct hostapd_iface *iface,
|
||||||
|
+ struct wpa_driver_scan_params *params);
|
||||||
|
+static void ieee80211n_scan_channels_5g(struct hostapd_iface *iface,
|
||||||
|
+ struct wpa_driver_scan_params *params);
|
||||||
|
+
|
||||||
|
|
||||||
|
void hostapd_free_hw_features(struct hostapd_hw_modes *hw_features,
|
||||||
|
size_t num_hw_features)
|
||||||
|
@@ -82,6 +93,33 @@
|
||||||
|
|
||||||
|
if (hostapd_drv_none(hapd))
|
||||||
|
return -1;
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ // scan
|
||||||
|
+ struct wpa_driver_scan_params params;
|
||||||
|
+ int ret1;
|
||||||
|
+
|
||||||
|
+ os_memset(¶ms, 0, sizeof(params));
|
||||||
|
+ ieee80211n_scan_channels_5g(iface, ¶ms);
|
||||||
|
+
|
||||||
|
+ ret1 = hostapd_driver_scan(iface->bss[0], ¶ms);
|
||||||
|
+
|
||||||
|
+ if (ret1 == -EBUSY) {
|
||||||
|
+ wpa_printf(MSG_ERROR,
|
||||||
|
+ "Failed to request a scan of neighboring BSSes ret=%d (%s)!",
|
||||||
|
+ ret1, strerror(-ret1));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (ret1 == 0) {
|
||||||
|
+ iface->scan_cb = ieee80211n_do_nothing;
|
||||||
|
+ wpa_printf(MSG_DEBUG,
|
||||||
|
+ "Sleeping...");
|
||||||
|
+ for (int i=0; i<110; i++) {
|
||||||
|
+ usleep(100000);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
modes = hostapd_get_hw_feature_data(hapd, &num_modes, &flags,
|
||||||
|
&dfs_domain);
|
||||||
|
if (modes == NULL) {
|
||||||
|
@@ -308,7 +346,6 @@
|
||||||
|
sec_chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
-
|
||||||
|
static void ieee80211n_check_scan(struct hostapd_iface *iface)
|
||||||
|
{
|
||||||
|
struct wpa_scan_results *scan_res;
|
||||||
|
@@ -517,8 +554,10 @@
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Check that HT40 is used and PRI / SEC switch is allowed */
|
||||||
|
- if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch)
|
||||||
|
+ if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch || iface->conf->noscan) {
|
||||||
|
+ wpa_printf(MSG_DEBUG, "Not scanning due to noscan?");
|
||||||
|
return 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
hostapd_set_state(iface, HAPD_IFACE_HT_SCAN);
|
||||||
|
wpa_printf(MSG_DEBUG, "Scan for neighboring BSSes prior to enabling "
|
||||||
|
@@ -915,7 +954,7 @@
|
||||||
|
if (!hostapd_is_usable_edmg(iface))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- if (!iface->conf->secondary_channel)
|
||||||
|
+ if (!iface->conf->secondary_channel || iface->conf->noscan)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (hostapd_is_usable_chan(iface, iface->freq +
|
||||||
|
diff -ru a/src/ap/ieee802_11_ht.c b/src/ap/ieee802_11_ht.c
|
||||||
|
--- a/src/ap/ieee802_11_ht.c 2022-01-16 15:51:29.000000000 -0500
|
||||||
|
+++ b/src/ap/ieee802_11_ht.c 2022-07-06 15:58:31.206322430 -0500
|
||||||
|
@@ -230,6 +230,9 @@
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (iface->conf->noscan)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
if (len < IEEE80211_HDRLEN + 2 + sizeof(*bc_ie)) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"Ignore too short 20/40 BSS Coexistence Management frame");
|
||||||
|
@@ -390,6 +393,9 @@
|
||||||
|
if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
|
||||||
|
return;
|
||||||
|
|
||||||
|
+ if (iface->conf->noscan)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
wpa_printf(MSG_INFO, "HT: Forty MHz Intolerant is set by STA " MACSTR
|
||||||
|
" in Association Request", MAC2STR(sta->addr));
|
||||||
|
|
Loading…
Reference in a new issue