Skip to content

Declare the account once, and leave no log file the service cannot write - #3

Merged
marcos-mendez merged 1 commit into
mainfrom
fix/one-user-declaration-and-no-log-left-behind
Sep 28, 2026
Merged

marcos-mendez merged 1 commit into
mainfrom
fix/one-user-declaration-and-no-log-left-behind

Conversation

@marcos-mendez

Copy link
Copy Markdown
Contributor

Two defects, both found by booting the layer, and neither findable by the build: the build's own checks passed, because a build runs everything as root.

A user may be declared only once

20-keel-acl.conf published the administrative account as user admin off, the way keel-mariadb publishes an account with a password hash no input produces, and firstboot.d/35redispass declared it again with its digest. Redis refuses that outright:

Error in user declaration 'admin': Duplicate user found.
A user can only be defined once in config files

Measured on the booted appliance, where it left redis-server.service in a restart loop and 35redispass failing with exit 1. The build time fragment names no administrative account now, and the first boot names it once. An account that is not declared cannot authenticate either, which is the property that mattered.

A log file the service cannot write

Redis opens every value its logfile setting is ever given, so the path in the packaged configuration is created even though the check passes --logfile pointing into its own scratch directory. The check runs as root:

redis-server[524]: *** FATAL CONFIG FILE ERROR (Redis 8.0.2) ***
redis-server[524]: Can't open the log file: Permission denied

/var/log/redis/redis-server.log, owned by root, in a directory owned by the redis user: a service that cannot start on any machine built from the layer. The package ships no such file and redis makes its own at its first start, as its own user, so the check removes an empty one and leaves one with anything in it alone.

The comparison that settled whose defect it was: the nodejs-nginx layer installs redis-server too, its /var/log/redis is empty, and the forum container built from it runs redis with a redis owned log. Nothing in the package or the common tree does this. The check did.

The corrected design, proved on the booted machine before this was written

service: active
authenticate over IPv6 with the declared secret: PONG
write and read a key: OK / hello
wrong secret: AUTH failed: WRONGPASS ...
keel inspect: database.server.engine redis, role standalone, listen 127.0.0.1 and ::1
GET without a secret: NOPERM

Coverage

70 bats tests, three measured files at 100 percent each, 129 lines. The redis-server stub in tests/conf.bats opens the packaged log file the way redis does now: the test would have caught this, and did not before, because the stub was more polite than the program.

Test plan

  • COVERAGE_THRESHOLD=100 tests/coverage.sh: 100/100/100 over 70 tests
  • Both fixes proved by hand in the booted container of the failing layer
  • tests / coverage green here
  • The layer rebuilt at this pin, and the boot test green end to end

Two defects, both found by booting the layer, and neither findable by the
build: the build's own checks passed, because a build runs everything as
root.

A user may be declared only once
--------------------------------

20-keel-acl.conf published the administrative account as "user admin off",
the way keel-mariadb publishes an account with a password hash no input
produces, and firstboot.d/35redispass declared it again with its digest.
Redis refuses that outright:

    Error in user declaration 'admin': Duplicate user found.
    A user can only be defined once in config files

Measured on the booted appliance, where it left redis-server.service in a
restart loop and 35redispass failing with exit 1. The build time fragment
names no administrative account now, and the first boot names it once. An
account that is not declared cannot authenticate either, which is the
property that mattered.

A log file the service cannot write
-----------------------------------

Redis opens every value its logfile setting is ever given, so the path in
the packaged configuration is created even though the check passes
--logfile pointing into its own scratch directory. The check runs as root:

    redis-server[524]: *** FATAL CONFIG FILE ERROR (Redis 8.0.2) ***
    redis-server[524]: Can't open the log file: Permission denied

/var/log/redis/redis-server.log, owned by root, in a directory owned by the
redis user, which is a service that cannot start on any machine built from
the layer. The package ships no such file and redis makes its own at its
first start, as its own user, so the check removes an empty one and leaves
one with anything in it alone.

The comparison that settled whose defect it was: the nodejs-nginx layer
installs redis-server too and its /var/log/redis is empty, and the forum
container built from it runs redis with a redis owned log. Nothing in the
package or the common tree does this. The check did.

Tests
-----

70 bats tests, three measured files at 100 percent each (129 lines). The
conf stub opens the packaged log file the way redis does, so the test would
have caught this; it did not before, because the stub was more polite than
the program.
@marcos-mendez
marcos-mendez merged commit 9b5d29e into main Sep 28, 2026
2 checks passed
@marcos-mendez
marcos-mendez deleted the fix/one-user-declaration-and-no-log-left-behind branch September 28, 2026 02:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant