Skip to content

Commit ccb485a

Browse files
authored
Merge pull request #1 from DataDog/ericd/cloudr-1422
use emissary on file server certs
2 parents 776fc36 + eb1e216 commit ccb485a

3 files changed

Lines changed: 59 additions & 4 deletions

File tree

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ require (
77
github.com/crossplane/crossplane-runtime/v2 v2.2.0
88
github.com/crossplane/function-sdk-go v0.6.0
99
github.com/google/go-cmp v0.7.0
10+
github.com/pkg/errors v0.9.1
11+
google.golang.org/grpc v1.78.0
1012
google.golang.org/protobuf v1.36.11
1113
k8s.io/api v0.35.2
1214
k8s.io/apimachinery v0.35.2
@@ -50,7 +52,6 @@ require (
5052
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
5153
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
5254
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
53-
github.com/pkg/errors v0.9.1 // indirect
5455
github.com/prometheus/client_golang v1.23.2 // indirect
5556
github.com/prometheus/client_model v0.6.2 // indirect
5657
github.com/prometheus/common v0.67.5 // indirect
@@ -73,7 +74,6 @@ require (
7374
golang.org/x/time v0.14.0 // indirect
7475
golang.org/x/tools v0.41.0 // indirect
7576
google.golang.org/genproto/googleapis/rpc v0.0.0-20260203192932-546029d2fa20 // indirect
76-
google.golang.org/grpc v1.78.0 // indirect
7777
gopkg.in/inf.v0 v0.9.1 // indirect
7878
gopkg.in/yaml.v2 v2.4.0 // indirect
7979
gopkg.in/yaml.v3 v3.0.1 // indirect

main.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ type CLI struct {
1313

1414
Network string `help:"Network on which to listen for gRPC connections." default:"tcp"`
1515
Address string `help:"Address at which to listen for gRPC connections." default:":9443"`
16-
TLSCertsDir string `help:"Directory containing server certs (tls.key, tls.crt) and the CA used to verify client certificates (ca.crt)" env:"TLS_SERVER_CERTS_DIR"`
16+
TLSCertsDir string `help:"Directory containing server certs and the CA used to verify client certificates" env:"TLS_SERVER_CERTS_DIR"`
17+
TLSCACertFileName string `help:"Filename of the CA certificate in the TLS certs directory." default:"ca.crt" env:"TLS_CA_CERT_FILENAME"`
18+
TLSCertFileName string `help:"Filename of the server certificate in the TLS certs directory." default:"tls.crt" env:"TLS_CERT_FILENAME"`
19+
TLSKeyFileName string `help:"Filename of the server private key in the TLS certs directory." default:"tls.key" env:"TLS_KEY_FILENAME"`
1720
Insecure bool `help:"Run without mTLS credentials. If you supply this flag --tls-server-certs-dir will be ignored."`
1821
MaxRecvMessageSize int `help:"Maximum size of received messages in MB." default:"4"`
1922
}
@@ -27,7 +30,7 @@ func (c *CLI) Run() error {
2730

2831
return function.Serve(&Function{log: log},
2932
function.Listen(c.Network, c.Address),
30-
function.MTLSCertificates(c.TLSCertsDir),
33+
mtlsCertificates(c.TLSCertsDir, c.TLSCACertFileName, c.TLSCertFileName, c.TLSKeyFileName),
3134
function.Insecure(c.Insecure),
3235
function.MaxRecvMessageSize(c.MaxRecvMessageSize*1024*1024))
3336
}

tls.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Package main implements a Composition Function.
2+
package main
3+
4+
import (
5+
"crypto/tls"
6+
"crypto/x509"
7+
"os"
8+
"path/filepath"
9+
10+
"github.com/crossplane/function-sdk-go"
11+
"github.com/pkg/errors"
12+
"google.golang.org/grpc/credentials"
13+
)
14+
15+
// mtlsCertificates returns a ServeOption that configures mTLS using certificates
16+
// loaded from the given directory. Unlike the SDK's function.MTLSCertificates,
17+
// this allows configuring the certificate filenames to support emissary-provided
18+
// TLS certs (https://datadoghq.atlassian.net/wiki/spaces/RPC/pages/4745232414).
19+
func mtlsCertificates(dir, caCertFile, certFile, keyFile string) function.ServeOption {
20+
return func(o *function.ServeOptions) error {
21+
if dir == "" {
22+
return nil
23+
}
24+
25+
crt, err := tls.LoadX509KeyPair(
26+
filepath.Join(dir, certFile),
27+
filepath.Join(dir, keyFile),
28+
)
29+
if err != nil {
30+
return errors.Wrap(err, "cannot load X509 keypair")
31+
}
32+
33+
ca, err := os.ReadFile(filepath.Clean(filepath.Join(dir, caCertFile)))
34+
if err != nil {
35+
return errors.Wrap(err, "cannot read CA certificate")
36+
}
37+
38+
pool := x509.NewCertPool()
39+
if !pool.AppendCertsFromPEM(ca) {
40+
return errors.New("invalid CA certificate")
41+
}
42+
43+
o.Credentials = credentials.NewTLS(&tls.Config{
44+
MinVersion: tls.VersionTLS12,
45+
Certificates: []tls.Certificate{crt},
46+
ClientCAs: pool,
47+
ClientAuth: tls.RequireAndVerifyClientCert,
48+
})
49+
50+
return nil
51+
}
52+
}

0 commit comments

Comments
 (0)