diff --git a/agent/app/dto/request/website_ssl.go b/agent/app/dto/request/website_ssl.go index 5754f434f..a8ca63673 100644 --- a/agent/app/dto/request/website_ssl.go +++ b/agent/app/dto/request/website_ssl.go @@ -47,11 +47,12 @@ type WebsiteSSLApply struct { type WebsiteAcmeAccountCreate struct { Email string `json:"email" validate:"required"` - Type string `json:"type" validate:"required,oneof=letsencrypt zerossl buypass google freessl"` + Type string `json:"type" validate:"required,oneof=letsencrypt zerossl buypass google custom"` KeyType string `json:"keyType" validate:"required,oneof=P256 P384 2048 3072 4096 8192"` EabKid string `json:"eabKid"` EabHmacKey string `json:"eabHmacKey"` UseProxy bool `json:"useProxy"` + CaDirURL string `json:"caDirURL"` } type WebsiteAcmeAccountUpdate struct { diff --git a/agent/app/model/website_acme_account.go b/agent/app/model/website_acme_account.go index 4d0c72943..4e4ba9640 100644 --- a/agent/app/model/website_acme_account.go +++ b/agent/app/model/website_acme_account.go @@ -10,6 +10,7 @@ type WebsiteAcmeAccount struct { EabHmacKey string `gorm:"default:null" json:"eabHmacKey"` KeyType string `gorm:"not null;default:2048" json:"keyType"` UseProxy bool `gorm:"default:false" json:"useProxy"` + CaDirURL string `gorm:"default:null" json:"caDirURL"` } func (w WebsiteAcmeAccount) TableName() string { diff --git a/agent/app/service/website_acme_account.go b/agent/app/service/website_acme_account.go index 1cf691433..be5ab0b80 100644 --- a/agent/app/service/website_acme_account.go +++ b/agent/app/service/website_acme_account.go @@ -54,6 +54,9 @@ func (w WebsiteAcmeAccountService) Create(create request.WebsiteAcmeAccountCreat acmeAccount.EabKid = create.EabKid acmeAccount.EabHmacKey = create.EabHmacKey } + if create.Type == "custom" && create.CaDirURL != "" { + acmeAccount.CaDirURL = create.CaDirURL + } client, err := ssl.NewAcmeClient(acmeAccount, getSystemProxy(acmeAccount.UseProxy)) if err != nil { diff --git a/agent/app/service/website_ssl.go b/agent/app/service/website_ssl.go index dcdb85266..5af8dd67a 100644 --- a/agent/app/service/website_ssl.go +++ b/agent/app/service/website_ssl.go @@ -348,7 +348,9 @@ func (w WebsiteSSLService) ObtainSSL(apply request.WebsiteSSLApply) error { websiteSSL.ExpireDate = cert.NotAfter websiteSSL.StartDate = cert.NotBefore websiteSSL.Type = cert.Issuer.CommonName - websiteSSL.Organization = cert.Issuer.Organization[0] + if len(cert.Issuer.Organization) > 0 { + websiteSSL.Organization = cert.Issuer.Organization[0] + } websiteSSL.Status = constant.SSLReady printSSLLog(logger, "ApplySSLSuccess", map[string]interface{}{"domain": strings.Join(domains, ",")}, apply.DisableLog) saveCertificateFile(websiteSSL, logger) diff --git a/agent/init/migration/migrations/init.go b/agent/init/migration/migrations/init.go index 557bd53d6..f78f619e2 100644 --- a/agent/init/migration/migrations/init.go +++ b/agent/init/migration/migrations/init.go @@ -344,7 +344,7 @@ var UpdateWebsite = &gormigrate.Migration{ } var UpdateWebsiteAcmeAccount = &gormigrate.Migration{ - ID: "20250422-update-websiteAcmeAccount", + ID: "20250425-update-websiteAcmeAccount", Migrate: func(tx *gorm.DB) error { if err := tx.AutoMigrate(&model.WebsiteAcmeAccount{}); err != nil { return err diff --git a/agent/utils/ssl/acme.go b/agent/utils/ssl/acme.go index 52f1ad724..af8830b22 100644 --- a/agent/utils/ssl/acme.go +++ b/agent/utils/ssl/acme.go @@ -109,7 +109,7 @@ func NewRegisterClient(acmeAccount *model.WebsiteAcmeAccount, proxy *dto.SystemP Email: acmeAccount.Email, Key: priKey, } - config := NewConfigWithProxy(myUser, acmeAccount.Type, proxy) + config := NewConfigWithProxy(myUser, acmeAccount.Type, acmeAccount.CaDirURL, proxy) client, err := lego.NewClient(config) if err != nil { return nil, err @@ -156,7 +156,7 @@ func NewRegisterClient(acmeAccount *model.WebsiteAcmeAccount, proxy *dto.SystemP return acmeClient, nil } -func NewConfigWithProxy(user registration.User, accountType string, systemProxy *dto.SystemProxy) *lego.Config { +func NewConfigWithProxy(user registration.User, accountType, customCaURL string, systemProxy *dto.SystemProxy) *lego.Config { var ( caDirURL string proxyURL string @@ -174,6 +174,8 @@ func NewConfigWithProxy(user registration.User, accountType string, systemProxy caDirURL = "https://dv.acme-v02.api.pki.goog/directory" case "freessl": caDirURL = "https://acmepro.freessl.cn/v2/DV" + case "custom": + caDirURL = customCaURL } if systemProxy != nil { proxyURL = fmt.Sprintf("%s:%s", systemProxy.URL, systemProxy.Port) @@ -241,8 +243,9 @@ func createHTTPClientWithProxy(proxyURL, username, password string) *http.Client TLSHandshakeTimeout: 60 * time.Second, ResponseHeaderTimeout: 60 * time.Second, TLSClientConfig: &tls.Config{ - ServerName: os.Getenv("LEGO_CA_SERVER_NAME"), - RootCAs: initCertPool(), + InsecureSkipVerify: true, + //ServerName: os.Getenv("LEGO_CA_SERVER_NAME"), + //RootCAs: initCertPool(), }, }, } diff --git a/frontend/src/global/mimetype.ts b/frontend/src/global/mimetype.ts index 09cd7b912..dbaf5175a 100644 --- a/frontend/src/global/mimetype.ts +++ b/frontend/src/global/mimetype.ts @@ -152,6 +152,7 @@ export const AcmeAccountTypes = [ { label: 'ZeroSSL', value: 'zerossl' }, { label: 'Buypass', value: 'buypass' }, { label: 'Google Cloud', value: 'google' }, + { label: i18n.global.t('ssl.customAcme'), value: 'custom' }, ]; export const KeyTypes = [ diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 077022dba..5d97cb7db 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -2555,6 +2555,8 @@ const message = { shell: 'Script content', shellHelper: 'The default execution directory of the script is the 1Panel installation directory. If a certificate is pushed, the execution directory is the certificate push directory. The default timeout is 30 minutes', + customAcme: 'Custom ACME Service', + customAcmeURL: 'ACME Service URL', }, firewall: { create: 'Create Rule', diff --git a/frontend/src/lang/modules/ja.ts b/frontend/src/lang/modules/ja.ts index c3acc5820..a0443b3ee 100644 --- a/frontend/src/lang/modules/ja.ts +++ b/frontend/src/lang/modules/ja.ts @@ -2445,6 +2445,8 @@ const message = { shell: 'スクリプトコンテンツ', shellHelper: 'スクリプトのデフォルトの実行ディレクトリは、1Panelインストールディレクトリです。証明書がローカルディレクトリにプッシュされた場合、実行ディレクトリは証明書プッシュディレクトリになります。デフォルトの実行タイムアウトは30分です。', + customAcme: 'カスタム ACME サービス', + customAcmeURL: 'ACME サービス URL', }, firewall: { create: 'ルールを作成します', diff --git a/frontend/src/lang/modules/ko.ts b/frontend/src/lang/modules/ko.ts index 08568f3d6..f8eed9ee6 100644 --- a/frontend/src/lang/modules/ko.ts +++ b/frontend/src/lang/modules/ko.ts @@ -2404,6 +2404,8 @@ const message = { shell: '스크립트 내용', shellHelper: '스크립트의 기본 실행 디렉토리는 1Panel 설치 디렉토리입니다. 인증서가 로컬 디렉토리에 푸시되는 경우 실행 디렉토리는 인증서 푸시 디렉토리가 됩니다. 기본 실행 제한 시간은 30분입니다.', + customAcme: '사용자 정의 ACME 서비스', + customAcmeURL: 'ACME 서비스 URL', }, firewall: { create: '규칙 만들기', diff --git a/frontend/src/lang/modules/ms.ts b/frontend/src/lang/modules/ms.ts index d3cb6144f..dfa21f2d4 100644 --- a/frontend/src/lang/modules/ms.ts +++ b/frontend/src/lang/modules/ms.ts @@ -2501,6 +2501,8 @@ const message = { shell: 'Kandungan skrip', shellHelper: 'Direktori pelaksanaan lalai skrip adalah direktori pemasangan 1Panel. Jika sijil ditolak ke direktori tempatan, direktori pelaksanaan akan menjadi direktori tolak sijil. Tamat masa pelaksanaan lalai ialah 30 minit.', + customAcme: 'Perkhidmatan ACME Tersuai', + customAcmeURL: 'URL Perkhidmatan ACME', }, firewall: { create: 'Buat peraturan', diff --git a/frontend/src/lang/modules/pt-br.ts b/frontend/src/lang/modules/pt-br.ts index 88fe9fc36..83ca5af67 100644 --- a/frontend/src/lang/modules/pt-br.ts +++ b/frontend/src/lang/modules/pt-br.ts @@ -2498,6 +2498,8 @@ const message = { shell: 'Conteúdo do script', shellHelper: 'O diretório padrão de execução do script é o diretório de instalação do 1Panel. Se um certificado for enviado para o diretório local, o diretório de execução será o diretório de envio do certificado. O tempo limite padrão de execução é de 30 minutos.', + customAcme: 'Serviço ACME Personalizado', + customAcmeURL: 'URL do Serviço ACME', }, firewall: { create: 'Criar regra', diff --git a/frontend/src/lang/modules/ru.ts b/frontend/src/lang/modules/ru.ts index ed43e3b75..01efae2bd 100644 --- a/frontend/src/lang/modules/ru.ts +++ b/frontend/src/lang/modules/ru.ts @@ -2497,6 +2497,8 @@ const message = { shell: 'Содержимое скрипта', shellHelper: 'Директория выполнения скрипта по умолчанию - директория установки 1Panel. Если сертификат отправляется в локальную директорию, директорией выполнения будет директория отправки сертификата. Тайм-аут выполнения по умолчанию - 30 минут.', + customAcme: 'Пользовательская служба ACME', + customAcmeURL: 'URL службы ACME', }, firewall: { create: 'Создать правило', diff --git a/frontend/src/lang/modules/zh-Hant.ts b/frontend/src/lang/modules/zh-Hant.ts index 86d0473ae..f82407eee 100644 --- a/frontend/src/lang/modules/zh-Hant.ts +++ b/frontend/src/lang/modules/zh-Hant.ts @@ -2372,6 +2372,8 @@ const message = { shell: '腳本內容', shellHelper: '腳本預設執行目錄為 1Panel 安裝目錄,如果有推送證書,那麼執行目錄為證書推送目錄。預設超時時間 30 分鐘', + customAcme: '自訂 ACME 服務', + customAcmeURL: 'ACME 服務 URL', }, firewall: { create: '創建規則', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index c9ddaa5d5..eff39b962 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -2363,6 +2363,8 @@ const message = { shell: '脚本内容', shellHelper: '脚本默认执行目录为 1Panel 安装目录,如果有推送证书,那么执行目录为证书推送目录。默认超时时间 30 分钟', + customAcme: '自定义 ACME 服务', + customAcmeURL: 'ACME 服务 URL', }, firewall: { create: '创建规则', diff --git a/frontend/src/views/website/ssl/acme-account/create/index.vue b/frontend/src/views/website/ssl/acme-account/create/index.vue index 4410cabd4..6e4cb8f93 100644 --- a/frontend/src/views/website/ssl/acme-account/create/index.vue +++ b/frontend/src/views/website/ssl/acme-account/create/index.vue @@ -55,6 +55,9 @@ {{ $t('ssl.googleHelper') }} + + + @@ -86,6 +89,7 @@ const rules = ref({ eabKid: [Rules.requiredInput], eabHmacKey: [Rules.requiredInput], keyType: [Rules.requiredSelect], + caDirURL: [Rules.requiredInput], }); const initData = () => ({ @@ -95,6 +99,7 @@ const initData = () => ({ eabHmacKey: '', keyType: 'P256', useProxy: false, + caDirURL: '', }); const account = ref(initData());