mirror of
https://github.com/gogrlx/nats-server.git
synced 2026-04-15 18:50:41 -07:00
Merge pull request #412 from nats-io/tls-curve-pref
Add curve preference option to configuration files
This commit is contained in:
@@ -2,6 +2,7 @@ language: go
|
||||
go:
|
||||
- 1.6.4
|
||||
- 1.7.4
|
||||
- 1.8beta2
|
||||
install:
|
||||
- go get github.com/nats-io/go-nats
|
||||
- go get github.com/mattn/goveralls
|
||||
@@ -17,4 +18,4 @@ script:
|
||||
- staticcheck -ignore "$(cat staticcheck.ignore)" $EXCLUDE_VENDOR
|
||||
after_success:
|
||||
- if [[ "$TRAVIS_GO_VERSION" == 1.7.* ]]; then ./scripts/cov.sh TRAVIS; fi
|
||||
- if [[ "$TRAVIS_GO_VERSION" == 1.7.* ]] && [ "$TRAVIS_TAG" != "" ]; then ./scripts/cross_compile.sh $TRAVIS_TAG; ghr --owner nats-io --token $GITHUB_TOKEN --draft --replace $TRAVIS_TAG pkg/; fi
|
||||
- if [[ "$TRAVIS_GO_VERSION" == 1.7.* ]] && [ "$TRAVIS_TAG" != "" ]; then ./scripts/cross_compile.sh $TRAVIS_TAG; ghr --owner nats-io --token $GITHUB_TOKEN --draft --replace $TRAVIS_TAG pkg/; fi
|
||||
|
||||
14
README.md
14
README.md
@@ -478,7 +478,7 @@ Note that `_INBOX.*` subscribe permissions must be granted in order to use the r
|
||||
### TLS
|
||||
|
||||
As of Release 0.7.0, the server can use modern TLS semantics for client connections, route connections, and the HTTPS monitoring port.
|
||||
The server requires TLS version 1.2, and sets preferences for modern cipher suites that avoid those known with vunerabilities. The
|
||||
The server requires TLS version 1.2, and sets preferences for modern cipher suites that avoid those known with vulnerabilities. The
|
||||
server's preferences when building with Go1.5 are as follows.
|
||||
|
||||
```go
|
||||
@@ -492,7 +492,17 @@ func defaultCipherSuites() []uint16 {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The curve preferences are also re-ordered to provide the most secure
|
||||
environment available, and are as follows:
|
||||
```go
|
||||
func defaultCurvePreferences() []tls.CurveID {
|
||||
return []tls.CurveID{
|
||||
tls.CurveP521,
|
||||
tls.CurveP384,
|
||||
tls.CurveP256,
|
||||
}
|
||||
}
|
||||
```
|
||||
Generating self signed certs and intermediary certificate authorities is beyond the scope here, but this document can be helpful in addition to Google Search: <a href="https://docs.docker.com/engine/articles/https/" target="_blank">https://docs.docker.com/engine/articles/https/</a>.
|
||||
|
||||
The server **requires** a certificate and private key. Optionally the server can require that clients need to present certificates, and the server can be configured with a CA authority to verify the client certificates.
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright 2015 Apcera Inc. All rights reserved.
|
||||
|
||||
// +build go1.4,!go1.5
|
||||
|
||||
package server
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
)
|
||||
|
||||
// Where we maintain all of the available 1.4 ciphers
|
||||
var cipherMap = map[string]uint16{
|
||||
"TLS_RSA_WITH_RC4_128_SHA": tls.TLS_RSA_WITH_RC4_128_SHA,
|
||||
"TLS_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
"TLS_RSA_WITH_AES_128_CBC_SHA": tls.TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
"TLS_RSA_WITH_AES_256_CBC_SHA": tls.TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
||||
"TLS_ECDHE_RSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
|
||||
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
}
|
||||
|
||||
func defaultCipherSuites() []uint16 {
|
||||
return []uint16{
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright 2015 Apcera Inc. All rights reserved.
|
||||
// Copyright 2016 Apcera Inc. All rights reserved.
|
||||
|
||||
// +build go1.5
|
||||
// +build go1.5,!go1.8
|
||||
|
||||
package server
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"crypto/tls"
|
||||
)
|
||||
|
||||
// Where we maintain all of the available 1.5 ciphers
|
||||
// Where we maintain all of the available ciphers
|
||||
var cipherMap = map[string]uint16{
|
||||
"TLS_RSA_WITH_RC4_128_SHA": tls.TLS_RSA_WITH_RC4_128_SHA,
|
||||
"TLS_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
@@ -29,10 +29,27 @@ var cipherMap = map[string]uint16{
|
||||
|
||||
func defaultCipherSuites() []uint16 {
|
||||
return []uint16{
|
||||
// The SHA384 versions are only in Go1.5
|
||||
// The SHA384 versions are only in Go1.5 and beyond
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
}
|
||||
}
|
||||
|
||||
// Where we maintain available curve preferences
|
||||
var curvePreferenceMap = map[string]tls.CurveID{
|
||||
"CurveP256": tls.CurveP256,
|
||||
"CurveP384": tls.CurveP384,
|
||||
"CurveP521": tls.CurveP521,
|
||||
}
|
||||
|
||||
// reorder to default to the highest level of security. See:
|
||||
// https://blog.bracebin.com/achieving-perfect-ssl-labs-score-with-go
|
||||
func defaultCurvePreferences() []tls.CurveID {
|
||||
return []tls.CurveID{
|
||||
tls.CurveP521,
|
||||
tls.CurveP384,
|
||||
tls.CurveP256,
|
||||
}
|
||||
}
|
||||
|
||||
62
server/ciphersuites_1.8.go
Normal file
62
server/ciphersuites_1.8.go
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright 2016 Apcera Inc. All rights reserved.
|
||||
|
||||
// +build go1.8
|
||||
|
||||
package server
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
)
|
||||
|
||||
// Where we maintain all of the available ciphers
|
||||
var cipherMap = map[string]uint16{
|
||||
"TLS_RSA_WITH_RC4_128_SHA": tls.TLS_RSA_WITH_RC4_128_SHA,
|
||||
"TLS_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
"TLS_RSA_WITH_AES_128_CBC_SHA": tls.TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
"TLS_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_RSA_WITH_AES_128_CBC_SHA256,
|
||||
"TLS_RSA_WITH_AES_256_CBC_SHA": tls.TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
"TLS_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
|
||||
"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
||||
"TLS_ECDHE_RSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
|
||||
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
|
||||
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305": tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
|
||||
}
|
||||
|
||||
func defaultCipherSuites() []uint16 {
|
||||
return []uint16{
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
}
|
||||
}
|
||||
|
||||
// Where we maintain available curve preferences
|
||||
var curvePreferenceMap = map[string]tls.CurveID{
|
||||
"CurveP256": tls.CurveP256,
|
||||
"CurveP384": tls.CurveP384,
|
||||
"CurveP521": tls.CurveP521,
|
||||
"X25519": tls.X25519,
|
||||
}
|
||||
|
||||
// reorder to default to the highest level of security. See:
|
||||
// https://blog.bracebin.com/achieving-perfect-ssl-labs-score-with-go
|
||||
func defaultCurvePreferences() []tls.CurveID {
|
||||
return []tls.CurveID{
|
||||
tls.CurveP521,
|
||||
tls.CurveP384,
|
||||
tls.X25519, // faster than P256, arguably more secure
|
||||
tls.CurveP256,
|
||||
}
|
||||
}
|
||||
13
server/configs/tls_bad_curve_prefs.conf
Normal file
13
server/configs/tls_bad_curve_prefs.conf
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
# Simple TLS config file
|
||||
|
||||
listen: localhost:4443
|
||||
|
||||
tls {
|
||||
cert_file: "./configs/certs/server.pem"
|
||||
key_file: "./configs/certs/key.pem"
|
||||
timeout: 2
|
||||
curve_preferences: [
|
||||
"GARBAGE"
|
||||
]
|
||||
}
|
||||
13
server/configs/tls_curve_prefs.conf
Normal file
13
server/configs/tls_curve_prefs.conf
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
# Simple TLS config file
|
||||
|
||||
listen: localhost:4443
|
||||
|
||||
tls {
|
||||
cert_file: "./configs/certs/server.pem"
|
||||
key_file: "./configs/certs/key.pem"
|
||||
timeout: 2
|
||||
curve_preferences: [
|
||||
"CurveP256"
|
||||
]
|
||||
}
|
||||
12
server/configs/tls_empty_curve_prefs.conf
Normal file
12
server/configs/tls_empty_curve_prefs.conf
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
# Simple TLS config file
|
||||
|
||||
listen: localhost:4443
|
||||
|
||||
tls {
|
||||
cert_file: "./configs/certs/server.pem"
|
||||
key_file: "./configs/certs/key.pem"
|
||||
timeout: 2
|
||||
curve_preferences: [
|
||||
]
|
||||
}
|
||||
@@ -98,12 +98,13 @@ type authorization struct {
|
||||
// TLSConfigOpts holds the parsed tls config information,
|
||||
// used with flag parsing
|
||||
type TLSConfigOpts struct {
|
||||
CertFile string
|
||||
KeyFile string
|
||||
CaFile string
|
||||
Verify bool
|
||||
Timeout float64
|
||||
Ciphers []uint16
|
||||
CertFile string
|
||||
KeyFile string
|
||||
CaFile string
|
||||
Verify bool
|
||||
Timeout float64
|
||||
Ciphers []uint16
|
||||
CurvePreferences []tls.CurveID
|
||||
}
|
||||
|
||||
var tlsUsage = `
|
||||
@@ -121,6 +122,11 @@ e.g.
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
|
||||
]
|
||||
curve_preferences: [
|
||||
"CurveP256",
|
||||
"CurveP384",
|
||||
"CurveP521"
|
||||
]
|
||||
}
|
||||
|
||||
Available cipher suites include:
|
||||
@@ -471,11 +477,14 @@ func checkSubjectArray(sa []string) ([]string, error) {
|
||||
|
||||
// PrintTLSHelpAndDie prints TLS usage and exits.
|
||||
func PrintTLSHelpAndDie() {
|
||||
fmt.Printf("%s\n", tlsUsage)
|
||||
fmt.Printf("%s", tlsUsage)
|
||||
for k := range cipherMap {
|
||||
fmt.Printf(" %s\n", k)
|
||||
}
|
||||
fmt.Printf("\n")
|
||||
fmt.Printf("\nAvailable curve preferences include:\n")
|
||||
for k := range curvePreferenceMap {
|
||||
fmt.Printf(" %s\n", k)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
@@ -489,6 +498,14 @@ func parseCipher(cipherName string) (uint16, error) {
|
||||
return cipher, nil
|
||||
}
|
||||
|
||||
func parseCurvePreferences(curveName string) (tls.CurveID, error) {
|
||||
curve, exists := curvePreferenceMap[curveName]
|
||||
if !exists {
|
||||
return 0, fmt.Errorf("Unrecognized curve preference %s", curveName)
|
||||
}
|
||||
return curve, nil
|
||||
}
|
||||
|
||||
// Helper function to parse TLS configs.
|
||||
func parseTLS(tlsm map[string]interface{}) (*TLSConfigOpts, error) {
|
||||
tc := TLSConfigOpts{}
|
||||
@@ -531,6 +548,19 @@ func parseTLS(tlsm map[string]interface{}) (*TLSConfigOpts, error) {
|
||||
}
|
||||
tc.Ciphers = append(tc.Ciphers, cipher)
|
||||
}
|
||||
case "curve_preferences":
|
||||
ra := mv.([]interface{})
|
||||
if len(ra) == 0 {
|
||||
return nil, fmt.Errorf("error parsing tls config, 'curve_preferences' cannot be empty")
|
||||
}
|
||||
tc.CurvePreferences = make([]tls.CurveID, 0, len(ra))
|
||||
for _, r := range ra {
|
||||
cps, err := parseCurvePreferences(r.(string))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tc.CurvePreferences = append(tc.CurvePreferences, cps)
|
||||
}
|
||||
case "timeout":
|
||||
at := float64(0)
|
||||
switch mv.(type) {
|
||||
@@ -550,6 +580,11 @@ func parseTLS(tlsm map[string]interface{}) (*TLSConfigOpts, error) {
|
||||
tc.Ciphers = defaultCipherSuites()
|
||||
}
|
||||
|
||||
// If curve preferences were not specified, then use the defaults
|
||||
if tc.CurvePreferences == nil {
|
||||
tc.CurvePreferences = defaultCurvePreferences()
|
||||
}
|
||||
|
||||
return &tc, nil
|
||||
}
|
||||
|
||||
@@ -569,6 +604,7 @@ func GenTLSConfig(tc *TLSConfigOpts) (*tls.Config, error) {
|
||||
// Create TLSConfig
|
||||
// We will determine the cipher suites that we prefer.
|
||||
config := tls.Config{
|
||||
CurvePreferences: tc.CurvePreferences,
|
||||
Certificates: []tls.Certificate{cert},
|
||||
PreferServerCipherSuites: true,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
|
||||
@@ -159,13 +159,49 @@ func TestTLSConfigFile(t *testing.T) {
|
||||
// Test an unrecognized/bad cipher
|
||||
opts, err = ProcessConfigFile("./configs/tls_bad_cipher.conf")
|
||||
if err == nil {
|
||||
t.Fatalf("Did not receive an error from a unrecognized cipher.")
|
||||
t.Fatal("Did not receive an error from a unrecognized cipher.")
|
||||
}
|
||||
|
||||
// Test an empty cipher entry in a config file.
|
||||
opts, err = ProcessConfigFile("./configs/tls_empty_cipher.conf")
|
||||
if err == nil {
|
||||
t.Fatalf("Did not receive an error from empty cipher_suites.")
|
||||
t.Fatal("Did not receive an error from empty cipher_suites.")
|
||||
}
|
||||
|
||||
// Test a curve preference from the config.
|
||||
curves := []tls.CurveID{
|
||||
tls.CurveP256,
|
||||
}
|
||||
|
||||
// test on a file that will load the curve preference defaults
|
||||
opts, err = ProcessConfigFile("./configs/tls_ciphers.conf")
|
||||
if err != nil {
|
||||
t.Fatalf("Received an error reading config file: %v\n", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(opts.TLSConfig.CurvePreferences, defaultCurvePreferences()) {
|
||||
t.Fatalf("Got incorrect curve preference list: [%+v]", tlsConfig.CurvePreferences)
|
||||
}
|
||||
|
||||
// Test specifying a single curve preference
|
||||
opts, err = ProcessConfigFile("./configs/tls_curve_prefs.conf")
|
||||
if err != nil {
|
||||
t.Fatal("Did not receive an error from a unrecognized cipher.")
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(opts.TLSConfig.CurvePreferences, curves) {
|
||||
t.Fatalf("Got incorrect cipher suite list: [%+v]", tlsConfig.CurvePreferences)
|
||||
}
|
||||
|
||||
// Test an unrecognized/bad curve preference
|
||||
opts, err = ProcessConfigFile("./configs/tls_bad_curve_prefs.conf")
|
||||
if err == nil {
|
||||
t.Fatal("Did not receive an error from a unrecognized curve preference.")
|
||||
}
|
||||
// Test an empty curve preference
|
||||
opts, err = ProcessConfigFile("./configs/tls_empty_curve_prefs.conf")
|
||||
if err == nil {
|
||||
t.Fatal("Did not receive an error from empty curve preferences.")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
24
test/configs/tls_curve_pref.conf
Normal file
24
test/configs/tls_curve_pref.conf
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
# Simple TLS config file
|
||||
|
||||
listen: localhost:4443
|
||||
|
||||
https: 11522
|
||||
|
||||
tls {
|
||||
# Server cert
|
||||
cert_file: "./configs/certs/server-cert.pem"
|
||||
# Server private key
|
||||
key_file: "./configs/certs/server-key.pem"
|
||||
# Specified time for handshake to complete
|
||||
timeout: 2
|
||||
curve_preferences: [
|
||||
"CurveP256"
|
||||
]
|
||||
}
|
||||
|
||||
authorization {
|
||||
user: derek
|
||||
password: boo
|
||||
timeout: 1
|
||||
}
|
||||
@@ -251,3 +251,47 @@ func TestTLSBadAuthError(t *testing.T) {
|
||||
t.Fatalf("Excpected and auth violation, got %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTLSConnectionCurvePref(t *testing.T) {
|
||||
srv, opts := RunServerWithConfig("./configs/tls_curve_pref.conf")
|
||||
defer srv.Shutdown()
|
||||
|
||||
if len(opts.TLSConfig.CurvePreferences) != 1 {
|
||||
t.Fatal("Invalid curve preference loaded.")
|
||||
}
|
||||
|
||||
if opts.TLSConfig.CurvePreferences[0] != tls.CurveP256 {
|
||||
t.Fatalf("Invalid curve preference loaded [%v].", opts.TLSConfig.CurvePreferences[0])
|
||||
}
|
||||
|
||||
endpoint := fmt.Sprintf("%s:%d", opts.Host, opts.Port)
|
||||
nurl := fmt.Sprintf("tls://%s:%s@%s/", opts.Username, opts.Password, endpoint)
|
||||
nc, err := nats.Connect(nurl)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected error trying to connect to secure server")
|
||||
}
|
||||
|
||||
// Do simple SecureConnect
|
||||
nc, err = nats.Connect(fmt.Sprintf("tls://%s/", endpoint))
|
||||
if err == nil {
|
||||
t.Fatalf("Expected error trying to connect to secure server with no auth")
|
||||
}
|
||||
|
||||
// Now do more advanced checking, verifying servername and using rootCA.
|
||||
|
||||
nc, err = nats.Connect(nurl, nats.RootCAs("./configs/certs/ca.pem"))
|
||||
if err != nil {
|
||||
t.Fatalf("Got an error on Connect with Secure Options: %+v\n", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
subj := "foo-tls"
|
||||
sub, _ := nc.SubscribeSync(subj)
|
||||
|
||||
nc.Publish(subj, []byte("We are Secure!"))
|
||||
nc.Flush()
|
||||
nmsgs, _ := sub.QueuedMsgs()
|
||||
if nmsgs != 1 {
|
||||
t.Fatalf("Expected to receive a message over the TLS connection")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user