mirror of
https://github.com/Vateron-Media/XC_VM.git
synced 2026-10-25 19:03:14 +01:00
OPENSSL_EXTRA keys the stream tokens MAIN mints for the redirects an LB serves, and hmac_keys. It is config/openssl_extra, or the built-in default when that file is absent. The current installer writes a random value on a fresh MAIN, but nothing ships it to an LB, so an LB added with server:install runs on the default and rejects every token MAIN mints for it. Nothing showed which clusters are affected. Each node's cron:servers now publishes a keyed 64-bit fingerprint of its value (never the value) as server_hardware.openssl_extra_fp, in the UPDATE it already runs every minute. server:diagnose compares the node's fingerprint with the main's, from the main and on the node itself, and reports "OPENSSL_EXTRA mismatch: tokens minted on MAIN are rejected by this node". A node or main that does not publish one reads as "unknown (... not updated)"; proxies are skipped. No behaviour changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TQHeypQpfAXTdCysmi7b6a
40 lines
1.9 KiB
PHP
40 lines
1.9 KiB
PHP
<?php
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
use XcVm\Core\Config\OpensslExtra;
|
|
|
|
/**
|
|
* OpensslExtra — a MAIN and its LBs must hold the same OPENSSL_EXTRA, or the
|
|
* tokens MAIN mints for its redirects are rejected by the LB.
|
|
*
|
|
* fingerprint / reportedFingerprint: what each node publishes in
|
|
* servers.server_hardware, so the values can be compared without leaving the
|
|
* node.
|
|
*/
|
|
final class OpensslExtraTest extends TestCase {
|
|
|
|
public function testFingerprintIsAShortStableDigestThatHidesTheValue(): void {
|
|
$rSecret = 'fNiu3XD448xTDa27xoY4';
|
|
$rPrint = OpensslExtra::fingerprint($rSecret);
|
|
|
|
$this->assertSame($rPrint, OpensslExtra::fingerprint($rSecret));
|
|
$this->assertMatchesRegularExpression('/^[0-9a-f]{16}$/', $rPrint);
|
|
$this->assertNotSame(OpensslExtra::fingerprint('a'), OpensslExtra::fingerprint('b'));
|
|
$this->assertStringNotContainsString($rSecret, $rPrint);
|
|
$this->assertNotSame(substr(hash('sha256', $rSecret), 0, 16), $rPrint, 'keyed, not a bare hash of the value');
|
|
$this->assertNotSame(substr(md5($rSecret), 0, 16), $rPrint);
|
|
}
|
|
|
|
public function testReportedFingerprintIsReadFromServerHardware(): void {
|
|
$rPrint = OpensslExtra::fingerprint('x');
|
|
|
|
$this->assertSame($rPrint, OpensslExtra::reportedFingerprint(['server_hardware' => json_encode(['cores' => 4, OpensslExtra::HARDWARE_KEY => $rPrint])]));
|
|
$this->assertNull(OpensslExtra::reportedFingerprint(['server_hardware' => json_encode(['cores' => 4])]), 'node not updated yet');
|
|
$this->assertNull(OpensslExtra::reportedFingerprint(['server_hardware' => json_encode([OpensslExtra::HARDWARE_KEY => ''])]));
|
|
$this->assertNull(OpensslExtra::reportedFingerprint(['server_hardware' => json_encode([OpensslExtra::HARDWARE_KEY => 12])]));
|
|
$this->assertNull(OpensslExtra::reportedFingerprint(['server_hardware' => 'not json']));
|
|
$this->assertNull(OpensslExtra::reportedFingerprint(['server_hardware' => null]));
|
|
$this->assertNull(OpensslExtra::reportedFingerprint([]));
|
|
}
|
|
}
|