mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 08:19:15 +08:00
feat: 证书申请增加配置,提高申请成功率 (#4903)
This commit is contained in:
parent
43ebf6eef9
commit
b489f5cf2f
@ -20,6 +20,10 @@ type WebsiteSSLCreate struct {
|
||||
Dir string `json:"dir"`
|
||||
ID uint `json:"id"`
|
||||
Description string `json:"description"`
|
||||
DisableCNAME bool `json:"disableCNAME"`
|
||||
SkipDNS bool `json:"skipDNS"`
|
||||
Nameserver1 string `json:"nameserver1"`
|
||||
Nameserver2 string `json:"nameserver2"`
|
||||
}
|
||||
|
||||
type WebsiteDNSReq struct {
|
||||
@ -79,6 +83,10 @@ type WebsiteSSLUpdate struct {
|
||||
Apply bool `json:"apply"`
|
||||
PushDir bool `json:"pushDir"`
|
||||
Dir string `json:"dir"`
|
||||
DisableCNAME bool `json:"disableCNAME"`
|
||||
SkipDNS bool `json:"skipDNS"`
|
||||
Nameserver1 string `json:"nameserver1"`
|
||||
Nameserver2 string `json:"nameserver2"`
|
||||
}
|
||||
|
||||
type WebsiteSSLUpload struct {
|
||||
|
@ -29,6 +29,10 @@ type WebsiteSSL struct {
|
||||
PushDir bool `json:"pushDir"`
|
||||
Dir string `json:"dir"`
|
||||
Description string `json:"description"`
|
||||
SkipDNS bool `json:"skipDNS"`
|
||||
Nameserver1 string `json:"nameserver1"`
|
||||
Nameserver2 string `json:"nameserver2"`
|
||||
DisableCNAME bool `json:"disableCNAME"`
|
||||
|
||||
AcmeAccount WebsiteAcmeAccount `json:"acmeAccount" gorm:"-:migration"`
|
||||
DnsAccount WebsiteDnsAccount `json:"dnsAccount" gorm:"-:migration"`
|
||||
|
@ -102,6 +102,12 @@ func (w WebsiteSSLService) Search(search request.WebsiteSSLSearch) ([]response.W
|
||||
}
|
||||
|
||||
func (w WebsiteSSLService) Create(create request.WebsiteSSLCreate) (request.WebsiteSSLCreate, error) {
|
||||
if create.Nameserver1 != "" && !common.IsValidIP(create.Nameserver1) {
|
||||
return create, buserr.New("ErrParseIP")
|
||||
}
|
||||
if create.Nameserver2 != "" && !common.IsValidIP(create.Nameserver2) {
|
||||
return create, buserr.New("ErrParseIP")
|
||||
}
|
||||
var res request.WebsiteSSLCreate
|
||||
acmeAccount, err := websiteAcmeRepo.GetFirst(commonRepo.WithByID(create.AcmeAccountID))
|
||||
if err != nil {
|
||||
@ -116,6 +122,10 @@ func (w WebsiteSSLService) Create(create request.WebsiteSSLCreate) (request.Webs
|
||||
KeyType: create.KeyType,
|
||||
PushDir: create.PushDir,
|
||||
Description: create.Description,
|
||||
Nameserver1: create.Nameserver1,
|
||||
Nameserver2: create.Nameserver2,
|
||||
SkipDNS: create.SkipDNS,
|
||||
DisableCNAME: create.DisableCNAME,
|
||||
}
|
||||
if create.PushDir {
|
||||
if !files.NewFileOp().Stat(create.Dir) {
|
||||
@ -191,7 +201,7 @@ func (w WebsiteSSLService) ObtainSSL(apply request.WebsiteSSLApply) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = client.UseDns(ssl.DnsType(dnsAccount.Type), dnsAccount.Authorization, apply.SkipDNSCheck, apply.Nameservers); err != nil {
|
||||
if err = client.UseDns(ssl.DnsType(dnsAccount.Type), dnsAccount.Authorization, *websiteSSL); err != nil {
|
||||
return err
|
||||
}
|
||||
case constant.Http:
|
||||
@ -374,6 +384,10 @@ func (w WebsiteSSLService) Update(update request.WebsiteSSLUpdate) error {
|
||||
updateParams["provider"] = update.Provider
|
||||
updateParams["key_type"] = update.KeyType
|
||||
updateParams["push_dir"] = update.PushDir
|
||||
updateParams["disable_cname"] = update.DisableCNAME
|
||||
updateParams["skip_dns"] = update.SkipDNS
|
||||
updateParams["nameserver1"] = update.Nameserver1
|
||||
updateParams["nameserver2"] = update.Nameserver2
|
||||
|
||||
acmeAccount, err := websiteAcmeRepo.GetFirst(commonRepo.WithByID(update.AcmeAccountID))
|
||||
if err != nil {
|
||||
|
@ -82,6 +82,8 @@ func Init() {
|
||||
migrations.UpdateXpackHideMenu,
|
||||
migrations.AddMenuTabsSetting,
|
||||
migrations.AddDeveloperSetting,
|
||||
|
||||
migrations.AddWebsiteSSLColumn,
|
||||
})
|
||||
if err := m.Migrate(); err != nil {
|
||||
global.LOG.Error(err)
|
||||
|
@ -154,3 +154,13 @@ var AddDeveloperSetting = &gormigrate.Migration{
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var AddWebsiteSSLColumn = &gormigrate.Migration{
|
||||
ID: "20240508-update-website-ssl",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
if err := tx.AutoMigrate(&model.WebsiteSSL{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -317,3 +317,7 @@ func SplitStr(str string, spi ...string) []string {
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
func IsValidIP(ip string) bool {
|
||||
return net.ParseIP(ip) != nil
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package ssl
|
||||
import (
|
||||
"crypto"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
@ -84,7 +85,7 @@ type DNSParam struct {
|
||||
SecretID string `json:"secretID"`
|
||||
}
|
||||
|
||||
func (c *AcmeClient) UseDns(dnsType DnsType, params string, skipDNSCheck bool, nameservers []string) error {
|
||||
func (c *AcmeClient) UseDns(dnsType DnsType, params string, websiteSSL model.WebsiteSSL) error {
|
||||
var (
|
||||
param DNSParam
|
||||
p challenge.Provider
|
||||
@ -162,11 +163,23 @@ func (c *AcmeClient) UseDns(dnsType DnsType, params string, skipDNSCheck bool, n
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var nameservers []string
|
||||
if websiteSSL.Nameserver1 != "" {
|
||||
nameservers = append(nameservers, websiteSSL.Nameserver1)
|
||||
}
|
||||
if websiteSSL.Nameserver2 != "" {
|
||||
nameservers = append(nameservers, websiteSSL.Nameserver2)
|
||||
}
|
||||
if websiteSSL.DisableCNAME {
|
||||
_ = os.Setenv("LEGO_DISABLE_CNAME_SUPPORT", "true")
|
||||
} else {
|
||||
_ = os.Setenv("LEGO_DISABLE_CNAME_SUPPORT", "false")
|
||||
}
|
||||
|
||||
return c.Client.Challenge.SetDNS01Provider(p,
|
||||
dns01.CondOption(len(nameservers) > 0,
|
||||
dns01.AddRecursiveNameservers(nameservers)),
|
||||
dns01.CondOption(skipDNSCheck,
|
||||
dns01.CondOption(websiteSSL.SkipDNS,
|
||||
dns01.DisableCompletePropagationRequirement()),
|
||||
dns01.AddDNSTimeout(10*time.Minute),
|
||||
)
|
||||
|
@ -173,6 +173,10 @@ export namespace Website {
|
||||
pushDir: boolean;
|
||||
dir: string;
|
||||
keyType: string;
|
||||
nameserver1: string;
|
||||
nameserver2: string;
|
||||
disableCNAME: boolean;
|
||||
skipDNS: boolean;
|
||||
}
|
||||
|
||||
export interface SSLDTO extends SSL {
|
||||
@ -452,7 +456,6 @@ export namespace Website {
|
||||
|
||||
export interface SSLObtain {
|
||||
ID: number;
|
||||
skipDNSCheck: boolean;
|
||||
}
|
||||
|
||||
export interface CA extends CommonModel {
|
||||
|
@ -22,6 +22,20 @@ const checkIp = (rule: any, value: any, callback: any) => {
|
||||
}
|
||||
};
|
||||
|
||||
const checkIpv4 = (rule: any, value: any, callback: any) => {
|
||||
if (value === '' || typeof value === 'undefined' || value == null) {
|
||||
callback();
|
||||
} else {
|
||||
const reg =
|
||||
/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
|
||||
if (!reg.test(value) && value !== '') {
|
||||
callback(new Error(i18n.global.t('commons.rule.ip')));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const checkIpV6 = (rule: any, value: any, callback: any) => {
|
||||
if (value === '' || typeof value === 'undefined' || value == null) {
|
||||
callback(new Error(i18n.global.t('commons.rule.requiredInput')));
|
||||
@ -533,6 +547,7 @@ interface CommonRule {
|
||||
floatNumber: FormItemRule;
|
||||
ip: FormItemRule;
|
||||
ipV6: FormItemRule;
|
||||
ipv4: FormItemRule;
|
||||
ipV4V6OrDomain: FormItemRule;
|
||||
host: FormItemRule;
|
||||
illegal: FormItemRule;
|
||||
@ -768,4 +783,8 @@ export const Rules: CommonRule = {
|
||||
validator: checkHttpOrHttps,
|
||||
trigger: 'blur',
|
||||
},
|
||||
ipv4: {
|
||||
validator: checkIpv4,
|
||||
trigger: 'blur',
|
||||
},
|
||||
};
|
||||
|
@ -2062,6 +2062,10 @@ const message = {
|
||||
deprecated: 'will be deprecated',
|
||||
deprecatedHelper:
|
||||
'Maintenance has been stopped and may be abandoned in a future version. Please use Tencent Cloud method for analysis',
|
||||
disableCNAME: 'Disable CNAME',
|
||||
disableCNAMEHelper: 'Domain name with CNAME configuration, if the application fails, you can check here',
|
||||
nameserver: 'DNS server',
|
||||
nameserverHelper: 'Use a custom DNS server to verify domain names',
|
||||
},
|
||||
firewall: {
|
||||
create: 'Create rule',
|
||||
|
@ -1929,6 +1929,10 @@ const message = {
|
||||
cfHelper: '請勿使用 Global API Key',
|
||||
deprecated: '即將廢棄',
|
||||
deprecatedHelper: '已經停止維護,可能會在以後的某個版本廢棄,請使用騰訊雲方式解析',
|
||||
disableCNAME: '停用 CNAME',
|
||||
disableCNAMEHelper: '有 CNAME 配置的域名,如果申請失敗,可以勾選此處',
|
||||
nameserver: 'DNS 伺服器',
|
||||
nameserverHelper: '使用自訂的 DNS 伺服器來校驗網域名稱',
|
||||
},
|
||||
firewall: {
|
||||
create: '創建規則',
|
||||
|
@ -1929,6 +1929,10 @@ const message = {
|
||||
cfHelper: '请勿使用 Global API Key',
|
||||
deprecated: '即将废弃',
|
||||
deprecatedHelper: '已经停止维护,可能会在以后的某个版本废弃,请使用腾讯云方式解析',
|
||||
disableCNAME: '禁用 CNAME',
|
||||
disableCNAMEHelper: '有 CNAME 配置的域名,如果申请失败,可以勾选此处',
|
||||
nameserver: 'DNS 服务器',
|
||||
nameserverHelper: '使用自定义的 DNS 服务器来校验域名',
|
||||
},
|
||||
firewall: {
|
||||
create: '创建规则',
|
||||
|
@ -31,11 +31,6 @@
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<el-checkbox v-model="skipDNSCheck">{{ $t('ssl.skipDNSCheck') }}</el-checkbox>
|
||||
<span class="input-help">{{ $t('ssl.skipDNSCheckHelper') }}</span>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
|
||||
@ -67,13 +62,11 @@ const handleClose = () => {
|
||||
open.value = false;
|
||||
em('close', false);
|
||||
};
|
||||
const skipDNSCheck = ref(false);
|
||||
|
||||
const acceptParams = async (props: RenewProps) => {
|
||||
open.value = true;
|
||||
dnsResolve.value = [];
|
||||
sslID.value = props.ssl.id;
|
||||
skipDNSCheck.value = false;
|
||||
getDnsResolve(props.ssl);
|
||||
};
|
||||
|
||||
@ -96,7 +89,7 @@ const getDnsResolve = async (row: Website.SSL) => {
|
||||
};
|
||||
|
||||
const submit = () => {
|
||||
ObtainSSL({ ID: sslID.value, skipDNSCheck: skipDNSCheck.value })
|
||||
ObtainSSL({ ID: sslID.value })
|
||||
.then(() => {
|
||||
MsgSuccess(i18n.global.t('ssl.applyStart'));
|
||||
handleClose();
|
||||
|
@ -119,6 +119,30 @@
|
||||
{{ $t('ssl.pushDirHelper') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="''" prop="disableCNAME">
|
||||
<el-checkbox v-model="ssl.disableCNAME" :label="$t('ssl.disableCNAME')" />
|
||||
<span class="input-help">
|
||||
{{ $t('ssl.disableCNAMEHelper') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="''" prop="skipDNS">
|
||||
<el-checkbox v-model="ssl.skipDNS" :label="$t('ssl.skipDNSCheck')" />
|
||||
<span class="input-help">
|
||||
{{ $t('ssl.skipDNSCheckHelper') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('ssl.nameserver') + '1'" prop="nameserver1">
|
||||
<el-input v-model.trim="ssl.nameserver1"></el-input>
|
||||
<span class="input-help">
|
||||
{{ $t('ssl.nameserverHelper') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('ssl.nameserver') + '2'" prop="nameserver1">
|
||||
<el-input v-model.trim="ssl.nameserver2"></el-input>
|
||||
<span class="input-help">
|
||||
{{ $t('ssl.nameserverHelper') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -178,6 +202,8 @@ const rules = ref({
|
||||
autoRenew: [Rules.requiredInput],
|
||||
keyType: [Rules.requiredInput],
|
||||
dir: [Rules.requiredInput],
|
||||
nameserver1: [Rules.ipv4],
|
||||
nameserver2: [Rules.ipv4],
|
||||
});
|
||||
const websiteID = ref();
|
||||
|
||||
@ -194,6 +220,10 @@ const initData = () => ({
|
||||
pushDir: false,
|
||||
dir: '',
|
||||
description: '',
|
||||
disableCNAME: false,
|
||||
skipDNS: false,
|
||||
nameserver1: '',
|
||||
nameserver2: '',
|
||||
});
|
||||
|
||||
const ssl = ref(initData());
|
||||
@ -231,6 +261,10 @@ const acceptParams = (op: string, websiteSSL: Website.SSLDTO) => {
|
||||
ssl.value.description = websiteSSL.description;
|
||||
ssl.value.id = websiteSSL.id;
|
||||
ssl.value.provider = websiteSSL.provider;
|
||||
ssl.value.skipDNS = websiteSSL.skipDNS;
|
||||
ssl.value.disableCNAME = websiteSSL.disableCNAME;
|
||||
ssl.value.nameserver1 = websiteSSL.nameserver1;
|
||||
ssl.value.nameserver2 = websiteSSL.nameserver2;
|
||||
}
|
||||
ssl.value.websiteId = Number(id.value);
|
||||
getAcmeAccounts();
|
||||
@ -318,6 +352,10 @@ const submit = async (formEl: FormInstance | undefined) => {
|
||||
dir: ssl.value.dir,
|
||||
description: ssl.value.description,
|
||||
provider: ssl.value.provider,
|
||||
disableCNAME: ssl.value.disableCNAME,
|
||||
skipDNS: ssl.value.skipDNS,
|
||||
nameserver1: ssl.value.nameserver1,
|
||||
nameserver2: ssl.value.nameserver2,
|
||||
};
|
||||
UpdateSSL(sslUpdate)
|
||||
.then(() => {
|
||||
|
@ -127,7 +127,6 @@ const rules = ref<any>({
|
||||
secretKey: [Rules.requiredInput],
|
||||
id: [Rules.requiredInput],
|
||||
token: [Rules.requiredInput],
|
||||
email: [Rules.requiredInput],
|
||||
apiKey: [Rules.requiredInput],
|
||||
apiUser: [Rules.requiredInput],
|
||||
secretID: [Rules.requiredInput],
|
||||
|
@ -21,10 +21,6 @@
|
||||
<br />
|
||||
</div>
|
||||
<span>{{ $t('ssl.renewConfirm', [ssl.primaryDomain]) }}</span>
|
||||
<div class="mt-3">
|
||||
<el-checkbox v-model="skipDNSCheck">{{ $t('ssl.skipDNSCheck') }}</el-checkbox>
|
||||
<span class="input-help">{{ $t('ssl.skipDNSCheckHelper') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
@ -56,12 +52,10 @@ const handleClose = () => {
|
||||
em('close', false);
|
||||
};
|
||||
const ssl = ref();
|
||||
const skipDNSCheck = ref(false);
|
||||
|
||||
const acceptParams = async (props: RenewProps) => {
|
||||
ssl.value = props.ssl;
|
||||
open.value = true;
|
||||
skipDNSCheck.value = false;
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
@ -70,7 +64,7 @@ const submit = async () => {
|
||||
if (ssl.value.provider == 'selfSigned') {
|
||||
await RenewSSLByCA({ SSLID: ssl.value.id });
|
||||
} else {
|
||||
await ObtainSSL({ ID: ssl.value.id, skipDNSCheck: skipDNSCheck.value });
|
||||
await ObtainSSL({ ID: ssl.value.id });
|
||||
}
|
||||
handleClose();
|
||||
MsgSuccess(i18n.global.t('ssl.applyStart'));
|
||||
|
Loading…
x
Reference in New Issue
Block a user