mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 08:19:15 +08:00
feat: HTTPS增加协议版本和加密算法
This commit is contained in:
parent
4000f2db3d
commit
92cb73a6eb
@ -30,7 +30,7 @@
|
|||||||
"labelEn": "Port",
|
"labelEn": "Port",
|
||||||
"required": true,
|
"required": true,
|
||||||
"default": 9001,
|
"default": 9001,
|
||||||
"envKey": "API_ROOT"
|
"envKey": "PORT_API"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -5,9 +5,9 @@ services:
|
|||||||
container_name: 1panel_minio
|
container_name: 1panel_minio
|
||||||
ports:
|
ports:
|
||||||
- ${PANEL_APP_PORT_HTTP}:9000
|
- ${PANEL_APP_PORT_HTTP}:9000
|
||||||
- ${API_ROOT}:9001
|
- ${PORT_API}:9001
|
||||||
restart: always
|
restart: always
|
||||||
command: server /data --console-address ":9001"
|
command: server /data --console-address :9000 --address :9001
|
||||||
environment:
|
environment:
|
||||||
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
|
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
|
||||||
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
|
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
|
||||||
|
@ -96,13 +96,15 @@ type WebsiteDomainDelete struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type WebsiteHTTPSOp struct {
|
type WebsiteHTTPSOp struct {
|
||||||
WebsiteID uint `json:"websiteId" validate:"required"`
|
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||||
Enable bool `json:"enable" validate:"required"`
|
Enable bool `json:"enable" validate:"required"`
|
||||||
WebsiteSSLID uint `json:"websiteSSLId"`
|
WebsiteSSLID uint `json:"websiteSSLId"`
|
||||||
Type string `json:"type" validate:"oneof=existed auto manual"`
|
Type string `json:"type" validate:"oneof=existed auto manual"`
|
||||||
PrivateKey string `json:"privateKey"`
|
PrivateKey string `json:"privateKey"`
|
||||||
Certificate string `json:"certificate"`
|
Certificate string `json:"certificate"`
|
||||||
HttpConfig string `json:"HttpConfig" validate:"oneof=HTTPSOnly HTTPAlso HTTPToHTTPS"`
|
HttpConfig string `json:"HttpConfig" validate:"oneof=HTTPSOnly HTTPAlso HTTPToHTTPS"`
|
||||||
|
SSLProtocol []string `json:"SSLProtocol"`
|
||||||
|
Algorithm string `json:"algorithm"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type WebsiteNginxUpdate struct {
|
type WebsiteNginxUpdate struct {
|
||||||
|
@ -30,7 +30,9 @@ type WebsiteWafConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type WebsiteHTTPS struct {
|
type WebsiteHTTPS struct {
|
||||||
Enable bool `json:"enable"`
|
Enable bool `json:"enable"`
|
||||||
HttpConfig string `json:"httpConfig"`
|
HttpConfig string `json:"httpConfig"`
|
||||||
SSL model.WebsiteSSL `json:"SSL"`
|
SSL model.WebsiteSSL `json:"SSL"`
|
||||||
|
SSLProtocol []string `json:"SSLProtocol"`
|
||||||
|
Algorithm string `json:"algorithm"`
|
||||||
}
|
}
|
||||||
|
@ -477,6 +477,18 @@ func (w WebsiteService) GetWebsiteHTTPS(websiteId uint) (response.WebsiteHTTPS,
|
|||||||
} else {
|
} else {
|
||||||
res.HttpConfig = constant.HTTPToHTTPS
|
res.HttpConfig = constant.HTTPToHTTPS
|
||||||
}
|
}
|
||||||
|
params, err := getNginxParamsByKeys(constant.NginxScopeServer, []string{"ssl_protocols", "ssl_ciphers"}, &website)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
for _, p := range params {
|
||||||
|
if p.Name == "ssl_protocols" {
|
||||||
|
res.SSLProtocol = p.Params
|
||||||
|
}
|
||||||
|
if p.Name == "ssl_ciphers" {
|
||||||
|
res.Algorithm = p.Params[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,7 +502,8 @@ func (w WebsiteService) OpWebsiteHTTPS(ctx context.Context, req request.WebsiteH
|
|||||||
websiteSSL model.WebsiteSSL
|
websiteSSL model.WebsiteSSL
|
||||||
)
|
)
|
||||||
res.Enable = req.Enable
|
res.Enable = req.Enable
|
||||||
|
res.SSLProtocol = req.SSLProtocol
|
||||||
|
res.Algorithm = req.Algorithm
|
||||||
if !req.Enable {
|
if !req.Enable {
|
||||||
website.Protocol = constant.ProtocolHTTP
|
website.Protocol = constant.ProtocolHTTP
|
||||||
website.WebsiteSSLID = 0
|
website.WebsiteSSLID = 0
|
||||||
@ -544,7 +557,7 @@ func (w WebsiteService) OpWebsiteHTTPS(ctx context.Context, req request.WebsiteH
|
|||||||
res.SSL = websiteSSL
|
res.SSL = websiteSSL
|
||||||
}
|
}
|
||||||
website.Protocol = constant.ProtocolHTTPS
|
website.Protocol = constant.ProtocolHTTPS
|
||||||
if err := applySSL(website, websiteSSL, req.HttpConfig); err != nil {
|
if err := applySSL(website, websiteSSL, req); err != nil {
|
||||||
return response.WebsiteHTTPS{}, err
|
return response.WebsiteHTTPS{}, err
|
||||||
}
|
}
|
||||||
website.HttpConfig = req.HttpConfig
|
website.HttpConfig = req.HttpConfig
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
@ -298,7 +299,7 @@ func createPemFile(website model.Website, websiteSSL model.WebsiteSSL) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func applySSL(website model.Website, websiteSSL model.WebsiteSSL, httpConfig string) error {
|
func applySSL(website model.Website, websiteSSL model.WebsiteSSL, req request.WebsiteHTTPSOp) error {
|
||||||
nginxFull, err := getNginxFull(&website)
|
nginxFull, err := getNginxFull(&website)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
@ -307,7 +308,7 @@ func applySSL(website model.Website, websiteSSL model.WebsiteSSL, httpConfig str
|
|||||||
server := config.FindServers()[0]
|
server := config.FindServers()[0]
|
||||||
server.UpdateListen("443", false, "ssl")
|
server.UpdateListen("443", false, "ssl")
|
||||||
|
|
||||||
switch httpConfig {
|
switch req.HttpConfig {
|
||||||
case constant.HTTPSOnly:
|
case constant.HTTPSOnly:
|
||||||
server.RemoveListenByBind("80")
|
server.RemoveListenByBind("80")
|
||||||
server.RemoveDirective("if", []string{"($scheme"})
|
server.RemoveDirective("if", []string{"($scheme"})
|
||||||
@ -333,6 +334,12 @@ func applySSL(website model.Website, websiteSSL model.WebsiteSSL, httpConfig str
|
|||||||
if param.Name == "ssl_certificate_key" {
|
if param.Name == "ssl_certificate_key" {
|
||||||
nginxParams[i].Params = []string{path.Join("/www", "sites", website.Alias, "ssl", "privkey.pem")}
|
nginxParams[i].Params = []string{path.Join("/www", "sites", website.Alias, "ssl", "privkey.pem")}
|
||||||
}
|
}
|
||||||
|
if param.Name == "ssl_protocols" {
|
||||||
|
nginxParams[i].Params = req.SSLProtocol
|
||||||
|
}
|
||||||
|
if param.Name == "ssl_ciphers" {
|
||||||
|
nginxParams[i].Params = []string{req.Algorithm}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err := updateNginxConfig(constant.NginxScopeServer, nginxParams, &website); err != nil {
|
if err := updateNginxConfig(constant.NginxScopeServer, nginxParams, &website); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -205,12 +205,16 @@ export namespace Website {
|
|||||||
certificate?: string;
|
certificate?: string;
|
||||||
privateKey?: string;
|
privateKey?: string;
|
||||||
httpConfig: string;
|
httpConfig: string;
|
||||||
|
SSLProtocol: string[];
|
||||||
|
algorithm: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface HTTPSConfig {
|
export interface HTTPSConfig {
|
||||||
enable: boolean;
|
enable: boolean;
|
||||||
SSL: SSL;
|
SSL: SSL;
|
||||||
httpConfig: string;
|
httpConfig: string;
|
||||||
|
SSLProtocol: string[];
|
||||||
|
algorithm: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CheckReq {
|
export interface CheckReq {
|
||||||
|
@ -864,7 +864,7 @@ export default {
|
|||||||
renewHelper: '确定续签证书?',
|
renewHelper: '确定续签证书?',
|
||||||
renewSuccess: '续签证书',
|
renewSuccess: '续签证书',
|
||||||
config: '配置',
|
config: '配置',
|
||||||
enableHTTPS: '启用HTTPS',
|
enableHTTPS: '启用 HTTPS',
|
||||||
aliasHelper: '代号是网站目录的文件夹名称',
|
aliasHelper: '代号是网站目录的文件夹名称',
|
||||||
lastBackupAt: '上次备份时间',
|
lastBackupAt: '上次备份时间',
|
||||||
null: '无',
|
null: '无',
|
||||||
@ -927,13 +927,19 @@ export default {
|
|||||||
selectSSL: '选择证书',
|
selectSSL: '选择证书',
|
||||||
privateKey: '密钥(KEY)',
|
privateKey: '密钥(KEY)',
|
||||||
certificate: '证书(PEM格式)',
|
certificate: '证书(PEM格式)',
|
||||||
HTTPConfig: 'HTTP选项',
|
HTTPConfig: 'HTTP 选项',
|
||||||
HTTPSOnly: '禁止HTTTP',
|
HTTPSOnly: '禁止 HTTTP',
|
||||||
HTTPToHTTPS: '访问HTTP自动跳转到HTTPS',
|
HTTPToHTTPS: '访问HTTP自动跳转到HTTPS',
|
||||||
HTTPAlso: 'HTTP可直接访问',
|
HTTPAlso: 'HTTP可直接访问',
|
||||||
sslConfig: 'SSL 选项',
|
sslConfig: 'SSL 选项',
|
||||||
disbaleHTTTPS: '禁用 HTTPS',
|
disbaleHTTTPS: '禁用 HTTPS',
|
||||||
disbaleHTTTPSHelper: '禁用 HTTPS会删除证书相关配置,是否继续',
|
disbaleHTTTPSHelper: '禁用 HTTPS会删除证书相关配置,是否继续',
|
||||||
|
SSLHelper: '注意:请勿将SSL证书用于非法网站 \n 如开启后无法使用HTTPS访问,请检查安全组是否正确放行443端口',
|
||||||
|
SSLConfig: '证书设置',
|
||||||
|
SSLProConfig: 'SSL 协议设置',
|
||||||
|
supportProtocol: '支持的协议版本',
|
||||||
|
encryptionAlgorithm: '加密算法',
|
||||||
|
notSecurity: ' 不安全',
|
||||||
},
|
},
|
||||||
nginx: {
|
nginx: {
|
||||||
serverNamesHashBucketSizeHelper: '服务器名字的hash表大小',
|
serverNamesHashBucketSizeHelper: '服务器名字的hash表大小',
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
<el-switch v-model="form.enable" @change="changeEnable"></el-switch>
|
<el-switch v-model="form.enable" @change="changeEnable"></el-switch>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<div v-if="form.enable">
|
<div v-if="form.enable">
|
||||||
|
<el-divider content-position="left">{{ $t('website.SSLConfig') }}</el-divider>
|
||||||
<el-form-item :label="$t('website.HTTPConfig')" prop="httpConfig">
|
<el-form-item :label="$t('website.HTTPConfig')" prop="httpConfig">
|
||||||
<el-select v-model="form.httpConfig" style="width: 240px">
|
<el-select v-model="form.httpConfig" style="width: 240px">
|
||||||
<el-option :label="$t('website.HTTPToHTTPS')" :value="'HTTPToHTTPS'"></el-option>
|
<el-option :label="$t('website.HTTPToHTTPS')" :value="'HTTPToHTTPS'"></el-option>
|
||||||
@ -67,12 +68,40 @@
|
|||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-divider content-position="left">{{ $t('website.SSLProConfig') }}</el-divider>
|
||||||
|
<el-form-item :label="$t('website.supportProtocol')" prop="SSLProtocol">
|
||||||
|
<el-checkbox-group v-model="form.SSLProtocol">
|
||||||
|
<el-checkbox :label="'TLSv1.2'">{{ 'TLS 1.2' }}</el-checkbox>
|
||||||
|
<el-checkbox :label="'TLSv1.1'">{{ 'TLS 1.1' }}</el-checkbox>
|
||||||
|
<el-checkbox :label="'TLSv1'">{{ 'TLS 1.0' }}</el-checkbox>
|
||||||
|
<el-checkbox :label="'SSLv3'">
|
||||||
|
{{ 'SSL V3' + $t('website.notSecurity') }}
|
||||||
|
</el-checkbox>
|
||||||
|
<el-checkbox :label="'SSLv2'">
|
||||||
|
{{ 'SSL V2' + $t('website.notSecurity') }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="algorithm" :label="$t('website.encryptionAlgorithm')">
|
||||||
|
<el-input
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{ minRows: 2, maxRows: 6 }"
|
||||||
|
v-model.trim="form.algorithm"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="submit(httpsForm)" :loading="loading">
|
<el-button type="primary" @click="submit(httpsForm)" :loading="loading">
|
||||||
{{ $t('commons.button.save') }}
|
{{ $t('commons.button.save') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<el-alert :closable="false">
|
||||||
|
<template #default>
|
||||||
|
<span style="white-space: pre-line">{{ $t('website.SSLHelper') }}</span>
|
||||||
|
</template>
|
||||||
|
</el-alert>
|
||||||
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@ -104,6 +133,9 @@ let form = reactive({
|
|||||||
privateKey: '',
|
privateKey: '',
|
||||||
certificate: '',
|
certificate: '',
|
||||||
httpConfig: 'HTTPToHTTPS',
|
httpConfig: 'HTTPToHTTPS',
|
||||||
|
algorithm:
|
||||||
|
'EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5',
|
||||||
|
SSLProtocol: ['TLSv1.2', 'TLSv1.1', 'TLSv1'],
|
||||||
});
|
});
|
||||||
let loading = ref(false);
|
let loading = ref(false);
|
||||||
const ssls = ref();
|
const ssls = ref();
|
||||||
@ -114,6 +146,8 @@ let rules = ref({
|
|||||||
certificate: [Rules.requiredInput],
|
certificate: [Rules.requiredInput],
|
||||||
websiteSSLId: [Rules.requiredSelect],
|
websiteSSLId: [Rules.requiredSelect],
|
||||||
httpConfig: [Rules.requiredSelect],
|
httpConfig: [Rules.requiredSelect],
|
||||||
|
SSLProtocol: [Rules.requiredSelect],
|
||||||
|
algorithm: [Rules.requiredInput],
|
||||||
});
|
});
|
||||||
const resData = ref();
|
const resData = ref();
|
||||||
|
|
||||||
@ -146,6 +180,12 @@ const get = () => {
|
|||||||
if (res.data.httpConfig != '') {
|
if (res.data.httpConfig != '') {
|
||||||
form.httpConfig = res.data.httpConfig;
|
form.httpConfig = res.data.httpConfig;
|
||||||
}
|
}
|
||||||
|
if (res.data.SSLProtocol.length > 0) {
|
||||||
|
form.SSLProtocol = res.data.SSLProtocol;
|
||||||
|
}
|
||||||
|
if (res.data.algorithm != '') {
|
||||||
|
form.algorithm = res.data.algorithm;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (res.data?.SSL && res.data?.SSL.id > 0) {
|
if (res.data?.SSL && res.data?.SSL.id > 0) {
|
||||||
form.websiteSSLId = res.data.SSL.id;
|
form.websiteSSLId = res.data.SSL.id;
|
||||||
@ -165,6 +205,7 @@ const submit = async (formEl: FormInstance | undefined) => {
|
|||||||
UpdateHTTPSConfig(form)
|
UpdateHTTPSConfig(form)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
ElMessage.success(i18n.global.t('commons.msg.updateSuccess'));
|
ElMessage.success(i18n.global.t('commons.msg.updateSuccess'));
|
||||||
|
get();
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
@ -203,3 +244,12 @@ onMounted(() => {
|
|||||||
get();
|
get();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.el-collapse,
|
||||||
|
.el-collapse-item__wrap {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.el-collapse-item__header {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user