CluPilotCloud/app/Provisioning/Steps/Host/EstablishSshTrust.php

52 lines
1.7 KiB
PHP

<?php
namespace App\Provisioning\Steps\Host;
use App\Models\ProvisioningRun;
use App\Provisioning\StepResult;
use App\Services\Ssh\RemoteShell;
use App\Support\ProvisioningSettings;
use Illuminate\Support\Facades\Crypt;
/**
* First login with the one-time root password, deploy CluPilot's SSH key, pin
* the host key, verify key login, then scrub the password from the run context.
*/
class EstablishSshTrust extends HostStep
{
public function __construct(private RemoteShell $shell) {}
public function key(): string
{
return 'establish_ssh_trust';
}
public function execute(ProvisioningRun $run): StepResult
{
$host = $this->host($run);
// Idempotent: already trusted (host key pinned) and password already scrubbed.
if (filled($host->ssh_host_key) && blank($run->context('root_password'))) {
return StepResult::advance();
}
$publicKey = trim(ProvisioningSettings::sshPublicKey());
$password = Crypt::decryptString((string) $run->context('root_password'));
$this->shell->connectWithPassword($host->public_ip, 'root', $password);
$this->shell->run('mkdir -p /root/.ssh && chmod 700 /root/.ssh');
$this->shell->run(
'grep -qxF '.escapeshellarg($publicKey).' /root/.ssh/authorized_keys 2>/dev/null '.
'|| echo '.escapeshellarg($publicKey).' >> /root/.ssh/authorized_keys'
);
$host->update(['ssh_host_key' => $this->shell->hostKeyFingerprint()]);
// Verify the key works, then remove the password from state.
$this->keyLogin($this->shell, $host);
$run->forgetContext('root_password');
return StepResult::advance();
}
}