mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-24 09:18:31 +02:00
simplify setup process with WebUI
This commit is contained in:
@@ -1,201 +0,0 @@
|
||||
package certs
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"math/big"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
E "github.com/yusing/go-proxy/internal/error"
|
||||
"github.com/yusing/go-proxy/internal/logging"
|
||||
"github.com/yusing/go-proxy/internal/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
CertsDNSName = "godoxy.agent"
|
||||
|
||||
caCertPath = "certs/ca.crt"
|
||||
caKeyPath = "certs/ca.key"
|
||||
srvCertPath = "certs/agent.crt"
|
||||
srvKeyPath = "certs/agent.key"
|
||||
)
|
||||
|
||||
func loadCerts(certPath, keyPath string) (*tls.Certificate, error) {
|
||||
cert, err := tls.LoadX509KeyPair(certPath, keyPath)
|
||||
return &cert, err
|
||||
}
|
||||
|
||||
func write(b []byte, f *os.File) error {
|
||||
_, err := f.Write(b)
|
||||
return err
|
||||
}
|
||||
|
||||
func saveCerts(certDER []byte, key *rsa.PrivateKey, certPath, keyPath string) ([]byte, []byte, error) {
|
||||
certPEM, keyPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER}),
|
||||
pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)})
|
||||
|
||||
if certPath == "" || keyPath == "" {
|
||||
return certPEM, keyPEM, nil
|
||||
}
|
||||
|
||||
certFile, err := os.Create(certPath)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer certFile.Close()
|
||||
|
||||
keyFile, err := os.Create(keyPath)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer keyFile.Close()
|
||||
|
||||
return certPEM, keyPEM, errors.Join(
|
||||
write(certPEM, certFile),
|
||||
write(keyPEM, keyFile),
|
||||
)
|
||||
}
|
||||
|
||||
func checkExists(certPath, keyPath string) bool {
|
||||
certExists, err := utils.FileExists(certPath)
|
||||
if err != nil {
|
||||
E.LogFatal("cert error", err)
|
||||
}
|
||||
keyExists, err := utils.FileExists(keyPath)
|
||||
if err != nil {
|
||||
E.LogFatal("key error", err)
|
||||
}
|
||||
return certExists && keyExists
|
||||
}
|
||||
|
||||
func InitCerts() (ca *tls.Certificate, srv *tls.Certificate, isNew bool, err error) {
|
||||
if checkExists(caCertPath, caKeyPath) && checkExists(srvCertPath, srvKeyPath) {
|
||||
logging.Info().Msg("Loading existing certs...")
|
||||
ca, err = loadCerts(caCertPath, caKeyPath)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
srv, err = loadCerts(srvCertPath, srvKeyPath)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
|
||||
logging.Info().Msg("Verifying agent cert...")
|
||||
|
||||
roots := x509.NewCertPool()
|
||||
roots.AddCert(ca.Leaf)
|
||||
|
||||
srvCert, err := x509.ParseCertificate(srv.Certificate[0])
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
|
||||
// check if srv is signed by ca
|
||||
if _, err := srvCert.Verify(x509.VerifyOptions{
|
||||
Roots: roots,
|
||||
}); err == nil {
|
||||
logging.Info().Msg("OK")
|
||||
return ca, srv, false, nil
|
||||
}
|
||||
logging.Error().Msg("Agent cert and CA cert mismatch, regenerating")
|
||||
}
|
||||
|
||||
// Create the CA's certificate
|
||||
caTemplate := x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{
|
||||
Organization: []string{"GoDoxy"},
|
||||
},
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().AddDate(1000, 0, 0), // 1000 years
|
||||
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
|
||||
BasicConstraintsValid: true,
|
||||
IsCA: true,
|
||||
}
|
||||
|
||||
caKey, err := rsa.GenerateKey(rand.Reader, 4096)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
|
||||
caCertDER, err := x509.CreateCertificate(rand.Reader, &caTemplate, &caTemplate, &caKey.PublicKey, caKey)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
|
||||
certPEM, keyPEM, err := saveCerts(caCertDER, caKey, caCertPath, caKeyPath)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
|
||||
caCert, err := tls.X509KeyPair(certPEM, keyPEM)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
|
||||
ca = &caCert
|
||||
|
||||
// Generate a new private key for the server certificate
|
||||
serverKey, err := rsa.GenerateKey(rand.Reader, 4096)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
|
||||
srvTemplate := caTemplate
|
||||
srvTemplate.Issuer = srvTemplate.Subject
|
||||
srvTemplate.DNSNames = append(srvTemplate.DNSNames, CertsDNSName)
|
||||
|
||||
srvCertDER, err := x509.CreateCertificate(rand.Reader, &srvTemplate, &caTemplate, &serverKey.PublicKey, caKey)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
|
||||
certPEM, keyPEM, err = saveCerts(srvCertDER, serverKey, srvCertPath, srvKeyPath)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
|
||||
agentCert, err := tls.X509KeyPair(certPEM, keyPEM)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
|
||||
srv = &agentCert
|
||||
|
||||
return ca, srv, true, nil
|
||||
}
|
||||
|
||||
func NewClientCert(ca *tls.Certificate) ([]byte, []byte, error) {
|
||||
// Generate the SSL's private key
|
||||
sslKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Create the SSL's certificate
|
||||
sslTemplate := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(2),
|
||||
Subject: pkix.Name{
|
||||
Organization: []string{"GoDoxy"},
|
||||
CommonName: CertsDNSName,
|
||||
},
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().AddDate(1000, 0, 0), // 1000 years
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||
}
|
||||
|
||||
// Sign the certificate with the CA
|
||||
sslCertDER, err := x509.CreateCertificate(rand.Reader, sslTemplate, ca.Leaf, &sslKey.PublicKey, ca.PrivateKey)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return saveCerts(sslCertDER, sslKey, "", "")
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
func writeFile(zipWriter *zip.Writer, name string, data []byte) error {
|
||||
w, err := zipWriter.CreateHeader(&zip.FileHeader{
|
||||
Name: name,
|
||||
Method: zip.Deflate,
|
||||
Method: zip.Store,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -31,8 +31,7 @@ func readFile(f *zip.File) ([]byte, error) {
|
||||
}
|
||||
|
||||
func ZipCert(ca, crt, key []byte) ([]byte, error) {
|
||||
data := bytes.NewBuffer(nil)
|
||||
data.Grow(6144)
|
||||
data := bytes.NewBuffer(make([]byte, 0, 6144))
|
||||
zipWriter := zip.NewWriter(data)
|
||||
defer zipWriter.Close()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user