You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在AWS EC2实例中配置前端URL及指定IP白名单?

解决AWS EC2 NodeJS后端的机器人请求限制问题

针对你的需求——仅允许Netlify免费层前端和指定个人IP访问EC2后端,以下是几种可行的方案,按推荐优先级排序:

方案1:AWS WAF + CloudFront(最稳定的云原生方案)

因为Netlify免费层无固定IP,直接用EC2安全组无法适配动态IP范围,结合CloudFront和WAF可以实现精准过滤:

  1. 配置CloudFront分发

    • 将EC2实例作为CloudFront的源站,源站协议选择HTTPS(匹配你的后端SSL配置),端口设为后端服务的HTTPS端口(如443)。
    • 确保CloudFront分发启用HTTPS,使用ACM证书覆盖你的后端域名。
  2. 创建WAF Web ACL

    • 在AWS WAF中创建两个允许规则,优先级高于默认的拒绝规则:
      • 规则1:允许指定个人IP:选择IP匹配类型,添加你的个人公网IP(可通过curl ifconfig.me获取),匹配方式设为等于,动作选允许。
      • 规则2:允许Netlify请求:
        1. 先获取Netlify的出口IP范围:执行curl https://api.netlify.com/api/v1/ips,提取其中的outbound数组。
        2. 在WAF中创建IP集,导入上述Netlify IP段。
        3. 创建规则选择IP匹配,关联这个Netlify IP集,动作选允许。
    • 设置Web ACL的默认动作为阻止,拦截所有未匹配规则的请求。
  3. 关联WAF到CloudFront
    在CloudFront分发的设置中,将创建好的Web ACL关联到对应的行为上,确保所有请求先经过WAF过滤再到达EC2。

方案2:Nginx反向代理 + IP/Origin验证(轻量服务器端方案)

如果不想用CloudFront,可以在EC2上部署Nginx作为反向代理,直接在Nginx层面过滤请求:

  1. 安装并配置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;
      }
      
  2. 自动更新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范围同步。

  3. 调整EC2安全组
    安全组仅允许Nginx的443端口对外开放,NodeJS服务端口(如3000)仅允许本地访问(127.0.0.1)。

方案3:NodeJS后端代码层面验证(快速实现)

如果不想额外部署服务,可以直接在NodeJS代码中添加过滤逻辑(以Express为例):

  1. 配置信任代理
    如果有反向代理(如Nginx),先设置Express信任代理,确保获取真实客户端IP:

    const express = require('express');
    const app = express();
    
    // 信任CloudFront/Nginx等反向代理
    app.set('trust proxy', true);
    
  2. 添加中间件过滤请求

    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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 12:44:51