tproxy

package
v1.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 8, 2022 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package tproxy listens tproxy and setup corresponding iptables for linux.

透明代理只能用于linux。

About TProxy 关于透明代理

透明代理原理 https://www.kernel.org/doc/html/latest/networking/tproxy.html

https://powerdns.org/tproxydoc/tproxy.md.html

golang 示例 https://github.com/LiamHaworth/go-tproxy/blob/master/tproxy_tcp.go

c 语言 示例 https://github.com/FarFetchd/simple_tproxy_example/blob/master/tproxy_captive_portal.c

关键点在于

1. 要使用 syscall.IP_TRANSPARENT 监听

2. 监听到的 连接 的 localAddr实际上是 真实的目标地址, 而不是我们监听的地址;

我们在本包里要做的事情就是 模仿 上面的 golang示例,

但是,上面的go示例有一个特点, 它是直接利用客户端自己的地址+reuse端口的方法去拨号实际地址的,而我们不需要那样做。

而且, udp 的过程更加特殊。

总之,这种情况完全不适配 proxy.Server 的接口, 应该单独拿出来, 属于网络层的特殊情况.

另外就是,偶然发现,trojan-go也是使用的 上面的示例的代码。

同时,trojan-go还使用了. https://github.com/cybozu-go/transocks/blob/master/original_dst_linux.go

不过实测我们不需要用这个代码来获取原始地址,因为地址我们直接就从 localAddr就能获取。也许是trojan-go的作者不懂tproxy的原理吧!

Iptables

iptables配置教程: https://toutyrater.github.io/app/tproxy.html

下面把该教程的重要部分搬过来。

ip rule add fwmark 1 table 100
ip route add local 0.0.0.0/0 dev lo table 100

iptables -t mangle -N V2RAY
iptables -t mangle -A V2RAY -d 127.0.0.1/32 -j RETURN
iptables -t mangle -A V2RAY -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A V2RAY -d 255.255.255.255/32 -j RETURN
iptables -t mangle -A V2RAY -d 192.168.0.0/16 -p tcp -j RETURN
iptables -t mangle -A V2RAY -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN
iptables -t mangle -A V2RAY -p udp -j TPROXY --on-port 12345 --tproxy-mark 1
iptables -t mangle -A V2RAY -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1
iptables -t mangle -A PREROUTING -j V2RAY

iptables -t mangle -N V2RAY_MASK
iptables -t mangle -A V2RAY_MASK -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A V2RAY_MASK -d 255.255.255.255/32 -j RETURN
iptables -t mangle -A V2RAY_MASK -d 192.168.0.0/16 -p tcp -j RETURN
iptables -t mangle -A V2RAY_MASK -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN
iptables -t mangle -A V2RAY_MASK -j RETURN -m mark --mark 0xff
iptables -t mangle -A V2RAY_MASK -p udp -j MARK --set-mark 1
iptables -t mangle -A V2RAY_MASK -p tcp -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -j V2RAY_MASK

Persistent iptables

单独设置iptables,重启后会消失. 下面是 有systemd 的系统的 持久化方法

mkdir -p /etc/iptables && iptables-save > /etc/iptables/rules.v4

vi /etc/systemd/system/tproxyrule.service

[Unit]
Description=Tproxy rule
After=network.target
Wants=network.target

[Service]

Type=oneshot
ExecStart=/sbin/ip rule add fwmark 1 table 100 ; /sbin/ip route add local 0.0.0.0/0 dev lo table 100 ; /sbin/iptables-restore /etc/iptables/rules.v4

[Install]
WantedBy=multi-user.target

systemctl enable tproxyrule

OffTopic

透明代理与Redir的参考博客:

http://ivo-wang.github.io/2018/02/24/ss-redir/

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CleanupIPTables added in v1.2.0

func CleanupIPTables()

clear iptables set by the last SetIPTablesByPort call

func CleanupIPTablesByDefault added in v1.2.0

func CleanupIPTablesByDefault()

port 12345

func DialUDP

func DialUDP(network string, laddr *net.UDPAddr, raddr *net.UDPAddr) (*net.UDPConn, error)

DialUDP connects to the remote address raddr on the network net, which must be "udp", "udp4", or "udp6". If laddr is not nil, it is used as the local address for the connection.

func HandshakeTCP

func HandshakeTCP(tcpConn *net.TCPConn) netLayer.Addr

从一个透明代理tcp连接中读取到实际地址

func HandshakeUDP

func HandshakeUDP(underlay *net.UDPConn) (netLayer.MsgConn, netLayer.Addr, error)

从一个透明代理udp连接中读取到实际地址,并返回 *MsgConn

func ListenUDP

func ListenUDP(network string, laddr *net.UDPAddr) (*net.UDPConn, error)

ListenUDP will construct a new UDP listener socket with the Linux IP_TRANSPARENT option set on the underlying socket

func ReadFromUDP

func ReadFromUDP(conn *net.UDPConn, b []byte) (n int, srcAddr *net.UDPAddr, dstAddr *net.UDPAddr, err error)

ReadFromUDP reads a UDP packet from c, copying the payload into b. It returns the number of bytes copied into b and the return address that was on the packet.

Out-of-band data is also read in so that the original destination address can be identified and parsed.

func SetIPTablesByDefault added in v1.2.0

func SetIPTablesByDefault() error

port 12345

func SetIPTablesByPort added in v1.2.0

func SetIPTablesByPort(port int) error

commands from https://toutyrater.github.io/app/tproxy.html

Types

type Machine

type Machine struct {
	netLayer.Addr
	net.Listener //tcpListener
	*net.UDPConn
}

一个tproxy状态机 具有 监听端口、tcplistener、udpConn 这三个要素。 用于关闭 以及 储存所监听的 端口。

func (*Machine) Stop

func (m *Machine) Stop()

type MsgConn

type MsgConn struct {
	// contains filtered or unexported fields
}

implements netLayer.MsgConn

func (*MsgConn) Close

func (mc *MsgConn) Close() error

func (*MsgConn) CloseConnWithRaddr

func (mc *MsgConn) CloseConnWithRaddr(raddr netLayer.Addr) error

func (*MsgConn) Fullcone

func (mc *MsgConn) Fullcone() bool

func (*MsgConn) ReadMsgFrom

func (mc *MsgConn) ReadMsgFrom() ([]byte, netLayer.Addr, error)

func (*MsgConn) WriteMsgTo

func (mc *MsgConn) WriteMsgTo(p []byte, addr netLayer.Addr) error

通过透明代理 写回 客户端

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL