tunsocks 是一个可以将 Linux Tunnel 设备流量包装成 Socks 的开源软件,通常可以结合 OpenConnect 给 VPN 加一层 Socks,供某些特定场景使用。比如,如果我希望将 OpenConnect VPN 作为 V2Ray 的出口(Outbound),就可以用到 tunsocks。
因为我的 OpenConnect 跑在 OpenWrt 上,而 OpenWrt 的官方软件源里并没有 tunsocks 的 ipk
软件包,也没有第三方提供,所以需要自己从源码编译。
tunsocks 使用 C 语言编写,编译虽然是 configure
、make
这样的老一套,但是在 OpenWrt 这种嵌入式 Linux 发行版上碰到了一些特殊情况,所以略记一笔,以供日后参考。
event2 库缺失的问题
执行 ./configure
然后 make
会提示 event2
的头文件缺失。
lwip-libevent/netif/fdif.c:18:10: fatal error: event2/event.h: No such file or directory
#include <event2/event.h>
^~~~~~~~~~~~~~~~
libevent2 在 OpenWrt 的官方软件源中已有,所以可以使用 opkg
安装,也可以选择下载最新版源代码之后编译安装。
我选择的后者,从官方网站下载,然后正常编译安装即可,未遇见任何异常。
libdl 库缺失的问题
因为编译安装的 libevent2 会放在 /usr/local
目录下,所以我们需要指定 CFLAGS
和 LDFLAGS
后重新 configure
。如使用 opkg
安装,则无需指定。
CFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/lib" ./configure
make clean
make
此时出现如下错误,也就是找不到 libdl
库。实际上在多数 Linux 操作系统上,这个是 glibc 的一部分,通常会随机附送。
/usr/bin/ld: cannot find -ldl
另外,编译过程中还会出现如下 Warning,提示 reallocarray
函数不存在,而这个函数同样也是 glibc 标准库中理应自带的。
lwip-libevent/netif/udptapif.c:213:18: warning: implicit declaration of function 'reallocarray'; did you mean 'realloc'? [-Wimplicit-function-declaration]
client->hw = reallocarray(client->hw, client->n, sizeof(*client->hw));
^~~~~~~~~~~~
realloc
使用 ldd
命令可以查看当前系统的 libc 版本,如下所示,我的 OpenWrt 上使用的是 musl libc 1.1.24 版,并非 glibc。
# ldd --version
musl libc (aarch64)
Version 1.1.24
搜索得知 musl 一个针对嵌入式设备的 C 标准库实现,从 Changelog 上看,musl 从 1.2.2 版本开始才支持 reallocarray
这个函数。
既然如此,我们编译安装一个新版的 musl 就好了。
-
下载 musl 1.2.2 或更新的版本。
-
运行如下命令编译安装
./configure make make install
生成的 libc 头文件和库文件默认会安装在 /usr/local/musl
下,这样也不会污染系统中已安装的版本。
最终编译安装 tunsocks
添加相应的 CFLAGS 和 LDFLAGS 重新运行 configure。
CFLAGS="-I/usr/local/include -I/usr/local/musl/include" LDFLAGS="-L/usr/local/lib -L/usr/local/musl/lib" ./configure
然后 make 编译安装。
# 清除之前生成的文件
make clean
# 编译、安装
make
make install
如果一切正常 tunsock 的二进制文件会安装在 /usr/local/bin
下。
总结
所以在 OpenWrt 上编译安装 tunsocks,正确的步骤应该是:
- 安装 libevent2
- 编译安装新版 musl
- 编译安装 tunsocks
我猜 OpenWrt 上使用 tunsocks 的人不会太多,不然可以考虑做一个第三方 Repo,提供 tunsocks 的 ipk 版。