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

如何让Nginx模拟主机宕机?禁止通过公网IP访问站点

问题分析与解决方案

你的猜测完全正确:

  • 访问不存在的主机时,客户端发送TCP SYN包后无任何响应,连接无法建立,最终超时判定主机不存在;
  • Nginx的return 444是在TCP三次握手完成后主动关闭连接,客户端仍能感知到服务器存在,和宕机效果差异明显。

要实现“模拟主机宕机”的无响应效果,不能仅依赖Nginx的HTTP层配置——因为Nginx监听端口时,操作系统内核会自动处理TCP握手。必须从网络层面拦截直接IP访问的流量,让服务器彻底不响应这类请求,以下是可行方案:

方案1:用iptables过滤HTTP/HTTPS流量(推荐)

针对HTTP(80端口)

利用iptables的string模块匹配HTTP请求中的Host头,若Host为服务器公网IP,则直接丢弃流量:

# 替换为你的服务器公网IP
PUBLIC_IP="x.x.x.x"

# 丢弃Host头为公网IP的HTTP请求
iptables -A INPUT -p tcp --dport 80 -m string --algo bm --string "Host: $PUBLIC_IP" -j DROP
# 处理带端口的IP访问场景(如x.x.x.x:80)
iptables -A INPUT -p tcp --dport 80 -m string --algo bm --string "Host: $PUBLIC_IP:" -j DROP

针对HTTPS(443端口)

HTTPS的Host头加密,但SNI(Server Name Indication)字段是明文的,可通过iptables的tls模块匹配SNI(需内核支持TLS模块):

PUBLIC_IP="x.x.x.x"

# 丢弃SNI为公网IP的HTTPS请求
iptables -A INPUT -p tcp --dport 443 -m tls --tls-sni $PUBLIC_IP -j DROP

配置后,直接用IP访问的流量会被彻底丢弃,客户端会因长时间无响应判定主机不存在,和访问无效主机的效果完全一致。

方案2:用tc工具模拟超时(备选)

若iptables的string/tls模块无法使用(如内核版本过低),可通过tc工具给直接IP访问的流量设置极高延迟,让客户端超时:

PUBLIC_IP="x.x.x.x"
# 创建根流量队列
tc qdisc add dev eth0 root handle 1: htb default 10
# 创建默认流量类
tc class add dev eth0 parent 1: classid 1:10 htb rate 1000mbit
# 匹配Host头为公网IP的HTTP流量,分配到延迟队列
tc filter add dev eth0 parent 1: protocol ip prio 1 u32 \
    match ip dport 80 0xffff \
    match u8 0x48 0xff at 40 \  # 匹配HTTP请求起始字符'H'
    match u32 $(printf '0x%08x' $(echo $PUBLIC_IP | awk -F. '{print ($1<<24)+($2<<16)+($3<<8)+$4}')) 0xffffffff at 52 \  # 匹配公网IP的十六进制值
    flowid 1:20
# 给目标队列设置10秒延迟
tc qdisc add dev eth0 parent 1:20 netem delay 10000ms

此方法让客户端等待超时,效果接近宕机,但不如iptables DROP彻底。

注意事项

  1. 配置iptables规则后,需保存规则(如iptables-save > /etc/iptables/rules.v4),避免服务器重启后失效;
  2. 若使用CDN服务,可直接在CDN面板配置“仅允许域名访问”,隐藏源站IP,这是更简便的方案。

内容的提问来源于stack exchange,提问作者Alpaca0x0

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 06:05:21