mirror of https://github.com/allinssl/allinssl
parent
f499afc060
commit
58e4c0ff11
|
@ -98,30 +98,61 @@ func DownloadCert(c *gin.Context) {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
zipWriter := zip.NewWriter(buf)
|
zipWriter := zip.NewWriter(buf)
|
||||||
|
|
||||||
for filename, content := range certData {
|
// 写入PEM文件
|
||||||
if filename == "cert" || filename == "key" {
|
// cert.pem
|
||||||
writer, err := zipWriter.Create(filename + ".pem")
|
certStr := certData["cert"]
|
||||||
|
certWriter, err := zipWriter.Create("Nginx/cert.pem")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
public.FailMsg(c, err.Error())
|
public.FailMsg(c, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err = writer.Write([]byte(content))
|
if _, err := certWriter.Write([]byte(certStr)); err != nil {
|
||||||
|
public.FailMsg(c, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// key.pem
|
||||||
|
keyStr := certData["key"]
|
||||||
|
keyWriter, err := zipWriter.Create("Nginx/key.pem")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
public.FailMsg(c, err.Error())
|
public.FailMsg(c, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if _, err := keyWriter.Write([]byte(keyStr)); err != nil {
|
||||||
|
public.FailMsg(c, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// cert.pfx
|
||||||
|
pfxPassword := "allinssl"
|
||||||
|
pfxData, err := public.PEMToPFX(certStr, keyStr, pfxPassword)
|
||||||
|
if err == nil && len(pfxData) > 0 {
|
||||||
|
pfxWriter, err := zipWriter.Create("IIS/cert.pfx")
|
||||||
|
if err != nil {
|
||||||
|
public.FailMsg(c, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, err := pfxWriter.Write(pfxData); err != nil {
|
||||||
|
public.FailMsg(c, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
txtWriter, err := zipWriter.Create("IIS/passwd.txt")
|
||||||
|
if err != nil {
|
||||||
|
public.FailMsg(c, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, err := txtWriter.Write([]byte(pfxPassword)); err != nil {
|
||||||
|
public.FailMsg(c, err.Error())
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭 zipWriter
|
// 关闭 zipWriter
|
||||||
if err := zipWriter.Close(); err != nil {
|
if err := zipWriter.Close(); err != nil {
|
||||||
public.FailMsg(c, err.Error())
|
public.FailMsg(c, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 设置响应头
|
// 设置响应头
|
||||||
|
|
||||||
zipName := strings.ReplaceAll(certData["domains"], ".", "_")
|
zipName := strings.ReplaceAll(certData["domains"], ".", "_")
|
||||||
zipName = strings.ReplaceAll(zipName, ",", "-")
|
zipName = strings.ReplaceAll(zipName, ",", "-")
|
||||||
|
|
||||||
c.Header("Content-Type", "application/zip")
|
c.Header("Content-Type", "application/zip")
|
||||||
c.Header("Content-Disposition", "attachment; filename="+zipName+".zip")
|
c.Header("Content-Disposition", "attachment; filename="+zipName+".zip")
|
||||||
c.Data(200, "application/zip", buf.Bytes())
|
c.Data(200, "application/zip", buf.Bytes())
|
||||||
|
|
|
@ -53,7 +53,7 @@ func Deploy(cfg map[string]any, logger *public.Logger) error {
|
||||||
return Deploy1panelSite(cfg)
|
return Deploy1panelSite(cfg)
|
||||||
case "ssh":
|
case "ssh":
|
||||||
logger.Debug("使用ssh部署到指定路径...")
|
logger.Debug("使用ssh部署到指定路径...")
|
||||||
return DeploySSH(cfg)
|
return DeploySSH(cfg, logger)
|
||||||
case "aliyun-cdn":
|
case "aliyun-cdn":
|
||||||
logger.Debug("部署到阿里云CDN...")
|
logger.Debug("部署到阿里云CDN...")
|
||||||
return DeployAliCdn(cfg)
|
return DeployAliCdn(cfg)
|
||||||
|
|
|
@ -30,25 +30,34 @@ func buildAuthMethods(password, privateKey string) ([]ssh.AuthMethod, error) {
|
||||||
var methods []ssh.AuthMethod
|
var methods []ssh.AuthMethod
|
||||||
|
|
||||||
if privateKey != "" {
|
if privateKey != "" {
|
||||||
signer, err := ssh.ParsePrivateKey([]byte(privateKey))
|
var signer ssh.Signer
|
||||||
|
var err error
|
||||||
|
if password != "" {
|
||||||
|
signer, err = ssh.ParsePrivateKeyWithPassphrase([]byte(privateKey), []byte(password))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to parse private key: %v", err)
|
return nil, fmt.Errorf("无法解析带密码的私钥: %v", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
signer, err = ssh.ParsePrivateKey([]byte(privateKey))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("无法解析私钥: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
methods = append(methods, ssh.PublicKeys(signer))
|
methods = append(methods, ssh.PublicKeys(signer))
|
||||||
}
|
}
|
||||||
|
|
||||||
if password != "" {
|
if password != "" && privateKey == "" {
|
||||||
methods = append(methods, ssh.Password(password))
|
methods = append(methods, ssh.Password(password))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(methods) == 0 {
|
if len(methods) == 0 {
|
||||||
return nil, fmt.Errorf("no authentication methods provided")
|
return nil, fmt.Errorf("未提供有效的认证方式")
|
||||||
}
|
}
|
||||||
|
|
||||||
return methods, nil
|
return methods, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeMultipleFilesViaSSH(config SSHConfig, files []RemoteFile, preCmd, postCmd string) error {
|
func writeMultipleFilesViaSSH(config SSHConfig, files []RemoteFile, preCmd, postCmd string, logger *public.Logger) error {
|
||||||
var port string
|
var port string
|
||||||
switch v := config.Port.(type) {
|
switch v := config.Port.(type) {
|
||||||
case float64:
|
case float64:
|
||||||
|
@ -91,8 +100,9 @@ func writeMultipleFilesViaSSH(config SSHConfig, files []RemoteFile, preCmd, post
|
||||||
return fmt.Errorf("会话创建失败: %v", err)
|
return fmt.Errorf("会话创建失败: %v", err)
|
||||||
}
|
}
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
|
var script, stdoutBuf, stderrBuf bytes.Buffer
|
||||||
var script bytes.Buffer
|
session.Stdout = &stdoutBuf
|
||||||
|
session.Stderr = &stderrBuf
|
||||||
|
|
||||||
if preCmd != "" {
|
if preCmd != "" {
|
||||||
script.WriteString(preCmd + " && ")
|
script.WriteString(preCmd + " && ")
|
||||||
|
@ -115,14 +125,14 @@ func writeMultipleFilesViaSSH(config SSHConfig, files []RemoteFile, preCmd, post
|
||||||
|
|
||||||
cmd := script.String()
|
cmd := script.String()
|
||||||
|
|
||||||
if err := session.Run(cmd); err != nil {
|
err = session.Run(cmd)
|
||||||
return fmt.Errorf("运行出错: %v", err)
|
logger.Debug("[STDOUT]", stdoutBuf.String())
|
||||||
}
|
logger.Debug("[STDERR]", stderrBuf.String())
|
||||||
|
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeploySSH(cfg map[string]any) error {
|
func DeploySSH(cfg map[string]any, logger *public.Logger) error {
|
||||||
cert, ok := cfg["certificate"].(map[string]any)
|
cert, ok := cfg["certificate"].(map[string]any)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("证书不存在")
|
return fmt.Errorf("证书不存在")
|
||||||
|
@ -180,7 +190,7 @@ func DeploySSH(cfg map[string]any) error {
|
||||||
{Path: certPath, Content: certPem},
|
{Path: certPath, Content: certPem},
|
||||||
{Path: keyPath, Content: keyPem},
|
{Path: keyPath, Content: keyPem},
|
||||||
}
|
}
|
||||||
err = writeMultipleFilesViaSSH(providerConfig, files, beforeCmd, afterCmd)
|
err = writeMultipleFilesViaSSH(providerConfig, files, beforeCmd, afterCmd, logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("SSH 部署失败: %v", err)
|
return fmt.Errorf("SSH 部署失败: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ func NotifyWorkWx(params map[string]any) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
configStr := providerData["config"].(string)
|
configStr := providerData["config"].(string)
|
||||||
fmt.Println(configStr)
|
//fmt.Println(configStr)
|
||||||
var config map[string]string
|
var config map[string]string
|
||||||
err = json.Unmarshal([]byte(configStr), &config)
|
err = json.Unmarshal([]byte(configStr), &config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -12,6 +12,8 @@ import (
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"software.sslmate.com/src/go-pkcs12"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -138,3 +140,47 @@ func GetSHA256(certStr string) (string, error) {
|
||||||
sha256Hash := sha256.Sum256(cert.Raw)
|
sha256Hash := sha256.Sum256(cert.Raw)
|
||||||
return hex.EncodeToString(sha256Hash[:]), nil
|
return hex.EncodeToString(sha256Hash[:]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PEMToPFX 将PEM格式的证书和私钥转换为PFX格式
|
||||||
|
func PEMToPFX(certPEM, keyPEM, pfxPassword string) ([]byte, error) {
|
||||||
|
// 使用默认密码如果未提供
|
||||||
|
if pfxPassword == "" {
|
||||||
|
pfxPassword = "allinssl"
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析证书PEM
|
||||||
|
certBlock, _ := pem.Decode([]byte(certPEM))
|
||||||
|
if certBlock == nil || certBlock.Type != "CERTIFICATE" {
|
||||||
|
return nil, fmt.Errorf("无效的证书PEM格式")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析私钥PEM
|
||||||
|
keyBlock, _ := pem.Decode([]byte(keyPEM))
|
||||||
|
if keyBlock == nil || (!strings.Contains(keyBlock.Type, "PRIVATE KEY")) {
|
||||||
|
return nil, fmt.Errorf("无效的私钥PEM格式")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析X.509证书
|
||||||
|
cert, err := x509.ParseCertificate(certBlock.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("解析证书失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试解析私钥(PKCS8或PKCS1格式)
|
||||||
|
var privKey interface{}
|
||||||
|
privKey, err = x509.ParsePKCS8PrivateKey(keyBlock.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
privKey, err = x509.ParsePKCS1PrivateKey(keyBlock.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("解析私钥失败: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编码为PFX格式
|
||||||
|
pfxData, err := pkcs12.Encode(rand.Reader, privKey, cert, nil, pfxPassword)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("编码PFX失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return pfxData, nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue