自建“类 Cloudflare”边缘网关:从 HTTPS、WAF 到内网穿透的完整配置方案
Cloudflare 私有化部署方案|附配置文件
说明:严格来说,Cloudflare 是一个全球化 SaaS 平台,完整的 Cloudflare CDN、Anycast 网络、DDoS 清洗中心、WAF 规则体系无法被“私有化部署”到本地或自有服务器中。
本文所说的“Cloudflare 私有化部署方案”,指的是在企业自有服务器、VPS、IDC 或私有云环境中,搭建一套具备 反向代理、HTTPS 证书、访问控制、WAF 防护、限流、日志审计、内网服务暴露 等能力的“类 Cloudflare 网关方案”。
一、方案目标
在很多企业场景中,业务系统可能并不希望完全依赖公有云安全网关,原因包括:
- 数据合规要求较高;
- 内部系统不能直接暴露公网;
- 希望掌握完整访问日志;
- 希望自定义安全策略;
- 希望降低长期 SaaS 成本;
- 希望在多云、混合云、本地机房之间统一入口。
因此,我们可以通过自建边缘网关实现类似 Cloudflare 的部分能力。
本方案主要实现以下功能:
| 能力 | 自建方案 |
|---|---|
| HTTPS 证书 | Caddy / Nginx + ACME |
| 反向代理 | Nginx / Caddy / Traefik |
| WAF | ModSecurity + OWASP CRS |
| 访问控制 | Basic Auth / IP 白名单 / OAuth2 Proxy |
| 限流 | Nginx limit_req |
| 日志审计 | Nginx 日志 + Prometheus / Loki |
| 内网穿透 | WireGuard / FRP / Cloudflare Tunnel |
| 安全封禁 | CrowdSec / Fail2ban |
| 容器化部署 | Docker Compose |
| 统一入口 | 私有网关节点 |
二、整体架构设计
推荐架构如下:
用户浏览器
│
▼
公网 DNS
│
▼
自建边缘网关服务器
Nginx / Caddy / Traefik
│
├── WAF:ModSecurity + OWASP CRS
├── TLS:Let's Encrypt / ZeroSSL
├── 限流:Nginx limit_req
├── 访问控制:IP 白名单 / OAuth2 Proxy
├── 日志审计:Loki / Prometheus
│
▼
后端服务
应用服务器 / Kubernetes / 内网主机
如果后端服务没有公网 IP,可以增加一层内网隧道:
用户
│
▼
公网网关
│
▼
WireGuard / FRP / Cloudflare Tunnel
│
▼
内网应用服务器
这个模式适合以下场景:
- 家庭实验室服务暴露;
- 企业内网 OA、GitLab、Jenkins、Wiki;
- Kubernetes Ingress 外部入口;
- 多个业务系统统一 HTTPS 出口;
- 自建零信任访问网关。
三、服务器准备
建议准备一台公网服务器作为边缘网关。
最低配置:
CPU:2 核
内存:2 GB
磁盘:40 GB
系统:Ubuntu 22.04 / Debian 12
带宽:根据业务访问量决定
开放端口:
80/tcp HTTP,用于证书签发和跳转
443/tcp HTTPS 主入口
22/tcp SSH 管理,可修改为非默认端口
51820/udp WireGuard,可选
安装基础组件:
apt update
apt install -y curl wget vim git ufw ca-certificates gnupg lsb-release
安装 Docker:
curl -fsSL https://get.docker.com | bash
systemctl enable docker
systemctl start docker
安装 Docker Compose:
apt install -y docker-compose-plugin
创建部署目录:
mkdir -p /opt/private-cloudflare
cd /opt/private-cloudflare
四、核心组件选择
本文采用以下组件:
| 组件 | 作用 |
|---|---|
| Nginx | 反向代理、HTTPS、限流 |
| ModSecurity | Web 应用防火墙 |
| OWASP CRS | 通用 WAF 规则集 |
| Certbot | 自动申请 HTTPS 证书 |
| CrowdSec | 行为分析与恶意 IP 封禁 |
| WireGuard | 内网安全隧道 |
| Prometheus + Grafana | 监控,可选 |
| Loki | 日志分析,可选 |
这里没有选择 Caddy 的原因是:Caddy 虽然自动 HTTPS 非常方便,但如果要集成 ModSecurity、复杂 WAF 策略和限流,Nginx 的生态更成熟。
五、Docker Compose 配置文件
创建 docker-compose.yml:
version: "3.9"
services:
nginx:
image: owasp/modsecurity-crs:nginx
container_name: private-edge-nginx
restart: always
ports:
- "80:80"
- "443:443"
environment:
PARANOIA: 1
ANOMALY_INBOUND: 5
ANOMALY_OUTBOUND: 4
BLOCKING_PARANOIA: 1
MODSEC_RULE_ENGINE: "On"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./certbot/www:/var/www/certbot
- ./certbot/conf:/etc/letsencrypt
- ./logs/nginx:/var/log/nginx
networks:
- edge
certbot:
image: certbot/certbot
container_name: private-edge-certbot
volumes:
- ./certbot/www:/var/www/certbot
- ./certbot/conf:/etc/letsencrypt
networks:
- edge
whoami:
image: traefik/whoami
container_name: demo-whoami
restart: always
networks:
- edge
networks:
edge:
driver: bridge
这个配置包含三个服务:
nginx:公网入口;certbot:证书申请工具;whoami:测试后端服务。
生产环境中,可以将 whoami 替换成自己的应用,例如 GitLab、Jenkins、企业后台等。
六、Nginx 主配置文件
创建目录:
mkdir -p nginx/conf.d certbot/www certbot/conf logs/nginx
创建 nginx/nginx.conf:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 4096;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server_tokens off;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
client_max_body_size 50m;
gzip on;
gzip_disable "msie6";
gzip_comp_level 5;
gzip_min_length 1k;
gzip_types text/plain text/css application/json application/javascript application/xml image/svg+xml;
real_ip_header X-Forwarded-For;
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
include /etc/nginx/conf.d/*.conf;
}
七、站点反向代理配置
假设你的域名是:
demo.example.com
请先将域名 A 记录解析到这台网关服务器的公网 IP。
创建 nginx/conf.d/demo.example.com.conf:
server {
listen 80;
server_name demo.example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
server_name demo.example.com;
ssl_certificate /etc/letsencrypt/live/demo.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/demo.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
limit_req zone=req_limit_per_ip burst=20 nodelay;
limit_conn conn_limit_per_ip 30;
location / {
proxy_pass http://whoami:80;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Real-IP $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 10s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
首次启动前,由于证书文件还不存在,Nginx 可能无法正常加载 HTTPS 配置。可以先临时注释掉 443 server,申请证书后再恢复。
八、申请 HTTPS 证书
先启动 Nginx:
docker compose up -d nginx
申请证书:
docker compose run --rm certbot certonly \
--webroot \
--webroot-path=/var/www/certbot \
--email admin@example.com \
--agree-tos \
--no-eff-email \
-d demo.example.com
申请成功后,重启 Nginx:
docker compose restart nginx
访问:
https://demo.example.com
如果看到 whoami 返回信息,说明反向代理已经生效。
九、证书自动续期配置
创建续期脚本 renew-cert.sh:
#!/bin/bash
cd /opt/private-cloudflare
docker compose run --rm certbot renew
docker compose exec nginx nginx -s reload
添加执行权限:
chmod +x renew-cert.sh
添加定时任务:
crontab -e
写入:
0 3 * * * /opt/private-cloudflare/renew-cert.sh >> /opt/private-cloudflare/logs/certbot-renew.log 2>&1
这样每天凌晨 3 点会尝试续期证书。如果证书未到期,Certbot 不会重复申请。
十、开启 WAF 防护
当前使用的镜像 owasp/modsecurity-crs:nginx 已经内置 ModSecurity 和 OWASP CRS。
环境变量中:
MODSEC_RULE_ENGINE: "On"
PARANOIA: 1
ANOMALY_INBOUND: 5
ANOMALY_OUTBOUND: 4
含义如下:
| 参数 | 说明 |
|---|---|
MODSEC_RULE_ENGINE |
是否启用阻断模式 |
PARANOIA |
检测等级,越高越严格 |
ANOMALY_INBOUND |
入站异常分数阈值 |
ANOMALY_OUTBOUND |
出站异常分数阈值 |
建议:
- 初次上线:使用
DetectionOnly; - 观察误报:分析日志;
- 稳定后:切换为
On。
例如,调试阶段可以改成:
MODSEC_RULE_ENGINE: "DetectionOnly"
这样 WAF 只记录攻击行为,不直接拦截请求。
十一、IP 白名单访问控制
对于后台系统,例如 Jenkins、GitLab Admin、内部管理后台,建议增加 IP 白名单。
示例配置:
location /admin/ {
allow 1.2.3.4;
allow 5.6.7.0/24;
deny all;
proxy_pass http://backend-admin:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
如果你的管理员 IP 不固定,可以使用 VPN 方案,例如 WireGuard,让管理员先接入 VPN,再访问后台系统。
十二、Basic Auth 访问认证
为某些测试环境增加简单密码认证。
安装 htpasswd 工具:
apt install -y apache2-utils
创建密码文件:
mkdir -p nginx/auth
htpasswd -bc nginx/auth/basic.htpasswd admin 'StrongPasswordHere'
修改 docker-compose.yml,挂载认证文件:
volumes:
- ./nginx/auth:/etc/nginx/auth
Nginx 配置增加:
location / {
auth_basic "Private Area";
auth_basic_user_file /etc/nginx/auth/basic.htpasswd;
proxy_pass http://whoami:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Basic Auth 适合测试环境,不建议作为生产系统唯一认证方式。
十三、接入内网服务:WireGuard 方案
如果后端应用部署在公司内网或家中 NAS,没有公网 IP,可以使用 WireGuard 建立安全隧道。
1. 网关服务器安装 WireGuard
apt install -y wireguard
生成密钥:
wg genkey | tee server_private.key | wg pubkey > server_public.key
创建 /etc/wireguard/wg0.conf:
[Interface]
Address = 10.10.0.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT
[Peer]
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.10.0.2/32
启动:
systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0
2. 内网客户端配置
内网服务器安装 WireGuard 后,创建客户端配置:
[Interface]
Address = 10.10.0.2/24
PrivateKey = CLIENT_PRIVATE_KEY
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = your-public-server-ip:51820
AllowedIPs = 10.10.0.0/24
PersistentKeepalive = 25
启动客户端后,公网网关就可以访问内网服务,例如:
http://10.10.0.2:8080
然后修改 Nginx 代理:
location / {
proxy_pass http://10.10.0.2:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
这样,用户访问公网域名时,实际请求会通过 WireGuard 隧道转发到内网应用。
十四、日志审计与安全分析
Nginx 日志会写入:
/opt/private-cloudflare/logs/nginx/access.log
/opt/private-cloudflare/logs/nginx/error.log
你可以直接查看:
tail -f logs/nginx/access.log
常见攻击请求包括:
/wp-admin
/.env
/phpmyadmin
/admin.php
/cgi-bin
如果日志中大量出现类似请求,可以结合 Fail2ban 或 CrowdSec 自动封禁。
十五、接入 CrowdSec 自动封禁
CrowdSec 可以分析 Nginx 日志,并自动识别扫描器、爆破攻击、恶意 IP。
安装 CrowdSec:
curl -s https://install.crowdsec.net | bash
apt install -y crowdsec
安装 Nginx collection:
cscli collections install crowdsecurity/nginx
systemctl reload crowdsec
安装防火墙 bouncer:
apt install -y crowdsec-firewall-bouncer-iptables
查看告警:
cscli alerts list
查看封禁决策:
cscli decisions list
这样可以实现类似 Cloudflare 防火墙规则和恶意 IP 拦截的部分能力。
十六、防火墙配置
使用 UFW 限制端口:
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 51820/udp
ufw enable
如果 SSH 修改了端口,例如 2222:
ufw allow 2222/tcp
ufw delete allow 22/tcp
建议禁止密码登录 SSH。
修改 /etc/ssh/sshd_config:
PasswordAuthentication no
PermitRootLogin no
重启 SSH:
systemctl restart ssh
十七、多个域名反向代理示例
如果你有多个系统,例如:
git.example.com
wiki.example.com
jenkins.example.com
可以分别创建配置文件。
GitLab 示例
server {
listen 80;
server_name git.example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
server_name git.example.com;
ssl_certificate /etc/letsencrypt/live/git.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/git.example.com/privkey.pem;
client_max_body_size 500m;
location / {
proxy_pass http://10.10.0.2:8929;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Wiki 示例
server {
listen 80;
server_name wiki.example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
server_name wiki.example.com;
ssl_certificate /etc/letsencrypt/live/wiki.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/wiki.example.com/privkey.pem;
location / {
proxy_pass http://10.10.0.3:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
十八、与 Cloudflare 官方能力对比
| 功能 | Cloudflare | 自建方案 |
|---|---|---|
| 全球 CDN | 强 | 需要多节点自建 |
| DDoS 防护 | 强 | 依赖服务器带宽和上游清洗 |
| WAF | 强 | 可用 ModSecurity/Coraza |
| HTTPS | 强 | 可用 Certbot/Caddy |
| Tunnel | 强 | 可用 WireGuard/FRP |
| 访问控制 | 强 | OAuth2 Proxy / Authelia |
| 日志掌控 | 企业版更强 | 完全自控 |
| 成本 | SaaS 订阅 | 服务器与维护成本 |
| 可定制化 | 有限制 | 高 |
| 运维复杂度 | 低 | 中高 |
自建方案的优势是自主可控、灵活度高;缺点是无法天然获得 Cloudflare 全球 Anycast 网络和超大规模 DDoS 清洗能力。
十九、生产环境建议
如果要用于生产环境,建议至少做到以下几点:
-
网关高可用
至少部署两台边缘网关,通过 DNS 轮询、Keepalived 或负载均衡实现冗余。 -
日志集中化
将 Nginx、WAF、系统日志统一接入 Loki、ELK 或 OpenSearch。 -
证书统一管理
对大量域名建议使用 DNS-01 方式申请通配符证书。 -
安全策略分级
普通业务走 WAF,后台系统走 VPN 或零信任认证。 -
定期更新规则
OWASP CRS、Nginx、Docker 镜像应定期升级。 -
备份配置文件
/opt/private-cloudflare目录应纳入 Git 或备份系统。 -
限制源站访问
后端应用只允许来自网关服务器或 WireGuard 网段访问,避免源站绕过安全网关。
二十、完整目录结构
最终目录结构如下:
/opt/private-cloudflare
├── docker-compose.yml
├── renew-cert.sh
├── nginx
│ ├── nginx.conf
│ ├── auth
│ │ └── basic.htpasswd
│ └── conf.d
│ ├── demo.example.com.conf
│ ├── git.example.com.conf
│ └── wiki.example.com.conf
├── certbot
│ ├── conf
│ └── www
└── logs
├── nginx
│ ├── access.log
│ └── error.log
└── certbot-renew.log
二十一、一键启动命令汇总
cd /opt/private-cloudflare
docker compose up -d
docker compose ps
docker compose logs -f nginx
重载 Nginx:
docker compose exec nginx nginx -s reload
停止服务:
docker compose down
更新镜像:
docker compose pull
docker compose up -d
总结
Cloudflare 本身无法完整私有化部署,但我们可以通过 Nginx、ModSecurity、OWASP CRS、Certbot、WireGuard、CrowdSec 等开源组件,自建一套具备反向代理、HTTPS、WAF、访问控制、限流、日志审计和内网穿透能力的私有边缘网关。
这套方案适合企业内部系统、个人实验室、多云混合部署、内网服务安全暴露等场景。它的核心价值在于:把公网入口收敛到自有网关,将安全能力前置,并通过配置文件统一管理访问策略。
如果你的业务对全球访问加速和大规模 DDoS 防护要求很高,仍然建议使用 Cloudflare、AWS CloudFront、Akamai、Fastly 等专业 CDN 和安全厂商;如果你的重点是自主可控、私有化、安全访问和成本优化,那么本文方案是一个非常实用的落地选择。