Skip to content

Commit b5e7fe0

Browse files
committed
feat: support tls certs reload
1 parent e9ed4ba commit b5e7fe0

File tree

4 files changed

+76
-12
lines changed

4 files changed

+76
-12
lines changed

tls/certificate.go

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,21 @@ import (
1313
type Cert struct {
1414
*tls.Certificate
1515
dnsnames utils.GroupRegexp
16+
1617
certfile string
18+
keyfile string
1719
}
1820

19-
type tlsMgr struct {
21+
type TlsMgr struct {
2022
certs map[string]Cert
2123
lookup *utils.BufferedLookup
2224

2325
muCerts sync.RWMutex
2426
}
2527

26-
func NewTlsMgr() *tlsMgr {
28+
func NewTlsMgr() *TlsMgr {
2729

28-
var mgr = tlsMgr{
30+
var mgr = TlsMgr{
2931
certs: make(map[string]Cert),
3032
}
3133

@@ -44,15 +46,15 @@ func NewTlsMgr() *tlsMgr {
4446
return &mgr
4547
}
4648

47-
func (m *tlsMgr) getCertificate(dnsname string) *tls.Certificate {
49+
func (m *TlsMgr) getCertificate(dnsname string) *tls.Certificate {
4850
if cert := m.lookup.Lookup(dnsname); cert != nil {
4951
return cert.(*tls.Certificate)
5052
} else {
5153
panic(errors.New("no certificate for " + dnsname))
5254
}
5355
}
5456

55-
func (m *tlsMgr) LoadCertificate(certfile, keyfile string) error {
57+
func (m *TlsMgr) LoadCertificate(certfile, keyfile string) error {
5658
c, e := tls.LoadX509KeyPair(certfile, keyfile)
5759
if e != nil {
5860
return e
@@ -67,21 +69,22 @@ func (m *tlsMgr) LoadCertificate(certfile, keyfile string) error {
6769
Certificate: &c,
6870
dnsnames: utils.MustCompileRegexp(dns.Dnsnames2Regexps(c.Leaf.DNSNames)),
6971
certfile: certfile,
72+
keyfile: keyfile,
7073
}
7174
m.muCerts.Unlock()
7275

7376
return nil
7477
}
7578
}
7679

77-
func (m *tlsMgr) ResetCertificates() {
80+
func (m *TlsMgr) ResetCertificates() {
7881
m.muCerts.Lock()
7982
m.lookup.Refresh()
8083
m.certs = make(map[string]Cert)
8184
m.muCerts.Unlock()
8285
}
8386

84-
func (mgr *tlsMgr) GetActiveCertificates() []Cert {
87+
func (mgr *TlsMgr) GetActiveCertificates() []Cert {
8588
mgr.muCerts.RLock()
8689
defer mgr.muCerts.RUnlock()
8790
var certs []Cert
@@ -90,3 +93,25 @@ func (mgr *tlsMgr) GetActiveCertificates() []Cert {
9093
}
9194
return certs
9295
}
96+
97+
func (m *TlsMgr) Reload() error {
98+
m.muCerts.Lock()
99+
defer m.muCerts.Unlock()
100+
101+
for _, v := range m.certs {
102+
cert, err := tls.LoadX509KeyPair(v.certfile, v.keyfile)
103+
if err != nil {
104+
return err
105+
}
106+
cert.Leaf, _ = x509.ParseCertificate(cert.Certificate[0])
107+
v.Certificate = &cert
108+
109+
v.dnsnames = utils.MustCompileRegexp(dns.Dnsnames2Regexps(cert.Leaf.DNSNames))
110+
111+
m.certs[v.certfile] = v
112+
113+
}
114+
115+
m.lookup.Refresh()
116+
return nil
117+
}

tls/tcp.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
tcp "github.com/mrhaoxx/OpenNG/tcp"
77
)
88

9-
func (mgr *tlsMgr) Handle(c *tcp.Conn) tcp.SerRet {
9+
func (mgr *TlsMgr) Handle(c *tcp.Conn) tcp.SerRet {
1010
hellov, ok := c.Load(tcp.KeyTLS)
1111
hello := hellov.(*tls.ClientHelloInfo)
1212

ui/builtin.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ var _builtin_refs_assertions = map[string]Assert{
324324
},
325325
},
326326
},
327-
"builtin::tls::watch": {
327+
"builtin::tls::reload": {
328328
Type: "ptr",
329329
Required: true,
330330
},
@@ -830,6 +830,10 @@ var _builtin_refs_assertions = map[string]Assert{
830830
Type: "ptr",
831831
Required: true,
832832
},
833+
"tls": {
834+
Type: "ptr",
835+
Required: false,
836+
},
833837
},
834838
},
835839
"builtin::wireguard::server": {
@@ -1110,8 +1114,13 @@ var _builtin_refs = map[string]Inst{
11101114

11111115
return controller, nil
11121116
},
1113-
"builtin::tls::watch": func(spec *ArgNode) (any, error) {
1114-
panic("not implemented")
1117+
"builtin::tls::reload": func(spec *ArgNode) (any, error) {
1118+
tls, err := spec.Value.(*tls.TlsMgr)
1119+
if !err {
1120+
return nil, errors.New("ptr is not a tls.TlsMgr")
1121+
}
1122+
1123+
return nil, tls.Reload()
11151124
},
11161125

11171126
"builtin::tcp::listen": func(spec *ArgNode) (any, error) {
@@ -1337,7 +1346,19 @@ var _builtin_refs = map[string]Inst{
13371346
return nil, errors.New("http midware ptr is not a Reporter")
13381347
}
13391348

1340-
return &UI{tcpcontroller, httpmidware}, nil
1349+
var webui = &UI{tcpcontroller, httpmidware, nil}
1350+
1351+
tlsptr, exists := spec.Get("tls")
1352+
1353+
if exists == nil {
1354+
tlsmgr, ok := tlsptr.Value.(*tls.TlsMgr)
1355+
if !ok {
1356+
return nil, errors.New("tls ptr is not a tls.TlsMgr")
1357+
}
1358+
webui.TlsMgr = tlsmgr
1359+
}
1360+
1361+
return webui, nil
13411362
},
13421363
"builtin::ssh::midware": func(spec *ArgNode) (any, error) {
13431364
services := spec.MustGet("services").ToList()

ui/ui.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/dlclark/regexp2"
1717
"github.com/mrhaoxx/OpenNG/http"
1818
"github.com/mrhaoxx/OpenNG/log"
19+
"github.com/mrhaoxx/OpenNG/tls"
1920
utils "github.com/mrhaoxx/OpenNG/utils"
2021
)
2122

@@ -41,6 +42,8 @@ var ReloadCount int = 0
4142
type UI struct {
4243
TcpController Reporter
4344
HttpMidware Reporter
45+
46+
TlsMgr *tls.TlsMgr
4447
}
4548

4649
func (*UI) Hosts() utils.GroupRegexp {
@@ -63,6 +66,21 @@ func (u *UI) HandleHTTP(ctx *http.HttpCtx) http.Ret {
6366
case "/restart":
6467
ctx.Resp.ErrorPage(http.StatusNotImplemented, "Not Implemented")
6568

69+
case "/api/v1/tls/reload":
70+
ctx.Resp.Header().Set("Cache-Control", "no-cache")
71+
if u.TlsMgr != nil {
72+
err := u.TlsMgr.Reload()
73+
if err != nil {
74+
ctx.Resp.WriteHeader(http.StatusBadRequest)
75+
ctx.WriteString(err.Error())
76+
} else {
77+
ctx.Resp.WriteHeader(http.StatusAccepted)
78+
}
79+
} else {
80+
ctx.Resp.WriteHeader(http.StatusFailedDependency)
81+
ctx.WriteString("TlsMgr not set")
82+
}
83+
6684
case "/api/v1/cfg/reload":
6785
ctx.Resp.Header().Set("Cache-Control", "no-cache")
6886
err := Reload()

0 commit comments

Comments
 (0)