Hello - thank you for this awesome plugin! I’m using it in a test environment and familiarizing myself with some of the auth methods. My goal is to:
-
provide anonymous authentication by default to Kibana, with the ability to search all, or specific, indices.
-
provide administrative privileges through searchguard internal basic authentication
I’ve left everything as the default but changed a single setting - in sg_config.yml, I set ‘anonymous_auth_enabled: true’ and reload SG using the admin tool, however, I am still basic auth prompted for credentials at a kibana login screen. I read several questions regarding this process, and it seems that once anonymous_auth_enabled is set to true, a role should be created, sg_anonymous, but I don’t see that in sg_roles.yml (Update, I see the role when connecting to ES without supplying credentials).
···
https://groups.google.com/forum/#!topic/search-guard/nz3FwxdLILc
Jochen says, emphasis mine:
This is what the “anonymous_auth_enabled” flag in sg_config does. If you set this to true:
- Search Guard will not challenge, regardless of the settings in sg_config
- In other words, it acts like every “challenge” flag is set to “false”
- Search Guard will look for credentials in the HTTP request
- This could be username:password in case of Basic Auth, or a JWT token, or a Kerberos ticket
- This depends on the authenticator(s) you configured
- If credentials are found, Search Guard uses them to authenticate the user
- If no credentials are found, the user will be treated as anonymous
- username is “sg_anonymous”
- role is “sg_anonymous_backendrole”
You can then use this username and role to configure any permissions on any index you like. So technically this is relatively easy to achieve.
If this is expected or I haven’t completed all the steps, is there a support article I can read to enable anonymous access to Kibana? Thank you.
- Search Guard and Elasticsearch version
6.2.3
- JVM version and operating system version
9
- Search Guard configuration files
searchguard:
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
#kibana:
# Kibana multitenancy - NOT FREE FOR COMMERCIAL USE
# see [https://github.com/floragunncom/search-guard-docs/blob/master/multitenancy.md](https://github.com/floragunncom/search-guard-docs/blob/master/multitenancy.md)
# To make this work you need to install [https://github.com/floragunncom/search-guard-module-kibana-multitenancy/wiki](https://github.com/floragunncom/search-guard-module-kibana-multitenancy/wiki)
#multitenancy_enabled: true
#server_username: kibanaserver
#index: '.kibana'
#do_not_fail_on_forbidden: false
http:
anonymous_auth_enabled: true
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'
proxiesHeader: 'x-forwarded-by'
#trustedProxies: '.*' # trust all external proxies, regex pattern
###### see [https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html](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](https://en.wikipedia.org/wiki/X-Forwarded-For)
###### and here [https://tools.ietf.org/html/rfc7239](https://tools.ietf.org/html/rfc7239)
###### and [https://tomcat.apache.org/tomcat-8.0-doc/config/valve.html#Remote_IP_Valve](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 # NOT FREE FOR COMMERCIAL USE
challenge: false
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:
http_enabled: true
transport_enabled: true
order: 4
http_authenticator:
type: basic
challenge: true
authentication_backend:
type: intern
proxy_auth_domain:
http_enabled: false
transport_enabled: false
order: 3
http_authenticator:
type: proxy
challenge: false
config:
user_header: "x-proxy-user"
roles_header: "x-proxy-roles"
authentication_backend:
type: noop
jwt_auth_domain:
http_enabled: false
transport_enabled: false
order: 0
http_authenticator:
type: jwt
challenge: false
config:
signing_key: "base64 encoded HMAC key or public RSA/ECDSA pem key"
jwt_header: "Authorization"
jwt_url_parameter: null
roles_key: null
subject_key: null
authentication_backend:
type: noop
clientcert_auth_domain:
http_enabled: false
transport_enabled: false
order: 2
http_authenticator:
type: clientcert
config:
username_attribute: cn #optional, if omitted DN becomes username
challenge: false
authentication_backend:
type: noop
ldap:
http_enabled: false
transport_enabled: false
order: 5
http_authenticator:
type: basic
challenge: false
authentication_backend:
# LDAP authentication backend (authenticate users against a LDAP or Active Directory)
type: ldap # NOT FREE FOR COMMERCIAL USE
config:
# enable ldaps
enable_ssl: false
# enable start tls, enable_ssl should be false
enable_start_tls: false
# send client certificate
enable_ssl_client_auth: false
# verify ldap hostname
verify_hostnames: true
hosts:
- localhost:8389
bind_dn: null
password: null
userbase: 'ou=people,dc=example,dc=com'
# Filter to search for users (currently in the whole subtree beneath userbase)
# {0} is substituted with the username
usersearch: '(sAMAccountName={0})'
# Use this attribute from the user as username (if not set then DN is used)
username_attribute: null
authz:
roles_from_myldap:
http_enabled: false
transport_enabled: false
authorization_backend:
# LDAP authorization backend (gather roles from a LDAP or Active Directory, you have to configure the above LDAP authentication backend settings too)
type: ldap # NOT FREE FOR COMMERCIAL USE
config:
# enable ldaps
enable_ssl: false
# enable start tls, enable_ssl should be false
enable_start_tls: false
# send client certificate
enable_ssl_client_auth: false
# verify ldap hostname
verify_hostnames: true
hosts:
- localhost:8389
bind_dn: null
password: null
rolebase: 'ou=groups,dc=example,dc=com'
# Filter to search for roles (currently in the whole subtree beneath rolebase)
# Filter to search for roles (currently in the whole subtree beneath rolebase)
# {0} is substituted with the DN of the user
# {1} is substituted with the username
# {2} is substituted with an attribute value from user's directory entry, of the authenticated user. Use userroleattribute to specify the name of the attribute
rolesearch: '(member={0})'
# Specify the name of the attribute which value should be substituted with {2} above
userroleattribute: null
# Roles as an attribute of the user entry
userrolename: disabled
#userrolename: memberOf
# The attribute in a role entry containing the name of that role, Default is "name".
# Can also be "dn" to use the full DN as rolename.
rolename: cn
# Resolve nested roles transitive (roles which are members of other roles and so on ...)
resolve_nested_roles: true
userbase: 'ou=people,dc=example,dc=com'
# Filter to search for users (currently in the whole subtree beneath userbase)
# {0} is substituted with the username
usersearch: '(uid={0})'
# Skip users matching a user name, a wildcard or a regex pattern
#skip_users:
# - 'cn=Michael Jackson,ou*people,o=TEST'
# - '/\S*/'
roles_from_another_ldap:
enabled: false
authorization_backend:
type: ldap # NOT FREE FOR COMMERCIAL USE
#config goes here ...
SG_ROLES.yml
sg_all_access:
readonly: true
cluster:
- UNLIMITED
indices:
'*':
'*':
- UNLIMITED
tenants:
admin_tenant: RW
Read all, but no write permissions
sg_readall:
readonly: true
cluster:
- CLUSTER_COMPOSITE_OPS_RO
indices:
'*':
'*':
- READ
Read all and monitor, but no write permissions
sg_readall_and_monitor:
cluster:
- CLUSTER_MONITOR
- CLUSTER_COMPOSITE_OPS_RO
indices:
'*':
'*':
- READ
For users which use kibana, access to indices must be granted separately
sg_kibana_user:
readonly: true
cluster:
- MONITOR
- CLUSTER_COMPOSITE_OPS_RO
indices:
'?kibana':
'*':
- MANAGE
- INDEX
- READ
- DELETE
'*':
'*':
- indices:data/read/field_caps*
For the kibana server
sg_kibana_server:
readonly: true
cluster:
- CLUSTER_MONITOR
- CLUSTER_COMPOSITE_OPS
- cluster:admin/xpack/monitoring*
- indices:admin/template*
indices:
'?kibana':
'*':
- INDICES_ALL
'?reporting*':
'*':
- INDICES_ALL
'?monitoring*':
'*':
- INDICES_ALL
For logstash and beats
sg_logstash:
cluster:
- CLUSTER_MONITOR
- CLUSTER_COMPOSITE_OPS
- indices:admin/template/get
- indices:admin/template/put
indices:
'logstash-*':
'*':
- CRUD
- CREATE_INDEX
'*beat*':
'*':
- CRUD
- CREATE_INDEX
Allows adding and modifying repositories and creating and restoring snapshots
sg_manage_snapshots:
cluster:
- MANAGE_SNAPSHOTS
indices:
'*':
'*':
- "indices:data/write/index"
- "indices:admin/create"
Allows each user to access own named index
sg_own_index:
cluster:
- CLUSTER_COMPOSITE_OPS
indices:
'${user_name}':
'*':
- INDICES_ALL
X-Pack COMPATIBILITY
sg_xp_monitoring:
readonly: true
indices:
'?monitor*':
'*':
- INDICES_ALL
sg_xp_alerting:
readonly: true
cluster:
- indices:data/read/scroll
- cluster:admin/xpack/watcher*
- cluster:monitor/xpack/watcher*
indices:
'?watches*':
'*':
- INDICES_ALL
'?watcher-history-*':
'*':
- INDICES_ALL
'?triggered_watches':
'*':
- INDICES_ALL
'*':
SG_ROLES_MAPPING.yml
sg_all_access:
readonly: true
backendroles:
- admin
sg_logstash:
backendroles:
- logstash
sg_kibana_server:
readonly: true
users:
- kibanaserver
sg_kibana_user:
backendroles:
- kibanauser
sg_readall:
readonly: true
backendroles:
- readall
sg_manage_snapshots:
readonly: true
backendroles:
- snapshotrestore
sg_own_index:
users:
- '*'