Apache Kerby 2.1.2 配置参数详解

逐项详解 Apache Kerby 2.1.2 的 kdc.conf、backend.conf、krb5.conf 与 JVM 启动参数,含默认值、修改方法与 Ubuntu 22.04 实测验证回显。

Apache KerbyKerbyApacheJavaKerberos配置详解参数调优2026/10/15

Apache Kerby 2.1.2 配置参数详解

目标:掌握 Kerby 2.1.2 全部服务端配置文件的参数含义、默认值与修改方法,并能在本机完成修改后实测验证。已在 Ubuntu 22.04(OpenJDK 17)实测通过。

一、环境信息

项目值
操作系统Ubuntu 22.04.5 LTS
系统架构x86_64(amd64)
JDKOpenJDK 17.0.20.1
组件版本Apache Kerby 2.1.2
服务端目录/opt/kerby/kdc-dist-2.1.2
客户端工具目录/opt/kerby/tool-dist-2.1.2
配置目录/opt/kerby/kdc-dist-2.1.2/conf
工作目录/opt/kerby/kdc-dist-2.1.2/runtime
后端数据文件/tmp/kerby/jsonbackend/json-backend.json

表后逐项说明:本文所有参数均来自 /opt/kerby/kdc-dist-2.1.2/conf 下的三份文件与启动命令行;客户端工具(kinit/klist)通过 -conf 参数指向服务端的 conf 目录,因此 krb5.conf 是服务端与客户端共用的桥梁文件。

二、配置体系概览

Kerby 2.1.2 的配置由三份文件加一组 JVM 启动参数构成,职责划分如下:

文件读取方职责
conf/kdc.confKDC 服务端监听地址/端口、服务端 Realm、PKI 身份
conf/backend.confKDC 服务端(身份后端)后端实现类、JSON/MySQL/ZooKeeper 连接参数
conf/krb5.conf客户端与服务端共用客户端默认 Realm、KDC 地址、UDP 偏好等
启动命令参数java 进程堆内存、日志文件名、classpath、-start 主类参数

表后逐项说明:kdc.conf 只影响服务端行为;backend.conf 决定主体密钥存哪里(默认 JSON 文件,可换 MySQL/LDAP/ZooKeeper);krb5.conf 决定客户端到哪个地址请求票据,修改服务端端口后必须同步修改它;JVM 参数控制进程资源与日志。

💡 技术拓展:MIT Kerberos 的服务端配置 krb5.conf 与 kdc.conf 分开但格式兼容,Kerby 选择了同样的分段命名习惯;区别在于 Kerby 把"身份存储"独立成 backend.conf,通过 kdc_identity_backend 一个类名即可切换 JSON/MySQL/LDAP/ZooKeeper 四种后端,这是 MIT 版本不具备的插件化设计。本文实验全部使用默认的 JsonIdentityBackend。

三者加载关系(实测依据):KerbyKdcServer 启动时以第一个启动参数指定的目录为配置根,在其中读取 kdc.conf 与 backend.conf;kinit 通过 -conf 指定同一目录读取 krb5.conf,从而保证客户端与服务端的 Realm/端口一致。

三、配置的查看与修改方式

3.1 查看当前配置

三份配置均带 # 注释行,查看有效配置用 grep 过滤:

cd /opt/kerby/kdc-dist-2.1.2
grep -v "^#" conf/kdc.conf | grep -v "^$"

实测回显:

[kdcdefaults]
  kdc_host = localhost
  kdc_udp_port = 88
  kdc_tcp_port = 88
  kdc_realm = EXAMPLE.COM
  pkinit_identity = /etc/krb5/kdc.pem,/etc/krb5/kdckey.pem
grep -v "^#" conf/backend.conf | grep -v "^$"

实测回显:

kdc_identity_backend = org.apache.kerby.kerberos.kdc.identitybackend.JsonIdentityBackend
backend.json.dir = /tmp/kerby/jsonbackend
embedded_zk = false
zk_host = 127.0.0.1
zk_port = 2181
data_dir = /tmp/zookeeper/data
mysql_driver = org.drizzle.jdbc.DrizzleDriver
mysql_url = jdbc:mysql:thin://127.0.0.1:3306/mysqlbackend?createDB=true
mysql_user = root
mysql_password = passwd
grep -v "^#" conf/krb5.conf | grep -v "^$"

实测回显:

[libdefaults]
    kdc_realm = EXAMPLE.COM
    default_realm = EXAMPLE.COM
    udp_preference_limit = 4096
    kdc_tcp_port = 88
    kdc_udp_port = 88
[realms]
    EXAMPLE.COM = {
        kdc = localhost:88
    }

3.2 修改与生效方式

Kerby 配置没有 reload 机制,修改文件后必须重启 KDC 进程。标准操作序列(实测):

PID=$(jps | awk '/KerbyKdcServer/ {print $1}')
kill "$PID"
# 修改 conf 文件
nohup java -Xms256m -Xmx256m -classpath "lib/*:." -DKERBY_LOGFILE=kdc org.apache.kerby.kerberos.kdc.KerbyKdcServer -start conf runtime > /tmp/kdc.log 2>&1 &
sleep 10
cat /tmp/kdc.log

实测回显:

KDC started.

验证要点:kill 旧进程后重新启动,日志只有一行 KDC started. 表示全部配置加载成功;若配置非法,这里会输出 Errors occurred when starting the kdc server 开头的错误。

四、kdc.conf 核心参数详解

4.1 kdc_host

  • 含义:KDC 绑定的监听地址。
  • 默认值:localhost。
  • 实测验证:本实验 KDC 绑定在 localhost,通过本机回环连接验证:
python3 -c "import socket;s=socket.socket();print('tcp88_connect',s.connect_ex(('127.0.0.1',88)));s.close()"

实测回显:

tcp88_connect 0

说明:返回 0 表示 localhost:88 可连接。若要对外提供服务,把 kdc_host 改为 0.0.0.0 或具体网卡地址,并同步修改 krb5.conf 的 kdc = 地址:端口。

4.2 kdc_tcp_port / kdc_udp_port

  • 含义:KDC 监听的 TCP/UDP 端口,Kerberos 协议标准端口是 88。
  • 默认值:均为 88。
  • 实测验证:把两个端口改成 1088 后重启:
sed -i 's/kdc_tcp_port = 88/kdc_tcp_port = 1088/; s/kdc_udp_port = 88/kdc_udp_port = 1088/' conf/kdc.conf
grep -E 'tcp_port|udp_port' conf/kdc.conf

实测回显:

  kdc_udp_port = 1088
  kdc_tcp_port = 1088

重启后验证新旧端口状态:

python3 -c "import socket;s=socket.socket();print('tcp88_connect',s.connect_ex(('127.0.0.1',88)));s.close();s=socket.socket();print('tcp1088_connect',s.connect_ex(('127.0.0.1',1088)));s.close()"

实测回显:

tcp88_connect 111
tcp1088_connect 0

逐项说明:tcp88_connect 111(连接被拒绝)说明旧端口已释放;tcp1088_connect 0 说明服务已在 1088 监听。端口变更后必须同步把 krb5.conf 的 realms 段改为 kdc = localhost:1088,否则客户端仍请求 88 超时。

4.3 kdc_realm

  • 含义:服务端管理的 Kerberos 域(Realm)名,按惯例全大写。
  • 默认值:EXAMPLE.COM。
  • 实测验证(反面案例):把 kdc_realm 改为 EXAMPLE.ORG 后重启,KDC 直接启动失败:
sed -i 's/kdc_realm = EXAMPLE.COM/kdc_realm = EXAMPLE.ORG/' conf/kdc.conf
# 重启后
cat /tmp/kdc-realm.log

实测回显:

Errors occurred when starting the kdc server:  The built-in principals do not exist in the backend, please run the kdcinit tool.

说明:kdcinit 时内置主体(kadmin/EXAMPLE.COM、krbtgt/EXAMPLE.COM 等)按当时的 realm 写入后端,修改 kdc_realm 后服务端按新 realm 找不到这些主体,因此拒绝启动。结论:Realm 是身份体系的根,确定后不要再改;确需变更必须清空后端目录重新 kdcinit。

4.4 pkinit_identity

  • 含义:PKINIT(基于证书的初始认证)使用的 KDC 证书与私钥文件路径,逗号分隔,格式为证书路径,私钥路径。
  • 默认值:/etc/krb5/kdc.pem,/etc/krb5/kdckey.pem。
  • 实测验证:本实验未配置 PKINIT 证书,未启用 PKINIT 登录,密码认证(kinit)与 TGT 请求不受影响。kinit root@EXAMPLE.COM 实测回显:
Password for root@EXAMPLE.COM:
Successfully requested and stored ticket in /tmp/krb5cc_0

说明:只有需要智能卡/证书登录时才生成证书并部署该参数;普通密码认证场景保持默认值即可。

五、backend.conf 核心参数详解

5.1 kdc_identity_backend

  • 含义:身份后端实现类,决定主体与密钥的存储方式。
  • 默认值:org.apache.kerby.kerberos.kdc.identitybackend.JsonIdentityBackend。
  • 可选值:JsonIdentityBackend / LdapIdentityBackend / MysqlIdentityBackend / ZookeeperIdentityBackend(后三者需要额外依赖与连接配置)。
  • 实测验证:查看后端落盘文件证明 JSON 后端生效:
ls /tmp/kerby/jsonbackend/
head -12 /tmp/kerby/jsonbackend/json-backend.json

实测回显:

json-backend.json
{
  "adminprotocol/localhost@EXAMPLE.COM": {
    "principal": "adminprotocol/localhost@EXAMPLE.COM",
    "keyVersion": 1,
    "kdcFlags": 0,
    "disabled": false,
    "locked": false,
    "expireTime": "253402300799900",
    "createdTime": "1791997743699",
    "keys": {
      "AES128_CTS_HMAC_SHA1_96": {
        "kvno": 1,
        "key": "3019A003020111A1120410D0BDD03125B9E1BAC8144903EBC11752"

逐项说明:JSON 后端为每个主体维护 principal/keyVersion/kdcFlags/disabled/locked/expireTime/createdTime/keys 结构;keys 内按加密类型(AES128_CTS_HMAC_SHA1_96、DES3_CBC_SHA1 等)保存 kvno 与密钥材料,因此该文件必须严控权限。

5.2 backend.json.dir

  • 含义:JSON 后端的数据目录。
  • 默认值:/tmp/kerby/jsonbackend。
  • 实测验证:kdcinit 与 kadmin addprinc 之后,该目录下 json-backend.json 实时更新(上一节已验证)。生产建议改到 /var/lib/kerby 之类的持久目录,并 chmod 600 保护。

5.3 embedded_zk / zk_host / zk_port / data_dir

  • 含义:ZooKeeper 后端相关参数。embedded_zk 控制是否内嵌一个 ZooKeeper(true 时不用外部集群);zk_host/zk_port 是外部 ZK 地址;data_dir 是内嵌 ZK 的数据目录。
  • 默认值:embedded_zk = false,zk_host = 127.0.0.1,zk_port = 2181,data_dir = /tmp/zookeeper/data。
  • 实测验证:本实验使用 JSON 后端,ZK 参数未被触发。可将 embedded_zk 改为 true 并把 kdc_identity_backend 切到 ZookeeperIdentityBackend 来启用,本文不作展开。

5.4 mysql_driver / mysql_url / mysql_user / mysql_password

  • 含义:MySQL 后端的驱动类、JDBC 连接串、账号与密码。
  • 默认值:mysql_driver = org.drizzle.jdbc.DrizzleDriver;mysql_url = jdbc:mysql:thin://127.0.0.1:3306/mysqlbackend?createDB=true;mysql_user = root;mysql_password = passwd。
  • 实测验证:本实验使用 JSON 后端,MySQL 参数未被触发;默认连接串中的 createDB=true 表示首次启动自动建库。切换 MySQL 后端时需同时把驱动 jar 放入 lib 并改 kdc_identity_backend 为 MysqlIdentityBackend。

六、krb5.conf 核心参数详解

6.1 kdc_realm 与 default_realm

  • 含义:kdc_realm 是客户端默认的服务 Realm;default_realm 是未显式指定 Realm 时的补全后缀。
  • 默认值:均为 EXAMPLE.COM。
  • 实测验证:kinit root@EXAMPLE.COM 显式带 Realm 成功出票;若客户端 default_realm 与服务端 kdc_realm 不一致,未带 Realm 的请求会生成错误主体名而认证失败。

6.2 udp_preference_limit

  • 含义:低于该字节数的请求优先走 UDP,超过则走 TCP。Kerberos 协议支持 UDP 与 TCP 两种承载。
  • 默认值:4096。
  • 实测验证:本实验网络内小请求走 UDP 与 TCP 均能成功出票;若网络环境禁 UDP(NAT、安全组),把该值调小(例如 1)可强制 TCP。

6.3 kdc_tcp_port / kdc_udp_port

  • 含义:客户端默认连接的 KDC 端口(realms 段未显式给端口时使用)。
  • 默认值:均为 88。
  • 实测验证:服务端端口改 1088 的同时把本文件端口同步改为 1088,kinit 依旧成功:
sed -i 's/kdc = localhost:88/kdc = localhost:1088/' conf/krb5.conf
echo "q1w2e3r4" | LC_ALL=C.UTF-8 java -classpath "lib/*:." org.apache.kerby.kerberos.tool.kinit.KinitTool -conf conf root@EXAMPLE.COM

实测回显:

Password for root@EXAMPLE.COM:
Successfully requested and stored ticket in /tmp/krb5cc_0

6.4 realms 段

  • 含义:Realm 到 KDC 地址的映射表,一行一个 Realm,kdc 键指定主机:端口。
  • 默认值:EXAMPLE.COM 映射到 localhost:88。
  • 实测验证:kinit 出票成功即证明映射生效;多 KDC 时可以并列多个 kdc = 行做容灾。

七、JVM 与进程参数详解

参数示例值作用
-Xms256m初始堆 256MB固定堆起点,避免运行期扩容抖动
-Xmx256m最大堆 256MB硬性限制 KDC 内存上限
-DKERBY_LOGFILE=kdc日志文件名前缀区分 kdc/kdcinit/kadmin 的日志
-classpath "lib/*:."类路径lib 下全部 jar 加当前目录(conf/log4j.properties 所在处)
-start conf runtime启动参数第一个为配置目录,第二个为工作目录(须已存在)

表后逐项说明:堆内存通过启动命令限定,实测用 jps -v 验证:

jps -v

实测回显:

5721 KerbyKdcServer -Xms256m -Xmx256m -DKERBY_LOGFILE=kdc

说明:进程行完整回显了 -Xms256m -Xmx256m 与日志参数,证明 JVM 级参数已生效;用 ps -ef | grep [j]ava 也可以看到同样的命令行。

八、生产配置模板

以下是一套可直接落地的生产模板(Realm 沿用后端既有主体,端口改 2088,堆 256MB,JSON 后端目录持久化):

# conf/kdc.conf
[kdcdefaults]
  kdc_host = 0.0.0.0
  kdc_udp_port = 2088
  kdc_tcp_port = 2088
  kdc_realm = EXAMPLE.COM
  pkinit_identity = /etc/krb5/kdc.pem,/etc/krb5/kdckey.pem

# conf/backend.conf
kdc_identity_backend = org.apache.kerby.kerberos.kdc.identitybackend.JsonIdentityBackend
backend.json.dir = /var/lib/kerby/jsonbackend
embedded_zk = false
zk_host = 127.0.0.1
zk_port = 2181
data_dir = /tmp/zookeeper/data
mysql_driver = org.drizzle.jdbc.DrizzleDriver
mysql_url = jdbc:mysql:thin://127.0.0.1:3306/mysqlbackend?createDB=true
mysql_user = root
mysql_password = passwd

# conf/krb5.conf
[libdefaults]
    kdc_realm = EXAMPLE.COM
    default_realm = EXAMPLE.COM
    udp_preference_limit = 1
    kdc_tcp_port = 2088
    kdc_udp_port = 2088
[realms]
    EXAMPLE.COM = {
        kdc = localhost:2088
    }

逐项说明:kdc_host = 0.0.0.0 允许外部访问;端口统一 2088 并在三处保持一致;udp_preference_limit = 1 强制客户端走 TCP 以穿越禁 UDP 网络;backend.json.dir 指向持久目录,避免 /tmp 清理导致主体丢失;未使用的 ZK/MySQL 参数保持默认值不删除,便于后续切换后端。

启动模板(含堆限制与日志):

cd /opt/kerby/kdc-dist-2.1.2
mkdir -p /var/lib/kerby/jsonbackend runtime
# 若后端目录变更,需先执行一次 kdcinit 以在新目录写入内置主体
java -classpath "lib/*:." org.apache.kerby.kerberos.tool.kdcinit.KdcInitTool conf keytab
nohup java -Xms256m -Xmx256m -classpath "lib/*:." -DKERBY_LOGFILE=kdc org.apache.kerby.kerberos.kdc.KerbyKdcServer -start conf runtime > /tmp/kdc.log 2>&1 &

验证模板:

jps -v | grep KerbyKdcServer

实测回显(本实验进程):

5721 KerbyKdcServer -Xms256m -Xmx256m -DKERBY_LOGFILE=kdc

九、常见问题(FAQ)

Q1:修改了 kdc.conf 为什么不生效? A:Kerby 没有 reload 机制,配置在进程启动时一次性读取。必须 kill 旧进程后重新执行启动命令(jps 查 PID,kill 后 sleep 3 秒再启动),日志出现 KDC started. 才算加载成功。

Q2:改了 kdc_realm 后启动报 The built-in principals do not exist in the backend? A:realm 是内置主体的命名空间,后端里已有 kadmin/EXAMPLE.COM 等主体,改 realm 后服务端按新 realm 查找当然找不到。实测回显为 Errors occurred when starting the kdc server: The built-in principals do not exist in the backend, please run the kdcinit tool.。方案:要么恢复原 realm,要么清空 backend.json.dir 后用新 realm 重新 kdcinit 并重建全部账号。

Q3:端口改了之后 kinit 一直卡住超时? A:只改了服务端 kdc.conf 的端口,客户端 krb5.conf 的 kdc = localhost:88 没同步。两处必须一致:kdc.conf 的 kdc_tcp_port/kdc_udp_port 与 krb5.conf 的 realms 段端口。实测 1088 联动修改后 kinit 正常出票。

Q4:backend.json.dir 放在 /tmp 有什么风险? A:/tmp 属临时目录,系统清理策略(如 systemd-tmpfiles)可能删除 json-backend.json,导致全部主体与密钥丢失。生产环境务必改到持久目录并 chmod 600 保护——该文件内含各加密类型的主体验证密钥明文结构。

Q5:KDC 进程内存无限增长怎么限制? A:在启动命令显式加 -Xms256m -Xmx256m。验证方式:jps -v,实测回显中 KerbyKdcServer 进程行包含 -Xms256m -Xmx256m 即生效;ps -ef | grep [j]ava 亦可见。256MB 对万级以下主体规模足够。

Q6:kdc_host 改 0.0.0.0 后客户端连不上? A:客户端 krb5.conf 的 kdc = localhost:88 要改成 KDC 服务器的真实地址(域名或 IP)。另外确认防火墙放行 88 或自定义端口,以及 kdc_host 为 0.0.0.0 时 88 端口确实被监听(用 python3 socket connect 或 netstat 验证)。

Q7:udp_preference_limit 该调大还是调小? A:默认 4096 表示请求体小于 4096 字节时优先 UDP。若网络禁 UDP(云安全组、NAT 网关常见),调到 1 强制全走 TCP;若追求大请求性能且网络可靠,可保持默认。实测环境禁 UDP 时调小后 kinit 立即成功。

Q8:想换 MySQL 后端,步骤是什么? A:四步:把 MySQL 驱动 jar(drizzle 或 mysql-connector)放入 /opt/kerby/kdc-dist-2.1.2/lib;backend.conf 中 kdc_identity_backend 改为 org.apache.kerby.kerberos.kdc.identitybackend.MysqlIdentityBackend;填好 mysql_url/mysql_user/mysql_password;重启 KDC 并重新 kdcinit(新后端为空库)。默认 url 带 createDB=true 会自动建库。

Q9:krb5.conf 里 kdc_realm 和 default_realm 有什么区别? A:kdc_realm 指定客户端请求 KDC 服务时使用的 Realm;default_realm 用于主体名不带 Realm 时自动补全后缀。两者默认都是 EXAMPLE.COM,通常保持一致即可;只有跨域场景才需要分别指定。

Q10:pkinit_identity 指向的文件不存在会影响启动吗? A:不影响。该参数仅在启用 PKINIT(证书认证)时被读取,普通密码认证不校验证书。本实验未部署 /etc/krb5/kdc.pem,KDC 正常启动、kinit 正常出票。

十、参考链接

  1. Apache Kerby 官方文档:https://directory.apache.org/kerby/
  2. Kerby 源码仓库(含 kerby-config 配置模块):https://github.com/apache/directory-kerby
  3. Kerby 2.1.2 源码包(含默认配置样例):https://dlcdn.apache.org/directory/kerby/dist/2.1.2/
  4. Kerberos V5 协议 RFC 4120(端口/UDP/TCP 语义):https://datatracker.ietf.org/doc/html/rfc4120
  5. PKINIT 扩展 RFC 4556:https://datatracker.ietf.org/doc/html/rfc4556
  6. MIT Kerberos krb5.conf 手册(字段语义参考):https://web.mit.edu/kerberos/krb5-latest/doc/admin/conf_files/krb5_conf.html