mirror of
git://f0xx.org/android_cast
synced 2026-07-29 03:38:52 +03:00
fix(ra): re-apply wg peers on connect and improve sync_wg_peers
Re-run wg set for existing session keys on each connect so peers survive wg0 restarts. sync_wg_peers now reconciles active sessions, reports provision_peers/live peer state, and lists broken/orphan peers before prune. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -25,19 +25,61 @@ foreach ($argv as $arg) {
|
||||
}
|
||||
|
||||
RemoteAccessRepository::ensureSchema();
|
||||
|
||||
$livePeers = WireGuardPeerProvisioner::listPeerDumpRows();
|
||||
$keep = RemoteAccessRepository::activeWireGuardSessionPublicKeys();
|
||||
$reconciled = RemoteAccessRepository::reconcileActiveWireGuardPeers($dryRun);
|
||||
$pruned = RemoteAccessRepository::pruneOrphanWireGuardPeers($dryRun);
|
||||
|
||||
fwrite(STDOUT, 'mode=' . ($dryRun ? 'dry-run' : 'apply') . "\n");
|
||||
fwrite(STDOUT, 'provision_peers=' . (WireGuardPeerProvisioner::isEnabled() ? 'true' : 'false') . "\n");
|
||||
fwrite(STDOUT, 'live_wg_peers=' . count($livePeers) . "\n");
|
||||
fwrite(STDOUT, 'active_session_peers=' . count($keep) . "\n");
|
||||
fwrite(STDOUT, 'reconciled_sessions=' . count($reconciled) . "\n");
|
||||
fwrite(STDOUT, 'pruned_peers=' . count($pruned) . "\n");
|
||||
|
||||
foreach ($reconciled as $row) {
|
||||
$pub = (string) ($row['public_key'] ?? '');
|
||||
$short = strlen($pub) > 12 ? substr($pub, 0, 8) . '…' : $pub;
|
||||
fwrite(
|
||||
STDOUT,
|
||||
sprintf(
|
||||
" reconcile %s allowed_ips=%s ok=%s\n",
|
||||
$short,
|
||||
(string) ($row['client_address'] ?? ''),
|
||||
($row['ok'] ?? false) ? 'true' : 'false'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($livePeers as $row) {
|
||||
$pub = (string) ($row['public_key'] ?? '');
|
||||
$allowed = trim((string) ($row['allowed_ips'] ?? ''));
|
||||
$short = strlen($pub) > 12 ? substr($pub, 0, 8) . '…' : $pub;
|
||||
$broken = ($allowed === '' || $allowed === '(none)');
|
||||
$orphan = !in_array($pub, $keep, true);
|
||||
if (!$broken && !$orphan) {
|
||||
continue;
|
||||
}
|
||||
fwrite(
|
||||
STDOUT,
|
||||
sprintf(
|
||||
" live %s allowed_ips=%s broken=%s orphan=%s\n",
|
||||
$short,
|
||||
$allowed === '' ? '(empty)' : $allowed,
|
||||
$broken ? 'true' : 'false',
|
||||
$orphan ? 'true' : 'false'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($pruned as $row) {
|
||||
$pub = $row['public_key'] ?? '';
|
||||
$short = strlen($pub) > 12 ? substr($pub, 0, 8) . '…' : $pub;
|
||||
fwrite(
|
||||
STDOUT,
|
||||
sprintf(
|
||||
" %s reason=%s allowed_ips=%s\n",
|
||||
" pruned %s reason=%s allowed_ips=%s\n",
|
||||
$short,
|
||||
(string) ($row['reason'] ?? ''),
|
||||
(string) ($row['allowed_ips'] ?? '')
|
||||
|
||||
@@ -502,6 +502,9 @@ final class RemoteAccessRepository {
|
||||
if ($pub === '') {
|
||||
$pub = WireGuardPeerProvisioner::publicKeyFromPrivate($priv);
|
||||
}
|
||||
if (!WireGuardPeerProvisioner::addClientPeer($pub, $addr)) {
|
||||
error_log('RemoteAccess: wg peer re-apply failed for session ' . $sessionId);
|
||||
}
|
||||
return [
|
||||
'client_private' => $priv,
|
||||
'client_public' => $pub,
|
||||
@@ -755,18 +758,10 @@ final class RemoteAccessRepository {
|
||||
|
||||
/** @return list<string> */
|
||||
public static function activeWireGuardSessionPublicKeys(): array {
|
||||
self::ensureSchema();
|
||||
$st = Database::pdo()->query(
|
||||
"SELECT DISTINCT wg_client_public_key FROM remote_access_sessions
|
||||
WHERE status IN ('pending','active') AND tunnel = 'wireguard'
|
||||
AND wg_client_public_key IS NOT NULL AND wg_client_public_key != ''"
|
||||
);
|
||||
if ($st === false) {
|
||||
return [];
|
||||
}
|
||||
$peers = self::activeWireGuardSessionPeers();
|
||||
$keys = [];
|
||||
foreach ($st->fetchAll(PDO::FETCH_COLUMN) as $pub) {
|
||||
$pub = trim((string) $pub);
|
||||
foreach ($peers as $row) {
|
||||
$pub = trim((string) ($row['public_key'] ?? ''));
|
||||
if ($pub !== '') {
|
||||
$keys[] = $pub;
|
||||
}
|
||||
@@ -774,6 +769,66 @@ final class RemoteAccessRepository {
|
||||
return $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pending/active WG sessions with client pubkey + tunnel address (for wg set reconcile).
|
||||
*
|
||||
* @return list<array{session_id: string, public_key: string, client_address: string}>
|
||||
*/
|
||||
public static function activeWireGuardSessionPeers(): array {
|
||||
self::ensureSchema();
|
||||
$st = Database::pdo()->query(
|
||||
"SELECT session_id, wg_client_public_key, wg_client_address FROM remote_access_sessions
|
||||
WHERE status IN ('pending','active') AND tunnel = 'wireguard'
|
||||
AND wg_client_public_key IS NOT NULL AND wg_client_public_key != ''
|
||||
AND wg_client_address IS NOT NULL AND wg_client_address != ''"
|
||||
);
|
||||
if ($st === false) {
|
||||
return [];
|
||||
}
|
||||
$rows = [];
|
||||
foreach ($st->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
if (!is_array($row)) {
|
||||
continue;
|
||||
}
|
||||
$pub = trim((string) ($row['wg_client_public_key'] ?? ''));
|
||||
$addr = trim((string) ($row['wg_client_address'] ?? ''));
|
||||
if ($pub === '' || $addr === '') {
|
||||
continue;
|
||||
}
|
||||
$rows[] = [
|
||||
'session_id' => (string) ($row['session_id'] ?? ''),
|
||||
'public_key' => $pub,
|
||||
'client_address' => $addr,
|
||||
];
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure wg0 has allowed-ips for every pending/active WG session (idempotent).
|
||||
*
|
||||
* @return list<array{session_id: string, public_key: string, client_address: string, ok: bool}>
|
||||
*/
|
||||
public static function reconcileActiveWireGuardPeers(bool $dryRun = false): array {
|
||||
$results = [];
|
||||
foreach (self::activeWireGuardSessionPeers() as $row) {
|
||||
$ok = true;
|
||||
if (!$dryRun) {
|
||||
$ok = WireGuardPeerProvisioner::addClientPeer(
|
||||
$row['public_key'],
|
||||
$row['client_address']
|
||||
);
|
||||
}
|
||||
$results[] = [
|
||||
'session_id' => $row['session_id'],
|
||||
'public_key' => $row['public_key'],
|
||||
'client_address' => $row['client_address'],
|
||||
'ok' => $ok,
|
||||
];
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop wg0 peers that are not referenced by pending/active sessions.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user