[comment]: # ({930fae3b-930fae3b})
# 13 使用 Zabbix 配置 Kerberos 监控

[comment]: # ({/930fae3b-930fae3b})

[comment]: # ({bfbefd40-5be9f534})
#### 概述

Kerberos 身份验证可用于 Zabbix 中的 web 监测和 HTTP 监控项。

本页介绍了一个示例：在 Debian/Ubuntu 上为 Zabbix 服务器配置 Kerberos，使其能够使用 Zabbix 进程的 Kerberos principal 对 `www.example.com` 执行 web 监测。

[comment]: # ({/bfbefd40-5be9f534})

[comment]: # ({825c7996-edb96e72})
#### 配置

1\. 安装 KDC 和客户端工具：

```bash
sudo apt update
sudo apt install krb5-kdc krb5-admin-server krb5-user
```

在软件包设置过程中按提示回答，例如：

```default
Default Kerberos version 5 realm: EXAMPLE.COM
Kerberos servers for your realm: localhost (or your FQDN)
Administrative server for your Kerberos realm: localhost (or your FQDN)
```

2\. 映射一个友好的主机名（可选，用于本地测试）。

如果没有 DNS，请编辑 /etc/hosts 并为你的 DC 和 webserver 添加一条记录：

```bash
sudo vi /etc/hosts
```

你可以添加的示例行：

```ini
192.168.1.100  dc01.example.com dc01
```

3\. 配置 Kerberos 客户端和 KDC realm：

```bash
sudo vi /etc/krb5.conf
```

示例设置：

```ini
[libdefaults]
    default_realm = EXAMPLE.COM
    dns_lookup_realm = false
    dns_lookup_kdc = false
    rdns = false
    ticket_lifetime = 24h
    renew_lifetime = 7d
    forwardable = true

[realms]
    EXAMPLE.COM = {
        kdc = dc01.example.com
        admin_server = dc01.example.com
    }

[domain_realm]
    .example.com = EXAMPLE.COM
    example.com = EXAMPLE.COM
```

如果你计划使用 `.localdomain` 或其他非公开名称，请添加明确的 domain→realm 映射，以便主机名→realm 映射能够正常工作。
这里不匹配会导致 `Server not found in Kerberos database` 错误。

4\. 初始化 Kerberos 数据库（仅需一次，在 KDC 主机上）。
出现提示时设置一个安全的主密码：

```bash
sudo krb5_newrealm
```

5\. 使用客户端将实际使用的主机名创建 `HTTP/host.fqdn@REALM` principal；建议使用小写（例如 `HTTP/web.example.com@EXAMPLE.COM`）。
大小写/名称不匹配会导致 `Server not found in Kerberos database`。

```bash
sudo kadmin.local
```

在 `kadmin.local` 中：

```bash
addprinc kerb-admin@EXAMPLE.COM     # administrative principal
addprinc -randkey HTTP/dc01.example.com@EXAMPLE.COM
ktadd -k /etc/apache2/http.keytab HTTP/dc01.example.com@EXAMPLE.COM
quit
```

将 keytab 移动到 web 主机（如果是同一台机器则可保留本地），并设置 Apache 可用的权限：

```bash
chown www-data:www-data /etc/apache2/http.keytab
chmod 600 /etc/apache2/http.keytab
# verify
sudo -u www-data -k /etc/apache2/http.keytab
```

6\. 安装并启用 Apache GSSAPI 模块：

```bash
sudo apt install libapache2-mod-auth-gssapi
sudo a2enmod auth_gssapi
sudo a2enmod headers
sudo systemctl restart apache2
```

:::noteimportant
并非所有 mod_auth_gssapi 版本都支持每一条 `Gssapi*` 指令。
如果 Apache 因 `Invalid command 'GssapiCredStore'` 失败，请移除不受支持的指令或升级该模块。
:::

7\. 配置 VirtualHost（根据你的 Zabbix UI 调整 `DocumentRoot` / 路径）：

```bash
sudo vi /etc/apache2/sites-available/zabbix.conf
```

在 `zabbix.conf` 中：

```apache
<VirtualHost *:80>
    ServerName dc01.example.com
    DocumentRoot /usr/share/zabbix/ui
    <Directory /usr/share/zabbix/ui>
        Options FollowSymLinks
        AllowOverride None
        Require all granted
        AuthType GSSAPI
        AuthName "Kerberos Login"
        GssapiCredStore keytab:/etc/apache2/http.keytab
        GssapiLocalName On
        Require valid-user
    </Directory>
    RequestHeader set X-Remote-User %{REMOTE_USER}s env=REMOTE_USER
    RequestHeader unset Authorization
</VirtualHost>
```

重启 Apache：

```bash
sudo systemctl restart apache2
```

8\. 启用/启动 KDC 服务并验证监听端口（KDC 主机）：

```bash
sudo systemctl enable --now krb5-kdc krb5-admin-server
ss -tnlp | grep :80    # or: sudo netstat -tnlp | grep :80
```

9\. 获取一个 TGT 进行测试（以将使用该票据的用户身份运行）。

你应当在票据列表中看到 `krbtgt/EXAMPLE.COM@EXAMPLE.COM`。
请以需要该票据的同一个 OS 用户运行 `kinit`（例如，Web 检查使用 `zabbix`，或交互式浏览器 SSO 测试使用 `www-data`/Apache）。
发给不同 OS 用户的票据不会可见，除非调整 `KRB5CCNAME` 和权限。

```bash
kinit kerb-admin@EXAMPLE.COM
klist
```

10\. 使用 curl 测试 SPNEGO 交换（从具有有效 TGT 的客户端执行）。
返回 `200 OK`（或重定向到应用）表示 SPNEGO 成功：

```bash
curl -v --negotiate -u : http://dc01.example.com/
```

11\. 可选地，如果 Zabbix UI 应接受 HTTP 认证登录，请在 Zabbix 前端（ui/conf/zabbix.conf.php）中启用 HTTP 认证：

```php
$ALLOW_HTTP_AUTH = true;
```

在 web UI 中进入 *Users* > *Authentication*，并切换到 [*HTTP settings*](/manual/web_interface/frontend_sections/users/authentication/http) 选项卡。
勾选 *Enable HTTP authentication* 复选框，并在弹窗中点击 *Ok*。
在 *Default login form* 下拉框中选择 "HTTP login form"。
根据你的目录策略决定 *Case-sensitive login* 是否合适。
点击 *Update* 按钮完成。

12\. 浏览器配置（以 Firefox 为例）：将 `network.negotiate-auth.trusted-uris` 设置为执行 Negotiate 的主机（`dc01.example.com`），这样浏览器会自动发送 Kerberos 令牌。

在 `about:config` 中：

```default
network.negotiate-auth.trusted-uris = dc01.example.com
```

现在访问 `http://dc01.example.com` 应该会直接登录到 Zabbix，而不会显示表单。

13\. 保持密钥/票据更新。
Kerberos 票据的默认有效期约为 10 小时。
添加 cron/systemd timer 以避免过期：

```bash
#for the web service
kinit -kt /etc/apache2/http.keytab HTTP/dc01.example.com@EXAMPLE.COM
#for the monitoring user
kinit -kt /var/lib/zabbix/kerb.keytab kerb-admin@EXAMPLE.COM
```

14\. 日常检查：

-   `klist -k /etc/apache2/http.keytab` — 验证 keytab 中是否存在服务 principal。
-   `sudo tail -f /var/log/apache2/error.log` — 监视 GSSAPI 错误（`gss_acquire_cred[_from]() failed to get server creds` 表示 keytab/权限问题或缺少 principal）。
-   `curl --negotiate` 返回 401/403 通常表示 principal 错误、没有票据、Host 头不匹配，或文件系统权限问题；请检查日志和 `/etc/krb5.conf` 中的 domain 映射。

[comment]: # ({/825c7996-edb96e72})

[comment]: # ({32287407-notes})
#### 安全与文件权限说明

keytab 文件必须只能由需要它们的账户读取。  
权限示例：zabbix 用户的 keytab 可设置为归属 `zabbix:zabbix` 且权限为 `0400`，Apache 的 keytab 可设置为权限 `0440` 且归属 `root:www-data`。

避免在主机上存储长期有效的明文密码。  
尽可能使用 keytab 或已加入域的机器主体。

在运行设置 `KRB5CCNAME` 或复制 keytab 的测试或脚本时，操作完成后请再次检查所有权和权限——web 服务器拒绝凭据通常是文件权限问题。

[comment]: # ({/32287407-notes})
