一. Cert Manager 的局限性
我们在之前的文章中演示了 Cert Manager 自动签发和管理 TLS 证书的过程,但在实践中会遇到一些问题:
1.HTTP 验证问题
cert-manager 默认使用 HTTP-01 验证时,需要暴露服务器或负载均衡的 80 端口给互联网。如果环境比较敏感,或者不想对外暴露服务,这会带来极大的安全隐患。
2.DNS 验证问题
采用 DNS-01 验证虽然只需要有 DNS 的 API 修改权限,但是对于没有公网 DNS 控制权的用户来说非常麻烦,并且无法保证安全性,需要额外的审计手段。
3.缺乏额外防护
虽然 cert manager 可以完成证书自动化,但它本身不提供 CDN、WAF、流量限制等功能,即便对于个人测试环境也显得很单薄。
所以,如果只需要快速实现 HTTPS 并配合一些流量管理,cert manager 并非最优选择。
二. Cloudflare 免费模式下的优势
针对个人测试环境等,Cloudflare 的免费套餐已经提供了很多的基础实用功能。

1.免费的 CDN 与 DNS
提供最基本的 CDN 缓存与 DNS 服务器功能。
2.免费的 SSL 证书
提供免费通用的 SSL/TLS 证书保护我们的站点(类似 AWS Certificate Manager),并且支持 Cloudflare 站点到我们业务站点之间通过自签名证书做 TLS 加密。
3.免费的 WAF 与流量限制
即使免费模式,也能设置 IP 访问限制、速率限制、防爬虫等规则,弥补了 cert manager 等工具的不足。
三. 解决方案概览
我们通过 Cloudflare + Kubernetes Ingress + 自签名证书构建一个测试环境,实现:
1.域名代理
外部访问经过 Cloudflare,再由 Ingress 转发到后端服务;隐藏我们业务服务器的 IP 地址。
2.HTTPS 加密
由 Cloudflare 提供 SSL/TLS 终端,供给浏览器访问域名使用;Cloudflare 和 Ingress 之间使用自签名证书加密流量。
3.流量控制
通过 Cloudflare 页面设置简单的 IP 访问限制和速率限制。
四.配置示例
1.配置 DNS 和网络安全组
首先我们查看 Cloudflare 名称服务器:

然后把域名的 DNS 服务器修改为 Cloudflare 指定的服务器(这里以阿里云购买的域名为例):

配置生效要等待一段时间,我们可以同时配置 DNS 记录:

个人测试环境没有创建负载均衡(使用云厂商的负载均衡会产生额外的费用),直接 A 记录指向了 Kubernetes Ingress 所在的服务器地址。
在服务器对应的网络安全组删除所有 0.0.0.0/0 的入站规则,只配置 Cloudflare 出口地址:

2.创建 Cloudflare 源证书
Cloudflare 和源服务器之间的 TLS 证书,可以用 openssl 等工具生成。
这里我们使用最简单的方式,让 Cloudflare 帮我们生成:



下载证书到服务器中,然后创建 secret:
kubectl -n drone create secret tls cloudflare-origin-tls --cert=origin.crt --key=origin.key
kubectl -n drone get secret | grep cloud
cloudflare-origin-tls kubernetes.io/tls 2 22s
3.配置 Ingress 使用新的 secret
修改之前的 yaml 文件:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: drone-ingress
namespace: drone
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
#cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- drone.fzwtest.xyz
secretName: cloudflare-origin-tls
rules:
- host: drone.fzwtest.xyz
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: drone-server
port:
number: 80
执行部署:
kubectl apply -f drone-ingress.yaml
4.配置 Cloudflare 的 SSL/TLS 加密模式


5.启用 HTTP 重定向 HTTPS

6.配置访问速率限制
这里设置一个最简单的规则:同一个 IP 来源对域名的访问每 10 秒钟最多 10 次,超过限制后阻止它的访问请求 10 秒钟。


7.配置国家地区访问限制
我们对互联网开放任何网站,运行一段时间后,总会发现来自国外地区 IP 的攻击行为,如下图所示的恶意扫描和流量消耗:

由于我们是个人测试演示的网站,直接简单的禁止国外地区访问即可:

五.验证
现在访问 http://drone.fzwtest.xyz(前面的文章我们用 Cert Manager 代理过的域名)。验证是否达到预期。
-
Cloudflare 拦截了请求,并返回 301 跳转 https 给客户端;
-
客户端看到的 Server 地址是 Cloudflare 的地址,隐藏了真实的服务器地址;

- 显示受信任的 Cloudflare 边缘证书;

- 多次快速刷新页面,出现访问频率限制;

等待 10 秒后解除拦截:

- 国外 IP 访问我们的网站直接被阻止:

其他子域名只需要修改对应的 Kubernetes Ingress 即可,非常简单高效。

