feat: 网站增加手动导入证书

pull/47/head
zhengkunwang223 2022-11-24 17:50:47 +08:00 committed by zhengkunwang223
parent 74b28cbf23
commit 3ccac92df6
7 changed files with 114 additions and 22 deletions

View File

@ -84,8 +84,10 @@ const (
)
type WebsiteHTTPSOp struct {
WebsiteID uint `json:"websiteId"`
Enable bool `json:"enable"`
WebsiteID uint `json:"websiteId" validate:"required"`
Enable bool `json:"enable" validate:"required"`
WebsiteSSLID uint `json:"websiteSSLId"`
Type SSlType `json:"type"`
PrivateKey string `json:"privateKey"`
Certificate string `json:"certificate"`
}

View File

@ -12,6 +12,7 @@ const (
DNSAccount = "dnsAccount"
DnsManual = "dnsManual"
Http = "http"
Manual = "manual"
)
type WebsiteSSLSearch struct {

View File

@ -2,6 +2,8 @@ package service
import (
"context"
"crypto/x509"
"encoding/pem"
"fmt"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/app/model"
@ -304,29 +306,80 @@ func (w WebsiteService) OpWebsiteHTTPS(req dto.WebsiteHTTPSOp) (dto.WebsiteHTTPS
return dto.WebsiteHTTPS{}, err
}
var res dto.WebsiteHTTPS
var (
res dto.WebsiteHTTPS
websiteSSL model.WebSiteSSL
)
res.Enable = req.Enable
ssl, err := websiteSSLRepo.GetFirst(commonRepo.WithByID(req.WebsiteSSLID))
if err != nil {
return dto.WebsiteHTTPS{}, err
}
if req.Type == dto.SSLExisted {
website.WebSiteSSLID = ssl.ID
websiteSSL, err = websiteSSLRepo.GetFirst(commonRepo.WithByID(req.WebsiteSSLID))
if err != nil {
return dto.WebsiteHTTPS{}, err
}
website.WebSiteSSLID = websiteSSL.ID
if err := websiteRepo.Save(context.TODO(), &website); err != nil {
return dto.WebsiteHTTPS{}, err
}
res.SSL = ssl
res.SSL = websiteSSL
}
if req.Type == dto.Manual {
certBlock, _ := pem.Decode([]byte(req.Certificate))
cert, err := x509.ParseCertificate(certBlock.Bytes)
if err != nil {
return dto.WebsiteHTTPS{}, err
}
websiteSSL.ExpireDate = cert.NotAfter
websiteSSL.StartDate = cert.NotBefore
websiteSSL.Type = cert.Issuer.CommonName
websiteSSL.Organization = cert.Issuer.Organization[0]
websiteSSL.PrimaryDomain = cert.Subject.CommonName
if len(cert.Subject.Names) > 0 {
var domains []string
for _, name := range cert.Subject.Names {
if v, ok := name.Value.(string); ok {
if v != cert.Subject.CommonName {
domains = append(domains, v)
}
}
}
if len(domains) > 0 {
websiteSSL.Domains = strings.Join(domains, "")
}
}
websiteSSL.Provider = dto.Manual
websiteSSL.PrivateKey = req.PrivateKey
websiteSSL.Pem = req.Certificate
res.SSL = websiteSSL
}
if req.Enable {
website.Protocol = constant.ProtocolHTTPS
if err := applySSL(website, ssl); err != nil {
if err := applySSL(website, websiteSSL); err != nil {
return dto.WebsiteHTTPS{}, err
}
} else {
website.Protocol = constant.ProtocolHTTP
website.WebSiteSSLID = 0
if err := deleteNginxConfig(website, getKeysFromStaticFile(dto.SSL)); err != nil {
return dto.WebsiteHTTPS{}, err
}
}
tx, ctx := getTxAndContext()
if websiteSSL.ID == 0 {
if err := websiteSSLRepo.Create(ctx, &websiteSSL); err != nil {
return dto.WebsiteHTTPS{}, err
}
website.WebSiteSSLID = websiteSSL.ID
}
if err := websiteRepo.Save(ctx, &website); err != nil {
return dto.WebsiteHTTPS{}, err
}
tx.Commit()
return res, nil
}

View File

@ -59,25 +59,20 @@ func (w WebSiteSSLService) Create(create dto.WebsiteSSLCreate) (dto.WebsiteSSLCr
switch create.Provider {
case dto.DNSAccount:
dnsAccount, err := websiteDnsRepo.GetFirst(commonRepo.WithByID(create.DnsAccountID))
if err != nil {
return res, err
}
if err := client.UseDns(ssl.DnsType(dnsAccount.Type), dnsAccount.Authorization); err != nil {
return res, err
}
case dto.Http:
appInstall, err := getAppInstallByKey("nginx")
if err != nil {
return dto.WebsiteSSLCreate{}, err
}
if err := client.UseHTTP(path.Join(constant.AppInstallDir, "nginx", appInstall.Name, "root")); err != nil {
return res, err
}
case dto.DnsManual:
}
@ -110,10 +105,6 @@ func (w WebSiteSSLService) Create(create dto.WebsiteSSLCreate) (dto.WebsiteSSLCr
websiteSSL.Type = cert.Issuer.CommonName
websiteSSL.Organization = cert.Issuer.Organization[0]
//if err := createPemFile(websiteSSL); err != nil {
// return dto.WebsiteSSLCreate{}, err
//}
if err := websiteSSLRepo.Create(context.TODO(), &websiteSSL); err != nil {
return res, err
}
@ -146,6 +137,13 @@ func (w WebSiteSSLService) Renew(sslId uint) error {
return err
}
case dto.Http:
appInstall, err := getAppInstallByKey("nginx")
if err != nil {
return err
}
if err := client.UseHTTP(path.Join(constant.AppInstallDir, "nginx", appInstall.Name, "root")); err != nil {
return err
}
case dto.DnsManual:
}

View File

@ -326,6 +326,19 @@ func getNginxParamsFromStaticFile(scope dto.NginxKey) []dto.NginxParam {
return nginxParams
}
func getKeysFromStaticFile(scope dto.NginxKey) []string {
var res []string
newConfig := &components.Config{}
switch scope {
case dto.SSL:
newConfig = parser.NewStringParser(string(nginx_conf.SSL)).Parse()
}
for _, dir := range newConfig.GetDirectives() {
res = append(res, dir.GetName())
}
return res
}
func deleteNginxConfig(website model.WebSite, keys []string) error {
nginxConfig, err := getNginxConfig(website.Alias)
if err != nil {
@ -385,6 +398,17 @@ func createPemFile(website model.WebSite, websiteSSL model.WebSiteSSL) error {
func applySSL(website model.WebSite, websiteSSL model.WebSiteSSL) error {
nginxConfig, err := getNginxConfig(website.Alias)
if err != nil {
return nil
}
config := nginxConfig.Config
server := config.FindServers()[0]
server.UpdateListen("443", false)
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
return err
}
if err := createPemFile(website, websiteSSL); err != nil {
return err
}

View File

@ -172,8 +172,10 @@ export namespace WebSite {
export interface HTTPSReq {
websiteId: number;
enable: boolean;
websiteSSLId: number;
websiteSSLId?: number;
type: string;
certificate?: string;
privateKey?: string;
}
export interface HTTPSConfig {

View File

@ -1,6 +1,6 @@
<template>
<el-row :gutter="20">
<el-col :span="20" :offset="2">
<el-col :span="10" :offset="2">
<el-form
ref="httpsForm"
label-position="left"
@ -18,7 +18,7 @@
<el-select v-model="form.type" @change="changeType()">
<el-option :label="'选择已有证书'" :value="'existed'"></el-option>
<el-option :label="'手动导入证书'" :value="'manual'"></el-option>
<el-option :label="'自动生成证书'" :value="'auto'"></el-option>
<!-- <el-option :label="'自动生成证书'" :value="'auto'"></el-option> -->
</el-select>
</el-form-item>
<el-form-item :label="' '" prop="websiteSSLId" v-if="form.type === 'existed'">
@ -35,6 +35,14 @@
></el-option>
</el-select>
</el-form-item>
<div v-if="form.type === 'manual'">
<el-form-item :label="'密钥代码(pem格式)'" prop="privateKey">
<el-input v-model="form.privateKey" :rows="6" type="textarea" />
</el-form-item>
<el-form-item :label="'证书代码(pem格式)'" prop="certificate">
<el-input v-model="form.certificate" :rows="6" type="textarea" />
</el-form-item>
</div>
<el-form-item :label="' '" v-if="websiteSSL && websiteSSL.id > 0">
<el-descriptions :column="3" border direction="vertical">
<el-descriptions-item label="主域名">{{ websiteSSL.primaryDomain }}</el-descriptions-item>
@ -77,12 +85,16 @@ let form = reactive({
websiteId: id.value,
websiteSSLId: undefined,
type: 'existed',
privateKey: '',
certificate: '',
});
let loading = ref(false);
const ssls = ref();
let websiteSSL = ref();
let rules = ref({
type: [Rules.requiredSelect],
privateKey: [Rules.requiredInput],
certificate: [Rules.requiredInput],
});
const listSSL = () => {