feat: add dns container with AGH + unbound

This commit is contained in:
Xavier Morel
2025-10-23 22:13:43 +02:00
parent 0d343b12a3
commit 16b9271caf
6 changed files with 210 additions and 2 deletions

4
.gitignore vendored
View File

@@ -15,5 +15,5 @@ config.tf.json
nixos-template nixos-template
# Possibly sensitive for public repo # Possibly sensitive for public repo
infra/ips.nix lib/ips.nix
infra/constants.nix lib/constants.nix

41
lxc/dns.nix Normal file
View File

@@ -0,0 +1,41 @@
{
pkgs,
name,
containersMapping,
...
}:
let
hostname = pkgs.lib.removeSuffix ".nix" name;
infra = import ../lib/constants.nix;
container_id = containersMapping.${hostname};
ip = infra.build_ip container_id;
domainname = "${hostname}${infra.domains.internal}";
in
{
cores = 2;
memory = "2G";
disk = "4G";
swap = 512;
ports = [
80
53
12345
];
exposed = false;
services = {
adguardhome = import ./dns/adguardhome-config.nix { inherit infra ip domainname; };
unbound = {
enable = true;
};
};
logging.enable = true;
logging.metrics.enable = true;
etc."alloy/logs-adguard.alloy".text =
(import ./dns/logs-adguard.alloy.nix {
inherit ip domainname;
}).out;
etc."alloy/logs-unbound.alloy".text =
(import ./dns/logs-unbound.alloy.nix {
inherit ip domainname;
}).out;
}

View File

@@ -0,0 +1,74 @@
{
infra,
ip,
domainname,
...
}:
{
enable = true;
host = "0.0.0.0";
port = 80;
openFirewall = true;
mutableSettings = true;
settings = {
http = {
address = "${ip}:80";
session_ttl = "720h";
};
users = [
{
name = infra.master_login;
password = infra.master_htpasswd;
}
];
filters = [
{
enabled = true;
url = "https://adguardteam.github.io/HostlistsRegistry/assets/filter_1.txt";
name = "AdGuard DNS filter";
id = 1;
}
{
enabled = true;
url = "https://adguardteam.github.io/HostlistsRegistry/assets/filter_2.txt";
name = "AdAway Default Blocklist";
id = 2;
}
];
auth_attempts = 5;
block_auth_min = 15;
language = "fr";
dns = {
bind_hosts = [ ip ];
port = 53;
upstream_dns = [
"127.0.0.1:5335"
"https://dns10.quad9.net/dns-query"
];
};
filtering = {
safe_search = {
enabled = true;
bing = true;
duckduckgo = true;
ecosia = true;
google = true;
pixabay = true;
yandex = true;
youtube = true;
};
rewrites = [
{
domain = "*${infra.domains.exposed}";
answer = infra.reverse_proxy_addr;
}
{
domain = domainname;
answer = ip;
}
# add internal domains for all containers?
];
};
};
}

View File

@@ -0,0 +1,49 @@
{ ip, domainname, ... }:
{
out = ''
loki.relabel "agh_journal" {
forward_to = []
rule {
source_labels = ["__journal__priority_keyword"]
target_label = "level"
}
rule {
source_labels = ["__journal__SYSLOG_IDENTIFIER"]
target_label = "app"
}
}
loki.source.journal "agh_journal_scrape" {
forward_to = [loki.process.agh_router.receiver]
matches = "_SYSTEMD_UNIT=adguardhome.service"
relabel_rules = loki.relabel.agh_journal.rules
labels = {
service = "adguardhome",
host = "${domainname}",
host_ip = "${ip}",
}
}
loki.process "agh_router" {
stage.regex {
expression = "^(?P<timestamp>\\S+ \\S+) \\[(?P<level>\\w+)\\] (?P<message>.*)$"
}
stage.timestamp {
source = "timestamp"
format = "2006-01-02 15:04:05"
}
stage.labels {
values = {
level = "level",
}
}
stage.output {
source = "message"
}
forward_to = [loki.write.grafana_loki.receiver]
}
'';
}

View File

@@ -0,0 +1,44 @@
{ ip, domainname, ... }:
{
out = ''
loki.relabel "unbd_journal" {
forward_to = []
rule {
source_labels = ["__journal__priority_keyword"]
target_label = "level"
}
rule {
source_labels = ["__journal__SYSLOG_IDENTIFIER"]
target_label = "app"
}
}
loki.source.journal "unbd_journal_scrape" {
forward_to = [loki.process.unbd_router.receiver]
matches = "_SYSTEMD_UNIT=unbound.service"
relabel_rules = loki.relabel.unbd_journal.rules
labels = {
service = "unbound",
host = "${domainname}",
host_ip = "${ip}",
}
}
loki.process "unbound_router" {
stage.pattern {
pattern = "[<_>] <level>: <message>"
}
stage.labels {
values = {
level = "level",
}
}
stage.output {
source = "message"
}
forward_to = [loki.write.grafana_loki.receiver]
}
'';
}