ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Kanidm 服务器配置与部署指南:server.toml 全参数解析、容器启动与管理员账户初始化

Kanidm 服务器配置与部署指南:server.toml 全参数解析、容器启动与管理员账户初始化
  • 后端
  • 认证鉴权
  • 安全

【免费下载链接】kanidm

Kanidm: A simple, secure, and fast identity management platform

项目地址:https://gitcode.com/gh_mirrors/ka/kanidm
点击查看免费下载

Kanidm 是一个以简单、安全、快速为目标的身份管理平台。本文基于 book/src/server_configuration.md 编写,围绕服务器实例的完整上线流程展开:从server.toml的两种配置方式与每个参数的含义,到用configtest校验配置、启动容器、使用NET_BIND_SERVICE能力绑定低端口,再到初始化admin/idm_admin双管理员账户。读完本文,你将掌握 Kanidm 服务器从零到可用的全部配置与运维要点,并能结合源码理解每个配置项的底层行为。

前置条件:本文的docker run命令假定你已按照 评估快速上手 创建了名为kanidmd的 Docker 数据卷(volume),用于持久化/data目录中的数据库、TLS 证书和配置文件。若尚未完成,请先阅读该文档(其中包含拉取镜像、创建卷、kanidmd cert-generate生成评估证书等步骤)。

两种配置方式:配置文件与环境变量

Kanidm 服务器(二进制名kanidmd)支持两种并列的配置方式:

  1. 在数据卷中提供server.toml配置文件。容器内默认路径为/data/server.toml,启动时服务器会自动加载它(docker run -p 443:8443 -v kanidmd:/data kanidm/server:latest这类命令即依赖此默认路径)。
  2. 使用环境变量指定配置项。将配置项名称大写,并加上KANIDM_前缀即可,例如KANIDM_DOMAIN、KANIDM_ORIGIN、KANIDM_LOG_LEVEL。

两种方式可以单独使用,也可以混合使用;环境变量的优先级高于配置文件中的同名选项。

[!WARNING]domain、origin、tls_chain、tls_key四个选项是必须设置的(无论用文件还是环境变量),否则服务器无法启动!

从源码看,这种“文件为底、环境变量覆盖”的机制是这样实现的:proto/src/cli.rs 中定义了一个全局的KanidmdCli结构体,每个字段都通过 clap 的env = "KANIDM_..."属性绑定到对应环境变量(例如KANIDM_DOMAIN、KANIDM_ORIGIN、KANIDM_DB_PATH、KANIDM_TLS_CHAIN、KANIDM_TLS_KEY、KANIDM_BINDADDRESS、KANIDM_LDAPBINDADDRESS、KANIDM_ONLINE_BACKUP_PATH等);而 server/core/src/config.rs 中的ConfigurationBuilder::add_cli_config会把这些 CLI/环境变量值覆盖到最终配置上。配置合并的完整优先级为:命令行参数 > 环境变量 > server.toml 文件 > 内置默认值。完整选项说明可查阅你所用构建版本的kanidmd_core::config::ServerConfig的 rustdoc 文档(本文仓库中对应 server/core/src/config.rs)。

另外,配置文件路径本身也可以由KANIDM_CONFIG环境变量或-c参数指定(见 server/daemon/src/opt.rs 中KanidmdParser的定义),默认值为/data/server.toml。

server.toml 参数逐项详解

以下是官方提供的带注释示例配置(完整文件见 examples/server_container.toml,另有面向 Linux 原生部署的 examples/server.toml 可作为对照)。

# The server configuration file version. version = "2" # The webserver bind address. Requires TLS certificates. # If the port is set to 443 you may require the # NET_BIND_SERVICE capability. This accepts a single address # or an array of addresses to listen on. # Defaults to "127.0.0.1:8443" bindaddress = "0.0.0.0:8443" # # The read-only ldap server bind address. Requires # TLS certificates. If set to 636 you may require the # NET_BIND_SERVICE capability. This accepts a single address # or an array of addresses to listen on. # Defaults to "" (disabled) # ldapbindaddress = "0.0.0.0:3636" # # The path to the kanidm database. db_path = "/data/kanidm.db" # # If you have a known filesystem, kanidm can tune the # database page size to match. Valid choices are: # [zfs, other] # If you are unsure about this leave it as the default # (other). After changing this # value you must run a vacuum task. # - zfs: # * sets database pagesize to 64k. You must set # recordsize=64k on the zfs filesystem. # - other: # * sets database pagesize to 4k, matching most # filesystems block sizes. # db_fs_type = "zfs" # # The number of entries to store in the in-memory cache. # Minimum value is 256. If unset # an automatic heuristic is used to scale this. # You should only adjust this value if you experience # memory pressure on your system. # db_arc_size = 2048 # # TLS chain and key in pem format. Both must be present. # If the server receives a SIGHUP, these files will be # re-read and reloaded if their content is valid. tls_chain = "/data/chain.pem" tls_key = "/data/key.pem" # The path where entry migrations will be read from. # This path should contain files that match the pattern # xx-name.json where xx are two number. For example: # 00-base.json # 10-groups.json # Migrations are applied in order. Migrations that fail # to apply, or have invalid syntax are skipped without # preventing server start up or reload. # migration_path = "/data/migrations.d" # # The log level of the server. May be one of info, debug, trace # # NOTE: this can be overridden by the environment variable # `KANIDM_LOG_LEVEL` at runtime # Defaults to "info" # log_level = "info" # # The DNS domain name of the server. This is used in a # number of security-critical contexts # such as webauthn, so it *must* match your DNS # hostname. It is used to create # security principal names such as `william@idm.example.com` # so that in a (future) trust configuration it is possible # to have unique Security Principal Names (spns) throughout # the topology. # # ⚠️ WARNING ⚠️ # # Changing this value WILL break many types of registered # credentials for accounts including but not limited to # webauthn, oauth tokens, and more. # If you change this value you *must* run # `kanidmd domain rename` immediately after. domain = "idm.example.com" # # The origin for webauthn. This is the url to the server, # with the port included if it is non-standard (any port # except 443). This must match or be a descendent of the # domain name you configure above. If these two items are # not consistent, the server WILL refuse to start! # origin = "https://idm.example.com" # # OR # origin = "https://idm.example.com:8443" origin = "https://idm.example.com" # HTTPS requests can be reverse proxied by a loadbalancer. # To preserve the original IP of the caller, these systems # will often add a header such as "Forwarded" or # "X-Forwarded-For". Some other proxies can use the PROXY # protocol v2 header. While we support the PROXY protocol # v1 header, we STRONGLY discourage its use as it has # significantly greater overheads compared to v2 during # processing. # This setting allows configuration of the list of trusted # IPs or IP ranges which can supply this header information, # and which format the information is provided in. # Defaults to "none" (no trusted sources) # Only one option can be used at a time. # [http_client_address_info] # proxy-v2 = ["127.0.0.1", "127.0.0.0/8"] # # OR # [http_client_address_info] # x-forward-for = ["127.0.0.1", "127.0.0.0/8"] # # OR # [http_client_address_info] # # AVOID IF POSSIBLE!!! # proxy-v1 = ["127.0.0.1", "127.0.0.0/8"] # LDAPS requests can be reverse proxied by a loadbalancer. # To preserve the original IP of the caller, these systems # can add a header such as the PROXY protocol v2 header. # While we support the PROXY protocol v1 header, we STRONGLY # discourage its use as it has significantly greater # overheads compared to v2 during processing. # This setting allows configuration of the list of trusted # IPs or IP ranges which can supply this header information, # and which format the information is provided in. # Defaults to "none" (no trusted sources) # [ldap_client_address_info] # proxy-v2 = ["127.0.0.1", "127.0.0.0/8"] # # OR # [ldap_client_address_info] # # AVOID IF POSSIBLE!!! # proxy-v1 = ["127.0.0.1", "127.0.0.0/8"] [online_backup] # The path to the output folder for online backups path = "/data/kanidm/backups/" # The schedule to run online backups (see https://crontab.guru/) # every day at 22:00 UTC (default) schedule = "00 22 * * *" # four times a day at 3 minutes past the hour, every 6th hours # schedule = "03 */6 * * *" # We also support non standard cron syntax, with the following format: # sec min hour day of month month day of week year # (it's very similar to the standard cron syntax, it just allows to specify the seconds # at the beginning and the year at the end) # Number of backups to keep (default 7) # versions = 7

核心参数速查表

参数含义默认值是否必填
version配置文件版本号,当前为"2";缺失时按旧版(legacy)配置解析"2"推荐显式声明
domainDNS 域名,用于生成 Security Principal Name(SPN,如william@idm.example.com)、WebAuthn 等安全关键上下文无必填
origin面向用户的 HTTPS URL;非 443 端口时需显式包含端口(如https://idm.example.com:8443);必须是domain本身或其子域,否则服务器拒绝启动无必填
tls_chain/tls_keyPEM 格式的 TLS 证书链与私钥路径,两者必须同时存在;收到 SIGHUP 时会在内容有效的情况下重新读取并热加载无必填
bindaddressHTTPS 监听地址,可写单个地址或地址数组(如["[::]:443", "0.0.0.0:443"]);端口为 443 时可能需要NET_BIND_SERVICE"127.0.0.1:8443"否
ldapbindaddress只读 LDAPS 监听地址,同样支持数组;不设置则禁用 LDAP""(禁用)否
db_pathKanidm 数据库文件路径无(不设置时为内存库)否
db_fs_type数据库页大小调优:zfs(页大小 64k,需在 ZFS 上设置recordsize=64k)或other(页大小 4k);修改后必须执行 vacuum才能生效other否
db_arc_size内存缓存条目数,最小 256;不设置时按启发式自动伸缩,仅在遇到内存压力时才建议手动调整自动否
migration_path条目迁移文件目录,文件需匹配xx-name.json(两位数字前缀,如00-base.json);按顺序应用,失败或语法无效的迁移会被跳过而不影响启动/重载无否
log_level日志级别:info、debug、trace;可在运行时被KANIDM_LOG_LEVEL覆盖info否
http_server_versions服务器提供的 HTTP 协议版本:all(HTTP/2 + HTTP/1)、1、2all否
http_client_address_info/ldap_client_address_info反向代理场景下的客户端地址信息来源与可信 IP/CIDR 列表,支持proxy-v2、x-forward-for、proxy-v1(官方强烈不建议用proxy-v1,处理开销显著大于 v2);默认none(无可信来源),三者只能同时启用其一none否
online_backup在线备份配置(见下方小节)默认启用否
adminbindpath本地管理 socket 路径,用于执行部分服务器控制任务;按构建目标自动设置默认值构建期确定否
thread_count异步工作线程池上限可用 CPU 核数否
maximum_request_size_bytes最大请求体大小(字节)256 KiB否
replication复制配置(开发特性,尚未达到生产就绪状态)关闭否
otel_grpc_endpointOpenTelemetry gRPC 收集器地址(如localhost:4317),不设置则关闭该特性关闭否

关于version字段:源码 server/core/src/config.rs 中的ServerConfigUntagged::new会先解析配置版本:显式version = "2"走ServerConfigV2(支持数组形式的绑定地址、http_client_address_info等新字段),否则按旧版ServerConfig解析。因此新部署建议始终显式声明version = "2"。

绑定地址的语义

  • bindaddress默认是127.0.0.1:8443(见 proto/src/constants.rs 中的DEFAULT_SERVER_ADDRESS),只监听本机回环地址。要让外部设备访问,必须改成0.0.0.0、[::]或具体网卡地址。
  • 若端口小于 1024(如443、636),在 Docker 内需要NET_BIND_SERVICE能力(见下文)。
  • 示例 examples/server.toml 展示了多地址数组写法,例如同时监听 IPv6 与 IPv4:bindaddress = ["[::]:443", "0.0.0.0:443"]。源码中bindaddress与ldapbindaddress通过serde_as(as = "Option<OneOrMany<_, PreferOne>>")解析(见 server/core/src/config.rs 的ServerConfigV2),因此单个字符串和数组两种写法都合法。

domain 与 origin 的严格约束

这是 Kanidm 配置里最容易出错、也最影响安全的两项:

  • 一致性要求:origin必须等于domain或为其子域,两者不一致时服务器拒绝启动。
  • 安全关键上下文:domain用于生成 SPN、绑定 WebAuthn 凭据、签发 OAuth2 token 等。修改domain会破坏已注册的 WebAuthn、OAuth token 等大量凭据,因此必须立即执行kanidmd domain rename(流程见 book/src/domain_rename.md:先docker stop,再改domain/origin,执行kanidmd domain rename -c /data/server.toml,最后启动)。
  • 选域建议:域名一经启用就很难更换,选错还有凭据钓鱼、会话泄露等安全风险。更详尽的选域指南见 book/src/choosing_a_domain_name.md。

反向代理场景的客户端地址

当 HTTPS/LDAPS 请求经过负载均衡器反向代理时,为保留调用方原始 IP,可在http_client_address_info/ldap_client_address_info中声明受信任的来源 IP 或 CIDR 范围,以及这些来源提供信息所用的格式:

  • proxy-v2:PROXY 协议 v2 头,推荐;
  • x-forward-for:X-Forwarded-For头(仅 HTTPS 支持);
  • proxy-v1:PROXY 协议 v1 头,尽量避免——处理开销显著高于 v2。

三者在同一节中只能启用其一;默认none表示没有任何受信任来源。源码 server/core/src/config.rs 中的HttpAddressInfo/LdapAddressInfo枚举对应上述取值,并提供了 IP/CIDR 白名单匹配能力(AddressSet::contains),只有命中白名单的代理来源提供的头信息才会被采信。

在线备份(online_backup)

[online_backup]小节控制由kanidmd server进程在线定期执行的自动备份(详见 book/src/backup_and_restore.md 的“Method 1 - Automatic Backup”):

  • path:备份输出目录;不设置时默认取db_path所在目录(源码见 server/core/src/config.rsConfigurationBuilder::finish的兜底逻辑)。
  • schedule:cron 表达式,默认每日 22:00 UTC("00 22 * * *")。除标准 cron 语法外,还支持扩展语法:sec min hour day-of-month month day-of-week year(秒在开头、年在末尾)。例如1 2 3 5 12 * 2023表示仅在 2023 年 12 月 5 日 03:02:01 备份一次;3 2 1 * * Mon *表示每个周一 03:02:01 备份。
  • versions:保留的备份版本数,默认 7。
  • compression:压缩方式gzip(默认)或nocompression。

注意:examples/server_container.toml未启用compression,而 examples/server.toml 中显式写了compression = "gzip"(默认值),二者等价。

校验配置:configtest

在正式启动前,建议先用configtest子命令验证配置是否合法。该命令会加载配置但不启动网络监听,适合在容器环境下快速检查。默认使用-c /data/server.toml(即我们在 评估快速上手 中创建的kanidmd卷中的配置):

docker run --rm -i -t -v kanidmd:/data \ kanidm/server:latest /sbin/kanidmd configtest

从源码看,configtest是 server/daemon/src/opt.rs 中KanidmdOpt::ConfigTest定义的子命令(“Test the IDM Server configuration, without starting network listeners”)。配置加载与校验的核心逻辑位于 server/core/src/config.rs 的ServerConfigUntagged::new(解析 TOML 并识别版本)与ConfigurationBuilder::finish(校验必填项)。finish中会强制检查:TLS 私钥与证书链必须同时存在、domain必须已设置、origin必须已设置,任一缺失都会打印ERROR: ...并返回None,这正是文档中“四个必填项缺失则服务器无法启动”的底层实现。

启动服务器

配置校验通过后,即可启动容器对外提供服务。容器默认读取/data/server.toml:

docker run -p 443:8443 -v kanidmd:/data kanidm/server:latest

该命令将宿主机的 443 端口映射到容器内bindaddress所监听的 8443 端口。注意:-p 443:8443是端口映射,容器内的bindaddress端口保持 8443 即可;若你想让容器直接占用宿主机的特权端口,则属于下面的NET_BIND_SERVICE场景。

使用 NET_BIND_SERVICE 能力

如果你打算不使用 Docker 端口映射或反向代理,而是让服务器进程直接绑定宿主机的低端口(bindaddress或ldapbindaddress的端口小于1024,如443/636),就需要为容器附加NET_BIND_SERVICE能力:

docker run --cap-add NET_BIND_SERVICE \ --network [host OR macvlan OR ipvlan] \ -v kanidmd:/data \ kanidm/server:latest
  • --cap-add NET_BIND_SERVICE:授予容器绑定特权端口的能力;
  • --network host(或macvlan/ipvlan):让容器直接使用宿主网络,端口映射不再适用。

[!TIP] 无论你最终选择哪种方式启动服务器,都应记录并妥善保存你所用的 docker run / docker create 命令。该命令在后续升级流程中会被再次使用(升级步骤见 book/src/server_updates.md)。

更多启动后的运维命令

容器镜像中kanidmd二进制提供了丰富的运维子命令(定义见 server/daemon/src/opt.rs),与配置直接相关的常见操作包括:

  • kanidmd database backup / restore:手动备份与恢复(见 book/src/backup_and_restore.md);
  • kanidmd database vacuum:回收未用页面,并可在修改db_fs_type后真正变更数据库页大小;
  • kanidmd database reindex:在添加自定义 schema 索引后强制重建索引(触发日志通常形如Index EQUALITY name not found);
  • kanidmd domain rename:更换域后的必需步骤。

初始化默认管理员账户

服务器启动后,需要初始化两个并行且职能分离的管理员账户:

账户职能
admin管理 Kanidm 自身的系统配置(域、TLS 等系统级设置)
idm_admin管理 Kanidm 中的账户与组(人员、组等业务实体)

这两个账户应被视为“break-glass”(应急破窗)账户:它们的存在是为了让服务器能够完成引导(bootstrap),并在紧急情况下提供访问入口,不适合日常使用。日常管理请创建并使用普通账户。

初始化方式是为每个账户生成新的随机密码。必须以与 kanidmd 进程相同的用户身份或 root 身份执行(容器场景下即进入容器执行),默认使用-c /data/server.toml:

docker exec -i -t <container name> \ kanidmd recover-account admin # new_password: "xjgG4..."
docker exec -i -t <container name> \ kanidmd recover-account idm_admin # new_password: "9Eux1..."

执行后命令行会输出新的随机密码(如上注释所示),请妥善保存。recover-account子命令的定义同样位于 server/daemon/src/opt.rs,其核心逻辑由 server/core/src/admin.rs 的RecoverAccount管理任务实现——它会重置目标账户的凭据并生成新密码,这也意味着它可以用于“恢复”被锁定的账户(与此相对的是disable-account子命令,可禁用账户且可用recover-account复位)。

拿到密码后,即可按照 评估快速上手 的后续步骤安装客户端工具并登录(kanidm login --name idm_admin),开始创建你自己的账户与组。

常见问题与排错要点

  • 服务器拒绝启动,报 TLS/domain/origin 相关错误:domain、origin、tls_chain、tls_key四项必须全部提供;origin必须是domain或其后代(子域)。用kanidmd configtest可快速定位。
  • 外部设备无法访问:确认bindaddress不是默认的127.0.0.1:8443,需改为0.0.0.0/[::]等可外部访问的地址;若走端口映射(-p 443:8443),容器内保持 8443 即可。
  • 低端口绑定失败(Permission denied):端口小于 1024 时需要--cap-add NET_BIND_SERVICE,并配合--network host/macvlan/ipvlan。
  • 修改 domain 后凭据失效:domain变更会破坏已注册的 WebAuthn、OAuth token 等凭据,必须紧接着执行kanidmd domain rename,并提前制定 WebAuthn 失效应对计划(参见 book/src/domain_rename.md)。
  • 内存压力:可下调db_arc_size(最小 256);正常情况下建议保持自动伸缩。
  • 修改 db_fs_type 后未生效:修改后必须执行kanidmd database vacuum才会应用新的页大小。

总结

本文完整走通了 Kanidm 服务器上线的主干流程:通过server.toml或KANIDM_*环境变量(两者可混用,环境变量优先)配置domain、origin、TLS 证书与监听地址;用configtest在启动前校验配置;以 Docker 容器方式启动服务并按需附加NET_BIND_SERVICE能力;最后通过recover-account初始化admin与idm_admin两个应急管理员。文中每个参数的行为与必填约束均可追溯到 server/core/src/config.rs 的解析与校验实现。下一步可参考 book/src/administration.md 进行日常管理,或阅读 book/src/backup_and_restore.md 配置自动备份以保障数据安全。

  • 后端
  • 认证鉴权
  • 安全

【免费下载链接】kanidm

Kanidm: A simple, secure, and fast identity management platform

项目地址:https://gitcode.com/gh_mirrors/ka/kanidm
点击查看免费下载

相关推荐

上一篇:Sonic架构深度剖析:理解扩散模型在视频生成中的应用
下一篇:React DayPicker 的 PreviousMonthButton 组件:源码解析与自定义导航按钮实战

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进