REJECT、REJECT-DROP、REJECT-NO-DROP分别返回什么?
在Shadowrocket的配置规则中,REJECT策略通过发送TCPRST包或ICMP端口不可达消息向请求方明确告知连接被拒绝,应用在毫秒级内获知失败信息,访问被阻页面时浏览器会立即显示连接重置或拒绝提示;REJECT-DROP策略则静默丢弃所有数据包,既不返回RST也不发送任何反馈,应用只能依赖自身的超时机制在数十秒后判定连接失败,行为上完全模拟了网络丢包或服务器宕机的场景,具有较强的隐蔽性;REJECT-NO-DROP与前两者在实现层级上不同,它不涉及网络层的数据包操作,仅在代理管道内标记该流量不转发,将请求交还给系统网络栈自行处理,其最终行为因应用实现和系统配置而异,通常表现为普通连接超时。在配置实际使用的拒绝规则时,广告拦截和域名屏蔽应优先选用REJECT以获得最快的连接终止速度和最清晰的用户反馈,如果发现REJECT导致某些应用出现异常的重试或弹窗行为,可替换为REJECT-DROP以静默处理,两者选择的关键在于应用兼容性和用户体验的权衡。REJECT-NO-DROP则通常不作为常规拒绝策略使用,更多出现在规则调试和流量观察的临时场景中。日常配置无需过于纠结三者的细微差别,在配置文件中统一使用REJECT即可满足绝大部分屏蔽需求,只有在遇到具体兼容性问题时才调整至其他变体。REJECT:主动发送拒绝信号,明确告知连接被拒绝REJECT返回TCPRST包终止连接当配置规则中指定REJECT策略时,Shadowrocket在匹配到该规则后会向请求的客户端(即设备上的应用)发送一个TCPRST(Reset)包,这是一个明确的连接终止信号,告诉应用“该连接被主动拒绝,请立即关闭”。应用收到RST包后,会立即停止等待响应并显示连接失败,整个过程干脆利落。对于UDP流量,REJECT通常返回一个ICMP端口不可达消息或直接丢弃数据包,具体行为取决于底层协议栈的实现,但整体逻辑与TCP类似——明确告知请求方拒绝发生。应用层感知REJECT的速度最快由于REJECT通过发送网络层的重置包而非等待超时来终止连接,应用在收到RST后会在毫秒级内得知连接被拒绝,不会进入长时间的等待状态。浏览器在访问被REJECT的域名时会立即显示“无法访问此网站”或“连接已重置”的提示,不会出现加载转圈或等待超时的现象。这种即时反馈对于用户排查规则是否生效提供了清晰的信号,当用户访问某网站瞬间被拒绝加载,即可判断是该域名被配置了REJECT规则。REJECT适用于明确的拒绝场景该策略最常用于广告拦截和恶意域名屏蔽,当配置规则判定某个域名属于广告追踪或恶意软件分发源时,REJECT会以最快的速度切断连接,节省设备流量并提升页面加载速度,因为浏览器不需要等待超时再渲染页面。对于用户明确不希望访问的域名,REJECT能提供清晰的拒绝反馈。REJECT-DROP:静默丢弃数据包,不返回任何响应REJECT-DROP不发送RST,模拟数据包在网络中丢失与REJECT发送明确的拒绝信号不同,REJECT-DROP策略在匹配规则后会将数据包直接丢弃(Drop),既不发送TCPRST包,也不返回ICMP错误消息,完全模拟数据包在网络传输过程中丢失的场景。应用在发送请求后,既没有收到服务器的回应,也没有收到连接拒绝的指示,只能通过自身的超时机制来判断连接失败,通常需要等待数十秒才会显示超时错误。应用层感知REJECT-DROP表现为连接超时由于没有收到任何响应信号,应用在尝试连接被REJECT-DROP的域名时,会持续等待并重试,最终因超时而显示“请求超时”或“无法连接到服务器”的错误。这种体验与访问一个不存在的IP地址或服务器宕机时的表现完全一致,用户无法区分是网络问题还是规则拒绝造成的。从应用的角度看,连接请求如同石沉大海,没有获得任何状态反馈。REJECT-DROP的隐蔽性优势REJECT-DROP的设计初衷在于隐藏拒绝行为的存在,使客户端无法区分是被防火墙规则拒绝还是目标服务器本身不可达。在某些网络环境中,明确返回RST可能被某些应用视为检测到防火墙而触发异常行为,而静默丢弃则让应用认为只是网络故障,从而避免额外的错误处理逻辑。对于希望低调屏蔽某些域名而不引起应用特殊反应的场景,REJECT-DROP相比REJECT更为合适。REJECT-NO-DROP:不丢弃数据包,但禁止其通过代理REJECT-NO-DROP在代理层面拦截而不涉及网络丢包REJECT-NO-DROP的行为逻辑与前两者存在本质区别,该策略不是通过丢弃网络数据包或返回拒绝信号来阻断连接,而是在Shadowrocket的代理处理管道中直接标记该请求“不允许通过代理转发”,但不对数据包本身做任何丢弃或重置操作。这意味着匹配该规则的流量既不会被发送至代理节点,也不会被应用发送RST,而是被交还给系统的网络栈,由设备自身的网络协议栈自行处理——通常表现为连接尝试失败,但失败的具体原因因应用和系统实现而异。REJECT-NO-DROP的应用层感知介于两者之间由于REJECT-NO-DROP不干预网络层的包收发,应用在尝试连接被该策略拦截的域名时,可能会经历一个标准连接超时周期,但具体等待时间取决于应用的超时设置和系统网络栈的行为。与REJECT-DROP的静默丢弃不同,REJECT-NO-DROP让流量走完了代理管道内的所有处理逻辑但最终被标记为“不转发”,应用的体验更接近“代理配置错误无法连接”而非“网络不通”。REJECT-NO-DROP适用于特定规则调试场景该策略在实际使用中的场景相对较少,主要出现在用户需要测试分流规则是否生效而不希望实际阻断连接的调试过程中。当用户不确定某个域名是否应该走代理,希望临时观察匹配行为而不真正中断连接时,可临时将策略设为REJECT-NO-DROP,通过日志查看匹配情况而不影响实际网络行为。在常规使用配置中,用户更倾向于使用REJECT或REJECT-DROP来获得明确的拒绝效果。三种策略在网络层的本质区别总结REJECT:积极拒绝,发送RST终止连接从网络协议栈的视角看,REJECT是唯一在传输层主动发送拒绝信号的策略,它在TCP层面通过RST包明确告诉请求方“该连接被拒绝”,请求方不需要等待任何超时即可知道连接失败。UDP层面则因协议无连接特性,通常表现为返回ICMP端口不可达消息或直接丢弃,但总体行为是积极响应的。这种策略最符合常规防火墙的拒绝行为,且对应用友好——应用能快速知道结果并执行相应的错误处理。REJECT-DROP:消极拒绝,静默丢弃所有包REJECT-DROP是消极的拒绝策略,它通过不发送任何响应来模拟网络丢包,让应用在超时后才能判断连接失败。这种策略不暴露拒绝意图,增强了规则屏蔽的隐蔽性,但代价是增加了应用的等待时间,可能影响用户体验。从网络安全的角度看,REJECT-DROP比REJECT更难被探测和绕过,因为探测方无法区分是规则拒绝还是目标不可达。REJECT-NO-DROP:代理层拦截,依赖系统栈行为REJECT-NO-DROP与前两者在实现层级上完全不同,它不涉及网络层的数据包操作,仅在应用层的代理管道中进行拦截。匹配该规则的流量被标记为“不由代理处理”后,完全交给系统网络栈按标准流程处理,而系统在没有有效路由或目标不可达的情况下最终会返回连接错误。这种策略的拒绝行为受系统和应用实现的变量影响,不如前两者在网络层面的行为确定。实际配置中的选择建议广告拦截和域名屏蔽优先使用REJECT对于绝大多数需要阻断特定域名访问的场景,如屏蔽广告域名、恶意软件C&C服务器、隐私追踪器等,REJECT是首选策略。它能够以最快的速度切断连接,避免浏览器或应用长时间等待,提升整体页面加载速度,同时清晰的拒绝信号也便于用户通过浏览器错误提示确认规则生效。REJECT的行为最符合用户对“屏蔽”一词的预期——立即拒绝,不拖沓。隐蔽阻断需求下选择REJECT-DROP在某些特定网络环境中,应用可能对收到RST包存在特殊处理逻辑(如反复重试或记录安全事件),此时REJECT-DROP的静默丢弃方式可以避免触发这些异常行为。例如某些社交应用在收到RST时会弹窗提示网络异常,而静默丢弃则让应用正常超时后自动切换到备用连接机制,用户体验更为平滑。如果用户发现REJECT导致某些应用行为异常,可尝试切换至REJECT-DROP观察是否改善。REJECT-NO-DROP通常不作为常规拒绝策略REJECT-NO-DROP在常规分流配置中的使用频率较低,因其拒绝效果不如REJECT明确且缺乏REJECT-DROP的隐蔽优势。该策略更适合用作规则调试工具,而非生产环境中的拒绝策略。用户在配置文件中如非特殊需求,应优先考虑REJECT和REJECT-DROP。常见问题FAQ







