Add support for enhanced security#692
Conversation
b873181 to
b0c9bcd
Compare
nixpanic
left a comment
There was a problem hiding this comment.
left a few minor comments for improving, looks pretty good to me already. Thanks!
|
@nixpanic should we disable it by default for easy opt-in for users? |
If it works on current Kubernetes installations by default, it can be enabled by default IMHO. You may want to add a note in https://github.com/csi-addons/kubernetes-csi-addons/blob/main/docs/deploy-controller.md on the requirements of Kubernetes services, and how to disable it in case those services are unavailable. |
|
@Madhu-1 my PR fails until I revert code introduced at https://github.com/csi-addons/kubernetes-csi-addons/pull/695/files#diff-03e0410a78ce106bc8ee10f594661c87995994955bfb6b07972d8fde2ec8a555R125-R146 |
@bipuladh please use latest yamls from master branch in Rook |
Madhu-1
left a comment
There was a problem hiding this comment.
Please add a documentation about this feature and as its enabled by default i assume upgraded works as it is (in kubernetes)
| } | ||
| tlsConfig := &tls.Config{ | ||
| RootCAs: caCertPool, // The CA certificates to verify the server | ||
| InsecureSkipVerify: true, |
There was a problem hiding this comment.
dont we need to set it to true?
There was a problem hiding this comment.
By default setting it to false but making it configurable by users from args
There was a problem hiding this comment.
After having discussions we need the ability to configure this to support certificates. We currently resolve the IP address and use that instead of host name. This causes certificate mismatch.
| return status.Errorf(codes.Unauthenticated, "missing metadata") | ||
| } | ||
|
|
||
| authHeader, ok := md["authorization"] | ||
| if !ok || len(authHeader) == 0 { | ||
| return status.Errorf(codes.Unauthenticated, "missing authorization token") | ||
| } | ||
|
|
||
| token := authHeader[0] | ||
| isValidated, err := validateBearerToken(ctx, token, kubeclient) | ||
| if !isValidated || (err != nil) { | ||
| return status.Errorf(codes.Unauthenticated, "invalid token") |
There was a problem hiding this comment.
i think you can use status.Error instead of status.Errorf
There was a problem hiding this comment.
return the err message as well for better debugging
| file, err := os.Open(tokenPath) | ||
| if err != nil { | ||
| return "", err | ||
| } | ||
| defer file.Close() | ||
|
|
||
| data, err := io.ReadAll(file) | ||
| if err != nil { | ||
| return "", err | ||
| } | ||
| return string(data), nil |
There was a problem hiding this comment.
make use of readfile function which is doing the same thing?
There was a problem hiding this comment.
ioutil readFile is deprecated.
There was a problem hiding this comment.
i meant readFile we have below in this file
| ss.server = grpc.NewServer(grpc.UnaryInterceptor(token.AuthorizationInterceptor(ss.client)), grpc.Creds(creds)) | ||
| } | ||
| if !ss.enableTLS { | ||
| ss.server = grpc.NewServer(grpc.UnaryInterceptor(token.AuthorizationInterceptor(ss.client))) |
There was a problem hiding this comment.
if tls is not enabled why we need to have add UnaryInterceptor here?
There was a problem hiding this comment.
I think this is something we need to decide. Should we disable auth token verification if TLS is disabled?
There was a problem hiding this comment.
Removing Interceptor when TLS not used.
| } | ||
| tlsConfig := &tls.Config{ | ||
| RootCAs: caCertPool, // The CA certificates to verify the server | ||
| InsecureSkipVerify: true, |
There was a problem hiding this comment.
Shouldn't it be set to false?
There was a problem hiding this comment.
By default setting it to false but making it configurable by users from args
| return nil | ||
| } | ||
|
|
||
| func removeBearer(authHeader string) string { |
There was a problem hiding this comment.
| func removeBearer(authHeader string) string { | |
| func extractToken(authHeader string) string { |
since the function just extracts the token, this naming is more suitable?
@Madhu-1 @nixpanic for a smoother upgrade experience, should we disable by default? As mentioned in the PR description the sidecar deployer will have to create a certificate and mount it if not done the sidecar would go to CLBO. I can add this setup procedure on the readme files for reference. |
Yes, users should not need to do anything extra for upgrading. If there are manual steps to configure certificates, disable the feature by default. |
nixpanic
left a comment
There was a problem hiding this comment.
Looks good to me. Please squash all the commits together so that the Mergify automation can merge it when all approvals are in.
| isValidated, err := validateBearerToken(ctx, token, kubeclient) | ||
| if !isValidated || (err != nil) { | ||
| return status.Errorf(codes.Unauthenticated, "invalid token") | ||
| return status.Error(codes.Unauthenticated, fmt.Sprint("invalid token: %w", err)) |
There was a problem hiding this comment.
this is where status.Errorf() can be used so that fmt.Sprintf() is not needed.
There was a problem hiding this comment.
Can you please address this as well?
| flag.BoolVar(&showVersion, "version", false, "Print Version details") | ||
| flag.StringVar(&cfg.SchedulePrecedence, "schedule-precedence", "", "The order of precedence in which schedule of reclaimspace and keyrotation is considered. Possible values are sc-only") | ||
| flag.BoolVar(&enableTLS, "enable-tls", false, "Enable TLS(enabled by default)") | ||
| flag.BoolVar(&skipInsecureVerify, "insecure-skip-tls-verify", false, "skip the certificate check") |
There was a problem hiding this comment.
| flag.BoolVar(&skipInsecureVerify, "insecure-skip-tls-verify", false, "skip the certificate check") | |
| flag.BoolVar(&skipInsecureVerify, "insecure-skip-tls-verify", false, "skip server certificate verification") |
Madhu-1
left a comment
There was a problem hiding this comment.
Please add/update the documentation on how to enable this functionality
| flag.BoolVar(&enableAdmissionWebhooks, "enable-admission-webhooks", false, "[DEPRECATED] Enable the admission webhooks") | ||
| flag.BoolVar(&showVersion, "version", false, "Print Version details") | ||
| flag.StringVar(&cfg.SchedulePrecedence, "schedule-precedence", "", "The order of precedence in which schedule of reclaimspace and keyrotation is considered. Possible values are sc-only") | ||
| flag.BoolVar(&enableTLS, "enable-tls", false, "Enable TLS(enabled by default)") |
There was a problem hiding this comment.
need to update the comment as its disabled by default
| grpc.WithIdleTimeout(time.Duration(0)), | ||
| } | ||
|
|
||
| opts = append(opts, token.WithServiceAccountToken()) |
There was a problem hiding this comment.
Do we need to move this inside the if check when TLS is enabled?
|
|
||
| caFile, caError := token.GetCACert() | ||
| if caError != nil { | ||
| return nil, (fmt.Errorf("failed to get server cert %w", caError)) |
There was a problem hiding this comment.
| return nil, (fmt.Errorf("failed to get server cert %w", caError)) | |
| return nil, fmt.Errorf("failed to get server cert %w", caError) |
| file, err := os.Open(tokenPath) | ||
| if err != nil { | ||
| return "", err | ||
| } | ||
| defer file.Close() | ||
|
|
||
| data, err := io.ReadAll(file) | ||
| if err != nil { | ||
| return "", err | ||
| } | ||
| return string(data), nil |
There was a problem hiding this comment.
i meant readFile we have below in this file
| func parseToken(authHeader string) string { | ||
| if strings.HasPrefix(authHeader, bearerPrefix) { | ||
| return strings.TrimPrefix(authHeader, bearerPrefix) | ||
| } | ||
| return authHeader | ||
| } |
There was a problem hiding this comment.
If the goal is to just to parse, we can remove the if check and trim it
func parseToken(authHeader string) string {
return strings.TrimPrefix(authHeader, bearerPrefix)
}| result, err := kubeclient.AuthenticationV1().TokenReviews().Create(ctx, tokenReview, metav1.CreateOptions{}) | ||
| if err != nil { | ||
| return false, fmt.Errorf("failed to review token %w", err) | ||
| } |
There was a problem hiding this comment.
Dont we need RBAC for this one? am not sure we have this RBAC already
There was a problem hiding this comment.
Yes we require. Whoever deploys the sidecar should be responsible to have this.
| // create the gRPC server and register services | ||
| ss.server = grpc.NewServer() | ||
| if ss.enableTLS { | ||
| creds, err := credentials.NewServerTLSFromFile("/etc/tls/tls.crt", "/etc/tls/tls.key") |
There was a problem hiding this comment.
"/etc/tls/tls.crt", "/etc/tls/tls.key" Are we going to have these two files in all the pods in same location when TLS is enabled?
There was a problem hiding this comment.
Ideally yes. But I guess we can make it configurable later on if that is preferred.
There was a problem hiding this comment.
adding these as parameters
| if ss.enableTLS { | ||
| creds, err := credentials.NewServerTLSFromFile("/etc/tls/tls.crt", "/etc/tls/tls.key") | ||
| if err != nil { | ||
| klog.Fatalf("Could not find TLS file: %v", err) |
There was a problem hiding this comment.
| klog.Fatalf("Could not find TLS file: %v", err) | |
| klog.Fatalf("failed to load TLS certificate and key: %v", err) |
Pull request has been modified.
Pull request has been modified.
Rakshith-R
left a comment
There was a problem hiding this comment.
one small nit,
rest looks good to me.
Signed-off-by: Bipul Adhikari <badhikar@redhat.com>
|
@Mergifyio queue |
✅ The pull request has been merged automaticallyDetailsThe pull request has been merged automatically at ae2ede2 |
|
@Mergifyio refresh |
✅ Pull request refreshed |
Changes
enable-auth(disabled by default. If enabled it will start checking for auth headers in Request objects and enables TLS for grpc connections.Requirements for the above features to work correctly:
.
Images for testing:
Test logs
2024-11-11T18:12:00.948Z INFO Successfully connected to sidecar {"controller": "csiaddonsnode", "controllerGroup": "csiaddons.openshift.io", "controllerKind": "CSIAddonsNode", "CSIAddonsNode": {"name":"csi-rbdplugin-gbr85","namespace":"openshift-storage"}, "namespace": "openshift-storage", "name": "csi-rbdplugin-gbr85", "reconcileID": "964eea1e-324b-4957-984d-2611972645ed", "NodeID": "ip-10-0-50-177.us-east-2.compute.internal", "DriverName": "openshift-storage.rbd.csi.ceph.com", "EndPoint": "10.0.50.177:9070"}