Skip to content

Commit 36ebd6e

Browse files
committed
Support listening on TLS
Allows specifying a certificate&key pair by file paths, as well as an optional CA file. Enforce/allow mutual-TLS handshake behaviour too. Signed-off-by: Joe Groocock <[email protected]>
1 parent 34bbefa commit 36ebd6e

File tree

1 file changed

+71
-1
lines changed

1 file changed

+71
-1
lines changed

cmd/cadvisor.go

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ package main
1616

1717
import (
1818
"crypto/tls"
19+
"crypto/x509"
1920
"flag"
2021
"fmt"
22+
"net"
2123
"net/http"
2224
"net/http/pprof"
2325
"os"
@@ -55,6 +57,11 @@ var httpAuthRealm = flag.String("http_auth_realm", "localhost", "HTTP auth realm
5557
var httpDigestFile = flag.String("http_digest_file", "", "HTTP digest file for the web UI")
5658
var httpDigestRealm = flag.String("http_digest_realm", "localhost", "HTTP digest file for the web UI")
5759

60+
var tlsCertPath = flag.String("tls_cert_path", "", "TLS certificate file path")
61+
var tlsKeyPath = flag.String("tls_key_path", "", "TLS key file path")
62+
var tlsCAPath = flag.String("tls_ca_path", "", "TLS certificate authority file path")
63+
var tlsClientAuth = flag.String("tls_client_auth", "require", "TLS authentication mode, must be one of request, optional, requireany, require or none")
64+
5865
var prometheusEndpoint = flag.String("prometheus_endpoint", "/metrics", "Endpoint to expose Prometheus metrics on")
5966

6067
var enableProfiling = flag.Bool("profiling", false, "Enable profiling via web interface host:port/debug/pprof/")
@@ -153,6 +160,53 @@ func main() {
153160
klog.Fatalf("Failed to register HTTP handlers: %v", err)
154161
}
155162

163+
// Load TLS server configuration
164+
var tlsConfig tls.Config
165+
if *tlsCertPath != "" && *tlsKeyPath != "" {
166+
if *tlsCertPath == "" || *tlsKeyPath == "" {
167+
klog.Fatal("Both tls_cert_path and tls_key_path are required at the same time")
168+
}
169+
170+
// Verify that the key/certificate load and are valid before starting up
171+
_, err := tls.LoadX509KeyPair(*tlsCertPath, *tlsKeyPath)
172+
if err != nil {
173+
klog.Fatalf("Failed to load TLS certificate/key pair: %v", err)
174+
}
175+
176+
tlsConfig.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
177+
cert, err := tls.LoadX509KeyPair(*tlsCertPath, *tlsKeyPath)
178+
if err != nil {
179+
return nil, err
180+
}
181+
return &cert, nil
182+
}
183+
}
184+
185+
if *tlsCAPath != "" {
186+
clientCAPool := x509.NewCertPool()
187+
clientCAFile, err := os.ReadFile(*tlsCAPath)
188+
if err != nil {
189+
klog.Fatalf("Failed to load TLS CA file: %v", err)
190+
}
191+
clientCAPool.AppendCertsFromPEM(clientCAFile)
192+
tlsConfig.ClientCAs = clientCAPool
193+
}
194+
195+
switch *tlsClientAuth {
196+
case "request":
197+
tlsConfig.ClientAuth = tls.RequestClientCert
198+
case "optional":
199+
tlsConfig.ClientAuth = tls.VerifyClientCertIfGiven
200+
case "requireany":
201+
tlsConfig.ClientAuth = tls.RequireAnyClientCert
202+
case "require":
203+
tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
204+
case "none":
205+
tlsConfig.ClientAuth = tls.NoClientCert
206+
default:
207+
klog.Fatalf("Invalid tls_client_auth: %s", *tlsClientAuth)
208+
}
209+
156210
containerLabelFunc := metrics.DefaultContainerLabels
157211
if !*storeContainerLabels {
158212
whitelistedLabels := strings.Split(*whitelistedContainerLabels, ",")
@@ -176,7 +230,23 @@ func main() {
176230
rootMux.Handle(*urlBasePrefix+"/", http.StripPrefix(*urlBasePrefix, mux))
177231

178232
addr := fmt.Sprintf("%s:%d", *argIP, *argPort)
179-
klog.Fatal(http.ListenAndServe(addr, rootMux))
233+
listener, err := net.Listen("tcp", addr)
234+
if err != nil {
235+
klog.Fatal(err)
236+
}
237+
238+
// Wrap in a TLS listener if cert/key was specfied
239+
if *tlsCertPath != "" {
240+
listener = tls.NewListener(listener, &tlsConfig)
241+
klog.V(1).Infof("Listening for TLS connections")
242+
}
243+
244+
server := &http.Server{
245+
Addr: addr,
246+
Handler: rootMux,
247+
TLSConfig: &tlsConfig,
248+
}
249+
klog.Fatal(server.Serve(listener))
180250
}
181251

182252
func setMaxProcs() {

0 commit comments

Comments
 (0)