查看原文
其他

为 Envoy 启用证书验证

杨传胜 云原生实验室 2021-05-26

由于微信公众号不能插入外链,请点击 阅读原文 查看原文。

如果你准备将服务暴露在互联网上,最好启用 SSL/TLS 加密协议。当使用 Envoy 作为前端代理或者服务网格代理时,可以通过 SSL/TLS 协议来加密客户端和代理之间的所有通信流量。

Envoy 同时支持监听器中的 TLS 终止 和与上游集群建立连接时的 TLS 发起。不管是为现代 web 服务提供标准的边缘代理功能,还是同具有高级 TLS 要求(TLS1.2, SNI, 等等)的外部服务建立连接,Envoy 都提供了充分的支持。

本文将会演示如何在前端代理中设置 TLS 终止,同时指定访问域名。主要分三个步骤:

  1. 创建 Envoy 需要使用的证书

  2. 为 Envoy 启用证书验证

  3. 配置 Envoy 将 80 端口重定向到 443 端口

1. 创建证书

如果要启用 HTTPS,我们就需要从证书授权机构(以下简称 CA) 处获取一个证书。如果你还没有证书,你可以从 Let’s Encrypt 获得网站域名的免费的证书,因为 Let’s Encrypt 就是一个 CA。本文为了测试使用 OpenSSL 生成私钥文件 example-com.key 和 自签名证书 example-com.crt

需要注意的是 Common Name 字段,本文测试使用的是 example.com



2. 为 Envoy 启用证书验证

修改 Dockerfile-frontenvoy 文件:

ADD ./example-com.crt /etc/example-com.crt
ADD ./example-com.key /etc/example-com.key

修改 front-envoy.yaml 配置文件,在 filters 列表后面添加 tls_context 配置项:

tls_context:
  common_tls_context:
    tls_certificates:
      - certificate_chain:
          filename: "/etc/example-com.crt"
        private_key:
          filename: "/etc/example-com.key"

将监听器的监听端口改为标准的 TLS 端口:443。

  - address:
      socket_address:
        address: 0.0.0.0
        port_value: 443

还要指定访问的域名,不再使用之前的通配符匹配:

domains:
"example.com"

Envoy 可以通过在同一个监听器中配置多个监听器过滤器链来支持多个域名的 SNI(如 example.com 和 www.example.com),你可以在 Envoy 官方文档 中看到一个示例。

最后修改 docker-compose.yaml 文件,将 443 端口暴露出来,同时将 8080 端口替换为 80 端口。

services:
  front-envoy:
  ...
    expose:
      - "80"
      - "443"
    ports:
      - "80:80"
      - "443:443"

重启该示例服务:

$ docker-compose down --remove-orphans
$ docker-compose up --build -d

下面就可以使用 curl 来进行测试了。这里有两个需要注意的地方:

  • 为了确保 curl 能成功验证证书,必须通过 --cacert 参数将证书文件传递给 Envoy。

  • 由于 DNS 无法解析 example.com,所以需要通过参数 --connect-to 明确指定连接到 localhost,同时在请求的头文件中申明 localhost 的域名为 example.com

$ curl --cacert example-com.crt --connect-to localhost -H 'Host: example.com' https://localhost/service/1

Hello from behind Envoy (service 1)! hostname: 56e8a5bff6bd resolvedhostname: 172.18.0.2

如果你的 curl 版本不支持 --connect-to 参数,可以在 /etc/hosts 中添加一个条目:127.0.0.1 example.com,然后直接通过域名访问:

$ curl --cacert example-com.crt https://example.com/service/1


3. 将 80 端口重定向到 443 端口

为了将所有 80 端口的流量重定向到 443 端口,可以将 443 端口的路由配置复制一份,然后稍作修改:

重启服务:

$ docker-compose down --remove-orphans
$ docker-compose up --build -d

再次通过 HTTP 协议访问 service1,将会返回 301 状态码:

$ curl -I -H 'Host: example.com' http://localhost/service/1

HTTP/1.1 301 Moved Permanently
location: https://example.com/
date: Tue, 03 Jul 2018 06:32:13 GMT
server: envoy
content-length: 0

OK,大功告成!完整的 front-proxy.yaml 配置文件内容如下:

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存