1/* 2Copyright 2017 The Kubernetes Authors. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package options 18 19import ( 20 "fmt" 21 "net" 22 23 "github.com/spf13/pflag" 24 25 "k8s.io/apiserver/pkg/server" 26 "k8s.io/client-go/rest" 27) 28 29// DeprecatedInsecureServingOptions are for creating an unauthenticated, unauthorized, insecure port. 30// No one should be using these anymore. 31// DEPRECATED: all insecure serving options are removed in a future version 32type DeprecatedInsecureServingOptions struct { 33 BindAddress net.IP 34 BindPort int 35 // BindNetwork is the type of network to bind to - defaults to "tcp", accepts "tcp", 36 // "tcp4", and "tcp6". 37 BindNetwork string 38 39 // Listener is the secure server network listener. 40 // either Listener or BindAddress/BindPort/BindNetwork is set, 41 // if Listener is set, use it and omit BindAddress/BindPort/BindNetwork. 42 Listener net.Listener 43 44 // ListenFunc can be overridden to create a custom listener, e.g. for mocking in tests. 45 // It defaults to options.CreateListener. 46 ListenFunc func(network, addr string, config net.ListenConfig) (net.Listener, int, error) 47} 48 49// Validate ensures that the insecure port values within the range of the port. 50func (s *DeprecatedInsecureServingOptions) Validate() []error { 51 if s == nil { 52 return nil 53 } 54 55 errors := []error{} 56 57 if s.BindPort < 0 || s.BindPort > 65535 { 58 errors = append(errors, fmt.Errorf("insecure port %v must be between 0 and 65535, inclusive. 0 for turning off insecure (HTTP) port", s.BindPort)) 59 } 60 61 return errors 62} 63 64// AddFlags adds flags related to insecure serving to the specified FlagSet. 65func (s *DeprecatedInsecureServingOptions) AddFlags(fs *pflag.FlagSet) { 66 if s == nil { 67 return 68 } 69 70 fs.IPVar(&s.BindAddress, "insecure-bind-address", s.BindAddress, ""+ 71 "The IP address on which to serve the --insecure-port (set to 0.0.0.0 for all IPv4 interfaces and :: for all IPv6 interfaces).") 72 // Though this flag is deprecated, we discovered security concerns over how to do health checks without it e.g. #43784 73 fs.MarkDeprecated("insecure-bind-address", "This flag will be removed in a future version.") 74 fs.Lookup("insecure-bind-address").Hidden = false 75 76 fs.IntVar(&s.BindPort, "insecure-port", s.BindPort, ""+ 77 "The port on which to serve unsecured, unauthenticated access.") 78 // Though this flag is deprecated, we discovered security concerns over how to do health checks without it e.g. #43784 79 fs.MarkDeprecated("insecure-port", "This flag will be removed in a future version.") 80 fs.Lookup("insecure-port").Hidden = false 81} 82 83// AddUnqualifiedFlags adds flags related to insecure serving without the --insecure prefix to the specified FlagSet. 84func (s *DeprecatedInsecureServingOptions) AddUnqualifiedFlags(fs *pflag.FlagSet) { 85 if s == nil { 86 return 87 } 88 89 fs.IPVar(&s.BindAddress, "address", s.BindAddress, 90 "The IP address on which to serve the insecure --port (set to 0.0.0.0 for all IPv4 interfaces and :: for all IPv6 interfaces).") 91 fs.MarkDeprecated("address", "see --bind-address instead.") 92 fs.Lookup("address").Hidden = false 93 94 fs.IntVar(&s.BindPort, "port", s.BindPort, "The port on which to serve unsecured, unauthenticated access. Set to 0 to disable.") 95 fs.MarkDeprecated("port", "see --secure-port instead.") 96 fs.Lookup("port").Hidden = false 97} 98 99// ApplyTo adds DeprecatedInsecureServingOptions to the insecureserverinfo and kube-controller manager configuration. 100// Note: the double pointer allows to set the *DeprecatedInsecureServingInfo to nil without referencing the struct hosting this pointer. 101func (s *DeprecatedInsecureServingOptions) ApplyTo(c **server.DeprecatedInsecureServingInfo) error { 102 if s == nil { 103 return nil 104 } 105 if s.BindPort <= 0 { 106 return nil 107 } 108 109 if s.Listener == nil { 110 var err error 111 listen := CreateListener 112 if s.ListenFunc != nil { 113 listen = s.ListenFunc 114 } 115 addr := net.JoinHostPort(s.BindAddress.String(), fmt.Sprintf("%d", s.BindPort)) 116 s.Listener, s.BindPort, err = listen(s.BindNetwork, addr, net.ListenConfig{}) 117 if err != nil { 118 return fmt.Errorf("failed to create listener: %v", err) 119 } 120 } 121 122 *c = &server.DeprecatedInsecureServingInfo{ 123 Listener: s.Listener, 124 } 125 126 return nil 127} 128 129// WithLoopback adds loopback functionality to the serving options. 130func (o *DeprecatedInsecureServingOptions) WithLoopback() *DeprecatedInsecureServingOptionsWithLoopback { 131 return &DeprecatedInsecureServingOptionsWithLoopback{o} 132} 133 134// DeprecatedInsecureServingOptionsWithLoopback adds loopback functionality to the DeprecatedInsecureServingOptions. 135// DEPRECATED: all insecure serving options will be removed in a future version, however note that 136// there are security concerns over how health checks can work here - see e.g. #43784 137type DeprecatedInsecureServingOptionsWithLoopback struct { 138 *DeprecatedInsecureServingOptions 139} 140 141// ApplyTo fills up serving information in the server configuration. 142func (s *DeprecatedInsecureServingOptionsWithLoopback) ApplyTo(insecureServingInfo **server.DeprecatedInsecureServingInfo, loopbackClientConfig **rest.Config) error { 143 if s == nil || s.DeprecatedInsecureServingOptions == nil || insecureServingInfo == nil { 144 return nil 145 } 146 147 if err := s.DeprecatedInsecureServingOptions.ApplyTo(insecureServingInfo); err != nil { 148 return err 149 } 150 151 if *insecureServingInfo == nil || loopbackClientConfig == nil { 152 return nil 153 } 154 155 secureLoopbackClientConfig, err := (*insecureServingInfo).NewLoopbackClientConfig() 156 switch { 157 // if we failed and there's no fallback loopback client config, we need to fail 158 case err != nil && *loopbackClientConfig == nil: 159 return err 160 161 // if we failed, but we already have a fallback loopback client config (usually insecure), allow it 162 case err != nil && *loopbackClientConfig != nil: 163 164 default: 165 *loopbackClientConfig = secureLoopbackClientConfig 166 } 167 168 return nil 169} 170