Skip to content

Generate a per-container SYSDBA password instead of sharing the build-time one - #52

Open
fdcastel wants to merge 4 commits into
FirebirdSQL:masterfrom
fdcastel:fix/issue-48-random-sysdba-password
Open

fdcastel wants to merge 4 commits into
FirebirdSQL:masterfrom
fdcastel:fix/issue-48-random-sysdba-password

Conversation

@fdcastel

@fdcastel fdcastel commented Sep 26, 2026 •

Copy link
Copy Markdown
Member

Fixes #48.

Depends on #49. This branch is stacked on fix/issue-47-fb3-sysdba-password, so the diff also shows #49's two commits until #49 is merged. Only the last two commits (2a1e256, 9199898) are new here.

Problem

When FIREBIRD_ROOT_PASSWORD is not set, the SYSDBA password is the one the Firebird installer generated at image build time. It is baked into an image layer, so every container of an image shares it, and anyone who can pull the image can read it from /opt/firebird/SYSDBA.password. A container started with port 3050 published and without FIREBIRD_ROOT_PASSWORD has SYSDBA protected by a publicly known password. FB4 and FB5 images are affected today. FB3 images will be too once #49 makes the installer's password actually work.

Fix

  • src/Dockerfile.template: after ./install.sh, record the SHA-256 checksum of the security database as shipped in the image (/opt/firebird/.security.fdb.sha256).
  • src/entrypoint.sh, when FIREBIRD_ROOT_PASSWORD is not set and the security database still matches that checksum:
    • generates a random 20-character alphanumeric password;
    • sets it with CREATE OR ALTER USER SYSDBA ... USING PLUGIN Srp (and Legacy_UserManager when FIREBIRD_USE_LEGACY_AUTH=true, like the existing FIREBIRD_ROOT_PASSWORD path);
    • rewrites /opt/firebird/SYSDBA.password in the installer's format (mode 0440).
  • Only the file's path is logged, not the password. Container logs are often readable by more people than the container itself (log aggregators, CI output).
  • Why a checksum instead of a "first start" marker: once the password is changed, the database no longer matches. Restarts of the same container therefore keep the password, and a recreated container gets a new one. A security database persisted outside the container and bind-mounted in (the allow the sysdba password to be set permanently without setting the environment variable FIREBIRD_ROOT_PASSWORD and without generating /opt/firebird/SYSDBA.password #5 use case) doesn't match either, so its SYSDBA password is never overwritten. A plain marker file would have reset it on every container recreation.
  • The behaviour when FIREBIRD_ROOT_PASSWORD is set is unchanged.
  • FIREBIRD_USER / FIREBIRD_PASSWORD are now validated before any initialization step. A missing FIREBIRD_PASSWORD fails the container before SYSDBA is changed (keeps FIREBIRD_USER_fails_without_password passing).
  • src/image.tests.ps1, new tests:
    • SYSDBA_password_is_generated_on_container_first_start:
      • the password differs from the image's and is not printed to the log;
      • the image's password is rejected;
      • the password is kept across docker restart.
    • FIREBIRD_USE_LEGACY_AUTH_generated_sysdba_password_works_with_legacy_auth: server restricted to AuthServer = Legacy_Auth.
    • SYSDBA_password_is_kept_for_bind_mounted_security_database: a security database with a known SYSDBA password, bind-mounted into a new container, keeps that password.
  • README: the FIREBIRD_ROOT_PASSWORD section no longer calls the installer's password "one-off", and describes the new behaviour.
  • DECISIONS.md: D-021. (D-020 is taken by Support running as a non-root user (firebird or any UID with GID 0) #51.)
  • generated/: updated.

Test plan

  • Local smoke test on firebirdsql/firebird:5.0.4, with the new entrypoint and checksum file mounted in:
    • a unique password on first start, and the build-time password is rejected;
    • the same password after restart;
    • Legacy_Auth-only login works;
    • a bind-mounted, already-modified security database is left untouched;
    • FIREBIRD_USER without a password fails with empty stdout.
  • Combined local build (master + Fix SYSDBA.password not working in Firebird 3 images #49 + Support running as a non-root user (firebird or any UID with GID 0) #51 + this PR), full suite with nothing excluded, trixie: 35/35 per version on 3.0.14, 4.0.7 and 5.0.4. That includes FIREBIRD_USER_fails_without_password and Support running as a non-root user (firebird or any UID with GID 0) #51's non-root tests that exercise the SYSDBA.password rewrite as UID 84 and 12345:0.
  • Fork CI, workflow_dispatch with distro-filter=trixie at 9199898: 36272737506 — success. amd64: all 19 releases (3.0.9 → 3.0.14, 4.0.0 → 4.0.7, 5.0.0 → 5.0.4). arm64: 5.0.0 → 5.0.4. 30/30 tests green on each image.

Bullseye is excluded from CI validation because of the unrelated bullseye-security 404 (#50).

…irebirdSQL#47)

The FB3 installer sets the generated SYSDBA password with 'gsec', which
links against libtommath.so.0 and libncurses.so.5. Both were provisioned
in RUN steps after install.sh, so gsec failed to load and the installer
silently carried on. Images shipped an untouched security3.fdb (no Srp
user, no PLG$SRP) with a SYSDBA.password that was never set, and every
Srp login failed with "Install incomplete".

Move the libtommath symlink and the libncurses5/libtinfo5 provisioning
into the main RUN step, ahead of install.sh. Add tests covering the
stock container's SYSDBA.password credentials. Record as D-019.
archive.ubuntu.com superseded 6.3-2ubuntu0.2 and the old .deb now
returns 404, breaking the Firebird 3 Noble build.
… start (issue FirebirdSQL#48)

When FIREBIRD_ROOT_PASSWORD is not set, the SYSDBA password was the one generated by the Firebird installer at image build time: the same for every container of an image, and readable by anyone who can pull it.

The entrypoint now generates a random password, sets it (Srp, plus Legacy_UserManager with FIREBIRD_USE_LEGACY_AUTH=true) and rewrites /opt/firebird/SYSDBA.password. Only the file's path is logged, not the password. It does so only while the security database still matches the checksum recorded at build time, so restarts keep the password and a bind-mounted security database (issue FirebirdSQL#5) is never touched.

See DECISIONS.md D-021.
…initialization step

set_sysdba now changes the security database even without FIREBIRD_ROOT_PASSWORD, so a missing FIREBIRD_PASSWORD was only detected after SYSDBA had been changed. Fail first, without changing anything (restores FIREBIRD_USER_fails_without_password).
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.

SYSDBA password in SYSDBA.password is a build-time constant shared by all containers of an image

1 participant