Hardened systemd deployment contract for read-only Monero observer
This commit is contained in:
@@ -28,3 +28,24 @@ test('database HBA requires TLS+SCRAM over TCP and provisioning refuses partial
|
||||
assert.match(setup, /subjectAltName=DNS:database/);
|
||||
assert.match(setup, /-checkend/);
|
||||
});
|
||||
|
||||
test('standalone Monero observer service is non-root, filesystem-hardened and has no public listener', async () => {
|
||||
const unit = await read('deploy/systemd/wikideck-monero-observer.service');
|
||||
const guide = await read('deploy/systemd/README.md');
|
||||
const observer = JSON.parse(await read('deploy/systemd/wallet-rpc.example.json')) as { network: string; url: string };
|
||||
const mtls = JSON.parse(await read('deploy/systemd/mtls.example.json')) as { url: string; clientPrivateKeyFile: string };
|
||||
assert.match(unit, /User=wikideck-observer/);
|
||||
assert.match(unit, /ProtectSystem=strict/);
|
||||
assert.match(unit, /ProtectHome=true/);
|
||||
assert.match(unit, /NoNewPrivileges=true/);
|
||||
assert.match(unit, /CapabilityBoundingSet=/);
|
||||
assert.match(unit, /RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX/);
|
||||
assert.match(unit, /WIKIDECK_MONERO_OBSERVER_WORKER=1/);
|
||||
assert.doesNotMatch(unit, /^\s*(?:ListenStream|ListenDatagram|SocketUser)=/m);
|
||||
assert.equal(observer.network, 'mainnet');
|
||||
assert.equal(observer.url, mtls.url);
|
||||
assert.equal(mtls.clientPrivateKeyFile, '/etc/wikideck/monero-observer/client.key');
|
||||
assert.match(guide, /migrate-mainnet-schema/);
|
||||
assert.match(guide, /does \*\*not\*\* issue customer deposit addresses/);
|
||||
assert.doesNotMatch(`${unit}\n${guide}`, /(?:password|api[_-]?key)\s*[:=]\s*[^\s<]+/i);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user