wg_ip ?: $hub->allocateIp(); $previous = $host->wg_pubkey; $code = Str::random(32); $host->forceFill([ 'wg_ip' => $ip, 'wg_pubkey' => $keypair->publicKey, 'enrolment_code_hash' => self::hash($code), 'enrolment_expires_at' => now()->addHours(self::LIFETIME_HOURS), // Ein neuer Code macht den alten wertlos. Sonst hätte eine Maschine, // die im Rettungssystem hängengeblieben ist, weiter einen gültigen // Ausweis für einen Host, den der Betreiber gerade neu übernimmt. 'enrolment_used_at' => null, ])->save(); // Der Peer wird NACH dem Speichern eingereiht, und nicht hier // eingetragen: `wg set` gelingt nur im Provisioning-Container, dem // einzigen mit NET_ADMIN und `wg0`. Der Web-Request lief dagegen im // `app`-Container — dort scheiterte er, und das Anlegen eines Hosts // endete in einem 500, bevor der Betreiber seinen Code je zu sehen bekam. // // Nach dem Speichern, weil der Auftrag den Sollzustand aus der Zeile // liest. Bei `QUEUE_CONNECTION=sync` — der Testsuite — läuft er sofort, // und die Reihenfolge ist dann nicht Stilfrage, sondern Bedingung. ApplyHostVpnPeer::dispatch($host->id, $previous); return [ 'code' => $code, 'private_key' => $keypair->privateKey, 'public_key' => $keypair->publicKey, 'wg_ip' => $ip, ]; } /** * Löst einen gültigen, unverbrauchten Code auf, OHNE ihn zu verbrauchen. * * Das ist der Weg für `/host/progress`: die Fortschrittsmeldungen kommen vor * der Registrierung, und würden sie den Code verbrauchen, könnte der Host * sich nach seiner ersten Meldung nie mehr registrieren. */ public static function resolve(string $code): ?Host { if ($code === '') { return null; } return Host::query() ->where('enrolment_code_hash', self::hash($code)) ->whereNull('enrolment_used_at') ->where('enrolment_expires_at', '>', now()) ->first(); } /** Löst einen Code auf und verbraucht ihn. Der Weg für `/host/register`. */ public static function claim(string $code): ?Host { $host = self::resolve($code); if ($host === null) { return null; } $host->forceFill(['enrolment_used_at' => now()])->save(); return $host; } }