github.com/crowdsecurity/crowdsec@v1.6.1/pkg/csconfig/tls.go (about) 1 package csconfig 2 3 import ( 4 "crypto/tls" 5 "crypto/x509" 6 "fmt" 7 "os" 8 "time" 9 10 log "github.com/sirupsen/logrus" 11 ) 12 13 type TLSCfg struct { 14 CertFilePath string `yaml:"cert_file"` 15 KeyFilePath string `yaml:"key_file"` 16 ClientVerification string `yaml:"client_verification,omitempty"` 17 ServerName string `yaml:"server_name"` 18 CACertPath string `yaml:"ca_cert_path"` 19 AllowedAgentsOU []string `yaml:"agents_allowed_ou"` 20 AllowedBouncersOU []string `yaml:"bouncers_allowed_ou"` 21 CRLPath string `yaml:"crl_path"` 22 CacheExpiration *time.Duration `yaml:"cache_expiration,omitempty"` 23 } 24 25 func (t *TLSCfg) GetAuthType() (tls.ClientAuthType, error) { 26 if t.ClientVerification == "" { 27 // sounds like a sane default: verify client cert if given, but don't make it mandatory 28 return tls.VerifyClientCertIfGiven, nil 29 } 30 31 switch t.ClientVerification { 32 case "NoClientCert": 33 return tls.NoClientCert, nil 34 case "RequestClientCert": 35 log.Warn("RequestClientCert is insecure, please use VerifyClientCertIfGiven or RequireAndVerifyClientCert instead") 36 return tls.RequestClientCert, nil 37 case "RequireAnyClientCert": 38 log.Warn("RequireAnyClientCert is insecure, please use VerifyClientCertIfGiven or RequireAndVerifyClientCert instead") 39 return tls.RequireAnyClientCert, nil 40 case "VerifyClientCertIfGiven": 41 return tls.VerifyClientCertIfGiven, nil 42 case "RequireAndVerifyClientCert": 43 return tls.RequireAndVerifyClientCert, nil 44 default: 45 return 0, fmt.Errorf("unknown TLS client_verification value: %s", t.ClientVerification) 46 } 47 } 48 49 func (t *TLSCfg) GetTLSConfig() (*tls.Config, error) { 50 if t == nil { 51 return &tls.Config{}, nil 52 } 53 54 clientAuthType, err := t.GetAuthType() 55 if err != nil { 56 return nil, err 57 } 58 59 caCertPool, err := x509.SystemCertPool() 60 if err != nil { 61 log.Warnf("Error loading system CA certificates: %s", err) 62 } 63 64 if caCertPool == nil { 65 caCertPool = x509.NewCertPool() 66 } 67 68 // the > condition below is a weird way to say "if a client certificate is required" 69 // see https://pkg.go.dev/crypto/tls#ClientAuthType 70 if clientAuthType > tls.RequestClientCert && t.CACertPath != "" { 71 log.Infof("(tls) Client Auth Type set to %s", clientAuthType.String()) 72 73 caCert, err := os.ReadFile(t.CACertPath) 74 if err != nil { 75 return nil, fmt.Errorf("while opening cert file: %w", err) 76 } 77 78 caCertPool.AppendCertsFromPEM(caCert) 79 } 80 81 return &tls.Config{ 82 ServerName: t.ServerName, //should it be removed ? 83 ClientAuth: clientAuthType, 84 ClientCAs: caCertPool, 85 MinVersion: tls.VersionTLS12, // TLS versions below 1.2 are considered insecure - see https://www.rfc-editor.org/rfc/rfc7525.txt for details 86 }, nil 87 }