用 Pomerium 来实现基于身份的访问控制
Google 在十年前提出了一套名为 BeyondCorp 的零信任网络的安全方案。这套方案想要完整地实现还是有一定门槛的,在这种模型下,企业内网不再作为一个安全边界存在,相反即使在内网进行的访问也必须进行和外网同样的鉴权与访问控制。最终的改造方向是内网不再是一个特权网络,每个终端上部署的客户端证书主要是作为一项身份信息来使用。
在 BeyondCorp 方案中对用户比较可见的一项便是统一登录认证 SSO 和基于用户身份进行访问控制的反向代理。之前考虑过许多其他方案,包括使用 nginx 自己山寨一套,不过后来听 @yegle 同学的建议,直接用 Pomerium 来实现了一套鉴权反向代理,这里把大致过程记录一下。
首先是安装。 FreeBSD 没有对应的 port,于是 做了一个。新用户可以直接用 pkg install pomerium 来安装了。
必须配置的一些选项包括 pomerium_enable (显然)。如果使用 Pomerium 来的做 https 服务,那么还需要配置 pomerium_cert_file(指向一个 wildcard 证书)和 pomerium_cert_key_file。除此之外,pomerium_shared_secret 和 pomerium_cookie_secret 应分别设置为两个随机串,不过如果没设置的话系统会自动每次启动时生成新的随机串。需要注意的是,假如需要使用标准的 https 端口443,如果以系统默认的非特权用户来运行 Pomerium 的话,需要将 net.inet.ip.portrange.reservedhigh 设为小于 443 的值才行。
然后是配置。OAuth 2.0 需要一个回调 URL,Pomerium 中这个可以是 https://authenticate.corp.{example.com}。在 IdP (如 Google、Azure等等)完成身份验证之后,IdP会将用户转回这个URL完成后续的设置。
IdP相关的主要设置是 idp_provider、idp_client_id 和 idp_client_secret,后两项信息要从 IdP 那里获得。如果 IdP 提供了群组功能,可能还需要进行一些额外的设置,例如 G Suite 就要求服务账户必须能够以某种管理员的身份运行。
代理方面,在代理服务器后面受其保护的服务器应 验证 Pomerium 的请求头签名。除此之外,代理的配置其实是很简单的,如果是比较小的系统,用 allowed_users就足够了。大一些的系统可以用 allowed_domains 和 allowed_groups。另一个潜在的坑是要注意后端服务器不要在做 redirect 时回自己的 URL,如果发生这种情况,需要把后端服务改对或者至少搞一层重写。