Ubuntu 22.04 安装 Pomerium 指南

在 Ubuntu 22.04 上通过 Cloudsmith 官方源与 systemd 安装 Pomerium 的完整实测记录,含排障与版本管理。

Pomerium零信任OIDCIAM2026/10/21

Ubuntu 22.04 安装 Pomerium 指南

本文记录在 Ubuntu 22.04 LTS(22.04.5, x86_64)上安装 Pomerium 的完整过程。主线采用官方软件源(Cloudsmith 托管的 deb 仓库)+ systemd 服务的方式,全部命令与回显均来自实测;文末给出等价的 Docker Compose 备用方案与常见故障排查。

安装前准备

  • 系统版本:Ubuntu 22.04.5 LTS, x86_64(实测环境;cat /etc/os-release 可确认)。
  • 域名与证书前提:Pomerium 的路由按对外域名划分,典型部署需要至少两个域名:authenticate 服务域名(如 authenticate.example.com)与各受保护应用域名,并准备对应的 TLS 证书(可用 Let's Encrypt 的 autocert 自动签发,或手动指定证书文件)。本文为本地实验采用自签证书与 *.localhost.pomerium.io 测试域名。
  • 端口规划:主服务监听 :443(HTTPS)与 :80(autocert 的 HTTP-01 验证/重定向),确认未被占用:ss -ltn。
  • 软件依赖:curl、ca-certificates、gnupg(配置软件源时使用)。

主线:官方 apt 源 + systemd

配置 Cloudsmith 软件源

Pomerium 的 deb/rpm 包通过 Cloudsmith 托管分发。执行官方 setup 脚本(以 root 运行,无需 sudo):

curl -1sLf 'https://dl.cloudsmith.io/public/pomerium/pomerium/setup.deb.sh' | bash

实测回显(节选):

Detected operating system as Ubuntu/jammy.
Checking for apt dependency requirements...
Installing apt repository...
Running apt-get update...
The repository is setup! You can now install packages.

脚本会写入 /etc/apt/sources.list.d/pomerium-pomerium.list 并导入签名密钥。查看仓库提供的版本:

apt-cache policy pomerium

实测回显(2026-10-20 查询):

pomerium:
  Installed: (none)
  Candidate: 1:0.33.4-1
  Version table:
     1:0.33.4-1 500
        500 https://dl.cloudsmith.io/public/pomerium/pomerium/deb/ubuntu jammy/main amd64 Packages
     1:0.33.3-1 500
     1:0.33.2-1 500
     1:0.33.1-1 500
     1:0.33.0-1 500
     1:0.32.11-1 500
     ...
     1:0.32.9-1 500

安装

DEBIAN_FRONTEND=noninteractive apt-get install -y pomerium

实测回显(节选):

Reading package lists...
Building dependency tree...
The following NEW packages will be installed:
  pomerium
Need to get 63.0 MB of archives.
After this operation, 227 MB of additional disk space will be used.
Setting up pomerium (1:0.33.4-1) ...

确认版本与包内文件清单:

pomerium --version
dpkg -L pomerium

实测回显:

pomerium version pomerium: 0.33.4+5cd94927f, envoy: 20261001211751-8b998d0f6ff3
/etc/pomerium
/etc/pomerium/config.yaml
/usr/lib/systemd/system/pomerium.service
/usr/sbin/pomerium

要点:

  • 主程序位于 /usr/sbin/pomerium,内嵌 Envoy 数据面(二进制约 216 MB,实测进程常驻内存约 215 MB RSS);
  • 默认配置在 /etc/pomerium/config.yaml;
  • 服务以 pomerium 系统用户(uid 999,安装时自动创建)运行。

理解 systemd 服务单元

/usr/lib/systemd/system/pomerium.service 关键内容:

[Unit]
Description=pomerium: an identity-aware reverse proxy
Documentation=https://www.pomerium.com/docs/
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
User=pomerium
Group=pomerium
Environment=AUTOCERT_DIR=/data/autocert
ExecStart=/usr/sbin/pomerium --config /etc/pomerium/config.yaml
WatchdogSec=30s
Restart=always
RestartSec=1

[Install]
WantedBy=multi-user.target

三个值得注意的点:

  1. Type=notify + WatchdogSec=30s:服务启动后需在 30 秒内通知 systemd 就绪,否则判定启动失败;运行期看门狗每 30 秒心跳。数据面进程是从主程序释放到临时目录再执行的,如果该目录不可执行,服务将一直无法就绪并最终超时(见下文排障实录二)。

  2. 若希望监听 443/80 特权端口,官方文档建议增加能力授予:

    echo -e "[Service]\nAmbientCapabilities=CAP_NET_BIND_SERVICE" | SYSTEMD_EDITOR=tee systemctl edit pomerium
    
  3. 自定义环境变量通过 drop-in 目录追加,例如 Environment=TMPDIR=/var/lib/pomerium。

最小可用配置与启动

生成自签证书(实验环境)

生产环境建议用 autocert: true 或外部证书。实验环境用 openssl 自签:

cd /etc/pomerium
openssl req -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes \
  -keyout key.pem -out cert.pem \
  -subj "/CN=*.localhost.pomerium.io" \
  -addext "subjectAltName=DNS:*.localhost.pomerium.io,DNS:localhost"

编写最小配置

在 /etc/pomerium/config.yaml 写入一份最小可用配置(随机密钥用 head -c32 /dev/urandom | base64 生成;idp_provider 部分需按你的真实 IdP 填写,本文以通用 OIDC 为例,IdP 服务地址为实验环境中自建的 Dex):

address: :8443

authenticate_service_url: https://authenticate.localhost.pomerium.io

certificates:
  - cert: /etc/pomerium/cert.pem
    key: /etc/pomerium/key.pem

shared_secret: <head -c32 /dev/urandom | base64 生成>
cookie_secret: <head -c32 /dev/urandom | base64 生成>

idp_provider: oidc
idp_client_id: pomerium
idp_client_secret: <你的 client secret>
idp_provider_url: http://<你的 IdP 地址>:5556

routes:
  - from: https://verify.localhost.pomerium.io
    to: http://<后端应用地址>:8080
    policy:
      - allow:
          or:
            - email:
                is: admin@example.com

配置要点:

  • address 为监听端口;authenticate_service_url 必须与用户实际访问 authenticate 的地址一致(含端口),不一致会导致 OAuth 回调校验失败;
  • shared_secret/cookie_secret 分别用于服务间加密与会话 cookie 加密,必须为合法 base64 且足够随机;
  • 每条 routes 的 from 是对外暴露的域名,to 是上游真实服务。

启动服务

systemctl enable --now pomerium
systemctl is-active pomerium

实测回显:

Synchronizing state of pomerium.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable pomerium
Created symlink /etc/systemd/system/multi-user.target.wants/pomerium.service → /usr/lib/systemd/system/pomerium.service.
active

服务状态(节选,已按系统服务路径归一化):

● pomerium.service - pomerium: an identity-aware reverse proxy
     Loaded: loaded (/usr/lib/systemd/system/pomerium.service; enabled; preset: enabled)
    Drop-In: /etc/systemd/system/pomerium.service.d/override.conf
             └─override.conf
     Active: active (running) since Mon 2026-10-20 18:02:05 UTC; 6s ago
   Main PID: 4340 (pomerium)
     CGroup: /system.slice/pomerium.service
             ├─4340 /usr/sbin/pomerium --config /etc/pomerium/config.yaml
             └─4420 /var/lib/pomerium/pomerium-envoy3352208503/envoy ...

验证

curl -sk https://localhost:8443/healthz -w "\nHTTP:%{http_code}\n"
curl -sk https://localhost:8443/ping -w "\nHTTP:%{http_code}\n"

实测回显:

OK
HTTP:200
OK
HTTP:200

访问受保护路由(未认证时)会被重定向到登录入口:

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

排障实录

以下三个故障在本次安装中真实发生,供对照排查。

故障一:证书私钥权限不足

现象:systemctl restart pomerium 后服务启动失败:

pomerium.service: Main process exited, code=exited, status=1/FAILURE
Failed with result 'exit-code'.

日志(journalctl -u pomerium,节选):

error loading config: open /etc/pomerium/key.pem: permission denied

原因:手工生成的 key.pem 属主为 root 且权限 600,而服务以 pomerium 用户运行。修复:

chown pomerium:pomerium /etc/pomerium/key.pem /etc/pomerium/cert.pem
chmod 600 /etc/pomerium/key.pem
systemctl restart pomerium

故障二:临时目录 noexec 导致启动超时

现象:服务反复重启后 start operation timed out. Terminating.,日志中出现:

error starting envoy: fork/exec /tmp/pomerium-envoy1560276494/envoy: permission denied

原因:数据面进程(Envoy)由主程序释放到 $TMPDIR 下的临时目录并执行;当 /tmp 以 noexec 挂载(部分发行版/安全基线默认如此,实验环境亦如此)时执行被拒绝,服务无法就绪,触发 30 秒看门狗超时。修复方式为把 TMPDIR 指向可执行目录:

mkdir -p /var/lib/pomerium && chown pomerium:pomerium /var/lib/pomerium
systemctl edit pomerium   # 写入:
# [Service]
# Environment=TMPDIR=/var/lib/pomerium
systemctl daemon-reload && systemctl restart pomerium

修复后服务立即进入 active (running)。生产环境若遇同样报错,也可以调整 /tmp 挂载选项,但更推荐前者(最小权限面改动)。

故障三:IdP 未就绪导致会话建立中断

authenticate 服务与 IdP(如 Dex/Okta)的连接是会话链路的必要条件。实测中发现:当 IdP 侧回调域名(dex 的 redirectURIs)与 authenticate_service_url 端口不一致时,回调阶段直接报错;callback 阶段还观察到 authenticate: session load error(会话记录读取失败)。排查要点:

  1. IdP 客户端的回调地址必须与 authenticate_service_url 逐字符一致(协议/域名/端口);
  2. 检查系统时间(会话与 token 校验强依赖时钟,NTP 漂移会造成假性失败);
  3. 用 journalctl -u pomerium -f 观察 callback 请求的 request-id 与错误详情。

版本管理:锁定、降级与升级

Cloudsmith 源保留完整历史版本,可直接指定版本安装:

apt-get install -y --allow-downgrades pomerium=1:0.32.9-1

实测降级回显(节选):

Preparing to unpack .../pomerium_1%3a0.32.9-1_amd64.deb ...
Unpacking pomerium (1:0.32.9-1) over (1:0.33.4-1) ...
Setting up pomerium (1:0.32.9-1) ...
pomerium --version
# pomerium version pomerium: 0.32.9+a5e506311, envoy: 1.36.8-p1+c227cb5b1f5cbbb8d6446ef7ca54450e47793825ef22aa52f9f55dd2a9ce25b4

重新升级回最新版:

apt-get install -y pomerium
pomerium --version
# pomerium version pomerium: 0.33.4+5cd94927f, envoy: 20261001211751-8b998d0f6ff3

升级只替换程序文件,/etc/pomerium/config.yaml 不被覆盖。生产环境升级前应查阅官方 changelog(关注内嵌 Envoy 的 CVE 修复与 Enterprise Console 配套升级顺序)。

备用方案:Docker Compose 部署

与主机安装等价的另一种形态是使用官方镜像(tag 规则::latest 最新稳定版、:vX.Y.Z 指定版本)。以下 compose 文件实测可用(镜像 pomerium/pomerium:v0.32.9,配置与证书文件挂载进程序目录):

# compose.yaml —— 注意 name 字段显式命名,避免与其他服务同名项目互相干扰
name: pomerium-0.32.9-stack

services:
  pomerium:
    image: pomerium/pomerium:v0.32.9
    container_name: pomerium-0-32-9-gateway
    restart: unless-stopped
    volumes:
      - ./config.yaml:/pomerium/config.yaml:ro
      - ./cert.pem:/pomerium/cert.pem:ro
      - ./key.pem:/pomerium/key.pem:ro
    ports:
      - "443:443"

networks:
  default:
    external: true
    name: pomerium-net

启动与验证:

$ docker compose up -d
 Container pomerium-0-32-9-gateway Created
 Container pomerium-0-32-9-gateway Started

$ docker compose ps
NAME                      STATUS
pomerium-0-32-9-gateway   Up 12 seconds

$ curl -sk https://<部署机IP>/healthz
OK

启动日志可确认版本与配置装载(节选):

{"level":"info","service":"all","config":"local","checksum":"e1e9418a288cd18a","message":"config: updated config"}
{"level":"info","envoy-version":"1.36.8-p1+...","version":"0.32.9+a5e506311","built":"2026-06-16T17:26:01Z","message":"cmd/pomerium"}
{"level":"info","health-addr":"127.0.0.1:28080","message":"cmd/pomerium"}

停止并清理该部署:

docker compose down    # 仅删除本项目(name 隔离),不影响其他服务

卸载

systemctl disable --now pomerium
apt-get purge -y pomerium

purge 会删除程序与服务单元,/etc/pomerium 与数据目录(如 /var/lib/pomerium)需按需手动清理。

小结

  • 主线安装 = Cloudsmith 源 + apt install pomerium + systemd 托管,安装过程约两分钟(63 MB 下载/227 MB 落盘),pomerium --version 即可确认版本;
  • 两个高发故障:证书私钥权限(pomerium 用户)与 TMPDIR noexec(Envoy 无法执行),均可用最小改动修复;
  • Docker Compose 形态适合快速验证与无 systemd 环境,注意在 compose 中显式 name 隔离项目;
  • IdP 是会话链路的前置条件,回调地址与 authenticate_service_url 必须完全一致。

下一篇《Pomerium v0.33.4 配置参数详解》将对 config.yaml 的各参数组逐一展开实测。