@@ -16,8 +16,10 @@ package main
16
16
17
17
import (
18
18
"crypto/tls"
19
+ "crypto/x509"
19
20
"flag"
20
21
"fmt"
22
+ "net"
21
23
"net/http"
22
24
"net/http/pprof"
23
25
"os"
@@ -55,6 +57,11 @@ var httpAuthRealm = flag.String("http_auth_realm", "localhost", "HTTP auth realm
55
57
var httpDigestFile = flag .String ("http_digest_file" , "" , "HTTP digest file for the web UI" )
56
58
var httpDigestRealm = flag .String ("http_digest_realm" , "localhost" , "HTTP digest file for the web UI" )
57
59
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
+
58
65
var prometheusEndpoint = flag .String ("prometheus_endpoint" , "/metrics" , "Endpoint to expose Prometheus metrics on" )
59
66
60
67
var enableProfiling = flag .Bool ("profiling" , false , "Enable profiling via web interface host:port/debug/pprof/" )
@@ -153,6 +160,53 @@ func main() {
153
160
klog .Fatalf ("Failed to register HTTP handlers: %v" , err )
154
161
}
155
162
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
+
156
210
containerLabelFunc := metrics .DefaultContainerLabels
157
211
if ! * storeContainerLabels {
158
212
whitelistedLabels := strings .Split (* whitelistedContainerLabels , "," )
@@ -176,7 +230,23 @@ func main() {
176
230
rootMux .Handle (* urlBasePrefix + "/" , http .StripPrefix (* urlBasePrefix , mux ))
177
231
178
232
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 ))
180
250
}
181
251
182
252
func setMaxProcs () {
0 commit comments