配置 auth 代理身份验证
您可以配置 Grafana,使其允许 HTTP 反向代理处理身份验证。流行的 Web 服务器有非常广泛的可插拔身份验证模块列表,其中任何一个都可以与 AuthProxy 功能一起使用。下面我们详细介绍 auth 代理的配置选项。
[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://:3000/api/users
[
{
"id":1,
"name":"",
"login":"admin",
"email":"admin@localhost",
"isAdmin":true
}
]
然后我们可以向 /api/user
方法发送第二个请求,该方法将返回已登录用户的详细信息。我们将使用此请求来展示 Grafana 如何自动将我们指定的新用户添加到系统中。在这里,我们创建一个名为“anthony”的新用户。
curl -H "X-WEBAUTH-USER: anthony" https://:3000/api/user
{
"email":"anthony",
"name":"",
"login":"anthony",
"theme":"",
"orgId":1,
"isGrafanaAdmin":false
}
使 Apache 的身份验证与 Grafana 的 AuthProxy 协同工作
我将演示如何使用 Apache 进行用户身份验证。在此示例中,我们将 BasicAuth 与 Apache 基于文本文件的身份验证处理程序(即 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://:3000/
ProxyPassReverse / https://:3000/
</VirtualHost>
virtualhost 配置的前四行是标准的,因此我们不会详细介绍它们的作用。
我们使用一个 <proxy> 配置块将身份验证规则应用于每个代理请求。这些规则包括要求基本身份验证,其中 user:password 凭据存储在 /etc/apache2/grafana_htpasswd 文件中。可以使用
htpasswd
命令创建此文件。配置的下一部分是棘手的部分。我们使用 Apache 的重写引擎来创建我们的 X-WEBAUTH-USER 头部,并填充经过身份验证的用户。
RewriteRule .* - [E=PROXY_USER:%{LA-U:REMOTE_USER}, NS]:这一行有点神奇。它所做的是,对于每个请求,使用重写引擎的预读 (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 之前移除 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 you@example.com
<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,密码为 passwordhtpasswd -bc htpasswd anthony password
使用我们的自定义
httpd.conf
和我们的htpasswd
文件启动 Apache HTTP 服务器容器。容器将监听端口 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:/// 并使用我们在 htpasswd
文件中创建的用户名和密码登录。
注意
如果用户从 Grafana 中被删除,则在
sync_ttl
过期后,该用户才能登录并重新同步。
团队同步(仅限 Enterprise 版)
仅在 Grafana Enterprise v6.3+ 中可用
通过团队同步,可以设置身份验证提供程序中的团队与 Grafana 之间的同步。您可以将 Grafana 值作为 HTTP 头部的一部分发送,并让 Grafana 将其映射到您的团队结构。这允许您自动将用户添加到特定的团队中。
为了支持该功能,auth 代理允许使用可选头部映射附加用户属性。支持团队同步的特定属性是 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://:3000/api/teams/search
{
"totalCount": 2,
"teams": [
{
"id": 1,
"orgId": 1,
"name": "Core",
"email": "core@grafana.com",
"avatarUrl": "/avatar/327a5353552d2dc3966e2e646908f540",
"memberCount": 1,
"permission": 0
},
{
"id": 2,
"orgId": 1,
"name": "Loki",
"email": "loki@grafana.com",
"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://: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://:3000/dashboards/home
{
"meta": {
"isHome": true,
"canSave": false,
...
}
这样,用户 leonard
将作为 Grafana 身份验证的一部分自动放置到 Loki 团队中。
注意
空的
X-WEBAUTH-GROUPS
或不存在 groups 头部将从所有团队中移除该用户。
登录令牌和会话 cookie
如果将 enable_login_token
设置为 true
,Grafana 在 auth 代理头部验证成功后,将为用户分配一个登录令牌和 cookie。您只需要配置您的 auth 代理为 /login 路由提供头部。通过其他路由的请求将使用 cookie 进行身份验证。
使用 [auth]
下的 login_maximum_inactive_lifetime_duration
和 login_maximum_lifetime_duration
设置来控制会话生命周期。