diff --git a/agent/app/api/v2/ssh.go b/agent/app/api/v2/ssh.go
index 6dbd1011a..5f6e1d78f 100644
--- a/agent/app/api/v2/ssh.go
+++ b/agent/app/api/v2/ssh.go
@@ -83,6 +83,7 @@ func (b *BaseApi) CreateRootCert(c *gin.Context) {
}
if err := loadCertAfterDecrypt(&req); err != nil {
helper.BadRequest(c, err)
+ return
}
if err := sshService.CreateRootCert(req); err != nil {
helper.InternalServer(c, err)
@@ -107,6 +108,7 @@ func (b *BaseApi) EditRootCert(c *gin.Context) {
}
if err := loadCertAfterDecrypt(&req); err != nil {
helper.BadRequest(c, err)
+ return
}
if err := sshService.EditRootCert(req); err != nil {
helper.InternalServer(c, err)
diff --git a/agent/app/dto/ssh.go b/agent/app/dto/ssh.go
index de965539f..4b07386f9 100644
--- a/agent/app/dto/ssh.go
+++ b/agent/app/dto/ssh.go
@@ -25,7 +25,7 @@ type RootCertOperate struct {
ID uint `json:"id"`
Name string `json:"name"`
Mode string `json:"mode"`
- EncryptionMode string `json:"encryptionMode" validate:"required,oneof=rsa ed25519 ecdsa dsa"`
+ EncryptionMode string `json:"encryptionMode"`
PassPhrase string `json:"passPhrase"`
PublicKey string `json:"publicKey"`
PrivateKey string `json:"privateKey"`
diff --git a/agent/app/service/ssh.go b/agent/app/service/ssh.go
index d69ef9dfe..2f970d719 100644
--- a/agent/app/service/ssh.go
+++ b/agent/app/service/ssh.go
@@ -7,6 +7,7 @@ import (
"context"
"encoding/base64"
"encoding/json"
+ "encoding/pem"
"fmt"
"io"
"net"
@@ -37,6 +38,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/utils/common"
"github.com/1Panel-dev/1Panel/agent/utils/re"
"github.com/pkg/errors"
+ "golang.org/x/crypto/ssh"
)
const sshPath = "/etc/ssh/sshd_config"
@@ -438,15 +440,33 @@ func (u *SSHService) SyncRootCert() error {
global.LOG.Errorf("read pubic key of %s for sync failed, err: %v", item, err)
continue
}
- cert.EncryptionMode = loadEncryptioMode(string(pubItem))
+ publicKey, _, _, rest, err := ssh.ParseAuthorizedKey(pubItem)
+ if err != nil || len(bytes.TrimSpace(rest)) != 0 {
+ continue
+ }
+ cert.EncryptionMode = loadSSHKeyType(publicKey)
+ if cert.EncryptionMode == "" {
+ continue
+ }
rootCerts = append(rootCerts, cert)
}
return hostRepo.SyncCert(rootCerts)
}
func (u *SSHService) CreateRootCert(req dto.RootCertOperate) error {
- if cmd.CheckIllegal(req.EncryptionMode, req.PassPhrase) {
- return buserr.New("ErrCmdIllegal")
+ switch req.Mode {
+ case "generate":
+ switch req.EncryptionMode {
+ case "rsa", "ed25519", "ecdsa", "dsa":
+ default:
+ return buserr.WithName("ErrNotSupportType", req.EncryptionMode)
+ }
+ case "input", "import":
+ if err := validateSSHKeyPair(&req); err != nil {
+ return err
+ }
+ default:
+ return buserr.WithName("ErrNotSupportType", req.Mode)
}
certItem, _ := hostRepo.GetCert(repo.WithByName(req.Name))
if certItem.ID != 0 {
@@ -543,6 +563,9 @@ func (u *SSHService) CreateRootCert(req dto.RootCertOperate) error {
}
func (u *SSHService) EditRootCert(req dto.RootCertOperate) error {
+ if err := validateSSHKeyPair(&req); err != nil {
+ return err
+ }
currentUser, err := user.Current()
if err != nil {
return fmt.Errorf("load current user failed, err: %v", err)
@@ -1681,22 +1704,60 @@ func loadDate(currentYear int, DateStr string, nyc *time.Location) time.Time {
return itemDate
}
-func loadEncryptioMode(content string) string {
- if strings.HasPrefix(content, "ssh-rsa") {
+func loadSSHKeyType(publicKey ssh.PublicKey) string {
+ switch publicKey.Type() {
+ case ssh.KeyAlgoRSA:
return "rsa"
- }
- if strings.HasPrefix(content, "ssh-ed25519") {
+ case ssh.KeyAlgoED25519:
return "ed25519"
- }
- if strings.HasPrefix(content, "ssh-ecdsa") {
+ case ssh.KeyAlgoECDSA256, ssh.KeyAlgoECDSA384, ssh.KeyAlgoECDSA521:
return "ecdsa"
- }
- if strings.HasPrefix(content, "ssh-dsa") {
+ case ssh.KeyAlgoDSA:
return "dsa"
}
return ""
}
+func validateSSHKeyPair(req *dto.RootCertOperate) error {
+ req.PublicKey = strings.TrimSpace(req.PublicKey)
+ req.PrivateKey = strings.TrimSpace(req.PrivateKey)
+ if req.PublicKey == "" || strings.ContainsAny(req.PublicKey, "\r\n") {
+ return buserr.New("ErrSSHPublicKey")
+ }
+ publicKey, comment, options, rest, err := ssh.ParseAuthorizedKey([]byte(req.PublicKey))
+ if err != nil || len(options) != 0 || len(bytes.TrimSpace(rest)) != 0 {
+ return buserr.New("ErrSSHPublicKey")
+ }
+ req.EncryptionMode = loadSSHKeyType(publicKey)
+ if req.EncryptionMode == "" {
+ return buserr.WithName("ErrNotSupportType", publicKey.Type())
+ }
+ block, rest := pem.Decode([]byte(req.PrivateKey))
+ if !strings.HasPrefix(req.PrivateKey, "-----BEGIN ") || block == nil || len(bytes.TrimSpace(rest)) != 0 {
+ return buserr.New("ErrSSHPrivateKey")
+ }
+ signer, err := ssh.ParsePrivateKey([]byte(req.PrivateKey))
+ var missingPassphrase *ssh.PassphraseMissingError
+ if errors.As(err, &missingPassphrase) {
+ signer, err = ssh.ParsePrivateKeyWithPassphrase([]byte(req.PrivateKey), []byte(req.PassPhrase))
+ } else if err == nil {
+ req.PassPhrase = ""
+ }
+ if err != nil {
+ return buserr.New("ErrSSHPrivateKey")
+ }
+ if !bytes.Equal(signer.PublicKey().Marshal(), publicKey.Marshal()) {
+ return buserr.New("ErrSSHKeyMismatch")
+ }
+ req.PublicKey = strings.TrimSpace(string(ssh.MarshalAuthorizedKey(publicKey)))
+ if comment != "" {
+ req.PublicKey += " " + comment
+ }
+ req.PublicKey += "\n"
+ req.PrivateKey += "\n"
+ return nil
+}
+
func updateLocalConn(newPort uint) error {
conn, _ := settingRepo.GetValueByKey("LocalSSHConn")
if len(conn) == 0 {
diff --git a/agent/i18n/lang/en.yaml b/agent/i18n/lang/en.yaml
index e208725c9..0c6dad9ad 100644
--- a/agent/i18n/lang/en.yaml
+++ b/agent/i18n/lang/en.yaml
@@ -731,3 +731,7 @@ FileTaskRename: 'Target filename: {{ .name }}'
ErrFirewallBackendCleanupRequired: "The current backend {{ .current }} still contains 1Panel rules. Clean it up before switching to {{ .target }}."
ErrDockerIPv4ForwardingDisabled: "IPv4 forwarding is disabled. Set net.ipv4.ip_forward=1 before using Docker's firewall backend."
ErrFirewallRuleSavedApplyFailed: "The new rule configuration was saved, but applying it to the firewall failed. Retry by synchronizing: {{ .detail }}"
+
+ErrSSHPublicKey: "Enter a valid SSH public key"
+ErrSSHPrivateKey: "Invalid SSH private key or incorrect passphrase; encrypted keys require the original passphrase"
+ErrSSHKeyMismatch: "The SSH public and private keys do not match"
diff --git a/agent/i18n/lang/es-ES.yaml b/agent/i18n/lang/es-ES.yaml
index 91467f1b0..4a4a52204 100644
--- a/agent/i18n/lang/es-ES.yaml
+++ b/agent/i18n/lang/es-ES.yaml
@@ -731,3 +731,7 @@ FileTaskRename: 'Nombre del archivo de destino: {{ .name }}'
ErrFirewallBackendCleanupRequired: "El backend actual {{ .current }} aún contiene reglas de 1Panel. Elimínelas antes de cambiar a {{ .target }}."
ErrDockerIPv4ForwardingDisabled: "El reenvío IPv4 está desactivado. Configure net.ipv4.ip_forward=1 antes de usar el backend de cortafuegos de Docker."
ErrFirewallRuleSavedApplyFailed: "Se guardó la configuración de la nueva regla, pero no se pudo aplicar al cortafuegos. Vuelva a intentarlo mediante la sincronización: {{ .detail }}"
+
+ErrSSHPublicKey: "Introduce una clave pública SSH válida"
+ErrSSHPrivateKey: "Clave privada SSH no válida o contraseña incorrecta; las claves cifradas requieren la contraseña original"
+ErrSSHKeyMismatch: "Las claves pública y privada SSH no coinciden"
diff --git a/agent/i18n/lang/fa.yaml b/agent/i18n/lang/fa.yaml
index 78ff0019a..a974edfc3 100644
--- a/agent/i18n/lang/fa.yaml
+++ b/agent/i18n/lang/fa.yaml
@@ -732,3 +732,7 @@ FileTaskRename: 'نام فایل مقصد: {{ .name }}'
ErrFirewallBackendCleanupRequired: "بکاند فعلی {{ .current }} هنوز شامل قوانین 1Panel است. پیش از تغییر به {{ .target }} آنها را پاک کنید."
ErrDockerIPv4ForwardingDisabled: "ارسال IPv4 غیرفعال است. پیش از استفاده از بکاند فایروال Docker، مقدار net.ipv4.ip_forward=1 را تنظیم کنید."
ErrFirewallRuleSavedApplyFailed: "پیکربندی قانون جدید ذخیره شد، اما اعمال آن در دیوار آتش ناموفق بود. با همگامسازی دوباره تلاش کنید: {{ .detail }}"
+
+ErrSSHPublicKey: "یک کلید عمومی SSH معتبر وارد کنید"
+ErrSSHPrivateKey: "کلید خصوصی SSH نامعتبر یا عبارت عبور نادرست است؛ کلیدهای رمزگذاریشده به عبارت عبور اصلی نیاز دارند"
+ErrSSHKeyMismatch: "کلید عمومی و خصوصی SSH مطابقت ندارند"
diff --git a/agent/i18n/lang/ja.yaml b/agent/i18n/lang/ja.yaml
index 9653bfebb..47d72c815 100644
--- a/agent/i18n/lang/ja.yaml
+++ b/agent/i18n/lang/ja.yaml
@@ -731,3 +731,7 @@ FileTaskRename: '保存先ファイル名:{{ .name }}'
ErrFirewallBackendCleanupRequired: "現在のバックエンド {{ .current }} に 1Panel ルールが残っています。{{ .target }} に切り替える前に削除してください。"
ErrDockerIPv4ForwardingDisabled: "IPv4 転送が無効です。Docker のファイアウォールバックエンドを使用する前に net.ipv4.ip_forward=1 を設定してください。"
ErrFirewallRuleSavedApplyFailed: "新しいルール設定は保存されましたが、ファイアウォールへの適用に失敗しました。同期で再試行してください:{{ .detail }}"
+
+ErrSSHPublicKey: "有効な SSH 公開鍵を入力してください"
+ErrSSHPrivateKey: "SSH 秘密鍵の形式が無効か、パスフレーズが間違っています。暗号化された鍵には元のパスフレーズが必要です"
+ErrSSHKeyMismatch: "SSH 公開鍵と秘密鍵が一致しません"
diff --git a/agent/i18n/lang/ko.yaml b/agent/i18n/lang/ko.yaml
index bd9aef612..1f72e42e9 100644
--- a/agent/i18n/lang/ko.yaml
+++ b/agent/i18n/lang/ko.yaml
@@ -731,3 +731,7 @@ FileTaskRename: '대상 파일 이름: {{ .name }}'
ErrFirewallBackendCleanupRequired: "현재 백엔드 {{ .current }}에 1Panel 규칙이 남아 있습니다. {{ .target }}로 전환하기 전에 정리하세요."
ErrDockerIPv4ForwardingDisabled: "IPv4 전달이 비활성화되어 있습니다. Docker 방화벽 백엔드를 사용하기 전에 net.ipv4.ip_forward=1을 설정하세요."
ErrFirewallRuleSavedApplyFailed: "새 규칙 설정이 저장되었지만 방화벽에 적용하지 못했습니다. 동기화하여 다시 시도하세요: {{ .detail }}"
+
+ErrSSHPublicKey: "유효한 SSH 공개 키를 입력하세요"
+ErrSSHPrivateKey: "SSH 개인 키 형식이 잘못되었거나 암호가 틀립니다. 암호화된 키에는 원래 암호가 필요합니다"
+ErrSSHKeyMismatch: "SSH 공개 키와 개인 키가 일치하지 않습니다"
diff --git a/agent/i18n/lang/lo.yaml b/agent/i18n/lang/lo.yaml
index 1875c8c7f..77fd89f8b 100644
--- a/agent/i18n/lang/lo.yaml
+++ b/agent/i18n/lang/lo.yaml
@@ -722,3 +722,7 @@ FileTaskRename: 'ຊື່ໄຟລ໌ປາຍທາງ: {{ .name }}'
ErrFirewallBackendCleanupRequired: "ແບັກເອນປັດຈຸບັນ {{ .current }} ຍັງມີກົດຂອງ 1Panel. ກະລຸນາລຶບອອກກ່ອນປ່ຽນໄປ {{ .target }}."
ErrDockerIPv4ForwardingDisabled: "ການສົ່ງຕໍ່ IPv4 ຖືກປິດ. ກະລຸນາຕັ້ງ net.ipv4.ip_forward=1 ກ່ອນໃຊ້ແບັກເອນໄຟວໍຂອງ Docker."
ErrFirewallRuleSavedApplyFailed: "ບັນທຶກການຕັ້ງຄ່າກົດໃໝ່ແລ້ວ ແຕ່ນຳໃຊ້ກັບໄຟວໍບໍ່ສຳເລັດ. ລອງອີກຄັ້ງດ້ວຍການຊິງຂໍ້ມູນ: {{ .detail }}"
+
+ErrSSHPublicKey: "ກະລຸນາປ້ອນຄີສາທາລະນະ SSH ທີ່ຖືກຕ້ອງ"
+ErrSSHPrivateKey: "ຄີສ່ວນຕົວ SSH ບໍ່ຖືກຕ້ອງ ຫຼື ລະຫັດຜ່ານຜິດ; ຄີທີ່ເຂົ້າລະຫັດຕ້ອງໃຊ້ລະຫັດຜ່ານເດີມ"
+ErrSSHKeyMismatch: "ຄີສາທາລະນະ ແລະ ຄີສ່ວນຕົວ SSH ບໍ່ກົງກັນ"
diff --git a/agent/i18n/lang/ms.yaml b/agent/i18n/lang/ms.yaml
index dd261ff94..2e90ec676 100644
--- a/agent/i18n/lang/ms.yaml
+++ b/agent/i18n/lang/ms.yaml
@@ -731,3 +731,7 @@ FileTaskRename: 'Nama fail sasaran: {{ .name }}'
ErrFirewallBackendCleanupRequired: "Bahagian belakang semasa {{ .current }} masih mengandungi peraturan 1Panel. Buangkannya sebelum beralih kepada {{ .target }}."
ErrDockerIPv4ForwardingDisabled: "Pemajuan IPv4 dilumpuhkan. Tetapkan net.ipv4.ip_forward=1 sebelum menggunakan bahagian belakang tembok api Docker."
ErrFirewallRuleSavedApplyFailed: "Konfigurasi peraturan baharu telah disimpan, tetapi gagal digunakan pada tembok api. Cuba lagi melalui penyegerakan: {{ .detail }}"
+
+ErrSSHPublicKey: "Masukkan kunci awam SSH yang sah"
+ErrSSHPrivateKey: "Kunci peribadi SSH tidak sah atau frasa laluan salah; kunci yang disulitkan memerlukan frasa laluan asal"
+ErrSSHKeyMismatch: "Kunci awam dan peribadi SSH tidak sepadan"
diff --git a/agent/i18n/lang/pt-BR.yaml b/agent/i18n/lang/pt-BR.yaml
index a8a2544a7..9b9d7da92 100644
--- a/agent/i18n/lang/pt-BR.yaml
+++ b/agent/i18n/lang/pt-BR.yaml
@@ -731,3 +731,7 @@ FileTaskRename: 'Nome do arquivo de destino: {{ .name }}'
ErrFirewallBackendCleanupRequired: "O backend atual {{ .current }} ainda contém regras do 1Panel. Remova-as antes de mudar para {{ .target }}."
ErrDockerIPv4ForwardingDisabled: "O encaminhamento IPv4 está desativado. Defina net.ipv4.ip_forward=1 antes de usar o backend de firewall do Docker."
ErrFirewallRuleSavedApplyFailed: "A configuração da nova regra foi salva, mas não pôde ser aplicada ao firewall. Tente novamente por meio da sincronização: {{ .detail }}"
+
+ErrSSHPublicKey: "Informe uma chave pública SSH válida"
+ErrSSHPrivateKey: "Chave privada SSH inválida ou senha incorreta; chaves criptografadas exigem a senha original"
+ErrSSHKeyMismatch: "As chaves pública e privada SSH não correspondem"
diff --git a/agent/i18n/lang/ru.yaml b/agent/i18n/lang/ru.yaml
index 89ed5305e..ad6838b31 100644
--- a/agent/i18n/lang/ru.yaml
+++ b/agent/i18n/lang/ru.yaml
@@ -731,3 +731,7 @@ FileTaskRename: 'Имя целевого файла: {{ .name }}'
ErrFirewallBackendCleanupRequired: "В текущем бэкенде {{ .current }} остались правила 1Panel. Удалите их перед переключением на {{ .target }}."
ErrDockerIPv4ForwardingDisabled: "Пересылка IPv4 отключена. Перед использованием бэкенда межсетевого экрана Docker установите net.ipv4.ip_forward=1."
ErrFirewallRuleSavedApplyFailed: "Настройки нового правила сохранены, но применить их к межсетевому экрану не удалось. Повторите попытку с помощью синхронизации: {{ .detail }}"
+
+ErrSSHPublicKey: "Введите действительный открытый ключ SSH"
+ErrSSHPrivateKey: "Недопустимый закрытый ключ SSH или неверная парольная фраза; для зашифрованных ключей требуется исходная парольная фраза"
+ErrSSHKeyMismatch: "Открытый и закрытый ключи SSH не соответствуют друг другу"
diff --git a/agent/i18n/lang/tr.yaml b/agent/i18n/lang/tr.yaml
index ca8140314..adf567a5b 100644
--- a/agent/i18n/lang/tr.yaml
+++ b/agent/i18n/lang/tr.yaml
@@ -731,3 +731,7 @@ FileTaskRename: 'Hedef dosya adı: {{ .name }}'
ErrFirewallBackendCleanupRequired: "Mevcut {{ .current }} arka ucunda hâlâ 1Panel kuralları var. {{ .target }} arka ucuna geçmeden önce bunları temizleyin."
ErrDockerIPv4ForwardingDisabled: "IPv4 yönlendirmesi devre dışı. Docker güvenlik duvarı arka ucunu kullanmadan önce net.ipv4.ip_forward=1 ayarını yapın."
ErrFirewallRuleSavedApplyFailed: "Yeni kural yapılandırması kaydedildi, ancak güvenlik duvarına uygulanamadı. Eşitleme yaparak yeniden deneyin: {{ .detail }}"
+
+ErrSSHPublicKey: "Geçerli bir SSH açık anahtarı girin"
+ErrSSHPrivateKey: "SSH özel anahtarı geçersiz veya parola yanlış; şifreli anahtarlar mevcut parolayı gerektirir"
+ErrSSHKeyMismatch: "SSH açık ve özel anahtarları eşleşmiyor"
diff --git a/agent/i18n/lang/zh-Hant.yaml b/agent/i18n/lang/zh-Hant.yaml
index ae7d9b747..79d190076 100644
--- a/agent/i18n/lang/zh-Hant.yaml
+++ b/agent/i18n/lang/zh-Hant.yaml
@@ -731,3 +731,7 @@ FileTaskRename: '目標檔名:{{ .name }}'
ErrFirewallBackendCleanupRequired: "目前後端 {{ .current }} 中仍有 1Panel 規則,請先清理後再切換至 {{ .target }}。"
ErrDockerIPv4ForwardingDisabled: "IPv4 轉送尚未啟用,請先設定 net.ipv4.ip_forward=1,再使用 Docker 防火牆後端。"
ErrFirewallRuleSavedApplyFailed: "新規則設定已儲存,但套用至防火牆失敗。可透過同步重試:{{ .detail }}"
+
+ErrSSHPublicKey: "請輸入有效的 SSH 公鑰"
+ErrSSHPrivateKey: "SSH 私鑰格式無效或密碼錯誤;加密私鑰需要填寫原密碼"
+ErrSSHKeyMismatch: "SSH 公鑰與私鑰不相符"
diff --git a/agent/i18n/lang/zh.yaml b/agent/i18n/lang/zh.yaml
index 00852883d..4a7ef3db2 100644
--- a/agent/i18n/lang/zh.yaml
+++ b/agent/i18n/lang/zh.yaml
@@ -731,3 +731,7 @@ FileTaskRename: '目标文件名:{{ .name }}'
ErrFirewallBackendCleanupRequired: "当前后端 {{ .current }} 中仍有 1Panel 规则,请先清理后再切换到 {{ .target }}。"
ErrDockerIPv4ForwardingDisabled: "IPv4 转发未开启,请先设置 net.ipv4.ip_forward=1,再使用 Docker 防火墙后端。"
ErrFirewallRuleSavedApplyFailed: "新规则配置已保存,但应用到防火墙失败。可通过同步重试:{{ .detail }}"
+
+ErrSSHPublicKey: "请输入有效的 SSH 公钥"
+ErrSSHPrivateKey: "SSH 私钥格式无效或密码错误;加密私钥需要填写原密码"
+ErrSSHKeyMismatch: "SSH 公钥与私钥不匹配"
diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts
index f2a43c34a..14b75ce5f 100644
--- a/frontend/src/lang/modules/en.ts
+++ b/frontend/src/lang/modules/en.ts
@@ -2888,6 +2888,9 @@ const message = {
privateKey: 'Private Key',
publicKey: 'Public Key',
password: 'Password',
+ existingPassPhrase: 'Existing private key passphrase',
+ existingPassPhraseHelper:
+ 'Enter the original passphrase if the private key is encrypted; otherwise leave blank. This does not change the passphrase.',
createMode: 'Creation Method',
generate: 'Auto-generate',
unSyncPass: 'Key password cannot be synchronized',
diff --git a/frontend/src/lang/modules/es-es.ts b/frontend/src/lang/modules/es-es.ts
index cdabe72a4..4be0207ce 100644
--- a/frontend/src/lang/modules/es-es.ts
+++ b/frontend/src/lang/modules/es-es.ts
@@ -2930,6 +2930,9 @@ const message = {
privateKey: 'Clave privada',
publicKey: 'Clave pública',
password: 'Contraseña',
+ existingPassPhrase: 'Contraseña actual de la clave privada',
+ existingPassPhraseHelper:
+ 'Introduce la contraseña original si la clave privada está cifrada; en caso contrario, deja el campo vacío. Esto no cambia la contraseña.',
createMode: 'Método de creación',
generate: 'Autogenerar',
unSyncPass: 'La contraseña de la clave no se puede sincronizar',
diff --git a/frontend/src/lang/modules/fa.ts b/frontend/src/lang/modules/fa.ts
index d47aecd2a..1ef3bc82a 100644
--- a/frontend/src/lang/modules/fa.ts
+++ b/frontend/src/lang/modules/fa.ts
@@ -2861,6 +2861,9 @@ const message = {
privateKey: 'کلید خصوصی',
publicKey: 'کلید عمومی',
password: 'رمز عبور',
+ existingPassPhrase: 'عبارت عبور فعلی کلید خصوصی',
+ existingPassPhraseHelper:
+ 'اگر کلید خصوصی رمزگذاری شده است، عبارت عبور اصلی را وارد کنید؛ در غیر این صورت خالی بگذارید. این کار عبارت عبور را تغییر نمیدهد.',
createMode: 'روش ایجاد',
generate: 'تولید خودکار',
unSyncPass: 'رمز عبور کلید قابل همگامسازی نیست',
diff --git a/frontend/src/lang/modules/ja.ts b/frontend/src/lang/modules/ja.ts
index 819866e7a..ba3336f96 100644
--- a/frontend/src/lang/modules/ja.ts
+++ b/frontend/src/lang/modules/ja.ts
@@ -2865,6 +2865,9 @@ const message = {
privateKey: '秘密鍵',
publicKey: '公開鍵',
password: 'パスワード',
+ existingPassPhrase: '既存の秘密鍵のパスフレーズ',
+ existingPassPhraseHelper:
+ '秘密鍵が暗号化されている場合は元のパスフレーズを入力し、それ以外は空欄にしてください。パスフレーズは変更されません。',
createMode: '作成方法',
generate: '自動生成',
unSyncPass: '鍵パスワードは同期できません',
diff --git a/frontend/src/lang/modules/ko.ts b/frontend/src/lang/modules/ko.ts
index 22cf61f59..24725ebe7 100644
--- a/frontend/src/lang/modules/ko.ts
+++ b/frontend/src/lang/modules/ko.ts
@@ -2827,6 +2827,9 @@ const message = {
privateKey: '개인 키',
publicKey: '공개 키',
password: '비밀번호',
+ existingPassPhrase: '기존 개인 키 암호',
+ existingPassPhraseHelper:
+ '개인 키가 암호화되어 있으면 원래 암호를 입력하고, 그렇지 않으면 비워 두세요. 이 작업은 암호를 변경하지 않습니다.',
createMode: '생성 방식',
generate: '자동 생성',
unSyncPass: '키 비밀번호 동기화 불가',
diff --git a/frontend/src/lang/modules/lo.ts b/frontend/src/lang/modules/lo.ts
index 12e16868a..40038f6bd 100644
--- a/frontend/src/lang/modules/lo.ts
+++ b/frontend/src/lang/modules/lo.ts
@@ -2807,6 +2807,9 @@ const message = {
privateKey: 'ຄີສ່ວນຕົວ',
publicKey: 'ຄີສາທາລະນະ',
password: 'ລະຫັດຜ່ານ',
+ existingPassPhrase: 'ລະຫັດຜ່ານເດີມຂອງຄີສ່ວນຕົວ',
+ existingPassPhraseHelper:
+ 'ຖ້າຄີສ່ວນຕົວຖືກເຂົ້າລະຫັດ ໃຫ້ປ້ອນລະຫັດຜ່ານເດີມ; ຖ້າບໍ່ ໃຫ້ປະໄວ້ຫວ່າງ. ການດຳເນີນການນີ້ບໍ່ປ່ຽນລະຫັດຜ່ານ.',
createMode: 'ວິທີການສ້າງ',
generate: 'ສ້າງອັດຕະໂນມັດ',
unSyncPass: 'ບໍ່ສາມາດຊິງຄ໌ລະຫັດຜ່ານຄີໄດ້',
diff --git a/frontend/src/lang/modules/ms.ts b/frontend/src/lang/modules/ms.ts
index 2a6054108..ae6b54ebe 100644
--- a/frontend/src/lang/modules/ms.ts
+++ b/frontend/src/lang/modules/ms.ts
@@ -2930,6 +2930,9 @@ const message = {
privateKey: 'Kunci Persendirian',
publicKey: 'Kunci Awam',
password: 'Kata Laluan',
+ existingPassPhrase: 'Frasa laluan kunci peribadi sedia ada',
+ existingPassPhraseHelper:
+ 'Masukkan frasa laluan asal jika kunci peribadi disulitkan; jika tidak, biarkan kosong. Ini tidak mengubah frasa laluan.',
createMode: 'Kaedah Penciptaan',
generate: 'Jana Automatik',
unSyncPass: 'Kata laluan kunci tidak dapat diselaraskan',
diff --git a/frontend/src/lang/modules/pt-br.ts b/frontend/src/lang/modules/pt-br.ts
index fd5a60def..fc4d6a39f 100644
--- a/frontend/src/lang/modules/pt-br.ts
+++ b/frontend/src/lang/modules/pt-br.ts
@@ -2929,6 +2929,9 @@ const message = {
privateKey: 'Chave Privada',
publicKey: 'Chave Pública',
password: 'Senha',
+ existingPassPhrase: 'Senha atual da chave privada',
+ existingPassPhraseHelper:
+ 'Informe a senha original se a chave privada estiver criptografada; caso contrário, deixe em branco. Isso não altera a senha.',
createMode: 'Método de Criação',
generate: 'Gerar Automaticamente',
unSyncPass: 'Senha da chave não pode ser sincronizada',
diff --git a/frontend/src/lang/modules/ru.ts b/frontend/src/lang/modules/ru.ts
index f7b45cba4..feef1be02 100644
--- a/frontend/src/lang/modules/ru.ts
+++ b/frontend/src/lang/modules/ru.ts
@@ -2903,6 +2903,9 @@ const message = {
privateKey: 'Приватный ключ',
publicKey: 'Публичный ключ',
password: 'Пароль',
+ existingPassPhrase: 'Текущая парольная фраза закрытого ключа',
+ existingPassPhraseHelper:
+ 'Если закрытый ключ зашифрован, введите исходную парольную фразу; иначе оставьте поле пустым. Это не изменяет парольную фразу.',
createMode: 'Способ создания',
generate: 'Автогенерация',
unSyncPass: 'Пароль ключа не может быть синхронизирован',
diff --git a/frontend/src/lang/modules/tr.ts b/frontend/src/lang/modules/tr.ts
index 965ebd937..a8f2887fa 100644
--- a/frontend/src/lang/modules/tr.ts
+++ b/frontend/src/lang/modules/tr.ts
@@ -2921,6 +2921,9 @@ const message = {
privateKey: 'Özel Anahtar',
publicKey: 'Genel Anahtar',
password: 'Parola',
+ existingPassPhrase: 'Mevcut özel anahtar parolası',
+ existingPassPhraseHelper:
+ 'Özel anahtar şifreliyse mevcut parolayı girin; değilse boş bırakın. Bu işlem parolayı değiştirmez.',
createMode: 'Oluşturma Yöntemi',
generate: 'Otomatik Oluştur',
unSyncPass: 'Anahtar parolası senkronize edilemez',
diff --git a/frontend/src/lang/modules/zh-Hant.ts b/frontend/src/lang/modules/zh-Hant.ts
index 537457e7f..216b070a4 100644
--- a/frontend/src/lang/modules/zh-Hant.ts
+++ b/frontend/src/lang/modules/zh-Hant.ts
@@ -2720,6 +2720,8 @@ const message = {
privateKey: '私鑰',
publicKey: '公鑰',
password: '密碼',
+ existingPassPhrase: '現有私鑰密碼',
+ existingPassPhraseHelper: '私鑰已加密時填寫原密碼,未加密則留空;此處不會修改私鑰密碼。',
createMode: '建立方式',
generate: '自動生成',
unSyncPass: '金鑰密碼無法同步',
diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts
index 8fc0dafc6..dd0e77f5c 100644
--- a/frontend/src/lang/modules/zh.ts
+++ b/frontend/src/lang/modules/zh.ts
@@ -2751,6 +2751,8 @@ const message = {
privateKey: '私钥',
publicKey: '公钥',
password: '密码',
+ existingPassPhrase: '已有私钥密码',
+ existingPassPhraseHelper: '私钥已加密时填写原密码,未加密则留空;此处不会修改私钥密码。',
createMode: '创建方式',
generate: '自动生成',
unSyncPass: '密钥密码无法同步',
diff --git a/frontend/src/views/host/ssh/ssh/certification/operate/index.vue b/frontend/src/views/host/ssh/ssh/certification/operate/index.vue
index 097a60a2c..5a28ac7ea 100644
--- a/frontend/src/views/host/ssh/ssh/certification/operate/index.vue
+++ b/frontend/src/views/host/ssh/ssh/certification/operate/index.vue
@@ -16,8 +16,15 @@
+