mirror of https://github.com/bjdgyc/anylink.git
feat:根据SNI返回SSL证书
This commit is contained in:
parent
8798de0d6d
commit
609a893feb
|
@ -46,7 +46,7 @@ func CustomCert(w http.ResponseWriter, r *http.Request) {
|
||||||
RespError(w, RespInternalErr, fmt.Sprintf("证书不合法,请重新上传:%v", err))
|
RespError(w, RespInternalErr, fmt.Sprintf("证书不合法,请重新上传:%v", err))
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
dbdata.TLSCert = tlscert
|
dbdata.LoadCertificate(tlscert)
|
||||||
}
|
}
|
||||||
RespSucess(w, "上传成功")
|
RespSucess(w, "上传成功")
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ func StartAdmin() {
|
||||||
base.Error(err)
|
base.Error(err)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
dbdata.TLSCert = tlscert
|
dbdata.LoadCertificate(tlscert)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置tls信息
|
// 设置tls信息
|
||||||
|
@ -112,8 +112,8 @@ func StartAdmin() {
|
||||||
NextProtos: []string{"http/1.1"},
|
NextProtos: []string{"http/1.1"},
|
||||||
MinVersion: tls.VersionTLS12,
|
MinVersion: tls.VersionTLS12,
|
||||||
CipherSuites: selectedCipherSuites,
|
CipherSuites: selectedCipherSuites,
|
||||||
GetCertificate: func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
|
GetCertificate: func(chi *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||||
return dbdata.TLSCert, nil
|
return dbdata.GetCertificateBySNI(chi.ServerName)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
srv := &http.Server{
|
srv := &http.Server{
|
||||||
|
|
|
@ -12,9 +12,11 @@ import (
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/pion/dtls/v2/pkg/crypto/selfsign"
|
||||||
"math/big"
|
"math/big"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -30,7 +32,14 @@ import (
|
||||||
"github.com/go-acme/lego/v4/registration"
|
"github.com/go-acme/lego/v4/registration"
|
||||||
)
|
)
|
||||||
|
|
||||||
var TLSCert *tls.Certificate
|
var nameToCertificate = make(map[string]*tls.Certificate)
|
||||||
|
|
||||||
|
var tempCert *tls.Certificate
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
c, _ := selfsign.GenerateSelfSignedWithDNS("localhost")
|
||||||
|
tempCert = &c
|
||||||
|
}
|
||||||
|
|
||||||
type SettingLetsEncrypt struct {
|
type SettingLetsEncrypt struct {
|
||||||
Domain string `json:"domain"`
|
Domain string `json:"domain"`
|
||||||
|
@ -200,6 +209,7 @@ func (c *LeGoClient) NewClient(l *SettingLetsEncrypt) error {
|
||||||
c.Client = client
|
c.Client = client
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *LeGoClient) GetCert(domain string) error {
|
func (c *LeGoClient) GetCert(domain string) error {
|
||||||
// 申请证书
|
// 申请证书
|
||||||
certificates, err := c.Client.Certificate.Obtain(
|
certificates, err := c.Client.Certificate.Obtain(
|
||||||
|
@ -255,7 +265,7 @@ func (c *LeGoClient) SaveCert() error {
|
||||||
if tlscert, _, err := ParseCert(); err != nil {
|
if tlscert, _, err := ParseCert(); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
TLSCert = tlscert
|
LoadCertificate(tlscert)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -278,6 +288,7 @@ func ParseCert() (*tls.Certificate, *time.Time, error) {
|
||||||
}
|
}
|
||||||
return &cert, &parseCert.NotAfter, nil
|
return &cert, &parseCert.NotAfter, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func PrivateCert() error {
|
func PrivateCert() error {
|
||||||
// 创建一个RSA密钥对
|
// 创建一个RSA密钥对
|
||||||
priv, _ := rsa.GenerateKey(rand.Reader, 2048)
|
priv, _ := rsa.GenerateKey(rand.Reader, 2048)
|
||||||
|
@ -313,10 +324,64 @@ func PrivateCert() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
TLSCert = &cert
|
LoadCertificate(&cert)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getTempCertificate() (*tls.Certificate, error) {
|
||||||
|
var err error
|
||||||
|
var cert tls.Certificate
|
||||||
|
if tempCert == nil {
|
||||||
|
cert, err = selfsign.GenerateSelfSignedWithDNS("localhost")
|
||||||
|
tempCert = &cert
|
||||||
|
}
|
||||||
|
return tempCert, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCertificateBySNI(commonName string) (*tls.Certificate, error) {
|
||||||
|
// Copy from tls.Config getCertificate()
|
||||||
|
name := strings.ToLower(commonName)
|
||||||
|
if cert, ok := nameToCertificate[name]; ok {
|
||||||
|
return cert, nil
|
||||||
|
}
|
||||||
|
if len(name) > 0 {
|
||||||
|
labels := strings.Split(name, ".")
|
||||||
|
labels[0] = "*"
|
||||||
|
wildcardName := strings.Join(labels, ".")
|
||||||
|
if cert, ok := nameToCertificate[wildcardName]; ok {
|
||||||
|
return cert, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return getTempCertificate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadCertificate(cert *tls.Certificate) {
|
||||||
|
buildNameToCertificate(cert)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy from tls.Config BuildNameToCertificate()
|
||||||
|
func buildNameToCertificate(cert *tls.Certificate) {
|
||||||
|
x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
startTime := x509Cert.NotBefore.String()
|
||||||
|
expiredTime := x509Cert.NotAfter.String()
|
||||||
|
if x509Cert.Subject.CommonName != "" && len(x509Cert.DNSNames) == 0 {
|
||||||
|
commonName := x509Cert.Subject.CommonName
|
||||||
|
fmt.Printf("┏ Load Certificate: %s\n", commonName)
|
||||||
|
fmt.Printf("┠╌╌ Start Time: %s\n", startTime)
|
||||||
|
fmt.Printf("┖╌╌ Expired Time: %s\n", expiredTime)
|
||||||
|
nameToCertificate[commonName] = cert
|
||||||
|
}
|
||||||
|
for _, san := range x509Cert.DNSNames {
|
||||||
|
fmt.Printf("┏ Load Certificate: %s\n", san)
|
||||||
|
fmt.Printf("┠╌╌ Start Time: %s\n", startTime)
|
||||||
|
fmt.Printf("┖╌╌ Expired Time: %s\n", expiredTime)
|
||||||
|
nameToCertificate[san] = cert
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// func Scrypt(passwd string) string {
|
// func Scrypt(passwd string) string {
|
||||||
// salt := []byte{0xc8, 0x28, 0xf2, 0x58, 0xa7, 0x6a, 0xad, 0x7b}
|
// salt := []byte{0xc8, 0x28, 0xf2, 0x58, 0xa7, 0x6a, 0xad, 0x7b}
|
||||||
// hashPasswd, err := scrypt.Key([]byte(passwd), salt, 1<<15, 8, 1, 32)
|
// hashPasswd, err := scrypt.Key([]byte(passwd), salt, 1<<15, 8, 1, 32)
|
||||||
|
|
|
@ -49,8 +49,8 @@ func startTls() {
|
||||||
NextProtos: []string{"http/1.1"},
|
NextProtos: []string{"http/1.1"},
|
||||||
MinVersion: tls.VersionTLS12,
|
MinVersion: tls.VersionTLS12,
|
||||||
CipherSuites: selectedCipherSuites,
|
CipherSuites: selectedCipherSuites,
|
||||||
GetCertificate: func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
|
GetCertificate: func(chi *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||||
return dbdata.TLSCert, nil
|
return dbdata.GetCertificateBySNI(chi.ServerName)
|
||||||
},
|
},
|
||||||
// InsecureSkipVerify: true,
|
// InsecureSkipVerify: true,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue