Skip to content

Commit

Permalink
Merge pull request kubernetes-sigs#282 from Tamas-Biro1/add-ciphersui…
Browse files Browse the repository at this point in the history
…te-option

add option to change cipher suites
  • Loading branch information
k8s-ci-robot committed Nov 8, 2021
2 parents 2a7e07e + 793abba commit fc56f4b
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 8 deletions.
4 changes: 2 additions & 2 deletions cmd/agent/app/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type GrpcProxyAgentOptions struct {
SyncIntervalCap time.Duration
// After a duration of this time if the agent doesn't see any activity it
// pings the server to see if the transport is still alive.
KeepaliveTime time.Duration
KeepaliveTime time.Duration

// file contains service account authorization token for enabling proxy-server token based authorization
ServiceAccountTokenPath string
Expand All @@ -65,7 +65,7 @@ func (o *GrpcProxyAgentOptions) ClientSetConfig(dialOptions ...grpc.DialOption)
SyncIntervalCap: o.SyncIntervalCap,
DialOptions: dialOptions,
ServiceAccountTokenPath: o.ServiceAccountTokenPath,
WarnOnChannelLimit: o.WarnOnChannelLimit,
WarnOnChannelLimit: o.WarnOnChannelLimit,
}
}

Expand Down
23 changes: 23 additions & 0 deletions cmd/server/app/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"k8s.io/klog/v2"

"sigs.k8s.io/apiserver-network-proxy/pkg/server"
"sigs.k8s.io/apiserver-network-proxy/pkg/util"
)

type ProxyRunOptions struct {
Expand Down Expand Up @@ -77,6 +78,13 @@ type ProxyRunOptions struct {
// blocking call has its own problems, so it cannot easily be made race condition safe.
// The check is an "unlocked" read but is still use at your own peril.
WarnOnChannelLimit bool

// Cipher suites used by the server.
// If empty, the default suite will be used from tls.CipherSuites(),
// also checks if given comma separated list contains cipher from tls.InsecureCipherSuites().
// NOTE that cipher suites are not configurable for TLS1.3,
// see: https://pkg.go.dev/crypto/tls#Config, so in that case, this option won't have any effect.
CipherSuites string
}

func (o *ProxyRunOptions) Flags() *pflag.FlagSet {
Expand Down Expand Up @@ -108,6 +116,7 @@ func (o *ProxyRunOptions) Flags() *pflag.FlagSet {
flags.StringVar(&o.AuthenticationAudience, "authentication-audience", o.AuthenticationAudience, "Expected agent's token authentication audience (used with agent-namespace, agent-service-account, kubeconfig).")
flags.StringVar(&o.ProxyStrategies, "proxy-strategies", o.ProxyStrategies, "The list of proxy strategies used by the server to pick a backend/tunnel, available strategies are: default, destHost.")
flags.BoolVar(&o.WarnOnChannelLimit, "warn-on-channel-limit", o.WarnOnChannelLimit, "Turns on a warning if the system is going to push to a full channel. The check involves an unsafe read.")
flags.StringVar(&o.CipherSuites, "cipher-suites", o.CipherSuites, "The comma separated list of allowed cipher suites. Has no effect on TLS1.3. Empty means allow default list.")
return flags
}

Expand Down Expand Up @@ -139,6 +148,7 @@ func (o *ProxyRunOptions) Print() {
klog.V(1).Infof("KubeconfigBurst set to %d.\n", o.KubeconfigBurst)
klog.V(1).Infof("ProxyStrategies set to %q.\n", o.ProxyStrategies)
klog.V(1).Infof("WarnOnChannelLimit set to %t.\n", o.WarnOnChannelLimit)
klog.V(1).Infof("CipherSuites set to %q.\n", o.CipherSuites)
}

func (o *ProxyRunOptions) Validate() error {
Expand Down Expand Up @@ -268,6 +278,18 @@ func (o *ProxyRunOptions) Validate() error {
}
}

// validate the cipher suites
if o.CipherSuites != "" {
acceptedCiphers := util.GetAcceptedCiphers()
css := strings.Split(o.CipherSuites, ",")
for _, cipher := range css {
_, ok := acceptedCiphers[cipher]
if !ok {
return fmt.Errorf("cipher suite %s not supported, doesn't exist or considered as insecure", cipher)
}
}
}

return nil
}

Expand Down Expand Up @@ -300,6 +322,7 @@ func NewProxyRunOptions() *ProxyRunOptions {
AuthenticationAudience: "",
ProxyStrategies: "default",
WarnOnChannelLimit: false,
CipherSuites: "",
}
return &o
}
27 changes: 23 additions & 4 deletions cmd/server/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"os/signal"
"path/filepath"
"runtime"
"strings"
"sync"
"syscall"

Expand Down Expand Up @@ -46,6 +47,20 @@ func NewProxyCommand(p *Proxy, o *options.ProxyRunOptions) *cobra.Command {
return cmd
}

func tlsCipherSuites(cipherNames []string) []uint16 {
// return nil, so use default cipher list
if len(cipherNames) == 0 {
return nil
}

acceptedCiphers := util.GetAcceptedCiphers()
ciphersIntSlice := make([]uint16, 0)
for _, cipher := range cipherNames {
ciphersIntSlice = append(ciphersIntSlice, acceptedCiphers[cipher])
}
return ciphersIntSlice
}

type Proxy struct {
}

Expand Down Expand Up @@ -211,14 +226,16 @@ func (p *Proxy) runUDSFrontendServer(ctx context.Context, o *options.ProxyRunOpt
return stop, nil
}

func (p *Proxy) getTLSConfig(caFile, certFile, keyFile string) (*tls.Config, error) {
func (p *Proxy) getTLSConfig(caFile, certFile, keyFile, cipherSuites string) (*tls.Config, error) {
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return nil, fmt.Errorf("failed to load X509 key pair %s and %s: %v", certFile, keyFile, err)
}

cipherSuiteIDs := tlsCipherSuites(strings.Split(cipherSuites, ","))

if caFile == "" {
return &tls.Config{Certificates: []tls.Certificate{cert}, MinVersion: tls.VersionTLS12}, nil
return &tls.Config{Certificates: []tls.Certificate{cert}, MinVersion: tls.VersionTLS12, CipherSuites: cipherSuiteIDs}, nil
}

certPool := x509.NewCertPool()
Expand All @@ -230,11 +247,13 @@ func (p *Proxy) getTLSConfig(caFile, certFile, keyFile string) (*tls.Config, err
if !ok {
return nil, fmt.Errorf("failed to append cluster CA cert to the cert pool")
}

tlsConfig := &tls.Config{
ClientAuth: tls.RequireAndVerifyClientCert,
Certificates: []tls.Certificate{cert},
ClientCAs: certPool,
MinVersion: tls.VersionTLS12,
CipherSuites: cipherSuiteIDs,
}

return tlsConfig, nil
Expand All @@ -245,7 +264,7 @@ func (p *Proxy) runMTLSFrontendServer(ctx context.Context, o *options.ProxyRunOp

var tlsConfig *tls.Config
var err error
if tlsConfig, err = p.getTLSConfig(o.ServerCaCert, o.ServerCert, o.ServerKey); err != nil {
if tlsConfig, err = p.getTLSConfig(o.ServerCaCert, o.ServerCert, o.ServerKey, o.CipherSuites); err != nil {
return nil, err
}

Expand Down Expand Up @@ -294,7 +313,7 @@ func (p *Proxy) runMTLSFrontendServer(ctx context.Context, o *options.ProxyRunOp
func (p *Proxy) runAgentServer(o *options.ProxyRunOptions, server *server.ProxyServer) error {
var tlsConfig *tls.Config
var err error
if tlsConfig, err = p.getTLSConfig(o.ClusterCaCert, o.ClusterCert, o.ClusterKey); err != nil {
if tlsConfig, err = p.getTLSConfig(o.ClusterCaCert, o.ClusterCert, o.ClusterKey, o.CipherSuites); err != nil {
return err
}

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ require (
github.com/golang/mock v1.4.4
github.com/golang/protobuf v1.4.3
github.com/google/uuid v1.1.2
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/prometheus/client_golang v1.7.1
github.com/spf13/cobra v0.0.3
github.com/spf13/pflag v1.0.5
Expand All @@ -30,6 +29,7 @@ require (
github.com/google/gofuzz v1.1.0 // indirect
github.com/googleapis/gnostic v0.4.1 // indirect
github.com/imdario/mergo v0.3.5 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/json-iterator/go v1.1.10 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
Expand Down
2 changes: 1 addition & 1 deletion pkg/agent/clientset.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func (cc *ClientSetConfig) NewAgentClientSet(stopCh <-chan struct{}) *ClientSet
syncIntervalCap: cc.SyncIntervalCap,
dialOptions: cc.DialOptions,
serviceAccountTokenPath: cc.ServiceAccountTokenPath,
warnOnChannelLimit: cc.WarnOnChannelLimit,
warnOnChannelLimit: cc.WarnOnChannelLimit,
stopCh: stopCh,
}
}
Expand Down
10 changes: 10 additions & 0 deletions pkg/util/net.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package util

import (
"crypto/tls"
"strings"
)

Expand Down Expand Up @@ -48,3 +49,12 @@ func RemovePortFromHost(host string) string {
}
return strings.Trim(host, "[]")
}

// GetAcceptedCiphers returns all the ciphers supported by the crypto/tls package
func GetAcceptedCiphers() map[string]uint16 {
acceptedCiphers := make(map[string]uint16, len(tls.CipherSuites()))
for _, v := range tls.CipherSuites() {
acceptedCiphers[v.Name] = v.ID
}
return acceptedCiphers
}

0 comments on commit fc56f4b

Please sign in to comment.