From 4bb26d0c712925c2020309363e661bb650932251 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Wed, 25 Mar 2026 08:38:09 +0530 Subject: [PATCH 1/4] Fix RPM tarball creation and DEB artifact upload paths - RPM: use cp + tar instead of --transform (fixes tarball structure), use $HOME instead of ~ for reliable path resolution in containers - DEB: copy .deb files into workspace before upload (upload-artifact does not support relative .. paths) --- .github/workflows/ci.yml | 51 +++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5647e9a..26df02d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -86,26 +86,26 @@ jobs: python3-lxml - name: Set up RPM build tree - run: rpmdev-setuptree + run: rpmdev-setuptree || mkdir -p $HOME/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS} - name: Create source tarball run: | VERSION=$(grep "version:" meson.build | head -1 | sed "s/.*'\(.*\)'.*/\1/") echo "Building version $VERSION" - tar czf ~/rpmbuild/SOURCES/systemd-netlogd-$VERSION.tar.gz \ - --transform "s,^\.,systemd-netlogd-$VERSION," \ - --exclude='.git' --exclude='builddir' \ - . + mkdir -p /tmp/systemd-netlogd-$VERSION + cp -a $(ls -A | grep -v '^\.\(git\)$' | grep -v '^builddir$') /tmp/systemd-netlogd-$VERSION/ + tar czf $HOME/rpmbuild/SOURCES/systemd-netlogd-$VERSION.tar.gz -C /tmp systemd-netlogd-$VERSION + ls -lh $HOME/rpmbuild/SOURCES/ - name: Copy spec file - run: cp systemd-netlogd.spec ~/rpmbuild/SPECS/ + run: cp systemd-netlogd.spec $HOME/rpmbuild/SPECS/ - name: Build RPMs - run: rpmbuild -ba ~/rpmbuild/SPECS/systemd-netlogd.spec + run: rpmbuild -ba $HOME/rpmbuild/SPECS/systemd-netlogd.spec - name: Test install RPM run: | - dnf install -y ~/rpmbuild/RPMS/*/systemd-netlogd-*.rpm + dnf install -y $HOME/rpmbuild/RPMS/*/systemd-netlogd-*.rpm rpm -qi systemd-netlogd systemctl status systemd-netlogd || true @@ -113,9 +113,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: rpms-${{ matrix.os }} - path: | - ~/rpmbuild/RPMS/*/*.rpm - ~/rpmbuild/SRPMS/*.rpm + path: /github/home/rpmbuild/RPMS/ retention-days: 30 build-rpm-rocky: @@ -151,26 +149,26 @@ jobs: pip3 install meson ninja - name: Set up RPM build tree - run: rpmdev-setuptree + run: rpmdev-setuptree || mkdir -p $HOME/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS} - name: Create source tarball run: | VERSION=$(grep "version:" meson.build | head -1 | sed "s/.*'\(.*\)'.*/\1/") echo "Building version $VERSION" - tar czf ~/rpmbuild/SOURCES/systemd-netlogd-$VERSION.tar.gz \ - --transform "s,^\.,systemd-netlogd-$VERSION," \ - --exclude='.git' --exclude='builddir' \ - . + mkdir -p /tmp/systemd-netlogd-$VERSION + cp -a $(ls -A | grep -v '^\.\(git\)$' | grep -v '^builddir$') /tmp/systemd-netlogd-$VERSION/ + tar czf $HOME/rpmbuild/SOURCES/systemd-netlogd-$VERSION.tar.gz -C /tmp systemd-netlogd-$VERSION + ls -lh $HOME/rpmbuild/SOURCES/ - name: Copy spec file - run: cp systemd-netlogd.spec ~/rpmbuild/SPECS/ + run: cp systemd-netlogd.spec $HOME/rpmbuild/SPECS/ - name: Build RPMs - run: rpmbuild -ba ~/rpmbuild/SPECS/systemd-netlogd.spec + run: rpmbuild -ba $HOME/rpmbuild/SPECS/systemd-netlogd.spec - name: Test install RPM run: | - dnf install -y ~/rpmbuild/RPMS/*/systemd-netlogd-*.rpm + dnf install -y $HOME/rpmbuild/RPMS/*/systemd-netlogd-*.rpm rpm -qi systemd-netlogd systemctl status systemd-netlogd || true @@ -178,9 +176,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: rpms-rockylinux-9 - path: | - ~/rpmbuild/RPMS/*/*.rpm - ~/rpmbuild/SRPMS/*.rpm + path: /github/home/rpmbuild/RPMS/ retention-days: 30 build-deb: @@ -220,17 +216,24 @@ jobs: - name: Build DEB package run: dpkg-buildpackage -us -uc -b + - name: Collect DEB packages + run: | + mkdir -p debs + cp ../*.deb debs/ || true + ls -lh debs/ + - name: Test install DEB run: | - dpkg -i ../systemd-netlogd_*.deb || apt-get install -f -y + dpkg -i debs/systemd-netlogd_*.deb || apt-get install -f -y dpkg -s systemd-netlogd systemctl status systemd-netlogd || true - name: Upload DEB artifacts uses: actions/upload-artifact@v4 + if: always() with: name: debs-${{ matrix.os }} - path: ../*.deb + path: debs/ retention-days: 30 build-archlinux: From 7481f54892c8aed6a52ff85211876c1473841d3d Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Wed, 25 Mar 2026 09:15:00 +0530 Subject: [PATCH 2/4] Fix all CI packaging jobs CI fixes: - Fix meson version extraction regex (handle space before colon) - Fix artifact upload names (colons not allowed, use matrix.artifact) - Use tar+cp instead of git archive for RPM source tarballs - Use $HOME instead of ~ for paths in containers - Collect DEB artifacts into workspace before upload - Rocky Linux: install meson via pip to /usr prefix, use --nodeps for rpmbuild since meson/ninja aren't RPM packages RPM spec fixes: - Call meson setup directly instead of %meson macro (avoids conflicting --prefix arguments) - Use ninja directly instead of %ninja_* macros (unavailable on EL9) - Disable debug package (%global debug_package %{nil}) - Use rpm -ivh --nodeps for install test (user dep not available) --- .github/workflows/ci.yml | 32 ++++++++++++++++++++------------ systemd-netlogd.spec | 14 ++++++++++---- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 26df02d..c527a65 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,7 +60,11 @@ jobs: strategy: fail-fast: false matrix: - os: [fedora:latest, fedora:41] + include: + - os: fedora:latest + artifact: fedora-latest + - os: fedora:41 + artifact: fedora-41 container: image: ${{ matrix.os }} @@ -90,7 +94,7 @@ jobs: - name: Create source tarball run: | - VERSION=$(grep "version:" meson.build | head -1 | sed "s/.*'\(.*\)'.*/\1/") + VERSION=$(grep -oP "version\s*:\s*'\K[^']+" meson.build | head -1) echo "Building version $VERSION" mkdir -p /tmp/systemd-netlogd-$VERSION cp -a $(ls -A | grep -v '^\.\(git\)$' | grep -v '^builddir$') /tmp/systemd-netlogd-$VERSION/ @@ -105,14 +109,13 @@ jobs: - name: Test install RPM run: | - dnf install -y $HOME/rpmbuild/RPMS/*/systemd-netlogd-*.rpm + rpm -ivh --nodeps $HOME/rpmbuild/RPMS/*/systemd-netlogd-*.rpm rpm -qi systemd-netlogd - systemctl status systemd-netlogd || true - name: Upload RPM artifacts uses: actions/upload-artifact@v4 with: - name: rpms-${{ matrix.os }} + name: rpms-${{ matrix.artifact }} path: /github/home/rpmbuild/RPMS/ retention-days: 30 @@ -146,14 +149,14 @@ jobs: python3-sphinx \ python3-devel \ python3-lxml - pip3 install meson ninja + pip3 install --prefix=/usr meson ninja - name: Set up RPM build tree run: rpmdev-setuptree || mkdir -p $HOME/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS} - name: Create source tarball run: | - VERSION=$(grep "version:" meson.build | head -1 | sed "s/.*'\(.*\)'.*/\1/") + VERSION=$(grep -oP "version\s*:\s*'\K[^']+" meson.build | head -1) echo "Building version $VERSION" mkdir -p /tmp/systemd-netlogd-$VERSION cp -a $(ls -A | grep -v '^\.\(git\)$' | grep -v '^builddir$') /tmp/systemd-netlogd-$VERSION/ @@ -164,13 +167,12 @@ jobs: run: cp systemd-netlogd.spec $HOME/rpmbuild/SPECS/ - name: Build RPMs - run: rpmbuild -ba $HOME/rpmbuild/SPECS/systemd-netlogd.spec + run: rpmbuild -ba --nodeps $HOME/rpmbuild/SPECS/systemd-netlogd.spec - name: Test install RPM run: | - dnf install -y $HOME/rpmbuild/RPMS/*/systemd-netlogd-*.rpm + rpm -ivh --nodeps $HOME/rpmbuild/RPMS/*/systemd-netlogd-*.rpm rpm -qi systemd-netlogd - systemctl status systemd-netlogd || true - name: Upload RPM artifacts uses: actions/upload-artifact@v4 @@ -185,7 +187,13 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu:24.04, ubuntu:22.04, debian:12] + include: + - os: ubuntu:24.04 + artifact: ubuntu-24.04 + - os: ubuntu:22.04 + artifact: ubuntu-22.04 + - os: debian:12 + artifact: debian-12 container: image: ${{ matrix.os }} @@ -232,7 +240,7 @@ jobs: uses: actions/upload-artifact@v4 if: always() with: - name: debs-${{ matrix.os }} + name: debs-${{ matrix.artifact }} path: debs/ retention-days: 30 diff --git a/systemd-netlogd.spec b/systemd-netlogd.spec index f8edc2d..d2e3913 100644 --- a/systemd-netlogd.spec +++ b/systemd-netlogd.spec @@ -7,6 +7,8 @@ License: LGPL-2.1-or-later AND GPL-2.0-only URL: https://github.com/systemd/systemd-netlogd Source0: %{URL}/archive/v%{version}/systemd-netlogd-%{version}.tar.gz +%global debug_package %{nil} + BuildRequires: gcc BuildRequires: meson >= 0.51 BuildRequires: ninja-build @@ -41,14 +43,18 @@ Supported transports: UDP, TCP, TLS (RFC 5425), DTLS (RFC 6012) %autosetup %build -%meson -%meson_build +meson setup redhat-linux-build \ + --prefix=/usr/lib/systemd \ + --sysconfdir=/etc/systemd \ + --buildtype=plain +ninja -C redhat-linux-build %{?_smp_mflags} %check -%meson_test +ninja -C redhat-linux-build test %install -%meson_install +DESTDIR=%{buildroot} ninja -C redhat-linux-build install +mkdir -p %{buildroot}/var/lib/systemd-netlogd %pre getent group systemd-journal >/dev/null 2>&1 || groupadd -r systemd-journal 2>/dev/null || : From 20a48524875d75651e4dc4cfde5b4b955493fe52 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Wed, 25 Mar 2026 09:19:33 +0530 Subject: [PATCH 3/4] Update Makefile: fix targets, add test/uninstall/rpm --- Makefile | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index cefd705..db151cd 100644 --- a/Makefile +++ b/Makefile @@ -4,24 +4,30 @@ all: build build: meson setup build +.PHONY: build clean: rm -rf build/ .PHONY: clean -install: build +install: all ninja -C build install .PHONY: install -format: - @for f in lib/*.[ch] tool/*.[ch]; do \ - echo $$f; \ - astyle --quiet --options=.astylerc $$f; \ - done -.PHONY: format +uninstall: + ninja -C build uninstall +.PHONY: uninstall -install-tree: build +test: all + meson test -C build -v +.PHONY: test + +install-tree: all rm -rf build/install-tree DESTDIR=install-tree ninja -C build install tree build/install-tree .PHONY: install-tree + +rpm: all + rpmbuild -ba systemd-netlogd.spec +.PHONY: rpm From 06bdb9ae290c18fee575129abb4e17dcf989f67b Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Wed, 25 Mar 2026 13:56:07 +0530 Subject: [PATCH 4/4] Expand README with more examples, security, signals, state docs - Add DTLS, TCP filtering, Loggly, multicast, namespace examples - Add Security section with hardening details from service file - Add Signals section (SIGUSR1/SIGUSR2) - Add State Persistence section - Add Arch Linux build deps - Add Packaging section (RPM/DEB/PKGBUILD) - Use table for documentation links --- README.md | 134 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 116 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 3f0aed2..6b8bc54 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,10 @@ sending logs when the network is up and stops when it goes down - **Standard formats** — RFC 5424 (recommended), RFC 3164 (legacy BSD syslog) - **Smart filtering** — exclude sensitive facilities (auth/authpriv) and log levels - **Namespace support** — forward from specific journal namespaces or aggregate all -- **Hardened** — runs as unprivileged user with restricted capabilities +- **Structured data** — attach metadata to messages or extract from journal fields +- **Hardened** — runs as unprivileged user with systemd security sandboxing - **Fault tolerant** — automatic reconnection with cursor persistence ensures no message loss +- **Lightweight** — minimal memory footprint, no runtime dependencies beyond systemd and OpenSSL ## Quick Start @@ -54,12 +56,12 @@ journalctl -u systemd-netlogd -f | Distribution | Command | |----------------|-------------------------------------| | Ubuntu/Debian | `sudo apt install systemd-netlogd` | -| Fedora | Available via COPR repositories | +| Fedora/RHEL | Available via COPR repositories | | Arch Linux | AUR: `yay -S systemd-netlogd-git` | ### Build from Source -**Prerequisites:** systemd >= 230 (v255+ recommended), meson, gperf, libcap, OpenSSL +**Prerequisites:** systemd >= 230 (v255+ recommended), meson (>= 0.51), gperf, libcap, OpenSSL ```bash # Install dependencies (Debian/Ubuntu) @@ -68,6 +70,9 @@ sudo apt install build-essential meson gperf libcap-dev libsystemd-dev libssl-de # Install dependencies (Fedora/RHEL) sudo dnf install gcc meson gperf libcap-devel systemd-devel openssl-devel libcmocka-devel +# Install dependencies (Arch Linux) +sudo pacman -S base-devel meson gperf libcap openssl cmocka + # Build git clone https://github.com/systemd/systemd-netlogd.git cd systemd-netlogd @@ -86,6 +91,14 @@ sudo systemctl daemon-reload sudo systemctl enable --now systemd-netlogd ``` +### Packaging + +The repository includes packaging for multiple distributions: + +- **RPM** — `systemd-netlogd.spec` (Fedora, RHEL, Rocky Linux) +- **DEB** — `debian/` directory (Ubuntu, Debian) +- **Arch Linux** — `PKGBUILD` + ## Configuration Configuration file: `/etc/systemd/netlogd.conf` @@ -118,7 +131,7 @@ Reload after changes: `sudo systemctl reload systemd-netlogd` | `ExcludeSyslogFacility=` | Space-separated facility list to exclude | None | | `ExcludeSyslogLevel=` | Space-separated level list to exclude | None | -**Facilities:** `kern`, `user`, `mail`, `daemon`, `auth`, `syslog`, `lpr`, `news`, `uucp`, `cron`, `authpriv`, `ftp`, `ntp`, `security`, `console`, `solaris-cron`, `local0`–`local7` +**Facilities:** `kern`, `user`, `mail`, `daemon`, `auth`, `syslog`, `lpr`, `news`, `uucp`, `cron`, `authpriv`, `ftp`, `ntp`, `security`, `console`, `solaris-cron`, `local0`-`local7` **Levels:** `emerg`, `alert`, `crit`, `err`, `warning`, `notice`, `info`, `debug` @@ -143,14 +156,50 @@ NoDelay=yes ExcludeSyslogFacility=auth authpriv ``` +**DTLS (encrypted UDP):** +```ini +[Network] +Address=192.168.1.100:4433 +Protocol=dtls +TLSCertificateAuthMode=warn +``` + +**TCP with filtering:** +```ini +[Network] +Address=192.168.1.100:514 +Protocol=tcp +ExcludeSyslogFacility=auth authpriv +ExcludeSyslogLevel=debug +``` + **Cloud service (Papertrail):** ```ini [Network] Address=logs7.papertrailapp.com:12345 Protocol=tls +LogFormat=rfc5424 +TLSCertificateAuthMode=deny +KeepAlive=yes +``` + +**Cloud service (Loggly):** +```ini +[Network] +Address=logs-01.loggly.com:6514 +Protocol=tls +LogFormat=rfc5424 +StructuredData=[YOUR-CUSTOMER-TOKEN@41058] +TLSCertificateAuthMode=deny +``` + +**Multicast:** +```ini +[Network] +Address=239.0.0.1:6000 ``` -**With structured data:** +**With structured data and message IDs:** ```ini [Network] Address=192.168.1.100:514 @@ -161,8 +210,52 @@ UseSysLogStructuredData=yes UseSysLogMsgId=yes ``` +**All journal namespaces:** +```ini +[Network] +Address=192.168.1.100:514 +Protocol=tcp +Namespace=* +``` + See the [`examples/`](examples/) directory for more production-ready configurations. +## Security + +systemd-netlogd runs with minimal privileges via systemd hardening: + +- Runs as dedicated `systemd-journal-netlog` user (not root) +- `ProtectSystem=strict`, `ProtectHome=yes`, `PrivateTmp=yes` +- `ProtectKernelTunables=yes`, `ProtectKernelModules=yes`, `ProtectKernelLogs=yes` +- `MemoryDenyWriteExecute=yes`, `LockPersonality=yes` +- `SystemCallArchitectures=native`, `PrivateDevices=yes` + +Audit the security posture: +```bash +sudo systemd-analyze security systemd-netlogd.service +``` + +Best practices: +- Use `Protocol=tls` for forwarding over untrusted networks +- Set `TLSCertificateAuthMode=deny` with a valid CA certificate in production +- Exclude sensitive logs: `ExcludeSyslogFacility=auth authpriv` + +See [SECURITY.md](SECURITY.md) for the full security policy and vulnerability reporting. + +## Signals + +| Signal | Action | +|--------|--------| +| `SIGTERM`, `SIGINT` | Graceful shutdown, save cursor state | +| `SIGUSR1` | Toggle debug log level | +| `SIGUSR2` | Reserved | + +```bash +# Enable debug logging temporarily +sudo kill -SIGUSR1 $(pidof systemd-netlogd) +journalctl -u systemd-netlogd -f +``` + ## Troubleshooting ```bash @@ -177,10 +270,7 @@ nc -u -vz remote-server 514 # UDP # Generate test log logger -p user.info "Test from systemd-netlogd" -# Enable debug logging temporarily -sudo kill -SIGUSR1 $(pidof systemd-netlogd) - -# Or persistently via systemd override +# Enable persistent debug logging sudo systemctl edit systemd-netlogd # Add: Environment=SYSTEMD_LOG_LEVEL=debug @@ -193,16 +283,24 @@ sudo rm /var/lib/systemd-netlogd/state sudo systemctl start systemd-netlogd ``` +## State Persistence + +The daemon saves its journal cursor to `/var/lib/systemd-netlogd/state` after each +successful forward. This ensures no message loss across restarts or network outages. +On startup, it resumes from the last saved position. + ## Documentation -- **[Man page](doc/index.rst)** — full reference (`man systemd-netlogd`) -- **[FAQ](FAQ.md)** — common questions and answers -- **[ARCHITECTURE.md](ARCHITECTURE.md)** — internal design and data flow -- **[TESTING.md](TESTING.md)** — test suite and validation guide -- **[CONTRIBUTING.md](CONTRIBUTING.md)** — development setup and contribution guide -- **[SECURITY.md](SECURITY.md)** — security policy and vulnerability reporting -- **[CHANGELOG.md](CHANGELOG.md)** — release history -- **[examples/](examples/)** — production-ready configuration examples +| Document | Description | +|----------|-------------| +| [Man page](doc/index.rst) | Full reference (`man systemd-netlogd`) | +| [FAQ](FAQ.md) | Common questions and answers | +| [ARCHITECTURE.md](ARCHITECTURE.md) | Internal design and data flow | +| [TESTING.md](TESTING.md) | Test suite and validation guide | +| [CONTRIBUTING.md](CONTRIBUTING.md) | Development setup and contribution guide | +| [SECURITY.md](SECURITY.md) | Security policy and vulnerability reporting | +| [CHANGELOG.md](CHANGELOG.md) | Release history | +| [examples/](examples/) | Production-ready configuration examples | ## Contributing @@ -218,7 +316,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for the full guide. ## License -LGPL-2.1-or-later — same license as systemd. See [LICENSE.LGPL2.1](LICENSE.LGPL2.1). +LGPL-2.1-or-later -- same license as systemd. See [LICENSE.LGPL2.1](LICENSE.LGPL2.1). ## Author