get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/test/tls_test.go (about) 1 // Copyright 2015-2020 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 "bufio" 18 "crypto/tls" 19 "crypto/x509" 20 "errors" 21 "fmt" 22 "net" 23 "net/url" 24 "os" 25 "strings" 26 "sync" 27 "testing" 28 "time" 29 30 "github.com/nats-io/nats.go" 31 32 "get.pme.sh/pnats/server" 33 ) 34 35 var noOpErrHandler = func(_ *nats.Conn, _ *nats.Subscription, _ error) {} 36 37 func TestTLSConnection(t *testing.T) { 38 srv, opts := RunServerWithConfig("./configs/tls.conf") 39 defer srv.Shutdown() 40 41 endpoint := fmt.Sprintf("%s:%d", opts.Host, opts.Port) 42 nurl := fmt.Sprintf("tls://%s:%s@%s/", opts.Username, opts.Password, endpoint) 43 nc, err := nats.Connect(nurl) 44 if err == nil { 45 nc.Close() 46 t.Fatalf("Expected error trying to connect to secure server") 47 } 48 49 // Do simple SecureConnect 50 nc, err = nats.Connect(fmt.Sprintf("tls://%s/", endpoint)) 51 if err == nil { 52 nc.Close() 53 t.Fatalf("Expected error trying to connect to secure server with no auth") 54 } 55 56 // Now do more advanced checking, verifying servername and using rootCA. 57 58 nc, err = nats.Connect(nurl, nats.RootCAs("./configs/certs/ca.pem")) 59 if err != nil { 60 t.Fatalf("Got an error on Connect with Secure Options: %+v\n", err) 61 } 62 defer nc.Close() 63 64 subj := "foo-tls" 65 sub, _ := nc.SubscribeSync(subj) 66 67 nc.Publish(subj, []byte("We are Secure!")) 68 nc.Flush() 69 nmsgs, _ := sub.QueuedMsgs() 70 if nmsgs != 1 { 71 t.Fatalf("Expected to receive a message over the TLS connection") 72 } 73 } 74 75 // TestTLSInProcessConnection checks that even if TLS is enabled on the server, 76 // that an in-process connection that does *not* use TLS still connects successfully. 77 func TestTLSInProcessConnection(t *testing.T) { 78 srv, opts := RunServerWithConfig("./configs/tls.conf") 79 defer srv.Shutdown() 80 81 nc, err := nats.Connect("", nats.InProcessServer(srv), nats.UserInfo(opts.Username, opts.Password)) 82 if err != nil { 83 t.Fatal(err) 84 } 85 defer nc.Close() 86 87 if nc.TLSRequired() { 88 t.Fatalf("Shouldn't have required TLS for in-process connection") 89 } 90 91 if _, err = nc.TLSConnectionState(); err == nil { 92 t.Fatal("Should have got an error retrieving TLS connection state") 93 } 94 } 95 96 func TestTLSClientCertificate(t *testing.T) { 97 srv, opts := RunServerWithConfig("./configs/tlsverify.conf") 98 defer srv.Shutdown() 99 100 nurl := fmt.Sprintf("tls://%s:%d", opts.Host, opts.Port) 101 102 _, err := nats.Connect(nurl) 103 if err == nil { 104 t.Fatalf("Expected error trying to connect to secure server without a certificate") 105 } 106 107 // Load client certificate to successfully connect. 108 certFile := "./configs/certs/client-cert.pem" 109 keyFile := "./configs/certs/client-key.pem" 110 cert, err := tls.LoadX509KeyPair(certFile, keyFile) 111 if err != nil { 112 t.Fatalf("error parsing X509 certificate/key pair: %v", err) 113 } 114 115 // Load in root CA for server verification 116 rootPEM, err := os.ReadFile("./configs/certs/ca.pem") 117 if err != nil || rootPEM == nil { 118 t.Fatalf("failed to read root certificate") 119 } 120 pool := x509.NewCertPool() 121 ok := pool.AppendCertsFromPEM([]byte(rootPEM)) 122 if !ok { 123 t.Fatalf("failed to parse root certificate") 124 } 125 126 config := &tls.Config{ 127 Certificates: []tls.Certificate{cert}, 128 ServerName: opts.Host, 129 RootCAs: pool, 130 MinVersion: tls.VersionTLS12, 131 } 132 133 copts := nats.GetDefaultOptions() 134 copts.Url = nurl 135 copts.Secure = true 136 copts.TLSConfig = config 137 138 nc, err := copts.Connect() 139 if err != nil { 140 t.Fatalf("Got an error on Connect with Secure Options: %+v\n", err) 141 } 142 nc.Flush() 143 defer nc.Close() 144 } 145 146 func TestTLSClientCertificateHasUserID(t *testing.T) { 147 srv, opts := RunServerWithConfig("./configs/tls_cert_id.conf") 148 defer srv.Shutdown() 149 nurl := fmt.Sprintf("tls://%s:%d", opts.Host, opts.Port) 150 nc, err := nats.Connect(nurl, 151 nats.ClientCert("./configs/certs/client-id-auth-cert.pem", "./configs/certs/client-id-auth-key.pem"), 152 nats.RootCAs("./configs/certs/ca.pem")) 153 if err != nil { 154 t.Fatalf("Expected to connect, got %v", err) 155 } 156 defer nc.Close() 157 } 158 159 func TestTLSClientCertificateCheckWithAllowedConnectionTypes(t *testing.T) { 160 conf := createConfFile(t, []byte( 161 ` 162 listen: "127.0.0.1:-1" 163 tls { 164 cert_file: "./configs/certs/server-cert.pem" 165 key_file: "./configs/certs/server-key.pem" 166 timeout: 2 167 ca_file: "./configs/certs/ca.pem" 168 verify_and_map: true 169 } 170 authorization { 171 users = [ 172 {user: derek@nats.io, permissions: { publish:"foo" }, allowed_connection_types: ["WEBSOCKET"]} 173 ] 174 } 175 `)) 176 s, o := RunServerWithConfig(conf) 177 defer s.Shutdown() 178 179 nurl := fmt.Sprintf("tls://%s:%d", o.Host, o.Port) 180 nc, err := nats.Connect(nurl, 181 nats.ClientCert("./configs/certs/client-id-auth-cert.pem", "./configs/certs/client-id-auth-key.pem"), 182 nats.RootCAs("./configs/certs/ca.pem")) 183 if err == nil { 184 if nc != nil { 185 nc.Close() 186 } 187 t.Fatal("Expected connection to fail, it did not") 188 } 189 } 190 191 func TestTLSClientCertificateCNBasedAuth(t *testing.T) { 192 srv, opts := RunServerWithConfig("./configs/tls_cert_cn.conf") 193 defer srv.Shutdown() 194 nurl := fmt.Sprintf("tls://%s:%d", opts.Host, opts.Port) 195 errCh1 := make(chan error) 196 errCh2 := make(chan error) 197 198 // Using the default permissions 199 nc1, err := nats.Connect(nurl, 200 nats.ClientCert("./configs/certs/tlsauth/client.pem", "./configs/certs/tlsauth/client-key.pem"), 201 nats.RootCAs("./configs/certs/tlsauth/ca.pem"), 202 nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) { 203 errCh1 <- err 204 }), 205 ) 206 if err != nil { 207 t.Fatalf("Expected to connect, got %v", err) 208 } 209 defer nc1.Close() 210 211 // Admin permissions can publish to '>' 212 nc2, err := nats.Connect(nurl, 213 nats.ClientCert("./configs/certs/tlsauth/client2.pem", "./configs/certs/tlsauth/client2-key.pem"), 214 nats.RootCAs("./configs/certs/tlsauth/ca.pem"), 215 nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) { 216 errCh2 <- err 217 }), 218 ) 219 if err != nil { 220 t.Fatalf("Expected to connect, got %v", err) 221 } 222 defer nc2.Close() 223 224 err = nc1.Publish("foo.bar", []byte("hi")) 225 if err != nil { 226 t.Fatal(err) 227 } 228 _, err = nc1.SubscribeSync("foo.>") 229 if err != nil { 230 t.Fatal(err) 231 } 232 nc1.Flush() 233 234 sub, err := nc2.SubscribeSync(">") 235 if err != nil { 236 t.Fatal(err) 237 } 238 nc2.Flush() 239 err = nc2.Publish("hello", []byte("hi")) 240 if err != nil { 241 t.Fatal(err) 242 } 243 nc2.Flush() 244 245 _, err = sub.NextMsg(1 * time.Second) 246 if err != nil { 247 t.Fatalf("Error during wait for next message: %s", err) 248 } 249 250 // Wait for a couple of errors 251 var count int 252 Loop: 253 for { 254 select { 255 case err := <-errCh1: 256 if err != nil { 257 count++ 258 } 259 if count == 2 { 260 break Loop 261 } 262 case err := <-errCh2: 263 if err != nil { 264 t.Fatalf("Received unexpected auth error from client: %s", err) 265 } 266 case <-time.After(2 * time.Second): 267 t.Fatalf("Timed out expecting auth errors") 268 } 269 } 270 } 271 272 func TestTLSClientCertificateSANsBasedAuth(t *testing.T) { 273 // In this test we have 3 clients, one with permissions defined 274 // for SAN 'app.nats.dev', other for SAN 'app.nats.prod' and another 275 // one without the default permissions for the CN. 276 srv, opts := RunServerWithConfig("./configs/tls_cert_san_auth.conf") 277 defer srv.Shutdown() 278 nurl := fmt.Sprintf("tls://%s:%d", opts.Host, opts.Port) 279 defaultErrCh := make(chan error) 280 devErrCh := make(chan error) 281 prodErrCh := make(chan error) 282 283 // default: Using the default permissions (no SANs) 284 // 285 // Subject: CN = www.nats.io 286 // 287 defaultc, err := nats.Connect(nurl, 288 nats.ClientCert("./configs/certs/sans/client.pem", "./configs/certs/sans/client-key.pem"), 289 nats.RootCAs("./configs/certs/sans/ca.pem"), 290 nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) { 291 defaultErrCh <- err 292 }), 293 ) 294 if err != nil { 295 t.Fatalf("Expected to connect, got %v", err) 296 } 297 defer defaultc.Close() 298 299 // dev: Using SAN 'app.nats.dev' with permissions to its own sandbox. 300 // 301 // Subject: CN = www.nats.io 302 // 303 // X509v3 Subject Alternative Name: 304 // DNS:app.nats.dev, DNS:*.app.nats.dev 305 // 306 devc, err := nats.Connect(nurl, 307 nats.ClientCert("./configs/certs/sans/dev.pem", "./configs/certs/sans/dev-key.pem"), 308 nats.RootCAs("./configs/certs/sans/ca.pem"), 309 nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) { 310 devErrCh <- err 311 }), 312 ) 313 if err != nil { 314 t.Fatalf("Expected to connect, got %v", err) 315 } 316 defer devc.Close() 317 318 // prod: Using SAN 'app.nats.prod' with all permissions. 319 // 320 // Subject: CN = www.nats.io 321 // 322 // X509v3 Subject Alternative Name: 323 // DNS:app.nats.prod, DNS:*.app.nats.prod 324 // 325 prodc, err := nats.Connect(nurl, 326 nats.ClientCert("./configs/certs/sans/prod.pem", "./configs/certs/sans/prod-key.pem"), 327 nats.RootCAs("./configs/certs/sans/ca.pem"), 328 nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) { 329 prodErrCh <- err 330 }), 331 ) 332 if err != nil { 333 t.Fatalf("Expected to connect, got %v", err) 334 } 335 defer prodc.Close() 336 337 // No permissions to publish or subscribe on foo.> 338 err = devc.Publish("foo.bar", []byte("hi")) 339 if err != nil { 340 t.Fatal(err) 341 } 342 _, err = devc.SubscribeSync("foo.>") 343 if err != nil { 344 t.Fatal(err) 345 } 346 devc.Flush() 347 348 prodSub, err := prodc.SubscribeSync(">") 349 if err != nil { 350 t.Fatal(err) 351 } 352 prodc.Flush() 353 err = prodc.Publish("hello", []byte("hi")) 354 if err != nil { 355 t.Fatal(err) 356 } 357 prodc.Flush() 358 359 // prod: can receive message on wildcard subscription. 360 _, err = prodSub.NextMsg(1 * time.Second) 361 if err != nil { 362 t.Fatalf("Error during wait for next message: %s", err) 363 } 364 365 // dev: enough permissions to publish to sandbox subject. 366 devSub, err := devc.SubscribeSync("sandbox.>") 367 if err != nil { 368 t.Fatal(err) 369 } 370 devc.Flush() 371 err = devc.Publish("sandbox.foo.bar", []byte("hi!")) 372 if err != nil { 373 t.Fatal(err) 374 } 375 // both dev and prod clients can receive message 376 _, err = devSub.NextMsg(1 * time.Second) 377 if err != nil { 378 t.Fatalf("Error during wait for next message: %s", err) 379 } 380 _, err = prodSub.NextMsg(1 * time.Second) 381 if err != nil { 382 t.Fatalf("Error during wait for next message: %s", err) 383 } 384 385 // default: no enough permissions 386 _, err = defaultc.SubscribeSync("sandbox.>") 387 if err != nil { 388 t.Fatal(err) 389 } 390 defaultSub, err := defaultc.SubscribeSync("public.>") 391 if err != nil { 392 t.Fatal(err) 393 } 394 defaultc.Flush() 395 err = devc.Publish("public.foo.bar", []byte("hi!")) 396 if err != nil { 397 t.Fatal(err) 398 } 399 _, err = defaultSub.NextMsg(1 * time.Second) 400 if err != nil { 401 t.Fatalf("Error during wait for next message: %s", err) 402 } 403 404 // Wait for a couple of errors 405 var count int 406 Loop: 407 for { 408 select { 409 case err := <-defaultErrCh: 410 if err != nil { 411 count++ 412 } 413 if count == 3 { 414 break Loop 415 } 416 case err := <-devErrCh: 417 if err != nil { 418 count++ 419 } 420 if count == 3 { 421 break Loop 422 } 423 case err := <-prodErrCh: 424 if err != nil { 425 t.Fatalf("Received unexpected auth error from client: %s", err) 426 } 427 case <-time.After(2 * time.Second): 428 t.Fatalf("Timed out expecting auth errors") 429 } 430 } 431 } 432 433 func TestTLSClientCertificateTLSAuthMultipleOptions(t *testing.T) { 434 srv, opts := RunServerWithConfig("./configs/tls_cert_san_emails.conf") 435 defer srv.Shutdown() 436 nurl := fmt.Sprintf("tls://%s:%d", opts.Host, opts.Port) 437 defaultErrCh := make(chan error) 438 devErrCh := make(chan error) 439 prodErrCh := make(chan error) 440 441 // default: Using the default permissions, there are SANs 442 // present in the cert but they are not users in the NATS config 443 // so the subject is used instead. 444 // 445 // Subject: CN = www.nats.io 446 // 447 // X509v3 Subject Alternative Name: 448 // DNS:app.nats.dev, DNS:*.app.nats.dev 449 // 450 defaultc, err := nats.Connect(nurl, 451 nats.ClientCert("./configs/certs/sans/dev.pem", "./configs/certs/sans/dev-key.pem"), 452 nats.RootCAs("./configs/certs/sans/ca.pem"), 453 nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) { 454 defaultErrCh <- err 455 }), 456 ) 457 if err != nil { 458 t.Fatalf("Expected to connect, got %v", err) 459 } 460 defer defaultc.Close() 461 462 // dev: Using SAN to validate user, even if emails are present in the config. 463 // 464 // Subject: CN = www.nats.io 465 // 466 // X509v3 Subject Alternative Name: 467 // DNS:app.nats.dev, email:admin@app.nats.dev, email:root@app.nats.dev 468 // 469 devc, err := nats.Connect(nurl, 470 nats.ClientCert("./configs/certs/sans/dev-email.pem", "./configs/certs/sans/dev-email-key.pem"), 471 nats.RootCAs("./configs/certs/sans/ca.pem"), 472 nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) { 473 devErrCh <- err 474 }), 475 ) 476 if err != nil { 477 t.Fatalf("Expected to connect, got %v", err) 478 } 479 defer devc.Close() 480 481 // prod: Using SAN '*.app.nats.prod' with all permissions, which is not the first SAN. 482 // 483 // Subject: CN = www.nats.io 484 // 485 // X509v3 Subject Alternative Name: 486 // DNS:app.nats.prod, DNS:*.app.nats.prod 487 // 488 prodc, err := nats.Connect(nurl, 489 nats.ClientCert("./configs/certs/sans/prod.pem", "./configs/certs/sans/prod-key.pem"), 490 nats.RootCAs("./configs/certs/sans/ca.pem"), 491 nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) { 492 prodErrCh <- err 493 }), 494 ) 495 if err != nil { 496 t.Fatalf("Expected to connect, got %v", err) 497 } 498 defer prodc.Close() 499 500 // No permissions to publish or subscribe on foo.> 501 err = devc.Publish("foo.bar", []byte("hi")) 502 if err != nil { 503 t.Fatal(err) 504 } 505 _, err = devc.SubscribeSync("foo.>") 506 if err != nil { 507 t.Fatal(err) 508 } 509 devc.Flush() 510 511 prodSub, err := prodc.SubscribeSync(">") 512 if err != nil { 513 t.Fatal(err) 514 } 515 prodc.Flush() 516 err = prodc.Publish("hello", []byte("hi")) 517 if err != nil { 518 t.Fatal(err) 519 } 520 prodc.Flush() 521 522 // prod: can receive message on wildcard subscription. 523 _, err = prodSub.NextMsg(1 * time.Second) 524 if err != nil { 525 t.Fatalf("Error during wait for next message: %s", err) 526 } 527 528 // dev: enough permissions to publish to sandbox subject. 529 devSub, err := devc.SubscribeSync("sandbox.>") 530 if err != nil { 531 t.Fatal(err) 532 } 533 devc.Flush() 534 err = devc.Publish("sandbox.foo.bar", []byte("hi!")) 535 if err != nil { 536 t.Fatal(err) 537 } 538 // both dev and prod clients can receive message 539 _, err = devSub.NextMsg(1 * time.Second) 540 if err != nil { 541 t.Fatalf("Error during wait for next message: %s", err) 542 } 543 _, err = prodSub.NextMsg(1 * time.Second) 544 if err != nil { 545 t.Fatalf("Error during wait for next message: %s", err) 546 } 547 548 // default: no enough permissions 549 _, err = defaultc.SubscribeSync("sandbox.>") 550 if err != nil { 551 t.Fatal(err) 552 } 553 defaultSub, err := defaultc.SubscribeSync("public.>") 554 if err != nil { 555 t.Fatal(err) 556 } 557 defaultc.Flush() 558 err = devc.Publish("public.foo.bar", []byte("hi!")) 559 if err != nil { 560 t.Fatal(err) 561 } 562 _, err = defaultSub.NextMsg(1 * time.Second) 563 if err != nil { 564 t.Fatalf("Error during wait for next message: %s", err) 565 } 566 567 // Wait for a couple of errors 568 var count int 569 Loop: 570 for { 571 select { 572 case err := <-defaultErrCh: 573 if err != nil { 574 count++ 575 } 576 if count == 3 { 577 break Loop 578 } 579 case err := <-devErrCh: 580 if err != nil { 581 count++ 582 } 583 if count == 3 { 584 break Loop 585 } 586 case err := <-prodErrCh: 587 if err != nil { 588 t.Fatalf("Received unexpected auth error from client: %s", err) 589 } 590 case <-time.After(2 * time.Second): 591 t.Fatalf("Timed out expecting auth errors") 592 } 593 } 594 } 595 596 func TestTLSRoutesCertificateCNBasedAuth(t *testing.T) { 597 // Base config for the servers 598 optsA := LoadConfig("./configs/tls_cert_cn_routes.conf") 599 optsB := LoadConfig("./configs/tls_cert_cn_routes.conf") 600 optsC := LoadConfig("./configs/tls_cert_cn_routes_invalid_auth.conf") 601 602 // TLS map should have been enabled 603 if !optsA.Cluster.TLSMap || !optsB.Cluster.TLSMap || !optsC.Cluster.TLSMap { 604 t.Error("Expected Cluster TLS verify and map feature to be activated") 605 } 606 607 routeURLs := "nats://localhost:9935, nats://localhost:9936, nats://localhost:9937" 608 609 optsA.Host = "127.0.0.1" 610 optsA.Port = 9335 611 optsA.Cluster.Name = "xyz" 612 optsA.Cluster.Host = optsA.Host 613 optsA.Cluster.Port = 9935 614 optsA.Routes = server.RoutesFromStr(routeURLs) 615 optsA.NoSystemAccount = true 616 srvA := RunServer(optsA) 617 defer srvA.Shutdown() 618 619 optsB.Host = "127.0.0.1" 620 optsB.Port = 9336 621 optsB.Cluster.Name = "xyz" 622 optsB.Cluster.Host = optsB.Host 623 optsB.Cluster.Port = 9936 624 optsB.Routes = server.RoutesFromStr(routeURLs) 625 optsB.NoSystemAccount = true 626 srvB := RunServer(optsB) 627 defer srvB.Shutdown() 628 629 optsC.Host = "127.0.0.1" 630 optsC.Port = 9337 631 optsC.Cluster.Name = "xyz" 632 optsC.Cluster.Host = optsC.Host 633 optsC.Cluster.Port = 9937 634 optsC.Routes = server.RoutesFromStr(routeURLs) 635 optsC.NoSystemAccount = true 636 srvC := RunServer(optsC) 637 defer srvC.Shutdown() 638 639 // srvC is not connected to srvA and srvB due to wrong cert 640 checkClusterFormed(t, srvA, srvB) 641 642 nc1, err := nats.Connect(fmt.Sprintf("%s:%d", optsA.Host, optsA.Port), nats.Name("A")) 643 if err != nil { 644 t.Fatalf("Expected to connect, got %v", err) 645 } 646 defer nc1.Close() 647 648 nc2, err := nats.Connect(fmt.Sprintf("%s:%d", optsB.Host, optsB.Port), nats.Name("B")) 649 if err != nil { 650 t.Fatalf("Expected to connect, got %v", err) 651 } 652 defer nc2.Close() 653 654 // This client is partitioned from rest of cluster due to using wrong cert. 655 nc3, err := nats.Connect(fmt.Sprintf("%s:%d", optsC.Host, optsC.Port), nats.Name("C")) 656 if err != nil { 657 t.Fatalf("Expected to connect, got %v", err) 658 } 659 defer nc3.Close() 660 661 // Allowed via permissions to broadcast to other members of cluster. 662 publicSub, err := nc1.SubscribeSync("public.>") 663 if err != nil { 664 t.Fatal(err) 665 } 666 667 // Not part of cluster permissions so message is not forwarded. 668 privateSub, err := nc1.SubscribeSync("private.>") 669 if err != nil { 670 t.Fatal(err) 671 } 672 // This ensures that srvA has received the sub, not srvB 673 nc1.Flush() 674 675 checkFor(t, time.Second, 15*time.Millisecond, func() error { 676 if n := srvB.NumSubscriptions(); n != 1 { 677 return fmt.Errorf("Expected 1 sub, got %v", n) 678 } 679 return nil 680 }) 681 682 // Not forwarded by cluster so won't be received. 683 err = nc2.Publish("private.foo", []byte("private message on server B")) 684 if err != nil { 685 t.Fatal(err) 686 } 687 err = nc2.Publish("public.foo", []byte("public message from server B to server A")) 688 if err != nil { 689 t.Fatal(err) 690 } 691 nc2.Flush() 692 err = nc3.Publish("public.foo", []byte("dropped message since unauthorized server")) 693 if err != nil { 694 t.Fatal(err) 695 } 696 nc3.Flush() 697 698 // Message will be received since allowed via permissions 699 _, err = publicSub.NextMsg(1 * time.Second) 700 if err != nil { 701 t.Fatalf("Error during wait for next message: %s", err) 702 } 703 msg, err := privateSub.NextMsg(500 * time.Millisecond) 704 if err == nil { 705 t.Errorf("Received unexpected message from private sub: %+v", msg) 706 } 707 msg, err = publicSub.NextMsg(500 * time.Millisecond) 708 if err == nil { 709 t.Errorf("Received unexpected message from private sub: %+v", msg) 710 } 711 } 712 713 func TestTLSGatewaysCertificateCNBasedAuth(t *testing.T) { 714 // Base config for the servers 715 optsA := LoadConfig("./configs/tls_cert_cn_gateways.conf") 716 optsB := LoadConfig("./configs/tls_cert_cn_gateways.conf") 717 optsC := LoadConfig("./configs/tls_cert_cn_gateways_invalid_auth.conf") 718 719 // TLS map should have been enabled 720 if !optsA.Gateway.TLSMap || !optsB.Gateway.TLSMap || !optsC.Gateway.TLSMap { 721 t.Error("Expected Cluster TLS verify and map feature to be activated") 722 } 723 724 gwA, err := url.Parse("nats://localhost:9995") 725 if err != nil { 726 t.Fatal(err) 727 } 728 gwB, err := url.Parse("nats://localhost:9996") 729 if err != nil { 730 t.Fatal(err) 731 } 732 gwC, err := url.Parse("nats://localhost:9997") 733 if err != nil { 734 t.Fatal(err) 735 } 736 737 optsA.Host = "127.0.0.1" 738 optsA.Port = -1 739 optsA.Gateway.Name = "A" 740 optsA.Gateway.Port = 9995 741 742 optsB.Host = "127.0.0.1" 743 optsB.Port = -1 744 optsB.Gateway.Name = "B" 745 optsB.Gateway.Port = 9996 746 747 optsC.Host = "127.0.0.1" 748 optsC.Port = -1 749 optsC.Gateway.Name = "C" 750 optsC.Gateway.Port = 9997 751 752 gateways := make([]*server.RemoteGatewayOpts, 3) 753 gateways[0] = &server.RemoteGatewayOpts{ 754 Name: optsA.Gateway.Name, 755 URLs: []*url.URL{gwA}, 756 } 757 gateways[1] = &server.RemoteGatewayOpts{ 758 Name: optsB.Gateway.Name, 759 URLs: []*url.URL{gwB}, 760 } 761 gateways[2] = &server.RemoteGatewayOpts{ 762 Name: optsC.Gateway.Name, 763 URLs: []*url.URL{gwC}, 764 } 765 optsA.Gateway.Gateways = gateways 766 optsB.Gateway.Gateways = gateways 767 optsC.Gateway.Gateways = gateways 768 769 server.SetGatewaysSolicitDelay(100 * time.Millisecond) 770 defer server.ResetGatewaysSolicitDelay() 771 772 srvA := RunServer(optsA) 773 defer srvA.Shutdown() 774 775 srvB := RunServer(optsB) 776 defer srvB.Shutdown() 777 778 srvC := RunServer(optsC) 779 defer srvC.Shutdown() 780 781 // Because we need to use "localhost" in the gw URLs (to match 782 // hostname in the user/CN), the server may try to connect to 783 // a [::1], etc.. that may or may not work, so give a lot of 784 // time for that to complete ok. 785 waitForOutboundGateways(t, srvA, 1, 5*time.Second) 786 waitForOutboundGateways(t, srvB, 1, 5*time.Second) 787 788 nc1, err := nats.Connect(srvA.Addr().String(), nats.Name("A")) 789 if err != nil { 790 t.Fatalf("Expected to connect, got %v", err) 791 } 792 defer nc1.Close() 793 794 nc2, err := nats.Connect(srvB.Addr().String(), nats.Name("B")) 795 if err != nil { 796 t.Fatalf("Expected to connect, got %v", err) 797 } 798 defer nc2.Close() 799 800 nc3, err := nats.Connect(srvC.Addr().String(), nats.Name("C")) 801 if err != nil { 802 t.Fatalf("Expected to connect, got %v", err) 803 } 804 defer nc3.Close() 805 806 received := make(chan *nats.Msg) 807 _, err = nc1.Subscribe("foo", func(msg *nats.Msg) { 808 select { 809 case received <- msg: 810 default: 811 } 812 }) 813 if err != nil { 814 t.Error(err) 815 } 816 _, err = nc3.Subscribe("help", func(msg *nats.Msg) { 817 nc3.Publish(msg.Reply, []byte("response")) 818 }) 819 if err != nil { 820 t.Error(err) 821 } 822 823 go func() { 824 for range time.NewTicker(10 * time.Millisecond).C { 825 if nc2.IsClosed() { 826 return 827 } 828 nc2.Publish("foo", []byte("bar")) 829 } 830 }() 831 832 select { 833 case <-received: 834 case <-time.After(2 * time.Second): 835 t.Error("Timed out waiting for gateway messages") 836 } 837 838 msg, err := nc2.Request("help", []byte("should fail"), 100*time.Millisecond) 839 if err == nil { 840 t.Errorf("Expected to not receive any messages, got: %+v", msg) 841 } 842 } 843 844 func TestTLSVerifyClientCertificate(t *testing.T) { 845 srv, opts := RunServerWithConfig("./configs/tlsverify_noca.conf") 846 defer srv.Shutdown() 847 848 nurl := fmt.Sprintf("tls://%s:%d", opts.Host, opts.Port) 849 850 // The client is configured properly, but the server has no CA 851 // to verify the client certificate. Connection should fail. 852 nc, err := nats.Connect(nurl, 853 nats.ClientCert("./configs/certs/client-cert.pem", "./configs/certs/client-key.pem"), 854 nats.RootCAs("./configs/certs/ca.pem")) 855 if err == nil { 856 nc.Close() 857 t.Fatal("Expected failure to connect, did not") 858 } 859 } 860 861 func TestTLSConnectionTimeout(t *testing.T) { 862 opts := LoadConfig("./configs/tls.conf") 863 opts.TLSTimeout = 0.25 864 865 srv := RunServer(opts) 866 defer srv.Shutdown() 867 868 // Dial with normal TCP 869 endpoint := fmt.Sprintf("%s:%d", opts.Host, opts.Port) 870 conn, err := net.Dial("tcp", endpoint) 871 if err != nil { 872 t.Fatalf("Could not connect to %q", endpoint) 873 } 874 defer conn.Close() 875 876 // Read deadlines 877 conn.SetReadDeadline(time.Now().Add(2 * time.Second)) 878 879 // Read the INFO string. 880 br := bufio.NewReader(conn) 881 info, err := br.ReadString('\n') 882 if err != nil { 883 t.Fatalf("Failed to read INFO - %v", err) 884 } 885 if !strings.HasPrefix(info, "INFO ") { 886 t.Fatalf("INFO response incorrect: %s\n", info) 887 } 888 wait := time.Duration(opts.TLSTimeout * float64(time.Second)) 889 time.Sleep(wait) 890 // Read deadlines 891 conn.SetReadDeadline(time.Now().Add(2 * time.Second)) 892 tlsErr, err := br.ReadString('\n') 893 if err == nil && !strings.Contains(tlsErr, "-ERR 'Secure Connection - TLS Required") { 894 t.Fatalf("TLS Timeout response incorrect: %q\n", tlsErr) 895 } 896 } 897 898 // Ensure there is no race between authorization timeout and TLS handshake. 899 func TestTLSAuthorizationShortTimeout(t *testing.T) { 900 opts := LoadConfig("./configs/tls.conf") 901 opts.AuthTimeout = 0.001 902 903 srv := RunServer(opts) 904 defer srv.Shutdown() 905 906 endpoint := fmt.Sprintf("%s:%d", opts.Host, opts.Port) 907 nurl := fmt.Sprintf("tls://%s:%s@%s/", opts.Username, opts.Password, endpoint) 908 909 // Expect an error here (no CA) but not a TLS oversized record error which 910 // indicates the authorization timeout fired too soon. 911 _, err := nats.Connect(nurl) 912 if err == nil { 913 t.Fatal("Expected error trying to connect to secure server") 914 } 915 if strings.Contains(err.Error(), "oversized record") { 916 t.Fatal("Corrupted TLS handshake:", err) 917 } 918 } 919 920 func TestClientTLSAndNonTLSConnections(t *testing.T) { 921 s, opts := RunServerWithConfig("./configs/tls_mixed.conf") 922 defer s.Shutdown() 923 924 surl := fmt.Sprintf("tls://%s:%d", opts.Host, opts.Port) 925 nc, err := nats.Connect(surl, nats.RootCAs("./configs/certs/ca.pem")) 926 if err != nil { 927 t.Fatalf("Failed to connect with TLS: %v", err) 928 } 929 defer nc.Close() 930 931 // Now also make sure we can connect through plain text. 932 nurl := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port) 933 nc2, err := nats.Connect(nurl) 934 if err != nil { 935 t.Fatalf("Failed to connect without TLS: %v", err) 936 } 937 defer nc2.Close() 938 939 // Make sure they can go back and forth. 940 sub, err := nc.SubscribeSync("foo") 941 if err != nil { 942 t.Fatalf("Error subscribing: %v", err) 943 } 944 sub2, err := nc2.SubscribeSync("bar") 945 if err != nil { 946 t.Fatalf("Error subscribing: %v", err) 947 } 948 nc.Flush() 949 nc2.Flush() 950 951 nmsgs := 100 952 for i := 0; i < nmsgs; i++ { 953 nc2.Publish("foo", []byte("HELLO FROM PLAINTEXT")) 954 nc.Publish("bar", []byte("HELLO FROM TLS")) 955 } 956 // Now wait for the messages. 957 checkFor(t, time.Second, 10*time.Millisecond, func() error { 958 if msgs, _, err := sub.Pending(); err != nil || msgs != nmsgs { 959 return fmt.Errorf("Did not receive the correct number of messages: %d", msgs) 960 } 961 if msgs, _, err := sub2.Pending(); err != nil || msgs != nmsgs { 962 return fmt.Errorf("Did not receive the correct number of messages: %d", msgs) 963 } 964 return nil 965 }) 966 967 } 968 969 func stressConnect(t *testing.T, wg *sync.WaitGroup, errCh chan error, url string, index int) { 970 defer wg.Done() 971 972 subName := fmt.Sprintf("foo.%d", index) 973 974 for i := 0; i < 33; i++ { 975 nc, err := nats.Connect(url, nats.RootCAs("./configs/certs/ca.pem")) 976 if err != nil { 977 errCh <- fmt.Errorf("Unable to create TLS connection: %v\n", err) 978 return 979 } 980 defer nc.Close() 981 982 sub, err := nc.SubscribeSync(subName) 983 if err != nil { 984 errCh <- fmt.Errorf("Unable to subscribe on '%s': %v\n", subName, err) 985 return 986 } 987 988 if err := nc.Publish(subName, []byte("secure data")); err != nil { 989 errCh <- fmt.Errorf("Unable to send on '%s': %v\n", subName, err) 990 } 991 992 if _, err := sub.NextMsg(2 * time.Second); err != nil { 993 errCh <- fmt.Errorf("Unable to get next message: %v\n", err) 994 } 995 996 nc.Close() 997 } 998 999 errCh <- nil 1000 } 1001 1002 func TestTLSStressConnect(t *testing.T) { 1003 opts, err := server.ProcessConfigFile("./configs/tls.conf") 1004 if err != nil { 1005 panic(fmt.Sprintf("Error processing configuration file: %v", err)) 1006 } 1007 opts.NoSigs, opts.NoLog = true, true 1008 1009 // For this test, remove the authorization 1010 opts.Username = "" 1011 opts.Password = "" 1012 1013 // Increase ssl timeout 1014 opts.TLSTimeout = 2.0 1015 1016 srv := RunServer(opts) 1017 defer srv.Shutdown() 1018 1019 nurl := fmt.Sprintf("tls://%s:%d", opts.Host, opts.Port) 1020 1021 threadCount := 3 1022 1023 errCh := make(chan error, threadCount) 1024 1025 var wg sync.WaitGroup 1026 wg.Add(threadCount) 1027 1028 for i := 0; i < threadCount; i++ { 1029 go stressConnect(t, &wg, errCh, nurl, i) 1030 } 1031 1032 wg.Wait() 1033 1034 var lastError error 1035 for i := 0; i < threadCount; i++ { 1036 err := <-errCh 1037 if err != nil { 1038 lastError = err 1039 } 1040 } 1041 1042 if lastError != nil { 1043 t.Fatalf("%v\n", lastError) 1044 } 1045 } 1046 1047 func TestTLSBadAuthError(t *testing.T) { 1048 srv, opts := RunServerWithConfig("./configs/tls.conf") 1049 defer srv.Shutdown() 1050 1051 endpoint := fmt.Sprintf("%s:%d", opts.Host, opts.Port) 1052 nurl := fmt.Sprintf("tls://%s:%s@%s/", opts.Username, "NOT_THE_PASSWORD", endpoint) 1053 1054 _, err := nats.Connect(nurl, nats.RootCAs("./configs/certs/ca.pem")) 1055 if err == nil { 1056 t.Fatalf("Expected error trying to connect to secure server") 1057 } 1058 if strings.ToLower(err.Error()) != nats.ErrAuthorization.Error() { 1059 t.Fatalf("Expected and auth violation, got %v\n", err) 1060 } 1061 } 1062 1063 func TestTLSConnectionCurvePref(t *testing.T) { 1064 srv, opts := RunServerWithConfig("./configs/tls_curve_pref.conf") 1065 defer srv.Shutdown() 1066 1067 if len(opts.TLSConfig.CurvePreferences) != 1 { 1068 t.Fatal("Invalid curve preference loaded.") 1069 } 1070 1071 if opts.TLSConfig.CurvePreferences[0] != tls.CurveP256 { 1072 t.Fatalf("Invalid curve preference loaded [%v].", opts.TLSConfig.CurvePreferences[0]) 1073 } 1074 1075 endpoint := fmt.Sprintf("%s:%d", opts.Host, opts.Port) 1076 nurl := fmt.Sprintf("tls://%s:%s@%s/", opts.Username, opts.Password, endpoint) 1077 nc, err := nats.Connect(nurl) 1078 if err == nil { 1079 nc.Close() 1080 t.Fatalf("Expected error trying to connect to secure server") 1081 } 1082 1083 // Do simple SecureConnect 1084 nc, err = nats.Connect(fmt.Sprintf("tls://%s/", endpoint)) 1085 if err == nil { 1086 nc.Close() 1087 t.Fatalf("Expected error trying to connect to secure server with no auth") 1088 } 1089 1090 // Now do more advanced checking, verifying servername and using rootCA. 1091 1092 nc, err = nats.Connect(nurl, nats.RootCAs("./configs/certs/ca.pem")) 1093 if err != nil { 1094 t.Fatalf("Got an error on Connect with Secure Options: %+v\n", err) 1095 } 1096 defer nc.Close() 1097 1098 subj := "foo-tls" 1099 sub, _ := nc.SubscribeSync(subj) 1100 1101 nc.Publish(subj, []byte("We are Secure!")) 1102 nc.Flush() 1103 nmsgs, _ := sub.QueuedMsgs() 1104 if nmsgs != 1 { 1105 t.Fatalf("Expected to receive a message over the TLS connection") 1106 } 1107 } 1108 1109 type captureSlowConsumerLogger struct { 1110 dummyLogger 1111 ch chan string 1112 gotIt bool 1113 } 1114 1115 func (l *captureSlowConsumerLogger) Noticef(format string, v ...interface{}) { 1116 msg := fmt.Sprintf(format, v...) 1117 if strings.Contains(msg, "Slow Consumer") { 1118 l.Lock() 1119 if !l.gotIt { 1120 l.gotIt = true 1121 l.ch <- msg 1122 } 1123 l.Unlock() 1124 } 1125 } 1126 1127 func TestTLSTimeoutNotReportSlowConsumer(t *testing.T) { 1128 oa, err := server.ProcessConfigFile("./configs/srv_a_tls.conf") 1129 if err != nil { 1130 t.Fatalf("Unable to load config file: %v", err) 1131 } 1132 1133 // Override TLSTimeout to very small value so that handshake fails 1134 oa.Cluster.TLSTimeout = 0.0000001 1135 sa := RunServer(oa) 1136 defer sa.Shutdown() 1137 1138 ch := make(chan string, 1) 1139 cscl := &captureSlowConsumerLogger{ch: ch} 1140 sa.SetLogger(cscl, false, false) 1141 1142 ob, err := server.ProcessConfigFile("./configs/srv_b_tls.conf") 1143 if err != nil { 1144 t.Fatalf("Unable to load config file: %v", err) 1145 } 1146 1147 sb := RunServer(ob) 1148 defer sb.Shutdown() 1149 1150 // Watch the logger for a bit and make sure we don't get any 1151 // Slow Consumer error. 1152 select { 1153 case e := <-ch: 1154 t.Fatalf("Unexpected slow consumer error: %s", e) 1155 case <-time.After(500 * time.Millisecond): 1156 // ok 1157 } 1158 } 1159 1160 func TestTLSHandshakeFailureMemUsage(t *testing.T) { 1161 for i, test := range []struct { 1162 name string 1163 config string 1164 }{ 1165 { 1166 "connect to TLS client port", 1167 ` 1168 port: -1 1169 %s 1170 `, 1171 }, 1172 { 1173 "connect to TLS route port", 1174 ` 1175 port: -1 1176 cluster { 1177 port: -1 1178 %s 1179 } 1180 `, 1181 }, 1182 { 1183 "connect to TLS gateway port", 1184 ` 1185 port: -1 1186 gateway { 1187 name: "A" 1188 port: -1 1189 %s 1190 } 1191 `, 1192 }, 1193 } { 1194 t.Run(test.name, func(t *testing.T) { 1195 content := fmt.Sprintf(test.config, ` 1196 tls { 1197 cert_file: "configs/certs/server-cert.pem" 1198 key_file: "configs/certs/server-key.pem" 1199 ca_file: "configs/certs/ca.pem" 1200 timeout: 5 1201 } 1202 `) 1203 conf := createConfFile(t, []byte(content)) 1204 s, opts := RunServerWithConfig(conf) 1205 defer s.Shutdown() 1206 1207 var port int 1208 switch i { 1209 case 0: 1210 port = opts.Port 1211 case 1: 1212 port = s.ClusterAddr().Port 1213 case 2: 1214 port = s.GatewayAddr().Port 1215 } 1216 1217 varz, _ := s.Varz(nil) 1218 base := varz.Mem 1219 buf := make([]byte, 1024*1024) 1220 for i := 0; i < 100; i++ { 1221 conn, err := net.Dial("tcp", fmt.Sprintf("localhost:%d", port)) 1222 if err != nil { 1223 t.Fatalf("Error on dial: %v", err) 1224 } 1225 conn.SetWriteDeadline(time.Now().Add(10 * time.Millisecond)) 1226 conn.Write(buf) 1227 conn.Close() 1228 } 1229 1230 varz, _ = s.Varz(nil) 1231 newval := (varz.Mem - base) / (1024 * 1024) 1232 // May need to adjust that, but right now, with 100 clients 1233 // we are at about 20MB for client port, 11MB for route 1234 // and 6MB for gateways, so pick 50MB as the threshold 1235 if newval >= 50 { 1236 t.Fatalf("Consumed too much memory: %v MB", newval) 1237 } 1238 }) 1239 } 1240 } 1241 1242 func TestTLSClientAuthWithRDNSequence(t *testing.T) { 1243 for _, test := range []struct { 1244 name string 1245 config string 1246 certs nats.Option 1247 err error 1248 rerr error 1249 }{ 1250 // To generate certs for these tests: 1251 // USE `regenerate_rdns_svid.sh` TO REGENERATE 1252 // 1253 // ``` 1254 // openssl req -newkey rsa:2048 -nodes -keyout client-$CLIENT_ID.key -subj "/C=US/ST=CA/L=Los Angeles/OU=NATS/O=NATS/CN=*.example.com/DC=example/DC=com" -addext extendedKeyUsage=clientAuth -out client-$CLIENT_ID.csr 1255 // openssl x509 -req -extfile <(printf "subjectAltName=DNS:localhost,DNS:example.com,DNS:www.example.com") -days 1825 -in client-$CLIENT_ID.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out client-$CLIENT_ID.pem 1256 // ``` 1257 // 1258 // To confirm subject from cert: 1259 // 1260 // ``` 1261 // openssl x509 -in client-$CLIENT_ID.pem -text | grep Subject: 1262 // ``` 1263 // 1264 { 1265 "connect with tls using full RDN sequence", 1266 ` 1267 port: -1 1268 %s 1269 1270 authorization { 1271 users = [ 1272 { user = "CN=localhost,OU=NATS,O=NATS,L=Los Angeles,ST=CA,C=US,DC=foo1,DC=foo2" } 1273 ] 1274 } 1275 `, 1276 // C = US, ST = CA, L = Los Angeles, O = NATS, OU = NATS, CN = localhost, DC = foo1, DC = foo2 1277 nats.ClientCert("./configs/certs/rdns/client-a.pem", "./configs/certs/rdns/client-a.key"), 1278 nil, 1279 nil, 1280 }, 1281 { 1282 "connect with tls using full RDN sequence in original order", 1283 ` 1284 port: -1 1285 %s 1286 1287 authorization { 1288 users = [ 1289 { user = "DC=foo2,DC=foo1,CN=localhost,OU=NATS,O=NATS,L=Los Angeles,ST=CA,C=US" } 1290 ] 1291 } 1292 `, 1293 // C = US, ST = CA, L = Los Angeles, O = NATS, OU = NATS, CN = localhost, DC = foo1, DC = foo2 1294 nats.ClientCert("./configs/certs/rdns/client-a.pem", "./configs/certs/rdns/client-a.key"), 1295 nil, 1296 nil, 1297 }, 1298 { 1299 "connect with tls using partial RDN sequence has different permissions", 1300 ` 1301 port: -1 1302 %s 1303 1304 authorization { 1305 users = [ 1306 { user = "DC=foo2,DC=foo1,CN=localhost,OU=NATS,O=NATS,L=Los Angeles,ST=CA,C=US" }, 1307 { user = "CN=localhost,OU=NATS,O=NATS,L=Los Angeles,ST=CA,C=US,DC=foo1,DC=foo2" }, 1308 { user = "CN=localhost,OU=NATS,O=NATS,L=Los Angeles,ST=CA,C=US", 1309 permissions = { subscribe = { deny = ">" }} } 1310 ] 1311 } 1312 `, 1313 // C = US, ST = California, L = Los Angeles, O = NATS, OU = NATS, CN = localhost 1314 nats.ClientCert("./configs/certs/rdns/client-b.pem", "./configs/certs/rdns/client-b.key"), 1315 nil, 1316 errors.New("nats: timeout"), 1317 }, 1318 { 1319 "connect with tls and RDN sequence partially matches", 1320 ` 1321 port: -1 1322 %s 1323 1324 authorization { 1325 users = [ 1326 { user = "DC=foo2,DC=foo1,CN=localhost,OU=NATS,O=NATS,L=Los Angeles,ST=CA,C=US" } 1327 { user = "CN=localhost,OU=NATS,O=NATS,L=Los Angeles,ST=CA,C=US,DC=foo1,DC=foo2" } 1328 { user = "CN=localhost,OU=NATS,O=NATS,L=Los Angeles,ST=CA,C=US"}, 1329 ] 1330 } 1331 `, 1332 // Cert is: 1333 // 1334 // C = US, ST = CA, L = Los Angeles, O = NATS, OU = NATS, CN = localhost, DC = foo3, DC = foo4 1335 // 1336 // but it will actually match the user without DCs so will not get an error: 1337 // 1338 // C = US, ST = CA, L = Los Angeles, O = NATS, OU = NATS, CN = localhost 1339 // 1340 nats.ClientCert("./configs/certs/rdns/client-c.pem", "./configs/certs/rdns/client-c.key"), 1341 nil, 1342 nil, 1343 }, 1344 { 1345 "connect with tls and RDN sequence does not match", 1346 ` 1347 port: -1 1348 %s 1349 1350 authorization { 1351 users = [ 1352 { user = "CN=localhost,OU=NATS,O=NATS,L=Los Angeles,ST=CA,C=US,DC=foo1,DC=foo2" }, 1353 { user = "DC=foo2,DC=foo1,CN=localhost,OU=NATS,O=NATS,L=Los Angeles,ST=CA,C=US" } 1354 ] 1355 } 1356 `, 1357 // C = US, ST = California, L = Los Angeles, O = NATS, OU = NATS, CN = localhost, DC = foo3, DC = foo4 1358 // 1359 nats.ClientCert("./configs/certs/rdns/client-c.pem", "./configs/certs/rdns/client-c.key"), 1360 errors.New("nats: Authorization Violation"), 1361 nil, 1362 }, 1363 { 1364 "connect with tls and RDN sequence with space after comma not should matter", 1365 ` 1366 port: -1 1367 %s 1368 1369 authorization { 1370 users = [ 1371 { user = "DC=foo2, DC=foo1, CN=localhost, OU=NATS, O=NATS, L=Los Angeles, ST=CA, C=US" } 1372 ] 1373 } 1374 `, 1375 // C=US/ST=California/L=Los Angeles/O=NATS/OU=NATS/CN=localhost/DC=foo1/DC=foo2 1376 // 1377 nats.ClientCert("./configs/certs/rdns/client-a.pem", "./configs/certs/rdns/client-a.key"), 1378 nil, 1379 nil, 1380 }, 1381 { 1382 "connect with tls and full RDN sequence respects order", 1383 ` 1384 port: -1 1385 %s 1386 1387 authorization { 1388 users = [ 1389 { user = "DC=com, DC=example, CN=*.example.com, O=NATS, OU=NATS, L=Los Angeles, ST=CA, C=US" } 1390 ] 1391 } 1392 `, 1393 // 1394 // C = US, ST = CA, L = Los Angeles, OU = NATS, O = NATS, CN = *.example.com, DC = example, DC = com 1395 // 1396 nats.ClientCert("./configs/certs/rdns/client-d.pem", "./configs/certs/rdns/client-d.key"), 1397 nil, 1398 nil, 1399 }, 1400 { 1401 "connect with tls and full RDN sequence with added domainComponents and spaces also matches", 1402 ` 1403 port: -1 1404 %s 1405 1406 authorization { 1407 users = [ 1408 { user = "CN=*.example.com,OU=NATS,O=NATS,L=Los Angeles,ST=CA,C=US,DC=example,DC=com" } 1409 ] 1410 } 1411 `, 1412 // 1413 // C = US, ST = CA, L = Los Angeles, OU = NATS, O = NATS, CN = *.example.com, DC = example, DC = com 1414 // 1415 nats.ClientCert("./configs/certs/rdns/client-d.pem", "./configs/certs/rdns/client-d.key"), 1416 nil, 1417 nil, 1418 }, 1419 { 1420 "connect with tls and full RDN sequence with correct order takes precedence over others matches", 1421 ` 1422 port: -1 1423 %s 1424 1425 authorization { 1426 users = [ 1427 { user = "CN=*.example.com,OU=NATS,O=NATS,L=Los Angeles,ST=CA,C=US,DC=example,DC=com", 1428 permissions = { subscribe = { deny = ">" }} } 1429 1430 # This should take precedence since it is in the RFC2253 order. 1431 { user = "DC=com,DC=example,CN=*.example.com,O=NATS,OU=NATS,L=Los Angeles,ST=CA,C=US" } 1432 1433 { user = "CN=*.example.com,OU=NATS,O=NATS,L=Los Angeles,ST=CA,C=US", 1434 permissions = { subscribe = { deny = ">" }} } 1435 ] 1436 } 1437 `, 1438 // 1439 // C = US, ST = CA, L = Los Angeles, OU = NATS, O = NATS, CN = *.example.com, DC = example, DC = com 1440 // 1441 nats.ClientCert("./configs/certs/rdns/client-d.pem", "./configs/certs/rdns/client-d.key"), 1442 nil, 1443 nil, 1444 }, 1445 { 1446 "connect with tls and RDN includes multiple CN elements", 1447 ` 1448 port: -1 1449 %s 1450 1451 authorization { 1452 users = [ 1453 { user = "DC=com,DC=acme,OU=Organic Units,OU=Users,CN=jdoe,CN=123456,CN=John Doe" } 1454 ] 1455 } 1456 `, 1457 // 1458 // OpenSSL: -subj "/CN=John Doe/CN=123456/CN=jdoe/OU=Users/OU=Organic Units/DC=acme/DC=com" 1459 // Go: CN=jdoe,OU=Users+OU=Organic Units 1460 // RFC2253: DC=com,DC=acme,OU=Organic Units,OU=Users,CN=jdoe,CN=123456,CN=John Doe 1461 // 1462 nats.ClientCert("./configs/certs/rdns/client-e.pem", "./configs/certs/rdns/client-e.key"), 1463 nil, 1464 nil, 1465 }, 1466 { 1467 "connect with tls and DN includes a multi value RDN", 1468 ` 1469 port: -1 1470 %s 1471 1472 authorization { 1473 users = [ 1474 { user = "CN=John Doe,DC=DEV+O=users,DC=OpenSSL,DC=org" } 1475 ] 1476 } 1477 `, 1478 // 1479 // OpenSSL: -subj "/DC=org/DC=OpenSSL/DC=DEV+O=users/CN=John Doe" -multivalue-rdn 1480 // Go: CN=John Doe,O=users 1481 // RFC2253: CN=John Doe,DC=DEV+O=users,DC=OpenSSL,DC=org 1482 // 1483 nats.ClientCert("./configs/certs/rdns/client-f.pem", "./configs/certs/rdns/client-f.key"), 1484 nil, 1485 nil, 1486 }, 1487 { 1488 "connect with tls and DN includes a multi value RDN but there is no match", 1489 ` 1490 port: -1 1491 %s 1492 1493 authorization { 1494 users = [ 1495 { user = "CN=John Doe,DC=DEV,DC=OpenSSL,DC=org" } 1496 ] 1497 } 1498 `, 1499 // 1500 // OpenSSL: -subj "/DC=org/DC=OpenSSL/DC=DEV+O=users/CN=John Doe" -multivalue-rdn 1501 // Go: CN=John Doe,O=users 1502 // RFC2253: CN=John Doe,DC=DEV+O=users,DC=OpenSSL,DC=org 1503 // 1504 nats.ClientCert("./configs/certs/rdns/client-f.pem", "./configs/certs/rdns/client-f.key"), 1505 errors.New("nats: Authorization Violation"), 1506 nil, 1507 }, 1508 { 1509 "connect with tls and DN includes a multi value RDN that are reordered", 1510 ` 1511 port: -1 1512 %s 1513 1514 authorization { 1515 users = [ 1516 { user = "CN=John Doe,O=users+DC=DEV,DC=OpenSSL,DC=org" } 1517 ] 1518 } 1519 `, 1520 // 1521 // OpenSSL: -subj "/DC=org/DC=OpenSSL/DC=DEV+O=users/CN=John Doe" -multivalue-rdn 1522 // Go: CN=John Doe,O=users 1523 // RFC2253: CN=John Doe,DC=DEV+O=users,DC=OpenSSL,DC=org 1524 // 1525 nats.ClientCert("./configs/certs/rdns/client-f.pem", "./configs/certs/rdns/client-f.key"), 1526 nil, 1527 nil, 1528 }, 1529 } { 1530 t.Run(test.name, func(t *testing.T) { 1531 content := fmt.Sprintf(test.config, ` 1532 tls { 1533 cert_file: "configs/certs/rdns/server.pem" 1534 key_file: "configs/certs/rdns/server.key" 1535 ca_file: "configs/certs/rdns/ca.pem" 1536 timeout: 5 1537 verify_and_map: true 1538 } 1539 `) 1540 conf := createConfFile(t, []byte(content)) 1541 s, opts := RunServerWithConfig(conf) 1542 defer s.Shutdown() 1543 1544 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 1545 test.certs, 1546 nats.RootCAs("./configs/certs/rdns/ca.pem"), 1547 nats.ErrorHandler(noOpErrHandler), 1548 ) 1549 if test.err == nil && err != nil { 1550 t.Errorf("Expected to connect, got %v", err) 1551 } else if test.err != nil && err == nil { 1552 t.Errorf("Expected error on connect") 1553 } else if test.err != nil && err != nil { 1554 // Error on connect was expected 1555 if test.err.Error() != err.Error() { 1556 t.Errorf("Expected error %s, got: %s", test.err, err) 1557 } 1558 return 1559 } 1560 defer nc.Close() 1561 1562 nc.Subscribe("ping", func(m *nats.Msg) { 1563 m.Respond([]byte("pong")) 1564 }) 1565 nc.Flush() 1566 1567 _, err = nc.Request("ping", []byte("ping"), 250*time.Millisecond) 1568 if test.rerr != nil && err == nil { 1569 t.Errorf("Expected error getting response") 1570 } else if test.rerr == nil && err != nil { 1571 t.Errorf("Expected response") 1572 } 1573 }) 1574 } 1575 } 1576 1577 func TestTLSClientAuthWithRDNSequenceReordered(t *testing.T) { 1578 for _, test := range []struct { 1579 name string 1580 config string 1581 certs nats.Option 1582 err error 1583 rerr error 1584 }{ 1585 { 1586 "connect with tls and DN includes a multi value RDN that are reordered", 1587 ` 1588 port: -1 1589 %s 1590 1591 authorization { 1592 users = [ 1593 { user = "DC=org,DC=OpenSSL,O=users+DC=DEV,CN=John Doe" } 1594 ] 1595 } 1596 `, 1597 // 1598 // OpenSSL: -subj "/DC=org/DC=OpenSSL/DC=DEV+O=users/CN=John Doe" -multivalue-rdn 1599 // Go: CN=John Doe,O=users 1600 // RFC2253: CN=John Doe,DC=DEV+O=users,DC=OpenSSL,DC=org 1601 // 1602 nats.ClientCert("./configs/certs/rdns/client-f.pem", "./configs/certs/rdns/client-f.key"), 1603 nil, 1604 nil, 1605 }, 1606 { 1607 "connect with tls and DN includes a multi value RDN that are reordered but not equal RDNs", 1608 ` 1609 port: -1 1610 %s 1611 1612 authorization { 1613 users = [ 1614 { user = "DC=org,DC=OpenSSL,O=users,CN=John Doe" } 1615 ] 1616 } 1617 `, 1618 // 1619 // OpenSSL: -subj "/DC=org/DC=OpenSSL/DC=DEV+O=users/CN=John Doe" -multivalue-rdn 1620 // Go: CN=John Doe,O=users 1621 // RFC2253: CN=John Doe,DC=DEV+O=users,DC=OpenSSL,DC=org 1622 // 1623 nats.ClientCert("./configs/certs/rdns/client-f.pem", "./configs/certs/rdns/client-f.key"), 1624 errors.New("nats: Authorization Violation"), 1625 nil, 1626 }, 1627 { 1628 "connect with tls and DN includes a multi value RDN that are reordered but not equal RDNs", 1629 ` 1630 port: -1 1631 %s 1632 1633 authorization { 1634 users = [ 1635 { user = "DC=OpenSSL, DC=org, O=users, CN=John Doe" } 1636 ] 1637 } 1638 `, 1639 // 1640 // OpenSSL: -subj "/DC=org/DC=OpenSSL/DC=DEV+O=users/CN=John Doe" -multivalue-rdn 1641 // Go: CN=John Doe,O=users 1642 // RFC2253: CN=John Doe,DC=DEV+O=users,DC=OpenSSL,DC=org 1643 // 1644 nats.ClientCert("./configs/certs/rdns/client-f.pem", "./configs/certs/rdns/client-f.key"), 1645 errors.New("nats: Authorization Violation"), 1646 nil, 1647 }, 1648 } { 1649 t.Run(test.name, func(t *testing.T) { 1650 content := fmt.Sprintf(test.config, ` 1651 tls { 1652 cert_file: "configs/certs/rdns/server.pem" 1653 key_file: "configs/certs/rdns/server.key" 1654 ca_file: "configs/certs/rdns/ca.pem" 1655 timeout: 5 1656 verify_and_map: true 1657 } 1658 `) 1659 conf := createConfFile(t, []byte(content)) 1660 s, opts := RunServerWithConfig(conf) 1661 defer s.Shutdown() 1662 1663 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 1664 test.certs, 1665 nats.RootCAs("./configs/certs/rdns/ca.pem"), 1666 ) 1667 if test.err == nil && err != nil { 1668 t.Errorf("Expected to connect, got %v", err) 1669 } else if test.err != nil && err == nil { 1670 t.Errorf("Expected error on connect") 1671 } else if test.err != nil && err != nil { 1672 // Error on connect was expected 1673 if test.err.Error() != err.Error() { 1674 t.Errorf("Expected error %s, got: %s", test.err, err) 1675 } 1676 return 1677 } 1678 defer nc.Close() 1679 1680 nc.Subscribe("ping", func(m *nats.Msg) { 1681 m.Respond([]byte("pong")) 1682 }) 1683 nc.Flush() 1684 1685 _, err = nc.Request("ping", []byte("ping"), 250*time.Millisecond) 1686 if test.rerr != nil && err == nil { 1687 t.Errorf("Expected error getting response") 1688 } else if test.rerr == nil && err != nil { 1689 t.Errorf("Expected response") 1690 } 1691 }) 1692 } 1693 } 1694 1695 func TestTLSClientSVIDAuth(t *testing.T) { 1696 for _, test := range []struct { 1697 name string 1698 config string 1699 certs nats.Option 1700 err error 1701 rerr error 1702 }{ 1703 { 1704 "connect with tls using certificate with URIs", 1705 ` 1706 port: -1 1707 %s 1708 1709 authorization { 1710 users = [ 1711 { 1712 user = "spiffe://localhost/my-nats-service/user-a" 1713 } 1714 ] 1715 } 1716 `, 1717 nats.ClientCert("./configs/certs/svid/client-a.pem", "./configs/certs/svid/client-a.key"), 1718 nil, 1719 nil, 1720 }, 1721 { 1722 "connect with tls using certificate with limited different permissions", 1723 ` 1724 port: -1 1725 %s 1726 1727 authorization { 1728 users = [ 1729 { 1730 user = "spiffe://localhost/my-nats-service/user-a" 1731 }, 1732 { 1733 user = "spiffe://localhost/my-nats-service/user-b" 1734 permissions = { subscribe = { deny = ">" }} 1735 } 1736 ] 1737 } 1738 `, 1739 nats.ClientCert("./configs/certs/svid/client-b.pem", "./configs/certs/svid/client-b.key"), 1740 nil, 1741 errors.New("nats: timeout"), 1742 }, 1743 { 1744 "connect with tls without URIs in permissions will still match SAN", 1745 ` 1746 port: -1 1747 %s 1748 1749 authorization { 1750 users = [ 1751 { 1752 user = "O=SPIRE,C=US" 1753 } 1754 ] 1755 } 1756 `, 1757 nats.ClientCert("./configs/certs/svid/client-b.pem", "./configs/certs/svid/client-b.key"), 1758 nil, 1759 nil, 1760 }, 1761 { 1762 "connect with tls but no permissions", 1763 ` 1764 port: -1 1765 %s 1766 1767 authorization { 1768 users = [ 1769 { 1770 user = "spiffe://localhost/my-nats-service/user-c" 1771 } 1772 ] 1773 } 1774 `, 1775 nats.ClientCert("./configs/certs/svid/client-a.pem", "./configs/certs/svid/client-a.key"), 1776 errors.New("nats: Authorization Violation"), 1777 nil, 1778 }, 1779 } { 1780 t.Run(test.name, func(t *testing.T) { 1781 content := fmt.Sprintf(test.config, ` 1782 tls { 1783 cert_file: "configs/certs/svid/server.pem" 1784 key_file: "configs/certs/svid/server.key" 1785 ca_file: "configs/certs/svid/ca.pem" 1786 timeout: 5 1787 insecure: true 1788 verify_and_map: true 1789 } 1790 `) 1791 conf := createConfFile(t, []byte(content)) 1792 s, opts := RunServerWithConfig(conf) 1793 defer s.Shutdown() 1794 1795 nc, err := nats.Connect(fmt.Sprintf("tls://localhost:%d", opts.Port), 1796 test.certs, 1797 nats.RootCAs("./configs/certs/svid/ca.pem"), 1798 nats.ErrorHandler(noOpErrHandler), 1799 ) 1800 if test.err == nil && err != nil { 1801 t.Errorf("Expected to connect, got %v", err) 1802 } else if test.err != nil && err == nil { 1803 t.Errorf("Expected error on connect") 1804 } else if test.err != nil && err != nil { 1805 // Error on connect was expected 1806 if test.err.Error() != err.Error() { 1807 t.Errorf("Expected error %s, got: %s", test.err, err) 1808 } 1809 return 1810 } 1811 defer nc.Close() 1812 1813 nc.Subscribe("ping", func(m *nats.Msg) { 1814 m.Respond([]byte("pong")) 1815 }) 1816 nc.Flush() 1817 1818 _, err = nc.Request("ping", []byte("ping"), 250*time.Millisecond) 1819 if test.rerr != nil && err == nil { 1820 t.Errorf("Expected error getting response") 1821 } else if test.rerr == nil && err != nil { 1822 t.Errorf("Expected response") 1823 } 1824 }) 1825 } 1826 } 1827 1828 func TestTLSPinnedCertsClient(t *testing.T) { 1829 tmpl := ` 1830 host: localhost 1831 port: -1 1832 tls { 1833 ca_file: "configs/certs/ca.pem" 1834 cert_file: "configs/certs/server-cert.pem" 1835 key_file: "configs/certs/server-key.pem" 1836 # Require a client certificate and map user id from certificate 1837 verify: true 1838 pinned_certs: ["%s"] 1839 }` 1840 1841 confFileName := createConfFile(t, []byte(fmt.Sprintf(tmpl, "aaaaaaaa09fde09451411ba3b42c0f74727d61a974c69fd3cf5257f39c75f0e9"))) 1842 srv, o := RunServerWithConfig(confFileName) 1843 defer srv.Shutdown() 1844 1845 if len(o.TLSPinnedCerts) != 1 { 1846 t.Fatal("expected one pinned cert") 1847 } 1848 1849 opts := []nats.Option{ 1850 nats.RootCAs("configs/certs/ca.pem"), 1851 nats.ClientCert("./configs/certs/client-cert.pem", "./configs/certs/client-key.pem"), 1852 } 1853 1854 nc, err := nats.Connect(srv.ClientURL(), opts...) 1855 if err == nil { 1856 nc.Close() 1857 t.Fatalf("Expected error trying to connect without a certificate in pinned_certs") 1858 } 1859 1860 os.WriteFile(confFileName, []byte(fmt.Sprintf(tmpl, "bf6f821f09fde09451411ba3b42c0f74727d61a974c69fd3cf5257f39c75f0e9")), 0660) 1861 if err := srv.Reload(); err != nil { 1862 t.Fatalf("on Reload got %v", err) 1863 } 1864 // reload pinned to the certs used 1865 nc, err = nats.Connect(srv.ClientURL(), opts...) 1866 if err != nil { 1867 t.Fatalf("Expected no error, got: %v", err) 1868 } 1869 nc.Close() 1870 } 1871 1872 type captureWarnLogger struct { 1873 dummyLogger 1874 receive chan string 1875 } 1876 1877 func newCaptureWarnLogger() *captureWarnLogger { 1878 return &captureWarnLogger{ 1879 receive: make(chan string, 100), 1880 } 1881 } 1882 1883 func (l *captureWarnLogger) Warnf(format string, v ...interface{}) { 1884 l.receive <- fmt.Sprintf(format, v...) 1885 } 1886 1887 func (l *captureWarnLogger) waitFor(expect string, timeout time.Duration) bool { 1888 for { 1889 select { 1890 case msg := <-l.receive: 1891 if strings.Contains(msg, expect) { 1892 return true 1893 } 1894 case <-time.After(timeout): 1895 return false 1896 } 1897 } 1898 } 1899 1900 func TestTLSConnectionRate(t *testing.T) { 1901 config := ` 1902 listen: "127.0.0.1:-1" 1903 tls { 1904 cert_file: "./configs/certs/server-cert.pem" 1905 key_file: "./configs/certs/server-key.pem" 1906 connection_rate_limit: 3 1907 } 1908 ` 1909 1910 confFileName := createConfFile(t, []byte(config)) 1911 1912 srv, _ := RunServerWithConfig(confFileName) 1913 logger := newCaptureWarnLogger() 1914 srv.SetLogger(logger, false, false) 1915 defer srv.Shutdown() 1916 1917 var err error 1918 count := 0 1919 for count < 10 { 1920 var nc *nats.Conn 1921 nc, err = nats.Connect(srv.ClientURL(), nats.RootCAs("./configs/certs/ca.pem")) 1922 1923 if err != nil { 1924 break 1925 } 1926 nc.Close() 1927 count++ 1928 } 1929 1930 if count != 3 { 1931 t.Fatalf("Expected 3 connections per second, got %d (%v)", count, err) 1932 } 1933 1934 if !logger.waitFor("connections due to TLS rate limiting", time.Second) { 1935 t.Fatalf("did not log 'TLS rate limiting' warning") 1936 } 1937 } 1938 1939 func TestTLSPinnedCertsRoute(t *testing.T) { 1940 tmplSeed := ` 1941 host: localhost 1942 port: -1 1943 cluster { 1944 port: -1 1945 pool_size: -1 1946 tls { 1947 ca_file: "configs/certs/ca.pem" 1948 cert_file: "configs/certs/server-cert.pem" 1949 key_file: "configs/certs/server-key.pem" 1950 } 1951 }` 1952 // this server connects to seed, but is set up to not trust seeds cert 1953 tmplSrv := ` 1954 host: localhost 1955 port: -1 1956 cluster { 1957 port: -1 1958 routes = [nats-route://localhost:%d] 1959 tls { 1960 ca_file: "configs/certs/ca.pem" 1961 cert_file: "configs/certs/server-cert.pem" 1962 key_file: "configs/certs/server-key.pem" 1963 # Require a client certificate and map user id from certificate 1964 verify: true 1965 # expected to fail the seed server 1966 pinned_certs: ["%s"] 1967 } 1968 }` 1969 1970 confSeed := createConfFile(t, []byte(tmplSeed)) 1971 srvSeed, o := RunServerWithConfig(confSeed) 1972 defer srvSeed.Shutdown() 1973 1974 confSrv := createConfFile(t, []byte(fmt.Sprintf(tmplSrv, o.Cluster.Port, "89386860ea1222698ea676fc97310bdf2bff6f7e2b0420fac3b3f8f5a08fede5"))) 1975 srv, _ := RunServerWithConfig(confSrv) 1976 defer srv.Shutdown() 1977 1978 checkClusterFormed(t, srvSeed, srv) 1979 1980 // this change will result in the server being and remaining disconnected 1981 os.WriteFile(confSrv, []byte(fmt.Sprintf(tmplSrv, o.Cluster.Port, "aaaaaaaa09fde09451411ba3b42c0f74727d61a974c69fd3cf5257f39c75f0e9")), 0660) 1982 if err := srv.Reload(); err != nil { 1983 t.Fatalf("on Reload got %v", err) 1984 } 1985 1986 checkNumRoutes(t, srvSeed, 0) 1987 checkNumRoutes(t, srv, 0) 1988 } 1989 1990 func TestAllowNonTLSReload(t *testing.T) { 1991 tmpl := ` 1992 listen: "127.0.0.1:-1" 1993 ping_interval: "%s" 1994 tls { 1995 ca_file: "configs/certs/ca.pem" 1996 cert_file: "configs/certs/server-cert.pem" 1997 key_file: "configs/certs/server-key.pem" 1998 } 1999 allow_non_tls: true 2000 ` 2001 conf := createConfFile(t, []byte(fmt.Sprintf(tmpl, "10s"))) 2002 s, o := RunServerWithConfig(conf) 2003 defer s.Shutdown() 2004 2005 check := func() { 2006 t.Helper() 2007 nc := createClientConn(t, "127.0.0.1", o.Port) 2008 defer nc.Close() 2009 info := checkInfoMsg(t, nc) 2010 if !info.TLSAvailable { 2011 t.Fatal("TLSAvailable should be true, was false") 2012 } 2013 if info.TLSRequired { 2014 t.Fatal("TLSRequired should be false, was true") 2015 } 2016 } 2017 check() 2018 2019 os.WriteFile(conf, []byte(fmt.Sprintf(tmpl, "20s")), 0660) 2020 if err := s.Reload(); err != nil { 2021 t.Fatalf("Error on reload: %v", err) 2022 } 2023 check() 2024 }