mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-27 15:49:58 +00:00
TUN-528: Move cloudflared into a separate repo
This commit is contained in:
151
tlsconfig/tlsconfig.go
Normal file
151
tlsconfig/tlsconfig.go
Normal file
@@ -0,0 +1,151 @@
|
||||
// Package tlsconfig provides convenience functions for configuring TLS connections from the
|
||||
// command line.
|
||||
package tlsconfig
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
|
||||
"github.com/cloudflare/cloudflared/log"
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
)
|
||||
|
||||
var logger = log.CreateLogger()
|
||||
|
||||
// CLIFlags names the flags used to configure TLS for a command or subsystem.
|
||||
// The nil value for a field means the flag is ignored.
|
||||
type CLIFlags struct {
|
||||
Cert string
|
||||
Key string
|
||||
ClientCert string
|
||||
RootCA string
|
||||
}
|
||||
|
||||
// GetConfig returns a TLS configuration according to the flags defined in f and
|
||||
// set by the user.
|
||||
func (f CLIFlags) GetConfig(c *cli.Context) *tls.Config {
|
||||
config := &tls.Config{}
|
||||
|
||||
if c.IsSet(f.Cert) && c.IsSet(f.Key) {
|
||||
cert, err := tls.LoadX509KeyPair(c.String(f.Cert), c.String(f.Key))
|
||||
if err != nil {
|
||||
logger.WithError(err).Fatal("Error parsing X509 key pair")
|
||||
}
|
||||
config.Certificates = []tls.Certificate{cert}
|
||||
config.BuildNameToCertificate()
|
||||
}
|
||||
return f.finishGettingConfig(c, config)
|
||||
}
|
||||
|
||||
func (f CLIFlags) GetConfigReloadableCert(c *cli.Context, cr *CertReloader) *tls.Config {
|
||||
config := &tls.Config{
|
||||
GetCertificate: cr.Cert,
|
||||
}
|
||||
config.BuildNameToCertificate()
|
||||
return f.finishGettingConfig(c, config)
|
||||
}
|
||||
|
||||
func (f CLIFlags) finishGettingConfig(c *cli.Context, config *tls.Config) *tls.Config {
|
||||
if c.IsSet(f.ClientCert) {
|
||||
// set of root certificate authorities that servers use if required to verify a client certificate
|
||||
// by the policy in ClientAuth
|
||||
config.ClientCAs = LoadCert(c.String(f.ClientCert))
|
||||
// server's policy for TLS Client Authentication. Default is no client cert
|
||||
config.ClientAuth = tls.RequireAndVerifyClientCert
|
||||
}
|
||||
// set of root certificate authorities that clients use when verifying server certificates
|
||||
if c.IsSet(f.RootCA) {
|
||||
config.RootCAs = LoadCert(c.String(f.RootCA))
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
// LoadCert creates a CertPool containing all certificates in a PEM-format file.
|
||||
func LoadCert(certPath string) *x509.CertPool {
|
||||
caCert, err := ioutil.ReadFile(certPath)
|
||||
if err != nil {
|
||||
logger.WithError(err).Fatalf("Error reading certificate %s", certPath)
|
||||
}
|
||||
ca := x509.NewCertPool()
|
||||
if !ca.AppendCertsFromPEM(caCert) {
|
||||
logger.WithError(err).Fatalf("Error parsing certificate %s", certPath)
|
||||
}
|
||||
return ca
|
||||
}
|
||||
|
||||
func LoadGlobalCertPool() (*x509.CertPool, error) {
|
||||
success := false
|
||||
|
||||
// First, obtain the system certificate pool
|
||||
certPool, systemCertPoolErr := x509.SystemCertPool()
|
||||
if systemCertPoolErr != nil {
|
||||
logger.Warnf("error obtaining the system certificates: %s", systemCertPoolErr)
|
||||
certPool = x509.NewCertPool()
|
||||
} else {
|
||||
success = true
|
||||
}
|
||||
|
||||
// Next, append the Cloudflare CA pool into the system pool
|
||||
if !certPool.AppendCertsFromPEM(cloudflareRootCA) {
|
||||
logger.Warn("could not append the CF certificate to the cloudflared certificate pool")
|
||||
} else {
|
||||
success = true
|
||||
}
|
||||
|
||||
if success != true { // Obtaining any of the CAs has failed; this is a fatal error
|
||||
return nil, errors.New("error loading any of the CAs into the global certificate pool")
|
||||
}
|
||||
|
||||
// Finally, add the Hello certificate into the pool (since it's self-signed)
|
||||
helloCertificate, err := GetHelloCertificateX509()
|
||||
if err != nil {
|
||||
logger.Warn("error obtaining the Hello server certificate")
|
||||
}
|
||||
|
||||
certPool.AddCert(helloCertificate)
|
||||
|
||||
return certPool, nil
|
||||
}
|
||||
|
||||
func LoadOriginCertPool(originCAPoolPEM []byte) (*x509.CertPool, error) {
|
||||
success := false
|
||||
|
||||
// Get the global pool
|
||||
certPool, globalPoolErr := LoadGlobalCertPool()
|
||||
if globalPoolErr != nil {
|
||||
certPool = x509.NewCertPool()
|
||||
} else {
|
||||
success = true
|
||||
}
|
||||
|
||||
// Then, add any custom origin CA pool the user may have passed
|
||||
if originCAPoolPEM != nil {
|
||||
if !certPool.AppendCertsFromPEM(originCAPoolPEM) {
|
||||
logger.Warn("could not append the provided origin CA to the cloudflared certificate pool")
|
||||
} else {
|
||||
success = true
|
||||
}
|
||||
}
|
||||
|
||||
if success != true {
|
||||
return nil, errors.New("error loading any of the CAs into the origin certificate pool")
|
||||
}
|
||||
|
||||
return certPool, nil
|
||||
}
|
||||
|
||||
func CreateTunnelConfig(c *cli.Context, addrs []string) *tls.Config {
|
||||
tlsConfig := CLIFlags{RootCA: "cacert"}.GetConfig(c)
|
||||
if tlsConfig.RootCAs == nil {
|
||||
tlsConfig.RootCAs = GetCloudflareRootCA()
|
||||
tlsConfig.ServerName = "cftunnel.com"
|
||||
} else if len(addrs) > 0 {
|
||||
// Set for development environments and for testing specific origintunneld instances
|
||||
tlsConfig.ServerName, _, _ = net.SplitHostPort(addrs[0])
|
||||
}
|
||||
return tlsConfig
|
||||
}
|
Reference in New Issue
Block a user