Pomerium v0.33.4 配置参数详解

Pomerium v0.33.4 的 config.yaml 关键参数分组解析,每组附实测验证方法与真实日志回显。

Pomerium零信任OIDCIAM2026/10/21

Pomerium v0.33.4 配置参数详解

Pomerium 的全部行为都由一份 config.yaml(或等价的环境变量)驱动。本文以 v0.33.4 为基准,按功能分组解析关键参数,每组均附实测验证方法与真实日志/回显。实测环境:Ubuntu 22.04.5(deb 包 + systemd,all-in-one 模式),IdP 为自建 Dex(OIDC),上游为一个静态页服务,对外域名使用 *.localhost.pomerium.io 测试域与自签证书。

配置体系与加载方式

Pomerium 支持三种等价的配置来源,优先级从高到低:环境变量(POMERIUM_ 前缀 + 参数名大写)、配置文件(--config /etc/pomerium/config.yaml)、内置默认值。配置文件改动后重启服务生效(systemctl restart pomerium),启动日志会输出配置装载记录:

{"level":"info","service":"all","config":"local","checksum":"e1e9418a288cd18a","message":"config: updated config"}

两个实测要点:

  • 未知参数会被显式告警。实测把已废弃的 headers: 写进配置,日志明确输出 "key":"headers",...,"message":"unknown config option"——配置拼写错误不会被静默吞掉。

  • 参数校验失败会直接拒绝启动。实测将 shared_secret 写成非法 base64(x):

    Error: config: options from config file "/tmp/bad.yaml": validation error config: invalid shared secret: illegal base64 data at input byte 0
    {"level":"fatal","error":"config: ... invalid shared secret ...","message":"cmd/pomerium"}
    

    服务以非零码退出,systemd 会记录 status=1/FAILURE。

全局与服务组参数

参数说明实测要点
address数据面监听地址(HTTPS),如 :443决定 proxy/authenticate 的对外端口;与域名是否带端口强相关(见下)
insecure_servertrue 时以明文 HTTP 运行实测改为 true + address: :80 后服务正常 active,仅用于本地试验,生产禁用
shared_secret各服务组件间加密通信的共享密钥head -c32 /dev/urandom | base64 生成;格式非法直接拒绝启动(见上)
cookie_secret会话 cookie 的加密密钥同上,32 字节 base64;泄露等于会话体系沦陷
certificates手动指定证书/私钥文件实测 - cert: /etc/pomerium/cert.pem, key: /etc/pomerium/key.pem;私钥必须对 pomerium 运行用户可读,否则启动失败(见安装篇故障一)
autocertLet's Encrypt 自动签发需要对外 443 可达且域名真实解析,本地实验不可用(前置条件,未实测)
metrics_addressPrometheus 指标端口实测 :9090,curl :9090/metrics 返回标准 Prometheus 文本
services服务角色拆分(默认 all-in-one)不配置即四服务同进程;拆分部署时按进程分别指定

一个容易踩的坑:authenticate_service_url 必须与用户实际访问 authenticate 的地址逐字符一致(协议/域名/端口)。实测中监听 :8443 而回调 URL 不带端口时,IdP 侧回调校验与浏览器跳转都会失败。凡是文档中出现 https://authenticate.localhost.pomerium.io 的示例,其隐含前提是 443 端口监听;改用非标端口时务必写成 https://...:8443 并同步修改 IdP 的回调地址。

身份提供方(IdP)组参数

Pomerium 自身不管理用户,认证完全委托 IdP。核心参数:

idp_provider: oidc          # google / azure / okta / auth0 / github / gitlab / onelogin / oidc / saml / dex 等
idp_client_id: pomerium
idp_client_secret: <secret>
idp_provider_url: http://10.89.62.10:5556

实测说明:

  • idp_provider: oidc 配合任意标准 OIDC 提供方(本文用 Dex:staticClients 中注册 client,回调地址填 https://authenticate.localhost.pomerium.io:8443/oauth2/callback)。

  • 回调地址必须与 authenticate_service_url 一致,并且是 IdP 侧 client 配置的 redirectURIs 之一,否则 IdP 拒绝回调。

  • IdP 不可达时的典型日志(实测):

    {"level":"error","error":"...context canceled...","message":"leaser lease error"}
    

    并伴随目录同步(storage/sync-querier: synced latest records,record-type 为 pomerium.io/DirectoryUser 等)停滞。

  • 完整的认证跳转链在实测日志中依次为:authorize check → allow-why-false:["user-unauthenticated"](数据面 302)→ /.pomerium/sign_in → IdP 授权页 → /oauth2/callback → idp-token-session-creator.CreateSession succeeded。

排障提示:实测中曾出现 token 交换成功(CreateSession succeeded)但随即 authenticate: session load error: session is not found 的现象,最终请求回到错误页。已确认排除证书权限、端口不一致、/tmp noexec、IdP 回调拼写四个因素。遇到同类问题时建议依次检查:系统时钟(token 校验强依赖)、databroker 存储目录(TMPDIR/数据盘)可写性、多副本部署时 databroker 是否共享同一后端,并抓取 callback 请求的 request-id 对照日志。

路由(routes)与策略(policy)参数

路由是 Pomerium 配置的主体,每条路由描述"一个对外域名 → 一个上游服务 + 一组策略":

routes:
  - from: https://verify.localhost.pomerium.io   # 对外域名(必须 HTTPS scheme)
    to: http://10.89.62.20:8080                  # 上游真实服务
    policy:                                      # PPL 策略,逐条 allow/deny
      - allow:
          or:
            - email:
                is: admin@example.com
    pass_identity_headers: true                  # 向上游注入 X-Pomerium-Claim-* 身份头

实测验证方式(未认证请求):

$ curl -skI https://verify.localhost.pomerium.io:8443/
HTTP/2 302
location: https://authenticate.localhost.pomerium.io:8443/.pomerium/sign_in?...
server: envoy

authorize 服务同时输出判定细节,allow-why-false: ["user-unauthenticated"] 直白地解释了拒绝原因——这类"解释性日志"是 Pomerium 排障体验最好的部分。登录会话建立后,同一请求将命中 to 上游并返回应用内容,同时(pass_identity_headers: true 时)携带 X-Pomerium-Claim-Email 等身份头。

PPL 策略常用条件(官方 reference):email(is/contains)、domain(is)、groups(has)、claims/<name>、reject 否定分支;and/or/not 可组合嵌套。策略写在配置文件中随 Git 管理,是"策略即代码"的落点。

响应头与会话组参数

  • set_response_headers(顶层 map):为所有经过数据面的响应注入自定义头。实测:

    set_response_headers:
      X-Frame-Options: DENY
      X-Content-Type-Options: nosniff
    

    重启后 curl -I 确认 x-frame-options: DENY、x-content-type-options: nosniff 生效。注意:旧参数名 headers 在 v0.33 中已不存在(实测 unknown config option)。

  • 会话生命周期(官方 reference 常用项):cookie_lifetime(默认 14h)、idle_timeout、cookie_name(默认 _pomerium)等,按需覆盖;cookie 相关密钥即 cookie_secret。实测会话 cookie 由 authenticate 服务在回调成功时签发(_pomerium_authenticate),未登录访问仅存在短时的 PKCE/CSRF 辅助 cookie(_pomerium_pkce_<id>,Path 限定在 /oauth2/callback)。

内置端点速查

端点用途实测回显
/healthz健康检查OK(HTTP 200)
/ping就绪检查OK(HTTP 200)
/.well-known/pomerium/发现端点返回 issuer、authentication_callback_endpoint、jwks_uri、frontchannel_logout_uri
/.well-known/pomerium/jwks.json令牌验签公钥{"keys":[{"kty":"EC","crv":"P-256","alg":"ES256",...}]}
metrics_address/metricsPrometheus 指标# HELP go_gc_duration_seconds ...(go_* 与 envoy 指标)

高频错误速查表

报错根因处置
invalid shared secret: illegal base64密钥非合法 base64用 head -c32 /dev/urandom | base64 重新生成
open /etc/pomerium/key.pem: permission denied证书私钥对 pomerium 用户不可读chown pomerium:pomerium key.pem
fork/exec /tmp/pomerium-envoy*/envoy: permission deniedTMPDIR 挂载了 noexecEnvironment=TMPDIR=/var/lib/pomerium(drop-in)+ 建目录授权
unknown config option参数名拼写错误或已改名(如 headers → set_response_headers)对照官方 reference 修正
session load error: session is not found回调时会话记录读取失败检查时钟、databroker 存储、回调地址一致性(见 IdP 组)
回调后 IdP 报 redirect_uri 错误IdP 侧回调与 authenticate_service_url 不一致逐字符对齐协议/域名/端口

小结

Pomerium 的配置面可以概括为"全局密钥 + IdP + routes + 可选增强"四层:密钥层决定服务间与会话安全,IdP 层决定认证入口,routes 层是日常运维改动最频繁的地方,其余参数(metrics、响应头、会话生命周期)按需叠加。实测中,配置错误都会以显式日志暴露(unknown option / validation error),配合结构化日志的 request-id 与 allow-why 判定,排障路径是清晰的。下一篇将走进命令行,实测 pomerium 主命令与各子命令的用法。