agent: setup grpc server with auto_encrypt certs and add -https-port (#7086)
* setup grpc server with TLS config used across consul. * add -https-port flag
This commit is contained in:
parent
f3a01e6a4a
commit
e00effa325
|
@ -723,9 +723,9 @@ func (a *Agent) listenAndServeGRPC() error {
|
|||
if a.config.HTTPSPort > 0 {
|
||||
// gRPC uses the same TLS settings as the HTTPS API. If HTTPS is
|
||||
// enabled then gRPC will require HTTPS as well.
|
||||
a.grpcServer, err = a.xdsServer.GRPCServer(a.config.CertFile, a.config.KeyFile)
|
||||
a.grpcServer, err = a.xdsServer.GRPCServer(a.tlsConfigurator)
|
||||
} else {
|
||||
a.grpcServer, err = a.xdsServer.GRPCServer("", "")
|
||||
a.grpcServer, err = a.xdsServer.GRPCServer(nil)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -79,6 +79,7 @@ func AddFlags(fs *flag.FlagSet, f *Flags) {
|
|||
add(&f.Config.EncryptKey, "encrypt", "Provides the gossip encryption key.")
|
||||
add(&f.Config.Ports.GRPC, "grpc-port", "Sets the gRPC API port to listen on (currently needed for Envoy xDS only).")
|
||||
add(&f.Config.Ports.HTTP, "http-port", "Sets the HTTP API port to listen on.")
|
||||
add(&f.Config.Ports.HTTPS, "https-port", "Sets the HTTPS API port to listen on.")
|
||||
add(&f.Config.StartJoinAddrsLAN, "join", "Address of an agent to join at start time. Can be specified multiple times.")
|
||||
add(&f.Config.StartJoinAddrsWAN, "join-wan", "Address of an agent to join -wan at start time. Can be specified multiple times.")
|
||||
add(&f.Config.LogLevel, "log-level", "Log level of the agent.")
|
||||
|
|
|
@ -52,6 +52,14 @@ func TestParseFlags(t *testing.T) {
|
|||
args: []string{`-grpc-port`, `1`},
|
||||
flags: Flags{Config: Config{Ports: Ports{GRPC: pInt(1)}}},
|
||||
},
|
||||
{
|
||||
args: []string{`-http-port`, `1`},
|
||||
flags: Flags{Config: Config{Ports: Ports{HTTP: pInt(1)}}},
|
||||
},
|
||||
{
|
||||
args: []string{`-https-port`, `1`},
|
||||
flags: Flags{Config: Config{Ports: Ports{HTTPS: pInt(1)}}},
|
||||
},
|
||||
{
|
||||
args: []string{`-serf-lan-port`, `1`},
|
||||
flags: Flags{Config: Config{Ports: Ports{SerfLAN: pInt(1)}}},
|
||||
|
|
|
@ -807,6 +807,7 @@ type RuntimeConfig struct {
|
|||
// Setting this to a value <= 0 disables the endpoint.
|
||||
//
|
||||
// hcl: ports { https = int }
|
||||
// flags: -https-port int
|
||||
HTTPSPort int
|
||||
|
||||
// KeyFile is used to provide a TLS key that is used for serving TLS
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/hashicorp/consul/agent/connect"
|
||||
"github.com/hashicorp/consul/agent/proxycfg"
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
"github.com/hashicorp/consul/tlsutil"
|
||||
)
|
||||
|
||||
// ADSStream is a shorter way of referring to this thing...
|
||||
|
@ -536,16 +537,15 @@ func (s *Server) Check(ctx context.Context, r *envoyauthz.CheckRequest) (*envoya
|
|||
|
||||
// GRPCServer returns a server instance that can handle XDS and ext_authz
|
||||
// requests.
|
||||
func (s *Server) GRPCServer(certFile, keyFile string) (*grpc.Server, error) {
|
||||
func (s *Server) GRPCServer(tlsConfigurator *tlsutil.Configurator) (*grpc.Server, error) {
|
||||
opts := []grpc.ServerOption{
|
||||
grpc.MaxConcurrentStreams(2048),
|
||||
}
|
||||
if certFile != "" && keyFile != "" {
|
||||
creds, err := credentials.NewServerTLSFromFile(certFile, keyFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if tlsConfigurator != nil {
|
||||
if tlsConfigurator.Cert() != nil {
|
||||
creds := credentials.NewTLS(tlsConfigurator.IncomingGRPCConfig())
|
||||
opts = append(opts, grpc.Creds(creds))
|
||||
}
|
||||
opts = append(opts, grpc.Creds(creds))
|
||||
}
|
||||
srv := grpc.NewServer(opts...)
|
||||
envoydisco.RegisterAggregatedDiscoveryServiceServer(srv, s)
|
||||
|
|
|
@ -441,12 +441,7 @@ func (c *Configurator) commonTLSConfig(verifyIncoming bool) *tls.Config {
|
|||
// autoEncrypt cert too so that a client can encrypt incoming
|
||||
// connections without having a manual cert configured.
|
||||
tlsConfig.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
cert := c.manual.cert
|
||||
if cert == nil {
|
||||
cert = c.autoEncrypt.cert
|
||||
}
|
||||
|
||||
return cert, nil
|
||||
return c.Cert(), nil
|
||||
}
|
||||
|
||||
// GetClientCertificate is used when acting as a client and responding
|
||||
|
@ -477,6 +472,17 @@ func (c *Configurator) commonTLSConfig(verifyIncoming bool) *tls.Config {
|
|||
return tlsConfig
|
||||
}
|
||||
|
||||
// This function acquires a read lock because it reads from the config.
|
||||
func (c *Configurator) Cert() *tls.Certificate {
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
cert := c.manual.cert
|
||||
if cert == nil {
|
||||
cert = c.autoEncrypt.cert
|
||||
}
|
||||
return cert
|
||||
}
|
||||
|
||||
// This function acquires a read lock because it reads from the config.
|
||||
func (c *Configurator) VerifyIncomingRPC() bool {
|
||||
c.RLock()
|
||||
|
@ -561,6 +567,22 @@ func (c *Configurator) VerifyServerHostname() bool {
|
|||
return c.base.VerifyServerHostname || c.autoEncrypt.verifyServerHostname
|
||||
}
|
||||
|
||||
// IncomingGRPCConfig generates a *tls.Config for incoming GRPC connections.
|
||||
func (c *Configurator) IncomingGRPCConfig() *tls.Config {
|
||||
c.log("IncomingGRPCConfig")
|
||||
|
||||
// false has the effect that this config doesn't require a client cert
|
||||
// verification. This is because there is no verify_incoming_grpc
|
||||
// configuration option. And using verify_incoming would be backwards
|
||||
// incompatible, because even if it was set before, it didn't have an
|
||||
// effect on the grpc server.
|
||||
config := c.commonTLSConfig(false)
|
||||
config.GetConfigForClient = func(*tls.ClientHelloInfo) (*tls.Config, error) {
|
||||
return c.IncomingGRPCConfig(), nil
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
// IncomingRPCConfig generates a *tls.Config for incoming RPC connections.
|
||||
func (c *Configurator) IncomingRPCConfig() *tls.Config {
|
||||
c.log("IncomingRPCConfig")
|
||||
|
|
|
@ -277,6 +277,10 @@ The options below are all specified on the command-line.
|
|||
to an environment which communicates the HTTP port through the environment e.g. PaaS like CloudFoundry, allowing
|
||||
you to set the port directly via a Procfile.
|
||||
|
||||
* <a name="_https_port"></a><a href="#_https_port">`-https-port`</a> - the HTTPS API
|
||||
port to listen on. Default -1 (https disabled). See [ports](#ports)
|
||||
documentation for more detail.
|
||||
|
||||
* <a name="_log_file"></a><a href="#_log_file">`-log-file`</a> - to redirect all the Consul agent log messages to a file. This can be specified with the complete path along with the name of the log. In case the path doesn't have the filename, the filename defaults to `consul-{timestamp}.log`. Can be combined with <a href="#_log_rotate_bytes"> -log-rotate-bytes</a> and <a href="#_log_rotate_duration"> -log-rotate-duration </a> for a fine-grained log rotation experience.
|
||||
|
||||
* <a name="_log_rotate_bytes"></a><a href="#_log_rotate_bytes">`-log-rotate-bytes`</a> - to specify the number of bytes that should be written to a log before it needs to be rotated. Unless specified, there is no limit to the number of bytes that can be written to a log file.
|
||||
|
|
Loading…
Reference in New Issue