shadowsocks / shadowsocks-rust

A Rust port of shadowsocks
https://shadowsocks.org/
MIT License
8.67k stars 1.18k forks source link

[Compatibility Issue] Tun protocol on R4S (OpenWRT with Linux 5.10) #744

Closed f4nff closed 2 years ago

f4nff commented 2 years ago

ifconfig

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:1469659 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1469659 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:4415232102 (4.1 GiB)  TX bytes:4415232102 (4.1 GiB)
tun1      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:10.255.0.1  P-t-P:10.255.0.1  Mask:255.255.255.0
          inet6 addr: fe80::3acb:b23c:904b:8820/64 Scope:Link
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:11357 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5053 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:10395741 (9.9 MiB)  TX bytes:524849 (512.5 KiB)
root@OpenWrt:~/socks# ./sslocal --protocol tun -s "[::1]:8388" -m "aes-256-gcm" -k "hello-kitty" --o
utbound-bind-interface lo --tun-interface-name tun1
error: The argument 'LOCAL_ADDR' wasn't found
f4nff commented 2 years ago
root@OpenWrt:~/socks# ./sslocal -b "127.0.0.1:3128" --protocol tun -s "[::1]:8388" -m "aes-256-gcm"
-k "hello-kitty" --outbound-bind-interface lo --tun-interface-name tun1
2022-01-11T01:27:56.780530101+00:00 INFO  shadowsocks local 1.12.5 build 2021-12-16T16:44:36.222412247+00:00
2022-01-11T01:27:56.832423527+00:00 ERROR tun device doesn't have address, error: Address not available (os error 99), set it by tun_interface_address
thread 'main' panicked at 'create local: Custom { kind: Other, error: Io(Os { code: 99, kind: AddrNotAvailable, message: "Address not available" }) }', src/service/local.rs:605:51
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Aborted
f4nff commented 2 years ago

openwrt /etc/config/network

config interface 'tun1'
    option proto 'static'
    option ipaddr '10.255.0.1'
    option netmask '255.255.255.0'
    option device 'tun1'

config route
    option interface 'tun1'
    option target '0.0.0.0'
    option netmask '0.0.0.0'
    option gateway '10.255.0.1'
    option table '10'
    option metric '0'

config rule
    option in 'lan'
    option lookup '10'
    option priority '0'

config route6
    option interface 'tun1'
    option target '::/0'
    option gateway 'fe80::1'
    option table '10'

config rule6
    option priority '10'
    option in 'lan'
    option dest '::/0'
    option lookup '10'
f4nff commented 2 years ago

使用 https://github.com/xjasonlyu/tun2socks 没有问题的。

zonyitoo commented 2 years ago

The error about LOCAL_ADDR missing should be fixed by this commit. But:

2022-01-11T01:27:56.832423527+00:00 ERROR tun device doesn't have address, error: Address not available (os error 99), set it by tun_interface_address

You have to set the address of tun interface by --tun-interface-address 10.255.0.1/24 or by ifconfig like ifconfig tun1 inet 10.255.0.1 netmask 255.255.255.0 up, the latter way is recommended on Linux if you have already created a tun interface manually.

f4nff commented 2 years ago

能不能不要自动创建网卡?

ip addr add 10.255.0.1/24 dev tun1
ip link set dev tun1 up
ip route add default via 10.255.0.1 dev tun1 table 10

如果是自动创建,无法自定义table

zonyitoo commented 2 years ago

It shouldn't if you use --tun-interface-name tun1.

zonyitoo commented 2 years ago

So you have already got the binary. But you have missed the --feature local-tun.

You can also get nightly builds from https://github.com/shadowsocks/shadowsocks-rust/actions

f4nff commented 2 years ago
root@OpenWrt:~/socks# ./sslocal --protocol tun -s "[::1]:8388" -m "aes-256-gcm" -k "hello-kitty" -
utbound-bind-interface lo --tun-interface-name tun2 --tun-interface-address 10.55.0.1/24  -U
error: The following required arguments were not provided:
    --local-addr <LOCAL_ADDR>

USAGE:
    sslocal --encrypt-method <ENCRYPT_METHOD> --server-addr <SERVER_ADDR> --local-addr <LOCAL_ADDR
--protocol <PROTOCOL> --password <PASSWORD> --outbound-bind-interface <OUTBOUND_BIND_INTERFACE> --
n-interface-name <TUN_INTERFACE_NAME> --tun-interface-address <TUN_INTERFACE_ADDRESS> -U

For more information try --help
f4nff commented 2 years ago

--protocol tun 模式下,--local-addr 问题好像并未解决。

f4nff commented 2 years ago

如何通过 --tun-interface-address 10.255.0.1/24 添加ipv6地址?

zonyitoo commented 2 years ago

There is no way to add IPv6 address because it would require APIs to call netlink. That's why it is recommended to set via ip or ifconfig.

f4nff commented 2 years ago

如果建议使用 ip 或者 ifconfig,那么 --tun-interface-address 10.55.0.1/24 这个为啥需要强制输入。

zonyitoo commented 2 years ago

If the tun's address can be read from the API, then it is not mandatory.

f4nff commented 2 years ago

如果我现在已经通过/etc/config/network 弄了一张网卡,并且设置好了ip,默认路由表,还有table,现在我只想通过ssloca的tun接管网卡,怎么操作?

f4nff commented 2 years ago

比如 :https://github.com/xjasonlyu/tun2socks 这个项目: 我已经有了网卡,我可以手动命令创建,通过脚本实现,然后接管指定网卡,只需要 tun2socks -device tun1 -proxy socks5://[::1]:1080 即可。

zonyitoo commented 2 years ago

https://github.com/shadowsocks/shadowsocks-rust#linux

I don't see any problem following the steps.

ip tuntap add mode tun tun0
ifconfig tun0 inet 10.255.0.1 netmask 255.255.255.0 up
sslocal --protocol tun -s "[::1]:8388" -m "aes-256-gcm" -k "hello-kitty" --outbound-bind-interface lo --tun-interface-name tun0  -U
f4nff commented 2 years ago

我是openwrt,

f4nff commented 2 years ago

想兼容更多的平台,至于创建网卡,添加ip,路由表,table这些,就不用理会,让用户自己通过脚本实现,

zonyitoo commented 2 years ago

OpenWRT is a Linux, there shouldn't have any differences.

f4nff commented 2 years ago

我个人觉得可以学一下 https://github.com/xjasonlyu/tun2socks 的设计思路,

zonyitoo commented 2 years ago

There is no difference with sslocal --protocol tun -s "[::1]:8388" -m "aes-256-gcm" -k "hello-kitty" --outbound-bind-interface lo --tun-interface-name tun0 -U.

f4nff commented 2 years ago
image image
f4nff commented 2 years ago

openwrt /etc/config/network

config interface 'tun1'
    option proto 'static'
    option ipaddr '10.255.0.1'
    option netmask '255.255.255.0'
    option device 'tun1'

config route
    option interface 'tun1'
    option target '0.0.0.0'
    option netmask '0.0.0.0'
    option gateway '10.255.0.1'
    option table '10'
    option metric '0'

config rule
    option in 'lan'
    option lookup '10'
    option priority '0'

config route6
    option interface 'tun1'
    option target '::/0'
    option gateway 'fe80::1'
    option table '10'

config rule6
    option priority '10'
    option in 'lan'
    option dest '::/0'
    option lookup '10'
zonyitoo commented 2 years ago

Run ifconfig and what did you see?

f4nff commented 2 years ago

ifconfig 不显示,但是 ifconfig -a 显示。

f4nff commented 2 years ago
ifconfig   #处于激活状态的网络接口
ifconfig -a  #所有配置的网络接口,不论其是否激活
ifconfig eth0  #显示eth0的网卡信息

不应该使用ifconfig进行判断。

f4nff commented 2 years ago
root@OpenWrt:~# ifconfig tun1
tun1      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:10.255.0.1  P-t-P:10.255.0.1  Mask:255.255.255.0
          inet6 addr: fe80::fe8c:2402:68a7:6287/64 Scope:Link
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:0 (0.0 B)  TX bytes:304 (304.0 B)

应该使用来判断网卡是否添加了IP

f4nff commented 2 years ago

slocal --protocol tun -s "[::1]:8388" -m "aes-256-gcm" -k "hello-kitty" --outbound-bind-interface lo --tun-interface-name tun1 -U 如何这样就可以启动,就ok了,那么就灵活多了

f4nff commented 2 years ago
root@OpenWrt:~/socks# ifconfig tun1 up
root@OpenWrt:~/socks# ./sslocal -b "127.0.0.1:3128"  --protocol tun -s "[::1]:8388" -m "aes-256-gcm"
 -k "hello-kitty" --outbound-bind-interface lo --tun-interface-name tun1  -U
2022-01-11T09:06:40.379470527+00:00 INFO  shadowsocks local 1.12.6 build 2022-01-11T04:52:24.602018376+00:00
thread 'main' panicked at 'create local: Os { code: 16, kind: ResourceBusy, message: "Resource busy" }', src/service/local.rs:765:51
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Aborted
root@OpenWrt:~/socks#
f4nff commented 2 years ago

多久继续改,我继续测。

zonyitoo commented 2 years ago

I will test it tonight with an OpenWRT device.

f4nff commented 2 years ago

openwrt /etc/config/network

config interface 'tun1'
    option proto 'static'
    option ipaddr '10.255.0.1'
    option netmask '255.255.255.0'
    option device 'tun1'

config route
    option interface 'tun1'
    option target '0.0.0.0'
    option netmask '0.0.0.0'
    option gateway '10.255.0.1'
    option table '10'
    option metric '0'

config rule
    option in 'lan'
    option lookup '10'
    option priority '0'

config route6
    option interface 'tun1'
    option target '::/0'
    option gateway 'fe80::1'
    option table '10'

config rule6
    option priority '10'
    option in 'lan'
    option dest '::/0'
    option lookup '10'

添加,重启。

f4nff commented 2 years ago

sslocal --protocol tun -s5 "socks5://user:pass@[::1]:1080" --outbound-bind-interface lo --tun-interface-name tun1 -U

最好能兼容下这样的格式,因为socks5通用性比较好, tun2socks项目有很多,大多都是golang的,占用内存太恐怖了,目前你们这个测试起来效果最佳。

f4nff commented 2 years ago

有udp内存泄露: gddx.zip

tun模式启动sslocal slocal --protocol tun -s "[::1]:8388" -m "aes-256-gcm" -k "hello-kitty" --outbound-bind-interface lo --tun-interface-name tun1 -U

设置路由表,使slocal全局转发tcp+udp包, 编译dns.go go build dns.go

然后执行

dns -sr gddx.txt -at google.com -sl 6

模拟dns udp发包, 然后关闭发包,

然后看sslocal内存

image

等久一会,sslocal 占用内存一直维持在较高水平,并且不释放内存,并且内存也会忽高忽低,

zonyitoo commented 2 years ago

I just tested on my router with OpenWRT

$ uname -a
Linux FusionWrt 5.4.150 #0 SMP PREEMPT Mon Oct 11 06:13:52 2021 aarch64 GNU/Linux

And everything works as expected:

$ ip tuntap add mode tun tun0
$ ifconfig tun0 inet 10.255.0.1 netmask 255.255.255.0 up
$ sslocal --protocol tun -s "[::1]:8388" -m "aes-256-gcm" -k "hello-kitty" --outbound-bind-interface lo --tun-interface-name tun0 -U
2022-01-11T14:34:14.123054848+00:00 INFO  shadowsocks local 1.12.6 build 2022-01-11T08:37:48.571863424+00:00
2022-01-11T14:34:14.125461942+00:00 INFO  shadowsocks tun device tun0, address 10.255.0.1, netmask 255.255.255.0, mtu 1500, mode tcp_and_udp

It just works.

zonyitoo commented 2 years ago

最好能兼容下这样的格式,因为socks5通用性比较好,

Well, this is a shadowsocks project, we will only focus on the shadowsocks protocol.

有udp内存泄露:

Well, try to limit the number of UDP associations with --udp-max-associations 1024. You are testing with DNS queries, which will always create new UDP associations for every queries, and all associations will be preserved for 5 minutes by default.

zonyitoo commented 2 years ago

You may try to run

sslocal --protocol tun -s "[::1]:8388" -m "aes-256-gcm" -k "hello-kitty" --outbound-bind-interface lo --tun-interface-name tun0 --tun-interface-address 10.255.0.1/24 -U

to create a tun0 interface for you, and then manually assign a IPv6 address to tun0 with ip or ifconfig (if you require IPv6), then you will be able to move forward and see whether there are other issues in the next steps.

f4nff commented 2 years ago

openwrt /etc/config/network

config interface 'tun1'
    option proto 'static'
    option ipaddr '10.255.0.1'
    option netmask '255.255.255.0'
    option device 'tun1'

config route
    option interface 'tun1'
    option target '0.0.0.0'
    option netmask '0.0.0.0'
    option gateway '10.255.0.1'
    option table '10'
    option metric '0'

config rule
    option in 'lan'
    option lookup '10'
    option priority '0'

config route6
    option interface 'tun1'
    option target '::/0'
    option gateway 'fe80::1'
    option table '10'

config rule6
    option priority '10'
    option in 'lan'
    option dest '::/0'
    option lookup '10'

保存,重启路由器,这样是通过openwrt 界面创建了一个虚拟网卡,而不是执行

$ ip tuntap add mode tun tun0
$ ifconfig tun0 inet 10.255.0.1 netmask 255.255.255.0 up

然后:

root@OpenWrt:~/socks# ifconfig tun1 up
root@OpenWrt:~/socks# ./sslocal -b "127.0.0.1:3128"  --protocol tun -s "[::1]:8388" -m "aes-256-gcm"
 -k "hello-kitty" --outbound-bind-interface lo --tun-interface-name tun1  -U
2022-01-11T09:06:40.379470527+00:00 INFO  shadowsocks local 1.12.6 build 2022-01-11T04:52:24.602018376+00:00
thread 'main' panicked at 'create local: Os { code: 16, kind: ResourceBusy, message: "Resource busy" }', src/service/local.rs:765:51
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Aborted
root@OpenWrt:~/socks#

直接崩掉了,

f4nff commented 2 years ago
image

https://downloads.openwrt.org/snapshots/targets/rockchip/armv8/openwrt-rockchip-armv8-friendlyarm_nanopi-r4s-ext4-sysupgrade.img.gz

f4nff commented 2 years ago

通过我的方法界面添加网卡,

image

https://github.com/xjasonlyu/tun2socks

启动正常。

但是使用sslocal

image
root@OpenWrt:~# /root/socks/sslocal --protocol tun -s "[::1]:8188" -m "chacha20-ietf-poly1305" -k "h
ello-kitty" --outbound-bind-interface lo --tun-interface-name tun1 -U --udp-timeout 60
2022-01-11T15:56:45.110992599+00:00 INFO  shadowsocks local 1.12.6 build 2022-01-11T08:37:48.571863424+00:00
2022-01-11T15:56:45.180789163+00:00 ERROR tun device doesn't have address, error: Address not available (os error 99), set it by tun_interface_address
thread 'main' panicked at 'create local: Custom { kind: Other, error: Io(Os { code: 99, kind: AddrNotAvailable, message: "Address not available" }) }', src/service/local.rs:763:51
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Aborted
f4nff commented 2 years ago

你测试,非真机测试,应该都是完整版本的linux openwrt

root@OpenWrt:~# uname -a
Linux OpenWrt 5.10.89 #0 SMP PREEMPT Mon Jan 3 09:36:09 2022 aarch64 GNU/Linux

真机测试的话, $ ip tuntap add mode tun tun0 这个命令都无法执行。

f4nff commented 2 years ago

/root/socks/sslocal --protocol tun -s "[::1]:8188" -m "chacha20-ietf-poly1305" -k "hello-kitty" --outbound-bind-interface lo --tun-interface-name tun2 --tun-interface-address 10.55.0.1/24 -U --udp-timeout 60 --udp-max-associations 65535

至于udp泄露,我修改了--udp-max-associations 65535, 然后问题还是一样的,

当连接数回归正常水平之后,

image

sslocal的占用内存还是很高,也没回归到正常水平,

image

但是我使用https://github.com/xjasonlyu/tun2socks 来完成这些,占用内存都会回落到正常水平。

f4nff commented 2 years ago

一句话,我反馈的两个bug, 你压根就没按我的要求去重现。

f4nff commented 2 years ago
image

现在已经过去好几分钟了,内存占用在800M+

f4nff commented 2 years ago
image image

udp内存泄露,根本不用质疑。

f4nff commented 2 years ago

--protocol tun 模式下,我估计压根就没人使用,也没人细测过,

zonyitoo commented 2 years ago

这个命令都无法执行。

I am testing it on R4S, it is a real ARM aarch64 device. Of course it can run correctly.

udp内存泄露,根本不用质疑。

UDP association shares code base with all the other protocols, including socks5 and redir. We have already use them for at least 1 year (after refactored). I don't think there are any memory leaks.

模式下,我估计压根就没人使用,也没人细测过,

Maybe. I can only say that it just works perfectly on my R4S with OpenWRT.

f4nff commented 2 years ago

1: 使用你的r4s刷 https://downloads.openwrt.org/snapshots/targets/rockchip/armv8/openwrt-rockchip-armv8-friendlyarm_nanopi-r4s-ext4-sysupgrade.img.gz 进行测试。 2:很多bug一直存在,只不过被忽略,只要不是明显的闪退,很少人会注意到。 3:我的也是r4s,刷了官方的openwrt,为什么表现跟你不同?

f4nff commented 2 years ago

这是你的版本:

$ uname -a
Linux FusionWrt 5.4.150 #0 SMP PREEMPT Mon Oct 11 06:13:52 2021 aarch64 GNU/Linux

这是我的版本:

root@OpenWrt:~# uname -a
Linux OpenWrt 5.10.89 #0 SMP PREEMPT Mon Jan 3 09:36:09 2022 aarch64 GNU/Linux

你可以刷openwrt官方提供的镜像,进行测试: https://downloads.openwrt.org/snapshots/targets/rockchip/armv8/openwrt-rockchip-armv8-friendlyarm_nanopi-r4s-ext4-sysupgrade.img.gz

zonyitoo commented 2 years ago

Why I didn't test your provided configuration in /etc/config/network? Because it just not working. After reboot, there is no tun1 interface showed up in ifconfig or luci's network interface page.