get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/test/cluster_tls_test.go (about)

     1  // Copyright 2013-2019 The NATS Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package test
    15  
    16  import (
    17  	"fmt"
    18  	"os"
    19  	"strings"
    20  	"testing"
    21  	"time"
    22  
    23  	"get.pme.sh/pnats/server"
    24  )
    25  
    26  func runTLSServers(t *testing.T) (srvA, srvB *server.Server, optsA, optsB *server.Options) {
    27  	srvA, optsA = RunServerWithConfig("./configs/srv_a_tls.conf")
    28  	srvB, optsB = RunServerWithConfig("./configs/srv_b_tls.conf")
    29  	checkClusterFormed(t, srvA, srvB)
    30  	return
    31  }
    32  
    33  func TestTLSClusterConfig(t *testing.T) {
    34  	srvA, srvB, _, _ := runTLSServers(t)
    35  	defer srvA.Shutdown()
    36  	defer srvB.Shutdown()
    37  }
    38  
    39  func TestBasicTLSClusterPubSub(t *testing.T) {
    40  	srvA, srvB, optsA, optsB := runTLSServers(t)
    41  	defer srvA.Shutdown()
    42  	defer srvB.Shutdown()
    43  
    44  	clientA := createClientConn(t, optsA.Host, optsA.Port)
    45  	defer clientA.Close()
    46  
    47  	clientB := createClientConn(t, optsB.Host, optsB.Port)
    48  	defer clientB.Close()
    49  
    50  	sendA, expectA := setupConn(t, clientA)
    51  	sendA("SUB foo 22\r\n")
    52  	sendA("PING\r\n")
    53  	expectA(pongRe)
    54  
    55  	if err := checkExpectedSubs(1, srvA, srvB); err != nil {
    56  		t.Fatalf("%v", err)
    57  	}
    58  
    59  	sendB, expectB := setupConn(t, clientB)
    60  	sendB("PUB foo 2\r\nok\r\n")
    61  	sendB("PING\r\n")
    62  	expectB(pongRe)
    63  
    64  	expectMsgs := expectMsgsCommand(t, expectA)
    65  
    66  	matches := expectMsgs(1)
    67  	checkMsg(t, matches[0], "foo", "22", "", "2", "ok")
    68  }
    69  
    70  type captureTLSError struct {
    71  	dummyLogger
    72  	ch chan struct{}
    73  }
    74  
    75  func (c *captureTLSError) Errorf(format string, v ...interface{}) {
    76  	msg := fmt.Sprintf(format, v...)
    77  	if strings.Contains(msg, "handshake error") {
    78  		select {
    79  		case c.ch <- struct{}{}:
    80  		default:
    81  		}
    82  	}
    83  }
    84  
    85  type captureClusterTLSInsecureLogger struct {
    86  	dummyLogger
    87  	ch chan struct{}
    88  }
    89  
    90  func (c *captureClusterTLSInsecureLogger) Warnf(format string, v ...interface{}) {
    91  	msg := fmt.Sprintf(format, v...)
    92  	if strings.Contains(msg, "solicited routes will not be verified") {
    93  		select {
    94  		case c.ch <- struct{}{}:
    95  		default:
    96  		}
    97  	}
    98  }
    99  
   100  func TestClusterTLSInsecure(t *testing.T) {
   101  	confA := createConfFile(t, []byte(`
   102  		port: -1
   103  		cluster {
   104  			name: "xyz"
   105  			listen: "127.0.0.1:-1"
   106  			pool_size: -1
   107  			compression: "disabled"
   108  			tls {
   109  			    cert_file: "./configs/certs/server-noip.pem"
   110  				key_file:  "./configs/certs/server-key-noip.pem"
   111  				ca_file:   "./configs/certs/ca.pem"
   112  				timeout: 2
   113  			}
   114  		}
   115  	`))
   116  	srvA, optsA := RunServerWithConfig(confA)
   117  	defer srvA.Shutdown()
   118  
   119  	l := &captureTLSError{ch: make(chan struct{}, 1)}
   120  	srvA.SetLogger(l, false, false)
   121  
   122  	bConfigTemplate := `
   123  		port: -1
   124  		cluster {
   125  			name: "xyz"
   126  			listen: "127.0.0.1:-1"
   127  			pool_size: -1
   128  			compression: "disabled"
   129  			tls {
   130  			    cert_file: "./configs/certs/server-noip.pem"
   131  				key_file:  "./configs/certs/server-key-noip.pem"
   132  				ca_file:   "./configs/certs/ca.pem"
   133  				timeout: 2
   134  				%s
   135  			}
   136  			routes [
   137  				"nats://%s:%d"
   138  			]
   139  		}
   140  	`
   141  	confB := createConfFile(t, []byte(fmt.Sprintf(bConfigTemplate,
   142  		"", optsA.Cluster.Host, optsA.Cluster.Port)))
   143  	srvB, _ := RunServerWithConfig(confB)
   144  	defer srvB.Shutdown()
   145  
   146  	// We should get errors
   147  	select {
   148  	case <-l.ch:
   149  	case <-time.After(2 * time.Second):
   150  		t.Fatalf("Did not get handshake error")
   151  	}
   152  
   153  	// Set a logger that will capture the warning
   154  	wl := &captureClusterTLSInsecureLogger{ch: make(chan struct{}, 1)}
   155  	srvB.SetLogger(wl, false, false)
   156  
   157  	// Need to add "insecure: true" and reload
   158  	if err := os.WriteFile(confB,
   159  		[]byte(fmt.Sprintf(bConfigTemplate, "insecure: true", optsA.Cluster.Host, optsA.Cluster.Port)),
   160  		0666); err != nil {
   161  		t.Fatalf("Error rewriting file: %v", err)
   162  	}
   163  	if err := srvB.Reload(); err != nil {
   164  		t.Fatalf("Error on reload: %v", err)
   165  	}
   166  
   167  	checkClusterFormed(t, srvA, srvB)
   168  
   169  	// Make sure we have the tracing
   170  	select {
   171  	case <-wl.ch:
   172  	case <-time.After(2 * time.Second):
   173  		t.Fatalf("Did not get warning about using cluster's insecure setting")
   174  	}
   175  }