在 API7 企业版和上游之间配置 mTLS
双向 TLS (mTLS) 是一种双向的 TLS,客户端和服务器在其中互相验证身份。它通常在高度安全的环境中实施,以防止未经授权的访问并加强安全性。
本指南将引导你了解如何在 API7 网关和上游服务之间配置 mTLS,使用 NGINX 作为示例上游服务。
前置条件
- 安装 API7 企业版。
- 在 API7 企业版上创建令牌(Token)。
生成证书和密钥
-
生成证书颁发机构 (CA) 的密钥和证书。
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -sha256 -days 36500 -out ca.crt \
-subj "/CN=ROOTCA" -
为上游服务(NGINX)生成通用名称(Common Name)为
test.com的服务器密钥和证书,并使用 CA 证书进行签名。openssl genrsa -out server.key 2048 && \
openssl req -new -key server.key -out server.csr -subj "/CN=test.com" && \
cat > server.ext << EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = test.com
EOF
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out server.crt -days 36500 \
-sha256 -extfile server.ext -
为 API7 网关(作为客户端)生成通用名称(Common Name)为
client的密钥和证书,并使用 CA 证书进行签名。openssl genrsa -out client.key 2048 && \
openssl req -new -key client.key -out client.csr -subj "/CN=client" && \
cat > client.ext << EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = clientAuth
EOF
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 36500 -sha256 -extfile client.ext -
生成证书和密钥后,检查你的目录以找到
client.crt、client.key和ca.crt。
配置上游服务
- Docker
- Kubernetes
启动一个 NGINX 服务器作为示例上游服务:
docker run -d \
--name quickstart-nginx \
--network=host \
nginx
将 CA 证书、服务器证书公钥和私钥复制到 NGINX 容器中:
docker cp ca.crt quickstart-nginx:/var/ca.crt
docker cp server.crt quickstart-nginx:/var/server.crt
docker cp server.key quickstart-nginx:/var/server.key
在 NGINX 配置文件中配置一个监听在 /hello 路径和 8443 端口上的 HTTPS 服务器:
http {
# ...
server {
listen 8443 ssl;
server_name test.com;
ssl_certificate /var/server.crt;
ssl_certificate_key /var/server.key;
ssl_client_certificate /var/ca.crt;
ssl_verify_client on;
location /hello {
return 200 "Hello API7!";
}
}
}
❶ server_name:设置为 test.com 以与服务器证书的 CN 值保持一致。
❷ ssl_certificate:配置服务器证书公钥 server.crt 的路径。
❸ ssl_certificate_key:配置服务器证书私钥 server.key 的路径。
❹ ssl_client_certificate:配置 CA 证书公钥 ca.crt 的路径。
❺ ssl_verify_client:设置为 on 以验证客户端证书。
重新加载 NGINX 服务器以应用配置更改:
docker exec quickstart-nginx nginx -s reload
为 NGINX 示例上游服务创建一个 Kubernetes secret:
kubectl create secret generic nginx-certs \
--from-file=server.crt=server.crt \
--from-file=server.key=server.key \
--from-file=ca.crt=ca.crt \
--namespace=api7
为 NGINX 示例上游服务创建一个 ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
namespace: api7
data:
default.conf: |
server {
listen 8443 ssl;
server_name test.com;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_client_certificate /etc/nginx/ssl/ca.crt;
ssl_verify_client on;
location /hello {
return 200 "Hello API7!";
}
}
❶ server_name:设置为 test.com 以与服务器证书的 CN 值保持一致。
❷ ssl_certificate:配置服务器证书公钥 server.crt 的路径。
❸ ssl_certificate_key:配置服务器证书私钥 server.key 的路径。
❹ ssl_client_certificate:配置 CA 证书公钥 ca.crt 的路径。
❺ ssl_verify_client:设置为 on 以验证客户端证书。
为 NGINX 示例上游服务的 Deployment 和 Service 创建 Kubernetes 资源清单文件:
apiVersion: v1
kind: Service
metadata:
name: quickstart-nginx
namespace: api7
spec:
type: NodePort
selector:
app: quickstart-nginx
ports:
- name: https
port: 8443
targetPort: 8443
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: api7
name: quickstart-nginx
spec:
replicas: 1
selector:
matchLabels:
app: quickstart-nginx
template:
metadata:
labels:
app: quickstart-nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 8443
volumeMounts:
- name: config
mountPath: /etc/nginx/conf.d
- name: certs
mountPath: /etc/nginx/ssl
volumes:
- name: config
configMap:
name: nginx-config
- name: certs
secret:
secretName: nginx-certs
将配置应用到你的集群中:
kubectl apply -f nginx-cm.yaml -f nginx.yaml
将 NGINX 服务的端口转发到本地机器端口以进行验证:
kubectl port-forward service/quickstart-nginx 8443:8443 &
要验证 NGINX 实例是否配置正确,请使用客户端证书和密钥向上游路由发送请求:
curl -ik "https://127.0.0.1:8443/hello" --cert client.crt --key client.key
你应该会收到 HTTP/1.1 200 OK 响应。
为 API7 企业版配置 mTLS
创建路由至 NGINX 服务器
- Dashboard
- Ingress Controller
- 从侧边导航栏的网关组下选择 已发布服务,然后点击 新增服务。
- 选择 手动新增。
- 在弹出的对话框中,执行以下操作:
- 在 服务基本信息的 名称 字段中,输入
mtls-nginx。 - 在 服务类型字段中,选择
HTTP (Layer 7 Proxy)。 - 在 上游基本信息的 名称 字段中,输入
default。 - 在 如何找到上游字段中,选择
Use Nodes(使用节点)。 - 点击 新增节点。
- 在 新增节点 对话框中,执行以下操作:
- 在 主机 字段中,输入你的 API7 控制台(dashboard)的 IP 地址。
- 在 端口 字段中,输入
8443。 - 在 权重 字段中,输入
100。
- 在 连接配置 字段中,选择
HTTPs。将 客户端证书 和 CA 证书 字段留空以备后续步骤配置。 - 打开 新增第一条路由 开关,然后创建一个路径为
/hello,方法为GET的路由。 - 点击 新增。
- 在 服务基本信息的 名称 字段中,输入
- Gateway API
- APISIX CRD
API7 Ingress Controller 目前不支持使用 Gateway API 配置上游 mTLS。
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: api7
name: mtls-nginx
spec:
ingressClassName: apisix
http:
- name: mtls-nginx
match:
paths:
- /hello
methods:
- GET
backends:
- serviceName: quickstart-nginx
servicePort: 8443
将配置应用到你 的集群中:
kubectl apply -f mtls-route.yaml
配置证书
如果你希望引用来自密钥管理提供商的 SSL 证书,请参阅引用 HashiCorp Vault 中的密钥、引用 AWS Secrets Manager 中的密钥或引用 Kubernetes Secret 中的密钥。
- Dashboard
- Ingress Controller
上传证书
- 从侧边导航栏选择你的网关组下的 证书,进入 SSL 证书 选项卡。
- 点击 Add SSL Certificate(添加 SSL 证书)。
- 在弹出的对话框中,执行以下操作:
- 在 名称字段中,输入
Upstream SSL Certificate。 - 在 证书字段中,上传
client.crt文件。 - 在 私钥字段中,上传
client.key文件。 - 点击 新增。
- 从侧边导航栏选择你的网关组下的 证书,然后点击 CA 证书选项卡。
- 点击 添加 CA 证书。
- 在弹出的对话框中,执行以下操作:
- 在 名称字段中,输入
Upstream CA Certificate。 - 在 证书字段中,上传
ca.crt文件。 - 点击 新增。
配置证书
- 从侧边导航栏选择你的网关组下的 已发布服务,进入你之前创建的
mtls-nginx服务。 - 从侧边导航栏选择 上游。
- 点击 连接配置 区域的编辑按钮。
- 在弹出的对话框中,执行以下操作:
- 在 客户端证书字段中,选择
Upstream SSL Certificate。 - 在 CA 证书字段中,选择
Upstream CA Certificate。 - 点击 保存。
- Gateway API
- APISIX CRD
API7 Ingress Controller 目前不支持使用 Gateway API 配置上游 mTLS。
为 API7 创建一个 Kubernetes secret:
kubectl create secret tls test-mtls-secret \
--cert=client.crt \
--key=client.key \
--namespace=api7
创建一个 Kubernetes 资源清单文件来配置之前创建的路由的上游:
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: api7
name: quickstart-nginx # 应该与服务名称匹配
spec:
ingressClassName: apisix
scheme: https
tlsSecret:
namespace: api7
name: test-mtls-secret
将配置应用到你的集群中:
kubectl apply -f mtls-upstream.yaml