feat: add disable-icmp-forwarding option to tun (#2248)
Some checks failed
Test / test (1.20, macos-13) (push) Has been cancelled
Test / test (1.20, macos-latest) (push) Has been cancelled
Test / test (1.20, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.20, ubuntu-latest) (push) Has been cancelled
Test / test (1.20, windows-latest) (push) Has been cancelled
Test / test (1.21, macos-13) (push) Has been cancelled
Test / test (1.21, macos-latest) (push) Has been cancelled
Test / test (1.21, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.21, ubuntu-latest) (push) Has been cancelled
Test / test (1.21, windows-latest) (push) Has been cancelled
Test / test (1.22, macos-13) (push) Has been cancelled
Test / test (1.22, macos-latest) (push) Has been cancelled
Test / test (1.22, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.22, ubuntu-latest) (push) Has been cancelled
Test / test (1.22, windows-latest) (push) Has been cancelled
Test / test (1.23, macos-13) (push) Has been cancelled
Test / test (1.23, macos-latest) (push) Has been cancelled
Test / test (1.23, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.23, ubuntu-latest) (push) Has been cancelled
Test / test (1.23, windows-latest) (push) Has been cancelled
Test / test (1.24, macos-13) (push) Has been cancelled
Test / test (1.24, macos-latest) (push) Has been cancelled
Test / test (1.24, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.24, ubuntu-latest) (push) Has been cancelled
Test / test (1.24, windows-latest) (push) Has been cancelled
Test / test (1.25, macos-13) (push) Has been cancelled
Test / test (1.25, macos-latest) (push) Has been cancelled
Test / test (1.25, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.25, ubuntu-latest) (push) Has been cancelled
Test / test (1.25, windows-latest) (push) Has been cancelled
Trigger CMFA Update / trigger-CMFA-update (push) Has been cancelled

When enabled, the TUN listener will use fake ping echo. This can be useful to prevent potential ICMP routing loops in certain network configurations.
This commit is contained in:
NuoFang 2025-09-07 19:40:30 +08:00 committed by GitHub
parent fed4b369a3
commit 9a124a390f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 16 additions and 4 deletions

View File

@ -292,6 +292,7 @@ type RawTun struct {
ExcludePackage []string `yaml:"exclude-package" json:"exclude-package,omitempty"` ExcludePackage []string `yaml:"exclude-package" json:"exclude-package,omitempty"`
EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"` EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"`
UDPTimeout int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"` UDPTimeout int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"`
DisableICMPForwarding bool `yaml:"disable-icmp-forwarding" json:"disable-icmp-forwarding,omitempty"`
FileDescriptor int `yaml:"file-descriptor" json:"file-descriptor"` FileDescriptor int `yaml:"file-descriptor" json:"file-descriptor"`
Inet4RouteAddress []netip.Prefix `yaml:"inet4-route-address" json:"inet4-route-address,omitempty"` Inet4RouteAddress []netip.Prefix `yaml:"inet4-route-address" json:"inet4-route-address,omitempty"`
@ -1552,6 +1553,7 @@ func parseTun(rawTun RawTun, general *General) error {
ExcludePackage: rawTun.ExcludePackage, ExcludePackage: rawTun.ExcludePackage,
EndpointIndependentNat: rawTun.EndpointIndependentNat, EndpointIndependentNat: rawTun.EndpointIndependentNat,
UDPTimeout: rawTun.UDPTimeout, UDPTimeout: rawTun.UDPTimeout,
DisableICMPForwarding: rawTun.DisableICMPForwarding,
FileDescriptor: rawTun.FileDescriptor, FileDescriptor: rawTun.FileDescriptor,
Inet4RouteAddress: rawTun.Inet4RouteAddress, Inet4RouteAddress: rawTun.Inet4RouteAddress,

View File

@ -142,6 +142,7 @@ tun:
# gso-max-size: 65536 # 通用分段卸载包的最大大小 # gso-max-size: 65536 # 通用分段卸载包的最大大小
auto-redirect: false # 自动配置 iptables 以重定向 TCP 连接。仅支持 Linux。带有 auto-redirect 的 auto-route 现在可以在路由器上按预期工作,无需干预。 auto-redirect: false # 自动配置 iptables 以重定向 TCP 连接。仅支持 Linux。带有 auto-redirect 的 auto-route 现在可以在路由器上按预期工作,无需干预。
# strict-route: true # 将所有连接路由到 tun 来防止泄漏,但你的设备将无法其他设备被访问 # strict-route: true # 将所有连接路由到 tun 来防止泄漏,但你的设备将无法其他设备被访问
# disable-icmp-forwarding: true # 禁用 ICMP 转发,防止某些情况下的 ICMP 环回问题ping 将不会显示真实的延迟
route-address-set: # 将指定规则集中的目标 IP CIDR 规则添加到防火墙, 不匹配的流量将绕过路由, 仅支持 Linux且需要 nftables`auto-route` 和 `auto-redirect` 已启用。 route-address-set: # 将指定规则集中的目标 IP CIDR 规则添加到防火墙, 不匹配的流量将绕过路由, 仅支持 Linux且需要 nftables`auto-route` 和 `auto-redirect` 已启用。
- ruleset-1 - ruleset-1
- ruleset-2 - ruleset-2
@ -1554,6 +1555,7 @@ listeners:
# - com.android.chrome # - com.android.chrome
# exclude-package: # 排除被路由的 Android 应用包名 # exclude-package: # 排除被路由的 Android 应用包名
# - com.android.captiveportallogin # - com.android.captiveportallogin
# disable-icmp-forwarding: true # 禁用 ICMP 转发,防止某些情况下的 ICMP 环回问题ping 将不会显示真实的延迟
# 入口配置与 Listener 等价,传入流量将和 socks,mixed 等入口一样按照 mode 所指定的方式进行匹配处理 # 入口配置与 Listener 等价,传入流量将和 socks,mixed 等入口一样按照 mode 所指定的方式进行匹配处理
# shadowsocks,vmess 入口配置(传入流量将和 socks,mixed 等入口一样按照 mode 所指定的方式进行匹配处理) # shadowsocks,vmess 入口配置(传入流量将和 socks,mixed 等入口一样按照 mode 所指定的方式进行匹配处理)
# ss-config: ss://2022-blake3-aes-256-gcm:vlmpIPSyHH6f4S8WVPdRIHIlzmB+GIRfoH3aNJ/t9Gg=@:23456 # ss-config: ss://2022-blake3-aes-256-gcm:vlmpIPSyHH6f4S8WVPdRIHIlzmB+GIRfoH3aNJ/t9Gg=@:23456

View File

@ -48,6 +48,7 @@ type Tun struct {
ExcludePackage []string `yaml:"exclude-package" json:"exclude-package,omitempty"` ExcludePackage []string `yaml:"exclude-package" json:"exclude-package,omitempty"`
EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"` EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"`
UDPTimeout int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"` UDPTimeout int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"`
DisableICMPForwarding bool `yaml:"disable-icmp-forwarding" json:"disable-icmp-forwarding,omitempty"`
FileDescriptor int `yaml:"file-descriptor" json:"file-descriptor"` FileDescriptor int `yaml:"file-descriptor" json:"file-descriptor"`
Inet4RouteAddress []netip.Prefix `yaml:"inet4-route-address" json:"inet4-route-address,omitempty"` Inet4RouteAddress []netip.Prefix `yaml:"inet4-route-address" json:"inet4-route-address,omitempty"`
@ -186,6 +187,9 @@ func (t *Tun) Equal(other Tun) bool {
if t.UDPTimeout != other.UDPTimeout { if t.UDPTimeout != other.UDPTimeout {
return false return false
} }
if t.DisableICMPForwarding != other.DisableICMPForwarding {
return false
}
if t.FileDescriptor != other.FileDescriptor { if t.FileDescriptor != other.FileDescriptor {
return false return false
} }

View File

@ -49,6 +49,7 @@ type TunOption struct {
ExcludePackage []string `inbound:"exclude-package,omitempty"` ExcludePackage []string `inbound:"exclude-package,omitempty"`
EndpointIndependentNat bool `inbound:"endpoint-independent-nat,omitempty"` EndpointIndependentNat bool `inbound:"endpoint-independent-nat,omitempty"`
UDPTimeout int64 `inbound:"udp-timeout,omitempty"` UDPTimeout int64 `inbound:"udp-timeout,omitempty"`
DisableICMPForwarding bool `inbound:"disable-icmp-forwarding,omitempty"`
FileDescriptor int `inbound:"file-descriptor,omitempty"` FileDescriptor int `inbound:"file-descriptor,omitempty"`
Inet4RouteAddress []netip.Prefix `inbound:"inet4-route-address,omitempty"` Inet4RouteAddress []netip.Prefix `inbound:"inet4-route-address,omitempty"`
@ -122,6 +123,7 @@ func NewTun(options *TunOption) (*Tun, error) {
ExcludePackage: options.ExcludePackage, ExcludePackage: options.ExcludePackage,
EndpointIndependentNat: options.EndpointIndependentNat, EndpointIndependentNat: options.EndpointIndependentNat,
UDPTimeout: options.UDPTimeout, UDPTimeout: options.UDPTimeout,
DisableICMPForwarding: options.DisableICMPForwarding,
FileDescriptor: options.FileDescriptor, FileDescriptor: options.FileDescriptor,
Inet4RouteAddress: options.Inet4RouteAddress, Inet4RouteAddress: options.Inet4RouteAddress,

View File

@ -21,6 +21,7 @@ import (
type ListenerHandler struct { type ListenerHandler struct {
*sing.ListenerHandler *sing.ListenerHandler
DnsAdds []netip.AddrPort DnsAdds []netip.AddrPort
DisableICMPForwarding bool
} }
func (h *ListenerHandler) ShouldHijackDns(targetAddr netip.AddrPort) bool { func (h *ListenerHandler) ShouldHijackDns(targetAddr netip.AddrPort) bool {

View File

@ -17,7 +17,7 @@ import (
func (h *ListenerHandler) PrepareConnection(network string, source M.Socksaddr, destination M.Socksaddr, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) { func (h *ListenerHandler) PrepareConnection(network string, source M.Socksaddr, destination M.Socksaddr, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
switch network { switch network {
case N.NetworkICMP: // our fork only send those type to PrepareConnection now case N.NetworkICMP: // our fork only send those type to PrepareConnection now
if resolver.IsFakeIP(destination.Addr) { // skip fakeip if h.DisableICMPForwarding || resolver.IsFakeIP(destination.Addr) { // skip fakeip and if ICMP handling is disabled
log.Infoln("[ICMP] %s %s --> %s using fake ping echo", network, source, destination) log.Infoln("[ICMP] %s %s --> %s using fake ping echo", network, source, destination)
return nil, nil return nil, nil
} }

View File

@ -269,6 +269,7 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
handler := &ListenerHandler{ handler := &ListenerHandler{
ListenerHandler: h, ListenerHandler: h,
DnsAdds: dnsAdds, DnsAdds: dnsAdds,
DisableICMPForwarding: options.DisableICMPForwarding,
} }
l = &Listener{ l = &Listener{
closed: false, closed: false,