tzssangglass commented on code in PR #7540: URL: https://github.com/apache/apisix/pull/7540#discussion_r930699684
########## docs/zh/latest/certificate.md: ########## @@ -168,3 +168,133 @@ curl --resolve 'www.test.com:9443:127.0.0.1' https://www.test.com:9443/hello -v * `keys`:PEM 格式的 SSL 证书私钥列表 `APISIX` 会将相同下标的证书和私钥配对使用,因此 `certs` 和 `keys` 列表的长度必须一致。 + +### 设置多个 CA 证书 + +APISIX 目前支持在多处设置 CA 证书,比如 [保护 Admin API](./mtls.md#保护-admin-api),[保护 ETCD](./mtls.md#保护-etcd),以及 [部署模式](../../en/latest/architecture-design/deployment-role.md) 等。 + +在这些地方,使用 `ssl_trusted_certificate` 或 `trusted_ca_cert` 来配置 CA 证书,但是这些配置最终将转化为 OpenResty 的 [lua_ssl_trusted_certificate](https://github.com/openresty/lua-nginx-module#lua_ssl_trusted_certificate) 指令。 + +如果你需要在不同的地方指定不同的 CA 证书,你可以将这些 CA 证书制作成一个 CA bundle 文件,在需要用到 CA 证书的地方将配置指向这个文件。这样可以避免生成的 `lua_ssl_trusted_certificate` 存在多处并且互相覆盖的问题。 + +下面用一个完整的例子来展示如何在 APISXI 设置多个 CA 证书。 Review Comment: done ########## docs/zh/latest/certificate.md: ########## @@ -168,3 +168,133 @@ curl --resolve 'www.test.com:9443:127.0.0.1' https://www.test.com:9443/hello -v * `keys`:PEM 格式的 SSL 证书私钥列表 `APISIX` 会将相同下标的证书和私钥配对使用,因此 `certs` 和 `keys` 列表的长度必须一致。 + +### 设置多个 CA 证书 + +APISIX 目前支持在多处设置 CA 证书,比如 [保护 Admin API](./mtls.md#保护-admin-api),[保护 ETCD](./mtls.md#保护-etcd),以及 [部署模式](../../en/latest/architecture-design/deployment-role.md) 等。 + +在这些地方,使用 `ssl_trusted_certificate` 或 `trusted_ca_cert` 来配置 CA 证书,但是这些配置最终将转化为 OpenResty 的 [lua_ssl_trusted_certificate](https://github.com/openresty/lua-nginx-module#lua_ssl_trusted_certificate) 指令。 + +如果你需要在不同的地方指定不同的 CA 证书,你可以将这些 CA 证书制作成一个 CA bundle 文件,在需要用到 CA 证书的地方将配置指向这个文件。这样可以避免生成的 `lua_ssl_trusted_certificate` 存在多处并且互相覆盖的问题。 + +下面用一个完整的例子来展示如何在 APISXI 设置多个 CA 证书。 + +假设让 Client 与 APISIX Admin API,APISXI 与 ETCD 之间都使用 mTLS 协议进行通信,目前有两张 CA 证书,分别是 `foo_ca.crt` 和 `bar_ca.crt`,用这两张 CA 证书各自签发 client 与 server 证书对,`foo_ca.crt` 及其签发的证书对用于保护 Admin API,`bar_ca.crt` 及其签发的证书对用于保护 ETCD。 + +下表详细列出这个示例所涉及到的配置及其作用: + +| 配置 | 类型 | 用途 | +| ------------- | ------- | ----------------------------------------------------------------------------------------------------------- | +| foo_ca.crt | CA 证书 | 签发客户端与 APISIX Admin API 进行 mTLS 通信所需的次级证书。 | +| foo_client.crt | 证书 | 由 `foo_ca.crt` 签发,客户端使用,访问 APISIX Admin API 时证明自身身份的证书。 | +| foo_client.key | 密钥文件 | 由 `foo_ca.crt` 签发,客户端使用,访问 APISIX Admin API 所需的密钥文件。 | +| foo_server.crt | 证书 | 由 `foo_ca.crt` 签发,APISIX 使用,对应 `apisix.admin_api_mtls.admin_ssl_cert` 配置项。 | +| foo_server.key | 密钥文件 | 由 `foo_ca.crt` 签发,APISIX 使用,对应 `apisix.admin_api_mtls.admin_ssl_cert_key` 配置项。 | +| admin.apisix.dev | 域名 | 签发 `foo_server.crt` 证书时使用的 Common Name,客户端通过该域名访问 APISIX Admin API | +| bar_ca.crt | CA 证书 | 签发 APISIX 与 ETCD 进行 mTLS 通信所需的次级证书。 | +| bar_etcd.crt | 证书 | 由 `bar_ca.crt` 签发,ETCD 使用,对应 ETCD 启动命令中的 `--cert-file` 选项。 | +| bar_etcd.key | 密钥文件 | 由 `bar_ca.crt` 签发,ETCD 使用,对应 ETCD 启动命令中的 `--key-file` 选项。 | +| bar_apisix.crt | 证书 | 由 `bar_ca.crt` 签发,APISIX 使用,对应 `etcd.tls.cert` 配置项。 | +| bar_apisix.key | 密钥文件 | 由 `bar_ca.crt` 签发,APISIX 使用,对应 `etcd.tls.key` 配置项。 | +| etcd.cluster.dev | 域名 | 签发 `bar_etcd.crt` 证书时使用的 Common Name,APISIX 与 ETCD 进行 mTLS 通信时,使用该域名作为 SNI。对应 `etcd.tls.sni` 配置项。| +| apisix.ca-bundle | CA bundle | 由 `foo_ca.crt` 与 `bar_ca.crt` 合并而成,替代 `foo_ca.crt` 与 `bar_ca.crt`。 | + +1. 制作 CA bundle 文件 + +``` +cat /path/to/foo_ca.crt /path/to/bar_ca.crt > apisix.ca-bundle +``` + +2. 启动 ETCD 集群,并开启客户端验证 + +```shell +# 运行 `go get github.com/mattn/goreman` 安装 goreman,用 goreman 执行以下命令: +etcd1: etcd --name infra1 --listen-client-urls https://127.0.0.1:12379 --advertise-client-urls https://127.0.0.1:12379 --listen-peer-urls http://127.0.0.1:12380 --initial-advertise-peer-urls http://127.0.0.1:12380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --cert-file /path/to/bar_etcd.crt --key-file /path/to/bar_etcd.key --client-cert-auth --trusted-ca-file /path/to/apisix.ca-bundle +etcd2: etcd --name infra2 --listen-client-urls https://127.0.0.1:22379 --advertise-client-urls https://127.0.0.1:22379 --listen-peer-urls http://127.0.0.1:22380 --initial-advertise-peer-urls http://127.0.0.1:22380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --cert-file /path/to/bar_etcd.crt --key-file /path/to/bar_etcd.key --client-cert-auth --trusted-ca-file /path/to/apisix.ca-bundle +etcd3: etcd --name infra3 --listen-client-urls https://127.0.0.1:32379 --advertise-client-urls https://127.0.0.1:32379 --listen-peer-urls http://127.0.0.1:32380 --initial-advertise-peer-urls http://127.0.0.1:32380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --cert-file /path/to/bar_etcd.crt --key-file /path/to/bar_etcd.key --client-cert-auth --trusted-ca-file /path/to/apisix.ca-bundle +``` + +3. 更新 `config.yaml` + +```yaml +apisix: + admin_key: + - name: admin + key: edd1c9f034335f136f87ad84b625c8f1 + role: admin + port_admin: 9180 + https_admin: true + + admin_api_mtls: + admin_ssl_ca_cert: /path/to/apisix.ca-bundle + admin_ssl_cert: /path/to/foo_server.crt + admin_ssl_cert_key: /path/to/foo_server.key + + ssl: + ssl_trusted_certificate: /path/to/apisix.ca-bundle + +etcd: + host: + - "https://127.0.0.1:12379" + - "https://127.0.0.1:22379" + - "https://127.0.0.1:32379" + tls: + cert: /path/to/bar_apisix.crt + key: /path/to/bar_apisix.key + sni: etcd.cluster.dev +``` + +4. 测试 Admin API + +启动 APISIX,如果 APISIX 启动成功,`logs/error.log` 中没有异常输出,表示 APISIX 与 ETCD 之间进行 mTLS 通信正常。 + +用 curl 模拟客户端,与 APISIX Admin API 进行 mTLS 通信,并创建一条路由: + +```shell +curl -vvv --resolve 'admin.apisix.dev:9180:127.0.0.1' https://admin.apisix.dev:9180/apisix/admin/routes/1 --cert /path/to/foo_client.crt --key /path/to/foo_client.key --cacert/path/to/apisix.ca-bundle -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d ' Review Comment: doen -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
