diff --git a/app/Helpers/SshMultiplexingHelper.php b/app/Helpers/SshMultiplexingHelper.php index 0e840c3ce..09ddbdde6 100644 --- a/app/Helpers/SshMultiplexingHelper.php +++ b/app/Helpers/SshMultiplexingHelper.php @@ -21,17 +21,16 @@ public static function serverSshConfiguration(Server $server) ]; } - public static function ensureMultiplexedConnection(Server $server) + public static function ensureMultiplexedConnection(Server $server): bool { if (! self::isMultiplexingEnabled()) { - return; + return false; } $sshConfig = self::serverSshConfiguration($server); $muxSocket = $sshConfig['muxFilename']; - $sshKeyLocation = $sshConfig['sshKeyLocation']; - self::validateSshKey($sshKeyLocation); + self::validateSshKey($server->privateKey); $checkCommand = "ssh -O check -o ControlPath=$muxSocket "; if (data_get($server, 'settings.is_cloudflare_tunnel')) { @@ -41,16 +40,17 @@ public static function ensureMultiplexedConnection(Server $server) $process = Process::run($checkCommand); if ($process->exitCode() !== 0) { - self::establishNewMultiplexedConnection($server); + return self::establishNewMultiplexedConnection($server); } + + return true; } - public static function establishNewMultiplexedConnection(Server $server) + public static function establishNewMultiplexedConnection(Server $server): bool { $sshConfig = self::serverSshConfiguration($server); $sshKeyLocation = $sshConfig['sshKeyLocation']; $muxSocket = $sshConfig['muxFilename']; - $connectionTimeout = config('constants.ssh.connection_timeout'); $serverInterval = config('constants.ssh.server_interval'); $muxPersistTime = config('constants.ssh.mux_persist_time'); @@ -60,15 +60,14 @@ public static function establishNewMultiplexedConnection(Server $server) if (data_get($server, 'settings.is_cloudflare_tunnel')) { $establishCommand .= ' -o ProxyCommand="cloudflared access ssh --hostname %h" '; } - $establishCommand .= self::getCommonSshOptions($server, $sshKeyLocation, $connectionTimeout, $serverInterval); $establishCommand .= "{$server->user}@{$server->ip}"; - $establishProcess = Process::run($establishCommand); - if ($establishProcess->exitCode() !== 0) { - throw new \RuntimeException('Failed to establish multiplexed connection: '.$establishProcess->errorOutput()); + return false; } + + return true; } public static function removeMuxFile(Server $server) @@ -97,9 +96,8 @@ public static function generateScpCommand(Server $server, string $source, string if ($server->isIpv6()) { $scp_command .= '-6 '; } - if (self::isMultiplexingEnabled()) { + if (self::isMultiplexingEnabled() && self::ensureMultiplexedConnection($server)) { $scp_command .= "-o ControlMaster=auto -o ControlPath=$muxSocket -o ControlPersist={$muxPersistTime} "; - self::ensureMultiplexedConnection($server); } if (data_get($server, 'settings.is_cloudflare_tunnel')) { @@ -127,9 +125,8 @@ public static function generateSshCommand(Server $server, string $command) $ssh_command = "timeout $timeout ssh "; - if (self::isMultiplexingEnabled()) { + if (self::isMultiplexingEnabled() && self::ensureMultiplexedConnection($server)) { $ssh_command .= "-o ControlMaster=auto -o ControlPath=$muxSocket -o ControlPersist={$muxPersistTime} "; - self::ensureMultiplexedConnection($server); } if (data_get($server, 'settings.is_cloudflare_tunnel')) { @@ -154,13 +151,14 @@ private static function isMultiplexingEnabled(): bool return config('constants.ssh.mux_enabled') && ! config('constants.coolify.is_windows_docker_desktop'); } - private static function validateSshKey(string $sshKeyLocation): void + private static function validateSshKey(PrivateKey $privateKey): void { - $checkKeyCommand = "ls $sshKeyLocation 2>/dev/null"; + $keyLocation = $privateKey->getKeyLocation(); + $checkKeyCommand = "ls $keyLocation 2>/dev/null"; $keyCheckProcess = Process::run($checkKeyCommand); if ($keyCheckProcess->exitCode() !== 0) { - throw new \RuntimeException("SSH key file not accessible: $sshKeyLocation"); + $privateKey->storeInFileSystem(); } } diff --git a/app/Models/Server.php b/app/Models/Server.php index 3df156a78..5bbd13ac7 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -1059,10 +1059,6 @@ public function validateConnection(bool $isManualCheck = true, bool $justCheckin return ['uptime' => false, 'error' => 'Server skipped.']; } try { - // Make sure the private key is stored - if ($this->privateKey) { - $this->privateKey->storeInFileSystem(); - } instant_remote_process(['ls /'], $this); if ($this->settings->is_reachable === false) { $this->settings->is_reachable = true;