Files
nix-config/hosts/idols-aquamarine/monitoring/victoriametrics.nix
T
ryan4yin | 二花 21d64e7add security: hardening pass 1 (AppArmor, firewall default, loopback metrics, k3s perms, SSH X11) (#266)
* security: make firewall secure-by-default, disable explicitly on servers

Flip the base firewall default to ON so new hosts are protected by default. Servers keep the firewall off (trusted internal LAN, WAN protected at the router) via explicit overrides in modules/nixos/server/{server,server-aarch64}.nix. Behavior-preserving for all 18 current hosts; adds a security-firewall eval test guarding the per-host state.

* test: fix security-firewall eval test to scalar per-host values

* security: enable AppArmor (complain) on all Linux hosts

* security: bind aquamarine metrics exporters to loopback

* security: restrict k3s kubeconfig file mode to 600

* security: disable SSH X11 forwarding on servers, keep on desktops

* security: add conservative systemd hardening to aquamarine services

* docs(apparmor): correct FHS-alias comment (nixpkgs has no broad FHS layer)

nixpkgs only creates /run/current-system, /usr/bin/env and /bin/sh; it does not
provide a broad FHS->store alias tree, so FHS-oriented abstractions are incomplete
on NixOS. They are safe only because the profiles run in complain mode.

* fix(aquamarine): scrape same-host exporters over loopback

The v2ray/postgres/sftpgo exporters were bound to 127.0.0.1 but VictoriaMetrics
scraped them via the host's routable IP, so those scrapes refused connections.
Point the three same-host scrape targets at 127.0.0.1 (VM runs on the same host).
node-exporter keeps the host IP since it binds 0.0.0.0.

* Revert "security: add conservative systemd hardening to aquamarine services"

This reverts commit f9cf99dadb.
2026-08-27 00:13:01 +08:00

207 lines
6.3 KiB
Nix

{
lib,
myvars,
...
}:
let
# Powered-off hosts (SBCs, k3s-prod-1) plus shoukei (exporter disabled on the
# machine); remove entries when they come back online.
offlineHosts = [
"shoukei"
"suzu"
"suzi"
"yukina"
"nozomi"
"chiaya"
"rakushun"
"mitsuha"
"k3s-prod-1-master-1"
"k3s-prod-1-master-2"
"k3s-prod-1-master-3"
"k3s-prod-1-worker-1"
"k3s-prod-1-worker-2"
"k3s-prod-1-worker-3"
];
in
{
# Since victoriametrics use DynamicUser, the user & group do not exists before the service starts.
# this group is used as a supplementary Unix group for the service to access our data dir(/data/apps/xxx)
users.groups.victoriametrics-data = { };
# Workaround for victoriametrics to store data in another place
# https://www.freedesktop.org/software/systemd/man/latest/tmpfiles.d.html#Type
systemd.tmpfiles.rules = [
"d /data/apps/victoriametrics 0770 root victoriametrics-data - -"
];
# Symlinks do not work with DynamicUser, so we should use bind mount here.
# https://github.com/systemd/systemd/issues/25097#issuecomment-1929074961
systemd.services.victoriametrics.serviceConfig = {
SupplementaryGroups = [ "victoriametrics-data" ];
BindPaths = [ "/data/apps/victoriametrics:/var/lib/victoriametrics:rbind" ];
};
# https://victoriametrics.io/docs/victoriametrics/latest/configuration/configuration/
services.victoriametrics = {
enable = true;
listenAddress = "127.0.0.1:9090";
retentionPeriod = "30d";
extraOptions = [
# Allowed percent of system memory VictoriaMetrics caches may occupy.
"-memory.allowedPercent=50"
];
# Directory below /var/lib to store victoriametrics metrics data.
stateDir = "victoriametrics";
# specifies a set of targets and parameters describing how to scrape metrics from them.
# https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config
prometheusConfig = {
scrape_configs = [
# --- Homelab Applications --- #
# suzi is powered off, disable scraping until it comes back online.
/*
{
job_name = "dnsmasq-exporter";
scrape_interval = "30s";
metrics_path = "/metrics";
static_configs = [
{
targets = [ "${myvars.networking.hostsAddr.suzi.ipv4}:9153" ];
labels.type = "app";
labels.app = "dnsmasq";
labels.host = "suzi";
labels.env = "homelab";
labels.cluster = "homelab";
}
];
}
*/
{
job_name = "v2ray-exporter";
scrape_interval = "30s";
metrics_path = "/metrics";
static_configs = [
{
# same-host exporter bound to loopback (127.0.0.1:9153)
targets = [ "127.0.0.1:9153" ];
labels.type = "app";
labels.app = "v2ray";
labels.host = "aquamarine";
labels.env = "homelab";
labels.cluster = "homelab";
}
];
}
{
job_name = "nut-exporter-homelab-ups";
scrape_interval = "30s";
metrics_path = "/ups_metrics";
params.ups = [ "homelab" ];
static_configs = [
{
targets = [ "${myvars.networking.hostsAddr.kubevirt-shushou.ipv4}:9199" ];
labels.type = "app";
labels.app = "nut";
labels.host = "kubevirt-shushou";
labels.env = "homelab";
labels.cluster = "homelab";
}
];
}
{
job_name = "postgres-exporter";
scrape_interval = "30s";
metrics_path = "/metrics";
static_configs = [
{
# same-host exporter bound to loopback (127.0.0.1:9187)
targets = [ "127.0.0.1:9187" ];
labels.type = "app";
labels.app = "postgresql";
labels.host = "aquamarine";
labels.env = "homelab";
labels.cluster = "homelab";
}
];
}
{
job_name = "sftpgo-embedded-exporter";
scrape_interval = "30s";
metrics_path = "/metrics";
static_configs = [
{
# same-host exporter bound to loopback (127.0.0.1:10000)
targets = [ "127.0.0.1:10000" ];
labels.type = "app";
labels.app = "sftpgo";
labels.host = "aquamarine";
labels.env = "homelab";
labels.cluster = "homelab";
}
];
}
{
job_name = "alertmanager-embedded-exporter";
scrape_interval = "30s";
metrics_path = "/metrics";
static_configs = [
{
targets = [ "localhost:9093" ];
labels.type = "app";
labels.app = "alertmanager";
labels.host = "aquamarine";
labels.env = "homelab";
labels.cluster = "homelab";
}
];
}
{
job_name = "victoriametrics-embedded-exporter";
scrape_interval = "30s";
metrics_path = "/metrics";
static_configs = [
{
# scrape vm itself
targets = [ "localhost:9090" ];
labels.type = "app";
labels.app = "victoriametrics";
labels.host = "aquamarine";
labels.env = "homelab";
labels.cluster = "homelab";
}
];
}
]
# --- Hosts --- #
++ (lib.attrsets.foldlAttrs
(
acc: hostname: addr:
acc
++ [
{
job_name = "node-exporter-${hostname}";
scrape_interval = "30s";
metrics_path = "/metrics";
static_configs = [
{
# All my NixOS hosts.
targets = [ "${addr.ipv4}:9100" ];
labels.type = "node";
labels.host = hostname;
labels.env = "homelab";
labels.cluster = "homelab";
}
];
}
]
)
[ ]
(lib.attrsets.filterAttrs (n: _: !(builtins.elem n offlineHosts)) myvars.networking.hostsAddr)
);
};
};
}