51 lines
1.7 KiB
PHP
51 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 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((string) config('provisioning.ssh.public_key'));
|
|
$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();
|
|
}
|
|
}
|