diff --git a/src/api.ts b/src/api.ts index 5bbab63..24b0a1b 100644 --- a/src/api.ts +++ b/src/api.ts @@ -356,6 +356,26 @@ export interface VmInstance { * known — use it to filter OS images for a reinstall. Omitted if unknown. */ cpu_arch?: CpuArch; + /** + * The VM's own SSH host keys, scanned from the guest after boot — for + * verifying the host on first connect instead of trusting whatever key it + * presents. Always an array, empty until the scan succeeds, and + * re-captured after a reinstall. Not the same as `ssh_key`, the customer's + * authorized key. + */ + host_ssh_keys: Array; +} + +export interface VmSshHostKey { + /** Key algorithm, e.g. "ssh-ed25519". */ + key_type: string; + /** Base64 key blob, without the algorithm prefix or a comment. */ + public_key: string; + /** + * `SHA256:…` fingerprint over the decoded key blob — the form + * `ssh-keygen -lf` prints and the one a client shows on an unknown host. + */ + fingerprint_sha256: string; } export interface VmIpAssignment { diff --git a/src/locales/ar.json b/src/locales/ar.json index 7b5cfa3..ab69d75 100644 --- a/src/locales/ar.json +++ b/src/locales/ar.json @@ -1511,6 +1511,9 @@ "acrOoz": { "defaultMessage": "استمر." }, + "af6sO8": { + "defaultMessage": "تحقق من مفتاح المضيف عند الاتصال لأول مرة." + }, "agOXPD": { "defaultMessage": "Size" }, diff --git a/src/locales/de.json b/src/locales/de.json index f742376..e5f64c3 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -1511,6 +1511,9 @@ "acrOoz": { "defaultMessage": "Weiter." }, + "af6sO8": { + "defaultMessage": "Überprüfen Sie beim ersten Verbindungsaufbau den Host-Schlüssel." + }, "agOXPD": { "defaultMessage": "Size" }, diff --git a/src/locales/en.json b/src/locales/en.json index 2bd6f9e..808cf92 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1511,6 +1511,9 @@ "acrOoz": { "defaultMessage": "Continue" }, + "af6sO8": { + "defaultMessage": "Verify the host key on first connect" + }, "agOXPD": { "defaultMessage": "Size" }, diff --git a/src/locales/es.json b/src/locales/es.json index ad8d279..d49bf42 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -1511,6 +1511,9 @@ "acrOoz": { "defaultMessage": "Continúe." }, + "af6sO8": { + "defaultMessage": "Verifique la clave del servidor al realizar la primera conexión." + }, "agOXPD": { "defaultMessage": "Size" }, diff --git a/src/locales/fr.json b/src/locales/fr.json index 81eb992..aed3104 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -1511,6 +1511,9 @@ "acrOoz": { "defaultMessage": "Continuez." }, + "af6sO8": { + "defaultMessage": "Vérifiez la clé de l’hôte lors de la première connexion." + }, "agOXPD": { "defaultMessage": "Size" }, diff --git a/src/locales/ja.json b/src/locales/ja.json index 97b1ea4..5985e49 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1511,6 +1511,9 @@ "acrOoz": { "defaultMessage": "続行してください。" }, + "af6sO8": { + "defaultMessage": "初回接続時にホストキーを確認してください。" + }, "agOXPD": { "defaultMessage": "Size" }, diff --git a/src/locales/ko.json b/src/locales/ko.json index f307eeb..f51436b 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1511,6 +1511,9 @@ "acrOoz": { "defaultMessage": "계속 진행하세요." }, + "af6sO8": { + "defaultMessage": "처음 연결할 때 호스트 키를 확인하세요." + }, "agOXPD": { "defaultMessage": "Size" }, diff --git a/src/locales/pt.json b/src/locales/pt.json index 993a91e..8217619 100644 --- a/src/locales/pt.json +++ b/src/locales/pt.json @@ -1511,6 +1511,9 @@ "acrOoz": { "defaultMessage": "Continue." }, + "af6sO8": { + "defaultMessage": "Verifique a chave do servidor na primeira conexão." + }, "agOXPD": { "defaultMessage": "Size" }, diff --git a/src/locales/ru.json b/src/locales/ru.json index be15138..2e08d7c 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -1511,6 +1511,9 @@ "acrOoz": { "defaultMessage": "Продолжайте." }, + "af6sO8": { + "defaultMessage": "При первом подключении убедитесь в подлинности ключа хоста." + }, "agOXPD": { "defaultMessage": "Size" }, diff --git a/src/locales/tr.json b/src/locales/tr.json index 0faecb0..7babbb8 100644 --- a/src/locales/tr.json +++ b/src/locales/tr.json @@ -1511,6 +1511,9 @@ "acrOoz": { "defaultMessage": "Devam et." }, + "af6sO8": { + "defaultMessage": "İlk bağlantıda ana bilgisayar anahtarını doğrulayın." + }, "agOXPD": { "defaultMessage": "Size" }, diff --git a/src/locales/zh.json b/src/locales/zh.json index 7f6e5f0..57f013c 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -1511,6 +1511,9 @@ "acrOoz": { "defaultMessage": "继续。" }, + "af6sO8": { + "defaultMessage": "首次连接时,请验证主机密钥。" + }, "agOXPD": { "defaultMessage": "Size" }, diff --git a/src/pages/vm.tsx b/src/pages/vm.tsx index 7118698..6a89238 100644 --- a/src/pages/vm.tsx +++ b/src/pages/vm.tsx @@ -363,6 +363,21 @@ export default function VmPage() {
                 ssh {state.image.default_username}@{bestHost()}
               
+ {(state.host_ssh_keys?.length ?? 0) > 0 && ( +
+ + + + {state.host_ssh_keys.map((k) => ( +
+                      {k.key_type} {k.fingerprint_sha256}
+                    
+ ))} +
+ )} )}