nixos/ulogd: init

Heavily based on original work by xvuko

Co-authored-by: xvuko <nix@vuko.pl>
This commit is contained in:
Philippe Hürlimann 2022-12-28 00:17:14 +01:00
parent 77763b4c88
commit bcbedfeefc
7 changed files with 147 additions and 1 deletions

View file

@ -67,6 +67,14 @@
<link xlink:href="options.html#opt-services.v2raya.enable">services.v2raya</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://www.netfilter.org/projects/ulogd/index.html">ulogd</link>,
a userspace logging daemon for netfilter/iptables related
logging. Available as
<link xlink:href="options.html#opt-services.ulogd.enable">services.ulogd</link>.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="sec-release-23.05-incompatibilities">

View file

@ -26,6 +26,8 @@ In addition to numerous new and upgraded packages, this release has the followin
- [v2rayA](https://v2raya.org), a Linux web GUI client of Project V which supports V2Ray, Xray, SS, SSR, Trojan and Pingtunnel. Available as [services.v2raya](options.html#opt-services.v2raya.enable).
- [ulogd](https://www.netfilter.org/projects/ulogd/index.html), a userspace logging daemon for netfilter/iptables related logging. Available as [services.ulogd](options.html#opt-services.ulogd.enable).
## Backward Incompatibilities {#sec-release-23.05-incompatibilities}
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->

View file

@ -520,6 +520,7 @@
./services/logging/syslog-ng.nix
./services/logging/syslogd.nix
./services/logging/vector.nix
./services/logging/ulogd.nix
./services/mail/clamsmtp.nix
./services/mail/davmail.nix
./services/mail/dkimproxy-out.nix

View file

@ -0,0 +1,48 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.ulogd;
settingsFormat = pkgs.formats.ini { };
settingsFile = settingsFormat.generate "ulogd.conf" cfg.settings;
in {
options = {
services.ulogd = {
enable = mkEnableOption (lib.mdDoc "ulogd");
settings = mkOption {
example = {
global.stack = "stack=log1:NFLOG,base1:BASE,pcap1:PCAP";
log1.group = 2;
pcap1 = {
file = "/var/log/ulogd.pcap";
sync = 1;
};
};
type = settingsFormat.type;
default = { };
description = lib.mdDoc "Configuration for ulogd. See {file}`/share/doc/ulogd/` in `pkgs.ulogd.doc`.";
};
logLevel = mkOption {
type = types.enum [ 1 3 5 7 8 ];
default = 5;
description = lib.mdDoc "Log level (1 = debug, 3 = info, 5 = notice, 7 = error, 8 = fatal)";
};
};
};
config = mkIf cfg.enable {
systemd.services.ulogd = {
description = "Ulogd Daemon";
wantedBy = [ "multi-user.target" ];
wants = [ "network-pre.target" ];
before = [ "network-pre.target" ];
serviceConfig = {
ExecStart = "${pkgs.ulogd}/bin/ulogd -c ${settingsFile} --verbose --loglevel ${toString cfg.logLevel}";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
};
};
};
}

View file

@ -681,6 +681,7 @@ in {
tuxguitar = handleTest ./tuxguitar.nix {};
ucarp = handleTest ./ucarp.nix {};
udisks2 = handleTest ./udisks2.nix {};
ulogd = handleTest ./ulogd.nix {};
unbound = handleTest ./unbound.nix {};
unifi = handleTest ./unifi.nix {};
unit-php = handleTest ./web-servers/unit-php.nix {};

84
nixos/tests/ulogd.nix Normal file
View file

@ -0,0 +1,84 @@
import ./make-test-python.nix ({ pkgs, lib, ... }: {
name = "ulogd";
meta = with lib; {
maintainers = with maintainers; [ p-h ];
};
nodes.machine = { ... }: {
networking.firewall.enable = false;
networking.nftables.enable = true;
networking.nftables.ruleset = ''
table inet filter {
chain input {
type filter hook input priority 0;
log group 2 accept
}
chain output {
type filter hook output priority 0; policy accept;
log group 2 accept
}
chain forward {
type filter hook forward priority 0; policy drop;
log group 2 accept
}
}
'';
services.ulogd = {
enable = true;
settings = {
global = {
logfile = "/var/log/ulogd.log";
stack = "log1:NFLOG,base1:BASE,pcap1:PCAP";
};
log1.group = 2;
pcap1 = {
file = "/var/log/ulogd.pcap";
sync = 1;
};
};
};
environment.systemPackages = with pkgs; [
tcpdump
];
};
testScript = ''
start_all()
machine.wait_for_unit("ulogd.service")
machine.wait_for_unit("network-online.target")
with subtest("Ulogd is running"):
machine.succeed("pgrep ulogd >&2")
# All packets show up twice in the logs
with subtest("Logs are collected"):
machine.succeed("ping -f 127.0.0.1 -c 5 >&2")
machine.succeed("sleep 2")
machine.wait_until_succeeds("du /var/log/ulogd.pcap >&2")
_, echo_request_packets = machine.execute("tcpdump -r /var/log/ulogd.pcap icmp[0] == 8 and host 127.0.0.1")
expected, actual = 5*2, len(echo_request_packets.splitlines())
assert expected == actual, f"Expected {expected} packets, got: {actual}"
_, echo_reply_packets = machine.execute("tcpdump -r /var/log/ulogd.pcap icmp[0] == 0 and host 127.0.0.1")
expected, actual = 5*2, len(echo_reply_packets.splitlines())
assert expected == actual, f"Expected {expected} packets, got: {actual}"
with subtest("Reloading service reopens log file"):
machine.succeed("mv /var/log/ulogd.pcap /var/log/old_ulogd.pcap")
machine.succeed("systemctl reload ulogd.service")
machine.succeed("ping -f 127.0.0.1 -c 5 >&2")
machine.succeed("sleep 2")
_, echo_request_packets = machine.execute("tcpdump -r /var/log/ulogd.pcap icmp[0] == 8 and host 127.0.0.1")
expected, actual = 5*2, len(echo_request_packets.splitlines())
assert expected == actual, f"Expected {expected} packets, got: {actual}"
_, echo_reply_packets = machine.execute("tcpdump -r /var/log/ulogd.pcap icmp[0] == 0 and host 127.0.0.1")
expected, actual = 5*2, len(echo_reply_packets.splitlines())
assert expected == actual, f"Expected {expected} packets, got: {actual}"
'';
})

View file

@ -1,6 +1,6 @@
{ stdenv, lib, fetchurl, gnumake, libnetfilter_acct, libnetfilter_conntrack
, libnetfilter_log, libmnl, libnfnetlink, automake, autoconf, autogen, libtool
, pkg-config, libpcap, linuxdoc-tools, autoreconfHook }:
, pkg-config, libpcap, linuxdoc-tools, autoreconfHook, nixosTests }:
stdenv.mkDerivation rec {
version = "2.0.8";
@ -49,6 +49,8 @@ stdenv.mkDerivation rec {
linuxdoc-tools
];
passthru.tests = { inherit (nixosTests) ulogd; };
meta = with lib; {
description = "Userspace logging daemon for netfilter/iptables";