配置认证代理身份验证
您可以将 Grafana 配置为让 HTTP 反向代理处理身份验证。流行的 Web 服务器具有非常广泛的插件式身份验证模块列表,并且任何模块都可以与 AuthProxy 功能一起使用。以下详细介绍了 auth proxy 的配置选项。
[auth.proxy]
# Defaults to false, but set to true to enable this feature
enabled = true
# HTTP Header name that will contain the username or email
header_name = X-WEBAUTH-USER
# HTTP Header property, defaults to `username` but can also be `email`
header_property = username
# Set to `true` to enable auto sign up of users who do not exist in Grafana DB. Defaults to `true`.
auto_sign_up = true
# Define cache time to live in minutes
# If combined with Grafana LDAP integration it is also the sync interval
# Set to 0 to always fetch and sync the latest user data
sync_ttl = 15
# Limit where auth proxy requests come from by configuring a list of IP addresses.
# This can be used to prevent users spoofing the X-WEBAUTH-USER header.
# Example `whitelist = 192.168.1.1, 192.168.1.0/24, 2001::23, 2001::0/120`
whitelist =
# Optionally define more headers to sync other user attributes
# Example `headers = Name:X-WEBAUTH-NAME Role:X-WEBAUTH-ROLE Email:X-WEBAUTH-EMAIL Groups:X-WEBAUTH-GROUPS`
headers =
# Non-ASCII strings in header values are encoded using quoted-printable encoding
;headers_encoded = false
# Check out docs on this for more details on the below setting
enable_login_token = false
通过 curl 与 Grafana 的 AuthProxy 交互
curl -H "X-WEBAUTH-USER: admin" https://127.0.0.1:3000/api/users
[
{
"id":1,
"name":"",
"login":"admin",
"email":"admin@localhost",
"isAdmin":true
}
]
然后,我们可以发送第二个请求到 /api/user
方法,该方法将返回已登录用户的详细信息。我们将使用此请求来展示 Grafana 如何自动将指定的用户添加到系统中。在这里,我们创建了一个名为“anthony”的新用户。
curl -H "X-WEBAUTH-USER: anthony" https://127.0.0.1:3000/api/user
{
"email":"anthony",
"name":"",
"login":"anthony",
"theme":"",
"orgId":1,
"isGrafanaAdmin":false
}
使 Apache 的身份验证与 Grafana 的 AuthProxy 一起工作
我将演示如何使用 Apache 进行用户认证。在这个例子中,我们使用基于 Apache 文本文件的认证处理器 BasicAuth,即 htpasswd 文件。然而,任何可用的 Apache 身份验证功能都可以使用。
Apache BasicAuth
在这个例子中,我们将 Apache 作为 Grafana 后端服务的反向代理使用。Apache 在将请求转发到 Grafana 后端服务之前处理用户的身份验证。
Apache 配置
<VirtualHost *:80>
ServerAdmin webmaster@authproxy
ServerName authproxy
ErrorLog "logs/authproxy-error_log"
CustomLog "logs/authproxy-access_log" common
<Proxy *>
AuthType Basic
AuthName GrafanaAuthProxy
AuthBasicProvider file
AuthUserFile /etc/apache2/grafana_htpasswd
Require valid-user
RewriteEngine On
RewriteRule .* - [E=PROXY_USER:%{LA-U:REMOTE_USER},NS]
RequestHeader set X-WEBAUTH-USER "%{PROXY_USER}e"
</Proxy>
RequestHeader unset Authorization
ProxyRequests Off
ProxyPass / https://127.0.0.1:3000/
ProxyPassReverse / https://127.0.0.1:3000/
</VirtualHost>
虚拟主机配置的前四行是标准的,因此我们不会详细介绍它们的作用。
我们使用一个 <proxy> 配置块来将我们的身份验证规则应用到每个代理请求。这些规则包括在 /etc/apache2/grafana_htpasswd 文件中存储用户名和密码时要求基本身份验证。此文件可以使用
htpasswd
命令创建。配置的下一部分是难点。我们使用 Apache 的重写引擎来创建我们的 X-WEBAUTH-USER header,其中包含已验证的用户。
RewriteRule .* - [E=PROXY_USER:%{LA-U:REMOTE_USER}, NS]:这是一行有点魔法。它所做的,是为每个请求使用 rewriteEngines 的 look-ahead(LA-U)功能来确定在处理请求后 REMOTE_USER 变量将被设置为什么值。然后将结果分配给变量 PROXY_USER。这是必要的,因为 REMOTE_USER 变量不可用于 RequestHeader 函数。
RequestHeader set X-WEBAUTH-USER “%{PROXY_USER}e”:现在,已验证的用户名已存储在 PROXY_USER 变量中,我们创建一个新的 HTTP 请求头,它将包含用户名发送到我们的后端 Grafana。
RequestHeader unset Authorization 在将 HTTP 请求转发到 Grafana 之前从 HTTP 请求中删除 Authorization 头。这确保 Grafana 不会尝试使用这些凭据对用户进行身份验证(BasicAuth 是 Grafana 中的支持的身份验证处理器)。
最后 3 行只是标准的反向代理配置,将所有已验证请求定向到运行在端口 3000 的 Grafana 服务器。
使用 Docker 完整说明。
对于这个例子,我们使用 Docker Hub 上可用的官方 Grafana Docker 图像,地址为 Docker Hub。
- 创建一个包含以下内容的文件
grafana.ini
[users]
allow_sign_up = false
auto_assign_org = true
auto_assign_org_role = Editor
[auth.proxy]
enabled = true
header_name = X-WEBAUTH-USER
header_property = username
auto_sign_up = true
启动 Grafana 容器,使用我们的自定义 grafana.ini 来替换 /etc/grafana/grafana.ini
。我们不会为此容器暴露任何端口,因为它将只通过我们的 Apache 容器连接。
docker run -i -v $(pwd)/grafana.ini:/etc/grafana/grafana.ini --name grafana grafana/grafana
Apache 容器
对于这个例子,我们使用 Docker Hub 上可用的官方 Apache Docker 图像,地址为 Docker Hub。
- 创建一个包含以下内容的文件
httpd.conf
ServerRoot "/usr/local/apache2"
Listen 80
LoadModule mpm_event_module modules/mod_mpm_event.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule env_module modules/mod_env.so
LoadModule headers_module modules/mod_headers.so
LoadModule unixd_module modules/mod_unixd.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
<IfModule unixd_module>
User daemon
Group daemon
</IfModule>
ServerAdmin [email protected]
<Directory />
AllowOverride none
Require all denied
</Directory>
DocumentRoot "/usr/local/apache2/htdocs"
ErrorLog /proc/self/fd/2
LogLevel error
<IfModule log_config_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
<IfModule logio_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
</IfModule>
CustomLog /proc/self/fd/1 common
</IfModule>
<Proxy *>
AuthType Basic
AuthName GrafanaAuthProxy
AuthBasicProvider file
AuthUserFile /tmp/htpasswd
Require valid-user
RewriteEngine On
RewriteRule .* - [E=PROXY_USER:%{LA-U:REMOTE_USER},NS]
RequestHeader set X-WEBAUTH-USER "%{PROXY_USER}e"
</Proxy>
RequestHeader unset Authorization
ProxyRequests Off
ProxyPass / http://grafana:3000/
ProxyPassReverse / http://grafana:3000/
创建一个 htpasswd 文件。我们创建了一个名为 anthony 的新用户,密码为 password。
htpasswd -bc htpasswd anthony password
使用我们的自定义 httpd.conf 和 htpasswd 文件启动 httpd 容器。该容器将监听端口 80,我们创建一个链接到 grafana 容器,以便该容器可以解析主机名 grafana 到 Grafana 容器的 IP 地址。
docker run -i -p 80:80 --link grafana:grafana -v $(pwd)/httpd.conf:/usr/local/apache2/conf/httpd.conf -v $(pwd)/htpasswd:/tmp/htpasswd httpd:2.4
使用 Grafana。
我们的Grafana和Apache容器运行后,您现在可以连接到 https://127.0.0.1/ 并使用我们在htpasswd文件中创建的用户名/密码登录。
注意
如果用户从Grafana中删除,则用户将无法登录和重新同步,直到sync_ttl
已过期。
团队同步(仅企业版)
仅适用于Grafana企业版v6.3及以上版本
使用团队同步,您可以在您的身份验证提供者和Grafana之间设置同步。您可以发送Grafana值作为HTTP头的一部分,并让Grafana将其映射到您的团队结构。这允许您自动将用户放入特定的团队。
为了支持此功能,认证代理允许可选头映射额外的用户属性。支持团队同步的具体属性是 Groups
。
# Optionally define more headers to sync other user attributes
headers = "Groups:X-WEBAUTH-GROUPS"
您使用 X-WEBAUTH-GROUPS
头发送每个用户的团队信息。具体来说,是用户所属的Grafana组ID集。
首先,我们需要设置您的身份验证提供者和Grafana之间的映射。按照 以下说明 将组添加到Grafana中的团队。
完成这些后,您可以通过查询API验证您的映射。
# First, inspect your teams and obtain the corresponding ID of the team we want to inspect the groups for.
curl -H "X-WEBAUTH-USER: admin" -H "X-WEBAUTH-GROUPS: lokiteamOnExternalSystem" https://127.0.0.1:3000/api/teams/search
{
"totalCount": 2,
"teams": [
{
"id": 1,
"orgId": 1,
"name": "Core",
"email": "[email protected]",
"avatarUrl": "/avatar/327a5353552d2dc3966e2e646908f540",
"memberCount": 1,
"permission": 0
},
{
"id": 2,
"orgId": 1,
"name": "Loki",
"email": "[email protected]",
"avatarUrl": "/avatar/102f937d5344d33fdb37b65d430f36ef",
"memberCount": 0,
"permission": 0
}
],
"page": 1,
"perPage": 1000
}
# Then, query the groups for that particular team. In our case, the Loki team which has an ID of "2".
curl -H "X-WEBAUTH-USER: admin" -H "X-WEBAUTH-GROUPS: lokiteamOnExternalSystem" https://127.0.0.1:3000/api/teams/2/groups
[
{
"orgId": 1,
"teamId": 2,
"groupId": "lokiTeamOnExternalSystem"
}
]
最后,每当Grafana收到带有 X-WEBAUTH-GROUPS: lokiTeamOnExternalSystem
头的请求时,正在认证的用户将被放入指定的团队。通过使用逗号分隔的值支持在多个团队中放置,例如 lokiTeamOnExternalSystem,CoreTeamOnExternalSystem
。
curl -H "X-WEBAUTH-USER: leonard" -H "X-WEBAUTH-GROUPS: lokiteamOnExternalSystem" https://127.0.0.1:3000/dashboards/home
{
"meta": {
"isHome": true,
"canSave": false,
...
}
这样,用户 leonard
将作为Grafana认证的一部分自动放入Loki团队。
注意
空的X-WEBAUTH-GROUPS
或缺少组头将使用户从所有团队中移除。
登录令牌和会话cookie
将 enable_login_token
设置为 true
后,Grafana将在认证代理头验证成功后,为用户分配一个登录令牌和cookie。您只需配置您的认证代理以提供 /login 路由的头部。通过其他路由的请求将使用cookie进行认证。
使用 [auth]
下的设置 login_maximum_inactive_lifetime_duration
和 login_maximum_lifetime_duration
来控制会话寿命。