为 Envoy 开启 TLS 验证实战

栏目: 服务器 · Nginx · 发布时间: 6年前

内容简介:我的博客之前是使用而关于如何为 Envoy 开启证书验证可以参考我之间的文章:

我的博客之前是使用 Nginx 来反代的,由于 Nginx 性能优异,目前有很多国内网站采用 Nginx 作为 Web 服务器,而且参考文档比较丰富,无论是对于其部署,配置还是调优都更为有经验。但是还是会碰到几个绕不开的问题:

  • Nginx 的反向代理不支持 http2/grpc (好像今年 3 月份刚支持)
  • 不像 Envoy 几乎所有的网络配置都可以利用 xDS API 来实现动态变更,Nginx 缺乏有效的配置热变更机制(除非深入开发或者不断地 reload )。
  • Nginx 的很多微服务功能都是要买 Nginx Plus 才有的。

Envoy 是一款现代化的,高性能,小体积的边缘及服务代理,浑身散发出一股时尚潮流的气息。作为一名斜杠青年,在经过一定地了解后,我果断入了 Envoy 的坑。

关于如何为 Envoy 开启证书验证可以参考我之间的文章: 为 Envoy 启用证书验证 。本文将直接进入实战部分,通过 Envoy 来反向代理我的博客静态页面,并且加密客户端和 Envoy 代理之间的所有流量。

1. 方案架构

本方案涉及到两层 Envoy:

  • 首先会有一个前端代理在某个地方单独运行。前端代理的工作是给其他地方提供一个入口。来自外部的传入连接请求到这里,前端代理将会决定他们在内部的转发路径。

  • 其次,博客静态页面由 nginx 提供,同时运行一个 “服务 Envoy”,它与 nginx 容器共享 network nemspace (相当于 Kubernetes 的 Sidecar )。

  • 所有的 Envoy 形成一个网格,然后在他们之间共享路由信息。

注意,通常情况下你也可以只使用前端代理,然后去掉服务 Envoy 这一层。但是,使用完整网格的话,服务 Envoy 可以对应用服务进行健康监控等,让网格知道尝试联系一个挂掉的服务是否是毫无意义的。此外,Envoy 的统计数据收集最适合用在全网格上。

但本文需要开启 TLS 验证,如果前端代理开启了 TLS 验证,那么必须配合服务 Envoy 使用,否则验证将无法通过。

2. 部署服务 Envoy

我的博客是通过 hugo 生成的,其他生成静态页面的软件类似,都可以采用我的方案。由于我的 hugo 根目录是 /home/hugo ,首先进入该目录,然后创建容器编排的 docker-compose.yml 文件。

version: '2'
services:

  hugo:
    image: nginx:alpine
    restart: always
    volumes:
      - /home/hugo/public:/usr/share/nginx/html ①
    networks:
      - default 
    expose:
      - "80"
      - "8080"

  service-envoy:
    image: envoyproxy/envoy-alpine:latest
    restart: always
    volumes:
      - ./service-envoy.yaml:/etc/envoy/envoy.yaml ②
    network_mode: "service:hugo" ③

networks:
  default:
    external:
      name: yang ④
root
network namespace

接下来需要创建服务 Envoy 的配置文件 service-envoy.yaml

static_resources:
  listeners:
  - address:
      socket_address:
        address: 0.0.0.0
        port_value: 8080 ①
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: service
              domains:
              - "*"
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: local_service
          http_filters:
          - name: envoy.router
            config: {}
  clusters:
  - name: local_service
    connect_timeout: 0.25s
    type: strict_dns
    lb_policy: round_robin
    hosts:
    - socket_address:
        address: 127.0.0.1
        port_value: 80 ②
admin:
  access_log_path: "/dev/null"
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 8081

3. 部署前端代理

docker-compose.yml 文件中添加前端代理部分:

version: '2'
services:

  ...
  front-envoy:
    image: envoyproxy/envoy
    restart: always
    volumes:
      - ./front-envoy.yaml:/etc/envoy/envoy.yaml
      - /etc/letsencrypt:/etc/letsencrypt
    labels:
      EnvironmentName: "proxy"
      ServiceName: "envoy"
      ProxyMode: "tcp"
    networks:
      - default
    expose:
      - "80"
      - "443"
    ports:
      - "80:80"
      - "443:443"

创建前端代理需要的配置文件 front-envoy.yaml

static_resources:
  listeners:
  - address:
      socket_address:
        address: 0.0.0.0
        port_value: 80
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto ①
          stat_prefix: ingress_http
          route_config:
            virtual_hosts:
            - name: backend
              domains: ②
              - "yangcs.net"
              - "www.yangcs.net"
              routes:
              - match:
                  prefix: "/"
                redirect:
                  path_redirect: "/"
                  https_redirect: true
          http_filters:
          - name: envoy.router
            config: {}
  - address:
      socket_address:
        address: 0.0.0.0
        port_value: 443
    filter_chains:
    - tls_context:
        common_tls_context:
          alpn_protocols: h2,http/1.1 ③
          tls_certificates: ④
            - certificate_chain:
                filename: "/etc/letsencrypt/live/www.yangcs.net/fullchain.pem"
              private_key:
                filename: "/etc/letsencrypt/live/www.yangcs.net/privkey.pem"
      filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains:
              - "yangcs.net"
              - "www.yangcs.net"
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: hugo
          http_filters:
          - name: envoy.router
            config: {}
  clusters:
  - name: hugo
    connect_timeout: 0.25s
    type: strict_dns
    lb_policy: round_robin
    http2_protocol_options: {}
    hosts:
    - socket_address:
        address: hugo
        port_value: 8080
admin:
  access_log_path: "/dev/null"
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 8001
  • ① : 编码/解码方式。参考: HttpConnectionManager.CodecType
  • ② : 允许访问的域名(这里使用公网可以访问的域名)。
  • ③ : TLS 监听器支持 ALPN 。HTTP 连接管理器使用这个信息(以及协议接口)来确定客户端使用的是 HTTP/1.1 还是 HTTP/2
  • ④ : 网站使用的证书。可以通过 Let’s Encrypt 申请免费的证书。

其他配置详细说明请参考: 为 Envoy 启用证书验证

准备好所有配置以后,我们就可以通过以下命令来启动所有服务了:

$ docker-compose up -d

Creating front-proxy_hugo_1        ... done
Creating front-proxy_front-envoy_1 ... done
Creating front-proxy_service-envoy_1 ... done

接下来就可以通过公网域名访问博客网站啦!没错,你现在浏览的我的博客就是通过 Envoy 反向代理的。


以上所述就是小编给大家介绍的《为 Envoy 开启 TLS 验证实战》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

プログラミングコンテストチャレンジブック

プログラミングコンテストチャレンジブック

秋葉 拓哉、岩田 陽一、北川 宜稔 / 毎日コミュニケーションズ / 2010-09-11 / JPY 34.44

現在、プログラミングコンテストは数多く開催されています。Google Code Jam、TopCoder、ACM/ICPCなどの名前を聞いたことがある人も少なくないでしょう。本書で扱うのはそれらのような、問題を正確にできるだけ多く解くことを競うプログラミングコンテストです。 プログラミングコンテストは気軽に参加することができます。例えば、Google Code JamやTopCoderはイン......一起来看看 《プログラミングコンテストチャレンジブック》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

在线进制转换器
在线进制转换器

各进制数互转换器

随机密码生成器
随机密码生成器

多种字符组合密码