From d347bbc0d24b6d12583edd189413e1641bf54d05 Mon Sep 17 00:00:00 2001 From: Oleksandr Usov Date: Sat, 22 Aug 2026 15:44:18 +0100 Subject: [PATCH 1/2] udp514-journal: init at 0.3.0 --- pkgs/by-name/ud/udp514-journal/package.nix | 49 ++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 pkgs/by-name/ud/udp514-journal/package.nix diff --git a/pkgs/by-name/ud/udp514-journal/package.nix b/pkgs/by-name/ud/udp514-journal/package.nix new file mode 100644 index 000000000000..dde930b7e5ea --- /dev/null +++ b/pkgs/by-name/ud/udp514-journal/package.nix @@ -0,0 +1,49 @@ +{ + stdenv, + lib, + fetchFromGitHub, + systemdLibs, + pkg-config, + discount +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "udp514-journal"; + version = "0.3.0"; + + src = fetchFromGitHub { + owner = "eworm-de"; + repo = "udp514-journal"; + tag = finalAttrs.version; + hash = "sha256-ufxxeW2G6C/DEzVgVVrQjUsI4tDvaqi5VrXZIr2Eh7Y="; + }; + + buildInputs = [ + systemdLibs + ]; + nativeBuildInputs = [ + pkg-config + discount + ]; + + # brute-force patching - remove /usr/ from install paths + postPatch = '' + substituteInPlace Makefile --replace-fail "$(DESTDIR)/usr/" "$(DESTDIR)/" + ''; + + makeFlags = [ "DESTDIR=$(out)" ]; + installTargets = [ + "install-bin" + "install-doc" + ]; + + strictDeps = true; + __structuredAttrs = true; + + meta = with lib; { + description = "Forward syslog from network (udp/514) to journal"; + homepage = "https://github.com/eworm-de/udp514-journal"; + license = with licenses; [ gpl3Plus ]; + maintainers = with maintainers; [ usovalx ]; + }; +}) From f1935fe4c97588012a41aa2cf2cb9d466999dcd3 Mon Sep 17 00:00:00 2001 From: Oleksandr Usov Date: Sat, 22 Aug 2026 15:44:39 +0100 Subject: [PATCH 2/2] nixos/udp514-journal: add module --- .../manual/release-notes/rl-2611.section.md | 2 + nixos/modules/module-list.nix | 1 + .../services/logging/udp514-journal.nix | 95 +++++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/udp514-journal.nix | 26 +++++ pkgs/by-name/ud/udp514-journal/package.nix | 5 +- 6 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 nixos/modules/services/logging/udp514-journal.nix create mode 100644 nixos/tests/udp514-journal.nix diff --git a/nixos/doc/manual/release-notes/rl-2611.section.md b/nixos/doc/manual/release-notes/rl-2611.section.md index fafd7c8af491..42100f026832 100644 --- a/nixos/doc/manual/release-notes/rl-2611.section.md +++ b/nixos/doc/manual/release-notes/rl-2611.section.md @@ -38,6 +38,8 @@ - [Moonlight Qt](https://moonlight-stream.org/), a client for playing your PC games on almost any device. Available as [programs.moonlight-qt](#opt-programs.moonlight-qt.enable). +- [udp514-journal](https://github.com/eworm-de/udp514-journal), a service to forward remote syslog messages to systemd-journal. Available as [services.udp514-journal](#opt-services.udp514-journal.enable). + - [RomM](https://romm.app/), a self-hosted ROM manager and player. Available as [services.romm](#opt-services.romm.enable). - [scx_loader](https://github.com/sched-ext/scx-loader), a system daemon and DBus-based loader for sched_ext schedulers. `scxctl` is the command-line client for interacting with the loader, allowing users to switch schedulers, modes, and arguments dynamically. Available as [services.scx-loader](#opt-services.scx-loader.enable) diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index d981c49c7813..d51bfac817c8 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -781,6 +781,7 @@ ./services/logging/syslog-ng.nix ./services/logging/syslogd.nix ./services/logging/SystemdJournal2Gelf.nix + ./services/logging/udp514-journal.nix ./services/logging/ulogd.nix ./services/logging/vector.nix ./services/mail/automx2.nix diff --git a/nixos/modules/services/logging/udp514-journal.nix b/nixos/modules/services/logging/udp514-journal.nix new file mode 100644 index 000000000000..d403821fd1cc --- /dev/null +++ b/nixos/modules/services/logging/udp514-journal.nix @@ -0,0 +1,95 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + cfg = config.services.udp514-journal; + description = "Forward syslog from network (udp/514) to journal"; +in +{ + options = { + services.udp514-journal = { + enable = lib.mkEnableOption "the udp514-journal systemd socket/service"; + + openFirewall = lib.mkEnableOption "" // { + description = "Whether to open the port in the firewall."; + }; + + port = lib.mkOption { + type = lib.types.port; + default = 514; + description = "Port to listen on"; + }; + + package = lib.mkPackageOption pkgs "udp514-journal" { }; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.sockets.udp514-journal = { + enable = true; + name = "udp514-journal.socket"; + inherit description; + listenDatagrams = [ (builtins.toString cfg.port) ]; + wantedBy = [ "sockets.target" ]; + }; + + systemd.services.udp514-journal = { + enable = true; + name = "udp514-journal.service"; + inherit description; + requires = [ + "systemd-journald.socket" + "udp514-journal.socket" + ]; + serviceConfig = { + Type = "notify"; + Restart = "always"; + ExecStart = "${cfg.package}/bin/udp514-journal"; + DynamicUser = "on"; + CapabilityBoundingSet = ""; + AmbientCapabilities = ""; + ProtectSystem = "strict"; + ProtectHome = "on"; + PrivateDevices = "on"; + PrivateTmp = true; + PrivateUsers = "self"; + PrivateNetwork = "on"; + RestrictAddressFamilies = [ "AF_UNIX" ]; + RestrictNamespaces = true; + RestrictSUIDSGID = true; + RestrictRealtime = true; + LockPersonality = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service" + "~@privileged" + "~@resources" + ]; + ProtectClock = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = "on"; + ProtectControlGroups = "strict"; + ProtectProc = "noaccess"; + ProcSubset = "pid"; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + MemoryMax = "5M"; + UMask = "0077"; + }; + confinement = { + enable = true; + binSh = null; + }; + }; + + networking.firewall.allowedUDPPorts = lib.mkIf cfg.openFirewall [ cfg.port ]; + }; + + meta.maintainers = with lib.maintainers; [ usovalx ]; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 647f548ba3d3..85a1d5e00919 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -1822,6 +1822,7 @@ in ucarp = runTest ./ucarp.nix; udisks2 = runTest ./udisks2.nix; udp-over-tcp = runTest ./udp-over-tcp.nix; + udp514-journal = runTest ./udp514-journal.nix; ulogd = runTest ./ulogd/ulogd.nix; umami = runTest ./web-apps/umami.nix; umurmur = runTest ./umurmur.nix; diff --git a/nixos/tests/udp514-journal.nix b/nixos/tests/udp514-journal.nix new file mode 100644 index 000000000000..e3cf398e5629 --- /dev/null +++ b/nixos/tests/udp514-journal.nix @@ -0,0 +1,26 @@ +{ + lib, + pkgs, + ... +}: +{ + name = "udp514-journal"; + meta.maintainers = with lib.maintainers; [ usovalx ]; + + containers.machine = { + services.udp514-journal.enable = true; + environment.systemPackages = [ pkgs.netcat ]; + }; + + testScript = '' + import datetime + start_all() + + machine.wait_for_unit("udp514-journal.socket"); + + # send a test log entry via UDP, RFC 5424 format + machine.execute('echo "<34>1 2026-08-01T00:24:15.123+01:00 router01 - testing" | nc -w1 -u localhost 514') + + machine.wait_until_succeeds('journalctl -u udp514-journal --grep "router01 - testing"', timeout = datetime.timedelta(seconds=60)) + ''; +} diff --git a/pkgs/by-name/ud/udp514-journal/package.nix b/pkgs/by-name/ud/udp514-journal/package.nix index dde930b7e5ea..24b2fde56f61 100644 --- a/pkgs/by-name/ud/udp514-journal/package.nix +++ b/pkgs/by-name/ud/udp514-journal/package.nix @@ -4,7 +4,8 @@ fetchFromGitHub, systemdLibs, pkg-config, - discount + discount, + nixosTests, }: stdenv.mkDerivation (finalAttrs: { @@ -40,6 +41,8 @@ stdenv.mkDerivation (finalAttrs: { strictDeps = true; __structuredAttrs = true; + passthru.tests.nixos = nixosTests.udp514-journal; + meta = with lib; { description = "Forward syslog from network (udp/514) to journal"; homepage = "https://github.com/eworm-de/udp514-journal";