Remote access: open iodine sessions and return connect credentials.

Wire opt_in_mode iodine through openSession and buildConnectResponse for mobile tunnel setup.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Anton Afanasyeu
2026-07-12 19:44:33 +02:00
parent af9c4bee8f
commit bfa2c003f6

View File

@@ -386,9 +386,40 @@ final class RemoteAccessRepository {
if ($tunnel === 'ssh_reverse') {
return self::buildRsshConnectResponse($session, $deviceId, $clientIp);
}
if ($tunnel === 'iodine') {
return self::buildIodineConnectResponse($session, $deviceId, $clientIp);
}
return self::buildWireGuardConnectResponse($session, $deviceId, $clientIp);
}
/** @param array<string, mixed> $session */
private static function buildIodineConnectResponse(array $session, string $deviceId, string $clientIp): array {
$sessionId = (string) ($session['session_id'] ?? '');
$expiresAt = (int) ($session['expires_at'] ?? (time() + 3600));
$serverHost = (string) cfg('remote_access.iodine.server_host', 'apps.f0xx.org');
$udpPort = (int) cfg('remote_access.iodine.udp_port', 5350);
$tunnelDomain = (string) cfg('remote_access.iodine.tunnel_domain', 't0.f0xx.org');
$password = (string) cfg('remote_access.iodine.password', 'zxc123');
$endpoint = $serverHost . ':' . $udpPort;
self::markSessionActive($sessionId);
self::logEvent($deviceId, $sessionId, null, 'tunnel_connect', 'iodine', null, $clientIp);
return self::raEnvelope('connect', [
'session_id' => $sessionId,
'endpoint' => $endpoint,
'tunnel' => 'iodine',
'credentials' => [
'mode' => 'iodine_dns',
'server_host' => $serverHost,
'udp_port' => $udpPort,
'tunnel_domain' => $tunnelDomain,
'password' => $password,
],
'expires_at' => $expiresAt,
]);
}
/** @param array<string, mixed> $session */
private static function buildWireGuardConnectResponse(array $session, string $deviceId, string $clientIp): array {
$sessionId = (string) ($session['session_id'] ?? '');
@@ -624,11 +655,19 @@ final class RemoteAccessRepository {
self::closeActiveSessionsForDevice($deviceId, 'superseded');
$sessionId = self::uuid4();
$companyId = $companyId ?? (int) ($device['company_id'] ?? Rbac::defaultCompanyId());
$tunnel = $optIn === self::OPT_RSSH ? 'ssh_reverse' : 'wireguard';
$tunnel = match ($optIn) {
self::OPT_RSSH => 'ssh_reverse',
self::OPT_IODINE => 'iodine',
default => 'wireguard',
};
if ($tunnel === 'ssh_reverse') {
$host = (string) cfg('remote_access.rssh.bastion_host', 'ra.apps.f0xx.org');
$port = (int) cfg('remote_access.rssh.bastion_port', 443);
$endpoint = $port === 443 ? $host : $host . ':' . $port;
} elseif ($tunnel === 'iodine') {
$host = (string) cfg('remote_access.iodine.server_host', 'apps.f0xx.org');
$port = (int) cfg('remote_access.iodine.udp_port', 5350);
$endpoint = $host . ':' . $port;
} else {
$endpoint = WireGuardAddressPool::defaultEndpoint();
}