Donnerstag, Juli 23, 2026

Netbox - Loki - Housekeeping - Abschluss des zentralen Loggings

Nachtrag 30.07.26: Man sollte einen anderen Pfad für das Logfile wählen, da sonst spätere Updates des LXCs fehlschlagen werden.

Damit die Logs nicht das LXC mit Loki vollschreiben und so zum Absturz bringen, muss ich eine Logrotation konfigurieren. Das ist per default nicht aktiviert. Man kann das bei Loki sehr fein einstellen. Manche Logs sollten evtl. länger als andere aufbewahrt werden und ich sollte mir möglichst vorher darüber Gedanken machen, wie ich das am besten strukturiere.
Grundsätzlich möchte ich zentrale Logs von

  1. NetBox (1x Einrichtung bekannt)
  2. Technitium (2x Einrichtung bekannt)
  3. PVE (4x Einrichtung bekannt)
  4. PBS (3x)
  5. TrueNAS (3x)
  6. einige LXCs (z.B. zigbee2mqtt, evtl. auch noch Home Assistant)

Punkt 4-6 wären nur ein Nice-to-have. Das zentrale Logging für die drei wichtigsten Dienste (Technitium, PVE und NetBox) funktioniert bereits bzw. die Einrichtung ist bekannt. Nun zur Vorhaltedauer der jeweiligen Logs. Ich lasse zwei KIs den voraussichtlichen Platzbedarf im Loki-LXC schätzen. Dafür werden 4–12 GB/Jahr geschätzt. Loki scheint die Logs effizient komprimieren zu können. Ich habe das LXC bereits vorher auf 10 GB resized, aktuell werden ca. 1,5 GB verbraucht, das sollte also vorerst locker reichen und ich werde mich jetzt hier nicht verkünsteln. Ich werde einfach eine globale Retention von 180 Tagen einstellen. Ich hoffe nicht, dass ich jemals in den Logs etwas nachsehen muss, das länger als 180 Tage in der Vergangenheit liegt.

cp /etc/loki/config.yml /etc/loki/config.yml.bak
nano /etc/loki/config.yml

Ich mache ein Backup der Original-Config-Datei und trage in der Config eine globale Vorhaltezeit ein:

limits_config:
  metric_aggregation_enabled: true
  retention_period: 4320h

4320h entsprechen den 180 Tagen. Das reicht aber noch nicht, die eingestellte Vorhaltezeit muss noch von dem sogenannten Compactor umgesetzt werden. Bei Loki ist der Compactor quasi der Buchhalter. Der Compactor braucht für die Komprimier-/Lese-/Schreib-/Löschvorgänge ein Arbeitsverzeichnis. Das Verzeichnis gibt es bereits unter /var/lib/loki/compactor. In der Config setze ich den neuen Codeblock mit dem Compactor zwischen die Blöcke limits_config und ruler:

compactor:
  working_directory: /var/lib/loki/compactor
  retention_enabled: true
  retention_delete_delay: 2h
  delete_request_store: filesystem

Wie oft der Compactor läuft, kann man in der gleichen Config unter dem Punkt compaction_interval eintragen, Default sind 10 Minuten, das passt für mich bereits. Abschließend Loki neu starten mit

systemctl restart loki

Ich hab’s eine Zeit lang laufen lassen. Man kann nach einiger Zeit mit

journalctl -u loki -f

Zeilen wie diese sehen:

Jul 23 13:10:12 loki loki[560]: level=info ts=2026-07-23T11:10:12.534471137Z caller=tables_manager.go:289 msg="finished compacting table" table-name=index_20654

Der Compactor scheint zu “kompaktieren” 😃
Bei der Gelegenheit räume ich auch gleich mein dämliches Konstrukt mit rsyslog in dem NetBox-LXC auf. Ich editiere dazu die /opt/netbox/netbox/netbox/configuration.py und ersetze dort den gesamten Part mit LOGGING durch:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'normal': {'format': '%(asctime)s %(name)s %(levelname)s: %(message)s'},
    },
    'handlers': {
        'console': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
        },
        'file': {
            'level': 'INFO',
            'class': 'logging.handlers.WatchedFileHandler',
            'filename': '/opt/netbox/logs/netbox.log',
            'formatter': 'normal',
        },
    },
    'loggers': {
        'netbox': {'handlers': ['console', 'file'], 'level': 'INFO'},
        'django': {'handlers': ['console', 'file'], 'level': 'WARNING'},
    },
}

Damit möchte ich die Logs zusätzlich in der Datei /opt/netbox/logs/netbox.log speichern. Das Verzeichnis gibt es noch nicht, also lege ich es an und übertrage die Ownership auf den User netbox.

mkdir -p /opt/netbox/logs
chown netbox:netbox /opt/netbox/logs

Jetzt NetBox neu starten

systemctl restart netbox netbox-rq

und ein Fantasiegerät in NetBox anlegen und wieder löschen.

cat /opt/netbox/logs/netbox.log

zeigt nun bei mir

2026-07-23 11:23:55,221 netbox.views.ObjectEditView INFO: Created Gerät jhghjvbhj (PK: 83)
2026-07-23 11:24:33,928 netbox.views.ObjectDeleteView INFO: Deleted Gerät jhghjvbhj

In UTC-Zeit, sehr schön, so soll das sein. Jetzt muss Alloy installiert werden, der dann das Ganze an das Loki-LXC schickt. Mein Denkfehler war, dass ich zuerst gedacht habe, dass EINE Alloy-Instanz alle Daten “einsammelt”, Alloy ist allerdings ein Agent, der auf dem sendenden Service mitlaufen muss.

apt update && apt install -y gpg wget
mkdir -p /etc/apt/keyrings
wget -q -O /etc/apt/keyrings/grafana.asc https://apt.grafana.com/gpg-full.key
chmod 644 /etc/apt/keyrings/grafana.asc
echo "deb [signed-by=/etc/apt/keyrings/grafana.asc] https://apt.grafana.com stable main" | tee /etc/apt/sources.list.d/grafana.list
apt update
apt install -y alloy

sollte Alloy auf alle Debian-basierten Geräte/Services packen können. Das wäre evtl. auch gleich ein Alloy-Deploy-Script für Ansible. Sobald Alloy in dem NetBox-LXC installiert ist, die /etc/alloy/config.alloy editieren, ich schmeiß dort alles raus und setze für das NetBox-LXC stattdessen folgendes ein:

loki.source.file "netbox" {
  targets = [
    {__path__ = "/opt/netbox/logs/netbox.log", job = "netbox", host = "netbox01"},
  ]
  forward_to = [loki.write.central.receiver]
}
loki.write "central" {
  endpoint {
    url = "http://192.168.2.12:3100/loki/api/v1/push"
  }
}

Alloy auf NetBox starten und enablen mit

systemctl enable --now alloy

Jetzt rsyslog wieder zurückbauen

systemctl disable --now rsyslog
rm -f /etc/rsyslog.d/99-loki-forward.conf
apt purge -y rsyslog
apt autoremove

und schon ist rsyslog wieder weg.

Als Nächstes Technitium reparieren. Dazu in das Technitium-LXC wechseln und Alloy genauso wie im NetBox-LXC installieren. Bei Technitium wird bereits das Log in ein File geschrieben, ich muss hier also kein extra Verzeichnis anlegen. Die /etc/alloy/config.alloy sieht für Technitium so bei mir aus:

local.file_match "technitium" {
  path_targets = [
    {__path__ = "/etc/dns/logs/*.log", job = "technitium", host = "technitium01"},
  ]
}
loki.source.file "technitium" {
  targets    = local.file_match.technitium.targets
  forward_to = [loki.write.central.receiver]
}
loki.write "central" {
  endpoint {
    url = "http://192.168.2.12:3100/loki/api/v1/push"
  }
}

Die einzelnen Werte muss man bei allen Configs natürlich entsprechend an sein Setup anpassen. Nun Alloy starten und enablen. rsyslog lässt sich genau so wie im NetBox-LXC entfernen

systemctl enable --now alloy
Bildschirmfoto_20260723_144248.png
Bildschirmfoto_20260723_144514.png

In Grafana kann ich jetzt mit einem Klick zwischen den Logs der einzelnen Services/Geräte hin- und herschalten. Man kann so auch die Logs mehrerer Geräte im gleichen Zeitraum nebeneinanderlegen, die Logs bequem durchsuchen oder sich anhand von Mustern oder Schlüsselwörtern alarmieren lassen. Wie cool ist das denn bitte! 😃 Der Aufwand hat sich definitiv gelohnt. Das Einbinden der restlichen Geräte werde ich nun der Reihe nach durchführen, dann geht’s weiter mit Ansible.

Mittwoch, Juli 22, 2026

Netbox - Einbinden weiterer Geräte in Alloy/Loki/Grafana - PVE

Nach meinem kleinen ungeplanten Exkurs bezüglich “Codedarstellung in Flatpress” kann ich mich wieder dem ursprünglichen Exkurs “zentrales Logging”, vom eigentlichen Hauptthema “Zentrale Steuerung via NetBox”, widmen. Man kommt schnell vom 100sten ins 1000ste, wenn man nicht aufpasst. Nun binde ich mal einen PVE ein. Hoffentlich geht das etwas simpler als die beiden vorherigen Dienste (NetBox & Technitium). Danach muss ich unbedingt noch die Aufräumfunktion für Logs in Alloy/Loki ansehen, sonst läuft mir das LXC ruckzuck mit Logfiles voll. Log-Housekeeping bekommt danach auch einen eigenen Artikel, doch zunächst zurück zu PVE/Loki.

Zuerst kläre ich mal, welche Uhrzeit überhaupt in PVE läuft

Bildschirmfoto_20260722_173156.png

irgendwie sehen die rohen Logs von PVE aber auch so aus, als ob sie Loki vom Format her nicht schmecken würden. Ich lese also doch mal lieber die Alloy/Loki-Doku, was ich von Anfang an hätte tun sollen, und stelle fest, dass ich die anderen beiden Geräte mit einer meiner irrsinnigen Overengineering-Frickellösungen “falsch” eingerichtet habe. 😂 Es funktioniert zwar, geht aber über einen Alloy-Agent VIEL einfacher. Das probieren wir doch gleich mal in PVE aus und revertieren danach die anderen beiden Dienste wieder.

Ich bin natürlich nicht der Erste, der Alloy mit PVE verheiraten will. Wie man Alloy am besten in PVE einbindet, wurde im Proxmox-Forum bereits diskutiert. Der Kommentar #8 klingt jedenfalls interessant. Der Kollege hat via Ansible nicht nur remote auf allen Zielgeräten den Alloy-Agent deployed, sondern er hält ihn über Ansible auch aktuell. Sehr clever 😃

Ich wollte auf den PVE-Hosts eigentlich so wenig wie möglich installieren, bei NUT habe ich bereits eine Ausnahme gemacht, eigentlich gefällt es mir nicht so gut, zusätzliche Software auf den PVE-Hosts selbst zu installieren. Ein eigenes LXC nur für Alloy klingt aber auch nicht viel besser. Ich habe mal im deutschen Discord-Channel der Community-Scripts nachgefragt, wie die Profis das so machen, aber MickLesk hat mich scheinbar missverstanden: Er dachte wohl, ich will zentral Metriken sammeln, was bei PVE wenig Sinn machen würde.

Ich gehe mal den direkten Weg und installiere Alloy direkt auf PVE:

apt update && apt install -y gpg wget
mkdir -p /etc/apt/keyrings #kann entfallen, falls es das Verzeichnis schon gibt
wget -q -O /etc/apt/keyrings/grafana.asc https://apt.grafana.com/gpg-full.key
chmod 644 /etc/apt/keyrings/grafana.asc
echo "deb [signed-by=/etc/apt/keyrings/grafana.asc] https://apt.grafana.com stable main" 
  | tee /etc/apt/sources.list.d/grafana.list
apt update
apt install -y alloy

Danach muss ich dem Alloy-Agent auf dem PVE noch eine passende Config verpassen. Den Inhalt von /etc/alloy/config.alloy auf dem PVE habe ich ersetzt durch:

loki.source.journal "pve_journal" {
  forward_to    = [loki.write.central.receiver]
  relabel_rules = loki.relabel.journal.rules
  labels        = {
    job  = "systemd-journal",
    host = "pve01",
  }
}
loki.relabel "journal" {
  forward_to = []
  rule {
    source_labels = ["__journal__systemd_unit"]
    target_label  = "unit"
  }
}
loki.write "central" {
  endpoint {
    url = "http://192.168.2.12:3100/loki/api/v1/push"
  }
}

und starten/enablen mit:

systemctl enable --now alloy
Bildschirmfoto_20260722_213550.png

Da sind die PVE Logs in Grafana. Das war wesentlich einfacher als meine Verrenkungen davor.

Netbox - Einbinden weiterer Geräte in Alloy/Loki/Grafana - Technitium

Das Einrichten geht viel einfacher, die Beschreibung ist im Housekeepingartikel

Das ist streng genommen kein NetBox Thema, ich lasse es aber in der Kategorie NetBox, weil es zum vorherigen Beitrag gehört. Das Senden von Logfiles sollte bei Anwendungen, die nicht in Python geschrieben sind bzw. nicht den Python SysLogHandler verwenden, wesentlich einfacher einzurichten sein.

Nochmal der Hinweis vorab, ich präsentiere hier keine ausführlich getesteten fertigen Lösungen. Das Blog ist eher ein “live Mitschnitt” meiner Aktivitäten, damit ich weiß, was ich wann und warum getan habe (um es ggf. später wieder Schritt für Schritt rückgängig machen zu können). Ich werde im Verlauf sicherlich noch diverse Dinge umbauen, daher sollte man das, was ich hier so tue, keinesfalls auf einem Produktivsystem 1:1 übernehmen! Ich lasse mir zur Zeitersparnis exzessiv von KIs helfen, sei es bei Zusammenfassungen von Anleitungen oder beim Debuggen von Code. Ich versuche so gut es geht nachzuvollziehen, was die KI vorschlägt, und übernehme nur Code, den ich auch selbst, zumindest meine, verstanden zu haben. Jeder muss/sollte das Gleiche tun und sich keinesfalls blind auf meine Lösungen verlassen.

Zuerst werde ich Technitium einbinden. Da ich die Einbindung der einzelnen Dienste, wie oben erwähnt, im Verlauf sicher noch anpassen werde, bekommt jeder Dienst einen eigenen Beitrag. Aktualisierungen werde ich zukünftig immer in der ersten Zeile des jeweiligen Artikels mit Datum kennzeichnen. Ich hoffe, dass die Übersicht so erhalten bleibt.

Zunächst rsyslog in Technitium installieren. Ich brauche rsyslog auch bei Technitium, um die Logs für Loki zu “normalisieren”:

apt update
apt install -y rsyslog

In der Shell von Technitium legen wir ein neues Template für die Normalisierung der Logs an:

cat > /etc/rsyslog.d/00-templates.conf << 'EOF'
template(name="RFC5424_UTC" type="string"
string="<%PRI%>1 %TIMESTAMP:::date-rfc3339,date-utc% %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg%n"
)
EOF

Das Template ignoriert bewusst den in der Logzeile enthaltenen Text-Timestamp und setzt stattdessen die tatsächliche UTC-Empfangszeit von rsyslog ein, unabhängig davon, ob die Quelle selbst schon in UTC loggt oder nicht. Das Template muss auf jedem Host, der an Loki sendet, separat existieren (Templates werden pro rsyslog-Instanz definiert, nicht global geteilt).

Nun noch die eigentliche Config-Datei für das Logging:

cat > /etc/rsyslog.d/97-technitium-corelog.conf << 'EOF'
module(load="imfile" mode="inotify")
input(type="imfile"
File="/etc/dns/logs/*.log"
Tag="technitium-core:"
Severity="info"
Facility="local0"
ruleset="forwardCoreLog"
freshStartTail="on"
startmsg.regex="^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}")
ruleset(name="forwardCoreLog") {
if tolower(msg) contains "xception" or tolower( msg) contains "rror" or tolower(msg) contains "ailed" or tolower( msg) contains "imeout" then {
action(type="omfwd" target="<LOKI-LXC-IP>" port="1514" protocol="tcp"
template="RFC5424_UTC")
}
}
EOF

Hier muss man die passende IP-Adresse von Alloy/Loki entsprechend eintragen/anpassen. Anschließend die Syntax der Config-Datei prüfen und, wenn es ohne Fehler durchläuft, gleich starten:

rsyslogd -N1 -f /etc/rsyslog.conf
systemctl enable --now rsyslog

Zum Testen erzeugen wir auf dem Technitium-Server einen Log-Eintrag mit:

echo "[$(date -u '+%Y-%m-%d %H:%M:%S') UTC] TEST error verification line" >> /etc/dns/logs/$(date +%Y-%m-%d).log

und schauen, ob es im Loki-LXC ankommt, mit:

curl -s "http://localhost:3100/loki/api/v1/query_range" 
--data-urlencode 'query={job="syslog"} |= "verification line"' 
--data-urlencode 'start='$(date -d '5 minutes ago' +%s)'000000000' 
--data-urlencode 'end='$(date +%s)'000000000' | jq -r '.data.result[].values[][1]'
Bildschirmfoto_20260722_151155.png

Hier sieht man die erzeugten Error-Logs in Grafana.

Dienstag, Juli 21, 2026

Netbox - Welche Zeitzone einstellen und zentrales Logging mit Alloy/Loki/Grafana

Das Einrichten geht viel einfacher, die Beschreibung ist im Housekeepingartikel

Das Aktualisieren der IPAM-Einträge funktioniert weiterhin gut, und ich war eigentlich gerade dabei, das erste Ansible-Playbook auszuarbeiten, als ich gedanklich auf ein weiteres Problem gestoßen bin.
Beim Zusammenspiel von NetBox, Ansible und Technitium ist es notwendig, dass alle drei Beteiligten mit der gleichen Uhrzeit arbeiten. Soweit ich aktuell weiß, ist bei allen dreien intern UTC die gültige Zeit. Mir ist schon vor ein paar Tagen aufgefallen, dass die NetBox-Logs ebenfalls mit UTC-Zeit angezeigt werden. In Technitium habe ich bereits bei der Installation vor mehr als zwei Jahren die Logs auf Lokalzeit, also UTC+2h (wegen der besseren Lesbarkeit), umgestellt. Ich persönlich glaube jedoch inzwischen, dass es besser wäre, wenn alle Dienste die Ereignisse mit UTC-Timestamps loggen würden. Die Services/Programme, mit denen man später die Logs darstellt (z. B. Grafana), können dann die Umrechnung in die jeweilige Lokalzeit übernehmen. Das ist auch von großem Vorteil, wenn man Geräte in einer anderen Zeitzone hat (in dem Fall oft auch ohne Sommerzeit). Das Logging habe ich daher in Technitium wieder auf UTC zurückgestellt.

Bildschirmfoto_20260721_180344.png

Als zentrale Datenbank für die Logs wird oft Loki/Alloy empfohlen oder der sogenannte ELK-Stack. Der ELK-Stack ist scheinbar deutlich komplexer einzurichten, wohl auch eher so ein Docker-Ding (Nachtrag: hier lag ich falsch, kann man genauso leicht installieren wie NetBox) (ich mag Docker einfach nicht), und da ich eigentlich viel lieber bei NetBox/Ansible weitermachen will, wähle ich den einfacheren Weg über Loki. Loki und Grafana gibt es bei den Community-Scripts als LXC, also muss ich mir hier wegen zukünftiger Updates keine allzu großen Sorgen machen. Ein sauberes zentrales Logging ist von größtem Vorteil zur geräteübergreifenden Fehlersuche und spätestens dann extrem zeitsparend, sobald ich anfange, andere Geräte via Ansible zu steuern. Von daher werde ich das Thema zentrales Logging hiermit vorziehen.
Ich installiere zunächst Loki und Grafana auf PVE und gebe ihnen, wie inzwischen auch dem NetBox-LXC, feste IPs. Die IPs dieser Dienste sollten sich nicht ändern können, sonst funktioniert das Zusammenspiel der einzelnen Dienste nicht mehr.
In Grafana verbinde ich zunächst das Loki-LXC als neue Datenquelle.

Bildschirmfoto_20260720_170916.png

Es reicht bereits, die IP-Adresse und den Port des LXC mit Loki anzugeben, um eine Verbindung herstellen zu können.

Bildschirmfoto_20260720_171407.png

Das muss ich natürlich später noch weiter absichern, aber zum Testen reicht es zunächst. Damit die Logs aber erst mal irgendwie in Loki “reinkommen”, brauche ich noch das Tool Alloy. Alloy empfängt Logs und/oder sammelt diese aktiv bei den hinterlegten Geräten ein und leitet sie anschließend an Loki weiter. Loki indexiert und komprimiert die Logs und regelt wohl auch das Aussortieren alter Logs. Alle drei Teile kommen vom gleichen Entwicklerteam, das sollte also gut zusammenarbeiten. Alloy ist weder Teil des Grafana-LXCs noch bei Loki dabei. Scheinbar hatten andere Leute bereits ähnliche Gedankengänge wie ich. MickLesk ist einer der Maintainer der Community-Scripts, und deswegen werde ich mich an seine Empfehlung halten. Ich hatte bereits überlegt, ob Alloy ein eigenes LXC benötigt. Erfreulicherweise ist das Nachrüsten von Alloy gar “nicht so deep”, wie man heute sagen würde. Es lässt sich mit einem simplen

apt install alloy

in dem LXC mit Loki nachinstallieren.
Bei der Installation des Loki-LXCs sind mir noch zwei weitere Punkte ins Auge gefallen. Man kann das Auswahlmenü mit

update

in der Shell des Loki-LXCs jederzeit erneut aufrufen.

Bildschirmfoto_20260720_200601.png

Ich wähle beim zweiten Durchlauf auch noch Option 2, damit alle ankommenden Adressen ihre Logs bei Alloy/Loki loswerden können. Das werde ich in Zukunft vermutlich noch einschränken - als kleiner Reminder für mich selbst.
Bis hierher war die Einrichtung noch trivial, und ich wollte das Thema eigentlich in ein bis zwei Stunden abhaken. Ich musste dann aber doch fast zwei Tage meiner Freizeit aufwenden, um die Logs von NetBox in Loki zu bekommen. Ich stelle hier meine Konfiguration vor; sie lässt sich aber bestimmt besser einrichten als in meinem Beispiel. Für mich passt es aktuell, und ich kann das Logging im Verlauf sukzessive noch weiter verbessern.
In der /etc/alloy/config.alloy des Alloy/Loki-LXCs habe ich am Ende folgenden Codeblock angehängt:

// --- Logs: Syslog-Listener ---
loki.source.syslog "central" {
  listener {
    address  = "0.0.0.0:1514"
    protocol = "tcp"
    labels   = {job = "syslog"}
  }
  forward_to = [loki.write.default.receiver]
}
loki.write "default" {
  endpoint {
    url = "http://localhost:3100/loki/api/v1/push"
  }
}

Danach den systemd-Dienst enablen mit

systemctl enable alloy

und starten mit

systemctl start alloy

.
Wie oben schon erwähnt, habe ich es zunächst nicht geschafft, die Logs von NetBox selbst über Alloy an Loki zu senden. Nach zwei Tagen des Herumprobierens meine ich, das Problem lokalisiert zu haben. NetBox ist eine Python/Django-Anwendung, und scheinbar sendet der SysLogHandler von Python keine RFC5424-konformen Logmeldungen. Alloy erwartet aber genau dieses Format und verwirft alle nicht RFC5424-konformen Nachrichten einfach. Das Problem sollte bei meinen anderen LXCs nicht auftreten, denn kein anderer meiner laufenden Services ist meines Wissens in Python geschrieben. Werde ich im Verlauf noch merken…
Jedenfalls musste ich in dem NetBox-LXC noch rsyslog nachinstallieren. rsyslog fungiert hier als Übersetzer: Es nimmt die minimale Nachricht von NetBox lokal entgegen (über /dev/log), reichert sie mit allen fehlenden Feldern an (Timestamp, Hostname, App-Name, Version) und schickt erst dann ein vollständiges, korrektes Paket weiter.

apt-get update
apt-get install -y rsyslog
systemctl enable rsyslog
systemctl start rsyslog

Damit rsyslog die NetBox-Nachrichten (Facility local0) auch tatsächlich an Alloy weiterleitet, musste ich noch eine Forward-Regel anlegen:

echo "local0.* @@<loki-lxc-ip>:1514;RSYSLOG_SyslogProtocol23Format" >> /etc/rsyslog.d/99-loki-forward.conf
systemctl restart rsyslog

Das Anhängsel ;RSYSLOG_SyslogProtocol23Format war dabei der Kern meines zweitägigen Problems: Ohne dieses Template sendet rsyslog standardmäßig im älteren RFC3164-Format, das Alloy nicht akzeptiert.
Nun muss man in dem NetBox-LXC noch die Config bezüglich des Loggings etwas anpassen. Bei mir war der Logging-Teil in der Config initial leer.

nano /opt/netbox/netbox/netbox/configuration.py

Hier folgendes beim Abschnitt Logging eintragen:

#   https://docs.djangoproject.com/en/stable/topics/logging/
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
        },
        'syslog': {
            'level': 'INFO',
            'class': 'logging.handlers.SysLogHandler',
            'address': '/dev/log',
            'facility': 'local0',
        },
    },
    'loggers': {
        'netbox': {
            'handlers': ['console', 'syslog'],
            'level': 'INFO',
        },
        'django': {
            'handlers': ['console', 'syslog'],
            'level': 'WARNING',
        },
    },
}

Um sicherzugehen, dass NetBox nicht das interne Logging zugunsten der neuen externen Lösung ganz deaktiviert, habe ich sicherheitshalber beide Handler

['console', 'syslog']

in meiner Config eingetragen. Danach NetBox neu starten mit

systemctl restart netbox netbox-rq

Ich hoffe, das passt so… es scheint jedenfalls zu funktionieren. Hier noch der Screenshot einer Abfrage von Loki via Grafana.

Bildschirmfoto_20260721_211452.png

Man sieht schön die Aktivität des Dynamic IP Script aus dem vorherigen Beitrag, das momentan noch alle 30 Minuten ausgeführt wird. Grafana hat dabei auch die UTC Timestamps automatisch in die Lokalzeit umgerechnet.

Bildschirmfoto_20260721_215417-1.png

Wie man auf dem letzten Bild sieht läuft das Logging in NetBox intern weiterhin auf UTC.

Samstag, Juli 18, 2026

Netbox - DHCP Plugin + Custom Script zum Abgleich dynamischer IPs in IPAM

Das DHCP-Plugin ist zwar noch als Beta markiert, ich probiere es aber natürlich trotzdem aus 😎 Da es aktuell (noch) keine Dokumentation für das Plugin gibt, habe ich Claude den Sourcecode des Plugins auf GitHub analysieren lassen. Man kann über KIs denken, wie man will, aber als Werkzeuge zur Code- und/oder Fehleranalyse sind sie ausgezeichnet geeignet.
Da das Plugin noch in aktiver Entwicklung ist, könnten sich einige Einstellungspunkte in Zukunft ändern, daher erwähne ich die einzelnen Schritte der Einrichtung hier nicht. Claude und die meisten anderen KIs leiten einen hier aktuell gut durch, wenn man irgendwo nicht weiterkommt. Ich werde daher nur ein paar Screenshots von der Einrichtung zeigen und den Textteil irgendwann später ergänzen, wenn das Plugin nicht mehr in der Betaphase ist.

Bildschirmfoto_20260718_130902.png
Bildschirmfoto_20260718_131058.png
Bildschirmfoto_20260719_193258.png

Das Anlegen der IP-Reservierungen muss man von Hand erledigen.
Es bleibt in Bezug auf DHCP aber noch eine Sache abzudecken, und zwar den Fall, dass sich Geräte (Handys etc.) im LAN anmelden, eine dynamische IP von Technitium bekommen und später wieder (manchmal für immer) verschwinden. Das wäre z. B. in einem WLAN-Gastnetz der Fall oder wenn Endgeräte ihre MAC-Adressen rotieren (iPhones z. B.). Die entsprechenden Geräte bekommen von Technitium dynamisch per DHCP eine Adresse zugewiesen, und diese Adressen sollten irgendwie auch in NetBox auftauchen. Wenn das Lease solcher Geräte abgelaufen ist und sie wieder aus dem WLAN-Netz verschwunden sind, sollen auch die IPAM-Einträge wieder entfernt werden. Solche Geräte kann ich in NetBox nicht als Devices abbilden, denn dann müsste ich u. U. dynamisch neue Hersteller, Geräteklassen, Geräte und Schnittstellen in NetBox erzeugen lassen. Es reicht mir vollkommen, in NetBox den Hostnamen und die korrespondierende IP-Adresse des Geräts sehen zu können. Die Technitium-API bietet zum Glück die Möglichkeit, eine Liste mit allen aktuellen Leases abzufragen. Ich lege hierfür in Technitium einen neuen User mit eingeschränkten Rechten an. Für den neuen User kann man in der GUI von Technitium auch gleich noch ein API-Token erzeugen. Der API-Token wird nur einmalig angezeigt; ich lege ihn daher in meinem Passwortmanager (KeePassXC/KeePassium) ab.
Man kann die API-Abfrage nun im Browser testen mit

http://<technitium-ip>:5380/api/dhcp/leases/list?token=<api-token>

und bekommt alle aktuellen Leases angezeigt. Dabei sind vor allem die Leases mit dem Zusatz Dynamic von Interesse. Dies sind die Adressen, für die keine Reservierung vorhanden ist.
Als nächsten Schritt habe ich mit dem guten Claude ein kleines Script erstellt, das man genauso in NetBox einbinden kann wie die Scripte von Peter Eckel. Man findet es in einem GitHub-Repository, das ich in meinem Account neu angelegt habe. Evtl. werde ich dort (bei Bedarf) in Zukunft noch weitere Scripte ergänzen. Claude hat auch noch ein README erstellt, das die Einrichtung bereits sehr gut beschreibt. Damit das Script funktioniert, muss man zusätzlich ein neues Custom Field einrichten

Bildschirmfoto_20260719_121211.png

Das Script ruft bei jedem Durchlauf über die Technitium-API die Liste mit den Leases ab, filtert nur die mit “Dynamic” heraus, prüft, ob es bereits einen IPAM-Eintrag gibt, ergänzt einen fehlenden IPAM-Eintrag (inklusive Tag) und entfernt IPAM-Einträge, für die es kein korrespondierendes Lease mehr gibt. Ich habe als Intervall aktuell 30 Minuten eingestellt, werde aber vermutlich auf 15 Minuten umstellen. Das Script befindet sich noch in der Testphase, scheint aber bisher gut zu funktionieren.

Bildschirmfoto_20260719_205931.png

Technitium

Bildschirmfoto_20260719_210219.png

IPAM in NetBox
Ich lasse es mal ein paar Tage laufen und nehme noch ein paar der IP-Reservierungen bei Technitium raus, um eine schöne Rotation zu simulieren. Wenn das Script die nächsten Tage ohne Probleme sauber durchläuft und meine IPAM nicht vollmüllt, werde ich als nächsten Schritt die Steuerung von Technitium via NetBox/Semaphore (Ansible) in Angriff nehmen. Proxmox lässt sich wohl auch sehr gut über NetBox steuern, das wird dann vermutlich als nächstes Thema drankommen.