Fix TLS listener

The TLS listener was not being set up correctly. The TLSConfig was changed
to include only cert and key. The cert now needs to be a full chain bundle
including intermediary CA certificates. The ca_cert config option was removed.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
This commit is contained in:
Gabriel Adrian Samfira 2023-01-31 13:42:39 +00:00
parent 1ad52e87ef
commit 27a523f133
7 changed files with 54 additions and 194 deletions

View file

@ -433,45 +433,18 @@ func (m *MySQL) ConnectionString() (string, error) {
// TLSConfig is the API server TLS config
type TLSConfig struct {
CRT string `toml:"certificate" json:"certificate"`
Key string `toml:"key" json:"key"`
CACert string `toml:"ca_certificate" json:"ca-certificate"`
}
// TLSConfig returns a new TLSConfig suitable for use in the
// API server
func (t *TLSConfig) TLSConfig() (*tls.Config, error) {
// TLS config not present.
if t.CRT == "" || t.Key == "" {
return nil, fmt.Errorf("missing crt or key")
}
var roots *x509.CertPool
if t.CACert != "" {
caCertPEM, err := os.ReadFile(t.CACert)
if err != nil {
return nil, err
}
roots = x509.NewCertPool()
ok := roots.AppendCertsFromPEM(caCertPEM)
if !ok {
return nil, fmt.Errorf("failed to parse CA cert")
}
}
cert, err := tls.LoadX509KeyPair(t.CRT, t.Key)
if err != nil {
return nil, err
}
return &tls.Config{
Certificates: []tls.Certificate{cert},
ClientCAs: roots,
}, nil
CRT string `toml:"certificate" json:"certificate"`
Key string `toml:"key" json:"key"`
}
// Validate validates the TLS config
func (t *TLSConfig) Validate() error {
if _, err := t.TLSConfig(); err != nil {
if t.CRT == "" || t.Key == "" {
return fmt.Errorf("missing crt or key")
}
_, err := tls.LoadX509KeyPair(t.CRT, t.Key)
if err != nil {
return err
}
return nil
@ -492,14 +465,6 @@ type APIServer struct {
CORSOrigins []string `toml:"cors_origins" json:"cors-origins"`
}
func (a *APIServer) APITLSConfig() (*tls.Config, error) {
if !a.UseTLS {
return nil, nil
}
return a.TLSConfig.TLSConfig()
}
// BindAddress returns a host:port string.
func (a *APIServer) BindAddress() string {
return fmt.Sprintf("%s:%d", a.Bind, a.Port)

View file

@ -39,9 +39,8 @@ func getDefaultSectionConfig(configDir string) Default {
func getDefaultTLSConfig() TLSConfig {
return TLSConfig{
CRT: "../testdata/certs/srv-pub.pem",
Key: "../testdata/certs/srv-key.pem",
CACert: "../testdata/certs/ca-pub.pem",
CRT: "../testdata/certs/srv-pub.pem",
Key: "../testdata/certs/srv-key.pem",
}
}
@ -293,120 +292,6 @@ func TestAPIBindAddress(t *testing.T) {
require.Equal(t, cfg.BindAddress(), "0.0.0.0:9998")
}
func TestAPITLSconfig(t *testing.T) {
cfg := getDefaultAPIServerConfig()
err := cfg.Validate()
require.Nil(t, err)
tlsCfg, err := cfg.APITLSConfig()
require.Nil(t, err)
require.NotNil(t, tlsCfg)
// Any error in the TLSConfig should return an error here.
cfg.TLSConfig = TLSConfig{}
tlsCfg, err = cfg.APITLSConfig()
require.Nil(t, tlsCfg)
require.NotNil(t, err)
require.EqualError(t, err, "missing crt or key")
// If TLS is disabled, don't validate TLSconfig.
cfg.UseTLS = false
tlsCfg, err = cfg.APITLSConfig()
require.Nil(t, err)
require.Nil(t, tlsCfg)
}
func TestTLSConfig(t *testing.T) {
dir, err := os.MkdirTemp("", "garm-config-test")
if err != nil {
t.Fatalf("failed to create temporary directory: %s", err)
}
t.Cleanup(func() { os.RemoveAll(dir) })
invalidCert := filepath.Join(dir, "invalid_cert.pem")
err = os.WriteFile(invalidCert, []byte("bogus content"), 0755)
if err != nil {
t.Fatalf("failed to write file: %s", err)
}
cfg := getDefaultTLSConfig()
err = cfg.Validate()
require.Nil(t, err)
tests := []struct {
name string
cfg TLSConfig
errString string
}{
{
name: "Config is valid",
cfg: cfg,
errString: "",
},
{
name: "missing crt",
cfg: TLSConfig{
CRT: "",
Key: cfg.Key,
CACert: cfg.CACert,
},
errString: "missing crt or key",
},
{
name: "missing key",
cfg: TLSConfig{
CRT: cfg.CRT,
Key: "",
CACert: cfg.CACert,
},
errString: "missing crt or key",
},
{
name: "invalid CA cert",
cfg: TLSConfig{
CRT: cfg.CRT,
Key: cfg.Key,
CACert: invalidCert,
},
errString: "failed to parse CA cert",
},
{
name: "invalid cert",
cfg: TLSConfig{
CRT: invalidCert,
Key: cfg.Key,
CACert: cfg.CACert,
},
errString: "tls: failed to find any PEM data in certificate input",
},
{
name: "invalid key",
cfg: TLSConfig{
CRT: cfg.CRT,
Key: invalidCert,
CACert: cfg.CACert,
},
errString: "tls: failed to find any PEM data in key input",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
tlsCfg, err := tc.cfg.TLSConfig()
if tc.errString == "" {
require.Nil(t, err)
require.NotNil(t, tlsCfg)
} else {
require.NotNil(t, err)
require.Nil(t, tlsCfg)
require.Regexp(t, tc.errString, err.Error())
}
})
}
}
func TestDatabaseConfig(t *testing.T) {
dir, err := os.MkdirTemp("", "garm-config-test")
if err != nil {