mirror of
https://git.sr.ht/~magic_rb/dotfiles
synced 2024-11-21 23:54:22 +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": {
|
||||
"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": {
|
||||
"inputs": {
|
||||
"nix": "nix",
|
||||
|
@ -40,6 +59,37 @@
|
|||
}
|
||||
},
|
||||
"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,
|
||||
"locked": {
|
||||
"lastModified": 1673956053,
|
||||
|
@ -55,7 +105,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat_2": {
|
||||
"flake-compat_4": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1673956053,
|
||||
|
@ -126,6 +176,20 @@
|
|||
}
|
||||
},
|
||||
"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": {
|
||||
"systems": "systems_2"
|
||||
},
|
||||
|
@ -143,7 +207,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_3": {
|
||||
"flake-utils_4": {
|
||||
"locked": {
|
||||
"lastModified": 1667395993,
|
||||
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
||||
|
@ -180,6 +244,22 @@
|
|||
"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": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
|
@ -231,6 +311,22 @@
|
|||
"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": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
|
@ -270,6 +366,24 @@
|
|||
"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": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_4"
|
||||
|
@ -406,6 +520,19 @@
|
|||
"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": {
|
||||
"locked": {
|
||||
"lastModified": 1684570954,
|
||||
|
@ -488,11 +615,43 @@
|
|||
},
|
||||
"nixpkgs_7": {
|
||||
"locked": {
|
||||
"lastModified": 1676569297,
|
||||
"narHash": "sha256-2n4C4H3/U+3YbDrQB6xIw7AaLdFISCCFwOkcETAigqU=",
|
||||
"path": "/nix/store/qhj65h4klgmnkblfly0apznnl3qdir6x-source",
|
||||
"rev": "ac1f5b72a9e95873d1de0233fddcb56f99884b37",
|
||||
"type": "path"
|
||||
"lastModified": 1648219316,
|
||||
"narHash": "sha256-Ctij+dOi0ZZIfX5eMhgwugfvB+WZSrvVNAyAuANOsnQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"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": {
|
||||
"id": "nixpkgs",
|
||||
|
@ -501,8 +660,8 @@
|
|||
},
|
||||
"pre-commit-hooks": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat_2",
|
||||
"flake-utils": "flake-utils_3",
|
||||
"flake-compat": "flake-compat_4",
|
||||
"flake-utils": "flake-utils_4",
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": [
|
||||
"tuxedo-rs",
|
||||
|
@ -537,6 +696,7 @@
|
|||
"nixpkgs": "nixpkgs_6",
|
||||
"nixpkgs-hashicorp": "nixpkgs-hashicorp",
|
||||
"secret": "secret",
|
||||
"serokell-nix": "serokell-nix",
|
||||
"tuxedo-nixos": "tuxedo-nixos",
|
||||
"tuxedo-rs": "tuxedo-rs",
|
||||
"udp-over-tcp": "udp-over-tcp",
|
||||
|
@ -582,6 +742,30 @@
|
|||
"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": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
|
@ -630,7 +814,7 @@
|
|||
},
|
||||
"tuxedo-nixos": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"flake-compat": "flake-compat_3",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
|
@ -651,7 +835,7 @@
|
|||
},
|
||||
"tuxedo-rs": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils_2",
|
||||
"flake-utils": "flake-utils_3",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
|
@ -690,7 +874,7 @@
|
|||
"uterranix": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts_2",
|
||||
"nixpkgs": "nixpkgs_7",
|
||||
"nixpkgs": "nixpkgs_10",
|
||||
"terranix": "terranix"
|
||||
},
|
||||
"locked": {
|
||||
|
@ -704,6 +888,21 @@
|
|||
"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": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
|
|
10
flake.nix
10
flake.nix
|
@ -12,6 +12,7 @@
|
|||
nil.url = "github:oxalica/nil";
|
||||
uterranix.url = "path:///home/main/uterranix";
|
||||
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.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
@ -42,6 +43,7 @@
|
|||
nixos/systems/heater
|
||||
nixos/systems/toothpick
|
||||
nixos/systems/liveusb
|
||||
nixos/systems/blowhole
|
||||
|
||||
overlays/udp-over-tcp.nix
|
||||
overlays/emacsclient-remote
|
||||
|
@ -49,10 +51,15 @@
|
|||
overlays/emacs-rofi
|
||||
overlays/tree-sitter-grammars.nix
|
||||
overlays/emacs-master-nativecomp
|
||||
overlays/zfs-relmount
|
||||
overlays/ical2org.nix
|
||||
];
|
||||
|
||||
flake.nixosModules = {
|
||||
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: {
|
||||
|
@ -62,6 +69,9 @@
|
|||
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.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 = [
|
||||
|
|
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.finegrained = true;
|
||||
|
||||
prime.reverseSync.enable = true;
|
||||
prime.reverseSync.enable = false;
|
||||
prime.offload.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