Skip to content

Commit

Permalink
Support listening on TLS
Browse files Browse the repository at this point in the history
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 <me@frebib.net>
  • Loading branch information
frebib committed Nov 3, 2021
1 parent 34bbefa commit 60cd758
Showing 1 changed file with 71 additions and 1 deletion.
72 changes: 71 additions & 1 deletion cmd/cadvisor.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ package main

import (
"crypto/tls"
"crypto/x509"
"flag"
"fmt"
"net"
"net/http"
"net/http/pprof"
"os"
Expand Down Expand Up @@ -55,6 +57,11 @@ var httpAuthRealm = flag.String("http_auth_realm", "localhost", "HTTP auth realm
var httpDigestFile = flag.String("http_digest_file", "", "HTTP digest file for the web UI")
var httpDigestRealm = flag.String("http_digest_realm", "localhost", "HTTP digest file for the web UI")

var tlsCertPath = flag.String("tls_cert_path", "", "TLS certificate file path")
var tlsKeyPath = flag.String("tls_key_path", "", "TLS key file path")
var tlsCAPath = flag.String("tls_ca_path", "", "TLS certificate authority file path")
var tlsClientAuth = flag.String("tls_client_auth", "require", "TLS authentication mode, must be one of request, optional, requireany, require or none")

var prometheusEndpoint = flag.String("prometheus_endpoint", "/metrics", "Endpoint to expose Prometheus metrics on")

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

// Load TLS server configuration
var tlsConfig tls.Config
if *tlsCertPath != "" && *tlsKeyPath != "" {
if *tlsCertPath == "" || *tlsKeyPath == "" {
klog.Fatal("Both tls_cert_path and tls_key_path are required at the same time")
}

// Verify that the key/certificate load and are valid before starting up
_, err := tls.LoadX509KeyPair(*tlsCertPath, *tlsKeyPath)
if err != nil {
klog.Fatalf("Failed to load TLS certificate/key pair: %v", err)
}

tlsConfig.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
cert, err := tls.LoadX509KeyPair(*tlsCertPath, *tlsKeyPath)
if err != nil {
return nil, err
}
return &cert, nil
}
}

if *tlsCAPath != "" {
clientCAPool := x509.NewCertPool()
clientCAFile, err := os.ReadFile(*tlsCAPath)
if err != nil {
klog.Fatalf("Failed to load TLS CA file: %v", err)
}
clientCAPool.AppendCertsFromPEM(clientCAFile)
tlsConfig.ClientCAs = clientCAPool
}

switch *tlsClientAuth {
case "request":
tlsConfig.ClientAuth = tls.RequestClientCert
case "optional":
tlsConfig.ClientAuth = tls.VerifyClientCertIfGiven
case "requireany":
tlsConfig.ClientAuth = tls.RequireAnyClientCert
case "require":
tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
case "none":
tlsConfig.ClientAuth = tls.NoClientCert
default:
klog.Fatalf("Invalid tls_client_auth: %s", *tlsClientAuth)
}

containerLabelFunc := metrics.DefaultContainerLabels
if !*storeContainerLabels {
whitelistedLabels := strings.Split(*whitelistedContainerLabels, ",")
Expand All @@ -176,7 +230,23 @@ func main() {
rootMux.Handle(*urlBasePrefix+"/", http.StripPrefix(*urlBasePrefix, mux))

addr := fmt.Sprintf("%s:%d", *argIP, *argPort)
klog.Fatal(http.ListenAndServe(addr, rootMux))
listener, err := net.Listen("tcp", addr)
if err != nil {
klog.Fatal(err)
}

// Wrap in a TLS listener if cert/key was specfied
if *tlsCertPath != "" {
listener = tls.NewListener(listener, &tlsConfig)
klog.V(1).Infof("Listening for TLS connections")
}

server := &http.Server{
Addr: addr,
Handler: rootMux,
TLSConfig: &tlsConfig,
}
klog.Fatal(server.Serve(listener))
}

func setMaxProcs() {
Expand Down

0 comments on commit 60cd758

Please sign in to comment.