mirror of
https://github.com/SunBK201/UA3F.git
synced 2025-12-16 16:57:08 +00:00
fix: add ipv6 support
This commit is contained in:
parent
dfe1999616
commit
b939858257
@ -155,6 +155,16 @@ func (f *Firewall) AddTproxyRoute(fwmark, routeTable string) error {
|
||||
return fmt.Errorf("cmd.Run: %w", err)
|
||||
}
|
||||
|
||||
cmd = exec.Command("ip", "-6", "rule", "add", "fwmark", fwmark, "table", routeTable)
|
||||
if err := cmd.Run(); err != nil {
|
||||
slog.Warn("ip -6 rule add", slog.String("error", err.Error()))
|
||||
}
|
||||
|
||||
cmd = exec.Command("ip", "-6", "route", "add", "local", "::/0", "dev", "lo", "table", routeTable)
|
||||
if err := cmd.Run(); err != nil {
|
||||
slog.Warn("ip -6 route add", slog.String("error", err.Error()))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -165,6 +175,12 @@ func (f *Firewall) DeleteTproxyRoute(fwmark, routeTable string) error {
|
||||
cmd = exec.Command("ip", "route", "flush", "table", routeTable)
|
||||
_ = cmd.Run()
|
||||
|
||||
cmd = exec.Command("ip", "-6", "rule", "del", "fwmark", fwmark, "table", routeTable)
|
||||
_ = cmd.Run()
|
||||
|
||||
cmd = exec.Command("ip", "-6", "route", "flush", "table", routeTable)
|
||||
_ = cmd.Run()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -3,10 +3,13 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@ -37,18 +40,43 @@ func GetOriginalDstAddr(conn net.Conn) (addr string, err error) {
|
||||
return "", errors.New("GetConnFD connection is not *net.TCPConn")
|
||||
}
|
||||
|
||||
file, err := tcpConn.File()
|
||||
rawConn, err := tcpConn.SyscallConn()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("tcpConn.File: %v", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
raw, err := unix.GetsockoptIPv6Mreq(int(file.Fd()), unix.SOL_IP, unix.SO_ORIGINAL_DST)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unix.GetsockoptIPv6Mreq: %v", err)
|
||||
return "", fmt.Errorf("SyscallConn: %v", err)
|
||||
}
|
||||
|
||||
ip := net.IPv4(raw.Multiaddr[4], raw.Multiaddr[5], raw.Multiaddr[6], raw.Multiaddr[7])
|
||||
port := uint16(raw.Multiaddr[2])<<8 + uint16(raw.Multiaddr[3])
|
||||
return fmt.Sprintf("%s:%d", ip.String(), port), nil
|
||||
var originalAddr string
|
||||
err = rawConn.Control(func(fd uintptr) {
|
||||
level := syscall.IPPROTO_IP
|
||||
if conn.RemoteAddr().String()[0] == '[' {
|
||||
level = syscall.IPPROTO_IPV6
|
||||
}
|
||||
|
||||
addr, err := syscall.GetsockoptIPv6MTUInfo(int(fd), level, unix.SO_ORIGINAL_DST)
|
||||
if err != nil {
|
||||
slog.Warn("unix.GetsockoptIPv6MTUInfo", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
var ip net.IP
|
||||
if level == syscall.IPPROTO_IPV6 {
|
||||
ip = net.IP(addr.Addr.Addr[:])
|
||||
} else {
|
||||
ipBytes := (*[4]byte)(unsafe.Pointer(&addr.Addr.Flowinfo))[:4]
|
||||
ip = net.IPv4(ipBytes[0], ipBytes[1], ipBytes[2], ipBytes[3])
|
||||
}
|
||||
|
||||
port := binary.BigEndian.Uint16((*[2]byte)(unsafe.Pointer(&addr.Addr.Port))[:2])
|
||||
|
||||
if level == syscall.IPPROTO_IPV6 {
|
||||
originalAddr = fmt.Sprintf("[%s]:%d", ip.String(), port)
|
||||
} else {
|
||||
originalAddr = fmt.Sprintf("%s:%d", ip.String(), port)
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("rawConn.Control: %v", err)
|
||||
}
|
||||
|
||||
return originalAddr, nil
|
||||
}
|
||||
|
||||
@ -96,6 +96,16 @@ func (s *Server) NftSetTproxy(tx *knftables.Transaction, table *knftables.Table)
|
||||
"counter accept",
|
||||
),
|
||||
})
|
||||
tx.Add(&knftables.Rule{
|
||||
Chain: sidecar.Name,
|
||||
Rule: knftables.Concat(
|
||||
"meta l4proto tcp",
|
||||
"mark", s.tproxyFwMark,
|
||||
"mark set 7894",
|
||||
fmt.Sprintf("tproxy ip6 to [::1]:%d", s.Cfg.Port),
|
||||
"counter accept",
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
prerouting := &knftables.Chain{
|
||||
@ -175,6 +185,15 @@ func (s *Server) NftSetTproxy(tx *knftables.Transaction, table *knftables.Table)
|
||||
"counter accept",
|
||||
),
|
||||
})
|
||||
tx.Add(&knftables.Rule{
|
||||
Chain: prerouting.Name,
|
||||
Rule: knftables.Concat(
|
||||
"meta l4proto tcp",
|
||||
"mark", s.tproxyFwMark,
|
||||
fmt.Sprintf("tproxy ip6 to [::1]:%d", s.Cfg.Port),
|
||||
"counter accept",
|
||||
),
|
||||
})
|
||||
|
||||
// default less hit. sc.
|
||||
tx.Add(&knftables.Rule{
|
||||
@ -186,6 +205,15 @@ func (s *Server) NftSetTproxy(tx *knftables.Transaction, table *knftables.Table)
|
||||
"counter accept",
|
||||
),
|
||||
})
|
||||
tx.Add(&knftables.Rule{
|
||||
Chain: prerouting.Name,
|
||||
Rule: knftables.Concat(
|
||||
"meta l4proto tcp",
|
||||
"mark set", s.tproxyFwMark,
|
||||
fmt.Sprintf("tproxy ip6 to [::1]:%d", s.Cfg.Port),
|
||||
"counter accept",
|
||||
),
|
||||
})
|
||||
|
||||
output := &knftables.Chain{
|
||||
Name: "OUTPUT",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user