Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit 8449de6

Browse files
authored
Merge pull request from GHSA-g677-5cc4-732g
Add support for client verification via TLS certs.
2 parents 1ef86fc + 2124633 commit 8449de6

4 files changed

Lines changed: 410 additions & 10 deletions

File tree

internal/commands/root/flag.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ func installFlags(flags *pflag.FlagSet, c *opts.Opts) {
4848
flags.Int32Var(&c.KubeAPIBurst, "kube-api-burst", c.KubeAPIBurst,
4949
"kubeAPIBurst is the burst to allow while talking with kubernetes apiserver")
5050

51+
flags.StringVar(&c.ClientCACert, "client-verify-ca", os.Getenv("APISERVER_CA_CERT_LOCATION"), "CA cert to use to verify client requests")
52+
flags.BoolVar(&c.AllowUnauthenticatedClients, "no-verify-clients", false, "Do not require client certificate validation")
53+
5154
flagset := flag.NewFlagSet("klog", flag.PanicOnError)
5255
klog.InitFlags(flagset)
5356
flagset.VisitAll(func(f *flag.Flag) {

internal/commands/root/http.go

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ package root
1717
import (
1818
"context"
1919
"crypto/tls"
20+
"crypto/x509"
2021
"fmt"
2122
"io"
23+
"io/ioutil"
2224
"net"
2325
"net/http"
2426
"os"
@@ -45,17 +47,39 @@ var AcceptedCiphers = []uint16{
4547
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
4648
}
4749

48-
func loadTLSConfig(certPath, keyPath string) (*tls.Config, error) {
50+
func loadTLSConfig(certPath, keyPath, caPath string, allowUnauthenticatedClients bool) (*tls.Config, error) {
4951
cert, err := tls.LoadX509KeyPair(certPath, keyPath)
5052
if err != nil {
5153
return nil, errors.Wrap(err, "error loading tls certs")
5254
}
5355

56+
var (
57+
caPool *x509.CertPool
58+
clientAuth = tls.RequireAndVerifyClientCert
59+
)
60+
61+
if allowUnauthenticatedClients {
62+
clientAuth = tls.NoClientCert
63+
}
64+
65+
if caPath != "" {
66+
caPool = x509.NewCertPool()
67+
pem, err := ioutil.ReadFile(caPath)
68+
if err != nil {
69+
return nil, err
70+
}
71+
if !caPool.AppendCertsFromPEM(pem) {
72+
return nil, errors.New("error appending ca cert to certificate pool")
73+
}
74+
}
75+
5476
return &tls.Config{
5577
Certificates: []tls.Certificate{cert},
5678
MinVersion: tls.VersionTLS12,
5779
PreferServerCipherSuites: true,
5880
CipherSuites: AcceptedCiphers,
81+
ClientCAs: caPool,
82+
ClientAuth: clientAuth,
5983
}, nil
6084
}
6185

@@ -72,19 +96,20 @@ func setupHTTPServer(ctx context.Context, p provider.Provider, cfg *apiServerCon
7296
}
7397
}()
7498

75-
if cfg.CertPath == "" || cfg.KeyPath == "" {
99+
if cfg.CertPath == "" || cfg.KeyPath == "" || (cfg.CACertPath == "" && !cfg.AllowUnauthenticatedClients) {
76100
log.G(ctx).
77101
WithField("certPath", cfg.CertPath).
78102
WithField("keyPath", cfg.KeyPath).
103+
WithField("caPath", cfg.CACertPath).
79104
Error("TLS certificates not provided, not setting up pod http server")
80105
} else {
81-
tlsCfg, err := loadTLSConfig(cfg.CertPath, cfg.KeyPath)
106+
tlsCfg, err := loadTLSConfig(cfg.CertPath, cfg.KeyPath, cfg.CACertPath, cfg.AllowUnauthenticatedClients)
82107
if err != nil {
83108
return nil, err
84109
}
85110
l, err := tls.Listen("tcp", cfg.Addr, tlsCfg)
86111
if err != nil {
87-
return nil, errors.Wrap(err, "error setting up listener for pod http server")
112+
return nil, errors.Wrapf(err, "error setting up listener for pod http server: tlsconfig: \n%+v", tlsCfg)
88113
}
89114

90115
mux := http.NewServeMux()
@@ -147,12 +172,14 @@ func serveHTTP(ctx context.Context, s *http.Server, l net.Listener, name string)
147172
}
148173

149174
type apiServerConfig struct {
150-
CertPath string
151-
KeyPath string
152-
Addr string
153-
MetricsAddr string
154-
StreamIdleTimeout time.Duration
155-
StreamCreationTimeout time.Duration
175+
CACertPath string
176+
CertPath string
177+
KeyPath string
178+
Addr string
179+
MetricsAddr string
180+
StreamIdleTimeout time.Duration
181+
StreamCreationTimeout time.Duration
182+
AllowUnauthenticatedClients bool
156183
}
157184

158185
func getAPIConfig(c *opts.Opts) (*apiServerConfig, error) {
@@ -165,6 +192,12 @@ func getAPIConfig(c *opts.Opts) (*apiServerConfig, error) {
165192
config.MetricsAddr = c.MetricsAddr
166193
config.StreamIdleTimeout = c.StreamIdleTimeout
167194
config.StreamCreationTimeout = c.StreamCreationTimeout
195+
config.AllowUnauthenticatedClients = c.AllowUnauthenticatedClients
196+
197+
config.CACertPath = c.ClientCACert
198+
if c.ClientCACert == "" {
199+
config.CACertPath = os.Getenv("APISERVER_CA_CERT_LOCATION")
200+
}
168201

169202
return &config, nil
170203
}

0 commit comments

Comments
 (0)