[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]: # ({e94370cd-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\. 映射一个易记的主机名（可选，用于本地测试）。

编辑 /etc/hosts，如果没有 DNS，则为您的 DC 和 web 服务器添加一条记录：

```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 映射，以便 hostname→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（调整 `DocumentRoot` / 指向您的 Zabbix UI 的路径）：

```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 前端中启用 HTTP 认证（ui/conf/zabbix.conf.php）：

```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 定时器以避免过期：

```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` 中的域映射。

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

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

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

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

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

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