mirror of
				https://github.com/coredns/coredns.git
				synced 2025-11-03 18:53:13 -05:00 
			
		
		
		
	
		
			
	
	
		
			322 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			322 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package https
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"bytes"
							 | 
						||
| 
								 | 
							
									"crypto/tls"
							 | 
						||
| 
								 | 
							
									"encoding/pem"
							 | 
						||
| 
								 | 
							
									"io/ioutil"
							 | 
						||
| 
								 | 
							
									"log"
							 | 
						||
| 
								 | 
							
									"os"
							 | 
						||
| 
								 | 
							
									"path/filepath"
							 | 
						||
| 
								 | 
							
									"strconv"
							 | 
						||
| 
								 | 
							
									"strings"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									"github.com/miekg/coredns/core/setup"
							 | 
						||
| 
								 | 
							
									"github.com/miekg/coredns/middleware"
							 | 
						||
| 
								 | 
							
									"github.com/miekg/coredns/server"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Setup sets up the TLS configuration and installs certificates that
							 | 
						||
| 
								 | 
							
								// are specified by the user in the config file. All the automatic HTTPS
							 | 
						||
| 
								 | 
							
								// stuff comes later outside of this function.
							 | 
						||
| 
								 | 
							
								func Setup(c *setup.Controller) (middleware.Middleware, error) {
							 | 
						||
| 
								 | 
							
									if c.Port == "80" {
							 | 
						||
| 
								 | 
							
										c.TLS.Enabled = false
							 | 
						||
| 
								 | 
							
										log.Printf("[WARNING] TLS disabled for %s.", c.Address())
							 | 
						||
| 
								 | 
							
										return nil, nil
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									c.TLS.Enabled = true
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// TODO(miek): disabled for now
							 | 
						||
| 
								 | 
							
									return nil, nil
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for c.Next() {
							 | 
						||
| 
								 | 
							
										var certificateFile, keyFile, loadDir, maxCerts string
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										args := c.RemainingArgs()
							 | 
						||
| 
								 | 
							
										switch len(args) {
							 | 
						||
| 
								 | 
							
										case 1:
							 | 
						||
| 
								 | 
							
											c.TLS.LetsEncryptEmail = args[0]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											// user can force-disable managed TLS this way
							 | 
						||
| 
								 | 
							
											if c.TLS.LetsEncryptEmail == "off" {
							 | 
						||
| 
								 | 
							
												c.TLS.Enabled = false
							 | 
						||
| 
								 | 
							
												return nil, nil
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										case 2:
							 | 
						||
| 
								 | 
							
											certificateFile = args[0]
							 | 
						||
| 
								 | 
							
											keyFile = args[1]
							 | 
						||
| 
								 | 
							
											c.TLS.Manual = true
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// Optional block with extra parameters
							 | 
						||
| 
								 | 
							
										var hadBlock bool
							 | 
						||
| 
								 | 
							
										for c.NextBlock() {
							 | 
						||
| 
								 | 
							
											hadBlock = true
							 | 
						||
| 
								 | 
							
											switch c.Val() {
							 | 
						||
| 
								 | 
							
											case "protocols":
							 | 
						||
| 
								 | 
							
												args := c.RemainingArgs()
							 | 
						||
| 
								 | 
							
												if len(args) != 2 {
							 | 
						||
| 
								 | 
							
													return nil, c.ArgErr()
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												value, ok := supportedProtocols[strings.ToLower(args[0])]
							 | 
						||
| 
								 | 
							
												if !ok {
							 | 
						||
| 
								 | 
							
													return nil, c.Errf("Wrong protocol name or protocol not supported '%s'", c.Val())
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												c.TLS.ProtocolMinVersion = value
							 | 
						||
| 
								 | 
							
												value, ok = supportedProtocols[strings.ToLower(args[1])]
							 | 
						||
| 
								 | 
							
												if !ok {
							 | 
						||
| 
								 | 
							
													return nil, c.Errf("Wrong protocol name or protocol not supported '%s'", c.Val())
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												c.TLS.ProtocolMaxVersion = value
							 | 
						||
| 
								 | 
							
											case "ciphers":
							 | 
						||
| 
								 | 
							
												for c.NextArg() {
							 | 
						||
| 
								 | 
							
													value, ok := supportedCiphersMap[strings.ToUpper(c.Val())]
							 | 
						||
| 
								 | 
							
													if !ok {
							 | 
						||
| 
								 | 
							
														return nil, c.Errf("Wrong cipher name or cipher not supported '%s'", c.Val())
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													c.TLS.Ciphers = append(c.TLS.Ciphers, value)
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											case "clients":
							 | 
						||
| 
								 | 
							
												c.TLS.ClientCerts = c.RemainingArgs()
							 | 
						||
| 
								 | 
							
												if len(c.TLS.ClientCerts) == 0 {
							 | 
						||
| 
								 | 
							
													return nil, c.ArgErr()
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											case "load":
							 | 
						||
| 
								 | 
							
												c.Args(&loadDir)
							 | 
						||
| 
								 | 
							
												c.TLS.Manual = true
							 | 
						||
| 
								 | 
							
											case "max_certs":
							 | 
						||
| 
								 | 
							
												c.Args(&maxCerts)
							 | 
						||
| 
								 | 
							
												c.TLS.OnDemand = true
							 | 
						||
| 
								 | 
							
											default:
							 | 
						||
| 
								 | 
							
												return nil, c.Errf("Unknown keyword '%s'", c.Val())
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// tls requires at least one argument if a block is not opened
							 | 
						||
| 
								 | 
							
										if len(args) == 0 && !hadBlock {
							 | 
						||
| 
								 | 
							
											return nil, c.ArgErr()
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// set certificate limit if on-demand TLS is enabled
							 | 
						||
| 
								 | 
							
										if maxCerts != "" {
							 | 
						||
| 
								 | 
							
											maxCertsNum, err := strconv.Atoi(maxCerts)
							 | 
						||
| 
								 | 
							
											if err != nil || maxCertsNum < 1 {
							 | 
						||
| 
								 | 
							
												return nil, c.Err("max_certs must be a positive integer")
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if onDemandMaxIssue == 0 || int32(maxCertsNum) < onDemandMaxIssue { // keep the minimum; TODO: We have to do this because it is global; should be per-server or per-vhost...
							 | 
						||
| 
								 | 
							
												onDemandMaxIssue = int32(maxCertsNum)
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// don't try to load certificates unless we're supposed to
							 | 
						||
| 
								 | 
							
										if !c.TLS.Enabled || !c.TLS.Manual {
							 | 
						||
| 
								 | 
							
											continue
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// load a single certificate and key, if specified
							 | 
						||
| 
								 | 
							
										if certificateFile != "" && keyFile != "" {
							 | 
						||
| 
								 | 
							
											err := cacheUnmanagedCertificatePEMFile(certificateFile, keyFile)
							 | 
						||
| 
								 | 
							
											if err != nil {
							 | 
						||
| 
								 | 
							
												return nil, c.Errf("Unable to load certificate and key files for %s: %v", c.Host, err)
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											log.Printf("[INFO] Successfully loaded TLS assets from %s and %s", certificateFile, keyFile)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										// load a directory of certificates, if specified
							 | 
						||
| 
								 | 
							
										if loadDir != "" {
							 | 
						||
| 
								 | 
							
											err := loadCertsInDir(c, loadDir)
							 | 
						||
| 
								 | 
							
											if err != nil {
							 | 
						||
| 
								 | 
							
												return nil, err
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									setDefaultTLSParams(c.Config)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return nil, nil
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// loadCertsInDir loads all the certificates/keys in dir, as long as
							 | 
						||
| 
								 | 
							
								// the file ends with .pem. This method of loading certificates is
							 | 
						||
| 
								 | 
							
								// modeled after haproxy, which expects the certificate and key to
							 | 
						||
| 
								 | 
							
								// be bundled into the same file:
							 | 
						||
| 
								 | 
							
								// https://cbonte.github.io/haproxy-dconv/configuration-1.5.html#5.1-crt
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// This function may write to the log as it walks the directory tree.
							 | 
						||
| 
								 | 
							
								func loadCertsInDir(c *setup.Controller, dir string) error {
							 | 
						||
| 
								 | 
							
									return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
							 | 
						||
| 
								 | 
							
										if err != nil {
							 | 
						||
| 
								 | 
							
											log.Printf("[WARNING] Unable to traverse into %s; skipping", path)
							 | 
						||
| 
								 | 
							
											return nil
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if info.IsDir() {
							 | 
						||
| 
								 | 
							
											return nil
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if strings.HasSuffix(strings.ToLower(info.Name()), ".pem") {
							 | 
						||
| 
								 | 
							
											certBuilder, keyBuilder := new(bytes.Buffer), new(bytes.Buffer)
							 | 
						||
| 
								 | 
							
											var foundKey bool // use only the first key in the file
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											bundle, err := ioutil.ReadFile(path)
							 | 
						||
| 
								 | 
							
											if err != nil {
							 | 
						||
| 
								 | 
							
												return err
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for {
							 | 
						||
| 
								 | 
							
												// Decode next block so we can see what type it is
							 | 
						||
| 
								 | 
							
												var derBlock *pem.Block
							 | 
						||
| 
								 | 
							
												derBlock, bundle = pem.Decode(bundle)
							 | 
						||
| 
								 | 
							
												if derBlock == nil {
							 | 
						||
| 
								 | 
							
													break
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												if derBlock.Type == "CERTIFICATE" {
							 | 
						||
| 
								 | 
							
													// Re-encode certificate as PEM, appending to certificate chain
							 | 
						||
| 
								 | 
							
													pem.Encode(certBuilder, derBlock)
							 | 
						||
| 
								 | 
							
												} else if derBlock.Type == "EC PARAMETERS" {
							 | 
						||
| 
								 | 
							
													// EC keys generated from openssl can be composed of two blocks:
							 | 
						||
| 
								 | 
							
													// parameters and key (parameter block should come first)
							 | 
						||
| 
								 | 
							
													if !foundKey {
							 | 
						||
| 
								 | 
							
														// Encode parameters
							 | 
						||
| 
								 | 
							
														pem.Encode(keyBuilder, derBlock)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
														// Key must immediately follow
							 | 
						||
| 
								 | 
							
														derBlock, bundle = pem.Decode(bundle)
							 | 
						||
| 
								 | 
							
														if derBlock == nil || derBlock.Type != "EC PRIVATE KEY" {
							 | 
						||
| 
								 | 
							
															return c.Errf("%s: expected elliptic private key to immediately follow EC parameters", path)
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														pem.Encode(keyBuilder, derBlock)
							 | 
						||
| 
								 | 
							
														foundKey = true
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												} else if derBlock.Type == "PRIVATE KEY" || strings.HasSuffix(derBlock.Type, " PRIVATE KEY") {
							 | 
						||
| 
								 | 
							
													// RSA key
							 | 
						||
| 
								 | 
							
													if !foundKey {
							 | 
						||
| 
								 | 
							
														pem.Encode(keyBuilder, derBlock)
							 | 
						||
| 
								 | 
							
														foundKey = true
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												} else {
							 | 
						||
| 
								 | 
							
													return c.Errf("%s: unrecognized PEM block type: %s", path, derBlock.Type)
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											certPEMBytes, keyPEMBytes := certBuilder.Bytes(), keyBuilder.Bytes()
							 | 
						||
| 
								 | 
							
											if len(certPEMBytes) == 0 {
							 | 
						||
| 
								 | 
							
												return c.Errf("%s: failed to parse PEM data", path)
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if len(keyPEMBytes) == 0 {
							 | 
						||
| 
								 | 
							
												return c.Errf("%s: no private key block found", path)
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											err = cacheUnmanagedCertificatePEMBytes(certPEMBytes, keyPEMBytes)
							 | 
						||
| 
								 | 
							
											if err != nil {
							 | 
						||
| 
								 | 
							
												return c.Errf("%s: failed to load cert and key for %s: %v", path, c.Host, err)
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											log.Printf("[INFO] Successfully loaded TLS assets from %s", path)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return nil
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// setDefaultTLSParams sets the default TLS cipher suites, protocol versions,
							 | 
						||
| 
								 | 
							
								// and server preferences of a server.Config if they were not previously set
							 | 
						||
| 
								 | 
							
								// (it does not overwrite; only fills in missing values). It will also set the
							 | 
						||
| 
								 | 
							
								// port to 443 if not already set, TLS is enabled, TLS is manual, and the host
							 | 
						||
| 
								 | 
							
								// does not equal localhost.
							 | 
						||
| 
								 | 
							
								func setDefaultTLSParams(c *server.Config) {
							 | 
						||
| 
								 | 
							
									// If no ciphers provided, use default list
							 | 
						||
| 
								 | 
							
									if len(c.TLS.Ciphers) == 0 {
							 | 
						||
| 
								 | 
							
										c.TLS.Ciphers = defaultCiphers
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Not a cipher suite, but still important for mitigating protocol downgrade attacks
							 | 
						||
| 
								 | 
							
									// (prepend since having it at end breaks http2 due to non-h2-approved suites before it)
							 | 
						||
| 
								 | 
							
									c.TLS.Ciphers = append([]uint16{tls.TLS_FALLBACK_SCSV}, c.TLS.Ciphers...)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Set default protocol min and max versions - must balance compatibility and security
							 | 
						||
| 
								 | 
							
									if c.TLS.ProtocolMinVersion == 0 {
							 | 
						||
| 
								 | 
							
										c.TLS.ProtocolMinVersion = tls.VersionTLS10
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if c.TLS.ProtocolMaxVersion == 0 {
							 | 
						||
| 
								 | 
							
										c.TLS.ProtocolMaxVersion = tls.VersionTLS12
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Prefer server cipher suites
							 | 
						||
| 
								 | 
							
									c.TLS.PreferServerCipherSuites = true
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Default TLS port is 443; only use if port is not manually specified,
							 | 
						||
| 
								 | 
							
									// TLS is enabled, and the host is not localhost
							 | 
						||
| 
								 | 
							
									if c.Port == "" && c.TLS.Enabled && (!c.TLS.Manual || c.TLS.OnDemand) && c.Host != "localhost" {
							 | 
						||
| 
								 | 
							
										c.Port = "443"
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Map of supported protocols.
							 | 
						||
| 
								 | 
							
								// SSLv3 will be not supported in future release.
							 | 
						||
| 
								 | 
							
								// HTTP/2 only supports TLS 1.2 and higher.
							 | 
						||
| 
								 | 
							
								var supportedProtocols = map[string]uint16{
							 | 
						||
| 
								 | 
							
									"ssl3.0": tls.VersionSSL30,
							 | 
						||
| 
								 | 
							
									"tls1.0": tls.VersionTLS10,
							 | 
						||
| 
								 | 
							
									"tls1.1": tls.VersionTLS11,
							 | 
						||
| 
								 | 
							
									"tls1.2": tls.VersionTLS12,
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Map of supported ciphers, used only for parsing config.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Note that, at time of writing, HTTP/2 blacklists 276 cipher suites,
							 | 
						||
| 
								 | 
							
								// including all but two of the suites below (the two GCM suites).
							 | 
						||
| 
								 | 
							
								// See https://http2.github.io/http2-spec/#BadCipherSuites
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// TLS_FALLBACK_SCSV is not in this list because we manually ensure
							 | 
						||
| 
								 | 
							
								// it is always added (even though it is not technically a cipher suite).
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// This map, like any map, is NOT ORDERED. Do not range over this map.
							 | 
						||
| 
								 | 
							
								var supportedCiphersMap = map[string]uint16{
							 | 
						||
| 
								 | 
							
									"ECDHE-RSA-AES256-GCM-SHA384":   tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
							 | 
						||
| 
								 | 
							
									"ECDHE-ECDSA-AES256-GCM-SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
							 | 
						||
| 
								 | 
							
									"ECDHE-RSA-AES128-GCM-SHA256":   tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
							 | 
						||
| 
								 | 
							
									"ECDHE-ECDSA-AES128-GCM-SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
							 | 
						||
| 
								 | 
							
									"ECDHE-RSA-AES128-CBC-SHA":      tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
							 | 
						||
| 
								 | 
							
									"ECDHE-RSA-AES256-CBC-SHA":      tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
							 | 
						||
| 
								 | 
							
									"ECDHE-ECDSA-AES256-CBC-SHA":    tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
							 | 
						||
| 
								 | 
							
									"ECDHE-ECDSA-AES128-CBC-SHA":    tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
							 | 
						||
| 
								 | 
							
									"RSA-AES128-CBC-SHA":            tls.TLS_RSA_WITH_AES_128_CBC_SHA,
							 | 
						||
| 
								 | 
							
									"RSA-AES256-CBC-SHA":            tls.TLS_RSA_WITH_AES_256_CBC_SHA,
							 | 
						||
| 
								 | 
							
									"ECDHE-RSA-3DES-EDE-CBC-SHA":    tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
							 | 
						||
| 
								 | 
							
									"RSA-3DES-EDE-CBC-SHA":          tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// List of supported cipher suites in descending order of preference.
							 | 
						||
| 
								 | 
							
								// Ordering is very important! Getting the wrong order will break
							 | 
						||
| 
								 | 
							
								// mainstream clients, especially with HTTP/2.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Note that TLS_FALLBACK_SCSV is not in this list since it is always
							 | 
						||
| 
								 | 
							
								// added manually.
							 | 
						||
| 
								 | 
							
								var supportedCiphers = []uint16{
							 | 
						||
| 
								 | 
							
									tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
							 | 
						||
| 
								 | 
							
									tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
							 | 
						||
| 
								 | 
							
									tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
							 | 
						||
| 
								 | 
							
									tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
							 | 
						||
| 
								 | 
							
									tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
							 | 
						||
| 
								 | 
							
									tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
							 | 
						||
| 
								 | 
							
									tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
							 | 
						||
| 
								 | 
							
									tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
							 | 
						||
| 
								 | 
							
									tls.TLS_RSA_WITH_AES_256_CBC_SHA,
							 | 
						||
| 
								 | 
							
									tls.TLS_RSA_WITH_AES_128_CBC_SHA,
							 | 
						||
| 
								 | 
							
									tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
							 | 
						||
| 
								 | 
							
									tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// List of all the ciphers we want to use by default
							 | 
						||
| 
								 | 
							
								var defaultCiphers = []uint16{
							 | 
						||
| 
								 | 
							
									tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
							 | 
						||
| 
								 | 
							
									tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
							 | 
						||
| 
								 | 
							
									tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
							 | 
						||
| 
								 | 
							
									tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
							 | 
						||
| 
								 | 
							
									tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
							 | 
						||
| 
								 | 
							
									tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
							 | 
						||
| 
								 | 
							
									tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
							 | 
						||
| 
								 | 
							
									tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
							 | 
						||
| 
								 | 
							
									tls.TLS_RSA_WITH_AES_256_CBC_SHA,
							 | 
						||
| 
								 | 
							
									tls.TLS_RSA_WITH_AES_128_CBC_SHA,
							 | 
						||
| 
								 | 
							
								}
							 |