TPROXY: Prevent TCP loopback (#5114)

Fixes https://t.me/projectXray/4434526
pull/4283/merge
风扇滑翔翼 2025-09-10 08:25:52 +08:00 committed by GitHub
parent 11f670c8a6
commit ce5c51d3ba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 34 additions and 0 deletions

View File

@ -2,6 +2,7 @@ package inbound
import (
"context"
gonet "net"
"sync"
"sync/atomic"
"time"
@ -76,6 +77,24 @@ func (w *tcpWorker) callback(conn stat.Connection) {
case internet.SocketConfig_TProxy:
dest = net.DestinationFromAddr(conn.LocalAddr())
}
// Check if try to connect to this inbound itself (can cause loopback)
var isLoopBack bool
if w.address == net.AnyIP || w.address == net.AnyIPv6 {
if dest.Port.Value() == w.port.Value() && IsLocal(dest.Address.IP()) {
isLoopBack = true
}
} else {
if w.hub.Addr().String() == dest.NetAddr() {
isLoopBack = true
}
}
if isLoopBack {
cancel()
conn.Close()
errors.LogError(ctx, errors.New("loopback connection detected"))
return
}
if dest.IsValid() {
outbounds[0].Target = dest
}
@ -544,3 +563,18 @@ func (w *dsWorker) Close() error {
return nil
}
func IsLocal(ip net.IP) bool {
addrs, err := gonet.InterfaceAddrs()
if err != nil {
return false
}
for _, addr := range addrs {
if ipnet, ok := addr.(*gonet.IPNet); ok {
if ipnet.IP.Equal(ip) {
return true
}
}
}
return false
}