Pomerium v0.33.4 配置参数详解
Pomerium v0.33.4 的 config.yaml 关键参数分组解析,每组附实测验证方法与真实日志回显。
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_server | true 时以明文 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 运行用户可读,否则启动失败(见安装篇故障一) |
autocert | Let's Encrypt 自动签发 | 需要对外 443 可达且域名真实解析,本地实验不可用(前置条件,未实测) |
metrics_address | Prometheus 指标端口 | 实测 :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的现象,最终请求回到错误页。已确认排除证书权限、端口不一致、/tmpnoexec、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/metrics | Prometheus 指标 | # 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 denied | TMPDIR 挂载了 noexec | Environment=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 主命令与各子命令的用法。