Hello,
I try to set up SAML SSO for Entra ID. However, when I deploy my configuration and I choose for to login with SSO at the wazuh dashboard a blank space shows up with the error:
{
"statusCode": 500,
"error": "Internal Server Error",
"message": "Internal Error"
}
Also when I check the logs at wazuh dashboard /var/log/messages I get the output:
Jan 8 16:18:19
wada1.domain.net opensearch-dashboards[1872670]: {"type":"log","@timestamp":"2025-01-08T16:18:19Z","tags":["error","plugins","securityDashboards"],"pid":1872670,"message":"Failed to get saml header: Authentication Exception :: {\"path\":\"/_plugins/_security/authinfo\",\"query\":{},\"statusCode\":401,\"response\":\"Authentication finally failed\"}"}
Jan 8 16:18:19
wada1.domain.net opensearch-dashboards[1872670]: {"type":"log","@timestamp":"2025-01-08T16:18:19Z","tags":["error","plugins","securityDashboards"],"pid":1872670,"message":"Failed to get saml header: Authentication Exception :: {\"path\":\"/_plugins/_security/authinfo\",\"query\":{},\"statusCode\":401,\"response\":\"Authentication finally failed\"}"}
Jan 8 16:18:19
wada1.domain.net opensearch-dashboards[1872670]: {"type":"error","@timestamp":"2025-01-08T16:18:19Z","tags":[],"pid":1872670,"level":"error","error":{"message":"Internal Server Error","name":"Error","stack":"Error: Internal Server Error\n at HapiResponseAdapter.toError (/usr/share/wazuh-dashboard/src/core/server/http/router/response_adapter.js:127:19)\n at HapiResponseAdapter.toHapiResponse (/usr/share/wazuh-dashboard/src/core/server/http/router/response_adapter.js:83:19)\n at HapiResponseAdapter.handle (/usr/share/wazuh-dashboard/src/core/server/http/router/response_adapter.js:79:17)\n at Router.handle (/usr/share/wazuh-dashboard/src/core/server/http/router/router.js:175:34)\n at processTicksAndRejections (node:internal/process/task_queues:95:5)\n at handler (/usr/share/wazuh-dashboard/src/core/server/http/router/router.js:140:50)\n at exports.Manager.execute (/usr/share/wazuh-dashboard/node_modules/@hapi/hapi/lib/toolkit.js:60:28)\n at Object.internals.handler (/usr/share/wazuh-dashboard/node_modules/@hapi/hapi/lib/handler.js:46:20)\n at exports.execute (/usr/share/wazuh-dashboard/node_modules/@hapi/hapi/lib/handler.js:31:20)\n at Request._lifecycle (/usr/share/wazuh-dashboard/node_modules/@hapi/hapi/lib/request.js:371:32)\n at Request._execute (/usr/share/wazuh-dashboard/node_modules/@hapi/hapi/lib/request.js:281:9)"},"url":"
https://wazuh.domain.net/auth/saml/login?nextUrl=%2F&redirectHash=false","message":"Internal Server Error"}
Jan 8 16:18:19
wada1.domain.net opensearch-dashboards[1872670]: {"type":"error","@timestamp":"2025-01-08T16:18:19Z","tags":[],"pid":1872670,"level":"error","error":{"message":"Internal Server Error","name":"Error","stack":"Error: Internal Server Error\n at HapiResponseAdapter.toError (/usr/share/wazuh-dashboard/src/core/server/http/router/response_adapter.js:127:19)\n at HapiResponseAdapter.toHapiResponse (/usr/share/wazuh-dashboard/src/core/server/http/router/response_adapter.js:83:19)\n at HapiResponseAdapter.handle (/usr/share/wazuh-dashboard/src/core/server/http/router/response_adapter.js:79:17)\n at Router.handle (/usr/share/wazuh-dashboard/src/core/server/http/router/router.js:175:34)\n at processTicksAndRejections (node:internal/process/task_queues:95:5)\n at handler (/usr/share/wazuh-dashboard/src/core/server/http/router/router.js:140:50)\n at exports.Manager.execute (/usr/share/wazuh-dashboard/node_modules/@hapi/hapi/lib/toolkit.js:60:28)\n at Object.internals.handler (/usr/share/wazuh-dashboard/node_modules/@hapi/hapi/lib/handler.js:46:20)\n at exports.execute (/usr/share/wazuh-dashboard/node_modules/@hapi/hapi/lib/handler.js:31:20)\n at Request._lifecycle (/usr/share/wazuh-dashboard/node_modules/@hapi/hapi/lib/request.js:371:32)\n at Request._execute (/usr/share/wazuh-dashboard/node_modules/@hapi/hapi/lib/request.js:281:9)"},"url":"
https://wazuh.domain.net/auth/saml/login?nextUrl=%2F&redirectHash= Jan 8 16:18:19
wada1.domain.net opensearch-dashboards[1872670]: {"type":"log","@timestamp":"2025-01-08T16:18:19Z","tags":["error","plugins","securityDashboards"],"pid":1872670,"message":"Failed to get saml header: Authentication Exception :: {\"path\":\"/_plugins/_security/authinfo\",\"query\":{},\"statusCode\":401,\"response\":\"Authentication finally failed\"}"}
And Wazuh-indexer:
[2025-01-08T19:31:07,414][WARN ][o.o.s.a.BackendRegistry ] [
wadex2.domain.net] Authentication finally failed for null from x.x.x.x
I use the following opensearch-security config.yml configuration for wazuh indexer:
---
# This is the main OpenSearch Security configuration file where authentication
# and authorization is defined.
#
# You need to configure at least one authentication domain in the authc of this file.
# An authentication domain is responsible for extracting the user credentials from
# the request and for validating them against an authentication backend like Active Directory for example.
#
# If more than one authentication domain is configured the first one which succeeds wins.
# If all authentication domains fail then the request is unauthenticated.
# In this case an exception is thrown and/or the HTTP status is set to 401.
#
# After authentication authorization (authz) will be applied. There can be zero or more authorizers which collect
# the roles from a given backend for the authenticated user.
#
# Both, authc and auth can be enabled/disabled separately for REST and TRANSPORT layer. Default is true for both.
# http_enabled: true
# transport_enabled: true
#
# For HTTP it is possible to allow anonymous authentication. If that is the case then the HTTP authenticators try to
# find user credentials in the HTTP request. If credentials are found then the user gets regularly authenticated.
# If none can be found the user will be authenticated as an "anonymous" user. This user has always the username "anonymous"
# and one role named "anonymous_backendrole".
# If you enable anonymous authentication all HTTP authenticators will not challenge
#
#
# Note: If you define more than one HTTP authenticators make sure to put non-challenging authenticators like "proxy" or "clientcert"
# first and the challenging one last.
# Because it's not possible to challenge a client with two different authentication methods (for example
# Kerberos and Basic) only one can have the challenge flag set to true. You can cope with this situation
# by using pre-authentication, e.g. sending a HTTP Basic authentication header in the request.
#
# Default value of the challenge flag is true.
#
#
# HTTP
# basic (challenging)
# proxy (not challenging, needs xff)
# kerberos (challenging)
# clientcert (not challenging, needs https)
# jwt (not challenging)
# host (not challenging) #DEPRECATED, will be removed in a future version.
# host based authentication is configurable in roles_mapping
# Authc
# internal
# noop
# ldap
# Authz
# ldap
# noop
_meta:
type: "config"
config_version: 2
config:
dynamic:
# Set filtered_alias_mode to 'disallow' to forbid more than 2 filtered aliases per index
# Set filtered_alias_mode to 'warn' to allow more than 2 filtered aliases per index but warns about it (default)
# Set filtered_alias_mode to 'nowarn' to allow more than 2 filtered aliases per index silently
#filtered_alias_mode: warn
#do_not_fail_on_forbidden: false
#kibana:
# Kibana multitenancy
#multitenancy_enabled: true
#private_tenant_enabled: true
#default_tenant: ""
#server_username: kibanaserver
#index: '.kibana'
http:
anonymous_auth_enabled: false
xff:
enabled: false
internalProxies: '192\.168\.0\.10|192\.168\.0\.11' # regex pattern
#internalProxies: '.*' # trust all internal proxies, regex pattern
#remoteIpHeader: 'x-forwarded-for'
###### see
https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html for regex help
###### more information about XFF
https://en.wikipedia.org/wiki/X-Forwarded-For ###### and here
https://tools.ietf.org/html/rfc7239 ###### and
https://tomcat.apache.org/tomcat-8.0-doc/config/valve.html#Remote_IP_Valve authc:
kerberos_auth_domain:
http_enabled: false
transport_enabled: false
order: 6
http_authenticator:
type: kerberos
challenge: true
config:
# If true a lot of kerberos/security related debugging output will be logged to standard out
krb_debug: false
# If true then the realm will be stripped from the user name
strip_realm_from_principal: true
authentication_backend:
type: noop
basic_internal_auth_domain:
description: "Authenticate via HTTP Basic against internal users database"
http_enabled: true
transport_enabled: true
order: 0
http_authenticator:
type: basic
challenge: false
authentication_backend:
type: intern
saml_auth_domain:
http_enabled: true
transport_enabled: false
order: 1
http_authenticator:
type: saml
challenge: true
config:
idp:
metadata_file: "/etc/wazuh-indexer/opensearch-security/wazuh.xml"
entity_id:
https://sts.windows.net/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/ sp:
entity_id:
https://wazuh.domain.net kibana_url:
https://wazuh.domain.net:443 roles_key:
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/Roles exchange_key: 'X.509 certificate'
authentication_backend:
type: noop
And this is wazuh-dashboards.yml config file:
server.host: 0.0.0.0
server.port: 443
opensearch.hosts: ["
https://wadex1.domain.net:9200", "
https://wadex2.domain.net:9200", "
https://wadex3.domain.net:9200"]
opensearch.ssl.verificationMode: certificate
#opensearch.username:
#opensearch.password:
opensearch.requestHeadersAllowlist: ["securitytenant","Authorization"]
opensearch_security.multitenancy.enabled: false
opensearch_security.readonly_mode.roles: ["kibana_read_only"]
server.ssl.enabled: true
server.ssl.key: "{{ domain_nl_net_key_path }}"
server.ssl.certificate: "{{ domain_nl_net_crt_path }}"
opensearch.ssl.certificateAuthorities: ["{{ wazuh_domain_ca_root_path }}"]
uiSettings.overrides.defaultRoute: /app/wz-home
opensearch_security.auth.multiple_auth_enabled: true
opensearch_security.auth.type: ["basicauth", "saml"]
server.xsrf.allowlist: ["/_opendistro/_security/saml/acs/idpinitiated", "/_opendistro/_security/saml/acs", "/_opendistro/_security/saml/logout", "/_plugins/_security/authinfo"]
opensearch_security.session.keepalive: false
what do I miss in my configuration?