ntopng and adguard now work

This commit is contained in:
Stefan Kempinger 2026-01-20 00:47:36 +01:00
parent 2db9235ad0
commit f9c6cf6f55
3 changed files with 71 additions and 556 deletions

View file

@ -1,538 +0,0 @@
# Auto-generated by compose2nix.
{ pkgs, lib, config, ... }:
{
# Runtime
virtualisation.podman = {
enable = true;
autoPrune.enable = true;
dockerCompat = true;
};
# Enable container name DNS for all Podman networks.
networking.firewall.interfaces = let
matchAll = if !config.networking.nftables.enable then "podman+" else "podman*";
in {
"${matchAll}".allowedUDPPorts = [ 53 ];
};
virtualisation.oci-containers.backend = "podman";
# Containers
virtualisation.oci-containers.containers."akvoado-akvorado-console" = {
image = "ghcr.io/akvorado/akvorado:2.1.1";
environment = {
"AKVORADO_CFG_CONSOLE_BRANDING" = "false";
"AKVORADO_CFG_CONSOLE_DATABASE_DSN" = "/run/akvorado/console.sqlite";
};
volumes = [
"akvoado_akvorado-console-db:/run/akvorado:rw"
];
cmd = [ "console" "http://akvorado-orchestrator:8080" ];
labels = {
"metrics.path" = "/api/v0/metrics";
"metrics.port" = "8080";
"traefik.enable" = "true";
"traefik.http.middlewares.console-auth.headers.customrequestheaders.Remote-Email" = "alfred@example.com";
"traefik.http.middlewares.console-auth.headers.customrequestheaders.Remote-Name" = "Alfred Pennyworth";
"traefik.http.middlewares.console-auth.headers.customrequestheaders.Remote-User" = "alfred";
"traefik.http.routers.akvorado-console-debug.entrypoints" = "private";
"traefik.http.routers.akvorado-console-debug.rule" = "PathPrefix(`/debug`)";
"traefik.http.routers.akvorado-console-debug.service" = "akvorado-console";
"traefik.http.routers.akvorado-console-metrics.observability.accesslogs" = "false";
"traefik.http.routers.akvorado-console-metrics.rule" = "PathPrefix(`/api/v0/console/metrics`)";
"traefik.http.routers.akvorado-console-metrics.service" = "akvorado-console";
"traefik.http.routers.akvorado-console.middlewares" = "console-auth";
"traefik.http.routers.akvorado-console.priority" = "1";
"traefik.http.routers.akvorado-console.rule" = "!PathPrefix(`/debug`)";
"traefik.http.services.akvorado-console.loadbalancer.server.port" = "8080";
};
dependsOn = [
"akvoado-akvorado-orchestrator"
"akvoado-clickhouse"
"akvoado-redis"
];
log-driver = "journald";
extraOptions = [
"--network-alias=akvorado-console"
"--network=akvoado_default"
];
};
systemd.services."podman-akvoado-akvorado-console" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
};
after = [
"podman-network-akvoado_default.service"
"podman-volume-akvoado_akvorado-console-db.service"
];
requires = [
"podman-network-akvoado_default.service"
"podman-volume-akvoado_akvorado-console-db.service"
];
partOf = [
"podman-compose-akvoado-root.target"
];
wantedBy = [
"podman-compose-akvoado-root.target"
];
};
virtualisation.oci-containers.containers."akvoado-akvorado-inlet" = {
image = "ghcr.io/akvorado/akvorado:2.1.1";
volumes = [
"akvoado_akvorado-run:/run/akvorado:rw"
];
ports = [
"2055:2055/udp"
"4739:4739/udp"
"6343:6343/udp"
];
cmd = [ "inlet" "http://akvorado-orchestrator:8080" ];
labels = {
"metrics.path" = "/api/v0/metrics";
"metrics.port" = "8080";
"traefik.enable" = "true";
"traefik.http.routers.akvorado-inlet-metrics.observability.accesslogs" = "false";
"traefik.http.routers.akvorado-inlet-metrics.rule" = "PathPrefix(`/api/v0/inlet/metrics`)";
"traefik.http.routers.akvorado-inlet-metrics.service" = "akvorado-inlet";
"traefik.http.routers.akvorado-inlet.entrypoints" = "private";
"traefik.http.routers.akvorado-inlet.rule" = "PathPrefix(`/api/v0/inlet`)";
"traefik.http.services.akvorado-inlet.loadbalancer.server.port" = "8080";
};
dependsOn = [
"akvoado-akvorado-orchestrator"
"akvoado-kafka"
];
log-driver = "journald";
extraOptions = [
"--network-alias=akvorado-inlet"
"--network=akvoado_default"
];
};
systemd.services."podman-akvoado-akvorado-inlet" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
};
after = [
"podman-network-akvoado_default.service"
"podman-volume-akvoado_akvorado-run.service"
];
requires = [
"podman-network-akvoado_default.service"
"podman-volume-akvoado_akvorado-run.service"
];
partOf = [
"podman-compose-akvoado-root.target"
];
wantedBy = [
"podman-compose-akvoado-root.target"
];
};
virtualisation.oci-containers.containers."akvoado-akvorado-orchestrator" = {
image = "ghcr.io/akvorado/akvorado:2.1.1";
volumes = [
"/root/akvorado/config:/etc/akvorado:ro"
"akvoado_akvorado-geoip:/usr/share/GeoIP:ro"
];
cmd = [ "orchestrator" "/etc/akvorado/akvorado.yaml" ];
labels = {
"metrics.path" = "/api/v0/metrics";
"metrics.port" = "8080";
"traefik.enable" = "true";
"traefik.http.routers.akvorado-orchestrator-metrics.observability.accesslogs" = "false";
"traefik.http.routers.akvorado-orchestrator-metrics.rule" = "PathPrefix(`/api/v0/orchestrator/metrics`)";
"traefik.http.routers.akvorado-orchestrator-metrics.service" = "akvorado-orchestrator";
"traefik.http.routers.akvorado-orchestrator.entrypoints" = "private";
"traefik.http.routers.akvorado-orchestrator.rule" = "PathPrefix(`/api/v0/orchestrator`)";
"traefik.http.services.akvorado-orchestrator.loadbalancer.server.port" = "8080";
};
dependsOn = [
"akvoado-kafka"
];
log-driver = "journald";
extraOptions = [
"--network-alias=akvorado-orchestrator"
"--network=akvoado_default"
];
};
systemd.services."podman-akvoado-akvorado-orchestrator" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
};
after = [
"podman-network-akvoado_default.service"
"podman-volume-akvoado_akvorado-geoip.service"
];
requires = [
"podman-network-akvoado_default.service"
"podman-volume-akvoado_akvorado-geoip.service"
];
partOf = [
"podman-compose-akvoado-root.target"
];
wantedBy = [
"podman-compose-akvoado-root.target"
];
};
virtualisation.oci-containers.containers."akvoado-akvorado-outlet" = {
image = "ghcr.io/akvorado/akvorado:2.1.1";
environment = {
"AKVORADO_CFG_OUTLET_FLOW_STATEPERSISTFILE" = "/run/akvorado/flow.state";
"AKVORADO_CFG_OUTLET_METADATA_CACHEPERSISTFILE" = "/run/akvorado/metadata.cache";
};
volumes = [
"akvoado_akvorado-run:/run/akvorado:rw"
];
ports = [
"10179:10179/tcp"
];
cmd = [ "outlet" "http://akvorado-orchestrator:8080" ];
labels = {
"metrics.path" = "/api/v0/metrics";
"metrics.port" = "8080";
"traefik.enable" = "true";
"traefik.http.routers.akvorado-outlet-metrics.observability.accesslogs" = "false";
"traefik.http.routers.akvorado-outlet-metrics.rule" = "PathPrefix(`/api/v0/outlet/metrics`)";
"traefik.http.routers.akvorado-outlet-metrics.service" = "akvorado-outlet";
"traefik.http.routers.akvorado-outlet.entrypoints" = "private";
"traefik.http.routers.akvorado-outlet.rule" = "PathPrefix(`/api/v0/outlet`)";
"traefik.http.services.akvorado-outlet.loadbalancer.server.port" = "8080";
};
dependsOn = [
"akvoado-akvorado-orchestrator"
"akvoado-clickhouse"
"akvoado-kafka"
];
log-driver = "journald";
extraOptions = [
"--network-alias=akvorado-outlet"
"--network=akvoado_default"
];
};
systemd.services."podman-akvoado-akvorado-outlet" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
};
after = [
"podman-network-akvoado_default.service"
"podman-volume-akvoado_akvorado-run.service"
];
requires = [
"podman-network-akvoado_default.service"
"podman-volume-akvoado_akvorado-run.service"
];
partOf = [
"podman-compose-akvoado-root.target"
];
wantedBy = [
"podman-compose-akvoado-root.target"
];
};
virtualisation.oci-containers.containers."akvoado-clickhouse" = {
image = "clickhouse/clickhouse-server:25.8";
environment = {
"CLICKHOUSE_INIT_TIMEOUT" = "60";
"CLICKHOUSE_SKIP_USER_SETUP" = "1";
};
volumes = [
"/root/akvorado/docker/clickhouse/observability.xml:/etc/clickhouse-server/config.d/observability.xml:rw"
"/root/akvorado/docker/clickhouse/server.xml:/etc/clickhouse-server/config.d/akvorado.xml:rw"
"akvoado_akvorado-clickhouse:/var/lib/clickhouse:rw"
];
labels = {
"metrics.port" = "8123";
"traefik.enable" = "true";
"traefik.http.middlewares.clickhouse-strip.stripprefix.prefixes" = "/clickhouse";
"traefik.http.routers.clickhouse.entrypoints" = "private";
"traefik.http.routers.clickhouse.middlewares" = "clickhouse-strip";
"traefik.http.routers.clickhouse.rule" = "PathPrefix(`/clickhouse`)";
};
log-driver = "journald";
extraOptions = [
"--cap-add=SYS_NICE"
"--health-cmd=[\"wget\", \"-T\", \"1\", \"--spider\", \"--no-proxy\", \"http://127.0.0.1:8123/ping\"]"
"--health-interval=20s"
"--network-alias=clickhouse"
"--network=akvoado_default"
];
};
systemd.services."podman-akvoado-clickhouse" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
};
after = [
"podman-network-akvoado_default.service"
"podman-volume-akvoado_akvorado-clickhouse.service"
];
requires = [
"podman-network-akvoado_default.service"
"podman-volume-akvoado_akvorado-clickhouse.service"
];
partOf = [
"podman-compose-akvoado-root.target"
];
wantedBy = [
"podman-compose-akvoado-root.target"
];
};
virtualisation.oci-containers.containers."akvoado-kafka" = {
image = "apache/kafka:4.1.1";
environment = {
"KAFKA_ADVERTISED_LISTENERS" = "CLIENT://kafka:9092";
"KAFKA_CONTROLLER_LISTENER_NAMES" = "CONTROLLER";
"KAFKA_CONTROLLER_QUORUM_VOTERS" = "1@kafka:9093";
"KAFKA_DELETE_TOPIC_ENABLE" = "true";
"KAFKA_INTER_BROKER_LISTENER_NAME" = "CLIENT";
"KAFKA_LISTENERS" = "CLIENT://:9092,CONTROLLER://:9093";
"KAFKA_LISTENER_SECURITY_PROTOCOL_MAP" = "CLIENT:PLAINTEXT,CONTROLLER:PLAINTEXT";
"KAFKA_LOG_DIRS" = "/var/lib/kafka/data";
"KAFKA_NODE_ID" = "1";
"KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR" = "1";
"KAFKA_PROCESS_ROLES" = "controller,broker";
"KAFKA_SHARE_COORDINATOR_STATE_TOPIC_MIN_ISR" = "1";
"KAFKA_SHARE_COORDINATOR_STATE_TOPIC_REPLICATION_FACTOR" = "1";
"KAFKA_TRANSACTION_STATE_LOG_MIN_ISR" = "1";
"KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR" = "1";
};
volumes = [
"akvoado_akvorado-kafka:/var/lib/kafka/data:rw"
];
log-driver = "journald";
extraOptions = [
"--health-cmd=[\"/opt/kafka/bin/kafka-topics.sh\", \"--list\", \"--bootstrap-server\", \"kafka:9092\"]"
"--health-interval=20s"
"--network-alias=kafka"
"--network=akvoado_default"
];
};
systemd.services."podman-akvoado-kafka" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
};
after = [
"podman-network-akvoado_default.service"
"podman-volume-akvoado_akvorado-kafka.service"
];
requires = [
"podman-network-akvoado_default.service"
"podman-volume-akvoado_akvorado-kafka.service"
];
partOf = [
"podman-compose-akvoado-root.target"
];
wantedBy = [
"podman-compose-akvoado-root.target"
];
};
virtualisation.oci-containers.containers."akvoado-kafka-ui" = {
image = "ghcr.io/kafbat/kafka-ui:v1.4.2";
environment = {
"KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS" = "kafka:9092";
"KAFKA_CLUSTERS_0_NAME" = "local";
"KAFKA_CLUSTERS_0_READONLY" = "true";
"SERVER_SERVLET_CONTEXT_PATH" = "/kafka-ui";
};
labels = {
"traefik.enable" = "true";
"traefik.http.routers.kafka-ui.rule" = "PathPrefix(`/kafka-ui`)";
};
dependsOn = [
"akvoado-kafka"
];
log-driver = "journald";
extraOptions = [
"--network-alias=kafka-ui"
"--network=akvoado_default"
];
};
systemd.services."podman-akvoado-kafka-ui" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
};
after = [
"podman-network-akvoado_default.service"
];
requires = [
"podman-network-akvoado_default.service"
];
partOf = [
"podman-compose-akvoado-root.target"
];
wantedBy = [
"podman-compose-akvoado-root.target"
];
};
virtualisation.oci-containers.containers."akvoado-redis" = {
image = "valkey/valkey:7.2";
log-driver = "journald";
extraOptions = [
"--health-cmd=timeout 3 redis-cli ping | grep -q PONG"
"--health-interval=20s"
"--network-alias=redis"
"--network=akvoado_default"
];
};
systemd.services."podman-akvoado-redis" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
};
after = [
"podman-network-akvoado_default.service"
];
requires = [
"podman-network-akvoado_default.service"
];
partOf = [
"podman-compose-akvoado-root.target"
];
wantedBy = [
"podman-compose-akvoado-root.target"
];
};
virtualisation.oci-containers.containers."akvoado-traefik" = {
image = "traefik:v3.6";
environment = {
"TRAEFIK_ACCESSLOG" = "true";
"TRAEFIK_API" = "true";
"TRAEFIK_API_BASEPATH" = "/traefik";
"TRAEFIK_ENTRYPOINTS_private_ADDRESS" = ":8080";
"TRAEFIK_ENTRYPOINTS_private_HTTP_MIDDLEWARES" = "compress@docker";
"TRAEFIK_ENTRYPOINTS_public_ADDRESS" = ":8081";
"TRAEFIK_ENTRYPOINTS_public_HTTP_MIDDLEWARES" = "compress@docker";
"TRAEFIK_METRICS_PROMETHEUS" = "true";
"TRAEFIK_METRICS_PROMETHEUS_ADDROUTERSLABELS" = "true";
"TRAEFIK_METRICS_PROMETHEUS_MANUALROUTING" = "true";
"TRAEFIK_PROVIDERS_DOCKER" = "true";
"TRAEFIK_PROVIDERS_DOCKER_EXPOSEDBYDEFAULT" = "false";
};
volumes = [
"/var/run/docker.sock:/var/run/docker.sock:ro"
];
ports = [
"127.0.0.1:8080:8080/tcp"
"8081:8081/tcp"
];
labels = {
"metrics.path" = "/traefik/metrics";
"metrics.port" = "8080";
"traefik.enable" = "true";
"traefik.http.middlewares.compress.compress" = "true";
"traefik.http.middlewares.compress.compress.includedcontenttypes" = "application/javascript,application/json,application/xml,image/svg+xml,text/css,text/csv,text/javascript,text/markdown,text/plain,text/xml";
"traefik.http.routers.traefik-metrics.priority" = "200";
"traefik.http.routers.traefik-metrics.rule" = "PathPrefix(`/traefik/metrics`)";
"traefik.http.routers.traefik-metrics.service" = "prometheus@internal";
"traefik.http.routers.traefik.rule" = "PathPrefix(`/traefik`) && !PathPrefix(`/traefik/debug`)";
"traefik.http.routers.traefik.service" = "api@internal";
};
log-driver = "journald";
extraOptions = [
"--network-alias=traefik"
"--network=akvoado_default"
];
};
systemd.services."podman-akvoado-traefik" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
};
after = [
"podman-network-akvoado_default.service"
];
requires = [
"podman-network-akvoado_default.service"
];
partOf = [
"podman-compose-akvoado-root.target"
];
wantedBy = [
"podman-compose-akvoado-root.target"
];
};
# Networks
systemd.services."podman-network-akvoado_default" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStop = "podman network rm -f akvoado_default";
};
script = ''
podman network inspect akvoado_default || podman network create akvoado_default --driver=bridge --opt=com.docker.network.bridge.name=br-akvorado --subnet=247.16.14.0/24 --subnet=fd1c:8ce3:6fb:1::/64 --ipv6
'';
partOf = [ "podman-compose-akvoado-root.target" ];
wantedBy = [ "podman-compose-akvoado-root.target" ];
};
# Volumes
systemd.services."podman-volume-akvoado_akvorado-clickhouse" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
podman volume inspect akvoado_akvorado-clickhouse || podman volume create akvoado_akvorado-clickhouse
'';
partOf = [ "podman-compose-akvoado-root.target" ];
wantedBy = [ "podman-compose-akvoado-root.target" ];
};
systemd.services."podman-volume-akvoado_akvorado-console-db" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
podman volume inspect akvoado_akvorado-console-db || podman volume create akvoado_akvorado-console-db
'';
partOf = [ "podman-compose-akvoado-root.target" ];
wantedBy = [ "podman-compose-akvoado-root.target" ];
};
systemd.services."podman-volume-akvoado_akvorado-geoip" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
podman volume inspect akvoado_akvorado-geoip || podman volume create akvoado_akvorado-geoip
'';
partOf = [ "podman-compose-akvoado-root.target" ];
wantedBy = [ "podman-compose-akvoado-root.target" ];
};
systemd.services."podman-volume-akvoado_akvorado-kafka" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
podman volume inspect akvoado_akvorado-kafka || podman volume create akvoado_akvorado-kafka
'';
partOf = [ "podman-compose-akvoado-root.target" ];
wantedBy = [ "podman-compose-akvoado-root.target" ];
};
systemd.services."podman-volume-akvoado_akvorado-run" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
podman volume inspect akvoado_akvorado-run || podman volume create akvoado_akvorado-run
'';
partOf = [ "podman-compose-akvoado-root.target" ];
wantedBy = [ "podman-compose-akvoado-root.target" ];
};
# Root service
# When started, this will automatically create all resources and start
# the containers. When stopped, this will teardown all resources.
systemd.targets."podman-compose-akvoado-root" = {
unitConfig = {
Description = "Root target generated by compose2nix.";
};
wantedBy = [ "multi-user.target" ];
};
}

View file

@ -14,7 +14,6 @@
imports = [
# Include the results of the hardware scan.
./hardware-configuration.nix
./akvorado.nix
specialArgs.inputs.vscode-server.nixosModules.default
];
@ -56,17 +55,15 @@
}
];
networking.defaultGateway = "192.168.69.1";
networking.nameservers = [ "1.1.1.1" ];
#networking.nameservers = [ "1.1.1.1" ];
networking.firewall.enable = true;
networking.firewall.allowedTCPPorts = [
22
53
80
443
2222 # forgejo ssh
3000 # forgejo frontend
2055 # akvorado sink
8080 # akvorado frontend
8081 # akvorado frontend
8184 # forgejo frontend
8123 # homeassistant
5580 # homeassistant matter
2283 # immich
@ -75,9 +72,14 @@
8971 # frigate
8554 # frigate rtsp
8555 # frigate rtsp
2055 # ntopng sink
8182 # ntopng frontend
3000 # adguardhome frontend
8183 # adguardhome frontend
9000
];
networking.firewall.allowedUDPPorts = [
53
8555 # frigate rtsp
2055 # ntopng sink
];
@ -134,7 +136,9 @@
certs."kempinger.at".domain = "*.kempinger.at";
};
services.resolved.enable = true;
#services.resolved.enable = true;
services.fail2ban.enable = true;
services.nginx = {
enable = true;
@ -193,7 +197,7 @@
DOMAIN = "git.kempinger.at";
# You need to specify this to remove the port from URLs in the web UI.
ROOT_URL = "https://${config.services.forgejo.settings.server.DOMAIN}/";
HTTP_PORT = 3000;
HTTP_PORT = 8184;
DISABLE_SSH = false;
SSH_PORT = 2222;
START_SSH_SERVER = true;
@ -235,6 +239,12 @@
# };
# };
services.immich = {
enable = true;
accelerationDevices = null;
port = 2283;
};
services.borgbackup.jobs."immich" = {
paths = config.services.immich.mediaLocation;
repo = "/backup/immich";
@ -298,7 +308,6 @@
];
};
containers.frigate = {
#autoStart = true;
volumes = [
@ -327,14 +336,58 @@
"--network=host"
];
};
containers.netflow2ng = {
# Note: The image will not be updated on rebuilds, unless the version label changes
image = "synfinatic/netflow2ng:v0.1.0";
cmd = [
"-a"
"0.0.0.0:2055"
"-m"
"0.0.0.0:8181"
"-z"
"tcp://127.0.0.1:5556"
"--log-level"
"debug"
"--tlv"
];
extraOptions = [
"--network=host"
];
};
};
services.immich = {
services.ntopng = {
enable = true;
accelerationDevices = null;
port = 2283;
#host = "immich.kempinger.at";
#openFirewall = true;
httpPort = 8182;
interfaces = [ "tcp://0.0.0.0:5556" ];
extraConfig = ''
--dns-mode 1
--local-networks "185.27.122.0/24=WAN,192.168.69.0/24=LAN"'';
};
services.influxdb.enable = true;
services.geoipupdate = {
enable = true;
settings = {
AccountID = 1284637;
DatabaseDirectory = "/var/lib/GeoIP";
LicenseKey = {
_secret = "/root/maxmind_license_key";
};
EditionIDs = [
"GeoLite2-ASN"
"GeoLite2-City"
"GeoLite2-Country"
];
};
};
services.adguardhome = {
enable = true;
# You can select any ip and port, just make sure to open firewalls where needed
host = "0.0.0.0";
port = 8183;
};
# Nix settings

6
flake.lock generated
View file

@ -20,11 +20,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1766651565,
"narHash": "sha256-QEhk0eXgyIqTpJ/ehZKg9IKS7EtlWxF3N7DXy42zPfU=",
"lastModified": 1768564909,
"narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "3e2499d5539c16d0d173ba53552a4ff8547f4539",
"rev": "e4bae1bd10c9c57b2cf517953ab70060a828ee6f",
"type": "github"
},
"original": {