Skip to content

Commit a0868c2

Browse files
authored
Allow dumping TLS keys for debug purposes (#439)
Allow dumping TLS keys for debug purposes.
1 parent eab98b2 commit a0868c2

File tree

3 files changed

+59
-27
lines changed

3 files changed

+59
-27
lines changed

pkg/config/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ type TLSConfig struct {
5353
Port int `yaml:"port"` // announced SIP signaling port
5454
ListenPort int `yaml:"port_listen"` // SIP signaling port to listen on
5555
Certs []TLSCert `yaml:"certs"`
56+
KeyLog string `yaml:"key_log"`
5657
}
5758

5859
type Config struct {

pkg/sip/server.go

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ func (s *Server) startTLS(addr netip.AddrPort, conf *tls.Config) error {
242242

243243
type RequestHandler func(req *sip.Request, tx sip.ServerTransaction) bool
244244

245-
func (s *Server) Start(agent *sipgo.UserAgent, sc *ServiceConfig, unhandled RequestHandler) error {
245+
func (s *Server) Start(agent *sipgo.UserAgent, sc *ServiceConfig, tlsConf *tls.Config, unhandled RequestHandler) error {
246246
s.sconf = sc
247247
s.log.Infow("server starting", "local", s.sconf.SignalingIPLocal, "external", s.sconf.SignalingIP)
248248

@@ -289,22 +289,8 @@ func (s *Server) Start(agent *sipgo.UserAgent, sc *ServiceConfig, unhandled Requ
289289
if err := s.startTCP(addr); err != nil {
290290
return err
291291
}
292-
if tconf := s.conf.TLS; tconf != nil {
293-
if len(tconf.Certs) == 0 {
294-
return errors.New("TLS certificate required")
295-
}
296-
var certs []tls.Certificate
297-
for _, c := range tconf.Certs {
298-
cert, err := tls.LoadX509KeyPair(c.CertFile, c.KeyFile)
299-
if err != nil {
300-
return err
301-
}
302-
certs = append(certs, cert)
303-
}
304-
tlsConf := &tls.Config{
305-
NextProtos: []string{"sip"},
306-
Certificates: certs,
307-
}
292+
if tlsConf != nil && s.conf.TLS != nil {
293+
tconf := s.conf.TLS
308294
addrTLS := netip.AddrPortFrom(ip, uint16(tconf.ListenPort))
309295
if err := s.startTLS(addrTLS, tlsConf); err != nil {
310296
return err

pkg/sip/service.go

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,14 @@ package sip
1616

1717
import (
1818
"context"
19+
"crypto/tls"
20+
"errors"
1921
"fmt"
22+
"io"
2023
"log/slog"
2124
"net"
2225
"net/netip"
26+
"os"
2327
"strings"
2428
"sync"
2529
"sync/atomic"
@@ -45,12 +49,13 @@ type ServiceConfig struct {
4549
}
4650

4751
type Service struct {
48-
conf *config.Config
49-
sconf *ServiceConfig
50-
log logger.Logger
51-
mon *stats.Monitor
52-
cli *Client
53-
srv *Server
52+
conf *config.Config
53+
sconf *ServiceConfig
54+
log logger.Logger
55+
mon *stats.Monitor
56+
cli *Client
57+
srv *Server
58+
closers []io.Closer
5459

5560
mu sync.Mutex
5661
pendingTransfers map[transferKey]chan struct{}
@@ -168,6 +173,9 @@ func (s *Service) Stop() {
168173
s.cli.Stop()
169174
s.srv.Stop()
170175
s.mon.Stop()
176+
for _, c := range s.closers {
177+
_ = c.Close()
178+
}
171179
}
172180

173181
func (s *Service) SetHandler(handler Handler) {
@@ -194,10 +202,47 @@ func (s *Service) Start() error {
194202
//
195203
// Routers are smart, they usually keep the UDP "session" open for a few moments, and may allow INVITE handshake
196204
// to pass even without forwarding rules on the firewall. ut it will inevitably fail later on follow-up requests like BYE.
197-
ua, err := sipgo.NewUA(
205+
var opts = []sipgo.UserAgentOption{
198206
sipgo.WithUserAgent(UserAgent),
199207
sipgo.WithUserAgentLogger(slog.New(logger.ToSlogHandler(s.log))),
200-
)
208+
}
209+
var tlsConf *tls.Config
210+
if tconf := s.conf.TLS; tconf != nil {
211+
if len(tconf.Certs) == 0 {
212+
return errors.New("TLS certificate required")
213+
}
214+
var certs []tls.Certificate
215+
for _, c := range tconf.Certs {
216+
cert, err := tls.LoadX509KeyPair(c.CertFile, c.KeyFile)
217+
if err != nil {
218+
return err
219+
}
220+
certs = append(certs, cert)
221+
}
222+
var keyLog io.Writer
223+
if tconf.KeyLog != "" {
224+
f, err := os.OpenFile(tconf.KeyLog, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
225+
if err != nil {
226+
return err
227+
}
228+
s.closers = append(s.closers, f)
229+
keyLog = f
230+
go func() {
231+
ticker := time.NewTicker(30 * time.Second)
232+
defer ticker.Stop()
233+
for range ticker.C {
234+
f.Sync()
235+
}
236+
}()
237+
}
238+
tlsConf = &tls.Config{
239+
NextProtos: []string{"sip"},
240+
Certificates: certs,
241+
KeyLogWriter: keyLog,
242+
}
243+
opts = append(opts, sipgo.WithUserAgenTLSConfig(tlsConf))
244+
}
245+
ua, err := sipgo.NewUA(opts...)
201246
if err != nil {
202247
return err
203248
}
@@ -206,7 +251,7 @@ func (s *Service) Start() error {
206251
}
207252
// Server is responsible for answering all transactions. However, the client may also receive some (e.g. BYE).
208253
// Thus, all unhandled transactions will be checked by the client.
209-
if err := s.srv.Start(ua, s.sconf, s.cli.OnRequest); err != nil {
254+
if err := s.srv.Start(ua, s.sconf, tlsConf, s.cli.OnRequest); err != nil {
210255
return err
211256
}
212257
s.log.Debugw("sip service ready")
@@ -223,7 +268,7 @@ func (s *Service) CreateSIPParticipantAffinity(ctx context.Context, req *rpc.Int
223268
}
224269

225270
func (s *Service) TransferSIPParticipant(ctx context.Context, req *rpc.InternalTransferSIPParticipantRequest) (*emptypb.Empty, error) {
226-
s.log.Infow("transfering SIP call", "callID", req.SipCallId, "transferTo", req.TransferTo)
271+
s.log.Infow("transferring SIP call", "callID", req.SipCallId, "transferTo", req.TransferTo)
227272

228273
var transferResult atomic.Pointer[error]
229274

0 commit comments

Comments
 (0)