Skip to content

Commit 9443235

Browse files
smasset-orangeshanduur
authored andcommitted
feat: add authority in GRPC client initialization
Enables support for trustd behind load balancer by providing SNI. (cherry picked from commit b593bc6) (cherry picked from commit 33f336d) Signed-off-by: Sébastien Masset <86793256+smasset-orange@users.noreply.github.com> Signed-off-by: Mateusz Urbanek <mateusz.urbanek@siderolabs.com>
1 parent 080efcb commit 9443235

5 files changed

Lines changed: 66 additions & 20 deletions

File tree

internal/app/machined/pkg/controllers/secrets/api.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ func (ctrl *APIController) reconcile(ctx context.Context, r controller.Runtime,
269269
return err
270270
}
271271
} else {
272-
if err := ctrl.generateWorker(ctx, r, logger, rootSpec, endpointsStr, certSANs); err != nil {
272+
if err := ctrl.generateWorker(ctx, r, logger, rootSpec, endpointsStr, "", certSANs); err != nil {
273273
return err
274274
}
275275
}
@@ -336,9 +336,11 @@ func (ctrl *APIController) generateControlPlane(ctx context.Context, r controlle
336336
}
337337

338338
func (ctrl *APIController) generateWorker(ctx context.Context, r controller.Runtime, logger *zap.Logger,
339-
rootSpec *secrets.OSRootSpec, endpointsStr []string, certSANs *secrets.CertSANSpec,
339+
rootSpec *secrets.OSRootSpec, endpointsStr []string, endpointHost string, certSANs *secrets.CertSANSpec,
340340
) error {
341-
remoteGen, err := gen.NewRemoteGenerator(rootSpec.Token, endpointsStr, rootSpec.AcceptedCAs)
341+
logger.Debug("Initializing CSR generator", zap.Strings("endpoints", endpointsStr), zap.String("host", endpointHost))
342+
343+
remoteGen, err := gen.NewRemoteGenerator(rootSpec.Token, endpointsStr, endpointHost, rootSpec.AcceptedCAs)
342344
if err != nil {
343345
return fmt.Errorf("failed creating trustd client: %w", err)
344346
}

pkg/grpc/gen/remote.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ type RemoteGenerator struct {
3131
}
3232

3333
// NewRemoteGenerator initializes a RemoteGenerator with a preconfigured grpc.ClientConn.
34-
func NewRemoteGenerator(token string, endpoints []string, acceptedCAs []*x509.PEMEncodedCertificate) (g *RemoteGenerator, err error) {
34+
func NewRemoteGenerator(token string, endpoints []string, host string, acceptedCAs []*x509.PEMEncodedCertificate) (g *RemoteGenerator, err error) {
3535
if len(endpoints) == 0 {
3636
return nil, errors.New("at least one root of trust endpoint is required")
3737
}
@@ -42,7 +42,7 @@ func NewRemoteGenerator(token string, endpoints []string, acceptedCAs []*x509.PE
4242

4343
remoteGeneratorPprof.Add(g, 1)
4444

45-
conn, err := basic.NewConnection(fmt.Sprintf("%s:///%s", resolver.RoundRobinResolverScheme, strings.Join(endpoints, ",")), basic.NewTokenCredentials(token), acceptedCAs)
45+
conn, err := basic.NewConnection(fmt.Sprintf("%s:///%s", resolver.RoundRobinResolverScheme, strings.Join(endpoints, ",")), host, basic.NewTokenCredentials(token), acceptedCAs)
4646
if err != nil {
4747
return nil, err
4848
}

pkg/grpc/middleware/auth/basic/basic.go

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"bytes"
99
"crypto/tls"
1010
stdx509 "crypto/x509"
11+
"net"
1112

1213
"github.com/siderolabs/crypto/x509"
1314
"github.com/siderolabs/gen/xslices"
@@ -27,7 +28,7 @@ type Credentials interface {
2728

2829
// NewConnection initializes a grpc.ClientConn configured for basic
2930
// authentication.
30-
func NewConnection(address string, creds credentials.PerRPCCredentials, acceptedCAs []*x509.PEMEncodedCertificate) (conn *grpc.ClientConn, err error) {
31+
func NewConnection(address string, host string, creds credentials.PerRPCCredentials, acceptedCAs []*x509.PEMEncodedCertificate) (conn *grpc.ClientConn, err error) {
3132
tlsConfig := &tls.Config{}
3233

3334
tlsConfig.RootCAs = stdx509.NewCertPool()
@@ -42,6 +43,7 @@ func NewConnection(address string, creds credentials.PerRPCCredentials, accepted
4243
))
4344

4445
grpcOpts := []grpc.DialOption{
46+
grpc.WithAuthority(ParseAuthority(host)),
4547
grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)),
4648
grpc.WithPerRPCCredentials(creds),
4749
grpc.WithSharedWriteBuffer(true),
@@ -55,3 +57,30 @@ func NewConnection(address string, creds credentials.PerRPCCredentials, accepted
5557

5658
return conn, nil
5759
}
60+
61+
// ParseAuthority checks if provided host parameter is neither empty nor
62+
// an IP address and returns the extracted host if found
63+
// or an empty string in all other cases.
64+
func ParseAuthority(host string) string {
65+
if host == "" {
66+
return ""
67+
}
68+
69+
var parsedHost string
70+
71+
// Check if port is provided and remove it
72+
h, _, err := net.SplitHostPort(host)
73+
if err == nil {
74+
parsedHost = h
75+
} else {
76+
parsedHost = host
77+
}
78+
79+
// If parsedHost is an IP address it should not be used as an authority
80+
if ip := net.ParseIP(parsedHost); ip != nil {
81+
return ""
82+
}
83+
84+
// Otherwise return the parsed host
85+
return parsedHost
86+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this
3+
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4+
5+
package basic_test
6+
7+
import (
8+
"testing"
9+
10+
"github.com/siderolabs/talos/pkg/grpc/middleware/auth/basic"
11+
"github.com/stretchr/testify/assert"
12+
)
13+
14+
func TestParseAuthority(t *testing.T) {
15+
for _, tc := range []struct {
16+
host string
17+
want string
18+
}{
19+
{"127.0.0.1", ""},
20+
{"127.0.0.1:443", ""},
21+
{"::1", ""},
22+
{"[::1]:443", ""},
23+
{"example.com", "example.com"},
24+
{"example.com:443", "example.com"},
25+
{"", ""},
26+
} {
27+
assert.Equal(t, tc.want, basic.ParseAuthority(tc.host))
28+
}
29+
}

pkg/grpc/middleware/auth/basic/username_and_password_test.go

Lines changed: 0 additions & 14 deletions
This file was deleted.

0 commit comments

Comments
 (0)