Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
JWT token generation/verification
  • Loading branch information
liggitt committed May 11, 2015
commit db1f0dc90686f1eeae1a5f14bdecd029d94773a7
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
{% if grains.cloud is defined -%}
{% set cloud_provider = "--cloud_provider=" + grains.cloud -%}

{% set service_account_key = " --service_account_private_key_file=/srv/kubernetes/server.key " -%}

{% if grains.cloud == 'gce' -%}
{% if grains.cloud_config is defined -%}
{% set cloud_config = "--cloud_config=" + grains.cloud_config -%}
Expand Down Expand Up @@ -55,7 +57,7 @@
{% endif -%}
{% endif -%}

{% set params = "--master=127.0.0.1:8080" + " " + machines + " " + cluster_name + " " + cluster_cidr + " " + allocate_node_cidrs + " " + minion_regexp + " " + cloud_provider + " " + sync_nodes + " " + cloud_config + " " + pillar['log_level'] -%}
{% set params = "--master=127.0.0.1:8080" + " " + machines + " " + cluster_name + " " + cluster_cidr + " " + allocate_node_cidrs + " " + minion_regexp + " " + cloud_provider + " " + sync_nodes + " " + cloud_config + service_account_key + pillar['log_level'] -%}

{
"apiVersion": "v1beta3",
Expand Down
10 changes: 9 additions & 1 deletion cmd/kube-apiserver/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ type APIServer struct {
BasicAuthFile string
ClientCAFile string
TokenAuthFile string
ServiceAccountKeyFile string
ServiceAccountLookup bool
AuthorizationMode string
AuthorizationPolicyFile string
AdmissionControl string
Expand Down Expand Up @@ -162,6 +164,8 @@ func (s *APIServer) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.BasicAuthFile, "basic-auth-file", s.BasicAuthFile, "If set, the file that will be used to admit requests to the secure port of the API server via http basic authentication.")
fs.StringVar(&s.ClientCAFile, "client-ca-file", s.ClientCAFile, "If set, any request presenting a client certificate signed by one of the authorities in the client-ca-file is authenticated with an identity corresponding to the CommonName of the client certificate.")
fs.StringVar(&s.TokenAuthFile, "token-auth-file", s.TokenAuthFile, "If set, the file that will be used to secure the secure port of the API server via token authentication.")
fs.StringVar(&s.ServiceAccountKeyFile, "service-account-key-file", s.ServiceAccountKeyFile, "File containing PEM-encoded x509 RSA private or public key, used to verify ServiceAccount tokens. If unspecified, --tls-private-key-file is used.")
fs.BoolVar(&s.ServiceAccountLookup, "service-account-lookup", s.ServiceAccountLookup, "If true, validate ServiceAccount tokens exist in etcd as part of authentication.")
fs.StringVar(&s.AuthorizationMode, "authorization-mode", s.AuthorizationMode, "Selects how to do authorization on the secure port. One of: "+strings.Join(apiserver.AuthorizationModeChoices, ","))
fs.StringVar(&s.AuthorizationPolicyFile, "authorization-policy-file", s.AuthorizationPolicyFile, "File with authorization policy in csv format, used with --authorization-mode=ABAC, on the secure port.")
fs.StringVar(&s.AdmissionControl, "admission-control", s.AdmissionControl, "Ordered list of plug-ins to do admission control of resources into cluster. Comma-delimited list of: "+strings.Join(admission.GetPlugins(), ", "))
Expand Down Expand Up @@ -267,7 +271,11 @@ func (s *APIServer) Run(_ []string) error {

n := net.IPNet(s.PortalNet)

authenticator, err := apiserver.NewAuthenticator(s.BasicAuthFile, s.ClientCAFile, s.TokenAuthFile)
// Default to the private server key for service account token signing
if s.ServiceAccountKeyFile == "" && s.TLSPrivateKeyFile != "" {
s.ServiceAccountKeyFile = s.TLSPrivateKeyFile
}
authenticator, err := apiserver.NewAuthenticator(s.BasicAuthFile, s.ClientCAFile, s.TokenAuthFile, s.ServiceAccountKeyFile, s.ServiceAccountLookup, client)
if err != nil {
glog.Fatalf("Invalid Authentication Config: %v", err)
}
Expand Down
27 changes: 20 additions & 7 deletions cmd/kube-controller-manager/app/controllermanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ limitations under the License.
package app

import (
"fmt"
"net"
"net/http"
"net/http/pprof"
Expand Down Expand Up @@ -75,6 +74,7 @@ type CMServer struct {
PodEvictionTimeout time.Duration
DeletingPodsQps float32
DeletingPodsBurst int
ServiceAccountKeyFile string

// TODO: Discover these by pinging the host machines, and rip out these params.
NodeMilliCPU int64
Expand Down Expand Up @@ -143,6 +143,7 @@ func (s *CMServer) AddFlags(fs *pflag.FlagSet) {
"Amount of time which we allow starting Node to be unresponsive before marking it unhealty.")
fs.DurationVar(&s.NodeMonitorPeriod, "node-monitor-period", 5*time.Second,
"The period for syncing NodeStatus in NodeController.")
fs.StringVar(&s.ServiceAccountKeyFile, "service-account-private-key-file", s.ServiceAccountKeyFile, "Filename containing a PEM-encoded private RSA key used to sign service account tokens.")
// TODO: Discover these by pinging the host machines, and rip out these flags.
// TODO: in the meantime, use resource.QuantityFlag() instead of these
fs.Int64Var(&s.NodeMilliCPU, "node-milli-cpu", s.NodeMilliCPU, "The amount of MilliCPU provisioned on each node")
Expand Down Expand Up @@ -251,12 +252,24 @@ func (s *CMServer) Run(_ []string) error {
pvclaimBinder.Run()
}

// TODO: generate signed token
tokenGenerator := serviceaccount.TokenGeneratorFunc(func(serviceAccount api.ServiceAccount, secret api.Secret) (string, error) {
return fmt.Sprintf("serviceaccount:%s:%s:%s:%s", serviceAccount.Namespace, serviceAccount.Name, serviceAccount.UID, secret.Name), nil
})
serviceaccount.NewTokensController(kubeClient, serviceaccount.DefaultTokenControllerOptions(tokenGenerator)).Run()
serviceaccount.NewServiceAccountsController(kubeClient, serviceaccount.DefaultServiceAccountControllerOptions()).Run()
if len(s.ServiceAccountKeyFile) > 0 {
privateKey, err := serviceaccount.ReadPrivateKey(s.ServiceAccountKeyFile)
if err != nil {
glog.Errorf("Error reading key for service account token controller: %v", err)
} else {
serviceaccount.NewTokensController(
kubeClient,
serviceaccount.DefaultTokenControllerOptions(
serviceaccount.JWTTokenGenerator(privateKey),
),
).Run()
}
}

serviceaccount.NewServiceAccountsController(
kubeClient,
serviceaccount.DefaultServiceAccountControllerOptions(),
).Run()

select {}
return nil
Expand Down
10 changes: 10 additions & 0 deletions hack/local-up-cluster.sh
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,21 @@ trap cleanup EXIT
echo "Starting etcd"
kube::etcd::start

SERVICE_ACCOUNT_LOOKUP=${SERVICE_ACCOUNT_LOOKUP:-false}
SERVICE_ACCOUNT_KEY=${SERVICE_ACCOUNT_KEY:-"/var/run/kubernetes/serviceaccount.key"}
# Generate ServiceAccount key if needed
if [[ ! -f "${SERVICE_ACCOUNT_KEY}" ]]; then
openssl genrsa -out "${SERVICE_ACCOUNT_KEY}" 2048 2>/dev/null
fi

# Admission Controllers to invoke prior to persisting objects in cluster
ADMISSION_CONTROL=NamespaceLifecycle,NamespaceAutoProvision,LimitRanger,SecurityContextDeny,ResourceQuota

APISERVER_LOG=/tmp/kube-apiserver.log
sudo -E "${GO_OUT}/kube-apiserver" \
--v=${LOG_LEVEL} \
--service_account_key_file="${SERVICE_ACCOUNT_KEY}" \
--service_account_lookup="${SERVICE_ACCOUNT_LOOKUP}" \
--admission_control="${ADMISSION_CONTROL}" \
--address="${API_HOST}" \
--port="${API_PORT}" \
Expand All @@ -155,6 +164,7 @@ CTLRMGR_LOG=/tmp/kube-controller-manager.log
sudo -E "${GO_OUT}/kube-controller-manager" \
--v=${LOG_LEVEL} \
--machines="127.0.0.1" \
--service_account_private_key_file="${SERVICE_ACCOUNT_KEY}" \
--master="${API_HOST}:${API_PORT}" >"${CTLRMGR_LOG}" 2>&1 &
CTLRMGR_PID=$!

Expand Down
24 changes: 23 additions & 1 deletion pkg/apiserver/authn.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ limitations under the License.
package apiserver

import (
"crypto/rsa"

"github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authenticator"
"github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authenticator/bearertoken"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/serviceaccount"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/auth/authenticator/password/passwordfile"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/auth/authenticator/request/basicauth"
Expand All @@ -28,7 +32,7 @@ import (
)

// NewAuthenticator returns an authenticator.Request or an error
func NewAuthenticator(basicAuthFile, clientCAFile, tokenFile string) (authenticator.Request, error) {
func NewAuthenticator(basicAuthFile, clientCAFile, tokenFile, serviceAccountKeyFile string, serviceAccountLookup bool, client client.Interface) (authenticator.Request, error) {
var authenticators []authenticator.Request

if len(basicAuthFile) > 0 {
Expand All @@ -55,6 +59,14 @@ func NewAuthenticator(basicAuthFile, clientCAFile, tokenFile string) (authentica
authenticators = append(authenticators, tokenAuth)
}

if len(serviceAccountKeyFile) > 0 {
serviceAccountAuth, err := newServiceAccountAuthenticator(serviceAccountKeyFile, serviceAccountLookup, client)
if err != nil {
return nil, err
}
authenticators = append(authenticators, serviceAccountAuth)
}

switch len(authenticators) {
case 0:
return nil, nil
Expand Down Expand Up @@ -85,6 +97,16 @@ func newAuthenticatorFromTokenFile(tokenAuthFile string) (authenticator.Request,
return bearertoken.New(tokenAuthenticator), nil
}

// newServiceAccountAuthenticator returns an authenticator.Request or an error
func newServiceAccountAuthenticator(keyfile string, lookup bool, client client.Interface) (authenticator.Request, error) {
publicKey, err := serviceaccount.ReadPublicKey(keyfile)
if err != nil {
return nil, err
}
tokenAuthenticator := serviceaccount.JWTTokenAuthenticator([]*rsa.PublicKey{publicKey}, lookup, client)
return bearertoken.New(tokenAuthenticator), nil
}

// newAuthenticatorFromClientCAFile returns an authenticator.Request or an error
func newAuthenticatorFromClientCAFile(clientCAFile string) (authenticator.Request, error) {
roots, err := util.CertPoolFromFile(clientCAFile)
Expand Down
Loading