mirror of
https://github.com/SunBK201/UA3F.git
synced 2025-12-18 01:35:52 +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)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,6 +175,12 @@ func (f *Firewall) DeleteTproxyRoute(fwmark, routeTable string) error {
|
|||||||
cmd = exec.Command("ip", "route", "flush", "table", routeTable)
|
cmd = exec.Command("ip", "route", "flush", "table", routeTable)
|
||||||
_ = cmd.Run()
|
_ = 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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,10 +3,13 @@
|
|||||||
package base
|
package base
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"net"
|
"net"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"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")
|
return "", errors.New("GetConnFD connection is not *net.TCPConn")
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := tcpConn.File()
|
rawConn, err := tcpConn.SyscallConn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("tcpConn.File: %v", err)
|
return "", fmt.Errorf("SyscallConn: %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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ip := net.IPv4(raw.Multiaddr[4], raw.Multiaddr[5], raw.Multiaddr[6], raw.Multiaddr[7])
|
var originalAddr string
|
||||||
port := uint16(raw.Multiaddr[2])<<8 + uint16(raw.Multiaddr[3])
|
err = rawConn.Control(func(fd uintptr) {
|
||||||
return fmt.Sprintf("%s:%d", ip.String(), port), nil
|
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",
|
"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{
|
prerouting := &knftables.Chain{
|
||||||
@ -175,6 +185,15 @@ func (s *Server) NftSetTproxy(tx *knftables.Transaction, table *knftables.Table)
|
|||||||
"counter accept",
|
"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.
|
// default less hit. sc.
|
||||||
tx.Add(&knftables.Rule{
|
tx.Add(&knftables.Rule{
|
||||||
@ -186,6 +205,15 @@ func (s *Server) NftSetTproxy(tx *knftables.Transaction, table *knftables.Table)
|
|||||||
"counter accept",
|
"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{
|
output := &knftables.Chain{
|
||||||
Name: "OUTPUT",
|
Name: "OUTPUT",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user