Allow adding optional Client CA files
This commit is contained in:
parent
1691f586d7
commit
4f4491c247
12 changed files with 97 additions and 25 deletions
|
@ -52,7 +52,10 @@ func TestDo_globalConfiguration(t *testing.T) {
|
||||||
{CertFile: "CertFile 1", KeyFile: "KeyFile 1"},
|
{CertFile: "CertFile 1", KeyFile: "KeyFile 1"},
|
||||||
{CertFile: "CertFile 2", KeyFile: "KeyFile 2"},
|
{CertFile: "CertFile 2", KeyFile: "KeyFile 2"},
|
||||||
},
|
},
|
||||||
ClientCAFiles: []string{"foo ClientCAFiles 1", "foo ClientCAFiles 2", "foo ClientCAFiles 3"},
|
ClientCA: traefikTls.ClientCA{
|
||||||
|
Files: []string{"foo ClientCAFiles 1", "foo ClientCAFiles 2", "foo ClientCAFiles 3"},
|
||||||
|
Optional: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Redirect: &configuration.Redirect{
|
Redirect: &configuration.Redirect{
|
||||||
Replacement: "foo Replacement",
|
Replacement: "foo Replacement",
|
||||||
|
@ -95,7 +98,10 @@ func TestDo_globalConfiguration(t *testing.T) {
|
||||||
{CertFile: "CertFile 1", KeyFile: "KeyFile 1"},
|
{CertFile: "CertFile 1", KeyFile: "KeyFile 1"},
|
||||||
{CertFile: "CertFile 2", KeyFile: "KeyFile 2"},
|
{CertFile: "CertFile 2", KeyFile: "KeyFile 2"},
|
||||||
},
|
},
|
||||||
ClientCAFiles: []string{"fii ClientCAFiles 1", "fii ClientCAFiles 2", "fii ClientCAFiles 3"},
|
ClientCA: traefikTls.ClientCA{
|
||||||
|
Files: []string{"fii ClientCAFiles 1", "fii ClientCAFiles 2", "fii ClientCAFiles 3"},
|
||||||
|
Optional: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Redirect: &configuration.Redirect{
|
Redirect: &configuration.Redirect{
|
||||||
Replacement: "fii Replacement",
|
Replacement: "fii Replacement",
|
||||||
|
|
|
@ -308,7 +308,11 @@ func (ep *EntryPoints) Set(value string) error {
|
||||||
}
|
}
|
||||||
if len(result["ca"]) > 0 {
|
if len(result["ca"]) > 0 {
|
||||||
files := strings.Split(result["ca"], ",")
|
files := strings.Split(result["ca"], ",")
|
||||||
configTLS.ClientCAFiles = files
|
optional := toBool(result, "ca_optional")
|
||||||
|
configTLS.ClientCA = tls.ClientCA{
|
||||||
|
Files: files,
|
||||||
|
Optional: optional,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var redirect *Redirect
|
var redirect *Redirect
|
||||||
if len(result["redirect_entrypoint"]) > 0 || len(result["redirect_regex"]) > 0 || len(result["redirect_replacement"]) > 0 {
|
if len(result["redirect_entrypoint"]) > 0 || len(result["redirect_regex"]) > 0 || len(result["redirect_replacement"]) > 0 {
|
||||||
|
|
|
@ -134,7 +134,7 @@ func TestEntryPoints_Set(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "all parameters camelcase",
|
name: "all parameters camelcase",
|
||||||
expression: "Name:foo Address::8000 TLS:goo,gii TLS CA:car Redirect.EntryPoint:RedirectEntryPoint Redirect.Regex:RedirectRegex Redirect.Replacement:RedirectReplacement Compress:true WhiteListSourceRange:Range ProxyProtocol.TrustedIPs:192.168.0.1 ForwardedHeaders.TrustedIPs:10.0.0.3/24,20.0.0.3/24",
|
expression: "Name:foo Address::8000 TLS:goo,gii TLS CA:car CA.Optional:false Redirect.EntryPoint:RedirectEntryPoint Redirect.Regex:RedirectRegex Redirect.Replacement:RedirectReplacement Compress:true WhiteListSourceRange:Range ProxyProtocol.TrustedIPs:192.168.0.1 ForwardedHeaders.TrustedIPs:10.0.0.3/24,20.0.0.3/24",
|
||||||
expectedEntryPointName: "foo",
|
expectedEntryPointName: "foo",
|
||||||
expectedEntryPoint: &EntryPoint{
|
expectedEntryPoint: &EntryPoint{
|
||||||
Address: ":8000",
|
Address: ":8000",
|
||||||
|
@ -152,7 +152,10 @@ func TestEntryPoints_Set(t *testing.T) {
|
||||||
},
|
},
|
||||||
WhitelistSourceRange: []string{"Range"},
|
WhitelistSourceRange: []string{"Range"},
|
||||||
TLS: &tls.TLS{
|
TLS: &tls.TLS{
|
||||||
ClientCAFiles: []string{"car"},
|
ClientCA: tls.ClientCA{
|
||||||
|
Files: []string{"car"},
|
||||||
|
Optional: false,
|
||||||
|
},
|
||||||
Certificates: tls.Certificates{
|
Certificates: tls.Certificates{
|
||||||
{
|
{
|
||||||
CertFile: tls.FileOrContent("goo"),
|
CertFile: tls.FileOrContent("goo"),
|
||||||
|
@ -164,7 +167,7 @@ func TestEntryPoints_Set(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "all parameters lowercase",
|
name: "all parameters lowercase",
|
||||||
expression: "name:foo address::8000 tls:goo,gii tls ca:car redirect.entryPoint:RedirectEntryPoint redirect.regex:RedirectRegex redirect.replacement:RedirectReplacement compress:true whiteListSourceRange:Range proxyProtocol.trustedIPs:192.168.0.1 forwardedHeaders.trustedIPs:10.0.0.3/24,20.0.0.3/24",
|
expression: "name:foo address::8000 tls:goo,gii tls ca:car ca.optional:true redirect.entryPoint:RedirectEntryPoint redirect.regex:RedirectRegex redirect.replacement:RedirectReplacement compress:true whiteListSourceRange:Range proxyProtocol.trustedIPs:192.168.0.1 forwardedHeaders.trustedIPs:10.0.0.3/24,20.0.0.3/24",
|
||||||
expectedEntryPointName: "foo",
|
expectedEntryPointName: "foo",
|
||||||
expectedEntryPoint: &EntryPoint{
|
expectedEntryPoint: &EntryPoint{
|
||||||
Address: ":8000",
|
Address: ":8000",
|
||||||
|
@ -182,7 +185,10 @@ func TestEntryPoints_Set(t *testing.T) {
|
||||||
},
|
},
|
||||||
WhitelistSourceRange: []string{"Range"},
|
WhitelistSourceRange: []string{"Range"},
|
||||||
TLS: &tls.TLS{
|
TLS: &tls.TLS{
|
||||||
ClientCAFiles: []string{"car"},
|
ClientCA: tls.ClientCA{
|
||||||
|
Files: []string{"car"},
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
Certificates: tls.Certificates{
|
Certificates: tls.Certificates{
|
||||||
{
|
{
|
||||||
CertFile: tls.FileOrContent("goo"),
|
CertFile: tls.FileOrContent("goo"),
|
||||||
|
|
|
@ -62,10 +62,13 @@ And here is another example with client certificate authentication:
|
||||||
[entryPoints.https]
|
[entryPoints.https]
|
||||||
address = ":443"
|
address = ":443"
|
||||||
[entryPoints.https.tls]
|
[entryPoints.https.tls]
|
||||||
clientCAFiles = ["tests/clientca1.crt", "tests/clientca2.crt"]
|
[entryPoints.https.tls]
|
||||||
[[entryPoints.https.tls.certificates]]
|
[entryPoints.https.tls.ClientCA]
|
||||||
certFile = "tests/traefik.crt"
|
files = ["tests/clientca1.crt", "tests/clientca2.crt"]
|
||||||
keyFile = "tests/traefik.key"
|
optional = false
|
||||||
|
[[entryPoints.https.tls.certificates]]
|
||||||
|
certFile = "tests/traefik.crt"
|
||||||
|
keyFile = "tests/traefik.key"
|
||||||
```
|
```
|
||||||
|
|
||||||
- We enable SSL on `https` by giving a certificate and a key.
|
- We enable SSL on `https` by giving a certificate and a key.
|
||||||
|
|
|
@ -72,11 +72,13 @@ Define an entrypoint with SNI support.
|
||||||
|
|
||||||
## TLS Mutual Authentication
|
## TLS Mutual Authentication
|
||||||
|
|
||||||
Only accept clients that present a certificate signed by a specified Certificate Authority (CA).
|
TLS Mutual Authentication can be `optional` or not.
|
||||||
|
If it's `optional`, Træfik will authorize connection with certificates not signed by a specified Certificate Authority (CA).
|
||||||
|
Otherwise, Træfik will only accept clients that present a certificate signed by a specified Certificate Authority (CA).
|
||||||
`ClientCAFiles` can be configured with multiple `CA:s` in the same file or use multiple files containing one or several `CA:s`.
|
`ClientCAFiles` can be configured with multiple `CA:s` in the same file or use multiple files containing one or several `CA:s`.
|
||||||
The `CA:s` has to be in PEM format.
|
The `CA:s` has to be in PEM format.
|
||||||
|
|
||||||
All clients will be required to present a valid cert.
|
By default, `ClientCAFiles` is not optional, all clients will be required to present a valid cert.
|
||||||
The requirement will apply to all server certs in the entrypoint.
|
The requirement will apply to all server certs in the entrypoint.
|
||||||
|
|
||||||
In the example below both `snitest.com` and `snitest.org` will require client certs
|
In the example below both `snitest.com` and `snitest.org` will require client certs
|
||||||
|
@ -86,7 +88,9 @@ In the example below both `snitest.com` and `snitest.org` will require client ce
|
||||||
[entryPoints.https]
|
[entryPoints.https]
|
||||||
address = ":443"
|
address = ":443"
|
||||||
[entryPoints.https.tls]
|
[entryPoints.https.tls]
|
||||||
ClientCAFiles = ["tests/clientca1.crt", "tests/clientca2.crt"]
|
[entryPoints.https.tls.ClientCA]
|
||||||
|
files = ["tests/clientca1.crt", "tests/clientca2.crt"]
|
||||||
|
optional = false
|
||||||
[[entryPoints.https.tls.certificates]]
|
[[entryPoints.https.tls.certificates]]
|
||||||
certFile = "integration/fixtures/https/snitest.com.cert"
|
certFile = "integration/fixtures/https/snitest.com.cert"
|
||||||
keyFile = "integration/fixtures/https/snitest.com.key"
|
keyFile = "integration/fixtures/https/snitest.com.key"
|
||||||
|
@ -95,6 +99,11 @@ In the example below both `snitest.com` and `snitest.org` will require client ce
|
||||||
keyFile = "integration/fixtures/https/snitest.org.key"
|
keyFile = "integration/fixtures/https/snitest.org.key"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
|
||||||
|
The deprecated argument `ClientCAFiles` allows adding Client CA files which are mandatory.
|
||||||
|
If this parameter exists, the new ones are not checked.
|
||||||
|
|
||||||
## Authentication
|
## Authentication
|
||||||
|
|
||||||
### Basic Authentication
|
### Basic Authentication
|
||||||
|
|
|
@ -6,7 +6,9 @@ defaultEntryPoints = ["https"]
|
||||||
[entryPoints.https]
|
[entryPoints.https]
|
||||||
address = ":4443"
|
address = ":4443"
|
||||||
[entryPoints.https.tls]
|
[entryPoints.https.tls]
|
||||||
ClientCAFiles = ["fixtures/https/clientca/ca1.crt"]
|
[entryPoints.https.tls.ClientCA]
|
||||||
|
files = ["fixtures/https/clientca/ca1.crt"]
|
||||||
|
optional = true
|
||||||
[[entryPoints.https.tls.certificates]]
|
[[entryPoints.https.tls.certificates]]
|
||||||
certFile = "fixtures/https/snitest.com.cert"
|
certFile = "fixtures/https/snitest.com.cert"
|
||||||
keyFile = "fixtures/https/snitest.com.key"
|
keyFile = "fixtures/https/snitest.com.key"
|
||||||
|
|
|
@ -6,7 +6,8 @@ defaultEntryPoints = ["https"]
|
||||||
[entryPoints.https]
|
[entryPoints.https]
|
||||||
address = ":4443"
|
address = ":4443"
|
||||||
[entryPoints.https.tls]
|
[entryPoints.https.tls]
|
||||||
ClientCAFiles = ["fixtures/https/clientca/ca1and2.crt"]
|
[entryPoints.https.tls.ClientCA]
|
||||||
|
files = ["fixtures/https/clientca/ca1and2.crt"]
|
||||||
[[entryPoints.https.tls.certificates]]
|
[[entryPoints.https.tls.certificates]]
|
||||||
certFile = "fixtures/https/snitest.com.cert"
|
certFile = "fixtures/https/snitest.com.cert"
|
||||||
keyFile = "fixtures/https/snitest.com.key"
|
keyFile = "fixtures/https/snitest.com.key"
|
||||||
|
|
|
@ -6,7 +6,9 @@ defaultEntryPoints = ["https"]
|
||||||
[entryPoints.https]
|
[entryPoints.https]
|
||||||
address = ":4443"
|
address = ":4443"
|
||||||
[entryPoints.https.tls]
|
[entryPoints.https.tls]
|
||||||
ClientCAFiles = ["fixtures/https/clientca/ca1.crt", "fixtures/https/clientca/ca2.crt"]
|
[entryPoints.https.tls.ClientCA]
|
||||||
|
files = ["fixtures/https/clientca/ca1.crt", "fixtures/https/clientca/ca2.crt"]
|
||||||
|
optional = false
|
||||||
[[entryPoints.https.tls.certificates]]
|
[[entryPoints.https.tls.certificates]]
|
||||||
certFile = "fixtures/https/snitest.com.cert"
|
certFile = "fixtures/https/snitest.com.cert"
|
||||||
keyFile = "fixtures/https/snitest.com.key"
|
keyFile = "fixtures/https/snitest.com.key"
|
||||||
|
|
|
@ -116,7 +116,7 @@ func (s *HTTPSSuite) TestWithSNIConfigRoute(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestWithClientCertificateAuthentication
|
// TestWithClientCertificateAuthentication
|
||||||
// The client has to send a certificate signed by a CA trusted by the server
|
// The client can send a certificate signed by a CA trusted by the server but it's optional
|
||||||
func (s *HTTPSSuite) TestWithClientCertificateAuthentication(c *check.C) {
|
func (s *HTTPSSuite) TestWithClientCertificateAuthentication(c *check.C) {
|
||||||
cmd, display := s.traefikCmd(withConfigFile("fixtures/https/clientca/https_1ca1config.toml"))
|
cmd, display := s.traefikCmd(withConfigFile("fixtures/https/clientca/https_1ca1config.toml"))
|
||||||
defer display(c)
|
defer display(c)
|
||||||
|
@ -135,7 +135,7 @@ func (s *HTTPSSuite) TestWithClientCertificateAuthentication(c *check.C) {
|
||||||
}
|
}
|
||||||
// Connection without client certificate should fail
|
// Connection without client certificate should fail
|
||||||
_, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
|
_, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
|
||||||
c.Assert(err, checker.NotNil, check.Commentf("should not be allowed to connect to server"))
|
c.Assert(err, checker.IsNil, check.Commentf("should be allowed to connect to server"))
|
||||||
|
|
||||||
// Connect with client certificate signed by ca1
|
// Connect with client certificate signed by ca1
|
||||||
cert, err := tls.LoadX509KeyPair("fixtures/https/clientca/client1.crt", "fixtures/https/clientca/client1.key")
|
cert, err := tls.LoadX509KeyPair("fixtures/https/clientca/client1.crt", "fixtures/https/clientca/client1.key")
|
||||||
|
@ -147,6 +147,16 @@ func (s *HTTPSSuite) TestWithClientCertificateAuthentication(c *check.C) {
|
||||||
|
|
||||||
conn.Close()
|
conn.Close()
|
||||||
|
|
||||||
|
// Connect with client certificate not signed by ca1
|
||||||
|
cert, err = tls.LoadX509KeyPair("fixtures/https/snitest.org.cert", "fixtures/https/snitest.org.key")
|
||||||
|
c.Assert(err, checker.IsNil, check.Commentf("unable to load client certificate and key"))
|
||||||
|
tlsConfig.Certificates = append(tlsConfig.Certificates, cert)
|
||||||
|
|
||||||
|
conn, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
|
||||||
|
c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))
|
||||||
|
|
||||||
|
conn.Close()
|
||||||
|
|
||||||
// Connect with client signed by ca2 should fail
|
// Connect with client signed by ca2 should fail
|
||||||
tlsConfig = &tls.Config{
|
tlsConfig = &tls.Config{
|
||||||
InsecureSkipVerify: true,
|
InsecureSkipVerify: true,
|
||||||
|
@ -158,8 +168,7 @@ func (s *HTTPSSuite) TestWithClientCertificateAuthentication(c *check.C) {
|
||||||
tlsConfig.Certificates = append(tlsConfig.Certificates, cert)
|
tlsConfig.Certificates = append(tlsConfig.Certificates, cert)
|
||||||
|
|
||||||
_, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
|
_, err = tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
|
||||||
c.Assert(err, checker.NotNil, check.Commentf("should not be allowed to connect to server"))
|
c.Assert(err, checker.IsNil, check.Commentf("should be allowed to connect to server"))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestWithClientCertificateAuthentication
|
// TestWithClientCertificateAuthentication
|
||||||
|
|
|
@ -574,8 +574,13 @@ func createClientTLSConfig(entryPointName string, tlsOption *traefikTls.TLS) (*t
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(tlsOption.ClientCAFiles) > 0 {
|
if len(tlsOption.ClientCAFiles) > 0 {
|
||||||
|
log.Warnf("Deprecated configuration found during client TLS configuration creation: %s. Please use %s (which allows to make the CA Files optional).", "tls.ClientCAFiles", "tls.ClientCA.files")
|
||||||
|
tlsOption.ClientCA.Files = tlsOption.ClientCAFiles
|
||||||
|
tlsOption.ClientCA.Optional = false
|
||||||
|
}
|
||||||
|
if len(tlsOption.ClientCA.Files) > 0 {
|
||||||
pool := x509.NewCertPool()
|
pool := x509.NewCertPool()
|
||||||
for _, caFile := range tlsOption.ClientCAFiles {
|
for _, caFile := range tlsOption.ClientCA.Files {
|
||||||
data, err := ioutil.ReadFile(caFile)
|
data, err := ioutil.ReadFile(caFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -611,8 +616,13 @@ func (server *Server) createTLSConfig(entryPointName string, tlsOption *traefikT
|
||||||
config.NextProtos = []string{"h2", "http/1.1"}
|
config.NextProtos = []string{"h2", "http/1.1"}
|
||||||
|
|
||||||
if len(tlsOption.ClientCAFiles) > 0 {
|
if len(tlsOption.ClientCAFiles) > 0 {
|
||||||
|
log.Warnf("Deprecated configuration found during TLS configuration creation: %s. Please use %s (which allows to make the CA Files optional).", "tls.ClientCAFiles", "tls.ClientCA.files")
|
||||||
|
tlsOption.ClientCA.Files = tlsOption.ClientCAFiles
|
||||||
|
tlsOption.ClientCA.Optional = false
|
||||||
|
}
|
||||||
|
if len(tlsOption.ClientCA.Files) > 0 {
|
||||||
pool := x509.NewCertPool()
|
pool := x509.NewCertPool()
|
||||||
for _, caFile := range tlsOption.ClientCAFiles {
|
for _, caFile := range tlsOption.ClientCA.Files {
|
||||||
data, err := ioutil.ReadFile(caFile)
|
data, err := ioutil.ReadFile(caFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -623,7 +633,11 @@ func (server *Server) createTLSConfig(entryPointName string, tlsOption *traefikT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
config.ClientCAs = pool
|
config.ClientCAs = pool
|
||||||
config.ClientAuth = tls.RequireAndVerifyClientCert
|
if tlsOption.ClientCA.Optional {
|
||||||
|
config.ClientAuth = tls.VerifyClientCertIfGiven
|
||||||
|
} else {
|
||||||
|
config.ClientAuth = tls.RequireAndVerifyClientCert
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if server.globalConfiguration.ACME != nil {
|
if server.globalConfiguration.ACME != nil {
|
||||||
|
|
10
tls/tls.go
10
tls/tls.go
|
@ -6,12 +6,20 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ClientCA defines traefik CA files for a entryPoint
|
||||||
|
// and it indicates if they are mandatory or have just to be analyzed if provided
|
||||||
|
type ClientCA struct {
|
||||||
|
Files []string
|
||||||
|
Optional bool
|
||||||
|
}
|
||||||
|
|
||||||
// TLS configures TLS for an entry point
|
// TLS configures TLS for an entry point
|
||||||
type TLS struct {
|
type TLS struct {
|
||||||
MinVersion string `export:"true"`
|
MinVersion string `export:"true"`
|
||||||
CipherSuites []string
|
CipherSuites []string
|
||||||
Certificates Certificates
|
Certificates Certificates
|
||||||
ClientCAFiles []string
|
ClientCAFiles []string // Deprecated
|
||||||
|
ClientCA ClientCA
|
||||||
}
|
}
|
||||||
|
|
||||||
// RootCAs hold the CA we want to have in root
|
// RootCAs hold the CA we want to have in root
|
||||||
|
|
|
@ -445,6 +445,7 @@ type AccessLog struct {
|
||||||
// CA, Cert and Key can be either path or file contents
|
// CA, Cert and Key can be either path or file contents
|
||||||
type ClientTLS struct {
|
type ClientTLS struct {
|
||||||
CA string `description:"TLS CA"`
|
CA string `description:"TLS CA"`
|
||||||
|
CAOptional bool `description:"TLS CA.Optional"`
|
||||||
Cert string `description:"TLS cert"`
|
Cert string `description:"TLS cert"`
|
||||||
Key string `description:"TLS key"`
|
Key string `description:"TLS key"`
|
||||||
InsecureSkipVerify bool `description:"TLS insecure skip verify"`
|
InsecureSkipVerify bool `description:"TLS insecure skip verify"`
|
||||||
|
@ -458,6 +459,7 @@ func (clientTLS *ClientTLS) CreateTLSConfig() (*tls.Config, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
caPool := x509.NewCertPool()
|
caPool := x509.NewCertPool()
|
||||||
|
clientAuth := tls.NoClientCert
|
||||||
if clientTLS.CA != "" {
|
if clientTLS.CA != "" {
|
||||||
var ca []byte
|
var ca []byte
|
||||||
if _, errCA := os.Stat(clientTLS.CA); errCA == nil {
|
if _, errCA := os.Stat(clientTLS.CA); errCA == nil {
|
||||||
|
@ -469,6 +471,11 @@ func (clientTLS *ClientTLS) CreateTLSConfig() (*tls.Config, error) {
|
||||||
ca = []byte(clientTLS.CA)
|
ca = []byte(clientTLS.CA)
|
||||||
}
|
}
|
||||||
caPool.AppendCertsFromPEM(ca)
|
caPool.AppendCertsFromPEM(ca)
|
||||||
|
if clientTLS.CAOptional {
|
||||||
|
clientAuth = tls.VerifyClientCertIfGiven
|
||||||
|
} else {
|
||||||
|
clientAuth = tls.RequireAndVerifyClientCert
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cert := tls.Certificate{}
|
cert := tls.Certificate{}
|
||||||
|
@ -505,6 +512,7 @@ func (clientTLS *ClientTLS) CreateTLSConfig() (*tls.Config, error) {
|
||||||
Certificates: []tls.Certificate{cert},
|
Certificates: []tls.Certificate{cert},
|
||||||
RootCAs: caPool,
|
RootCAs: caPool,
|
||||||
InsecureSkipVerify: clientTLS.InsecureSkipVerify,
|
InsecureSkipVerify: clientTLS.InsecureSkipVerify,
|
||||||
|
ClientAuth: clientAuth,
|
||||||
}
|
}
|
||||||
return TLSConfig, nil
|
return TLSConfig, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue