From e144a39c5c20211266578d086758f7b5c0b273e5 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Fri, 6 Dec 2024 00:52:33 +0900 Subject: [PATCH] attempting to support TLS --- client.go | 7 ++++- cmd/main.go | 80 +++++++++++++++++++++++++++++++++++++++++++++++---- server-ctl.go | 19 ++++++++++++ server.go | 9 +++++- 4 files changed, 107 insertions(+), 8 deletions(-) diff --git a/client.go b/client.go index dc63263..eda780d 100644 --- a/client.go +++ b/client.go @@ -987,6 +987,7 @@ func NewClient(ctx context.Context, ctl_addrs []string, logger Logger, tlscfg *t c.ctl[i] = &http.Server{ Addr: ctl_addrs[i], Handler: c.ctl_mux, + TLSConfig: tlscfg, // TODO: more settings } } @@ -1183,7 +1184,11 @@ func (c *Client) RunCtlTask(wg *sync.WaitGroup) { l_wg.Add(1) go func(i int, cs *http.Server) { c.log.Write ("", LOG_INFO, "Control channel[%d] started on %s", i, c.ctl_addr[i]) - err = cs.ListenAndServe() + if c.tlscfg == nil { + err = cs.ListenAndServe() + } else { + err = cs.ListenAndServeTLS("", "") // c.tlscfg must provide a certificate and a key + } if errors.Is(err, http.ErrServerClosed) { c.log.Write("", LOG_DEBUG, "Control channel[%d] ended", i) } else { diff --git a/cmd/main.go b/cmd/main.go index 2d6f56c..c22be5e 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -160,13 +160,41 @@ func server_main(ctl_addrs []string, svcaddrs []string) error { var s *hodu.Server var err error var cert tls.Certificate + var cert_pool *x509.CertPool + var tlscfg *tls.Config cert, err = tls.X509KeyPair([]byte(rootCert), []byte(rootKey)) if err != nil { return fmt.Errorf("ERROR: failed to load key pair - %s\n", err) } - s, err = hodu.NewServer(context.Background(), ctl_addrs, svcaddrs, &AppLogger{id: "server", out: os.Stderr}, &tls.Config{Certificates: []tls.Certificate{cert}}) + cert_pool = x509.NewCertPool() + ok := cert_pool.AppendCertsFromPEM([]byte(rootCert)) + if !ok { + return fmt.Errorf("ERROR: failed to append root certificate\n") + } + +/* + // Don't use `Certificates` it doesn't work with some certificate files. + // See, `getClientCertificate` in ${GOSRC}/src/crypto/tls/handshake_client.go for details + tlsConfig.GetClientCertificate = func(cri *tls.CertificateRequestInfo) (*tls.Certificate, error) { + return clientCert, nil + } +*/ + + tlscfg = &tls.Config{ + Certificates: []tls.Certificate{cert}, + ClientAuth: tls.NoClientCert, // tls.RequestClientCert, tls.RequestAnyClientCert, VerifyClientCertIfGiven, RequireAndVerifyClientCert + ClientCAs: cert_pool, // trusted CA certs for client certificate verification + ServerName: "hodu", + } + + s, err = hodu.NewServer( + context.Background(), + ctl_addrs, + svcaddrs, + &AppLogger{id: "server", out: os.Stderr}, + tlscfg) if err != nil { return fmt.Errorf("ERROR: failed to create new server - %s", err.Error()) } @@ -181,25 +209,65 @@ func server_main(ctl_addrs []string, svcaddrs []string) error { // -------------------------------------------------------------------- -func client_main(ctl_addr []string, server_addr string, peer_addrs []string) error { +func client_main(ctl_addrs []string, server_addr string, peer_addrs []string) error { var c *hodu.Client + var cert tls.Certificate var cert_pool *x509.CertPool var tlscfg *tls.Config var cc hodu.ClientConfig + var err error +/* cert_pool = x509.NewCertPool() ok := cert_pool.AppendCertsFromPEM([]byte(rootCert)) if !ok { fmt.Printf("failed to parse root certificate") } + tlscfg = &tls.Config{ RootCAs: cert_pool, - ServerName: "localhost", - InsecureSkipVerify: true, + ClientAuth: + ServerName: "hodu", + //InsecureSkipVerify: true, } -// TODO: support multiple ctl addrs - c = hodu.NewClient(context.Background(), ctl_addr, &AppLogger{id: "client", out: os.Stderr}, tlscfg) + + tlscfg := &tls.Config{ + MinVersion: tls.VersionTLS12, + CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256}, + PreferServerCipherSuites: true, + CipherSuites: []uint16{ + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + tls.TLS_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_RSA_WITH_AES_256_CBC_SHA, + }, + } +*/ + + cert, err = tls.X509KeyPair([]byte(rootCert), []byte(rootKey)) + if err != nil { + return fmt.Errorf("ERROR: failed to load key pair - %s\n", err) + } + + cert_pool = x509.NewCertPool() + ok := cert_pool.AppendCertsFromPEM([]byte(rootCert)) + if !ok { + return fmt.Errorf("ERROR: failed to append root certificate\n") + } + + tlscfg = &tls.Config{ + Certificates: []tls.Certificate{cert}, + ClientAuth: tls.NoClientCert, // tls.RequestClientCert, tls.RequestAnyClientCert, VerifyClientCertIfGiven, RequireAndVerifyClientCert + ClientCAs: cert_pool, // trusted CA certs for client certificate verification + ServerName: "hodu", + } + + c = hodu.NewClient( + context.Background(), + ctl_addrs, + &AppLogger{id: "client", out: os.Stderr}, + tlscfg) cc.ServerAddr = server_addr cc.PeerAddrs = peer_addrs diff --git a/server-ctl.go b/server-ctl.go index 24399f7..b6f0845 100644 --- a/server-ctl.go +++ b/server-ctl.go @@ -30,6 +30,14 @@ type server_ctl_server_conns_id struct { s *Server } +type server_ctl_server_conns_id_routes struct { + s *Server +} + +type server_ctl_server_conns_id_routes_id struct { + s *Server +} + // ------------------------------------ func (ctl *server_ctl_server_conns) ServeHTTP(w http.ResponseWriter, req *http.Request) { @@ -168,3 +176,14 @@ oops: s.log.Write("", LOG_ERROR, "[%s] %s %s - %s", req.RemoteAddr, req.Method, req.URL.String(), err.Error()) return } + +// ------------------------------------ + +func (ctl *server_ctl_server_conns_id_routes) ServeHTTP(w http.ResponseWriter, req *http.Request) { + +} + +// ------------------------------------ + +func (ctl *server_ctl_server_conns_id_routes_id) ServeHTTP(w http.ResponseWriter, req *http.Request) { +} diff --git a/server.go b/server.go index badb035..52e3fec 100644 --- a/server.go +++ b/server.go @@ -852,6 +852,8 @@ func NewServer(ctx context.Context, ctl_addrs []string, rpc_addrs []string, logg s.ctl_mux.Handle(s.ctl_prefix + "/ws/tty", new_server_ctl_ws_tty(&s)) s.ctl_mux.Handle(s.ctl_prefix + "/server-conns", &server_ctl_server_conns{s: &s}) s.ctl_mux.Handle(s.ctl_prefix + "/server-conns/{conn_id}", &server_ctl_server_conns_id{s: &s}) + s.ctl_mux.Handle(s.ctl_prefix + "/server-conns/{conn_id}/routes", &server_ctl_server_conns_id_routes{s: &s}) + s.ctl_mux.Handle(s.ctl_prefix + "/server-conns/{conn_id}/routes/{route_id}", &server_ctl_server_conns_id_routes_id{s: &s}) s.ctl_addr = make([]string, len(ctl_addrs)) s.ctl = make([]*http.Server, len(ctl_addrs)) @@ -860,6 +862,7 @@ func NewServer(ctx context.Context, ctl_addrs []string, rpc_addrs []string, logg s.ctl[i] = &http.Server{ Addr: ctl_addrs[i], Handler: s.ctl_mux, + TLSConfig: s.tlscfg, // TODO: more settings } } @@ -946,7 +949,11 @@ func (s *Server) RunCtlTask(wg *sync.WaitGroup) { l_wg.Add(1) go func(i int, cs *http.Server) { s.log.Write ("", LOG_INFO, "Control channel[%d] started on %s", i, s.ctl_addr[i]) - err = cs.ListenAndServe() + if s.tlscfg == nil { + err = cs.ListenAndServe() + } else { + err = cs.ListenAndServeTLS("", "") // c.tlscfg must provide a certificate and a key + } if errors.Is(err, http.ErrServerClosed) { s.log.Write("", LOG_DEBUG, "Control channel[%d] ended", i) } else {