Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/tests: test hardened logrotate service #345466

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 118 additions & 64 deletions nixos/tests/logrotate.nix
Original file line number Diff line number Diff line change
@@ -1,82 +1,130 @@
# Test logrotate service works and is enabled by default

let
importTest = { ... }: {
services.logrotate.settings.import = {
olddir = false;
importTest =
{ ... }:
{
services.logrotate.settings.import = {
olddir = false;
};
};
};

in

import ./make-test-python.nix ({ pkgs, ... }: rec {
name = "logrotate";
meta = with pkgs.lib.maintainers; {
maintainers = [ martinetd ];
};

nodes = {
defaultMachine = { ... }: {
services.logrotate.enable = true;
};
failingMachine = { ... }: {
services.logrotate = {
enable = true;
configFile = pkgs.writeText "logrotate.conf" ''
# self-written config file
su notarealuser notagroupeither
'';
};
import ./make-test-python.nix (
{ pkgs, lib, ... }:
rec {
name = "logrotate";
meta = with pkgs.lib.maintainers; {
maintainers = [ martinetd ];
};
machine = { config, ... }: {
imports = [ importTest ];

services.logrotate = {
enable = true;
settings = {
# remove default frequency header and add another
header = {
frequency = null;
delaycompress = true;
};
# extra global setting... affecting nothing
last_line = {
global = true;
priority = 2000;
shred = true;
};
# using mail somewhere should add --mail to logrotate invocation
sendmail = {
mail = "[email protected]";
};
# postrotate should be suffixed by 'endscript'
postrotate = {
postrotate = "touch /dev/null";
nodes = {
defaultMachine =
{ ... }:
{
services.logrotate.enable = true;
};
failingMachine =
{ ... }:
{
services.logrotate = {
enable = true;
configFile = pkgs.writeText "logrotate.conf" ''
# self-written config file
su notarealuser notagroupeither
'';
};
# check checkConfig works as expected: there is nothing to check here
# except that the file build passes
checkConf = {
su = "root utmp";
createolddir = "0750 root utmp";
create = "root utmp";
"create " = "0750 root utmp";
};
machine =
{ config, ... }:
{
imports = [ importTest ];

services.logrotate = {
enable = true;
settings = {
# remove default frequency header and add another
header = {
frequency = null;
delaycompress = true;
};
# extra global setting... affecting nothing
last_line = {
global = true;
priority = 2000;
shred = true;
};
# using mail somewhere should add --mail to logrotate invocation
sendmail = {
mail = "[email protected]";
};
# postrotate should be suffixed by 'endscript'
postrotate = {
postrotate = "touch /dev/null";
};
# check checkConfig works as expected: there is nothing to check here
# except that the file build passes
checkConf = {
su = "root utmp";
createolddir = "0750 root utmp";
create = "root utmp";
"create " = "0750 root utmp";
};
# multiple paths should be aggregated
multipath = {
files = [
"file1"
"file2"
];
};
# overriding imported path should keep existing attributes
# (e.g. olddir is still set)
import = {
notifempty = true;
};
};
};
# multiple paths should be aggregated
multipath = {
files = [ "file1" "file2" ];
};
keepPerm =
{ ... }:
{
systemd.services.foo =
let
exe = pkgs.writeShellScript "exe" ''
while true; do
echo 0123456789abcdef >> /var/log/foo/log
sleep 1s
done
'';
in
{
wantedBy = [ "multi-user.target" ];
serviceConfig = {
DynamicUser = true;
LogsDirectory = "foo";
ExecStart = "${exe}";
};
};

systemd.services.logrotate = {
serviceConfig = {
RestrictAddressFamilies = lib.mkForce "AF_UNIX";
};
};
# overriding imported path should keep existing attributes
# (e.g. olddir is still set)
import = {
notifempty = true;

services.logrotate = {
enable = true;
settings.foo = {
files = [ "/var/log/private/foo/log" ];
size = "16";
postrotate = "systemctl restart foo";
};
};
};
};
};
};

testScript =
''
testScript = ''
with subtest("whether logrotate works"):
# we must rotate once first to create logrotate stamp
defaultMachine.succeed("systemctl start logrotate.service")
Expand Down Expand Up @@ -126,8 +174,14 @@ import ./make-test-python.nix ({ pkgs, ... }: rec {
info = failingMachine.get_unit_info("logrotate-checkconf.service")
if info["ActiveState"] != "failed":
raise Exception('logrotate-checkconf.service was not failed')
with subtest("Keep permission"):
keepPerm.wait_for_unit("foo.service")
keepPerm.wait_for_file("/var/log/private/foo/log", 3)
keepPerm.succeed("systemctl start logrotate.service")
keepPerm.wait_for_file("/var/log/private/foo/log.1", 3)

machine.log(machine.execute("systemd-analyze security logrotate.service | grep -v ✓")[1])

'';
})
}
)