From 471b62c7fe52313cb97319d28b9bae104b3b7f62 Mon Sep 17 00:00:00 2001 From: "kk.cheng" Date: Wed, 7 Jan 2026 19:07:52 +0800 Subject: [PATCH] Add option to select RSA or ECDSA key type when creating certificates --- backend/internal/certificate.js | 20 +++++++++++++ .../schema/components/certificate-object.json | 5 ++++ frontend/src/locale/src/bg.json | 12 ++++++++ frontend/src/locale/src/de.json | 12 ++++++++ frontend/src/locale/src/en.json | 12 ++++++++ frontend/src/locale/src/es.json | 12 ++++++++ frontend/src/locale/src/it.json | 12 ++++++++ frontend/src/locale/src/ja.json | 12 ++++++++ frontend/src/locale/src/ko.json | 14 ++++++++- frontend/src/locale/src/nl.json | 12 ++++++++ frontend/src/locale/src/pl.json | 12 ++++++++ frontend/src/locale/src/ru.json | 12 ++++++++ frontend/src/locale/src/sk.json | 12 ++++++++ frontend/src/locale/src/vi.json | 12 ++++++++ frontend/src/locale/src/zh.json | 12 ++++++++ frontend/src/modals/DNSCertificateModal.tsx | 27 ++++++++++++++++- frontend/src/modals/HTTPCertificateModal.tsx | 29 ++++++++++++++++++- 17 files changed, 236 insertions(+), 3 deletions(-) diff --git a/backend/internal/certificate.js b/backend/internal/certificate.js index 0828878b..bde1bdca 100644 --- a/backend/internal/certificate.js +++ b/backend/internal/certificate.js @@ -798,6 +798,11 @@ const internalCertificate = { certificate.domain_names.join(","), ]; + // Add key-type parameter if specified + if (certificate.meta?.key_type) { + args.push("--key-type", certificate.meta.key_type); + } + const adds = internalCertificate.getAdditionalCertbotArgs(certificate.id); args.push(...adds.args); @@ -858,6 +863,11 @@ const internalCertificate = { ); } + // Add key-type parameter if specified + if (certificate.meta?.key_type) { + args.push("--key-type", certificate.meta.key_type); + } + const adds = internalCertificate.getAdditionalCertbotArgs(certificate.id, certificate.meta.dns_provider); args.push(...adds.args); @@ -938,6 +948,11 @@ const internalCertificate = { "--disable-hook-validation", ]; + // Add key-type parameter if specified + if (certificate.meta?.key_type) { + args.push("--key-type", certificate.meta.key_type); + } + const adds = internalCertificate.getAdditionalCertbotArgs(certificate.id, certificate.meta.dns_provider); args.push(...adds.args); @@ -979,6 +994,11 @@ const internalCertificate = { "--no-random-sleep-on-renew", ]; + // Add key-type parameter if specified + if (certificate.meta?.key_type) { + args.push("--key-type", certificate.meta.key_type); + } + const adds = internalCertificate.getAdditionalCertbotArgs(certificate.id, certificate.meta.dns_provider); args.push(...adds.args); diff --git a/backend/schema/components/certificate-object.json b/backend/schema/components/certificate-object.json index ef2d613f..80cd92be 100644 --- a/backend/schema/components/certificate-object.json +++ b/backend/schema/components/certificate-object.json @@ -71,6 +71,11 @@ "propagation_seconds": { "type": "integer", "minimum": 0 + }, + "key_type": { + "type": "string", + "enum": ["rsa", "ecdsa"], + "default": "rsa" } }, "example": { diff --git a/frontend/src/locale/src/bg.json b/frontend/src/locale/src/bg.json index 81cab598..5183fe31 100644 --- a/frontend/src/locale/src/bg.json +++ b/frontend/src/locale/src/bg.json @@ -170,6 +170,18 @@ "certificates.http.warning": { "defaultMessage": "Тези домейни трябва вече да сочат към тази инсталация." }, + "certificates.key-type": { + "defaultMessage": "Тип ключ" + }, + "certificates.key-type-description": { + "defaultMessage": "RSA е широко съвместим, ECDSA е по-бърз и по-сигурен, но може да не се поддържа от по-стари системи" + }, + "certificates.key-type-ecdsa": { + "defaultMessage": "ECDSA 256" + }, + "certificates.key-type-rsa": { + "defaultMessage": "RSA 2048" + }, "certificates.request.subtitle": { "defaultMessage": "с Let's Encrypt" }, diff --git a/frontend/src/locale/src/de.json b/frontend/src/locale/src/de.json index d36b259d..ae97a29b 100644 --- a/frontend/src/locale/src/de.json +++ b/frontend/src/locale/src/de.json @@ -155,6 +155,18 @@ "certificates.http.warning": { "defaultMessage": "Diese Domänen müssen bereits so konfiguriert sein, dass sie auf diese Installation verweisen." }, + "certificates.key-type": { + "defaultMessage": "Schlüsseltyp" + }, + "certificates.key-type-description": { + "defaultMessage": "RSA ist weit verbreitet, ECDSA ist schneller und sicherer, wird aber möglicherweise von älteren Systemen nicht unterstützt" + }, + "certificates.key-type-ecdsa": { + "defaultMessage": "ECDSA 256" + }, + "certificates.key-type-rsa": { + "defaultMessage": "RSA 2048" + }, "certificates.request.subtitle": { "defaultMessage": "Über Let's Encrypt" }, diff --git a/frontend/src/locale/src/en.json b/frontend/src/locale/src/en.json index 355d0db7..efc7335f 100644 --- a/frontend/src/locale/src/en.json +++ b/frontend/src/locale/src/en.json @@ -170,6 +170,18 @@ "certificates.http.warning": { "defaultMessage": "These domains must be already configured to point to this installation." }, + "certificates.key-type": { + "defaultMessage": "Key Type" + }, + "certificates.key-type-description": { + "defaultMessage": "RSA is widely compatible, ECDSA is faster and more secure but may not be supported by older systems" + }, + "certificates.key-type-ecdsa": { + "defaultMessage": "ECDSA 256" + }, + "certificates.key-type-rsa": { + "defaultMessage": "RSA 2048" + }, "certificates.request.subtitle": { "defaultMessage": "with Let's Encrypt" }, diff --git a/frontend/src/locale/src/es.json b/frontend/src/locale/src/es.json index 2b1ebfa4..c8b1edb0 100644 --- a/frontend/src/locale/src/es.json +++ b/frontend/src/locale/src/es.json @@ -170,6 +170,18 @@ "certificates.http.warning": { "defaultMessage": "Estos dominios ya deben estar configurados para apuntar a esta instalación." }, + "certificates.key-type": { + "defaultMessage": "Tipo de Clave" + }, + "certificates.key-type-description": { + "defaultMessage": "RSA es ampliamente compatible, ECDSA es más rápido y seguro pero puede no ser compatible con sistemas antiguos" + }, + "certificates.key-type-ecdsa": { + "defaultMessage": "ECDSA 256" + }, + "certificates.key-type-rsa": { + "defaultMessage": "RSA 2048" + }, "certificates.request.subtitle": { "defaultMessage": "con Let's Encrypt" }, diff --git a/frontend/src/locale/src/it.json b/frontend/src/locale/src/it.json index 3301218f..3bbc7316 100644 --- a/frontend/src/locale/src/it.json +++ b/frontend/src/locale/src/it.json @@ -155,6 +155,18 @@ "certificates.http.warning": { "defaultMessage": "Questi domini devono già essere configurati per puntare a questa installazione." }, + "certificates.key-type": { + "defaultMessage": "Tipo di Chiave" + }, + "certificates.key-type-description": { + "defaultMessage": "RSA è ampiamente compatibile, ECDSA è più veloce e sicuro ma potrebbe non essere supportato da sistemi più vecchi" + }, + "certificates.key-type-ecdsa": { + "defaultMessage": "ECDSA 256" + }, + "certificates.key-type-rsa": { + "defaultMessage": "RSA 2048" + }, "certificates.request.subtitle": { "defaultMessage": "con Let's Encrypt" }, diff --git a/frontend/src/locale/src/ja.json b/frontend/src/locale/src/ja.json index 1ace1c64..2ffadd0c 100644 --- a/frontend/src/locale/src/ja.json +++ b/frontend/src/locale/src/ja.json @@ -155,6 +155,18 @@ "certificates.http.warning": { "defaultMessage": "これらのドメインは、すでにこのインストール先を指すように設定されている必要がありますあ." }, + "certificates.key-type": { + "defaultMessage": "鍵タイプ" + }, + "certificates.key-type-description": { + "defaultMessage": "RSAは広く互換性があり、ECDSAはより高速で安全ですが、古いシステムではサポートされていない場合があります" + }, + "certificates.key-type-ecdsa": { + "defaultMessage": "ECDSA 256" + }, + "certificates.key-type-rsa": { + "defaultMessage": "RSA 2048" + }, "certificates.request.subtitle": { "defaultMessage": "Let's Encryptを使用する" }, diff --git a/frontend/src/locale/src/ko.json b/frontend/src/locale/src/ko.json index f9d82d85..9c009359 100644 --- a/frontend/src/locale/src/ko.json +++ b/frontend/src/locale/src/ko.json @@ -170,6 +170,18 @@ "certificates.http.warning": { "defaultMessage": "도메인이 이 서버를 가리키도록 설정되어 있어야 합니다." }, + "certificates.key-type": { + "defaultMessage": "키 유형" + }, + "certificates.key-type-description": { + "defaultMessage": "RSA는 호환성이 넓고, ECDSA는 더 빠르고 안전하지만 오래된 시스템에서 지원되지 않을 수 있습니다" + }, + "certificates.key-type-ecdsa": { + "defaultMessage": "ECDSA 256" + }, + "certificates.key-type-rsa": { + "defaultMessage": "RSA 2048" + }, "certificates.request.subtitle": { "defaultMessage": "Let's Encrypt 사용" }, @@ -218,7 +230,7 @@ "column.provider": { "defaultMessage": "공급자" }, - "column.roles": { + "column.roles": { "defaultMessage": "권한" }, "column.rules": { diff --git a/frontend/src/locale/src/nl.json b/frontend/src/locale/src/nl.json index 2732f5e4..91e71df7 100644 --- a/frontend/src/locale/src/nl.json +++ b/frontend/src/locale/src/nl.json @@ -155,6 +155,18 @@ "certificates.http.warning": { "defaultMessage": "Deze domeinen moeten al worden geconfigureerd om naar deze installatie te wijzen." }, + "certificates.key-type": { + "defaultMessage": "Sleuteltype" + }, + "certificates.key-type-description": { + "defaultMessage": "RSA is breed compatibel, ECDSA is sneller en veiliger maar wordt mogelijk niet ondersteund door oudere systemen" + }, + "certificates.key-type-ecdsa": { + "defaultMessage": "ECDSA 256" + }, + "certificates.key-type-rsa": { + "defaultMessage": "RSA 2048" + }, "certificates.request.subtitle": { "defaultMessage": "met Let's Encrypt" }, diff --git a/frontend/src/locale/src/pl.json b/frontend/src/locale/src/pl.json index 9853c7bc..faaebc5e 100644 --- a/frontend/src/locale/src/pl.json +++ b/frontend/src/locale/src/pl.json @@ -155,6 +155,18 @@ "certificates.http.warning": { "defaultMessage": "Te domeny muszą być już skonfigurowane tak, aby wskazywały na ten serwer www" }, + "certificates.key-type": { + "defaultMessage": "Typ klucza" + }, + "certificates.key-type-description": { + "defaultMessage": "RSA jest szeroko kompatybilny, ECDSA jest szybszy i bezpieczniejszy, ale może nie być obsługiwany przez starsze systemy" + }, + "certificates.key-type-ecdsa": { + "defaultMessage": "ECDSA 256" + }, + "certificates.key-type-rsa": { + "defaultMessage": "RSA 2048" + }, "certificates.request.subtitle": { "defaultMessage": "z Let's Encrypt" }, diff --git a/frontend/src/locale/src/ru.json b/frontend/src/locale/src/ru.json index dedcd513..44dff129 100644 --- a/frontend/src/locale/src/ru.json +++ b/frontend/src/locale/src/ru.json @@ -155,6 +155,18 @@ "certificates.http.warning": { "defaultMessage": "Эти домены должны быть настроены и указывать на этот экземпляр." }, + "certificates.key-type": { + "defaultMessage": "Тип ключа" + }, + "certificates.key-type-description": { + "defaultMessage": "RSA широко совместим, ECDSA быстрее и безопаснее, но может не поддерживаться старыми системами" + }, + "certificates.key-type-ecdsa": { + "defaultMessage": "ECDSA 256" + }, + "certificates.key-type-rsa": { + "defaultMessage": "RSA 2048" + }, "certificates.request.subtitle": { "defaultMessage": "через Let's Encrypt" }, diff --git a/frontend/src/locale/src/sk.json b/frontend/src/locale/src/sk.json index d006e555..6431643f 100644 --- a/frontend/src/locale/src/sk.json +++ b/frontend/src/locale/src/sk.json @@ -155,6 +155,18 @@ "certificates.http.warning": { "defaultMessage": "Tieto domény musia byť už nakonfigurované tak, aby smerovali na túto inštaláciu." }, + "certificates.key-type": { + "defaultMessage": "Typ kľúča" + }, + "certificates.key-type-description": { + "defaultMessage": "RSA je široko kompatibilný, ECDSA je rýchlejší a bezpečnejší, ale nemusí byť podporovaný staršími systémami" + }, + "certificates.key-type-ecdsa": { + "defaultMessage": "ECDSA 256" + }, + "certificates.key-type-rsa": { + "defaultMessage": "RSA 2048" + }, "certificates.request.subtitle": { "defaultMessage": "pomocou Let's Encrypt" }, diff --git a/frontend/src/locale/src/vi.json b/frontend/src/locale/src/vi.json index fc1ed85b..32d26d55 100644 --- a/frontend/src/locale/src/vi.json +++ b/frontend/src/locale/src/vi.json @@ -155,6 +155,18 @@ "certificates.http.warning": { "defaultMessage": "Các miền này phải được cấu hình sẵn để trỏ đến cài đặt này." }, + "certificates.key-type": { + "defaultMessage": "Loại khóa" + }, + "certificates.key-type-description": { + "defaultMessage": "RSA tương thích rộng rãi, ECDSA nhanh hơn và an toàn hơn nhưng có thể không được hỗ trợ bởi các hệ thống cũ" + }, + "certificates.key-type-ecdsa": { + "defaultMessage": "ECDSA 256" + }, + "certificates.key-type-rsa": { + "defaultMessage": "RSA 2048" + }, "certificates.request.subtitle": { "defaultMessage": "bằng Let's Encrypt" }, diff --git a/frontend/src/locale/src/zh.json b/frontend/src/locale/src/zh.json index 541093a6..d40ea39d 100755 --- a/frontend/src/locale/src/zh.json +++ b/frontend/src/locale/src/zh.json @@ -155,6 +155,18 @@ "certificates.http.warning": { "defaultMessage": "这些域名必须配置为指向本设备。" }, + "certificates.key-type": { + "defaultMessage": "密钥类型" + }, + "certificates.key-type-description": { + "defaultMessage": "RSA 兼容性更好,ECDSA 更快更安全但旧系统可能不支持" + }, + "certificates.key-type-ecdsa": { + "defaultMessage": "ECDSA 256" + }, + "certificates.key-type-rsa": { + "defaultMessage": "RSA 2048" + }, "certificates.request.subtitle": { "defaultMessage": "使用 Let's Encrypt" }, diff --git a/frontend/src/modals/DNSCertificateModal.tsx b/frontend/src/modals/DNSCertificateModal.tsx index 3c97fddd..f062e24d 100644 --- a/frontend/src/modals/DNSCertificateModal.tsx +++ b/frontend/src/modals/DNSCertificateModal.tsx @@ -1,6 +1,6 @@ import { useQueryClient } from "@tanstack/react-query"; import EasyModal, { type InnerModalProps } from "ez-modal-react"; -import { Form, Formik } from "formik"; +import { Form, Formik, Field } from "formik"; import { type ReactNode, useState } from "react"; import { Alert } from "react-bootstrap"; import Modal from "react-bootstrap/Modal"; @@ -44,6 +44,7 @@ const DNSCertificateModal = EasyModal.create(({ visible, remove }: InnerModalPro provider: "letsencrypt", meta: { dnsChallenge: true, + keyType: "ecdsa", }, } as any } @@ -63,6 +64,30 @@ const DNSCertificateModal = EasyModal.create(({ visible, remove }: InnerModalPro
+ + {({ field }: any) => ( +
+ + + + + +
+ )} +
diff --git a/frontend/src/modals/HTTPCertificateModal.tsx b/frontend/src/modals/HTTPCertificateModal.tsx index b996a7d6..a06df2c6 100644 --- a/frontend/src/modals/HTTPCertificateModal.tsx +++ b/frontend/src/modals/HTTPCertificateModal.tsx @@ -1,7 +1,7 @@ import { IconAlertTriangle } from "@tabler/icons-react"; import { useQueryClient } from "@tanstack/react-query"; import EasyModal, { type InnerModalProps } from "ez-modal-react"; -import { Form, Formik } from "formik"; +import { Form, Formik, Field } from "formik"; import { type ReactNode, useState } from "react"; import { Alert } from "react-bootstrap"; import Modal from "react-bootstrap/Modal"; @@ -115,6 +115,9 @@ const HTTPCertificateModal = EasyModal.create(({ visible, remove }: InnerModalPr { domainNames: [], provider: "letsencrypt", + meta: { + keyType: "ecdsa", + }, } as any } onSubmit={onSubmit} @@ -142,6 +145,30 @@ const HTTPCertificateModal = EasyModal.create(({ visible, remove }: InnerModalPr setTestResults(null); }} /> + + {({ field }: any) => ( +
+ + + + + +
+ )} +
{testResults ? (