Nginx的allow/deny仅在http、server、location块中生效,且按顺序匹配,首个匹配即终止;须置于location/server内、deny all收尾,注意$remote_addr为代理IP需修正,IPv6需单独配置。
nginx 配置 allow 和 deny 为什么没生效?
因为 allow/deny 只在 http、server、location 块里生效,且顺序严格:**先匹配的规则优先生效,遇到第一个匹配就停止**。很多人把规则写在 upstream 或错放层级,或者漏了 deny all 收尾,结果白名单形同虚设。
实操建议:
- 必须在
location或server块内配置,例如:location /admin/ {<br> allow 192.168.1.0/24;<br> deny all;<br>} -
allow和deny的顺序不能颠倒——deny all必须放在最后(或明确覆盖所有未授权 IP) - 如果用了反向代理,注意
$remote_addr是上游代理 IP,不是真实客户端 IP;需配合real_ip_header和set_real_ip_from修正 - IPv6 要单独写
allow 2001:db8::/32,不支持混合写法
iptables 拒绝外网访问某端口但保留局域网通路
核心是用 -s 限定源地址范围,再用 -j DROP 或 -j REJECT 终止非信任流量。直接 iptables -P INPUT DROP 是高危操作,容易锁死 SSH。
实操建议:
- 只封特定端口,比如只限制 Web 服务:
iptables -A INPUT -p tcp --dport 80 -s ! 192.168.0.0/16 -j DROP
- 务必先放行本地回环和已建立连接:
iptables -A INPUT -i lo -j ACCEPT<br>iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
- 如果服务器有多个网卡(如 eth0 是内网、eth1 是公网),可按接口过滤:
iptables -A INPUT -i eth1 -p tcp --dport 22 -j DROP - 规则持久化别忘:Ubuntu 用
iptables-persistent,CentOS 7+ 用iptables-save > /etc/sysconfig/iptables
云服务器安全组 vs 本地防火墙,该信谁?
安全组是云平台最外层网络 ACL,优先级高于系统内 iptables 或 firewalld。如果安全组已放行 0.0.0.0/0,那本地防火墙再怎么拦,流量早就进来了。
实操建议:
- 先收紧安全组:只允许
192.168.0.0/16、10.0.0.0/8等内网段访问关键端口(如 22、8080) - 安全组不支持基于 HTTP 头或 URL 的控制,复杂逻辑(比如只允某些内网 IP 访问
/api/internal)必须靠 nginx 或应用层做 - 阿里云/腾讯云的安全组规则是“全拒绝”默认策略,但 AWS 安全组默认是“全放行”,这点容易误判
- 测试时别只 curl 自己机器,要用另一台外网机器验证是否真被挡住——很多开发者只在本机测
curl localhost,结果白忙活
fail2ban 对内网 IP 生效吗?要不要开?
要开,但默认配置会把内网 IP 也拉黑,反而可能误伤运维。fail2ban 本质是动态更新 iptables 规则,它不区分内外网,只看日志匹配和 ignoreip 配置。
实操建议:
- 务必修改
jail.local中的ignoreip:ignoreip = 127.0.0.1/8 192.168.0.0/16 10.0.0.0/8
- 不要对内网服务(如内网 API、数据库管理后台)启用过于激进的 ban 时间,
bantime = 600足够 - fail2ban 日志路径因软件而异:
/var/log/auth.log(SSH)、/var/log/nginx/error.log(nginx 404 扫描),确认监控的是真实访问日志 - 启用后用
fail2ban-client status sshd查当前封禁列表,避免配错正则导致全网拉黑
真正难的不是加几条规则,而是厘清流量路径:请求从网卡进来 → 安全组放行 → iptables 过滤 → nginx 解析 → 应用处理。每层都可能成为漏网之鱼,也都能成为最后一道锁。尤其当用 Docker 或 Kubernetes 时,iptables 规则会被容器运行时自动插入,顺序一乱,白名单就失效。











