@@ -2,11 +2,19 @@ package server
22
33import (
44 "context"
5+ "crypto/rand"
6+ "crypto/rsa"
7+ "crypto/tls"
8+ "crypto/x509"
9+ "crypto/x509/pkix"
10+ "encoding/pem"
511 "fmt"
12+ "math/big"
613 "time"
714
815 extProcPb "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3"
916 "google.golang.org/grpc"
17+ "google.golang.org/grpc/credentials"
1018 "k8s.io/apimachinery/pkg/types"
1119 klog "k8s.io/klog/v2"
1220 ctrl "sigs.k8s.io/controller-runtime"
@@ -27,6 +35,8 @@ type ExtProcServerRunner struct {
2735 RefreshMetricsInterval time.Duration
2836 RefreshPrometheusMetricsInterval time.Duration
2937 Datastore * backend.K8sDatastore
38+ SecureServing bool
39+ CertPath string
3040}
3141
3242// Default values for CLI flags in main
@@ -38,6 +48,7 @@ const (
3848 DefaultRefreshPodsInterval = 10 * time .Second // default for --refreshPodsInterval
3949 DefaultRefreshMetricsInterval = 50 * time .Millisecond // default for --refreshMetricsInterval
4050 DefaultRefreshPrometheusMetricsInterval = 5 * time .Second // default for --refreshPrometheusMetricsInterval
51+ DefaultSecureServing = true // default for --secureServing
4152)
4253
4354func NewDefaultExtProcServerRunner () * ExtProcServerRunner {
@@ -49,6 +60,7 @@ func NewDefaultExtProcServerRunner() *ExtProcServerRunner {
4960 RefreshPodsInterval : DefaultRefreshPodsInterval ,
5061 RefreshMetricsInterval : DefaultRefreshMetricsInterval ,
5162 RefreshPrometheusMetricsInterval : DefaultRefreshPrometheusMetricsInterval ,
63+ SecureServing : DefaultSecureServing ,
5264 // Datastore can be assigned later.
5365 }
5466}
@@ -107,8 +119,29 @@ func (r *ExtProcServerRunner) AsRunnable(
107119 return err
108120 }
109121
110- // Init the server.
111- srv := grpc .NewServer ()
122+ var srv * grpc.Server
123+ if r .SecureServing {
124+ var cert tls.Certificate
125+ var err error
126+ if r .CertPath != "" {
127+ cert , err = tls .LoadX509KeyPair (r .CertPath + "/tls.crt" , r .CertPath + "/tls.key" )
128+ } else {
129+ // Create tls based credential.
130+ cert , err = createSelfSignedTLSCertificate ()
131+ }
132+ if err != nil {
133+ klog .ErrorS (err , "Failed to create self signed certificate" )
134+ return err
135+ }
136+
137+ creds := credentials .NewTLS (& tls.Config {
138+ Certificates : []tls.Certificate {cert },
139+ })
140+ // Init the server.
141+ srv = grpc .NewServer (grpc .Creds (creds ))
142+ } else {
143+ srv = grpc .NewServer ()
144+ }
112145 extProcPb .RegisterExternalProcessorServer (
113146 srv ,
114147 handlers .NewServer (pp , scheduling .NewScheduler (pp ), r .TargetEndpointKey , r .Datastore ),
@@ -118,3 +151,48 @@ func (r *ExtProcServerRunner) AsRunnable(
118151 return runnable .GRPCServer ("ext-proc" , srv , r .GrpcPort ).Start (ctx )
119152 }))
120153}
154+
155+ func createSelfSignedTLSCertificate () (tls.Certificate , error ) {
156+ serialNumberLimit := new (big.Int ).Lsh (big .NewInt (1 ), 128 )
157+ serialNumber , err := rand .Int (rand .Reader , serialNumberLimit )
158+ if err != nil {
159+ klog .ErrorS (err , "Failed to create serial number for self-signed cert" )
160+ return tls.Certificate {}, err
161+ }
162+ now := time .Now ()
163+ notBefore := now .UTC ()
164+ template := x509.Certificate {
165+ SerialNumber : serialNumber ,
166+ Subject : pkix.Name {
167+ Organization : []string {"Inference Ext" },
168+ },
169+ NotBefore : notBefore ,
170+ NotAfter : now .Add (time .Hour * 24 * 365 * 10 ).UTC (), // 10 years
171+ KeyUsage : x509 .KeyUsageKeyEncipherment | x509 .KeyUsageDigitalSignature ,
172+ ExtKeyUsage : []x509.ExtKeyUsage {x509 .ExtKeyUsageServerAuth },
173+ BasicConstraintsValid : true ,
174+ }
175+
176+ priv , err := rsa .GenerateKey (rand .Reader , 4096 )
177+ if err != nil {
178+ klog .ErrorS (err , "Failed to generate key for self-signed cert" )
179+ return tls.Certificate {}, err
180+ }
181+
182+ derBytes , err := x509 .CreateCertificate (rand .Reader , & template , & template , & priv .PublicKey , priv )
183+ if err != nil {
184+ klog .ErrorS (err , "Failed to create self-signed certificate" )
185+ return tls.Certificate {}, err
186+ }
187+
188+ certBytes := pem .EncodeToMemory (& pem.Block {Type : "CERTIFICATE" , Bytes : derBytes })
189+
190+ privBytes , err := x509 .MarshalPKCS8PrivateKey (priv )
191+ if err != nil {
192+ klog .ErrorS (err , "Failed to marshal private key for self-signed certificate" )
193+ return tls.Certificate {}, err
194+ }
195+ keyBytes := pem .EncodeToMemory (& pem.Block {Type : "PRIVATE KEY" , Bytes : privBytes })
196+
197+ return tls .X509KeyPair (certBytes , keyBytes )
198+ }
0 commit comments