Graylog-auth-proxy is a service that syncs users from an SSO provider (such as Active Directory) with users in Graylog. The service works as a reverse proxy for the Graylog server.
Supported deploy schemes¶
Currently, graylog-auth-proxy supports as SSO provider only LDAP (or AD) server.
How it works¶
During working process graylog-auth-proxy connects to an SSO provider and handles all requests that are going to the Graylog server. If user wants to access to the Graylog UI via the proxy, they need to enter credentials for a user from SSO provider. Then the proxy verifies these creds and adds user with the same username and random password to Graylog and gives him the rights (attaches roles and shares several streams) based on the proxy configuration and some attributes of the user from SSO provider. If the proxy is integrated with OAuth service, the credentials are verified on the OAuth server-side. If the user is already exist in the Graylog, graylog-auth-proxy tries to update it.
After successful authentication graylog-auth-proxy adds a trusted header with the username to each request that goes to Graylog to avoid internal Graylog authentication. The proxy connect to LDAP or OAuth server only once and then uses cookies to identify users for better performance. That mechanism work until cookies expired.
Regardless of this, the proxy runs the script for rotation of random passwords for users created in the Graylog and deleting users that no longer exist in the SSO provider. This script runs every few days (3 days by default).
Also, graylog-auth-proxy have a metrics endpoint /metrics
with Prometheus metrics.
flowchart LR
A[User] -->|auth|B{auth-proxy}
B -->|auth request| C[LDAP or OAuth]
C -->|auth response| B
B -->|successful login| D[Graylog]
Installation¶
You can deploy the graylog-auth-proxy
as part of the Graylog container with the logging-operator
.
In this document, we will talk about the features of the configuration and installation of the graylog-auth-proxy
.
You can see more information about the deployment of the logging-operator in general
in the installation guide.
You must set .Values.graylog.authProxy.install
to true
to allow installation. In addition, you need to
configure several parameters to properly connect to the SSO provider (e.g. to LDAP or OAuth server).
You can find the list of parameters in the installation guide.
Connecting to LDAP¶
If you want to use LDAP as an SSO provider, you have to specify parameter authType
as ldap
.
Then you have to specify a several mandatory parameters to connect to LDAP (or AD) server:
url
- URL of LDAP serverbaseDn
- base DN for users that will be synchronized with the corresponding users in the GraylogbindDn
- DN for LDAP user that will be used to connect to LDAP and query other users by usingbaseDn
bindPassword
orhtpasswd
- password for user specified bybindDn
configured as plaintext in thebindPassword
parameter or as path to htpasswd file with password stored on the VM in thehtpasswd
parametersearchFilter
- LDAP template for query. Default value is used for OpenLDAP. If you want to use Active Directory you can set(SAMAccountName=%(username)s)
as value of the parameter
Also, you can specify unnecessary parameters which can be used for detailed configuration of the connection to LDAP and details of synchronization between LDAP and Graylog users:
roleMapping
- configuration that describes the proxy how to match Graylog roles and groups of LDAP usersstreamMapping
- similar configuration asrole_mapping
that allows to share Graylog streams to users based on the user's membership in LDAP grouprotationPassInterval
- interval in days between password rotation for users in Graylog except those who specified in thepre_created_users
parameterpreCreatedUsers
- names of users separated by commas for whom will not work password rotation
Let's take a closer look at the configuration of the proxy and how it works.
When you enter username and password from LDAP user to the basic auth form, the proxy tries to find user with the same
username in LDAP server at address stored in the url
on the DN, specified in the baseDn
parameter.
Search is conducted on behalf of the user specified in the bindDn
parameter. Also, the proxy should know password
for this user. This password can be set in 2 different ways:
- As plain text in the
bindPassword
parameter - (recommended) You can create htpasswd file that contains password encoded in base64. Path to this file on VM
should be specified in the
htpasswd
parameter
Also, you should set correct searchFilter
if needed. Usually you can use the default value (cn=%(username)s)
for
OpenLDAP server or (SAMAccountName=%(username)s)
value for Active Directory server.
If you want to configure matching between Graylog users and LDAP users based on attribute memberOf
from LDAP, you
should specify roleMapping
parameter in the following format:
The last set of roles will be used if the user doesn't match any of specified groups.
For example, the following configuration:
"CN=otrk_admins,OU=OTRK_Groups,OU=IRQA_LDAP,DC=testad,DC=local":["Admin"] | "CN=otrk_users,OU=OTRK_Groups,OU=IRQA_LDAP,DC=testad,DC=local":["Reader","Operator"] | ["Reader"]
will match this cases:
- LDAP users who are members of group with CN
CN=otrk_admins,OU=OTRK_Groups,OU=IRQA_LDAP,DC=testad,DC=local
will have roleAdmin
in the Graylog - LDAP users who are members of group with CN
CN=otrk_users,OU=OTRK_Groups,OU=IRQA_LDAP,DC=testad,DC=local
will have rolesReader
andOperator
in the Graylog - Users who are not members of groups above will have role
Reader
Note that the order in which groups are specified matters. If user is a member of two or more groups that specified in the configuration, the first one will be chosen.
You can find available roles or create your own on the Graylog interface: System -> Roles
.
Stream sharing for Graylog users is configured in a similar way:
"<group_CN_1>":["<stream_name_x>/<access_level_x>","<stream_name_y>/<access_level_y>"] | "<group_CN_2>":["<stream_name_z>"] | ["<stream_name_default>/<access_level_default>"]
where access level can take values view
, manage
and own
. If the access level is not specified, view
capability
will set by default.
For example, the following configuration:
"CN=otrk_admins,OU=OTRK_Groups,OU=IRQA_LDAP,DC=testad,DC=local":["All messages/manage","all events/view"] | "CN=otrk_users,OU=OTRK_Groups,OU=IRQA_LDAP,DC=testad,DC=local":["All events"] | ["System logs/view"]
will match this cases:
- Stream with name
All messages
with capabilityManager
and streamAll events
with capabilityViewer
will be shared for each LDAP user who is members of group with CNCN=otrk_admins,OU=OTRK_Groups,OU=IRQA_LDAP,DC=testad,DC=local
- Stream with name
All events
with default capabilityViewer
will be shared for each LDAP user who is members of group with CNCN=otrk_users,OU=OTRK_Groups,OU=IRQA_LDAP,DC=testad,DC=local
- Users who are not members of groups above will have access to stream
System logs
with capabilityViewer
The order in which groups are specified matters just as for the role mapping. Names of streams are case-insensitive.
Please, do not forget to put quotes and other punctuation marks in the same way as it is done in the examples.
The proxy creates corresponding users in the Graylog for each user that logged in the Graylog via the proxy at least once. These users are created with random passwords.
The graylog-auth-proxy consists of HTTP server that handles requests and redirects them to Graylog, and the separate script for rotation Graylog passwords for created users and deleting those that no longer exists in LDAP.
This part runs on a schedule at intervals of several days. The interval can be specified in the
rotationPassInterval
parameter (3 days by default).
This script run for each user, no matter it was created by the proxy or not. But you can exclude users from the
rotation by adding those names to the preCreatedUsers
parameter. The following users will be excluded by default:
admin,auditViewer,operator,telegraf_operator,graylog-sidecar,graylog_api_th_user
, where admin
is the default
root user for Graylog UI and others - technical users for internal usage.
If you want to add your own users to this list, please, do not remove any of default users from it. It means that
you if you want to add user_1
and user_2
, you should specify the preCreatedUsers
parameter like that:
Otherwise, this can lead to unpredictable consequences.
Storing of LDAP bind password¶
You must set password for LDAP bind user specified in the ldap.bindDN
parameter as value of the ldap.bindPassword
parameter during deploy for correct LDAP connection. In this case, the password will be stored in the Secret with
the name that specified in ldap.bindPasswordSecret.name
parameter (graylog-auth-proxy-secret
by default) at the key
that specified in ldap.bindPasswordSecret.key
parameter (bindPassword
by default).
The ldap.bindPasswordSecret
parameter uses v1.SecretKeySelector
structure.
See Kubernetes docs
to figure out how to customize this parameter.
Note: Bind password will be encoded in base64 twice. It means that the password will be double encoded in the Secret. This is required due to the way graylog-auth-proxy works.
LDAP over SSL¶
If your LDAP server has a port with an ability to connect to it with SSL encryption, you should prefer an LDAP over SSL instead of insecure LDAP connection.
The main path to configure the proxy to connect to LDAP over SSL is almost the same as in the previous section.
Differences in the configuration between insecure and secure connections:
url
- note that the URL of the LDAP server must start withldaps://
. Also, usually there is a different port for LDAPS connection. The default port for LDAPS is636
overSsl
- set this value totrue
skipVerify
- don't touch this parameter if you're not fully aware of all risks! You can set this parameter totrue
, but only if your LDAP server uses self-signed certificateca
- this parameter containca.secretName
andca.secretKey
and allows setting of the CA certificate to verify LDAP server's certificatecert
andkey
- you can set these parameters if you need to send info about client certificate to the LDAP server. IncludesecretName
andsecretKey
too
You must have a CA certificate of your LDAP server to verify its certificate during handshake. LDAP server's SSL certificates can be retrieved by using the following OpenSSL command:
Root CA for the LDAP server should be placed to the Kubernetes Secret in the same namespace as logging-operator.
Then you should set the name of the Secret to the ca.secretName
parameter and the key (name of the file with
the certificate in the Secret) to the ca.secretKey
parameter.
Client certificate and private key can be set the similar way as CA to cert
and key
parameters respectively.
You might use them if you need to support mTLS connection with the client verification.
LDAP with STARTTLS¶
STARTTLS is a feature that allows using TLS encryption over the simple LDAP (not LDAPS) protocol. The newest RFC recommends using LDAP over SSL instead of STARTTLS.
Connection with STARTTLS is almost the same as the connection over SSL except the URL that should start with ldap://
.
Also, you should set startTls: true
instead of overSsl
.
Configuration examples for LDAP mode¶
Simple configuration without role mapping, stream sharing or any deep customization (for Active Directory server):
graylog:
...
authProxy:
install: true
authType: ldap
ldap:
url: ldap://adfs.test.org
baseDN: "OU=IRQA_LDAP,DC=testad,DC=local"
bindDN: "otrk_admin"
bindPassword: <otrk_admin_password>
searchFilter: "(SAMAccountName=%(username)s)"
Configuration example for LDAP mode with more customization:
graylog:
...
authProxy:
install: true
authType: ldap
logLevel: INFO
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 512Mi
ldap:
url: ldap://adfs.test.org
startTls: false
overSsl: false
skipVerify: false
disableReferrals: false
baseDN: "OU=IRQA_LDAP,DC=testad,DC=local"
bindDN: "otrk_super"
bindPassword: <otrk_admin_password>
bindPasswordSecret:
name: graylog-auth-proxy-secret
key: bindPassword
searchFilter: "(SAMAccountName=%(username)s)"
preCreatedUsers: admin,auditViewer,operator,telegraf_operator,graylog-sidecar,graylog_api_th_user
rotationPassInterval: 3
roleMapping: '"CN=otrk_admins,OU=OTRK_Groups,OU=IRQA_LDAP,DC=testad,DC=local":["Admin"] | ["Reader"]'
streamMapping: '"CN=otrk_admins,OU=OTRK_Groups,OU=IRQA_LDAP,DC=testad,DC=local":["All messages/manage","all events/view"] | "CN=otrk_users,OU=OTRK_Groups,OU=IRQA_LDAP,DC=testad,DC=local":["All events"] | ["System logs/view"]'
Connecting to OAuth authorization server¶
If you want to use OAuth authorization server as an SSO provider, you have to specify parameter authType
as oauth
.
Then you have to specify mandatory parameters for OAuth protocol. You can find the list of these parameters in this section of the installation guide.
The best way to explain these parameters is to configure the proxy for using a specific service as an example. You can find such example below.
Integration with Keycloak¶
Keycloak configuration¶
In this guide we assume that you already have a working Keycloak service in the cloud and have access to its UI as a user with admin permissions. Deployment configuration of the Keycloak server is not a goal of this guide.
Let's assume that you have logged in to the Keycloak UI as an admin user located at https://mykeycloak.com
.
Realm¶
You have to choose a realm when you want to create a client entity for graylog-auth-proxy. Remember that realm is an isolated area in your Keycloak cluster, so you can't gain access to users and clients from the one realm when you interact with another. You will have to use the name for the realm in the proxy's configuration.
If you want to create a new realm, click on the drop-down list in the left top corner of the UI and then click on
Create realm
button. Enter the name of the realm and click Create
.
Let's assume that the name of the realm is myrealm
.
Client¶
Go to the Clients
section (choose it in the menu on the left side of the screen) and click on the Create client
button.
On the first page General settings
: Client type
should be set as OpenID Connect
.
Enter Client ID
(this parameter will be used in the proxy's configuration). Other fields on this page are optional.
Let's assume that the Client ID is graylog-auth-proxy
.
Click on the Next
button to go to the Capability config
page: turn on Client authentication
switch and
uncheck the Direct access grants
box.
Click on the Next
button to go to the Login settings
page: the only required field here is Valid redirect URIs
which must include the hostname of your Graylog server with /code
path: http(-s)://<graylog-host>/code
.
Click on the Save
button the client is ready.
Click on your new client on the Clients list
tab and go to the Credentials
tab. Copy the Client Secret
for
configuring of the proxy later.
Client scopes¶
Let's assume that you want to map roles and streams in Graylog to specific roles of users from Keycloak.
If so, go to the Client scopes
section and click on the Roles
in the list of the scopes. Go to Mappers
tab and
click on the realm roles
. Turn on the Add to userinfo
switch and click on the Save
button.
After the steps above the proxy will be able to get information about roles attached to the specific users.
Users¶
You can skip this step if you chose an existing realm and already have a set of created users.
Go to the Users
section and click on the Add user
button. The only required field here is Username
and press
the Save
button.
Then you can go to the Role mapping
tab to assign roles to the user. The roles configuration can be found in the
Realm roles
section.
Also, you can join the user to groups. Configuration of groups can be found in the Groups
section. Roles can be
assigned to the whole group of users. In this case, all users in the group will inherit the roles from the groups.
The new user has no credentials, so you have to go to the Credentials
tab and click on the Set password
button.
Enter the password for the user and click on the Save
button. If you want to make user to change their password
during the first login, keep the Temporary
switch turned on, otherwise turn it off.
Proxy configuration¶
Required parameters for integration with the Keycloak server:
authType
- must be set tooauth
oauth.host
- Keycloak server's hostoauth.authorizationPath
- path for redirection to OAuth2 authorization server login page. Keycloak uses/realms/<realm-name>/protocol/openid-connect/auth
oauth.tokenPath
- path for getting access token from OAuth2 authorization server. Keycloak uses/realms/<realm-name>/protocol/openid-connect/token
oauth.userinfoPath
- path for getting information about current user from OAuth2 authorization server to get username and entities (roles, groups, etc.) for Graylog roles and streams mapping. Keycloak uses/realms/<realm-name>/protocol/openid-connect/userinfo
oauth.clientID
- ID of the client created in the Keycloak for graylog-auth-proxyoauth.clientSecret
- the Client Secret associated with this Client ID
Optional parameters for integration with the Keycloak server:
oauth.redirectUri
- you can specify redirect URI for manipulation with the Keycloak API manually if you don't use automatically created Ingress to gain access to Graylog UI for some reason. If so, the URI have to start with the scheme and end with non-empty path (e.g./code
). Leave the parameter empty if you want to use Ingress created by logging-operator.oauth.scopes
- OAuth2 scopes for the proxy separated by spaces. Leave the default value to give the proxy access to the username and rolesoauth.userJsonpath
- JSONPath (by jsonpath-ng) for taking username from the JSON returned from OAuth2 server by using userinfo path. The default value is already configured for Keycloak.oauth.rolesJsonpath
- JSONPath (by jsonpath-ng) for taking information about entities (roles, groups, etc.) for Graylog roles and streams mapping from the JSON returned from OAuth2 server by using userinfo path. The default value is already configured to take roles from Keycloak.oauth.skipVerify
,oauth.ca
,oauth.cert
,oauth.key
- TLS configuration for the OAuth serviceoauth.clientCredentialsSecret
- configuration of the Kubernetes Secret where is Client Secret stored
Configuration examples for integration with Keycloak¶
The examples below use values from the Keycloak configuration section.
Please, pay attention that the Keycloak server from this example uses HTTPS protocol, so you have to specify TLS parameters to verify its certificate.
Simple configuration without role mapping, stream sharing or any deep customization:
graylog:
...
authProxy:
install: true
authType: oauth
oauth:
url: https://mykeycloak.com
authorizationPath: /realms/myrealm/protocol/openid-connect/auth
tokenPath: /realms/myrealm/protocol/openid-connect/token
userinfoPath: /realms/myrealm/protocol/openid-connect/userinfo
skipVerify: false
ca:
secretName: graylog-auth-proxy-oauth-ca
secretKey: ca.crt
clientID: graylog-auth-proxy
clientSecret: <client-secret>
scopes: "openid profile roles"
userJsonpath: "preferred_username"
rolesJsonpath: "realm_access.roles[*]"
clientCredentialsSecret:
name: graylog-auth-proxy-secret
key: clientSecret
Configuration example with more customization:
graylog:
...
authProxy:
install: true
authType: oauth
logLevel: INFO
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 512Mi
oauth:
url: https://mykeycloak.com
authorizationPath: /realms/myrealm/protocol/openid-connect/auth
tokenPath: /realms/myrealm/protocol/openid-connect/token
userinfoPath: /realms/myrealm/protocol/openid-connect/userinfo
skipVerify: false
ca:
secretName: graylog-auth-proxy-oauth-ca
secretKey: ca.crt
clientID: graylog-auth-proxy
clientSecret: <client-secret>
scopes: "openid profile roles"
userJsonpath: "preferred_username"
rolesJsonpath: "realm_access.roles[*]"
clientCredentialsSecret:
name: graylog-auth-proxy-secret
key: clientSecret
preCreatedUsers: admin,auditViewer,operator,telegraf_operator,graylog-sidecar,graylog_api_th_user
rotationPassInterval: 3
roleMapping: '"test_admin_role":["Admin"] | ["Reader"]'
streamMapping: '"test_admin_role":["All messages/manage","all events/view"] | ["System logs/view"]'
Storing of OAuth Client Secret¶
You must set OAuth Client Secret as value of the oauth.clientSecret
. In this case, the password will be stored
in the Secret with the name that specified in oauth.clientCredentialsSecret.name
parameter
(graylog-auth-proxy-secret
by default) at the key
that specified in oauth.clientCredentialsSecret.key
parameter (clientSecret
by default).
The oauth.clientCredentialsSecret
parameter uses v1.SecretKeySelector
structure.
See Kubernetes docs
to figure out how to customize this parameter.
Note: Client Secret will be encoded in base64 twice. It means that the password will be double encoded in the Secret. This is required due to the way graylog-auth-proxy works.
OAuth service with TLS¶
Differences in the configuration between insecure and secure connections:
url
- note that the URL of the OAuth server have to start withhttps://
skipVerify
- don't touch this parameter if you're not fully aware of all risks! You can set this parameter totrue
, but only if your OAuth server uses self-signed certificateca
- this parameter containca.secretName
andca.secretKey
and allows setting of the CA certificate to verify OAuth server's certificatecert
andkey
- you can set these parameters if you need to send info about client certificate to the OAuth server. IncludesecretName
andsecretKey
too
Root CA for the OAuth server should be placed to the Kubernetes Secret in the same namespace as logging-operator.
Then you should set the name of the Secret to the ca.secretName
parameter and the key (name of the file with
the certificate in the Secret) to the ca.secretKey
parameter.
Client certificate and private key can be set the similar way as CA to cert
and key
parameters respectively.
You might use them if you need to support mTLS connection with the client verification.