diff --git a/modules/lamassu-lnbits.nix b/modules/lamassu-lnbits.nix index ec25f2b..7bb6b4e 100644 --- a/modules/lamassu-lnbits.nix +++ b/modules/lamassu-lnbits.nix @@ -101,8 +101,11 @@ in user = mkOption { type = types.str; default = cfg.user; - description = "PostgreSQL username (uses peer authentication via Unix socket)"; + description = "PostgreSQL username"; }; + + # Password is managed by nix-bitcoin secrets system. + # See: ${secretsDir}/lamassu-db-password }; hostname = mkOption { @@ -181,10 +184,15 @@ in user = cfg.user; permissions = "444"; # World readable (it's a public cert) }; + lamassu-db-password = { + user = cfg.user; + group = "postgres"; # PostgreSQL needs to read this too + }; }; nix-bitcoin.generateSecretsCmds.lamassu = '' makeCert lamassu '${nbLib.mkCertExtraAltNames cfg.certificate}' + makePasswordSecret lamassu-db-password ''; # ═══════════════════════════════════════════════════════════════════════════ @@ -192,7 +200,7 @@ in # NOTE: Nginx reverse proxy is disabled. See docs/lamassu-future-nginx.md # for future implementation when --ui-port is added to upstream. - # Enable PostgreSQL with peer authentication (no password needed) + # Enable PostgreSQL services.postgresql = { enable = true; package = pkgs.postgresql_15; @@ -203,6 +211,13 @@ in ensureDBOwnership = true; } ]; + # Enable password authentication for localhost connections + authentication = pkgs.lib.mkOverride 10 '' + # TYPE DATABASE USER ADDRESS METHOD + local all all peer + host all all 127.0.0.1/32 md5 + host all all ::1/128 md5 + ''; }; # Create system users and groups @@ -232,17 +247,47 @@ in "Z '${cfg.package}' 0755 ${cfg.user} ${cfg.group} - -" ]; + # Service to set PostgreSQL password from nix-bitcoin secrets + systemd.services.lamassu-postgres-setup = { + description = "Setup PostgreSQL password for lamassu-server"; + wantedBy = [ "multi-user.target" ]; + after = [ "postgresql.service" "nix-bitcoin-secrets.target" ]; + wants = [ "postgresql.service" ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + User = "postgres"; + }; + script = '' + # Wait for user to exist, then set password from secrets + for i in {1..30}; do + if ${pkgs.postgresql}/bin/psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='${cfg.database.user}'" | grep -q 1; then + echo "Setting password for ${cfg.database.user}..." + password=$(cat ${secretsDir}/lamassu-db-password) + ${pkgs.postgresql}/bin/psql -c "ALTER USER \"${cfg.database.user}\" WITH PASSWORD '$password';" + exit 0 + fi + echo "Waiting for user ${cfg.database.user} to be created (attempt $i/30)..." + sleep 1 + done + echo "ERROR: User ${cfg.database.user} was not created after 30 seconds" + exit 1 + ''; + }; + # Main lamassu server service systemd.services.lamassu-server = { description = "Lamassu Bitcoin ATM Server"; wantedBy = [ "multi-user.target" ]; - after = [ "network.target" "postgresql.service" "nix-bitcoin-secrets.target" ]; - wants = [ "postgresql.service" ]; + after = [ "network.target" "postgresql.service" "lamassu-postgres-setup.service" "nix-bitcoin-secrets.target" ]; + wants = [ "postgresql.service" "lamassu-postgres-setup.service" ]; environment = { NODE_ENV = "production"; - # Database configuration (peer auth via Unix socket) + # Database configuration (password read at runtime from secrets) + POSTGRES_HOST = "127.0.0.1"; + POSTGRES_PORT = "5432"; POSTGRES_DB = cfg.database.name; POSTGRES_USER = cfg.database.user; @@ -282,8 +327,10 @@ in #!/bin/bash set -euo pipefail export PATH=${pkgs.nodejs_22}/bin:$PATH - # Use Unix socket for peer authentication (no password needed) - export DATABASE_URL="postgresql://${cfg.database.user}@/${cfg.database.name}?host=/run/postgresql" + # Read database password from nix-bitcoin secrets + DB_PASSWORD=$(cat ${secretsDir}/lamassu-db-password) + export DATABASE_URL="postgresql://${cfg.database.user}:$DB_PASSWORD@127.0.0.1:5432/${cfg.database.name}" + export POSTGRES_PASSWORD="$DB_PASSWORD" export NODE_PATH=${cfg.package}/node_modules:${cfg.package}/packages/server/node_modules cd ${cfg.package} exec "$@" @@ -344,7 +391,9 @@ in CA_PATH = cfg.certPath; CERT_PATH = cfg.certPath; KEY_PATH = cfg.keyPath; - # Database configuration (peer auth via Unix socket) + # Database configuration (password read at runtime from secrets) + POSTGRES_HOST = "127.0.0.1"; + POSTGRES_PORT = "5432"; POSTGRES_DB = cfg.database.name; POSTGRES_USER = cfg.database.user; MNEMONIC_PATH = "${cfg.dataDir}/lamassu-mnemonic"; @@ -361,8 +410,10 @@ in #!/bin/bash set -euo pipefail export PATH=${pkgs.nodejs_22}/bin:$PATH - # Use Unix socket for peer authentication (no password needed) - export DATABASE_URL="postgresql://${cfg.database.user}@/${cfg.database.name}?host=/run/postgresql" + # Read database password from nix-bitcoin secrets + DB_PASSWORD=$(cat ${secretsDir}/lamassu-db-password) + export DATABASE_URL="postgresql://${cfg.database.user}:$DB_PASSWORD@127.0.0.1:5432/${cfg.database.name}" + export POSTGRES_PASSWORD="$DB_PASSWORD" export NODE_PATH=${cfg.package}/node_modules:${cfg.package}/packages/admin-server/node_modules cd ${cfg.package} exec "$@" @@ -394,12 +445,16 @@ in nodePackages.pnpm postgresql (writeShellScriptBin "lamassu-register-user" '' - # Use Unix socket for peer authentication (no password needed) + # Read database password from nix-bitcoin secrets + DB_PASSWORD=$(cat ${secretsDir}/lamassu-db-password) export NODE_PATH="${cfg.package}/node_modules:${cfg.package}/packages/server/node_modules" - export DATABASE_URL="postgresql://${cfg.database.user}@/${cfg.database.name}?host=/run/postgresql" + export DATABASE_URL="postgresql://${cfg.database.user}:$DB_PASSWORD@127.0.0.1:5432/${cfg.database.name}" export HOSTNAME="${cfg.hostname}" + export POSTGRES_HOST="127.0.0.1" + export POSTGRES_PORT="5432" export POSTGRES_DB="${cfg.database.name}" export POSTGRES_USER="${cfg.database.user}" + export POSTGRES_PASSWORD="$DB_PASSWORD" export SKIP_2FA="${if cfg.skip2FA then "true" else "false"}" sudo -E -u ${cfg.user} bash -c "cd ${cfg.package}/packages/server && ${pkgs.nodejs_22}/bin/node bin/lamassu-register \"\$@\"" -- "$@"