Support TLS based auth for routes

Similar as with clients, this makes it possible to
use the subject from a TLS certificate to validate
the permissions from a cluster member.

Currently only a single configured user is supported:

```
cluster {
  tls {
    cert_file = "./configs/certs/tlsauth/server.pem"
    key_file = "./configs/certs/tlsauth/server-key.pem"
    ca_file = "./configs/certs/tlsauth/ca.pem"
    verify_and_map = true
    timeout = 2
  }

  permissions {
    publish {
  	allow = ["public.>"]
    }
    subscribe {
  	allow = ["public.>"]
    }
  }

  authorization {
    user = "CN=localhost,OU=NATS.io Operators"
  }
}
```

Signed-off-by: Waldemar Quevedo <wally@synadia.com>
This commit is contained in:
Waldemar Quevedo
2019-02-18 08:51:51 -08:00
parent 01016a2105
commit 01057467cf
13 changed files with 393 additions and 141 deletions

View File

@@ -252,7 +252,8 @@ func (s *Server) isClientAuthorized(c *client) bool {
tlsMap := s.opts.TLSMap
s.optsMu.RUnlock()
// Check custom auth first, then jwts, then nkeys, then multiple users, then token, then single user/pass.
// Check custom auth first, then jwts, then nkeys, then
// multiple users, then token, then single user/pass.
if customClientAuthentication != nil {
return customClientAuthentication.Check(c)
}
@@ -469,6 +470,8 @@ func (s *Server) isRouterAuthorized(c *client) bool {
// Snapshot server options.
opts := s.getOpts()
// Check custom auth first, then TLS map if enabled
// then single user/pass.
if s.opts.CustomRouterAuthentication != nil {
return s.opts.CustomRouterAuthentication.Check(c)
}
@@ -477,6 +480,41 @@ func (s *Server) isRouterAuthorized(c *client) bool {
return true
}
if opts.Cluster.TLSMap {
// Verify the cert
tlsState := c.GetTLSConnectionState()
if tlsState == nil {
c.Debugf("User required in cert, no TLS connection state")
return false
}
if len(tlsState.PeerCertificates) == 0 {
c.Debugf("User required in cert, no peer certificates found")
return false
}
cert := tlsState.PeerCertificates[0]
if len(tlsState.PeerCertificates) > 1 {
c.Debugf("Multiple peer certificates found, selecting first")
}
hasEmailAddresses := len(cert.EmailAddresses) > 0
hasSubject := len(cert.Subject.String()) > 0
if !hasEmailAddresses && !hasSubject {
c.Debugf("User required in cert, none found")
return false
}
var euser string
if hasEmailAddresses {
euser = cert.EmailAddresses[0]
if len(cert.EmailAddresses) > 1 {
c.Debugf("Multiple users found in cert, selecting first [%q]", euser)
}
} else {
euser = cert.Subject.String()
}
return opts.Cluster.Username == euser
}
if opts.Cluster.Username != c.opts.Username {
return false
}

View File

@@ -44,6 +44,7 @@ type ClusterOpts struct {
Permissions *RoutePermissions `json:"-"`
TLSTimeout float64 `json:"-"`
TLSConfig *tls.Config `json:"-"`
TLSMap bool `json:"-"`
ListenStr string `json:"-"`
Advertise string `json:"-"`
NoAdvertise bool `json:"-"`
@@ -749,13 +750,14 @@ func parseCluster(v interface{}, opts *Options, errors *[]error, warnings *[]err
}
opts.Routes = routes
case "tls":
config, timeout, err := getTLSConfig(tk)
config, tlsopts, err := getTLSConfig(tk)
if err != nil {
*errors = append(*errors, err)
continue
}
opts.Cluster.TLSConfig = config
opts.Cluster.TLSTimeout = timeout
opts.Cluster.TLSTimeout = tlsopts.Timeout
opts.Cluster.TLSMap = tlsopts.Map
case "cluster_advertise", "advertise":
opts.Cluster.Advertise = mv.(string)
case "no_advertise":
@@ -854,13 +856,13 @@ func parseGateway(v interface{}, o *Options, errors *[]error, warnings *[]error)
o.Gateway.Password = auth.pass
o.Gateway.AuthTimeout = auth.timeout
case "tls":
config, timeout, err := getTLSConfig(tk)
config, tlsopts, err := getTLSConfig(tk)
if err != nil {
*errors = append(*errors, err)
continue
}
o.Gateway.TLSConfig = config
o.Gateway.TLSTimeout = timeout
o.Gateway.TLSTimeout = tlsopts.Timeout
case "advertise":
o.Gateway.Advertise = mv.(string)
case "connect_retries":
@@ -891,22 +893,22 @@ func parseGateway(v interface{}, o *Options, errors *[]error, warnings *[]error)
// Parse TLS and returns a TLSConfig and TLSTimeout.
// Used by cluster and gateway parsing.
func getTLSConfig(tk token) (*tls.Config, float64, error) {
func getTLSConfig(tk token) (*tls.Config, *TLSConfigOpts, error) {
tc, err := parseTLS(tk)
if err != nil {
return nil, 0, err
return nil, nil, err
}
config, err := GenTLSConfig(tc)
if err != nil {
err := &configErr{tk, err.Error()}
return nil, 0, err
return nil, nil, err
}
// For clusters/gateways, we will force strict verification. We also act
// as both client and server, so will mirror the rootCA to the
// clientCA pool.
config.ClientAuth = tls.RequireAndVerifyClientCert
config.RootCAs = config.ClientCAs
return config, tc.Timeout, nil
return config, tc, nil
}
func parseGateways(v interface{}, errors *[]error, warnings *[]error) ([]*RemoteGatewayOpts, error) {
@@ -932,13 +934,13 @@ func parseGateways(v interface{}, errors *[]error, warnings *[]error) ([]*Remote
case "name":
gateway.Name = v.(string)
case "tls":
tls, timeout, err := getTLSConfig(tk)
tls, tlsopts, err := getTLSConfig(tk)
if err != nil {
*errors = append(*errors, err)
continue
}
gateway.TLSConfig = tls
gateway.TLSTimeout = timeout
gateway.TLSTimeout = tlsopts.Timeout
case "url":
url, err := parseURL(v.(string), "gateway")
if err != nil {

View File

@@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@@ -1,21 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDhjCCAm6gAwIBAgIUfLE3jBpwGplOUDcpbxIsvRInDGQwDQYJKoZIhvcNAQEL
MIIDhjCCAm6gAwIBAgIUOpzkAYCyt3JSkWfE5EdY9r5SSA4wDQYJKoZIhvcNAQEL
BQAwTDEkMCIGA1UEChMbU3luYWRpYSBDb21tdW5pY2F0aW9ucyBJbmMuMRAwDgYD
VQQLEwdOQVRTLmlvMRIwEAYDVQQDEwlsb2NhbGhvc3QwHhcNMTkwMjA0MTk1MTAw
WhcNMjQwMjAzMTk1MTAwWjAoMRAwDgYDVQQLEwdOQVRTLmlvMRQwEgYDVQQDEwtl
eGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK+UC1WN
BXnhDvpj0A0hmUmnpdXDtHHwAcMO6+XzZMRUYqSS9OLjirD9+fXRqPwMvDFktppQ
KKF9Y0QNvGFoITY4GcL9OW25nENnBqPf+001isbrJMx2IGC3PVjW4CZ0hjXHspEM
SIJyOEv6Rfn8aaCW8Uzru9bb4pMuUgD/dyFPCaXweGiKUqNCnwNMA6WrmA9aK461
2OyTLy/zUSy2L5E7yWjHrhAFrlt1GnAldcH0/daEFhQWhbqbGrTU9FDyfnjK3xtB
oOnDPW31PmTWUTkDjkdIADPVw+JJ7jmELL3SlqxJLjfGwagjzoQiGGArVGp+tO6Y
bUKCAbsMsaxJEiUCAwEAAaOBgzCBgDAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAww
CgYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUa1+2h/uPRLo1o6Ee
qOTA1hKmUlcwHwYDVR0jBBgwFoAUbwbb4b9Hyi/JdmgKO0hyj272GsswCwYDVR0R
BAQwAoIAMA0GCSqGSIb3DQEBCwUAA4IBAQBr50msBYEhIMj6b8QoBAbvdBhE9TeF
76k4PZpGVF6EoGVdyTXvO0LBNT7BFysIVgy51Bv5kyz7z9B6iOwnnTDhZIj0kGMA
KPkgyMHHRlL9iOXC/fCuf9dfBuq7u2oykILCI8VY6yzTvHtIWg0/wk6/2e13WmtU
nkI9ySxJGzaZJaVjV7UWkzzR1anwJ6Q0IaRohIByWcE43uIzNi1sA1U8cZ70C43t
JNSXp9mBodV2jLCM3bU9jpSyz8thH3ghogioG8obYSS22a+Ei4SRsmHK1B2fu6Uh
z8UJCtjq5lbVlPgZQlmIHAJaq/cK8nSccv/2KBHx5hOR8rIqwsAL6p46
VQQLEwdOQVRTLmlvMRIwEAYDVQQDEwlsb2NhbGhvc3QwHhcNMTkwMjE4MTgwMDAw
WhcNMjQwMjE3MTgwMDAwWjAoMRAwDgYDVQQLEwdOQVRTLmlvMRQwEgYDVQQDEwtl
eGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANNzCxjH
N2kVjIxis3S/jZ3FMAg54hFpeUeaHxX9rl+dmUFvIAl77xRVqe8nuUMm6UcWQkZC
2fmvB3urXc7vdLN/1LEHEF8dmNCJAxRNouRNVWclUdVJS5cjyUDjVzN7XjNG/2uk
5ovkFasehRflkX2Oh5466EliOXQ1wgVEXIubEvVleylYFGsn66ZHsrDiW0xi9S0t
1EFolcKIlRiFiLr7PT8BKDZzzS4Ac+/W01HOYFs5CmzRjRhqVzTPwNzNw+/f8Hqo
wO2y7CeuRy7aHzeLLUTuBSq7lkJDysAhL3W1oAKmSTOs75cMLAe8yccgXpvOx6YU
MfZc9KWMOeRQWUMCAwEAAaOBgzCBgDAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAww
CgYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUpDFefmusbDTjF/ja
m0gpSu0h5mswHwYDVR0jBBgwFoAUbwbb4b9Hyi/JdmgKO0hyj272GsswCwYDVR0R
BAQwAoIAMA0GCSqGSIb3DQEBCwUAA4IBAQDNHF80dmkqe6IR9wUj8nITd0EkMUuQ
7IcQQP9eY3rlO7QAT8alEpJsfRcLWjxGKTJQRrcFG8I8iY35aM2tHUyS/cODlc5f
XdKKFyFGpF8CmZMzEX7jNK4m3TQ7JVZUiNX5EBmn8EsmoHFjBk72dP1xY7yxY0PG
13mfsQmDY8FH6IMjtb21iR/Z3ucOAOd4mnv4iJDzHnHBX/sf+pst+1uXHIsv4NgO
cmSTrV37VzXsaPWRqxeDatvUzaUqBCmtcrCAhyrhCzolf51Sgnc62Cv/YuJ32L4L
R2c7wcPwhin0sdvCPo3P1uxGuUhFEYcEcX4+QzDZbS6iJ94lnTHA8UYt
-----END CERTIFICATE-----

View File

@@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@@ -1,21 +1,21 @@
-----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE-----

View File

@@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA330XGNotGWellHcjsr2O8rL51Htvk6wtJAep8wsPL7KtZYqe
0GL6No3WSw/JVTaIf27e45tBTLSPrVk0qGzkBAXxpy6ywdWmVL2NhoZ5E0jeABTb
Ud3Lj6zL+ggM+BQq2xJh85fytSNJ9nEcPBHzbwGB6baKpE84872qQ2jH8vXzdEHI
kWseJGItJ5JAcXGBQ0DqpUTUhI9Nww+EWjOYbiFZg2cy8ZMgOwReEgioQrwrN5i1
PPeIpRKk23cQjeDa50J6uQjj6rcAO8PcQLjB4VCuSo4y4RSCLK4N5JZm01oOndLZ
Viyo14Rk87zNfQVKAlBm+wGfoYfbPNCu2oDUDwIDAQABAoIBAQCKW8n509CJ4tXq
pRuPo7Uk4dKzTjvUY4qKvMflNJqRQAADVh9eCXi4X3UkgUB2pc05f20z4cE6eKpe
elSUVN2Q9BEYHFwEjn1sBvHgL84zNzBhQohJFZPZffPF9kf5KZsihy3m/dH/fDpk
/L+rHL3lojxIcX9Bm945X9lR5EOtUJhkZ2xJI37VHNN1iWvNcNwls/Ud+lwsxndt
Pj8tjPZ1e0ypMSJllgKi8X4+JBIfcOL7v5OmNwOx5YMuUYDRWT35I3Tz/M12o0BB
nrrDBeTRXq/netqBWEa15id4g7xSGvZQKoNOpqDjtQZU851DRQniM1hqjTZR9qj+
Pdj3/41RAoGBAOH+OBNogdvlADW4lUCcbF0cKktNwsv4hsRFyRUs3Yz91ESLhCc8
KKRdqTO1SB3wdt8Q+Dxfsdorjf51CX1hjTk7lHL8v0GhU3zjOsanACd0pDMQK1lv
fQVKvZHZms5UZD0G27l6yS/Dxg7fkDUkTcR1n0t4cJqpjP0OKU+mkyMZAoGBAP0p
vkP7D4ICO2el023xK14SR1I4RbgEO9h3+IbdWsOjhioB/WjvWsWBJYa5ihFYCaGN
x3nEl1J8xCy6ADjbtvSYcgTWKjcsABY6adlwmoBE/UlwFrr0VA5+qJCyRK/zJMjr
Y5pICmC2rV6T+C+jpEOGNd06fN+lbNHfcAXKTv1nAoGAe2Cxto7Qjn9IDQwXl62O
T4rn4DK0zWyCDrdWn1PeJHITJ9TPMihau9lSXaNzmrzD+OYnz7Yiv8wVejzlEGlo
kz1evyQTOj5b+QuI9BkKMYAxgJssP2hpZbE3K2AUbt6N1u9el7VcDtKf11DgRtLq
Df51F9vKBfXYvfK0RQLYw0kCgYBioanEGINBNpdoWT3XXpdzzhFFYjEfcV7ThmIo
QQNEp2f049OT13T478jsBUtaWH9gFrm5ojMGax+PAWRmwos0HlSFt964ogbioh1t
HqbDBJ3dx7LDYb+B6izIOvvxxPv232ZtzFVmuqUu7N1LyiiMOjSwHUJba7rKxY+C
YgCGTwKBgFLUxkEDszCMPKQRb2G7rt/D5Hat7gsBvkYifa8wPA57v20johtKDlGF
lo1AolMCsebwS9IwwMO5taenJrWVNnw+YeHkr9E7sHoOlxRWjJImxs30cGJAEdQg
xMANEnpb8OQd4t47dpBgMh5KXqgQqg3kGPO55ZJlb1wfQ1HqWLii
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDhTCCAm2gAwIBAgIUbXHf4iAemXfIpLSWpRMkEVsdjy8wDQYJKoZIhvcNAQEL
BQAwTDEkMCIGA1UEChMbU3luYWRpYSBDb21tdW5pY2F0aW9ucyBJbmMuMRAwDgYD
VQQLEwdOQVRTLmlvMRIwEAYDVQQDEwlsb2NhbGhvc3QwHhcNMTkwMjE4MjE0MjAw
WhcNMjQwMjE3MjE0MjAwWjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDffRcY2i0ZZ6WUdyOyvY7ysvnUe2+TrC0k
B6nzCw8vsq1lip7QYvo2jdZLD8lVNoh/bt7jm0FMtI+tWTSobOQEBfGnLrLB1aZU
vY2GhnkTSN4AFNtR3cuPrMv6CAz4FCrbEmHzl/K1I0n2cRw8EfNvAYHptoqkTzjz
vapDaMfy9fN0QciRax4kYi0nkkBxcYFDQOqlRNSEj03DD4RaM5huIVmDZzLxkyA7
BF4SCKhCvCs3mLU894ilEqTbdxCN4NrnQnq5COPqtwA7w9xAuMHhUK5KjjLhFIIs
rg3klmbTWg6d0tlWLKjXhGTzvM19BUoCUGb7AZ+hh9s80K7agNQPAgMBAAGjgZYw
gZMwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD
AjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSubJojZMv2Ithfumfx12lAhWyaSjAf
BgNVHSMEGDAWgBRvBtvhv0fKL8l2aAo7SHKPbvYayzAUBgNVHREEDTALgglsb2Nh
bGhvc3QwDQYJKoZIhvcNAQELBQADggEBACGDpZ9oxuuCB8ujf7YXMPw7Ae1WH7DL
pBtPNL99bnPLQd/6iv12TWBFal5xSTCxhN/exAqDEk36zCKIEk2LvY/VJHP8Y2si
A79PqrlzSptOxeEuQRZnk+FiWYLwelkvL66TnpUW3QwdCCj/vodabDlaq6eSMEF+
+kwxWZUixYkWASwuPSd7xjgNNBvIjeGvZIZvyjgTwyzPx/hSEMET68lRAoeE1S7S
IHqLPp/UwvvI9qMzBzkOz/XOmptB2fG3a5BLefEErcjVqfqYNAAA5V58+pyRrCSO
nX8UaSmy42aHryV0eelTLIxFSeSOHycpEhY2Hxq75JG8eSNfRd9rSt8=
-----END CERTIFICATE-----

View File

@@ -1,22 +1,22 @@
-----BEGIN CERTIFICATE-----
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
j4uv6u+kCJxABz3EyggU4BEPEPNL
-----END CERTIFICATE-----

View File

@@ -0,0 +1,23 @@
cluster {
tls {
cert_file = "./configs/certs/tlsauth/server.pem"
key_file = "./configs/certs/tlsauth/server-key.pem"
ca_file = "./configs/certs/tlsauth/ca.pem"
verify_and_map = true
timeout = 2
}
permissions {
publish {
allow = ["public.>"]
}
subscribe {
allow = ["public.>"]
}
}
authorization {
user = "CN=localhost,OU=NATS.io Operators"
}
}

View File

@@ -0,0 +1,25 @@
cluster {
tls {
cert_file = "./configs/certs/tlsauth/server-no-ou.pem"
key_file = "./configs/certs/tlsauth/server-no-ou-key.pem"
ca_file = "./configs/certs/tlsauth/ca.pem"
verify_and_map = true
timeout = 2
}
no_advertise = true
permissions {
publish {
allow = ["public.>"]
}
subscribe {
allow = ["public.>"]
}
}
authorization {
user = "CN=localhost"
}
}

View File

@@ -20,6 +20,7 @@ import (
"fmt"
"io/ioutil"
"net"
"net/url"
"os"
"strings"
"sync"
@@ -209,6 +210,121 @@ func TestTLSClientCertificateCNBasedAuth(t *testing.T) {
}
}
func TestTLSRoutesCertificateCNBasedAuth(t *testing.T) {
// Base config for the servers
optsA := LoadConfig("./configs/tls_cert_cn_routes.conf")
optsB := LoadConfig("./configs/tls_cert_cn_routes.conf")
optsC := LoadConfig("./configs/tls_cert_cn_routes_invalid_auth.conf")
// TLS map should have been enabled
if !optsA.Cluster.TLSMap || !optsB.Cluster.TLSMap || !optsC.Cluster.TLSMap {
t.Error("Expected Cluster TLS verify and map feature to be activated")
}
routeA, err := url.Parse("nats://localhost:9935")
if err != nil {
t.Fatal(err)
}
routeB, err := url.Parse("nats://localhost:9936")
if err != nil {
t.Fatal(err)
}
routeC, err := url.Parse("nats://localhost:9937")
if err != nil {
t.Fatal(err)
}
routes := make([]*url.URL, 3)
routes[0] = routeA
routes[1] = routeB
routes[2] = routeC
optsA.Host = "127.0.0.1"
optsA.Port = 9335
optsA.Cluster.Host = optsA.Host
optsA.Cluster.Port = 9935
optsA.Routes = routes
srvA := RunServer(optsA)
defer srvA.Shutdown()
optsB.Host = "127.0.0.1"
optsB.Port = 9336
optsB.Cluster.Host = optsB.Host
optsB.Cluster.Port = 9936
optsB.Routes = routes
srvB := RunServer(optsB)
defer srvB.Shutdown()
optsC.Host = "127.0.0.1"
optsC.Port = 9337
optsC.Cluster.Host = optsC.Host
optsC.Cluster.Port = 9937
optsC.Routes = routes
srvC := RunServer(optsC)
defer srvC.Shutdown()
nc1, err := nats.Connect(fmt.Sprintf("%s:%d", optsA.Host, optsA.Port), nats.Name("A"))
if err != nil {
t.Fatalf("Expected to connect, got %v", err)
}
defer nc1.Close()
nc2, err := nats.Connect(fmt.Sprintf("%s:%d", optsB.Host, optsB.Port), nats.Name("B"))
if err != nil {
t.Fatalf("Expected to connect, got %v", err)
}
defer nc2.Close()
// This client is partitioned from rest of cluster due to using wrong cert.
nc3, err := nats.Connect(fmt.Sprintf("%s:%d", optsC.Host, optsC.Port), nats.Name("C"))
if err != nil {
t.Fatalf("Expected to connect, got %v", err)
}
defer nc3.Close()
// Allowed via permissions to broadcast to other members of cluster.
publicSub, err := nc1.SubscribeSync("public.>")
if err != nil {
t.Fatal(err)
}
// Not part of cluster permissions so message is not forwarded.
privateSub, err := nc1.SubscribeSync("private.>")
if err != nil {
t.Fatal(err)
}
nc1.Flush()
// Not forwarded by cluster so won't be received.
err = nc2.Publish("private.foo", []byte("private message on server B"))
if err != nil {
t.Fatal(err)
}
err = nc2.Publish("public.foo", []byte("public message from server B to server A"))
if err != nil {
t.Fatal(err)
}
nc2.Flush()
err = nc3.Publish("public.foo", []byte("dropped message since unauthorized server"))
if err != nil {
t.Fatal(err)
}
nc3.Flush()
// Message will be received since allowed via permissions
_, err = publicSub.NextMsg(1 * time.Second)
if err != nil {
t.Fatalf("Error during wait for next message: %s", err)
}
msg, err := privateSub.NextMsg(500 * time.Millisecond)
if err == nil {
t.Errorf("Received unexpected message from private sub: %+v", msg)
}
msg, err = publicSub.NextMsg(500 * time.Millisecond)
if err == nil {
t.Errorf("Received unexpected message from private sub: %+v", msg)
}
}
func TestTLSVerifyClientCertificate(t *testing.T) {
srv, opts := RunServerWithConfig("./configs/tlsverify_noca.conf")
defer srv.Shutdown()