// InClusterConfig returns a config object which uses the service account // kubernetes gives to pods. It's intended for clients that expect to be // running inside a pod running on kubernetes. It will return an error if // called from a process not running in a kubernetes environment. func InClusterConfig() (*Config, error) { host, port := os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT") if len(host) == 0 || len(port) == 0 { return nil, fmt.Errorf("unable to load in-cluster configuration, KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined") } token, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/" + api.ServiceAccountTokenKey) if err != nil { return nil, err } tlsClientConfig := TLSClientConfig{} rootCAFile := "/var/run/secrets/kubernetes.io/serviceaccount/" + api.ServiceAccountRootCAKey if _, err := certutil.NewPool(rootCAFile); err != nil { glog.Errorf("Expected to load root CA config from %s, but got err: %v", rootCAFile, err) } else { tlsClientConfig.CAFile = rootCAFile } return &Config{ // TODO: switch to using cluster DNS. Host: "https://" + net.JoinHostPort(host, port), BearerToken: string(token), TLSClientConfig: tlsClientConfig, }, nil }
// InitializeTLS checks for a configured TLSCertFile and TLSPrivateKeyFile: if unspecified a new self-signed // certificate and key file are generated. Returns a configured server.TLSOptions object. func InitializeTLS(kc *componentconfig.KubeletConfiguration) (*server.TLSOptions, error) { if kc.TLSCertFile == "" && kc.TLSPrivateKeyFile == "" { kc.TLSCertFile = path.Join(kc.CertDirectory, "kubelet.crt") kc.TLSPrivateKeyFile = path.Join(kc.CertDirectory, "kubelet.key") if !certutil.CanReadCertOrKey(kc.TLSCertFile, kc.TLSPrivateKeyFile) { if err := certutil.GenerateSelfSignedCert(nodeutil.GetHostname(kc.HostnameOverride), kc.TLSCertFile, kc.TLSPrivateKeyFile, nil, nil); err != nil { return nil, fmt.Errorf("unable to generate self signed cert: %v", err) } glog.V(4).Infof("Using self-signed cert (%s, %s)", kc.TLSCertFile, kc.TLSPrivateKeyFile) } } tlsOptions := &server.TLSOptions{ Config: &tls.Config{ // Can't use SSLv3 because of POODLE and BEAST // Can't use TLSv1.0 because of POODLE and BEAST using CBC cipher // Can't use TLSv1.1 because of RC4 cipher usage MinVersion: tls.VersionTLS12, }, CertFile: kc.TLSCertFile, KeyFile: kc.TLSPrivateKeyFile, } if len(kc.Authentication.X509.ClientCAFile) > 0 { clientCAs, err := cert.NewPool(kc.Authentication.X509.ClientCAFile) if err != nil { return nil, fmt.Errorf("unable to load client CA file %s: %v", kc.Authentication.X509.ClientCAFile, err) } // Specify allowed CAs for client certificates tlsOptions.Config.ClientCAs = clientCAs // Populate PeerCertificates in requests, but don't reject connections without verified certificates tlsOptions.Config.ClientAuth = tls.RequestClientCert } return tlsOptions, nil }
func (o CreateNodeConfigOptions) Validate(args []string) error { if len(args) != 0 { return errors.New("no arguments are supported") } if len(o.NodeConfigDir) == 0 { return errors.New("--node-dir must be provided") } if len(o.NodeName) == 0 { return errors.New("--node must be provided") } if len(o.APIServerURL) == 0 { return errors.New("--master must be provided") } if len(o.APIServerCAFiles) == 0 { return fmt.Errorf("--certificate-authority must be a valid certificate file") } else { for _, caFile := range o.APIServerCAFiles { if _, err := cert.NewPool(caFile); err != nil { return fmt.Errorf("--certificate-authority must be a valid certificate file: %v", err) } } } if len(o.Hostnames) == 0 { return errors.New("at least one hostname must be provided") } if len(o.ClientCertFile) != 0 { if len(o.ClientKeyFile) == 0 { return errors.New("--client-key must be provided if --client-certificate is provided") } } else if len(o.ClientKeyFile) != 0 { return errors.New("--client-certificate must be provided if --client-key is provided") } if len(o.ServerCertFile) != 0 { if len(o.ServerKeyFile) == 0 { return errors.New("--server-key must be provided if --server-certificate is provided") } } else if len(o.ServerKeyFile) != 0 { return errors.New("--server-certificate must be provided if --server-key is provided") } if o.IsCreateClientCertificate() || o.IsCreateServerCertificate() { if len(o.SignerCertOptions.KeyFile) == 0 { return errors.New("--signer-key must be provided to create certificates") } if len(o.SignerCertOptions.CertFile) == 0 { return errors.New("--signer-cert must be provided to create certificates") } if len(o.SignerCertOptions.SerialFile) == 0 { return errors.New("--signer-serial must be provided to create certificates") } } if o.ExpireDays < 0 { return errors.New("expire-days must be valid number of days") } return nil }
func (o CreateKubeConfigOptions) Validate(args []string) error { if len(args) != 0 { return errors.New("no arguments are supported") } if len(o.KubeConfigFile) == 0 { return errors.New("kubeconfig must be provided") } if len(o.CertFile) == 0 { return errors.New("client-certificate must be provided") } if len(o.KeyFile) == 0 { return errors.New("client-key must be provided") } if len(o.APIServerCAFiles) == 0 { return errors.New("certificate-authority must be provided") } else { for _, caFile := range o.APIServerCAFiles { if _, err := cert.NewPool(caFile); err != nil { return fmt.Errorf("certificate-authority must be a valid certificate file: %v", err) } } } if len(o.ContextNamespace) == 0 { return errors.New("namespace must be provided") } if len(o.APIServerURL) == 0 { return errors.New("master must be provided") } return nil }
// newAuthenticatorFromClientCAFile returns an authenticator.Request or an error func newAuthenticatorFromClientCAFile(clientCAFile string) (authenticator.Request, error) { roots, err := certutil.NewPool(clientCAFile) if err != nil { return nil, err } opts := x509.DefaultVerifyOptions() opts.Roots = roots return x509.New(opts, x509.CommonNameUserConversion), nil }
// serveSecurely runs the secure http server. It fails only if certificates cannot // be loaded or the initial listen call fails. The actual server loop (stoppable by closing // stopCh) runs in a go routine, i.e. serveSecurely does not block. func (s *GenericAPIServer) serveSecurely(stopCh <-chan struct{}) error { namedCerts, err := getNamedCertificateMap(s.SecureServingInfo.SNICerts) if err != nil { return fmt.Errorf("unable to load SNI certificates: %v", err) } secureServer := &http.Server{ Addr: s.SecureServingInfo.BindAddress, Handler: s.Handler, MaxHeaderBytes: 1 << 20, TLSConfig: &tls.Config{ NameToCertificate: namedCerts, // Can't use SSLv3 because of POODLE and BEAST // Can't use TLSv1.0 because of POODLE and BEAST using CBC cipher // Can't use TLSv1.1 because of RC4 cipher usage MinVersion: tls.VersionTLS12, // enable HTTP2 for go's 1.7 HTTP Server NextProtos: []string{"h2", "http/1.1"}, }, } if len(s.SecureServingInfo.ServerCert.CertFile) != 0 || len(s.SecureServingInfo.ServerCert.KeyFile) != 0 { secureServer.TLSConfig.Certificates = make([]tls.Certificate, 1) secureServer.TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(s.SecureServingInfo.ServerCert.CertFile, s.SecureServingInfo.ServerCert.KeyFile) if err != nil { return fmt.Errorf("unable to load server certificate: %v", err) } } // append all named certs. Otherwise, the go tls stack will think no SNI processing // is necessary because there is only one cert anyway. // Moreover, if ServerCert.CertFile/ServerCert.KeyFile are not set, the first SNI // cert will become the default cert. That's what we expect anyway. for _, c := range namedCerts { secureServer.TLSConfig.Certificates = append(secureServer.TLSConfig.Certificates, *c) } if len(s.SecureServingInfo.ClientCA) > 0 { clientCAs, err := certutil.NewPool(s.SecureServingInfo.ClientCA) if err != nil { return fmt.Errorf("unable to load client CA file: %v", err) } // Populate PeerCertificates in requests, but don't reject connections without certificates // This allows certificates to be validated by authenticators, while still allowing other auth types secureServer.TLSConfig.ClientAuth = tls.RequestClientCert // Specify allowed CAs for client certificates secureServer.TLSConfig.ClientCAs = clientCAs } glog.Infof("Serving securely on %s", s.SecureServingInfo.BindAddress) s.effectiveSecurePort, err = runServer(secureServer, stopCh) return err }
// New creates a token authenticator which validates OpenID Connect ID Tokens. func New(opts OIDCOptions) (*OIDCAuthenticator, error) { url, err := url.Parse(opts.IssuerURL) if err != nil { return nil, err } if url.Scheme != "https" { return nil, fmt.Errorf("'oidc-issuer-url' (%q) has invalid scheme (%q), require 'https'", opts.IssuerURL, url.Scheme) } if opts.UsernameClaim == "" { return nil, errors.New("no username claim provided") } var roots *x509.CertPool if opts.CAFile != "" { roots, err = certutil.NewPool(opts.CAFile) if err != nil { return nil, fmt.Errorf("Failed to read the CA file: %v", err) } } else { glog.Info("OIDC: No x509 certificates provided, will use host's root CA set") } // Copied from http.DefaultTransport. tr := net.SetTransportDefaults(&http.Transport{ // According to golang's doc, if RootCAs is nil, // TLS uses the host's root CA set. TLSClientConfig: &tls.Config{RootCAs: roots}, }) authenticator := &OIDCAuthenticator{ issuerURL: opts.IssuerURL, trustedClientID: opts.ClientID, usernameClaim: opts.UsernameClaim, groupsClaim: opts.GroupsClaim, httpClient: &http.Client{Transport: tr}, } // Attempt to initialize the authenticator asynchronously. // // Ignore errors instead of returning it since the OpenID Connect provider might not be // available yet, for instance if it's running on the cluster and needs the API server // to come up first. Errors will be logged within the client() method. go func() { defer runtime.HandleCrash() authenticator.client() }() return authenticator, nil }
func (o CreateMasterCertsOptions) Validate(args []string) error { if len(args) != 0 { return errors.New("no arguments are supported") } if len(o.Hostnames) == 0 { return errors.New("at least one hostname must be provided") } if len(o.CertDir) == 0 { return errors.New("cert-dir must be provided") } if len(o.SignerName) == 0 { return errors.New("signer-name must be provided") } if o.ExpireDays <= 0 { return errors.New("expire-days must be valid number of days") } if o.SignerExpireDays <= 0 { return errors.New("signer-expire-days must be valid number of days") } if len(o.APIServerURL) == 0 { return errors.New("master must be provided") } else if u, err := url.Parse(o.APIServerURL); err != nil { return errors.New("master must be a valid URL (e.g. https://10.0.0.1:8443)") } else if len(u.Scheme) == 0 { return errors.New("master must be a valid URL (e.g. https://10.0.0.1:8443)") } if len(o.PublicAPIServerURL) == 0 { // not required } else if u, err := url.Parse(o.PublicAPIServerURL); err != nil { return errors.New("public master must be a valid URL (e.g. https://example.com:8443)") } else if len(u.Scheme) == 0 { return errors.New("public master must be a valid URL (e.g. https://example.com:8443)") } for _, caFile := range o.APIServerCAFiles { if _, err := cert.NewPool(caFile); err != nil { return fmt.Errorf("certificate authority must be a valid certificate file: %v", err) } } return nil }
// NewKeystoneAuthenticator returns a password authenticator that validates credentials using openstack keystone func NewKeystoneAuthenticator(authURL string, caFile string) (*KeystoneAuthenticator, error) { if !strings.HasPrefix(authURL, "https") { return nil, errors.New("Auth URL should be secure and start with https") } if authURL == "" { return nil, errors.New("Auth URL is empty") } if caFile != "" { roots, err := certutil.NewPool(caFile) if err != nil { return nil, err } config := &tls.Config{} config.RootCAs = roots transport := netutil.SetOldTransportDefaults(&http.Transport{TLSClientConfig: config}) return &KeystoneAuthenticator{authURL, transport}, nil } return &KeystoneAuthenticator{authURL: authURL}, nil }
func buildAuthn(client authenticationclient.TokenReviewInterface, authn componentconfig.KubeletAuthentication) (authenticator.Request, error) { authenticators := []authenticator.Request{} // x509 client cert auth if len(authn.X509.ClientCAFile) > 0 { clientCAs, err := cert.NewPool(authn.X509.ClientCAFile) if err != nil { return nil, fmt.Errorf("unable to load client CA file %s: %v", authn.X509.ClientCAFile, err) } verifyOpts := x509.DefaultVerifyOptions() verifyOpts.Roots = clientCAs authenticators = append(authenticators, x509.New(verifyOpts, x509.CommonNameUserConversion)) } // bearer token auth that uses authentication.k8s.io TokenReview to determine userinfo if authn.Webhook.Enabled { if client == nil { return nil, errors.New("no client provided, cannot use webhook authentication") } tokenAuth, err := webhooktoken.NewFromInterface(client, authn.Webhook.CacheTTL.Duration) if err != nil { return nil, err } authenticators = append(authenticators, bearertoken.New(tokenAuth)) } if len(authenticators) == 0 { if authn.Anonymous.Enabled { return anonymous.NewAuthenticator(), nil } return nil, errors.New("No authentication method configured") } authenticator := group.NewGroupAdder(unionauth.New(authenticators...), []string{"system:authenticated"}) if authn.Anonymous.Enabled { authenticator = unionauth.NewFailOnError(authenticator, anonymous.NewAuthenticator()) } return authenticator, nil }
func (s *GenericAPIServer) Run(options *options.ServerRunOptions) { // install APIs which depend on other APIs to be installed if s.enableSwaggerSupport { s.InstallSwaggerAPI() } if s.enableOpenAPISupport { s.InstallOpenAPI() } secureStartedCh := make(chan struct{}) if options.SecurePort != 0 { secureLocation := net.JoinHostPort(options.BindAddress.String(), strconv.Itoa(options.SecurePort)) secureServer := &http.Server{ Addr: secureLocation, Handler: s.Handler, MaxHeaderBytes: 1 << 20, TLSConfig: &tls.Config{ // Can't use SSLv3 because of POODLE and BEAST // Can't use TLSv1.0 because of POODLE and BEAST using CBC cipher // Can't use TLSv1.1 because of RC4 cipher usage MinVersion: tls.VersionTLS12, }, } if len(options.ClientCAFile) > 0 { clientCAs, err := certutil.NewPool(options.ClientCAFile) if err != nil { glog.Fatalf("Unable to load client CA file: %v", err) } // Populate PeerCertificates in requests, but don't reject connections without certificates // This allows certificates to be validated by authenticators, while still allowing other auth types secureServer.TLSConfig.ClientAuth = tls.RequestClientCert // Specify allowed CAs for client certificates secureServer.TLSConfig.ClientCAs = clientCAs // "h2" NextProtos is necessary for enabling HTTP2 for go's 1.7 HTTP Server secureServer.TLSConfig.NextProtos = []string{"h2"} } glog.Infof("Serving securely on %s", secureLocation) if options.TLSCertFile == "" && options.TLSPrivateKeyFile == "" { options.TLSCertFile = path.Join(options.CertDirectory, "apiserver.crt") options.TLSPrivateKeyFile = path.Join(options.CertDirectory, "apiserver.key") // TODO (cjcullen): Is ClusterIP the right address to sign a cert with? alternateIPs := []net.IP{s.ServiceReadWriteIP} alternateDNS := []string{"kubernetes.default.svc", "kubernetes.default", "kubernetes", "localhost"} // It would be nice to set a fqdn subject alt name, but only the kubelets know, the apiserver is clueless // alternateDNS = append(alternateDNS, "kubernetes.default.svc.CLUSTER.DNS.NAME") if !certutil.CanReadCertOrKey(options.TLSCertFile, options.TLSPrivateKeyFile) { if err := certutil.GenerateSelfSignedCert(s.ClusterIP.String(), options.TLSCertFile, options.TLSPrivateKeyFile, alternateIPs, alternateDNS); err != nil { glog.Errorf("Unable to generate self signed cert: %v", err) } else { glog.Infof("Using self-signed cert (%s, %s)", options.TLSCertFile, options.TLSPrivateKeyFile) } } } go func() { defer utilruntime.HandleCrash() notifyStarted := sync.Once{} for { if err := secureServer.ListenAndServeTLS(options.TLSCertFile, options.TLSPrivateKeyFile); err != nil { glog.Errorf("Unable to listen for secure (%v); will try again.", err) } else { notifyStarted.Do(func() { close(secureStartedCh) }) } time.Sleep(15 * time.Second) } }() } else { close(secureStartedCh) } insecureLocation := net.JoinHostPort(options.InsecureBindAddress.String(), strconv.Itoa(options.InsecurePort)) insecureServer := &http.Server{ Addr: insecureLocation, Handler: s.InsecureHandler, MaxHeaderBytes: 1 << 20, } insecureStartedCh := make(chan struct{}) glog.Infof("Serving insecurely on %s", insecureLocation) go func() { defer utilruntime.HandleCrash() notifyStarted := sync.Once{} for { if err := insecureServer.ListenAndServe(); err != nil { glog.Errorf("Unable to listen for insecure (%v); will try again.", err) } else { notifyStarted.Do(func() { close(insecureStartedCh) }) } time.Sleep(15 * time.Second) } }() <-secureStartedCh <-insecureStartedCh s.RunPostStartHooks(PostStartHookContext{}) // err == systemd.SdNotifyNoSocket when not running on a systemd system if err := systemd.SdNotify("READY=1\n"); err != nil && err != systemd.SdNotifyNoSocket { glog.Errorf("Unable to send systemd daemon successful start message: %v\n", err) } select {} }
func (s *GenericAPIServer) Run() { // install APIs which depend on other APIs to be installed if s.enableSwaggerSupport { s.InstallSwaggerAPI() } if s.enableOpenAPISupport { s.InstallOpenAPI() } if s.SecureServingInfo != nil { secureServer := &http.Server{ Addr: s.SecureServingInfo.BindAddress, Handler: s.Handler, MaxHeaderBytes: 1 << 20, TLSConfig: &tls.Config{ // Can't use SSLv3 because of POODLE and BEAST // Can't use TLSv1.0 because of POODLE and BEAST using CBC cipher // Can't use TLSv1.1 because of RC4 cipher usage MinVersion: tls.VersionTLS12, }, } if len(s.SecureServingInfo.ClientCA) > 0 { clientCAs, err := certutil.NewPool(s.SecureServingInfo.ClientCA) if err != nil { glog.Fatalf("Unable to load client CA file: %v", err) } // Populate PeerCertificates in requests, but don't reject connections without certificates // This allows certificates to be validated by authenticators, while still allowing other auth types secureServer.TLSConfig.ClientAuth = tls.RequestClientCert // Specify allowed CAs for client certificates secureServer.TLSConfig.ClientCAs = clientCAs // "h2" NextProtos is necessary for enabling HTTP2 for go's 1.7 HTTP Server secureServer.TLSConfig.NextProtos = []string{"h2"} } // It would be nice to set a fqdn subject alt name, but only the kubelets know, the apiserver is clueless // alternateDNS = append(alternateDNS, "kubernetes.default.svc.CLUSTER.DNS.NAME") if s.SecureServingInfo.ServerCert.Generate && !certutil.CanReadCertOrKey(s.SecureServingInfo.ServerCert.CertFile, s.SecureServingInfo.ServerCert.KeyFile) { // TODO (cjcullen): Is ClusterIP the right address to sign a cert with? alternateIPs := []net.IP{s.ServiceReadWriteIP} alternateDNS := []string{"kubernetes.default.svc", "kubernetes.default", "kubernetes", "localhost"} if err := certutil.GenerateSelfSignedCert(s.ClusterIP.String(), s.SecureServingInfo.ServerCert.CertFile, s.SecureServingInfo.ServerCert.KeyFile, alternateIPs, alternateDNS); err != nil { glog.Errorf("Unable to generate self signed cert: %v", err) } else { glog.Infof("Using self-signed cert (%s, %s)", s.SecureServingInfo.ServerCert.CertFile, s.SecureServingInfo.ServerCert.KeyFile) } } glog.Infof("Serving securely on %s", s.SecureServingInfo.BindAddress) go func() { defer utilruntime.HandleCrash() for { if err := secureServer.ListenAndServeTLS(s.SecureServingInfo.ServerCert.CertFile, s.SecureServingInfo.ServerCert.KeyFile); err != nil { glog.Errorf("Unable to listen for secure (%v); will try again.", err) } time.Sleep(15 * time.Second) } }() } if s.InsecureServingInfo != nil { insecureServer := &http.Server{ Addr: s.InsecureServingInfo.BindAddress, Handler: s.InsecureHandler, MaxHeaderBytes: 1 << 20, } glog.Infof("Serving insecurely on %s", s.InsecureServingInfo.BindAddress) go func() { defer utilruntime.HandleCrash() for { if err := insecureServer.ListenAndServe(); err != nil { glog.Errorf("Unable to listen for insecure (%v); will try again.", err) } time.Sleep(15 * time.Second) } }() } // Attempt to verify the server came up for 20 seconds (100 tries * 100ms, 100ms timeout per try) per port if s.SecureServingInfo != nil { if err := waitForSuccessfulDial(true, "tcp", s.SecureServingInfo.BindAddress, 100*time.Millisecond, 100*time.Millisecond, 100); err != nil { glog.Fatalf("Secure server never started: %v", err) } } if s.InsecureServingInfo != nil { if err := waitForSuccessfulDial(false, "tcp", s.InsecureServingInfo.BindAddress, 100*time.Millisecond, 100*time.Millisecond, 100); err != nil { glog.Fatalf("Insecure server never started: %v", err) } } s.RunPostStartHooks() // err == systemd.SdNotifyNoSocket when not running on a systemd system if err := systemd.SdNotify("READY=1\n"); err != nil && err != systemd.SdNotifyNoSocket { glog.Errorf("Unable to send systemd daemon successful start message: %v\n", err) } select {} }
func (s *GenericAPIServer) Run() { // install APIs which depend on other APIs to be installed if s.enableSwaggerSupport { s.InstallSwaggerAPI() } if s.enableOpenAPISupport { s.InstallOpenAPI() } if s.SecureServingInfo != nil && s.Handler != nil { secureServer := &http.Server{ Addr: s.SecureServingInfo.BindAddress, Handler: s.Handler, MaxHeaderBytes: 1 << 20, TLSConfig: &tls.Config{ // Can't use SSLv3 because of POODLE and BEAST // Can't use TLSv1.0 because of POODLE and BEAST using CBC cipher // Can't use TLSv1.1 because of RC4 cipher usage MinVersion: tls.VersionTLS12, }, } if len(s.SecureServingInfo.ClientCA) > 0 { clientCAs, err := certutil.NewPool(s.SecureServingInfo.ClientCA) if err != nil { glog.Fatalf("Unable to load client CA file: %v", err) } // Populate PeerCertificates in requests, but don't reject connections without certificates // This allows certificates to be validated by authenticators, while still allowing other auth types secureServer.TLSConfig.ClientAuth = tls.RequestClientCert // Specify allowed CAs for client certificates secureServer.TLSConfig.ClientCAs = clientCAs // "h2" NextProtos is necessary for enabling HTTP2 for go's 1.7 HTTP Server secureServer.TLSConfig.NextProtos = []string{"h2"} } glog.Infof("Serving securely on %s", s.SecureServingInfo.BindAddress) go func() { defer utilruntime.HandleCrash() for { if err := secureServer.ListenAndServeTLS(s.SecureServingInfo.ServerCert.CertFile, s.SecureServingInfo.ServerCert.KeyFile); err != nil { glog.Errorf("Unable to listen for secure (%v); will try again.", err) } time.Sleep(15 * time.Second) } }() } if s.InsecureServingInfo != nil && s.InsecureHandler != nil { insecureServer := &http.Server{ Addr: s.InsecureServingInfo.BindAddress, Handler: s.InsecureHandler, MaxHeaderBytes: 1 << 20, } glog.Infof("Serving insecurely on %s", s.InsecureServingInfo.BindAddress) go func() { defer utilruntime.HandleCrash() for { if err := insecureServer.ListenAndServe(); err != nil { glog.Errorf("Unable to listen for insecure (%v); will try again.", err) } time.Sleep(15 * time.Second) } }() } // Attempt to verify the server came up for 20 seconds (100 tries * 100ms, 100ms timeout per try) per port if s.SecureServingInfo != nil { if err := waitForSuccessfulDial(true, "tcp", s.SecureServingInfo.BindAddress, 100*time.Millisecond, 100*time.Millisecond, 100); err != nil { glog.Fatalf("Secure server never started: %v", err) } } if s.InsecureServingInfo != nil { if err := waitForSuccessfulDial(false, "tcp", s.InsecureServingInfo.BindAddress, 100*time.Millisecond, 100*time.Millisecond, 100); err != nil { glog.Fatalf("Insecure server never started: %v", err) } } s.RunPostStartHooks() // err == systemd.SdNotifyNoSocket when not running on a systemd system if err := systemd.SdNotify("READY=1\n"); err != nil && err != systemd.SdNotifyNoSocket { glog.Errorf("Unable to send systemd daemon successful start message: %v\n", err) } select {} }
func (c DelegatingAuthenticatorConfig) New() (authenticator.Request, *spec.SecurityDefinitions, error) { authenticators := []authenticator.Request{} securityDefinitions := spec.SecurityDefinitions{} // front-proxy first, then remote // Add the front proxy authenticator if requested if c.RequestHeaderConfig != nil { requestHeaderAuthenticator, err := headerrequest.NewSecure( c.RequestHeaderConfig.ClientCA, c.RequestHeaderConfig.AllowedClientNames, c.RequestHeaderConfig.UsernameHeaders, c.RequestHeaderConfig.GroupHeaders, c.RequestHeaderConfig.ExtraHeaderPrefixes, ) if err != nil { return nil, nil, err } authenticators = append(authenticators, requestHeaderAuthenticator) } // x509 client cert auth if len(c.ClientCAFile) > 0 { clientCAs, err := cert.NewPool(c.ClientCAFile) if err != nil { return nil, nil, fmt.Errorf("unable to load client CA file %s: %v", c.ClientCAFile, err) } verifyOpts := x509.DefaultVerifyOptions() verifyOpts.Roots = clientCAs authenticators = append(authenticators, x509.New(verifyOpts, x509.CommonNameUserConversion)) } if c.TokenAccessReviewClient != nil { tokenAuth, err := webhooktoken.NewFromInterface(c.TokenAccessReviewClient, c.CacheTTL) if err != nil { return nil, nil, err } authenticators = append(authenticators, bearertoken.New(tokenAuth)) securityDefinitions["BearerToken"] = &spec.SecurityScheme{ SecuritySchemeProps: spec.SecuritySchemeProps{ Type: "apiKey", Name: "authorization", In: "header", Description: "Bearer Token authentication", }, } } if len(authenticators) == 0 { if c.Anonymous { return anonymous.NewAuthenticator(), &securityDefinitions, nil } return nil, nil, errors.New("No authentication method configured") } authenticator := group.NewGroupAdder(unionauth.New(authenticators...), []string{user.AllAuthenticated}) if c.Anonymous { authenticator = unionauth.NewFailOnError(authenticator, anonymous.NewAuthenticator()) } return authenticator, &securityDefinitions, nil }