mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
fn: SSL config adjustments (#1160)
SSL related FN_NODE_CERT (and related) settings are not very clear today. Removing this in favor of a simple map of tls.Config objects. Three keys are provided for this map: TLSGRPCServer TLSAdminServer TLSWebServer which correspond to server TLS settings for the associated services. Operators/implementers can further add more keys to the map and add their own TLS config.
This commit is contained in:
@@ -2,6 +2,7 @@ package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -27,13 +28,12 @@ type mockRunner struct {
|
||||
type mockRunnerPool struct {
|
||||
runners []pool.Runner
|
||||
generator pool.MTLSRunnerFactory
|
||||
pki *pool.PKIData
|
||||
}
|
||||
|
||||
func newMockRunnerPool(rf pool.MTLSRunnerFactory, runnerAddrs []string) *mockRunnerPool {
|
||||
var runners []pool.Runner
|
||||
for _, addr := range runnerAddrs {
|
||||
r, err := rf(addr, "", nil)
|
||||
r, err := rf(addr, nil)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
@@ -43,7 +43,6 @@ func newMockRunnerPool(rf pool.MTLSRunnerFactory, runnerAddrs []string) *mockRun
|
||||
return &mockRunnerPool{
|
||||
runners: runners,
|
||||
generator: rf,
|
||||
pki: &pool.PKIData{},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +55,7 @@ func (rp *mockRunnerPool) Shutdown(context.Context) error {
|
||||
}
|
||||
|
||||
func NewMockRunnerFactory(sleep time.Duration, maxCalls int32) pool.MTLSRunnerFactory {
|
||||
return func(addr, cn string, pki *pool.PKIData) (pool.Runner, error) {
|
||||
return func(addr string, tlsConf *tls.Config) (pool.Runner, error) {
|
||||
return &mockRunner{
|
||||
sleep: sleep,
|
||||
maxCalls: maxCalls,
|
||||
@@ -66,7 +65,7 @@ func NewMockRunnerFactory(sleep time.Duration, maxCalls int32) pool.MTLSRunnerFa
|
||||
}
|
||||
|
||||
func FaultyRunnerFactory() pool.MTLSRunnerFactory {
|
||||
return func(addr, cn string, pki *pool.PKIData) (pool.Runner, error) {
|
||||
return func(addr string, tlsConf *tls.Config) (pool.Runner, error) {
|
||||
return &mockRunner{
|
||||
addr: addr,
|
||||
}, errors.New("Creation of new runner failed")
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
@@ -866,26 +865,22 @@ func (pr *pureRunner) Status(ctx context.Context, _ *empty.Empty) (*runner.Runne
|
||||
return pr.handleStatusCall(ctx)
|
||||
}
|
||||
|
||||
func DefaultPureRunner(cancel context.CancelFunc, addr string, da CallHandler, cert string, key string, ca string) (Agent, error) {
|
||||
func DefaultPureRunner(cancel context.CancelFunc, addr string, da CallHandler, tlsCfg *tls.Config) (Agent, error) {
|
||||
|
||||
agent := New(da)
|
||||
|
||||
// WARNING: SSL creds are optional.
|
||||
if cert == "" || key == "" || ca == "" {
|
||||
if tlsCfg == nil {
|
||||
return NewPureRunner(cancel, addr, PureRunnerWithAgent(agent))
|
||||
}
|
||||
return NewPureRunner(cancel, addr, PureRunnerWithAgent(agent), PureRunnerWithSSL(cert, key, ca))
|
||||
return NewPureRunner(cancel, addr, PureRunnerWithAgent(agent), PureRunnerWithSSL(tlsCfg))
|
||||
}
|
||||
|
||||
type PureRunnerOption func(*pureRunner) error
|
||||
|
||||
func PureRunnerWithSSL(cert string, key string, ca string) PureRunnerOption {
|
||||
func PureRunnerWithSSL(tlsCfg *tls.Config) PureRunnerOption {
|
||||
return func(pr *pureRunner) error {
|
||||
c, err := createCreds(cert, key, ca)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to create pure runner credentials: %s", err)
|
||||
}
|
||||
pr.creds = c
|
||||
pr.creds = credentials.NewTLS(tlsCfg)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -961,34 +956,5 @@ func NewPureRunner(cancel context.CancelFunc, addr string, options ...PureRunner
|
||||
return pr, nil
|
||||
}
|
||||
|
||||
func createCreds(cert string, key string, ca string) (credentials.TransportCredentials, error) {
|
||||
if cert == "" || key == "" || ca == "" {
|
||||
return nil, errors.New("Failed to create credentials, cert/key/ca not provided")
|
||||
}
|
||||
|
||||
// Load the certificates from disk
|
||||
certificate, err := tls.LoadX509KeyPair(cert, key)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not load server key pair: %s", err)
|
||||
}
|
||||
|
||||
// Create a certificate pool from the certificate authority
|
||||
certPool := x509.NewCertPool()
|
||||
authority, err := ioutil.ReadFile(ca)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not read ca certificate: %s", err)
|
||||
}
|
||||
|
||||
if ok := certPool.AppendCertsFromPEM(authority); !ok {
|
||||
return nil, errors.New("Failed to append client certs")
|
||||
}
|
||||
|
||||
return credentials.NewTLS(&tls.Config{
|
||||
ClientAuth: tls.RequireAndVerifyClientCert,
|
||||
Certificates: []tls.Certificate{certificate},
|
||||
ClientCAs: certPool,
|
||||
}), nil
|
||||
}
|
||||
|
||||
var _ runner.RunnerProtocolServer = &pureRunner{}
|
||||
var _ Agent = &pureRunner{}
|
||||
|
||||
@@ -2,6 +2,7 @@ package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
@@ -39,8 +40,8 @@ type gRPCRunner struct {
|
||||
client pb.RunnerProtocolClient
|
||||
}
|
||||
|
||||
func SecureGRPCRunnerFactory(addr, runnerCertCN string, pki *pool.PKIData) (pool.Runner, error) {
|
||||
conn, client, err := runnerConnection(addr, runnerCertCN, pki)
|
||||
func SecureGRPCRunnerFactory(addr string, tlsConf *tls.Config) (pool.Runner, error) {
|
||||
conn, client, err := runnerConnection(addr, tlsConf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -59,20 +60,15 @@ func (r *gRPCRunner) Close(context.Context) error {
|
||||
return r.conn.Close()
|
||||
}
|
||||
|
||||
func runnerConnection(address, runnerCertCN string, pki *pool.PKIData) (*grpc.ClientConn, pb.RunnerProtocolClient, error) {
|
||||
func runnerConnection(address string, tlsConf *tls.Config) (*grpc.ClientConn, pb.RunnerProtocolClient, error) {
|
||||
|
||||
ctx := context.Background()
|
||||
logger := common.Logger(ctx).WithField("runner_addr", address)
|
||||
ctx = common.WithLogger(ctx, logger)
|
||||
|
||||
var creds credentials.TransportCredentials
|
||||
if pki != nil {
|
||||
var err error
|
||||
creds, err = grpcutil.CreateCredentials(pki.Cert, pki.Key, pki.Ca, runnerCertCN)
|
||||
if err != nil {
|
||||
logger.WithError(err).Error("Unable to create credentials to connect to runner node")
|
||||
return nil, nil, err
|
||||
}
|
||||
if tlsConf != nil {
|
||||
creds = credentials.NewTLS(tlsConf)
|
||||
}
|
||||
|
||||
// we want to set a very short timeout to fail-fast if something goes wrong
|
||||
|
||||
@@ -2,6 +2,7 @@ package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
|
||||
pool "github.com/fnproject/fn/api/runnerpool"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -10,20 +11,20 @@ import (
|
||||
// manages a single set of runners ignoring lb groups
|
||||
type staticRunnerPool struct {
|
||||
generator pool.MTLSRunnerFactory
|
||||
pki *pool.PKIData // can be nil when running in insecure mode
|
||||
tlsConf *tls.Config // can be nil when running in insecure mode
|
||||
runnerCN string
|
||||
runners []pool.Runner
|
||||
}
|
||||
|
||||
func DefaultStaticRunnerPool(runnerAddresses []string) pool.RunnerPool {
|
||||
return NewStaticRunnerPool(runnerAddresses, nil, "", SecureGRPCRunnerFactory)
|
||||
return NewStaticRunnerPool(runnerAddresses, nil, SecureGRPCRunnerFactory)
|
||||
}
|
||||
|
||||
func NewStaticRunnerPool(runnerAddresses []string, pki *pool.PKIData, runnerCN string, runnerFactory pool.MTLSRunnerFactory) pool.RunnerPool {
|
||||
func NewStaticRunnerPool(runnerAddresses []string, tlsConf *tls.Config, runnerFactory pool.MTLSRunnerFactory) pool.RunnerPool {
|
||||
logrus.WithField("runners", runnerAddresses).Info("Starting static runner pool")
|
||||
var runners []pool.Runner
|
||||
for _, addr := range runnerAddresses {
|
||||
r, err := runnerFactory(addr, runnerCN, pki)
|
||||
r, err := runnerFactory(addr, tlsConf)
|
||||
if err != nil {
|
||||
logrus.WithError(err).WithField("runner_addr", addr).Warn("Invalid runner")
|
||||
continue
|
||||
@@ -33,8 +34,7 @@ func NewStaticRunnerPool(runnerAddresses []string, pki *pool.PKIData, runnerCN s
|
||||
}
|
||||
return &staticRunnerPool{
|
||||
runners: runners,
|
||||
pki: pki,
|
||||
runnerCN: runnerCN,
|
||||
tlsConf: tlsConf,
|
||||
generator: runnerFactory,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
@@ -9,7 +10,7 @@ import (
|
||||
)
|
||||
|
||||
func setupStaticPool(runners []string) pool.RunnerPool {
|
||||
return NewStaticRunnerPool(runners, nil, "", mockRunnerFactory)
|
||||
return NewStaticRunnerPool(runners, nil, mockRunnerFactory)
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -36,7 +37,7 @@ func (r *mockStaticRunner) Address() string {
|
||||
return r.address
|
||||
}
|
||||
|
||||
func mockRunnerFactory(addr, cn string, pki *pool.PKIData) (pool.Runner, error) {
|
||||
func mockRunnerFactory(addr string, tlsConf *tls.Config) (pool.Runner, error) {
|
||||
return &mockStaticRunner{address: addr}, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user