1package tlsutil 2 3import ( 4 "crypto/tls" 5 "crypto/x509" 6 "fmt" 7 "io/ioutil" 8 "net" 9 "os" 10 "path/filepath" 11 "sort" 12 "strings" 13 "sync" 14 "time" 15 16 "github.com/hashicorp/go-hclog" 17 "github.com/hashicorp/go-multierror" 18 19 "github.com/hashicorp/consul/logging" 20) 21 22// ALPNWrapper is a function that is used to wrap a non-TLS connection and 23// returns an appropriate TLS connection or error. This taks a datacenter and 24// node name as argument to configure the desired SNI value and the desired 25// next proto for configuring ALPN. 26type ALPNWrapper func(dc, nodeName, alpnProto string, conn net.Conn) (net.Conn, error) 27 28// DCWrapper is a function that is used to wrap a non-TLS connection 29// and returns an appropriate TLS connection or error. This takes 30// a datacenter as an argument. 31type DCWrapper func(dc string, conn net.Conn) (net.Conn, error) 32 33// Wrapper is a variant of DCWrapper, where the DC is provided as 34// a constant value. This is usually done by currying DCWrapper. 35type Wrapper func(conn net.Conn) (net.Conn, error) 36 37// TLSLookup maps the tls_min_version configuration to the internal value 38var TLSLookup = map[string]uint16{ 39 "": tls.VersionTLS10, // default in golang 40 "tls10": tls.VersionTLS10, 41 "tls11": tls.VersionTLS11, 42 "tls12": tls.VersionTLS12, 43 "tls13": tls.VersionTLS13, 44} 45 46// TLSVersions has all the keys from the map above. 47var TLSVersions = strings.Join(tlsVersions(), ", ") 48 49// Config used to create tls.Config 50type Config struct { 51 // VerifyIncoming is used to verify the authenticity of incoming 52 // connections. This means that TCP requests are forbidden, only 53 // allowing for TLS. TLS connections must match a provided certificate 54 // authority. This can be used to force client auth. 55 VerifyIncoming bool 56 57 // VerifyIncomingRPC is used to verify the authenticity of incoming RPC 58 // connections. This means that TCP requests are forbidden, only 59 // allowing for TLS. TLS connections must match a provided certificate 60 // authority. This can be used to force client auth. 61 VerifyIncomingRPC bool 62 63 // VerifyIncomingHTTPS is used to verify the authenticity of incoming 64 // HTTPS connections. This means that TCP requests are forbidden, only 65 // allowing for TLS. TLS connections must match a provided certificate 66 // authority. This can be used to force client auth. 67 VerifyIncomingHTTPS bool 68 69 // VerifyOutgoing is used to verify the authenticity of outgoing 70 // connections. This means that TLS requests are used, and TCP 71 // requests are not made. TLS connections must match a provided 72 // certificate authority. This is used to verify authenticity of server 73 // nodes. 74 VerifyOutgoing bool 75 76 // VerifyServerHostname is used to enable hostname verification of 77 // servers. This ensures that the certificate presented is valid for 78 // server.<datacenter>.<domain>. This prevents a compromised client 79 // from being restarted as a server, and then intercepting request 80 // traffic as well as being added as a raft peer. This should be 81 // enabled by default with VerifyOutgoing, but for legacy reasons we 82 // cannot break existing clients. 83 VerifyServerHostname bool 84 85 // CAFile is a path to a certificate authority file. This is used with 86 // VerifyIncoming or VerifyOutgoing to verify the TLS connection. 87 CAFile string 88 89 // CAPath is a path to a directory containing certificate authority 90 // files. This is used with VerifyIncoming or VerifyOutgoing to verify 91 // the TLS connection. 92 CAPath string 93 94 // CertFile is used to provide a TLS certificate that is used for 95 // serving TLS connections. Must be provided to serve TLS connections. 96 CertFile string 97 98 // KeyFile is used to provide a TLS key that is used for serving TLS 99 // connections. Must be provided to serve TLS connections. 100 KeyFile string 101 102 // Node name is the name we use to advertise. Defaults to hostname. 103 NodeName string 104 105 // ServerName is used with the TLS certificate to ensure the name we 106 // provide matches the certificate 107 ServerName string 108 109 // Domain is the Consul TLD being used. Defaults to "consul." 110 Domain string 111 112 // TLSMinVersion is the minimum accepted TLS version that can be used. 113 TLSMinVersion string 114 115 // CipherSuites is the list of TLS cipher suites to use. 116 CipherSuites []uint16 117 118 // PreferServerCipherSuites specifies whether to prefer the server's 119 // ciphersuite over the client ciphersuites. 120 PreferServerCipherSuites bool 121 122 // EnableAgentTLSForChecks is used to apply the agent's TLS settings in 123 // order to configure the HTTP client used for health checks. Enabling 124 // this allows HTTP checks to present a client certificate and verify 125 // the server using the same TLS configuration as the agent (CA, cert, 126 // and key). 127 EnableAgentTLSForChecks bool 128 129 // AutoTLS opts the agent into provisioning agent 130 // TLS certificates. 131 AutoTLS bool 132} 133 134func tlsVersions() []string { 135 versions := []string{} 136 for v := range TLSLookup { 137 if v != "" { 138 versions = append(versions, v) 139 } 140 } 141 sort.Strings(versions) 142 return versions 143} 144 145// KeyPair is used to open and parse a certificate and key file 146func (c *Config) KeyPair() (*tls.Certificate, error) { 147 return loadKeyPair(c.CertFile, c.KeyFile) 148} 149 150// SpecificDC is used to invoke a static datacenter 151// and turns a DCWrapper into a Wrapper type. 152func SpecificDC(dc string, tlsWrap DCWrapper) Wrapper { 153 if tlsWrap == nil { 154 return nil 155 } 156 return func(conn net.Conn) (net.Conn, error) { 157 return tlsWrap(dc, conn) 158 } 159} 160 161type autoTLS struct { 162 extraCAPems []string 163 connectCAPems []string 164 cert *tls.Certificate 165 verifyServerHostname bool 166} 167 168// manual stores the TLS CA and cert received from Configurator.Update which 169// generally comes from the agent configuration. 170type manual struct { 171 caPems []string 172 cert *tls.Certificate 173 // caPool containing only the caPems. This CertPool should be used instead of 174 // the Configurator.caPool when only the Agent TLS CA is allowed. 175 caPool *x509.CertPool 176} 177 178// Configurator holds a Config and is responsible for generating all the 179// *tls.Config necessary for Consul. Except the one in the api package. 180type Configurator struct { 181 sync.RWMutex 182 base *Config 183 autoTLS *autoTLS 184 manual *manual 185 peerDatacenterUseTLS map[string]bool 186 187 caPool *x509.CertPool 188 logger hclog.Logger 189 version int 190} 191 192// NewConfigurator creates a new Configurator and sets the provided 193// configuration. 194func NewConfigurator(config Config, logger hclog.Logger) (*Configurator, error) { 195 if logger == nil { 196 logger = hclog.New(&hclog.LoggerOptions{ 197 Level: hclog.Debug, 198 }) 199 } 200 201 c := &Configurator{ 202 logger: logger.Named(logging.TLSUtil), 203 manual: &manual{}, 204 autoTLS: &autoTLS{}, 205 peerDatacenterUseTLS: map[string]bool{}, 206 } 207 err := c.Update(config) 208 if err != nil { 209 return nil, err 210 } 211 return c, nil 212} 213 214// ManualCAPems returns the currently loaded CAs in PEM format. 215func (c *Configurator) ManualCAPems() []string { 216 c.RLock() 217 defer c.RUnlock() 218 return c.manual.caPems 219} 220 221// Update updates the internal configuration which is used to generate 222// *tls.Config. 223// This function acquires a write lock because it writes the new config. 224func (c *Configurator) Update(config Config) error { 225 c.Lock() 226 // order of defers matters because log acquires a RLock() 227 defer c.log("Update") 228 defer c.Unlock() 229 230 cert, err := loadKeyPair(config.CertFile, config.KeyFile) 231 if err != nil { 232 return err 233 } 234 pems, err := LoadCAs(config.CAFile, config.CAPath) 235 if err != nil { 236 return err 237 } 238 caPool, err := newX509CertPool(pems, c.autoTLS.extraCAPems, c.autoTLS.connectCAPems) 239 if err != nil { 240 return err 241 } 242 if err = c.check(config, caPool, cert); err != nil { 243 return err 244 } 245 manualCAPool, err := newX509CertPool(pems) 246 if err != nil { 247 return err 248 } 249 250 c.base = &config 251 c.manual.cert = cert 252 c.manual.caPool = manualCAPool 253 c.manual.caPems = pems 254 c.caPool = caPool 255 c.version++ 256 return nil 257} 258 259// UpdateAutoTLSCA updates the autoEncrypt.caPems. This is supposed to be called 260// from the server in order to be able to accept TLS connections with TLS 261// certificates. 262// Or it is being called on the client side when CA changes are detected. 263func (c *Configurator) UpdateAutoTLSCA(connectCAPems []string) error { 264 c.Lock() 265 // order of defers matters because log acquires a RLock() 266 defer c.log("UpdateAutoEncryptCA") 267 defer c.Unlock() 268 269 pool, err := newX509CertPool(c.manual.caPems, c.autoTLS.extraCAPems, connectCAPems) 270 if err != nil { 271 c.RUnlock() 272 return err 273 } 274 if err = c.check(*c.base, pool, c.manual.cert); err != nil { 275 c.RUnlock() 276 return err 277 } 278 c.autoTLS.connectCAPems = connectCAPems 279 c.caPool = pool 280 c.version++ 281 return nil 282} 283 284// UpdateAutoTLSCert 285func (c *Configurator) UpdateAutoTLSCert(pub, priv string) error { 286 // order of defers matters because log acquires a RLock() 287 defer c.log("UpdateAutoEncryptCert") 288 cert, err := tls.X509KeyPair([]byte(pub), []byte(priv)) 289 if err != nil { 290 return fmt.Errorf("Failed to load cert/key pair: %v", err) 291 } 292 293 c.Lock() 294 defer c.Unlock() 295 296 c.autoTLS.cert = &cert 297 c.version++ 298 return nil 299} 300 301// UpdateAutoTLS sets everything under autoEncrypt. This is being called on the 302// client when it received its cert from AutoEncrypt/AutoConfig endpoints. 303func (c *Configurator) UpdateAutoTLS(manualCAPems, connectCAPems []string, pub, priv string, verifyServerHostname bool) error { 304 // order of defers matters because log acquires a RLock() 305 defer c.log("UpdateAutoEncrypt") 306 cert, err := tls.X509KeyPair([]byte(pub), []byte(priv)) 307 if err != nil { 308 return fmt.Errorf("Failed to load cert/key pair: %v", err) 309 } 310 311 c.Lock() 312 defer c.Unlock() 313 314 pool, err := newX509CertPool(c.manual.caPems, manualCAPems, connectCAPems) 315 if err != nil { 316 return err 317 } 318 c.autoTLS.extraCAPems = manualCAPems 319 c.autoTLS.connectCAPems = connectCAPems 320 c.autoTLS.cert = &cert 321 c.caPool = pool 322 c.autoTLS.verifyServerHostname = verifyServerHostname 323 c.version++ 324 return nil 325} 326 327func (c *Configurator) UpdateAreaPeerDatacenterUseTLS(peerDatacenter string, useTLS bool) { 328 c.Lock() 329 defer c.Unlock() 330 c.version++ 331 c.peerDatacenterUseTLS[peerDatacenter] = useTLS 332} 333 334func (c *Configurator) getAreaForPeerDatacenterUseTLS(peerDatacenter string) bool { 335 c.RLock() 336 defer c.RUnlock() 337 if v, ok := c.peerDatacenterUseTLS[peerDatacenter]; ok { 338 return v 339 } 340 return true 341} 342 343func (c *Configurator) Base() Config { 344 c.RLock() 345 defer c.RUnlock() 346 return *c.base 347} 348 349// newX509CertPool loads all the groups of PEM encoded certificates into a 350// single x509.CertPool. 351// 352// The groups argument is a varargs of slices so that callers do not need to 353// append slices together. In some cases append can modify the backing array 354// of the first slice passed to append, which will often result in hard to 355// find bugs. By accepting a varargs of slices we remove the need for the 356// caller to append the groups, which should prevent any such bugs. 357func newX509CertPool(groups ...[]string) (*x509.CertPool, error) { 358 pool := x509.NewCertPool() 359 for _, group := range groups { 360 for _, pem := range group { 361 if !pool.AppendCertsFromPEM([]byte(pem)) { 362 return nil, fmt.Errorf("failed to parse PEM %s", pem) 363 } 364 } 365 } 366 if len(pool.Subjects()) == 0 { 367 return nil, nil 368 } 369 return pool, nil 370} 371 372func (c *Configurator) check(config Config, pool *x509.CertPool, cert *tls.Certificate) error { 373 // Check if a minimum TLS version was set 374 if config.TLSMinVersion != "" { 375 if _, ok := TLSLookup[config.TLSMinVersion]; !ok { 376 return fmt.Errorf("TLSMinVersion: value %s not supported, please specify one of [%s]", config.TLSMinVersion, TLSVersions) 377 } 378 } 379 380 // Ensure we have a CA if VerifyOutgoing is set 381 if config.VerifyOutgoing && pool == nil { 382 return fmt.Errorf("VerifyOutgoing set, and no CA certificate provided!") 383 } 384 385 // Ensure we have a CA and cert if VerifyIncoming is set 386 if config.anyVerifyIncoming() { 387 if pool == nil { 388 // both auto-config and auto-encrypt require verifying the connection from the client to the server for secure 389 // operation. In order to be able to verify the servers certificate we must have some CA certs already provided. 390 // Therefore, even though both of those features can push down extra CA certificates which could be used to 391 // verify incoming connections, we still must consider it an error if none are provided in the initial configuration 392 // as those features cannot be successfully enabled without providing CA certificates to use those features. 393 return fmt.Errorf("VerifyIncoming set but no CA certificates were provided") 394 } 395 396 // We will use the auto_encrypt/auto_config cert for TLS in the incoming APIs when available. Therefore the check 397 // here will ensure that either we enabled one of those two features or a certificate and key were provided manually 398 if cert == nil && !config.AutoTLS { 399 return fmt.Errorf("VerifyIncoming requires either a Cert and Key pair in the configuration file, or auto_encrypt/auto_config be enabled") 400 } 401 } 402 return nil 403} 404 405func (c Config) anyVerifyIncoming() bool { 406 return c.baseVerifyIncoming() || c.VerifyIncomingRPC || c.VerifyIncomingHTTPS 407} 408 409func (c Config) verifyIncomingRPC() bool { 410 return c.baseVerifyIncoming() || c.VerifyIncomingRPC 411} 412 413func (c Config) verifyIncomingHTTPS() bool { 414 return c.baseVerifyIncoming() || c.VerifyIncomingHTTPS 415} 416 417func (c *Config) baseVerifyIncoming() bool { 418 return c.VerifyIncoming 419} 420 421func loadKeyPair(certFile, keyFile string) (*tls.Certificate, error) { 422 if certFile == "" || keyFile == "" { 423 return nil, nil 424 } 425 cert, err := tls.LoadX509KeyPair(certFile, keyFile) 426 if err != nil { 427 return nil, fmt.Errorf("Failed to load cert/key pair: %v", err) 428 } 429 return &cert, nil 430} 431 432func LoadCAs(caFile, caPath string) ([]string, error) { 433 if caFile == "" && caPath == "" { 434 return nil, nil 435 } 436 437 pems := []string{} 438 439 readFn := func(path string) error { 440 pem, err := ioutil.ReadFile(path) 441 if err != nil { 442 return fmt.Errorf("Error loading from %s: %s", path, err) 443 } 444 pems = append(pems, string(pem)) 445 return nil 446 } 447 448 walkFn := func(path string, info os.FileInfo, err error) error { 449 if err != nil { 450 return err 451 } 452 453 if !info.IsDir() { 454 if err := readFn(path); err != nil { 455 return err 456 } 457 } 458 return nil 459 } 460 461 if caFile != "" { 462 err := readFn(caFile) 463 if err != nil { 464 return pems, err 465 } 466 } else if caPath != "" { 467 err := filepath.Walk(caPath, walkFn) 468 if err != nil { 469 return pems, err 470 } 471 if len(pems) == 0 { 472 return pems, fmt.Errorf("Error loading from CAPath: no CAs found") 473 } 474 } 475 return pems, nil 476} 477 478// commonTLSConfig generates a *tls.Config from the base configuration the 479// Configurator has. It accepts an additional flag in case a config is needed 480// for incoming TLS connections. 481// This function acquires a read lock because it reads from the config. 482func (c *Configurator) commonTLSConfig(verifyIncoming bool) *tls.Config { 483 // this needs to be outside of RLock because it acquires an RLock itself 484 verifyServerHostname := c.VerifyServerHostname() 485 486 c.RLock() 487 defer c.RUnlock() 488 tlsConfig := &tls.Config{ 489 InsecureSkipVerify: !verifyServerHostname, 490 } 491 492 // Set the cipher suites 493 if len(c.base.CipherSuites) != 0 { 494 tlsConfig.CipherSuites = c.base.CipherSuites 495 } 496 497 tlsConfig.PreferServerCipherSuites = c.base.PreferServerCipherSuites 498 499 // GetCertificate is used when acting as a server and responding to 500 // client requests. Default to the manually configured cert, but allow 501 // autoEncrypt cert too so that a client can encrypt incoming 502 // connections without having a manual cert configured. 503 tlsConfig.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) { 504 return c.Cert(), nil 505 } 506 507 // GetClientCertificate is used when acting as a client and responding 508 // to a server requesting a certificate. Return the autoEncrypt certificate 509 // if possible, otherwise default to the manually provisioned one. 510 tlsConfig.GetClientCertificate = func(*tls.CertificateRequestInfo) (*tls.Certificate, error) { 511 cert := c.autoTLS.cert 512 if cert == nil { 513 cert = c.manual.cert 514 } 515 516 if cert == nil { 517 // the return value MUST not be nil but an empty certificate will be 518 // treated the same as having no client certificate 519 cert = &tls.Certificate{} 520 } 521 522 return cert, nil 523 } 524 525 tlsConfig.ClientCAs = c.caPool 526 tlsConfig.RootCAs = c.caPool 527 528 // This is possible because TLSLookup also contains "" with golang's 529 // default (tls10). And because the initial check makes sure the 530 // version correctly matches. 531 tlsConfig.MinVersion = TLSLookup[c.base.TLSMinVersion] 532 533 // Set ClientAuth if necessary 534 if verifyIncoming { 535 tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert 536 } 537 538 return tlsConfig 539} 540 541// This function acquires a read lock because it reads from the config. 542func (c *Configurator) Cert() *tls.Certificate { 543 c.RLock() 544 defer c.RUnlock() 545 cert := c.manual.cert 546 if cert == nil { 547 cert = c.autoTLS.cert 548 } 549 return cert 550} 551 552// This function acquires a read lock because it reads from the config. 553func (c *Configurator) VerifyIncomingRPC() bool { 554 c.RLock() 555 defer c.RUnlock() 556 return c.base.verifyIncomingRPC() 557} 558 559// This function acquires a read lock because it reads from the config. 560func (c *Configurator) outgoingRPCTLSDisabled() bool { 561 c.RLock() 562 defer c.RUnlock() 563 564 // if AutoEncrypt enabled, always use TLS 565 if c.base.AutoTLS { 566 return false 567 } 568 569 // if CAs are provided or VerifyOutgoing is set, use TLS 570 if c.base.VerifyOutgoing { 571 return false 572 } 573 574 return true 575} 576 577func (c *Configurator) MutualTLSCapable() bool { 578 return c.mutualTLSCapable() 579} 580 581// This function acquires a read lock because it reads from the config. 582func (c *Configurator) mutualTLSCapable() bool { 583 c.RLock() 584 defer c.RUnlock() 585 return c.caPool != nil && (c.autoTLS.cert != nil || c.manual.cert != nil) 586} 587 588// This function acquires a read lock because it reads from the config. 589func (c *Configurator) verifyOutgoing() bool { 590 c.RLock() 591 defer c.RUnlock() 592 593 // If AutoEncryptTLS is enabled and there is a CA, then verify 594 // outgoing. 595 if c.base.AutoTLS && c.caPool != nil { 596 return true 597 } 598 599 return c.base.VerifyOutgoing 600} 601 602func (c *Configurator) ServerSNI(dc, nodeName string) string { 603 // Strip the trailing '.' from the domain if any 604 domain := strings.TrimSuffix(c.domain(), ".") 605 606 if nodeName == "" || nodeName == "*" { 607 return "server." + dc + "." + domain 608 } 609 610 return nodeName + ".server." + dc + "." + domain 611} 612 613// This function acquires a read lock because it reads from the config. 614func (c *Configurator) domain() string { 615 c.RLock() 616 defer c.RUnlock() 617 return c.base.Domain 618} 619 620// This function acquires a read lock because it reads from the config. 621func (c *Configurator) verifyIncomingRPC() bool { 622 c.RLock() 623 defer c.RUnlock() 624 return c.base.verifyIncomingRPC() 625} 626 627// This function acquires a read lock because it reads from the config. 628func (c *Configurator) verifyIncomingHTTPS() bool { 629 c.RLock() 630 defer c.RUnlock() 631 return c.base.verifyIncomingHTTPS() 632} 633 634// This function acquires a read lock because it reads from the config. 635func (c *Configurator) enableAgentTLSForChecks() bool { 636 c.RLock() 637 defer c.RUnlock() 638 return c.base.EnableAgentTLSForChecks 639} 640 641// This function acquires a read lock because it reads from the config. 642func (c *Configurator) serverNameOrNodeName() string { 643 c.RLock() 644 defer c.RUnlock() 645 if c.base.ServerName != "" { 646 return c.base.ServerName 647 } 648 return c.base.NodeName 649} 650 651// This function acquires a read lock because it reads from the config. 652func (c *Configurator) VerifyServerHostname() bool { 653 c.RLock() 654 defer c.RUnlock() 655 return c.base.VerifyServerHostname || c.autoTLS.verifyServerHostname 656} 657 658// IncomingGRPCConfig generates a *tls.Config for incoming GRPC connections. 659func (c *Configurator) IncomingGRPCConfig() *tls.Config { 660 c.log("IncomingGRPCConfig") 661 662 // false has the effect that this config doesn't require a client cert 663 // verification. This is because there is no verify_incoming_grpc 664 // configuration option. And using verify_incoming would be backwards 665 // incompatible, because even if it was set before, it didn't have an 666 // effect on the grpc server. 667 config := c.commonTLSConfig(false) 668 config.GetConfigForClient = func(*tls.ClientHelloInfo) (*tls.Config, error) { 669 return c.IncomingGRPCConfig(), nil 670 } 671 return config 672} 673 674// IncomingRPCConfig generates a *tls.Config for incoming RPC connections. 675func (c *Configurator) IncomingRPCConfig() *tls.Config { 676 c.log("IncomingRPCConfig") 677 config := c.commonTLSConfig(c.verifyIncomingRPC()) 678 config.GetConfigForClient = func(*tls.ClientHelloInfo) (*tls.Config, error) { 679 return c.IncomingRPCConfig(), nil 680 } 681 return config 682} 683 684// IncomingALPNRPCConfig generates a *tls.Config for incoming RPC connections 685// directly using TLS with ALPN instead of the older byte-prefixed protocol. 686func (c *Configurator) IncomingALPNRPCConfig(alpnProtos []string) *tls.Config { 687 c.log("IncomingALPNRPCConfig") 688 // Since the ALPN-RPC variation is indirectly exposed to the internet via 689 // mesh gateways we force mTLS and full server name verification. 690 config := c.commonTLSConfig(true) 691 config.InsecureSkipVerify = false 692 693 config.GetConfigForClient = func(*tls.ClientHelloInfo) (*tls.Config, error) { 694 return c.IncomingALPNRPCConfig(alpnProtos), nil 695 } 696 config.NextProtos = alpnProtos 697 return config 698} 699 700// IncomingInsecureRPCConfig means that it doesn't verify incoming even thought 701// it might have been configured. This is only supposed to be used by the 702// servers for the insecure RPC server. At the time of writing only the 703// AutoEncrypt.Sign call is supported on that server. And it might be the only 704// usecase ever. 705func (c *Configurator) IncomingInsecureRPCConfig() *tls.Config { 706 c.log("IncomingInsecureRPCConfig") 707 config := c.commonTLSConfig(false) 708 config.GetConfigForClient = func(*tls.ClientHelloInfo) (*tls.Config, error) { 709 return c.IncomingInsecureRPCConfig(), nil 710 } 711 return config 712} 713 714// IncomingHTTPSConfig generates a *tls.Config for incoming HTTPS connections. 715func (c *Configurator) IncomingHTTPSConfig() *tls.Config { 716 c.log("IncomingHTTPSConfig") 717 config := c.commonTLSConfig(c.verifyIncomingHTTPS()) 718 config.NextProtos = []string{"h2", "http/1.1"} 719 config.GetConfigForClient = func(*tls.ClientHelloInfo) (*tls.Config, error) { 720 return c.IncomingHTTPSConfig(), nil 721 } 722 return config 723} 724 725// OutgoingTLSConfigForCheck generates a *tls.Config for outgoing TLS connections 726// for checks. This function is separated because there is an extra flag to 727// consider for checks. EnableAgentTLSForChecks and InsecureSkipVerify has to 728// be checked for checks. 729func (c *Configurator) OutgoingTLSConfigForCheck(skipVerify bool, serverName string) *tls.Config { 730 c.log("OutgoingTLSConfigForCheck") 731 732 if !c.enableAgentTLSForChecks() { 733 return &tls.Config{ 734 InsecureSkipVerify: skipVerify, 735 ServerName: serverName, 736 } 737 } 738 739 if serverName == "" { 740 serverName = c.serverNameOrNodeName() 741 } 742 config := c.commonTLSConfig(false) 743 config.InsecureSkipVerify = skipVerify 744 config.ServerName = serverName 745 746 return config 747} 748 749// OutgoingRPCConfig generates a *tls.Config for outgoing RPC connections. If 750// there is a CA or VerifyOutgoing is set, a *tls.Config will be provided, 751// otherwise we assume that no TLS should be used. 752func (c *Configurator) OutgoingRPCConfig() *tls.Config { 753 c.log("OutgoingRPCConfig") 754 if c.outgoingRPCTLSDisabled() { 755 return nil 756 } 757 return c.commonTLSConfig(false) 758} 759 760// OutgoingALPNRPCConfig generates a *tls.Config for outgoing RPC connections 761// directly using TLS with ALPN instead of the older byte-prefixed protocol. 762// If there is a CA or VerifyOutgoing is set, a *tls.Config will be provided, 763// otherwise we assume that no TLS should be used which completely disables the 764// ALPN variation. 765func (c *Configurator) OutgoingALPNRPCConfig() *tls.Config { 766 c.log("OutgoingALPNRPCConfig") 767 if !c.mutualTLSCapable() { 768 return nil // ultimately this will hard-fail as TLS is required 769 } 770 771 // Since the ALPN-RPC variation is indirectly exposed to the internet via 772 // mesh gateways we force mTLS and full server name verification. 773 config := c.commonTLSConfig(true) 774 config.InsecureSkipVerify = false 775 return config 776} 777 778// OutgoingRPCWrapper wraps the result of OutgoingRPCConfig in a DCWrapper. It 779// decides if verify server hostname should be used. 780func (c *Configurator) OutgoingRPCWrapper() DCWrapper { 781 c.log("OutgoingRPCWrapper") 782 783 // Generate the wrapper based on dc 784 return func(dc string, conn net.Conn) (net.Conn, error) { 785 if c.UseTLS(dc) { 786 return c.wrapTLSClient(dc, conn) 787 } 788 return conn, nil 789 } 790} 791 792func (c *Configurator) UseTLS(dc string) bool { 793 return !c.outgoingRPCTLSDisabled() && c.getAreaForPeerDatacenterUseTLS(dc) 794} 795 796// OutgoingALPNRPCWrapper wraps the result of OutgoingALPNRPCConfig in an 797// ALPNWrapper. It configures all of the negotiation plumbing. 798func (c *Configurator) OutgoingALPNRPCWrapper() ALPNWrapper { 799 c.log("OutgoingALPNRPCWrapper") 800 if !c.mutualTLSCapable() { 801 return nil 802 } 803 804 return func(dc, nodeName, alpnProto string, conn net.Conn) (net.Conn, error) { 805 return c.wrapALPNTLSClient(dc, nodeName, alpnProto, conn) 806 } 807} 808 809// AutoEncryptCertNotAfter returns NotAfter from the auto_encrypt cert. In case 810// there is no cert, it will return a time in the past. 811func (c *Configurator) AutoEncryptCertNotAfter() time.Time { 812 c.RLock() 813 defer c.RUnlock() 814 tlsCert := c.autoTLS.cert 815 if tlsCert == nil || tlsCert.Certificate == nil { 816 return time.Now().AddDate(0, 0, -1) 817 } 818 cert, err := x509.ParseCertificate(tlsCert.Certificate[0]) 819 if err != nil { 820 return time.Now().AddDate(0, 0, -1) 821 } 822 return cert.NotAfter 823} 824 825// AutoEncryptCertExpired returns if the auto_encrypt cert is expired. 826func (c *Configurator) AutoEncryptCertExpired() bool { 827 return c.AutoEncryptCertNotAfter().Before(time.Now()) 828} 829 830// This function acquires a read lock because it reads from the config. 831func (c *Configurator) log(name string) { 832 if c.logger != nil { 833 c.RLock() 834 defer c.RUnlock() 835 c.logger.Trace(name, "version", c.version) 836 } 837} 838 839// Wrap a net.Conn into a client tls connection, performing any 840// additional verification as needed. 841// 842// As of go 1.3, crypto/tls only supports either doing no certificate 843// verification, or doing full verification including of the peer's 844// DNS name. For consul, we want to validate that the certificate is 845// signed by a known CA, but because consul doesn't use DNS names for 846// node names, we don't verify the certificate DNS names. Since go 1.3 847// no longer supports this mode of operation, we have to do it 848// manually. 849func (c *Configurator) wrapTLSClient(dc string, conn net.Conn) (net.Conn, error) { 850 config := c.OutgoingRPCConfig() 851 verifyServerHostname := c.VerifyServerHostname() 852 verifyOutgoing := c.verifyOutgoing() 853 domain := c.domain() 854 855 if verifyServerHostname { 856 // Strip the trailing '.' from the domain if any 857 domain = strings.TrimSuffix(domain, ".") 858 config.ServerName = "server." + dc + "." + domain 859 } 860 tlsConn := tls.Client(conn, config) 861 862 // If crypto/tls is doing verification, there's no need to do 863 // our own. 864 if !config.InsecureSkipVerify { 865 return tlsConn, nil 866 } 867 868 // If verification is not turned on, don't do it. 869 if !verifyOutgoing { 870 return tlsConn, nil 871 } 872 873 err := tlsConn.Handshake() 874 if err != nil { 875 tlsConn.Close() 876 return nil, err 877 } 878 879 // The following is lightly-modified from the doFullHandshake 880 // method in crypto/tls's handshake_client.go. 881 opts := x509.VerifyOptions{ 882 Roots: config.RootCAs, 883 CurrentTime: time.Now(), 884 DNSName: "", 885 Intermediates: x509.NewCertPool(), 886 } 887 888 cs := tlsConn.ConnectionState() 889 for _, cert := range cs.PeerCertificates[1:] { 890 opts.Intermediates.AddCert(cert) 891 } 892 _, err = cs.PeerCertificates[0].Verify(opts) 893 if err != nil { 894 tlsConn.Close() 895 return nil, err 896 } 897 898 return tlsConn, err 899} 900 901// Wrap a net.Conn into a client tls connection suitable for secure ALPN-RPC, 902// performing any additional verification as needed. 903func (c *Configurator) wrapALPNTLSClient(dc, nodeName, alpnProto string, conn net.Conn) (net.Conn, error) { 904 if dc == "" { 905 return nil, fmt.Errorf("cannot dial using ALPN-RPC without a target datacenter") 906 } else if nodeName == "" { 907 return nil, fmt.Errorf("cannot dial using ALPN-RPC without a target node") 908 } else if alpnProto == "" { 909 return nil, fmt.Errorf("cannot dial using ALPN-RPC without a target alpn protocol") 910 } 911 912 config := c.OutgoingALPNRPCConfig() 913 if config == nil { 914 return nil, fmt.Errorf("cannot dial via a mesh gateway when outgoing TLS is disabled") 915 } 916 917 // Since the ALPN-RPC variation is indirectly exposed to the internet via 918 // mesh gateways we force mTLS and full hostname validation (forcing 919 // verify_server_hostname and verify_outgoing to be effectively true). 920 921 config.ServerName = c.ServerSNI(dc, nodeName) 922 config.NextProtos = []string{alpnProto} 923 924 tlsConn := tls.Client(conn, config) 925 926 // NOTE: For this handshake to succeed the server must have key material 927 // for either "<nodename>.server.<datacenter>.<domain>" or 928 // "*.server.<datacenter>.<domain>" in addition to the 929 // "server.<datacenter>.<domain>" required for standard TLS'd RPC. 930 if err := tlsConn.Handshake(); err != nil { 931 tlsConn.Close() 932 return nil, err 933 } 934 935 return tlsConn, nil 936} 937 938// AuthorizeServerConn is used to validate that the connection is being established 939// by a Consul server in the same datacenter. 940// 941// The identity of the connection is checked by verifying that the certificate 942// presented is signed by the Agent TLS CA, and has a DNSName that matches the 943// local ServerSNI name. 944// 945// Note this check is only performed if VerifyServerHostname is enabled, otherwise 946// it does no authorization. 947func (c *Configurator) AuthorizeServerConn(dc string, conn *tls.Conn) error { 948 if !c.VerifyServerHostname() { 949 return nil 950 } 951 952 c.RLock() 953 caPool := c.manual.caPool 954 c.RUnlock() 955 956 expected := c.ServerSNI(dc, "") 957 cs := conn.ConnectionState() 958 var errs error 959 for _, chain := range cs.VerifiedChains { 960 if len(chain) == 0 { 961 continue 962 } 963 opts := x509.VerifyOptions{ 964 DNSName: expected, 965 Intermediates: x509.NewCertPool(), 966 Roots: caPool, 967 KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, 968 } 969 for _, cert := range cs.PeerCertificates[1:] { 970 opts.Intermediates.AddCert(cert) 971 } 972 _, err := cs.PeerCertificates[0].Verify(opts) 973 if err == nil { 974 return nil 975 } 976 multierror.Append(errs, err) 977 } 978 return fmt.Errorf("AuthorizeServerConn failed certificate validation for certificate with a SAN.DNSName of %v: %w", expected, errs) 979 980} 981 982// ParseCiphers parse ciphersuites from the comma-separated string into 983// recognized slice 984func ParseCiphers(cipherStr string) ([]uint16, error) { 985 suites := []uint16{} 986 987 cipherStr = strings.TrimSpace(cipherStr) 988 if cipherStr == "" { 989 return []uint16{}, nil 990 } 991 ciphers := strings.Split(cipherStr, ",") 992 993 // Note: this needs to be kept up to date with the cipherMap in CipherString 994 cipherMap := map[string]uint16{ 995 "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 996 "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 997 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 998 "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 999 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 1000 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 1001 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 1002 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1003 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 1004 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 1005 } 1006 for _, cipher := range ciphers { 1007 if v, ok := cipherMap[cipher]; ok { 1008 suites = append(suites, v) 1009 } else { 1010 return suites, fmt.Errorf("unsupported cipher %q", cipher) 1011 } 1012 } 1013 1014 return suites, nil 1015} 1016 1017// CipherString performs the inverse operation of ParseCiphers 1018func CipherString(ciphers []uint16) (string, error) { 1019 // Note: this needs to be kept up to date with the cipherMap in ParseCiphers 1020 cipherMap := map[uint16]string{ 1021 tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", 1022 tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", 1023 tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", 1024 tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", 1025 tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", 1026 tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", 1027 tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", 1028 tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 1029 tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", 1030 tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", 1031 } 1032 1033 cipherStrings := make([]string, len(ciphers)) 1034 for i, cipher := range ciphers { 1035 if v, ok := cipherMap[cipher]; ok { 1036 cipherStrings[i] = v 1037 } else { 1038 return "", fmt.Errorf("unsupported cipher %d", cipher) 1039 } 1040 } 1041 1042 return strings.Join(cipherStrings, ","), nil 1043} 1044