Skip to content

fix: fix cluster compliance query for security account and banner checks - #4366

Merged
rahulguptajss merged 2 commits into
mainfrom
rg2-fix-security
Jul 30, 2026
Merged

fix: fix cluster compliance query for security account and banner checks#4366
rahulguptajss merged 2 commits into
mainfrom
rg2-fix-security

Conversation

@rahulguptajss

@rahulguptajss rahulguptajss commented Jul 29, 2026

Copy link
Copy Markdown
Contributor
  1. Locked account check – bug. It currently flags a cluster as non-compliant if any local account is unlocked, but it should only check the built-in admin account (per the "Default Admin User" rule). Regular users being unlocked is normal. security_account_labels metrics

  2. security_login_labels – used in 2 places in this check:
    Login banner check (banner="") – correct, no issue.
    A second, unconditioned clause that just checks if the metric exists (no banner filter) – this matches almost always since ONTAP always returns a login-message record, so it incorrectly contributes to non-compliance regardless of actual banner status. This is the bug.

Copilot AI review requested due to automatic review settings July 29, 2026 07:31
@cla-bot cla-bot Bot added the cla-signed label Jul 29, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the ONTAP Security Grafana dashboard’s “cluster compliance” PromQL so the security-account unlocked check and login-banner-related checks behave correctly across cluster/SVM selections.

Changes:

  • Refines the unlocked-account compliance check to target the built-in admin account (role_name="admin", user_name="admin").
  • Reworks the login/banner portion of the compliance queries using an unless clause to better detect missing login-message series for selected SVMs.
  • Applies the updated compliance query logic consistently across the dashboard’s stat/pie/table panels.
Comments suppressed due to low confidence (2)

grafana/dashboards/cmode/security.json:883

  • Same issue as panel 214: the unless join is on (svm) but Cluster/Datacenter variables are multi-select, so SVM-name collisions across clusters can cause incorrect results. Use unless on (datacenter, cluster, svm) so matching is scoped to the selected cluster/datacenter.
          "expr": "count(\n    group by (datacenter, cluster) (\n                              support_labels{asup_enabled=\"true\",asup_https_configured!=\"https\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}\n                            or\n                              security_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",telnet_enabled=\"true\"}\n                          or\n                            security_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",rsh_enabled=\"true\"}\n                        or\n                            group by (datacenter, cluster) (\n                              security_account_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",hash_algorithm=\"md5\"}\n                            )\n                          \u003e\n                            0\n                      or\n                        cluster_peer_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",encryption_state=\"\"}\n                    or\n                      cluster_peer_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",encryption_state=\"none\"}\n                  or\n                      group by (datacenter, cluster) (\n                        security_account_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",locked=\"false\",role_name=\"admin\",user_name=\"admin\"}\n                      )\n                    \u003e\n                      0\n                or\n                  security_login_labels{banner=\"\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",scope=\"cluster\"}\n              or\n                count by (datacenter, cluster) (ntpserver_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}) \u003c 1\n            or\n              security_audit_destination_status{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",protocol!=\"tcp_encrypted\"}\n          or\n            security_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",fips_enabled=\"false\"}\n        or\n          svm_labels{ciphers=~\".*_cbc.*\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\",type=\"admin\"}\n      or\n        group by (datacenter, cluster) (\n                (\n                    (\n                        svm_labels{cifs_protocol_enabled=\"true\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\"}\n                      or\n                        svm_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",nfs_protocol_enabled=\"true\",svm=~\"$SVM\"}\n                    )\n                  and\n                    svm_labels{audit_protocol_enabled=\"false\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\"}\n                )\n              or\n                security_ssh_labels{ciphers=~\".*_cbc.*\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}\n            or\n              security_login_labels{banner=\"\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",scope=\"svm\"}\n          or\n            (\n                svm_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\"}\n              unless on (svm)\n                security_login_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm!=\"$Cluster\",svm=~\"$SVM\"}\n            )\n        )\n    )\n  )\nor\n  vector(0)",

grafana/dashboards/cmode/security.json:4260

  • The unless match is scoped only to svm, but this dashboard allows multi-select Cluster/Datacenter and the same SVM name can appear in multiple clusters. Using unless on (svm) can therefore suppress missing security_login_labels for one cluster because another cluster has the same SVM name. Match on (datacenter, cluster, svm) to avoid cross-cluster collisions.
              "expr": "group by (datacenter, cluster) (\n                          support_labels{asup_enabled=\"true\",asup_https_configured!=\"https\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}\n                        or\n                          security_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",telnet_enabled=\"true\"}\n                      or\n                        security_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",rsh_enabled=\"true\"}\n                    or\n                        group by (datacenter, cluster) (\n                          security_account_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",hash_algorithm=\"md5\"}\n                        )\n                      \u003e\n                        0\n                  or\n                    cluster_peer_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",encryption_state=\"\"}\n                or\n                  cluster_peer_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",encryption_state=\"none\"}\n              or\n                  group by (datacenter, cluster) (\n                    security_account_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",locked=\"false\",role_name=\"admin\",user_name=\"admin\"}\n                  )\n                \u003e\n                  0\n            or\n              security_login_labels{banner=\"\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",scope=\"cluster\"}\n          or\n            count by (datacenter, cluster) (ntpserver_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}) \u003c 1\n        or\n          security_audit_destination_status{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",protocol!=\"tcp_encrypted\"}\n      or\n        security_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",fips_enabled=\"false\"}\n    or\n      svm_labels{ciphers=~\".*_cbc.*\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\",type=\"admin\"}\n  or\n    group by (datacenter, cluster) (\n                        (\n                            (\n                                svm_labels{cifs_protocol_enabled=\"true\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\"}\n                              or\n                                svm_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",nfs_protocol_enabled=\"true\",svm=~\"$SVM\"}\n                            )\n                          and\n                            svm_labels{audit_protocol_enabled=\"false\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\"}\n                        )\n                      or\n                        security_ssh_labels{ciphers=~\".*_cbc.*\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}\n                    or\n                      security_login_labels{banner=\"\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",scope=\"svm\"}\n                  or\n                    (\n                        svm_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\"}\n                      unless on (svm)\n                        security_login_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm!=\"$Cluster\",svm=~\"$SVM\"}\n                    )\n                or\n                    sum by (datacenter, cluster) (\n                      volume_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",root_volume=\"No\",snapshot_policy=\"none\"}\n                    )\n                  \u003e\n                    0\n              or\n                  sum by (datacenter, cluster) (\n                    volume_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",root_volume=\"No\",snapshot_autodelete=\"true\"}\n                  )\n                \u003e\n                  0\n            or\n                sum by (datacenter, cluster) (\n                  svm_labels{anti_ransomware_state=~\"|.*disabled\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\"}\n                )\n              \u003e\n                0\n          or\n              volume_arw_status{ArwStatus!=\"Active Mode\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}\n            * on (instance) group_left ()\n              metadata_collector_instances{collector=\"Rest\",datacenter=~\"$Datacenter\",object=\"Volume\"}\n        or\n            count by (datacenter, cluster) (\n              ems_destination_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}\n            )\n          \u003e\n            0\n      or\n        support_auto_update_labels{auto_update_enabled=\"false\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}\n    )\n)",

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread grafana/dashboards/cmode/security.json Outdated
Copilot AI review requested due to automatic review settings July 29, 2026 07:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

cgrinds
cgrinds previously approved these changes Jul 29, 2026
Copilot AI review requested due to automatic review settings July 29, 2026 15:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

grafana/dashboards/cmode/security.json:883

  • Same issue as the earlier cluster compliance expression: the SVM login-banner check only matches security_login_labels with scope="svm". If the exporter sometimes omits the scope label (as accounted for elsewhere in this dashboard via svm!="$Cluster"), SVMs with an empty banner could be missed.

Recommend adding an or security_login_labels{banner="",...,svm!="$Cluster",svm=~"$SVM"} fallback alongside the scope="svm" clause.

          "expr": "count(\n    group by (datacenter, cluster) (\n                                support_labels{asup_enabled=\"true\",asup_https_configured!=\"https\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}\n                              or\n                                security_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",telnet_enabled=\"true\"}\n                            or\n                              security_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",rsh_enabled=\"true\"}\n                          or\n                              group by (datacenter, cluster) (\n                                security_account_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",hash_algorithm=\"md5\"}\n                              )\n                            \u003e\n                              0\n                        or\n                          cluster_peer_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",encryption_state=\"\"}\n                      or\n                        cluster_peer_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",encryption_state=\"none\"}\n                    or\n                        group by (datacenter, cluster) (\n                          security_account_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",locked=\"false\",role_name=\"admin\",user_name=\"admin\"}\n                        )\n                      \u003e\n                        0\n                  or\n                    security_login_labels{banner=\"\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",scope=\"cluster\"}\n                or\n                  security_login_labels{banner=\"\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$Cluster\"}\n              or\n                count by (datacenter, cluster) (ntpserver_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}) \u003c 1\n            or\n              security_audit_destination_status{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",protocol!=\"tcp_encrypted\"}\n          or\n            security_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",fips_enabled=\"false\"}\n        or\n          svm_labels{ciphers=~\".*_cbc.*\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\",type=\"admin\"}\n      or\n        group by (datacenter, cluster) (\n              (\n                  (\n                      svm_labels{cifs_protocol_enabled=\"true\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\"}\n                    or\n                      svm_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",nfs_protocol_enabled=\"true\",svm=~\"$SVM\"}\n                  )\n                and\n                  svm_labels{audit_protocol_enabled=\"false\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\"}\n              )\n            or\n              security_ssh_labels{ciphers=~\".*_cbc.*\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}\n          or\n            security_login_labels{banner=\"\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",scope=\"svm\",svm=~\"$SVM\"}\n        )\n    )\n  )\nor\n  vector(0)",

grafana/dashboards/cmode/security.json:4260

  • This table/query variant of the cluster compliance logic also only checks SVM login-banner emptiness via security_login_labels{...,scope="svm",svm=~"$SVM"}. If SVM login-message series can exist without a scope label (as handled elsewhere with svm!="$Cluster"), empty-banner SVMs could be missed here.

Suggest adding a fallback or security_login_labels{banner="",...,svm!="$Cluster",svm=~"$SVM"} near the existing scope="svm" clause.

              "expr": "group by (datacenter, cluster) (\n                            support_labels{asup_enabled=\"true\",asup_https_configured!=\"https\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}\n                          or\n                            security_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",telnet_enabled=\"true\"}\n                        or\n                          security_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",rsh_enabled=\"true\"}\n                      or\n                          group by (datacenter, cluster) (\n                            security_account_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",hash_algorithm=\"md5\"}\n                          )\n                        \u003e\n                          0\n                    or\n                      cluster_peer_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",encryption_state=\"\"}\n                  or\n                    cluster_peer_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",encryption_state=\"none\"}\n                or\n                    group by (datacenter, cluster) (\n                      security_account_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",locked=\"false\",role_name=\"admin\",user_name=\"admin\"}\n                    )\n                  \u003e\n                    0\n              or\n                security_login_labels{banner=\"\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",scope=\"cluster\"}\n            or\n              security_login_labels{banner=\"\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$Cluster\"}\n          or\n            count by (datacenter, cluster) (ntpserver_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}) \u003c 1\n        or\n          security_audit_destination_status{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",protocol!=\"tcp_encrypted\"}\n      or\n        security_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",fips_enabled=\"false\"}\n    or\n      svm_labels{ciphers=~\".*_cbc.*\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\",type=\"admin\"}\n  or\n    group by (datacenter, cluster) (\n                      (\n                          (\n                              svm_labels{cifs_protocol_enabled=\"true\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\"}\n                            or\n                              svm_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",nfs_protocol_enabled=\"true\",svm=~\"$SVM\"}\n                          )\n                        and\n                          svm_labels{audit_protocol_enabled=\"false\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\"}\n                      )\n                    or\n                      security_ssh_labels{ciphers=~\".*_cbc.*\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}\n                  or\n                    security_login_labels{banner=\"\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",scope=\"svm\",svm=~\"$SVM\"}\n                or\n                    sum by (datacenter, cluster) (\n                      volume_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",root_volume=\"No\",snapshot_policy=\"none\"}\n                    )\n                  \u003e\n                    0\n              or\n                  sum by (datacenter, cluster) (\n                    volume_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",root_volume=\"No\",snapshot_autodelete=\"true\"}\n                  )\n                \u003e\n                  0\n            or\n                sum by (datacenter, cluster) (\n                  svm_labels{anti_ransomware_state=~\"|.*disabled\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\"}\n                )\n              \u003e\n                0\n          or\n              volume_arw_status{ArwStatus!=\"Active Mode\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}\n            * on (instance) group_left ()\n              metadata_collector_instances{collector=\"Rest\",datacenter=~\"$Datacenter\",object=\"Volume\"}\n        or\n            count by (datacenter, cluster) (\n              ems_destination_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}\n            )\n          \u003e\n            0\n      or\n        support_auto_update_labels{auto_update_enabled=\"false\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}\n    )\n)",

grafana/dashboards/cmode/security.json:215

  • The SVM login-banner noncompliance check only matches security_login_labels series with scope="svm". Elsewhere in this dashboard (e.g. the SVM login-message table query) you also handle SVM records that don’t have a scope label by matching svm!="$Cluster". If those scope-less series can occur here too, an empty banner on an SVM could be missed and the cluster incorrectly marked compliant.

Consider OR-ing in the scope-less variant with the same banner="" filter (e.g. add or security_login_labels{banner="",...,svm!="$Cluster",svm=~"$SVM"} next to the existing scope="svm" clause).

This issue also appears in the following locations of the same file:

  • line 883
  • line 4260
          "expr": "count(\n    group by (datacenter, cluster) (\n                                support_labels{asup_enabled=\"true\",asup_https_configured!=\"https\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}\n                              or\n                                security_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",telnet_enabled=\"true\"}\n                            or\n                              security_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",rsh_enabled=\"true\"}\n                          or\n                              group by (datacenter, cluster) (\n                                security_account_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",hash_algorithm=\"md5\"}\n                              )\n                            \u003e\n                              0\n                        or\n                          cluster_peer_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",encryption_state=\"\"}\n                      or\n                        cluster_peer_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",encryption_state=\"none\"}\n                    or\n                        group by (datacenter, cluster) (\n                          security_account_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",locked=\"false\",role_name=\"admin\",user_name=\"admin\"}\n                        )\n                      \u003e\n                        0\n                  or\n                    security_login_labels{banner=\"\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",scope=\"cluster\"}\n                or\n                  security_login_labels{banner=\"\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$Cluster\"}\n              or\n                count by (datacenter, cluster) (ntpserver_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}) \u003c 1\n            or\n              security_audit_destination_status{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",protocol!=\"tcp_encrypted\"}\n          or\n            security_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",fips_enabled=\"false\"}\n        or\n          svm_labels{ciphers=~\".*_cbc.*\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\",type=\"admin\"}\n      or\n        group by (datacenter, cluster) (\n              (\n                  (\n                      svm_labels{cifs_protocol_enabled=\"true\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\"}\n                    or\n                      svm_labels{cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",nfs_protocol_enabled=\"true\",svm=~\"$SVM\"}\n                  )\n                and\n                  svm_labels{audit_protocol_enabled=\"false\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",svm=~\"$SVM\"}\n              )\n            or\n              security_ssh_labels{ciphers=~\".*_cbc.*\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\"}\n          or\n            security_login_labels{banner=\"\",cluster=~\"$Cluster\",datacenter=~\"$Datacenter\",scope=\"svm\",svm=~\"$SVM\"}\n        )\n    )\n  )\nor\n  vector(0)",

@rahulguptajss
rahulguptajss merged commit 19599a8 into main Jul 30, 2026
14 checks passed
@rahulguptajss
rahulguptajss deleted the rg2-fix-security branch July 30, 2026 11:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants