Skip to content

Commit ee59d88

Browse files
committed
Fix replica sync TLS
1 parent f9177e4 commit ee59d88

File tree

3 files changed

+33
-16
lines changed

3 files changed

+33
-16
lines changed

enterprise/coderd/coderd.go

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -129,32 +129,38 @@ func New(ctx context.Context, options *Options) (*API, error) {
129129
})
130130
}
131131

132-
var err error
133-
api.replicaManager, err = replicasync.New(ctx, options.Logger, options.Database, options.Pubsub, replicasync.Options{
134-
// Create a new replica ID for each Coder instance!
135-
ID: uuid.New(),
136-
RelayAddress: options.DERPServerRelayAddress,
137-
RegionID: int32(options.DERPServerRegionID),
138-
})
139-
if err != nil {
140-
return nil, xerrors.Errorf("initialize replica: %w", err)
141-
}
142-
143-
rootCA := x509.NewCertPool()
132+
meshRootCA := x509.NewCertPool()
144133
for _, certificate := range options.TLSCertificates {
145134
for _, certificatePart := range certificate.Certificate {
146135
certificate, err := x509.ParseCertificate(certificatePart)
147136
if err != nil {
148137
return nil, xerrors.Errorf("parse certificate %s: %w", certificate.Subject.CommonName, err)
149138
}
150-
rootCA.AddCert(certificate)
139+
meshRootCA.AddCert(certificate)
151140
}
152141
}
153-
// nolint:gosec
154-
api.derpMesh = derpmesh.New(options.Logger.Named("derpmesh"), api.DERPServer, &tls.Config{
142+
// This TLS configuration spoofs access from the access URL hostname
143+
// assuming that the certificates provided will cover that hostname.
144+
//
145+
// Replica sync and DERP meshing require accessing replicas via their
146+
// internal IP addresses, and if TLS is configured we use the same
147+
// certificates.
148+
meshTLSConfig := &tls.Config{
155149
ServerName: options.AccessURL.Hostname(),
156-
RootCAs: rootCA,
150+
RootCAs: meshRootCA,
151+
}
152+
var err error
153+
api.replicaManager, err = replicasync.New(ctx, options.Logger, options.Database, options.Pubsub, replicasync.Options{
154+
// Create a new replica ID for each Coder instance!
155+
ID: uuid.New(),
156+
RelayAddress: options.DERPServerRelayAddress,
157+
RegionID: int32(options.DERPServerRegionID),
158+
TLSConfig: meshTLSConfig,
157159
})
160+
if err != nil {
161+
return nil, xerrors.Errorf("initialize replica: %w", err)
162+
}
163+
api.derpMesh = derpmesh.New(options.Logger.Named("derpmesh"), api.DERPServer, meshTLSConfig)
158164

159165
err = api.updateEntitlements(ctx)
160166
if err != nil {

enterprise/coderd/replicas_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,5 +129,11 @@ func TestReplicas(t *testing.T) {
129129
return err == nil
130130
}, testutil.WaitLong, testutil.IntervalFast)
131131
_ = conn.Close()
132+
replicas, err = secondClient.Replicas(context.Background())
133+
require.NoError(t, err)
134+
require.Len(t, replicas, 2)
135+
for _, replica := range replicas {
136+
require.Empty(t, replica.Error)
137+
}
132138
})
133139
}

enterprise/replicasync/replicasync.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package replicasync
22

33
import (
44
"context"
5+
"crypto/tls"
56
"database/sql"
67
"errors"
78
"fmt"
@@ -30,6 +31,7 @@ type Options struct {
3031
PeerTimeout time.Duration
3132
RelayAddress string
3233
RegionID int32
34+
TLSConfig *tls.Config
3335
}
3436

3537
// New registers the replica with the database and periodically updates to ensure
@@ -254,6 +256,9 @@ func (m *Manager) run(ctx context.Context) error {
254256
}
255257
client := http.Client{
256258
Timeout: m.options.PeerTimeout,
259+
Transport: &http.Transport{
260+
TLSClientConfig: m.options.TLSConfig,
261+
},
257262
}
258263
res, err := client.Do(req)
259264
if err != nil {

0 commit comments

Comments
 (0)