1
0
Fork 0
mirror of https://github.com/kubernetes-sigs/node-feature-discovery.git synced 2024-12-14 11:57:51 +00:00

nfd-master: implement --verify-node-name

Make NodeName based authorization of the workers optional (off by
default). This makes it possible for all nfd-worker pods in the cluster
to use one shared secret, making NFD deployment much easier. However,
this also opens a way for nfd-workers to label other nodes (than what it
is running on), too.
This commit is contained in:
Markus Lehtonen 2019-01-31 15:54:06 +02:00
parent 40061e6a78
commit 4c1e892d88

View file

@ -73,6 +73,7 @@ type Args struct {
labelWhiteList *regexp.Regexp labelWhiteList *regexp.Regexp
noPublish bool noPublish bool
port int port int
verifyNodeName bool
} }
func main() { func main() {
@ -145,6 +146,7 @@ func argsParse(argv []string) (Args, error) {
Usage: Usage:
%s [--no-publish] [--label-whitelist=<pattern>] [--port=<port>] %s [--no-publish] [--label-whitelist=<pattern>] [--port=<port>]
[--ca-file=<path>] [--cert-file=<path>] [--key-file=<path>] [--ca-file=<path>] [--cert-file=<path>] [--key-file=<path>]
[--verify-node-name]
%s -h | --help %s -h | --help
%s --version %s --version
@ -159,6 +161,9 @@ func argsParse(argv []string) (Args, error) {
[Default: ] [Default: ]
--key-file=<path> Private key matching --cert-file --key-file=<path> Private key matching --cert-file
[Default: ] [Default: ]
--verify-node-name Verify worker node name against CN from the TLS
certificate. Only has effect when TLS authentication
has been enabled.
--no-publish Do not publish feature labels --no-publish Do not publish feature labels
--label-whitelist=<pattern> Regular expression to filter label names to --label-whitelist=<pattern> Regular expression to filter label names to
publish to the Kubernetes API server. [Default: ]`, publish to the Kubernetes API server. [Default: ]`,
@ -185,6 +190,7 @@ func argsParse(argv []string) (Args, error) {
if err != nil { if err != nil {
return args, fmt.Errorf("error parsing whitelist regex (%s): %s", arguments["--label-whitelist"], err) return args, fmt.Errorf("error parsing whitelist regex (%s): %s", arguments["--label-whitelist"], err)
} }
args.verifyNodeName = arguments["--verify-node-name"].(bool)
// Check TLS related args // Check TLS related args
if args.certFile != "" || args.keyFile != "" || args.caFile != "" { if args.certFile != "" || args.keyFile != "" || args.caFile != "" {
@ -242,28 +248,29 @@ type labelerServer struct {
// Service SetLabels // Service SetLabels
func (s *labelerServer) SetLabels(c context.Context, r *pb.SetLabelsRequest) (*pb.SetLabelsReply, error) { func (s *labelerServer) SetLabels(c context.Context, r *pb.SetLabelsRequest) (*pb.SetLabelsReply, error) {
// Client authorization. if s.args.verifyNodeName {
// Check that the node name matches the CN from the TLS cert // Client authorization.
client, ok := peer.FromContext(c) // Check that the node name matches the CN from the TLS cert
if !ok { client, ok := peer.FromContext(c)
stderrLogger.Printf("gRPC request error: failed to get peer (client)") if !ok {
return &pb.SetLabelsReply{}, fmt.Errorf("failed to get peer (client)") stderrLogger.Printf("gRPC request error: failed to get peer (client)")
return &pb.SetLabelsReply{}, fmt.Errorf("failed to get peer (client)")
}
tlsAuth, ok := client.AuthInfo.(credentials.TLSInfo)
if !ok {
stderrLogger.Printf("gRPC request error: incorrect client credentials from '%v'", client.Addr)
return &pb.SetLabelsReply{}, fmt.Errorf("incorrect client credentials")
}
if len(tlsAuth.State.VerifiedChains) == 0 || len(tlsAuth.State.VerifiedChains[0]) == 0 {
stderrLogger.Printf("gRPC request error: client certificate verification for '%v' failed", client.Addr)
return &pb.SetLabelsReply{}, fmt.Errorf("client certificate verification failed")
}
cn := tlsAuth.State.VerifiedChains[0][0].Subject.CommonName
if cn != r.NodeName {
stderrLogger.Printf("gRPC request error: authorization for %v failed: cert valid for '%s', requested node name '%s'", client.Addr, cn, r.NodeName)
return &pb.SetLabelsReply{}, fmt.Errorf("request authorization failed: cert valid for '%s', requested node name '%s'", cn, r.NodeName)
}
} }
tlsAuth, ok := client.AuthInfo.(credentials.TLSInfo)
if !ok {
stderrLogger.Printf("gRPC request error: incorrect client credentials from '%v'", client.Addr)
return &pb.SetLabelsReply{}, fmt.Errorf("incorrect client credentials")
}
if len(tlsAuth.State.VerifiedChains) == 0 || len(tlsAuth.State.VerifiedChains[0]) == 0 {
stderrLogger.Printf("gRPC request error: client certificate verification for '%v' failed", client.Addr)
return &pb.SetLabelsReply{}, fmt.Errorf("client certificate verification failed")
}
cn := tlsAuth.State.VerifiedChains[0][0].Subject.CommonName
if cn != r.NodeName {
stderrLogger.Printf("gRPC request error: authorization for %v failed: cert valid for '%s', requested node name '%s'", client.Addr, cn, r.NodeName)
return &pb.SetLabelsReply{}, fmt.Errorf("request authorization failed: cert valid for '%s', requested node name '%s'", cn, r.NodeName)
}
stdoutLogger.Printf("REQUEST Node: %s NFD-version: %s Labels: %s", r.NodeName, r.NfdVersion, r.Labels) stdoutLogger.Printf("REQUEST Node: %s NFD-version: %s Labels: %s", r.NodeName, r.NfdVersion, r.Labels)
if !s.args.noPublish { if !s.args.noPublish {