Pomerium不能当普通反向代理用,因其核心是身份感知:必须完成认证授权、注入可信身份头(如X-Forwarded-User)、强制HTTPS上游、校验JWT签名与aud/iss,并需适配gRPC及开发降级等特殊配置。

为什么不能直接把 Pomerium 当成普通反向代理用?
Pomerium 的核心设计目标不是替代 nginx 或 traefik,而是做「身份感知」——它必须在请求到达你的 Go 微服务前,完成认证、授权,并把用户身份信息(如 email、groups)以可信头(X-Pomerium-Jwt-Assertion、X-Forwarded-User 等)注入请求。如果你只是把它当透明代理配,Go 服务收不到用户身份,等于白搭。
- 默认不透传原始 Host 头,
Host会被改写为 Pomerium 的路由域名,微服务里r.Host不再是你期望的入口域名 -
X-Forwarded-For和X-Forwarded-Proto需显式开启,否则 Go 的r.TLS判断和日志 IP 会出错 - Pomerium 要求上游服务(你的 Go 微服务)必须支持 HTTPS(或明确配置
insecure_upstream),否则健康检查失败,路由直接不可用
Go 微服务里怎么安全读取 Pomerium 注入的身份头?
别直接信 r.Header.Get("X-Forwarded-User") —— 这个头可能被客户端伪造。Pomerium 提供两种验证方式:JWT 断言签名验证,或 TLS 客户端证书双向认证。推荐前者,更轻量。
- 从
X-Pomerium-Jwt-Assertion取 JWT 字符串,用 Pomerium 配置里的shared_secret(或公钥)校验签名和有效期 - 不要解析 JWT 后就信任
email字段,必须检查aud(应匹配你服务的policy中定义的to地址)和iss(必须是你的 Pomerium 域名) - 示例关键逻辑:
token, _ := jwt.ParseSigned(r.Header.Get("X-Pomerium-Jwt-Assertion")) if err := token.UnsafeVerify("HS256", []byte(os.Getenv("POMERIUM_SHARED_SECRET"))); err != nil { /* 拒绝 */ } - 如果用了 OIDC provider(如 Google),JWT 中的
groups是数组,但 Pomerium 默认只传第一个 group;需在 policy 中加allow_groups并确保 upstream 配置启用了pass_identity_headers: true
如何让 Pomerium 正确转发 gRPC 请求到 Go 微服务?
gRPC over HTTP/2 会被 Pomerium 默认拦截或降级。它不是开箱即用的 gRPC 代理,需要显式适配。
Colly 是一个用于 Go 语言的快速开源爬取和爬虫框架。它适用于从简单的页面提取到异步爬虫处理大量页面集合,支持请求回调和结构化解析。
- 在 Pomerium 的
policy中必须设置tls_skip_verify: true(仅限测试)或提供上游服务的合法证书路径,否则 gRPC 连接建立失败 - Go 微服务的 gRPC server 必须监听
http.Server上的h2c(HTTP/2 without TLS),或启用 TLS 并在 Pomerium 配置中指定upstream_tls_server_name - Pomerium 的
from地址必须带grpc://前缀(如grpc://api.example.com),否则它按 HTTP/1.1 处理,导致content-type: application/grpc被丢弃 - HTTP/2 流控参数(如
MaxConcurrentStreams)由 Pomerium 控制,Go 侧无法覆盖;若出现400 Bad Request且含too_many_pings,需调大 Pomerium 的grpc_max_concurrent_streams
本地开发时怎么绕过 Pomerium 的 DNS 和 TLS 强制要求?
你不可能在 localhost:8080 上跑 Pomerium + Go 微服务还配通 Let's Encrypt。开发阶段要降级,但不能破坏生产配置一致性。
立即学习“go语言免费学习笔记(深入)”;
- 用
forward_auth模式替代 full-proxy:Pomerium 只做认证网关,反向代理交给nginx或envoy,这样 Go 服务可直连 localhost,Pomerium 只校验/verify请求 - 在 Pomerium config 中对本地策略设
insecure_upstream: true和tls_skip_verify: true,同时把from改成https://local.api.test,再用hosts文件映射到127.0.0.1 - Go 服务启动时加
-pomerium-dev-mode标志,跳过 JWT 校验(仅限 dev),但保留头字段结构,避免代码分支爆炸 - 别用
http://开头的to地址——Pomerium 会拒绝,哪怕insecure_upstream设了也不行,必须是https://或grpc://
真正麻烦的是 header 信任链断点:Pomerium 到 Go 之间若经过另一层代理(比如 Docker 网络或 k8s Service),X-Pomerium-Jwt-Assertion 可能被清空或篡改。这时候要么把 Pomerium 和 Go 部署在同一 Pod,要么用 mTLS 锁死中间链路。

















