Closed zppan closed 1 year ago
具体速度可能会受到 ssr-local/server 的影响,理论上是多线程性能更好。
我也是这么理解的,多次测试了是有差别,多线程峰值在 250Mbps,单线程峰值能上到 300Mbps。
顺便请教个问题: ip rule add fwmark 0x69 lookup 169 ip route add local 0.0.0.0/0 dev lo table 169 通过上面的路由表后的包是回到 PREROUTING 吗?还是说环回的包跳过了 PREROUTING 链,我的理解是从 lo 出来的数据包应该跟 eth1 进来的数据包一样是完全经过所有链才对吧,但奇怪的是iptables -t nat -A PREROUTING -p tcp -j TEST 捕获不到环回的包,而 iptables -t mangle -A PREROUTING -p tcp -j tpGFW 却能捕获。
#----------------------------------------------------------------
iptables -t mangle -N tpGFW
iptables -t mangle -A tpGFW -d 0.0.0.0/8 -j RETURN
iptables -t mangle -A tpGFW -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A tpGFW -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A tpGFW -d 169.254.0.0/16 -j RETURN
iptables -t mangle -A tpGFW -d 192.168.0.0/16 -j RETURN
iptables -t mangle -A tpGFW -p tcp -j TPROXY --tproxy-mark 0x69 --on-port 1087
#----------------------------------------------------------------
iptables -t nat -N TEST
iptables -t nat -A TEST -j RETURN
#----------------------------------------------------------------
iptables -t mangle -A OUTPUT -p tcp -d 1.1.1.1 -j MARK --set-mark 0x69
iptables -t mangle -A PREROUTING -p tcp -d 1.1.1.1 -j tpGFW
iptables -t nat -A PREROUTING -p tcp -j TEST
ip rule add fwmark 0x69 lookup 169
ip route add local 0.0.0.0/0 dev lo table 169
###################################################
iptables -t mangle -A PREROUTING -p tcp -d 1.1.1.1 -j tpGFW
#这句能捕获 OUTPUT -p tcp -d 1.1.1.1 -j MARK --set-mark 0x69 环回的包
iptables -t nat -A PREROUTING -p tcp -j TEST
#这句捕获不到 OUTPUT -p tcp -d 1.1.1.1 -j MARK --set-mark 0x69 环回的包
#就有点搞不懂 mark --set-mark 0x69 环回的包到底是有进入 PREROUTING 还是没进入 PREROUTING
谢谢,在国内的坛子发贴太麻烦,只能请教你了。
我对linux内核和iptables这块不是很熟悉,只能帮你测试分析下,无法完全回答你的疑问。
我测试了你发的规则,并添加了几条log规则,具体如下:
# Generated by iptables-save v1.4.21 on Fri Nov 18 12:45:49 2022
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [4:240]
:POSTROUTING ACCEPT [4:240]
:TEST - [0:0]
-A PREROUTING -p tcp -j LOG --log-prefix before_enter_test
-A PREROUTING -p tcp -j TEST
-A PREROUTING -p tcp -j LOG --log-prefix after_enter_test
-A TEST -j LOG --log-prefix nat-test-chain
-A TEST -j RETURN
COMMIT
# Completed on Fri Nov 18 12:45:49 2022
# Generated by iptables-save v1.4.21 on Fri Nov 18 12:45:49 2022
*mangle
:PREROUTING ACCEPT [13056:1030409]
:INPUT ACCEPT [13060:1030633]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [11253:1143840]
:POSTROUTING ACCEPT [11253:1143840]
:tpGFW - [0:0]
-A PREROUTING -d 1.1.1.1/32 -p tcp -j LOG --log-prefix before_enter_tpGFW
-A PREROUTING -d 1.1.1.1/32 -p tcp -j tpGFW
-A PREROUTING -d 1.1.1.1/32 -p tcp -j LOG --log-prefix after_enter_tpGFW
-A OUTPUT -d 1.1.1.1/32 -p tcp -j MARK --set-xmark 0x69/0xffffffff
-A tpGFW -d 0.0.0.0/8 -j RETURN
-A tpGFW -d 10.0.0.0/8 -j RETURN
-A tpGFW -d 127.0.0.0/8 -j RETURN
-A tpGFW -d 169.254.0.0/16 -j RETURN
-A tpGFW -d 192.168.0.0/16 -j RETURN
-A tpGFW -p tcp -j LOG --log-prefix before_tproxy
-A tpGFW -p tcp -j TPROXY --on-port 1087 --on-ip 0.0.0.0 --tproxy-mark 0x69/0xffffffff
-A tpGFW -p tcp -j LOG --log-prefix after_tproxy
COMMIT
# Completed on Fri Nov 18 12:45:49 2022
然后这是ipt2socks的运行log
$ ipt2socks -l 1087 -v
2022-11-18 12:42:57 INF: [main] server address: 127.0.0.1#1080
2022-11-18 12:42:57 INF: [main] listen address: 127.0.0.1#1087
2022-11-18 12:42:57 INF: [main] listen address: ::1#1087
2022-11-18 12:42:57 INF: [main] udp cache maximum size: 256
2022-11-18 12:42:57 INF: [main] udp socket idle timeout: 60
2022-11-18 12:42:57 INF: [main] number of worker threads: 1
2022-11-18 12:42:57 INF: [main] enable tcp transparent proxy
2022-11-18 12:42:57 INF: [main] enable udp transparent proxy
2022-11-18 12:42:57 INF: [main] verbose mode (affect performance)
2022-11-18 12:43:00 INF: [tcp_tproxy_accept_cb] source socket address: 192.168.136.128#58084
2022-11-18 12:43:00 INF: [tcp_tproxy_accept_cb] target socket address: 1.1.1.1#8080
2022-11-18 12:43:00 INF: [tcp_tproxy_accept_cb] try to connect to 127.0.0.1#1080 ...
2022-11-18 12:43:00 ERR: [tcp_socks5_connect_cb] connect to 127.0.0.1#1080: Connection refused
2022-11-18 12:44:04 INF: [tcp_tproxy_accept_cb] source socket address: 192.168.136.128#58088
2022-11-18 12:44:04 INF: [tcp_tproxy_accept_cb] target socket address: 1.1.1.1#8080
2022-11-18 12:44:04 INF: [tcp_tproxy_accept_cb] try to connect to 127.0.0.1#1080 ...
2022-11-18 12:44:04 ERR: [tcp_socks5_connect_cb] connect to 127.0.0.1#1080: Connection refused
^C
这是 dmesg -w 的日志输出
[922690.978201] before_enter_tpGFWIN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=60087 DF PROTO=TCP SPT=58084 DPT=8080 WINDOW=29200RES=0x00 SYN URGP=0 MARK=0x69
[922690.978204] before_tproxyIN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=60087 DF PROTO=TCP SPT=58084 DPT=8080 WINDOW=29200 RES=0x00 SYN URGP=0 MARK=0x69
[922690.978223] before_enter_tpGFWIN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=60088 DF PROTO=TCP SPT=58084 DPT=8080 WINDOW=115 RES=0x00 ACK URGP=0 MARK=0x69
[922690.978224] before_tproxyIN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=60088 DF PROTO=TCP SPT=58084 DPT=8080 WINDOW=115 RES=0x00 ACK URGP=0 MARK=0x69
[922754.556170] before_enter_tpGFWIN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=61026 DF PROTO=TCP SPT=58088 DPT=8080 WINDOW=29200RES=0x00 SYN URGP=0 MARK=0x69
[922754.556174] before_tproxyIN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=61026 DF PROTO=TCP SPT=58088 DPT=8080 WINDOW=29200 RES=0x00 SYN URGP=0 MARK=0x69
[922754.556230] before_enter_tpGFWIN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=61027 DF PROTO=TCP SPT=58088 DPT=8080 WINDOW=115 RES=0x00 ACK URGP=0 MARK=0x69
[922754.556232] before_tproxyIN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=61027 DF PROTO=TCP SPT=58088 DPT=8080 WINDOW=115 RES=0x00 ACK URGP=0 MARK=0x69
^C
这是telnet 1.1.1.1 8080输出:
$ telnet 1.1.1.1 8080
Trying 1.1.1.1...
Connected to 1.1.1.1.
Escape character is '^]'.
Connection closed by foreign host.
$ telnet 1.1.1.1 8080
Trying 1.1.1.1...
Connected to 1.1.1.1.
Escape character is '^]'.
Connection closed by foreign host.
以下均为个人猜测,因为网上关于这块的资料太少了,有兴趣的只能阅读源码。。
-j TPROXY
这个target 会‘消耗’掉被匹配的数据包(PREROUTING链结束)具体 TPROXY 这个target里面做了啥,估计只有查看相关 C 源码才能知道
我这边只能给你几个参考链接:
建议在 raw 表的 OUTPUT、PREROUTING 设置 TRACE 规则,dmesg -w 分析log,查看数据包的走向及匹配情况
我加了TRACE规则 (telnet->1.1.1.1方向):
# root @ vm-centos7 in ~ [12:47:32]
$ iptables -t raw -I PREROUTING -p tcp -d 1.1.1.1 -j TRACE
# root @ vm-centos7 in ~ [13:11:57]
$ iptables -t raw -I OUTPUT -p tcp -d 1.1.1.1 -j TRACE
这是dmesg -w输出,具体分析如下:
###### 这里是 telnet->1.1.1.1:8080 方向的 SYN 包,首先数据包进入 OUTPUT 链
###### 注意看这里的 OUT=eth0
[924455.513870] TRACE: raw:OUTPUT:policy:2 IN= OUT=eth0 SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=18176 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351525 ACK=0 WINDOW=29200 RES=0x00 SYN URGP=0 OPT (020405B40402080A371617250000000001030308) UID=0 GID=0
[924455.513891] TRACE: mangle:OUTPUT:rule:1 IN= OUT=eth0 SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=18176 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351525 ACK=0 WINDOW=29200 RES=0x00 SYNURGP=0 OPT (020405B40402080A371617250000000001030308) UID=0 GID=0
[924455.513921] TRACE: mangle:OUTPUT:policy:2 IN= OUT=eth0 SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=18176 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351525 ACK=0 WINDOW=29200 RES=0x00 SYN URGP=0 OPT (020405B40402080A371617250000000001030308) UID=0 GID=0 MARK=0x69
[924455.513929] TRACE: nat:OUTPUT:policy:1 IN= OUT=eth0 SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=18176 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351525 ACK=0 WINDOW=29200 RES=0x00 SYN URGP=0 OPT (020405B40402080A371617250000000001030308) UID=0 GID=0 MARK=0x69
###### OUTPUT之后,数据包被路由系统处理(ip rule/route),即 local default dev lo 这条规则
###### 关键在于 `local`,查看 man 文档得知,这是一个 route type,意思是将数据包提交到本地网络栈
###### 同时注意这里的 OUT=lo,说明符合我们的猜想,数据包确实被发往 lo 了
###### 路由之后,进入 POSTROUTING 链
[924455.513932] TRACE: mangle:POSTROUTING:policy:1 IN= OUT=lo SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=18176 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351525 ACK=0 WINDOW=29200 RES=0x00 SYN URGP=0 OPT (020405B40402080A371617250000000001030308) UID=0 GID=0 MARK=0x69
[924455.513934] TRACE: nat:POSTROUTING:policy:1 IN= OUT=lo SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=18176 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351525 ACK=0 WINDOW=29200 RES=0x00 SYN URGP=0 OPT (020405B40402080A371617250000000001030308) UID=0 GID=0 MARK=0x69
###### 因为该握手包被发送至 lo,所以会从 lo 网卡收到此包,然后进入 PREROUTING(数据包进入'主机'的第一个链)
###### 而且可以看到此处的 IN=lo
[924455.513941] TRACE: raw:PREROUTING:rule:1 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=18176 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351525 ACK=0 WINDOW=29200 RES=0x00 SYN URGP=0 OPT (020405B40402080A371617250000000001030308) MARK=0x69
[924455.513943] TRACE: raw:PREROUTING:policy:2 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=18176 DF PROTO=TCP SPT=58092 DPT=8080SEQ=3180351525 ACK=0 WINDOW=29200 RES=0x00 SYN URGP=0 OPT (020405B40402080A371617250000000001030308) MARK=0x69
[924455.513946] TRACE: mangle:PREROUTING:rule:1 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=18176 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351525 ACK=0 WINDOW=29200 RES=0x00 SYN URGP=0 OPT (020405B40402080A371617250000000001030308) MARK=0x69
[924455.513948] before_enter_tpGFWIN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=18176 DF PROTO=TCP SPT=58092 DPT=8080 WINDOW=29200RES=0x00 SYN URGP=0 MARK=0x69
[924455.513950] TRACE: mangle:PREROUTING:rule:2 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=18176 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351525 ACK=0 WINDOW=29200 RES=0x00 SYN URGP=0 OPT (020405B40402080A371617250000000001030308) MARK=0x69
[924455.513953] TRACE: mangle:tpGFW:rule:6 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=18176 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351525 ACK=0 WINDOW=29200 RES=0x00 SYN URGP=0 OPT (020405B40402080A371617250000000001030308) MARK=0x69
[924455.513954] before_tproxyIN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=18176 DF PROTO=TCP SPT=58092 DPT=8080 WINDOW=29200 RES=0x00 SYN URGP=0 MARK=0x69
##### 这里的第7条rule,就是TPROXY
[924455.513957] TRACE: mangle:tpGFW:rule:7 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=18176 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351525 ACK=0 WINDOW=29200 RES=0x00 SYN URGP=0 OPT (020405B40402080A371617250000000001030308) MARK=0x69
##### 可以看到,tproxy处理后,数据包被'结束匹配',因此prerouting结束,进入路由系统
##### 由于目的地是本地(IN=lo),因此进入INPUT(见下),经内核处理后,被送入应用层(ipt2socks)
[924455.513961] TRACE: mangle:INPUT:policy:1 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=18176 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351525 ACK=0 WINDOW=29200 RES=0x00 SYN URGP=0 OPT (020405B40402080A371617250000000001030308) UID=0 GID=0 MARK=0x69
##### 因为 TCP 握手是这样:
##### 1. c->s SYN
##### 2. s->c SYN+ACK
##### 3. c->s ACK
##### 我这里并没有 TRACE s->c 这个方向(ipt2socks->telnet),所以没有log,有兴趣可以自己加trace观察
##### 这里是 telnet->1.1.1.1:8080 方向的 ACK 包(3 c->s ACK),其实流程与最开始的 SYN 包是一样的,就不继续分析了
[924455.513985] TRACE: raw:OUTPUT:policy:2 IN= OUT=eth0 SRC=192.168.136.128 DST=1.1.1.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=18177 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351526 ACK=2965863369 WINDOW=115 RES=0x00 ACK URGP=0 OPT (0101080A3716172537161725) UID=0 GID=0
[924455.513989] TRACE: mangle:OUTPUT:rule:1 IN= OUT=eth0 SRC=192.168.136.128 DST=1.1.1.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=18177 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351526 ACK=2965863369 WINDOW=115 RES=0x00 ACK URGP=0 OPT (0101080A3716172537161725) UID=0 GID=0
[924455.513990] TRACE: mangle:OUTPUT:policy:2 IN= OUT=eth0 SRC=192.168.136.128 DST=1.1.1.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=18177 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351526 ACK=2965863369 WINDOW=115 RES=0x00 ACK URGP=0 OPT (0101080A3716172537161725) UID=0 GID=0 MARK=0x69
[924455.513993] TRACE: mangle:POSTROUTING:policy:1 IN= OUT=lo SRC=192.168.136.128 DST=1.1.1.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=18177 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351526 ACK=2965863369 WINDOW=115 RES=0x00 ACK URGP=0 OPT (0101080A3716172537161725) UID=0 GID=0 MARK=0x69
[924455.513996] TRACE: raw:PREROUTING:rule:1 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=18177 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351526 ACK=2965863369 WINDOW=115 RES=0x00 ACK URGP=0 OPT (0101080A3716172537161725) MARK=0x69
[924455.513998] TRACE: raw:PREROUTING:policy:2 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=18177 DF PROTO=TCP SPT=58092 DPT=8080SEQ=3180351526 ACK=2965863369 WINDOW=115 RES=0x00 ACK URGP=0 OPT (0101080A3716172537161725) MARK=0x69
[924455.514000] TRACE: mangle:PREROUTING:rule:1 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=18177 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351526 ACK=2965863369 WINDOW=115 RES=0x00 ACK URGP=0 OPT (0101080A3716172537161725) MARK=0x69
[924455.514002] before_enter_tpGFWIN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=18177 DF PROTO=TCP SPT=58092 DPT=8080 WINDOW=115 RES=0x00 ACK URGP=0 MARK=0x69
[924455.514004] TRACE: mangle:PREROUTING:rule:2 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=18177 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351526 ACK=2965863369 WINDOW=115 RES=0x00 ACK URGP=0 OPT (0101080A3716172537161725) MARK=0x69
[924455.514006] TRACE: mangle:tpGFW:rule:6 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=18177 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351526 ACK=2965863369 WINDOW=115 RES=0x00 ACK URGP=0 OPT (0101080A3716172537161725) MARK=0x69
[924455.514007] before_tproxyIN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=18177 DF PROTO=TCP SPT=58092 DPT=8080 WINDOW=115 RES=0x00 ACK URGP=0 MARK=0x69
### 此处是tproxy规则
[924455.514009] TRACE: mangle:tpGFW:rule:7 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=18177 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351526 ACK=2965863369 WINDOW=115 RES=0x00 ACK URGP=0 OPT (0101080A3716172537161725) MARK=0x69
### tproxy后(不在继续匹配prerouting的规则,因此prerouting结束,进入路由,然后进入input,交给应用层
[924455.514012] TRACE: mangle:INPUT:policy:1 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.136.128 DST=1.1.1.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=18177 DF PROTO=TCP SPT=58092 DPT=8080 SEQ=3180351526 ACK=2965863369 WINDOW=115 RES=0x00 ACK URGP=0 OPT (0101080A3716172537161725) UID=0 GID=0 MARK=0x69
原来还有 LOG 跟 TRACE 可以调试,这样就好办多了,路由器本机包 MARK --set-mark 跟局域网进来的包 TPROXY --tproxy-mark 路径是有差别的,局域网进来的包 TPROXY 后仍然会有包被 nat PREROUTING 捕获,但不是全部,我之前留了 nat 规则配置 TPROXY 就一直不成功,有 LOG 跟 TRACE 我自己再调试分析一下,应该就能弄明白了。谢谢
有意思, 我查看了一下 man ip-rule, ip-route
, 然后了解到这两条规则的作用如下:
ip rule add fwmark 0x69 table 169
# mark 为 0x69 的包, 送到 table 169 处理. 'table 169' 也可以用 'lookup 169', 他们等效
ip route add local default dev lo table 169
# table 169 里面的目的地为 default 的包 (等于是所有包了), 都当做目的地为本地, 并且让他们从lo 发出.
# 这个 default 的意思是 ipv4的 0/0 或者 0.0.0.0/0 或者 ipv6 的 ::/0, 所以写成后者也可以.
# 这个阶段之后, 数据已经交给 tproxy 的端口接管了
所以 @zfl9 你 trace 下来, 觉得 ss-tproxy 的 iptables 规则是否有什么优化的地方呢? 如果没有, 那么 @zppan 那边的问题就是 CPU 性能问题了, 因为在跑 speedtest.net 的时候, 其实 ipt2socks 和 ssr-local 在使用 cpu 资源方面存在竞争, 如果资源不足, ipt2socks 用单线程反而会提高速度, 因为能更好的平衡 cpu 资源.
补充一点: 数据包是先经过 iptables 处理, 然后再由 ip rule/route 处理, 然后再送到 ipt2socks 的 tproxy 的端口. 理解这个顺序很重要
ss-tproxy的iptables规则,之前写的时候,是一边 TRACE 一边改的,目前我想不出其他优化点了:joy:
至于性能/速度问题,我个人还是猜测,与 ss-local <-> ss-server 之间的链路性能/质量 有关,
原来还有 LOG 跟 TRACE 可以调试,这样就好办多了,路由器本机包 MARK --set-mark 跟局域网进来的包 TPROXY --tproxy-mark 路径是有差别的,局域网进来的包 TPROXY 后仍然会有包被 nat PREROUTING 捕获,但不是全部,我之前留了 nat 规则配置 TPROXY 就一直不成功,有 LOG 跟 TRACE 我自己再调试分析一下,应该就能弄明白了。谢谢
建议加上 TRACE,留意 MARK 字段。
上面测试本机发出的包,在 prerouting 中被 tproxy 处理后,就结束 prerouting 链的匹配了,进入路由(route)。
至于你说的外部主机发过来的包,在tproxy处理后的是否会结束prerouting匹配,期待你的测试结果哈。
iptables -t nat -A PREROUTING -p tcp -j TEST
#这句捕获不到 OUTPUT -p tcp -d 1.1.1.1 -j MARK --set-mark 0x69 环回的包
捕获不到 nat 很正常, 因为 mark 了的包是在 mangle 表处理就直接 policy routing 然后送到 tproxy 端口了. 压根就没去 nat 表.
iptables -t mangle -A OUTPUT -p tcp -d 1.1.1.1 -j MARK --set-mark 0x69
iptables -t mangle -A tpGFW -p tcp -j TPROXY --tproxy-mark 0x69 --on-port 1087
你这两条规则, -d 1.1.1.1 的包被打了2次 mark , 虽然打的 mark 是一样的... . 第一条规则 打了 mark 触发 reroute 到 prerouting, 然后第二条再打一次 mark. @zppan
哦对了, ipt2socks 配合 trojan-r (rust 写的 trojan 客户端) 最高速度能跑个 700M 左右, 在 ARM 的 A53 上, 4核心 1.5G最高速度 (斐讯 n1), 而且还是用 speedtest 的命令行软件跑的, 也就是 speedtest + ipt2socks + trojan-r 跑在同一个 A53 cpu上, 且 speedtest 走的代理, 测的是加州的服务器.
你这两条规则, -d 1.1.1.1 的包被打了2次 mark , 虽然打的 mark 是一样的.
打了两次mark这个确实,我个人比较倾向于使用 -j MARK 来标记,然后最后统一使用 TPROXY 导到透明代理去。这样本机和外部(局域网主机)发来的包,处理流程比较一致
有意思, 我查看了一下
man ip-rule, ip-route
, 然后了解到这两条规则的作用如下:ip rule add fwmark 0x69 table 169 # mark 为 0x69 的包, 送到 table 169 处理. 'table 169' 也可以用 'lookup 169', 他们等效 ip route add local default dev lo table 169 # table 169 里面的目的地为 default 的包 (等于是所有包了), 都当做目的地为本地, 并且让他们从lo 发出. # 这个 default 的意思是 ipv4的 0/0 或者 0.0.0.0/0 或者 ipv6 的 ::/0, 所以写成后者也可以. # 这个阶段之后, 数据已经交给 tproxy 的端口接管了
所以 @zfl9 你 trace 下来, 觉得 ss-tproxy 的 iptables 规则是否有什么优化的地方呢? 如果没有, 那么 @zppan 那边的问题就是 CPU 性能问题了, 因为在跑 speedtest.net 的时候, 其实 ipt2socks 和 ssr-local 在使用 cpu 资源方面存在竞争, 如果资源不足, ipt2socks 用单线程反而会提高速度, 因为能更好的平衡 cpu 资源.
补充一点: 数据包是先经过 iptables 处理, 然后再由 ip rule/route 处理, 然后再送到 ipt2socks 的 tproxy 的端口. 理解这个顺序很重要
Intel(R) Atom(TM) CPU E3845 @ 1.91GHz 4GRAM 单跑 openwrt,我测试的时候 CPU load 3.2 ( 主要是 python 节点监测程序占用多),测试速度跟 TPROXY 或者 REDIRECT 模式无关,我试下来速度由高到低顺序如下:ssr-redir(300Mbps) > ipt2socks单线程 + ssr-local(270Mbps) > ipt2socks 4线程 + ssr-local(250Mbps),速度为多次测试的均值,测试过程中 ssr-redir 跟 ssr-local 没有重新连接或切换节点。
@zppan 所以你这个服务器也当路由器用? 我的n1是作为旁路用. 可能区别在于这里吧.
iptables -t nat -A PREROUTING -p tcp -j TEST #这句捕获不到 OUTPUT -p tcp -d 1.1.1.1 -j MARK --set-mark 0x69 环回的包
捕获不到 nat 很正常, 因为 mark 了的包是在 mangle 表处理就直接 policy routing 然后送到 tproxy 端口了. 压根就没去 nat 表.
iptables -t mangle -A OUTPUT -p tcp -d 1.1.1.1 -j MARK --set-mark 0x69 iptables -t mangle -A tpGFW -p tcp -j TPROXY --tproxy-mark 0x69 --on-port 1087
你这两条规则, -d 1.1.1.1 的包被打了2次 mark , 虽然打的 mark 是一样的... . 第一条规则 打了 mark 触发 reroute 到 prerouting, 然后第二条再打一次 mark. @zppan
1.1.1.1 是经过了dns-forwarder 转为 TCP DNS 就到了 OUTPUT 了,就要 mark 环回到 PREROUTING 才能进 TPROXY。
@zppan 所以你这个服务器也当路由器用? 我的n1是作为旁路用. 可能区别在于这里吧.
就是一个跑着 ssr-local 的主路由,没跑别的服务了,负载跟你的旁路由差别不大,只是 Netflix 经常要换节点,就自己写了个 python 小程序监测当前节点解锁情况及自动切换 ssr 节点而已。
你试试下载这个 cli , 然后在路由器本机跑测速: https://install.speedtest.net/app/cli/ookla-speedtest-1.2.0-linux-x86_64.tgz , 看看能跑多少?
你试试下载这个 cli , 然后在路由器本机跑测速: https://install.speedtest.net/app/cli/ookla-speedtest-1.2.0-linux-x86_64.tgz , 看看能跑多少?
用程序跑就都差不多了,都能上到300Mbps(应该是我家宽带的极限吧),奇怪网页端却有差异,哈哈
网页端, 有路由器的网络地址转换消耗... 这消耗还不小.
原来还有 LOG 跟 TRACE 可以调试,这样就好办多了,路由器本机包 MARK --set-mark 跟局域网进来的包 TPROXY --tproxy-mark 路径是有差别的,局域网进来的包 TPROXY 后仍然会有包被 nat PREROUTING 捕获,但不是全部,我之前留了 nat 规则配置 TPROXY 就一直不成功,有 LOG 跟 TRACE 我自己再调试分析一下,应该就能弄明白了。谢谢
建议加上 TRACE,留意 MARK 字段。
上面测试本机发出的包,在 prerouting 中被 tproxy 处理后,就结束 prerouting 链的匹配了,进入路由(route)。
至于你说的外部主机发过来的包,在tproxy处理后的是否会结束prerouting匹配,期待你的测试结果哈。
刚刚上了一下 TRACE 调试,一下子把路由拖死掉了,得等家人不看电视的时候才能测试了,感觉上还是加 -R 用 redirect 模式容易理解点, 想到环回脑袋有点绕,总怕一个不小心就把数据包搞成全在路由里打转出不去,尝试用 TPROXY 的时候我也只是把本机的 TCP DNS 做环回,别的流量没试,估计要使用 nobody 运行 ssr-local 再用 --owner 匹配才保险。
哈哈,TRACE在流量大的时候,确实容易卡死,很耗性能。尽量让TRACE匹配较少的包,不然眼睛都看花你。
ipt2socks 一个线程理论上是不是同时(从微观时间片上看)只能处理一个TCP连接?我在考虑我应该开多少线程合理。
你要是说严格的同一时刻,那一个线程必定只能处理一个连接(因为同一时刻一个CPU核心只能执行一条CPU指令) 但是从常规角度来说,使用epoll是可以让一个线程可以'同时'处理多个连接的,libev在linux上使用epoll 至于开多少线程数合理,只能你自己测试了~
我突然想到,前面说到的speedtest测试,ipt2socks多线程反而速度降低,会不会是因为ss-local(libev)是单线程epoll导致的呢?
建议ss-local打开reuse-port选项,然后开多个进程负载均衡(监听同一个端口,如1080)试试?
就是说 ipt2socks 与 ss-local 的 线程数/进程数(建议同cpu核心数) 都一样,可能性能会比较好。
ssr-local 只有 [--mptcp] Enable Multipath TCP on MPTCP Kernel. 是不是这个选项?这个好像还要打开内核支持,没有找到reuse-port
哦,好像ssr-local默认启用reuse_port,ss-local系列才默认不启用。 你直接启动与cpu核数相同的ssr-local进程、ipt2socks -j核心数,再看看。
那就是4线程,先用用试试,ssr-local 已经开了两个进程了,电视一个专用进程,手机电脑一个进程。
你试试下载这个 cli , 然后在路由器本机跑测速: https://install.speedtest.net/app/cli/ookla-speedtest-1.2.0-linux-x86_64.tgz , 看看能跑多少?
用程序跑就都差不多了,都能上到300Mbps(应该是我家宽带的极限吧),奇怪网页端却有差异,哈哈
当你用网页端测速的时候, 你的路由器的网卡一边从speedtest.net下载, 一边还要上传给你的电脑, 这个时候, 网卡是会有中断的.
你可以做一个简单的测试, 在路由器和电脑同时运行 iperf3 -s , 然后路由器和电脑这边也运行 同时运行 iperf3 -c, 模拟一个同时上传下载的场景, 可以看出速度还是有瓶颈的.
多线程模式是为了并发性能吗?我在speedtest.net测速发现单线程速度更高, iptables redirect -> ipt2socks5 -> ssr-local