1Panel/backend/utils/ssl/ssl.go

113 lines
3.3 KiB
Go

package ssl
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"net"
"os"
"path"
"time"
"github.com/1Panel-dev/1Panel/backend/global"
)
func GenerateSSL(domain string) error {
rootPrivateKey, _ := rsa.GenerateKey(rand.Reader, 2048)
ipItem := net.ParseIP(domain)
isIP := false
if len(ipItem) != 0 {
isIP = true
}
rootTemplate := x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{CommonName: "1Panel Root CA"},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
BasicConstraintsValid: true,
IsCA: true,
KeyUsage: x509.KeyUsageCertSign,
}
if isIP {
rootTemplate.IPAddresses = []net.IP{ipItem}
} else {
rootTemplate.DNSNames = []string{domain}
}
rootCertBytes, _ := x509.CreateCertificate(rand.Reader, &rootTemplate, &rootTemplate, &rootPrivateKey.PublicKey, rootPrivateKey)
rootCertBlock := &pem.Block{
Type: "CERTIFICATE",
Bytes: rootCertBytes,
}
interPrivateKey, _ := rsa.GenerateKey(rand.Reader, 2048)
interTemplate := x509.Certificate{
SerialNumber: big.NewInt(2),
Subject: pkix.Name{CommonName: "1Panel Intermediate CA"},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
BasicConstraintsValid: true,
IsCA: true,
KeyUsage: x509.KeyUsageCertSign,
}
if isIP {
interTemplate.IPAddresses = []net.IP{ipItem}
} else {
interTemplate.DNSNames = []string{domain}
}
interCertBytes, _ := x509.CreateCertificate(rand.Reader, &interTemplate, &rootTemplate, &interPrivateKey.PublicKey, rootPrivateKey)
interCertBlock := &pem.Block{
Type: "CERTIFICATE",
Bytes: interCertBytes,
}
clientPrivateKey, _ := rsa.GenerateKey(rand.Reader, 2048)
clientTemplate := x509.Certificate{
SerialNumber: big.NewInt(3),
Subject: pkix.Name{CommonName: domain},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
KeyUsage: x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
}
if isIP {
clientTemplate.IPAddresses = []net.IP{ipItem}
} else {
clientTemplate.DNSNames = []string{domain}
}
clientCertBytes, _ := x509.CreateCertificate(rand.Reader, &clientTemplate, &interTemplate, &clientPrivateKey.PublicKey, interPrivateKey)
clientCertBlock := &pem.Block{
Type: "CERTIFICATE",
Bytes: clientCertBytes,
}
pemBytes := []byte{}
pemBytes = append(pemBytes, pem.EncodeToMemory(clientCertBlock)...)
pemBytes = append(pemBytes, pem.EncodeToMemory(interCertBlock)...)
pemBytes = append(pemBytes, pem.EncodeToMemory(rootCertBlock)...)
certOut, err := os.OpenFile(path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt.tmp"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return err
}
defer certOut.Close()
if _, err := certOut.Write(pemBytes); err != nil {
return err
}
keyOut, err := os.OpenFile(path.Join(global.CONF.System.BaseDir, "1panel/secret/server.key.tmp"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return err
}
defer keyOut.Close()
if err := pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(clientPrivateKey)}); err != nil {
return err
}
return nil
}