Skip to content

Commit 9f1c988

Browse files
committed
cluster: auto session certs
Signed-off-by: xhe <[email protected]>
1 parent 79c584f commit 9f1c988

File tree

2 files changed

+120
-26
lines changed

2 files changed

+120
-26
lines changed

pkg/cluster/manager/builder.go

+82-26
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ package manager
1515

1616
import (
1717
"context"
18+
"encoding/pem"
1819
"fmt"
20+
"os"
1921
"path/filepath"
2022
"strings"
2123

@@ -835,6 +837,36 @@ func buildTLSTask(
835837
return builder.Build(), nil
836838
}
837839

840+
func genTiProxySessionCerts(dir string) error {
841+
if _, err := os.Stat(filepath.Join(dir, "tiproxy-session.crt")); err == nil {
842+
return nil
843+
}
844+
845+
ca, err := crypto.NewCA("tiproxy")
846+
if err != nil {
847+
return err
848+
}
849+
privKey, err := crypto.NewKeyPair(crypto.KeyTypeRSA, crypto.KeySchemeRSASSAPSSSHA256)
850+
if err != nil {
851+
return err
852+
}
853+
csr, err := privKey.CSR("tiproxy", "tiproxy", nil, nil)
854+
if err != nil {
855+
return err
856+
}
857+
cert, err := ca.Sign(csr)
858+
if err != nil {
859+
return err
860+
}
861+
if err := utils.SaveFileWithBackup(filepath.Join(dir, "tiproxy-session.key"), privKey.Pem(), ""); err != nil {
862+
return err
863+
}
864+
return utils.SaveFileWithBackup(filepath.Join(dir, "tiproxy-session.crt"), pem.EncodeToMemory(&pem.Block{
865+
Type: "CERTIFICATE",
866+
Bytes: cert,
867+
}), "")
868+
}
869+
838870
// buildCertificateTasks generates certificate for instance and transfers it to the server
839871
func buildCertificateTasks(
840872
m *Manager,
@@ -848,37 +880,61 @@ func buildCertificateTasks(
848880
certificateTasks []*task.StepDisplay // tasks which are used to copy certificate to remote host
849881
)
850882

851-
if topo.BaseTopo().GlobalOptions.TLSEnabled {
852-
// copy certificate to remote host
853-
topo.IterInstance(func(inst spec.Instance) {
854-
deployDir := spec.Abs(base.User, inst.DeployDir())
855-
tlsDir := filepath.Join(deployDir, spec.TLSCertKeyDir)
883+
// check if there is tiproxy
884+
// if there is tiproxy, whether or not TLS, we must issue a self-signed cert
885+
hasTiProxy := false
886+
topo.IterInstance(func(inst spec.Instance) {
887+
if inst.ComponentName() == spec.ComponentTiProxy {
888+
hasTiProxy = true
889+
}
890+
})
891+
if hasTiProxy {
892+
if err := genTiProxySessionCerts(m.specManager.Path(name, spec.TempConfigPath)); err != nil {
893+
return certificateTasks, err
894+
}
895+
}
856896

897+
// copy certificate to remote host
898+
topo.IterInstance(func(inst spec.Instance) {
899+
deployDir := spec.Abs(base.User, inst.DeployDir())
900+
tlsDir := filepath.Join(deployDir, spec.TLSCertKeyDir)
901+
902+
needSessionCert := hasTiProxy && inst.ComponentName() == spec.ComponentTiDB
903+
if needSessionCert || topo.BaseTopo().GlobalOptions.TLSEnabled {
857904
tb := task.NewSimpleUerSSH(m.logger, inst.GetManageHost(), inst.GetSSHPort(), base.User, gOpt, p, topo.BaseTopo().GlobalOptions.SSHType).
858905
Mkdir(base.User, inst.GetManageHost(), topo.BaseTopo().GlobalOptions.SystemdMode != spec.UserMode, deployDir, tlsDir)
859906

860-
ca, err := crypto.ReadCA(
861-
name,
862-
m.specManager.Path(name, spec.TLSCertKeyDir, spec.TLSCACert),
863-
m.specManager.Path(name, spec.TLSCertKeyDir, spec.TLSCAKey),
864-
)
865-
if err != nil {
866-
iterErr = err
867-
return
907+
if needSessionCert {
908+
tb = tb.
909+
CopyFile(filepath.Join(m.specManager.Path(name, spec.TempConfigPath), "tiproxy-session.key"), filepath.Join(deployDir, spec.TLSCertKeyDir, "tiproxy-session.key"), inst.GetHost(), false, 0, false).
910+
CopyFile(filepath.Join(m.specManager.Path(name, spec.TempConfigPath), "tiproxy-session.crt"), filepath.Join(deployDir, spec.TLSCertKeyDir, "tiproxy-session.crt"), inst.GetHost(), false, 0, false)
868911
}
869-
t := tb.TLSCert(
870-
inst.GetHost(),
871-
inst.ComponentName(),
872-
inst.Role(),
873-
inst.GetMainPort(),
874-
ca,
875-
meta.DirPaths{
876-
Deploy: deployDir,
877-
Cache: m.specManager.Path(name, spec.TempConfigPath),
878-
}).
879-
BuildAsStep(fmt.Sprintf(" - Generate certificate %s -> %s", inst.ComponentName(), inst.ID()))
912+
913+
if topo.BaseTopo().GlobalOptions.TLSEnabled {
914+
ca, err := crypto.ReadCA(
915+
name,
916+
m.specManager.Path(name, spec.TLSCertKeyDir, spec.TLSCACert),
917+
m.specManager.Path(name, spec.TLSCertKeyDir, spec.TLSCAKey),
918+
)
919+
if err != nil {
920+
iterErr = err
921+
return
922+
}
923+
tb = tb.TLSCert(
924+
inst.GetHost(),
925+
inst.ComponentName(),
926+
inst.Role(),
927+
inst.GetMainPort(),
928+
ca,
929+
meta.DirPaths{
930+
Deploy: deployDir,
931+
Cache: m.specManager.Path(name, spec.TempConfigPath),
932+
})
933+
}
934+
935+
t := tb.BuildAsStep(fmt.Sprintf(" - Generate certificate %s -> %s", inst.ComponentName(), inst.ID()))
880936
certificateTasks = append(certificateTasks, t)
881-
})
882-
}
937+
}
938+
})
883939
return certificateTasks, iterErr
884940
}

pkg/cluster/spec/tidb.go

+38
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,11 @@ func (i *TiDBInstance) InitConfig(
241241
}
242242
}
243243

244+
spec.Config, err = i.setTiProxyConfig(ctx, topo, spec.Config, paths)
245+
if err != nil {
246+
return err
247+
}
248+
244249
// set TLS configs
245250
spec.Config, err = i.setTLSConfig(ctx, enableTLS, spec.Config, paths)
246251
if err != nil {
@@ -254,6 +259,39 @@ func (i *TiDBInstance) InitConfig(
254259
return checkConfig(ctx, e, i.ComponentName(), i.ComponentSource(), version, i.OS(), i.Arch(), i.ComponentName()+".toml", paths)
255260
}
256261

262+
// setTiProxyConfig sets tiproxy session certs
263+
func (i *TiDBInstance) setTiProxyConfig(ctx context.Context, topo *Specification, configs map[string]any, paths meta.DirPaths) (map[string]any, error) {
264+
hasTiProxy := false
265+
topo.IterInstance(func(instance Instance) {
266+
if instance.ComponentName() == ComponentTiProxy {
267+
hasTiProxy = true
268+
}
269+
})
270+
271+
if hasTiProxy {
272+
if configs == nil {
273+
configs = make(map[string]any)
274+
}
275+
configs["security.session-token-signing-cert"] = fmt.Sprintf(
276+
"%s/tls/tiproxy-session.crt",
277+
paths.Deploy)
278+
configs["security.session-token-signing-key"] = fmt.Sprintf(
279+
"%s/tls/tiproxy-session.key",
280+
paths.Deploy)
281+
} else {
282+
tlsConfigs := []string{
283+
"security.session-token-signing-cert",
284+
"security.session-token-signing-key",
285+
}
286+
if configs != nil {
287+
for _, config := range tlsConfigs {
288+
delete(configs, config)
289+
}
290+
}
291+
}
292+
return configs, nil
293+
}
294+
257295
// setTLSConfig set TLS Config to support enable/disable TLS
258296
func (i *TiDBInstance) setTLSConfig(ctx context.Context, enableTLS bool, configs map[string]any, paths meta.DirPaths) (map[string]any, error) {
259297
// set TLS configs

0 commit comments

Comments
 (0)