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

Merged
marcos-mendez merged 1 commit from fix/one-user-declaration-and-no-log-left-behind into main 2026-09-27 23:28:35 -03:00
marcos-mendez commented 2026-09-27 23:23:17 -03:00 (Migrated from github.com)

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: 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 - [x] `COVERAGE_THRESHOLD=100 tests/coverage.sh`: 100/100/100 over 70 tests - [x] 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
Sign in to join this conversation.
No description provided.