fix: fix issue with enable website ssl with ipv6 failed (#9255)

This commit is contained in:
CityFun 2025-06-24 13:44:17 +08:00 committed by GitHub
parent af4b23e0e0
commit 193ae2b7d6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 101 additions and 109 deletions

View file

@ -922,18 +922,12 @@ func (w WebsiteService) GetWebsiteHTTPS(websiteId uint) (response.WebsiteHTTPS,
res response.WebsiteHTTPS
httpsPorts []string
)
websiteDomains, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithWebsiteId(websiteId))
for _, domain := range websiteDomains {
if domain.SSL {
httpsPorts = append(httpsPorts, strconv.Itoa(domain.Port))
}
}
if len(httpsPorts) == 0 {
nginxInstall, _ := getAppInstallByKey(constant.AppOpenresty)
res.HttpsPort = strconv.Itoa(nginxInstall.HttpsPort)
} else {
res.HttpsPort = strings.Join(httpsPorts, ",")
httpsPortsMap := getHttpsPort(websiteId)
for port := range httpsPortsMap {
httpsPorts = append(httpsPorts, strconv.Itoa(port))
}
res.HttpsPort = strings.Join(httpsPorts, ",")
if website.WebsiteSSLID == 0 {
res.Enable = false
return res, nil
@ -981,10 +975,6 @@ func (w WebsiteService) OpWebsiteHTTPS(ctx context.Context, req request.WebsiteH
res response.WebsiteHTTPS
websiteSSL model.WebsiteSSL
)
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
if err != nil {
return nil, err
}
if err = ChangeHSTSConfig(req.Hsts, req.Http3, website); err != nil {
return nil, err
}
@ -995,24 +985,27 @@ func (w WebsiteService) OpWebsiteHTTPS(ctx context.Context, req request.WebsiteH
website.Protocol = constant.ProtocolHTTP
website.WebsiteSSLID = 0
httpsPorts, err := getHttpsPort(&website)
websiteDomains, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithWebsiteId(website.ID))
ports := make(map[int]struct{})
for _, domain := range websiteDomains {
ports[domain.Port] = struct{}{}
}
for port := range ports {
if err = removeSSLListen(website, []string{strconv.Itoa(port)}); err != nil {
return nil, err
}
}
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
if err != nil {
return nil, err
}
if len(httpsPorts) == 1 && httpsPorts[0] == nginxInstall.HttpsPort {
httpsPortStr := strconv.Itoa(httpsPorts[0])
if _, ok := ports[nginxInstall.HttpsPort]; !ok {
httpsPortStr := strconv.Itoa(nginxInstall.HttpsPort)
if err = deleteListenAndServerName(website, []string{httpsPortStr, "[::]:" + httpsPortStr}, []string{}); err != nil {
return nil, err
}
} else {
for _, port := range httpsPorts {
httpsPortStr := strconv.Itoa(port)
if err = removeSSLListen(website, []string{httpsPortStr}); err != nil {
return nil, err
}
}
}
nginxParams := getNginxParamsFromStaticFile(dto.SSL, nil)
nginxParams = append(nginxParams,
dto.NginxParam{

View file

@ -651,22 +651,33 @@ func createPemFile(website model.Website, websiteSSL model.WebsiteSSL) error {
return nil
}
func getHttpsPort(website *model.Website) ([]int, error) {
websiteDomains, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithWebsiteId(website.ID))
var httpsPorts []int
for _, domain := range websiteDomains {
if domain.SSL {
httpsPorts = append(httpsPorts, domain.Port)
func getHttpsPort(websiteID uint) map[int]struct{} {
domains, err := websiteDomainRepo.GetBy(websiteDomainRepo.WithWebsiteId(websiteID))
if err != nil {
return nil
}
httpsPorts := make(map[int]struct{})
nginxInstall, _ := getAppInstallByKey(constant.AppOpenresty)
hasDefaultPort := false
for _, domain := range domains {
if domain.Port == nginxInstall.HttpPort {
hasDefaultPort = true
}
if domain.SSL {
httpsPorts[domain.Port] = struct{}{}
}
}
if hasDefaultPort {
httpsPorts[nginxInstall.HttpsPort] = struct{}{}
}
if len(httpsPorts) == 0 {
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
if err != nil {
return nil, err
for _, domain := range domains {
if !domain.SSL {
httpsPorts[domain.Port] = struct{}{}
}
}
httpsPorts = append(httpsPorts, nginxInstall.HttpsPort)
}
return httpsPorts, nil
return httpsPorts
}
func applySSL(website *model.Website, websiteSSL model.WebsiteSSL, req request.WebsiteHTTPSOp) error {
@ -678,63 +689,71 @@ func applySSL(website *model.Website, websiteSSL model.WebsiteSSL, req request.W
if err != nil {
return nil
}
noDefaultPort := true
httpPorts := make(map[int]struct{})
httpsPorts := make(map[int]struct{})
hasDefaultPort := false
for _, domain := range domains {
if domain.Port == 80 {
noDefaultPort = false
if domain.Port == nginxFull.Install.HttpPort {
hasDefaultPort = true
}
if domain.Port != 80 && !domain.SSL {
if domain.SSL {
httpsPorts[domain.Port] = struct{}{}
} else {
httpPorts[domain.Port] = struct{}{}
}
}
if hasDefaultPort {
httpsPorts[nginxFull.Install.HttpsPort] = struct{}{}
}
if len(httpsPorts) == 0 {
for port := range httpPorts {
httpsPorts[port] = struct{}{}
}
}
config := nginxFull.SiteConfig.Config
server := config.FindServers()[0]
httpPort := strconv.Itoa(nginxFull.Install.HttpPort)
httpsPort, err := getHttpsPort(website)
if err != nil {
return err
}
httpPortIPV6 := "[::]:" + httpPort
defaultHttpPort := strconv.Itoa(nginxFull.Install.HttpPort)
defaultHttpPortIPV6 := "[::]:" + defaultHttpPort
for _, port := range httpsPort {
if _, ok := httpPorts[port]; !ok {
server.DeleteListen(strconv.Itoa(port))
}
setListen(server, strconv.Itoa(port), website.IPV6, req.Http3, website.DefaultServer, true)
for port := range httpsPorts {
portStr := strconv.Itoa(port)
server.RemoveListenByBind(portStr)
server.RemoveListenByBind("[::]:" + portStr)
setListen(server, portStr, website.IPV6, req.Http3, website.DefaultServer, true)
}
server.UpdateDirective("http2", []string{"on"})
switch req.HttpConfig {
case constant.HTTPSOnly:
server.RemoveListenByBind(httpPort)
server.RemoveListenByBind(httpPortIPV6)
server.RemoveListenByBind(defaultHttpPort)
server.RemoveListenByBind(defaultHttpPortIPV6)
server.RemoveDirective("if", []string{"($scheme"})
case constant.HTTPToHTTPS:
if !noDefaultPort {
server.UpdateListen(httpPort, website.DefaultServer)
}
if website.IPV6 {
server.UpdateListen(httpPortIPV6, website.DefaultServer)
if hasDefaultPort {
server.UpdateListen(defaultHttpPort, website.DefaultServer)
if website.IPV6 {
server.UpdateListen(defaultHttpPortIPV6, website.DefaultServer)
}
}
server.AddHTTP2HTTPS()
case constant.HTTPAlso:
if !noDefaultPort {
server.UpdateListen(httpPort, website.DefaultServer)
if hasDefaultPort {
server.UpdateListen(defaultHttpPort, website.DefaultServer)
if website.IPV6 {
server.UpdateListen(defaultHttpPortIPV6, website.DefaultServer)
}
}
server.RemoveDirective("if", []string{"($scheme"})
if website.IPV6 {
server.UpdateListen(httpPortIPV6, website.DefaultServer)
}
}
if !req.Hsts {
server.RemoveDirective("add_header", []string{"Strict-Transport-Security", "\"max-age=31536000\""})
}
if !req.Http3 {
for _, port := range httpsPort {
for port := range httpsPorts {
server.RemoveListen(strconv.Itoa(port), "quic")
if website.IPV6 {
httpsPortIPV6 := "[::]:" + strconv.Itoa(port)

View file

@ -2416,8 +2416,6 @@ const message = {
enableSSLHelper: 'Failure to enable will not affect the creation of the website',
batchAdd: 'Batch Add Domains',
generateDomain: 'Generate',
domainSSLHelper:
'Enabling SSL on a non-443 port will cause the 443 port to stop listening. If you need the 443 port to continue listening, please add the domain:443',
global: 'Global',
subsite: 'Subsite',
subsiteHelper: 'A subsite can select an existing PHP or static website directory as the main directory.',

View file

@ -2331,8 +2331,6 @@ const message = {
enableSSLHelper: 'SSLの有効化に失敗してもウェブサイトの作成には影響しません',
batchAdd: 'ドメインを一括追加',
generateDomain: '生成',
domainSSLHelper:
'443以外のポートでSSLを有効にすると443ポートのリスナーが削除されます443ポートを引き続きリスニングするにはドメイン:443を追加してください',
global: 'グローバル',
subsite: 'サブサイト',
subsiteHelper:

View file

@ -2291,8 +2291,6 @@ const message = {
enableSSLHelper: 'SSL 활성화 실패는 웹사이트 생성에 영향을 미치지 않습니다.',
batchAdd: '도메인 일괄 추가',
generateDomain: '생성',
domainSSLHelper:
'443 아닌 포트에서 SSL을 활성화하면 443 포트 리스너가 제거됩니다. 443 포트를 계속 리스닝하려면 도메인:443 추가하세요.',
global: '글로벌',
subsite: '하위 사이트',
subsiteHelper: '하위 사이트는 기존 PHP 또는 정적 웹사이트의 디렉토리를 루트 디렉토리로 선택할 있습니다.',

View file

@ -2384,8 +2384,6 @@ const message = {
enableSSLHelper: 'Kegagalan mengaktifkan SSL tidak akan menjejaskan penciptaan laman web.',
batchAdd: 'Tambah Domain Secara Batch',
generateDomain: 'Hasilkan',
domainSSLHelper:
'Mengaktifkan SSL pada port selain 443 akan menghapus pendengar port 443. Untuk terus mendengar port 443, sila tambah domain:443.',
global: 'Global',
subsite: 'Sublaman',
subsiteHelper:

View file

@ -2381,8 +2381,6 @@ const message = {
enableSSLHelper: 'A falha ao ativar o SSL não afetará a criação do site.',
batchAdd: 'Adicionar Domínios em Lote',
generateDomain: 'Gerar',
domainSSLHelper:
'Ativar o SSL em portas que não sejam a 443 removerá o ouvinte da porta 443. Para manter a porta 443 ouvindo, adicione o domínio:443.',
global: 'Global',
subsite: 'Subsite',
subsiteHelper:

View file

@ -2379,8 +2379,6 @@ const message = {
enableSSLHelper: 'Неудача при включении SSL не повлияет на создание сайта.',
batchAdd: 'Пакетное Добавление Доменов',
generateDomain: 'Сгенерировать',
domainSSLHelper:
'Включение SSL на портах, отличных от 443, удалит слушатель порта 443. Чтобы порт 443 продолжал прослушиваться, добавьте домен:443.',
global: 'Глобальный',
subsite: 'Подсайт',
subsiteHelper:

View file

@ -2255,7 +2255,6 @@ const message = {
enableSSLHelper: '開啟失敗不會影響網站創建',
batchAdd: '批量添加域名',
generateDomain: '生成',
domainSSLHelper: ' 443 端口開啟 SSL 會導致 443 端口移除監聽如需 443 端口繼續監聽請添加域名:443',
global: '全局',
subsite: '子網站',
subsiteHelper: '子網站可以選擇已存在的 PHP 和靜態網站的目錄作為主目錄',

View file

@ -2243,7 +2243,6 @@ const message = {
enableSSLHelper: '开启失败不会影响网站创建',
batchAdd: '批量添加域名',
generateDomain: '生成',
domainSSLHelper: ' 443 端口开启 SSL 会导致 443 端口去掉监听如需 443 端口继续监听请添加域名:443',
global: '全局',
subsite: '子网站',
subsiteHelper: '子网站可以选择已存在的 PHP 和静态网站的目录作为主目录',

View file

@ -2,7 +2,6 @@
<ComplexTable :data="data" @search="search" v-loading="loading" :heightDiff="400">
<template #toolbar>
<el-button type="primary" plain @click="openCreate">{{ $t('website.addDomain') }}</el-button>
<el-text type="info" class="!ml-2">{{ $t('website.domainSSLHelper') }}</el-text>
</template>
<el-table-column width="30px">
<template #default="{ row }">

View file

@ -55,6 +55,7 @@
label-width="125px"
:rules="rules"
:validate-on-rule-change="false"
v-loading="loading"
>
<el-form-item :label="$t('commons.table.group')" prop="webSiteGroupId">
<el-select v-model="website.webSiteGroupId">
@ -888,7 +889,7 @@ const changeSSl = (sslid: number) => {
const submit = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid) => {
await formEl.validate(async (valid) => {
if (!valid) {
return;
}
@ -897,35 +898,29 @@ const submit = async (formEl: FormInstance | undefined) => {
return;
}
loading.value = true;
preCheck({})
.then((res) => {
if (res.data) {
loading.value = false;
preCheckRef.value.acceptParams({ items: res.data });
} else {
if (website.value.type === 'proxy') {
website.value.proxy = website.value.proxyProtocol + website.value.proxyAddress;
}
if (!website.value.enableFtp) {
website.value.ftpUser = '';
website.value.ftpPassword = '';
}
const taskID = uuidv4();
website.value.taskID = taskID;
createWebsite(website.value)
.then(() => {
MsgSuccess(i18n.global.t('commons.msg.createSuccess'));
handleClose();
})
.finally(() => {
loading.value = false;
});
openTaskLog(taskID);
try {
const res = await preCheck({});
if (res.data) {
preCheckRef.value.acceptParams({ items: res.data });
} else {
if (website.value.type === 'proxy') {
website.value.proxy = website.value.proxyProtocol + website.value.proxyAddress;
}
})
.catch(() => {
loading.value = false;
});
if (!website.value.enableFtp) {
website.value.ftpUser = '';
website.value.ftpPassword = '';
}
const taskID = uuidv4();
website.value.taskID = taskID;
await createWebsite(website.value);
MsgSuccess(i18n.global.t('commons.msg.createSuccess'));
handleClose();
openTaskLog(taskID);
}
} catch (error) {
} finally {
loading.value = false;
}
});
};