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",
|
||||
"required": true,
|
||||
"default": 9001,
|
||||
"envKey": "API_ROOT"
|
||||
"envKey": "PORT_API"
|
||||
}
|
||||
]
|
||||
}
|
@ -5,9 +5,9 @@ services:
|
||||
container_name: 1panel_minio
|
||||
ports:
|
||||
- ${PANEL_APP_PORT_HTTP}:9000
|
||||
- ${API_ROOT}:9001
|
||||
- ${PORT_API}:9001
|
||||
restart: always
|
||||
command: server /data --console-address ":9001"
|
||||
command: server /data --console-address :9000 --address :9001
|
||||
environment:
|
||||
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
|
||||
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
|
||||
|
@ -96,13 +96,15 @@ type WebsiteDomainDelete struct {
|
||||
}
|
||||
|
||||
type WebsiteHTTPSOp struct {
|
||||
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||
Enable bool `json:"enable" validate:"required"`
|
||||
WebsiteSSLID uint `json:"websiteSSLId"`
|
||||
Type string `json:"type" validate:"oneof=existed auto manual"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
Certificate string `json:"certificate"`
|
||||
HttpConfig string `json:"HttpConfig" validate:"oneof=HTTPSOnly HTTPAlso HTTPToHTTPS"`
|
||||
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||
Enable bool `json:"enable" validate:"required"`
|
||||
WebsiteSSLID uint `json:"websiteSSLId"`
|
||||
Type string `json:"type" validate:"oneof=existed auto manual"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
Certificate string `json:"certificate"`
|
||||
HttpConfig string `json:"HttpConfig" validate:"oneof=HTTPSOnly HTTPAlso HTTPToHTTPS"`
|
||||
SSLProtocol []string `json:"SSLProtocol"`
|
||||
Algorithm string `json:"algorithm"`
|
||||
}
|
||||
|
||||
type WebsiteNginxUpdate struct {
|
||||
|
@ -30,7 +30,9 @@ type WebsiteWafConfig struct {
|
||||
}
|
||||
|
||||
type WebsiteHTTPS struct {
|
||||
Enable bool `json:"enable"`
|
||||
HttpConfig string `json:"httpConfig"`
|
||||
SSL model.WebsiteSSL `json:"SSL"`
|
||||
Enable bool `json:"enable"`
|
||||
HttpConfig string `json:"httpConfig"`
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
@ -490,7 +502,8 @@ func (w WebsiteService) OpWebsiteHTTPS(ctx context.Context, req request.WebsiteH
|
||||
websiteSSL model.WebsiteSSL
|
||||
)
|
||||
res.Enable = req.Enable
|
||||
|
||||
res.SSLProtocol = req.SSLProtocol
|
||||
res.Algorithm = req.Algorithm
|
||||
if !req.Enable {
|
||||
website.Protocol = constant.ProtocolHTTP
|
||||
website.WebsiteSSLID = 0
|
||||
@ -544,7 +557,7 @@ func (w WebsiteService) OpWebsiteHTTPS(ctx context.Context, req request.WebsiteH
|
||||
res.SSL = websiteSSL
|
||||
}
|
||||
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
|
||||
}
|
||||
website.HttpConfig = req.HttpConfig
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
@ -298,7 +299,7 @@ func createPemFile(website model.Website, websiteSSL model.WebsiteSSL) error {
|
||||
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)
|
||||
if err != nil {
|
||||
return nil
|
||||
@ -307,7 +308,7 @@ func applySSL(website model.Website, websiteSSL model.WebsiteSSL, httpConfig str
|
||||
server := config.FindServers()[0]
|
||||
server.UpdateListen("443", false, "ssl")
|
||||
|
||||
switch httpConfig {
|
||||
switch req.HttpConfig {
|
||||
case constant.HTTPSOnly:
|
||||
server.RemoveListenByBind("80")
|
||||
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" {
|
||||
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 {
|
||||
return err
|
||||
|
@ -205,12 +205,16 @@ export namespace Website {
|
||||
certificate?: string;
|
||||
privateKey?: string;
|
||||
httpConfig: string;
|
||||
SSLProtocol: string[];
|
||||
algorithm: string;
|
||||
}
|
||||
|
||||
export interface HTTPSConfig {
|
||||
enable: boolean;
|
||||
SSL: SSL;
|
||||
httpConfig: string;
|
||||
SSLProtocol: string[];
|
||||
algorithm: string;
|
||||
}
|
||||
|
||||
export interface CheckReq {
|
||||
|
@ -864,7 +864,7 @@ export default {
|
||||
renewHelper: '确定续签证书?',
|
||||
renewSuccess: '续签证书',
|
||||
config: '配置',
|
||||
enableHTTPS: '启用HTTPS',
|
||||
enableHTTPS: '启用 HTTPS',
|
||||
aliasHelper: '代号是网站目录的文件夹名称',
|
||||
lastBackupAt: '上次备份时间',
|
||||
null: '无',
|
||||
@ -927,13 +927,19 @@ export default {
|
||||
selectSSL: '选择证书',
|
||||
privateKey: '密钥(KEY)',
|
||||
certificate: '证书(PEM格式)',
|
||||
HTTPConfig: 'HTTP选项',
|
||||
HTTPSOnly: '禁止HTTTP',
|
||||
HTTPConfig: 'HTTP 选项',
|
||||
HTTPSOnly: '禁止 HTTTP',
|
||||
HTTPToHTTPS: '访问HTTP自动跳转到HTTPS',
|
||||
HTTPAlso: 'HTTP可直接访问',
|
||||
sslConfig: 'SSL 选项',
|
||||
disbaleHTTTPS: '禁用 HTTPS',
|
||||
disbaleHTTTPSHelper: '禁用 HTTPS会删除证书相关配置,是否继续',
|
||||
SSLHelper: '注意:请勿将SSL证书用于非法网站 \n 如开启后无法使用HTTPS访问,请检查安全组是否正确放行443端口',
|
||||
SSLConfig: '证书设置',
|
||||
SSLProConfig: 'SSL 协议设置',
|
||||
supportProtocol: '支持的协议版本',
|
||||
encryptionAlgorithm: '加密算法',
|
||||
notSecurity: ' 不安全',
|
||||
},
|
||||
nginx: {
|
||||
serverNamesHashBucketSizeHelper: '服务器名字的hash表大小',
|
||||
|
@ -13,6 +13,7 @@
|
||||
<el-switch v-model="form.enable" @change="changeEnable"></el-switch>
|
||||
</el-form-item>
|
||||
<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-select v-model="form.httpConfig" style="width: 240px">
|
||||
<el-option :label="$t('website.HTTPToHTTPS')" :value="'HTTPToHTTPS'"></el-option>
|
||||
@ -67,12 +68,40 @@
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</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-button type="primary" @click="submit(httpsForm)" :loading="loading">
|
||||
{{ $t('commons.button.save') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</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-col>
|
||||
</el-row>
|
||||
@ -104,6 +133,9 @@ let form = reactive({
|
||||
privateKey: '',
|
||||
certificate: '',
|
||||
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);
|
||||
const ssls = ref();
|
||||
@ -114,6 +146,8 @@ let rules = ref({
|
||||
certificate: [Rules.requiredInput],
|
||||
websiteSSLId: [Rules.requiredSelect],
|
||||
httpConfig: [Rules.requiredSelect],
|
||||
SSLProtocol: [Rules.requiredSelect],
|
||||
algorithm: [Rules.requiredInput],
|
||||
});
|
||||
const resData = ref();
|
||||
|
||||
@ -146,6 +180,12 @@ const get = () => {
|
||||
if (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) {
|
||||
form.websiteSSLId = res.data.SSL.id;
|
||||
@ -165,6 +205,7 @@ const submit = async (formEl: FormInstance | undefined) => {
|
||||
UpdateHTTPSConfig(form)
|
||||
.then(() => {
|
||||
ElMessage.success(i18n.global.t('commons.msg.updateSuccess'));
|
||||
get();
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
@ -203,3 +244,12 @@ onMounted(() => {
|
||||
get();
|
||||
});
|
||||
</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