如何在AWS EC2实例中配置前端URL及指定IP白名单?
解决AWS EC2 NodeJS后端的机器人请求限制问题
针对你的需求——仅允许Netlify免费层前端和指定个人IP访问EC2后端,以下是几种可行的方案,按推荐优先级排序:
方案1:AWS WAF + CloudFront(最稳定的云原生方案)
因为Netlify免费层无固定IP,直接用EC2安全组无法适配动态IP范围,结合CloudFront和WAF可以实现精准过滤:
配置CloudFront分发
- 将EC2实例作为CloudFront的源站,源站协议选择
HTTPS(匹配你的后端SSL配置),端口设为后端服务的HTTPS端口(如443)。 - 确保CloudFront分发启用HTTPS,使用ACM证书覆盖你的后端域名。
- 将EC2实例作为CloudFront的源站,源站协议选择
创建WAF Web ACL
- 在AWS WAF中创建两个允许规则,优先级高于默认的拒绝规则:
- 规则1:允许指定个人IP:选择
IP匹配类型,添加你的个人公网IP(可通过curl ifconfig.me获取),匹配方式设为等于,动作选允许。 - 规则2:允许Netlify请求:
- 先获取Netlify的出口IP范围:执行
curl https://api.netlify.com/api/v1/ips,提取其中的outbound数组。 - 在WAF中创建
IP集,导入上述Netlify IP段。 - 创建规则选择
IP匹配,关联这个Netlify IP集,动作选允许。
- 先获取Netlify的出口IP范围:执行
- 规则1:允许指定个人IP:选择
- 设置Web ACL的默认动作为
阻止,拦截所有未匹配规则的请求。
- 在AWS WAF中创建两个允许规则,优先级高于默认的拒绝规则:
关联WAF到CloudFront
在CloudFront分发的设置中,将创建好的Web ACL关联到对应的行为上,确保所有请求先经过WAF过滤再到达EC2。
方案2:Nginx反向代理 + IP/Origin验证(轻量服务器端方案)
如果不想用CloudFront,可以在EC2上部署Nginx作为反向代理,直接在Nginx层面过滤请求:
安装并配置Nginx
- 安装Nginx后,编辑站点配置文件(如
/etc/nginx/sites-available/your-backend.conf):server { listen 443 ssl; server_name your-backend-domain.com; # 导入你的SSL证书和密钥 ssl_certificate /path/to/your/cert.pem; ssl_certificate_key /path/to/your/key.pem; location / { # 仅允许指定个人IP allow 1.2.3.4; # 替换为你的个人IP # 允许Netlify的出口IP段(需先从Netlify API获取) allow 104.198.14.55/32; allow 104.248.138.0/24; # 补充所有Netlify outbound IP段 # 验证请求Origin是否为你的Netlify域名(防止IP伪造) if ($http_origin != "https://your-netlify-site.netlify.app") { return 403; } # 反向代理到NodeJS后端端口 proxy_pass https://localhost:3000; # 替换为你的NodeJS服务端口 proxy_set_header Host $host; 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; } # 拦截所有未允许的请求 deny all; }
- 安装Nginx后,编辑站点配置文件(如
自动更新Netlify IP
编写简单脚本定期拉取Netlify最新IP并更新Nginx配置,示例脚本:#!/bin/bash NETLIFY_IPS=$(curl -s https://api.netlify.com/api/v1/ips | jq -r '.outbound[]') CONFIG_FILE="/etc/nginx/sites-available/your-backend.conf" # 清除旧的Netlify IP规则 sed -i '/allow 104\./d' $CONFIG_FILE # 添加新的Netlify IP规则 for ip in $NETLIFY_IPS; do sed -i "/allow 1.2.3.4;/a allow $ip;" $CONFIG_FILE done # 重启Nginx systemctl restart nginx用
crontab设置每天执行一次,确保IP范围同步。调整EC2安全组
安全组仅允许Nginx的443端口对外开放,NodeJS服务端口(如3000)仅允许本地访问(127.0.0.1)。
方案3:NodeJS后端代码层面验证(快速实现)
如果不想额外部署服务,可以直接在NodeJS代码中添加过滤逻辑(以Express为例):
配置信任代理
如果有反向代理(如Nginx),先设置Express信任代理,确保获取真实客户端IP:const express = require('express'); const app = express(); // 信任CloudFront/Nginx等反向代理 app.set('trust proxy', true);添加中间件过滤请求
const allowedPersonalIp = '1.2.3.4'; // 你的个人IP const allowedNetlifyDomain = 'https://your-netlify-site.netlify.app'; // 预存Netlify出口IP范围(需定期更新) const allowedNetlifyIps = [ '104.198.14.55/32', '104.248.138.0/24', // 补充所有Netlify outbound IP段 ]; // 验证IP是否在允许范围内的工具函数 function isIpAllowed(ip, allowedIps) { const ipInt = ip.split('.').reduce((acc, octet) => (acc << 8) + parseInt(octet, 10), 0) >>> 0; return allowedIps.some(cidr => { const [range, mask] = cidr.split('/'); const rangeInt = range.split('.').reduce((acc, octet) => (acc << 8) + parseInt(octet, 10), 0) >>> 0; const maskInt = -1 << (32 - parseInt(mask, 10)); return (ipInt & maskInt) === (rangeInt & maskInt); }); } app.use((req, res, next) => { const clientIp = req.ip; const origin = req.get('Origin'); // 检查是否为个人IP if (clientIp === allowedPersonalIp) { return next(); } // 检查是否为Netlify来源:IP在允许范围且Origin匹配 if (isIpAllowed(clientIp, allowedNetlifyIps) && origin === allowedNetlifyDomain) { return next(); } // 拦截非法请求 res.status(403).send('Forbidden'); });
注意事项
- Netlify的IP范围会定期更新,无论用哪种方案,都需要确保IP列表同步,避免前端访问被拦截。
- SSL证书要确保在对应的代理层(CloudFront/Nginx)或后端正确配置,避免HTTPS连接失败。
- 测试规则时,用个人IP和Netlify前端分别发起请求,确认正常访问,同时验证随机请求会被拦截。
内容的提问来源于stack exchange,提问作者RoachCat
相关产品推荐
相关产品推荐

