Thinking_Out_Loud

我是如何用掉一天的:OpenWRT配v2ray

2018-09-22

一个小目标

今天把我的小Y从lede-17.01升级到了openwrt-18.06.1。对,lede又重新和openwrt合并了,XP。
很欣喜的是发现默认主题居然变好看了,交互体验也提升了很多,这个开源小组终于有美工了,升级过程暂且不表,今天我的小目标是在路由器上用v2ray搭好爱国透明代理。

然而第一步就掉了链子,openwrt中默认的wget命令是由busybox提供的,不支持https,所以需要重新安装一个。

1
2
> opkg update
> opkg install wget

然后就可以高高兴兴去下二进制安装包了,不料这mipsle的安装包竟然有17MB,一个主程序和辅助工具再加上IP数据集,我的小Y只有16MB的Flash,真是天要亡我。还是不死心,go在编译时去掉符号表能省不少空间,还能再挤挤,果然在谷歌第一页就翻到了大牛留下的笔记:

https://gobomb.github.io/post/cross-complie-v2ray/

多亏大牛我才想起在openwrt官网下载的系统升级固件默认是没开FPU支持的,运行go程序会报Illegal instruction,就是说我要从固件开始自己编译,抬头望天

挣扎

翻出了还在15.05-cc版的本地仓库,用30KB的平均速度pull到了最新的代码,长征第一步。

我沿用了之前搭建的环境,如果有需要从零开始搭建的同学可以参考官方指引,或者使用docker上的build-root镜像(张口就来,其实我没实际用过)。

代码更新完后更新一下软件包:

1
2
>./scripts/feeds update -a
>./scripts/feeds install -a

开始编译

那么可以开始编译固件了

首先把最重要的FPU支持打开,先进入内核选项菜单:

1
> make kernel_menuconfig

按下列路径进去把FPU支持开启

1
Kernel type ---> MIPS FPU Emulator

然后再去把需要预装的包都勾上

1
> make menuconfig

我的小Y是MT7620的板,开启5G-wifi需要安装kmod-mt76,如下:

1
kernel modules ---> wireless drivers ---> kmod-mt76

再去把usb自动挂载配置好(未雨绸缪):

  1. 添加USB相关支持
    • Kernel modules —> USB Support —> <> kmod-usb-core. #默认已经选了
    • Kernel modules —> USB Support —> <
    > kmod-usb-ohci. #默认已选 old usb1.0
    • Kernel modules —> USB Support —> <> kmod-usb-uhci. # usb1.1
    • Kernel modules —> USB Support —> <
    > kmod-usb-storage.
    • Kernel modules —> USB Support —> <> kmod-usb-storage-extras.
    • Kernel modules —> USB Support —> <
    > kmod-usb2. #默认已经选了 usb2.0
    • 再加个usb3
  2. 添加USB挂载
    • Base system —> <*>block-mount
  3. 添加自动挂载工具
    • Utilities —> Filesystem —> <*> badblocks
  4. 添加文件系统支持
    • Kernel modules —> Filesystems —> <> kmod-fs-ext4 (移动硬盘EXT4格式选择)
    • Kernel modules —> Filesystems —> <
    > kmod-fs-vfat(FAT16 / FAT32 格式 选择)
  5. 添加UTF8编码,CP437编码,ISO8859-1编码(否则即使/dev/中出现设备也无法挂载)
    • Kernel modules —> Native Language Support —> <> kmod-nls-utf8
    • Utilities —> disc —> <
    > fdisk……………………………… manipulate disk partition table
    • Utilities —> <*> usbutils…………………………….. USB devices listing utilities

又因为后面需要设置iptables转发,所以需要在menuconfig中安装如下包,因为是自编译固件,所以有些不能通过官方feed安装,提前放在这里:

1
2
3
4
5
6
7
ip-tiny / ip-full
ipset
iptables
iptables-mod-tproxy
kmod-ipt-ipset
kmod-ipt-tproxy
libipset

首先先把之前的toolchain等清理掉,因为占用的磁盘真的大。

1
> make dirclean # /bin /build_dir /staging_dir /toolchain /tmp /logs.

建议第一遍编译先用verbose模式输出日志,一遍成功是不存在的

1
> make -j1 V=s

报错

编译过程中出现了这样的complain:

1
WARNING: Image file /openwrt/cc/build_dir/target-mipsel_24kc_musl/linux-ramips_mt7620/tmp/openwrt-ramips-mt7620-ex2700-squashfs-sysupgrade.bin is too big

这因为胡乱塞了很多东西,导致没办法兼容Flash只有4M的设备。

1
> vim ./target/linux/ramips/image/Makefile

修改220行的ralink_default_fw_size_4M=3866624值为更大的就好了。
而我的做法是:重进menuconfig,把忘记选上的profile选好,这样就只编译我需要的Y1固件了,XD


漫无止境的编译和网络I/O…

十年后

新鲜出炉的固件在/bin目录下,又回到最初的起点。

编译V2ray

根据v2ray的官方指引准备好编译环境。

分别编译v2ray和v2ctl:

1
2
3
4
> cd $GOPATH/src/v2ray/core/main
> GOARCH=mipsle GOMIPS=softfloat go build -ldflags '-w -s' -o v2ray
> cd $GOPATH/src/v2ray.com/ext/tools/control/main
> GOARCH=mipsle GOMIPS=softfloat go build -ldflags '-w -s' -o v2ctl

题外话,我发现v2ray自带的构建工具vbuild并没有考虑GOPATH变量中存在两个路径的情况:我的GOPATH中第一个路径设定为第三方lib的目录,接着的是个人项目的目录,这样在go get时会自动把依赖库都放在第一个目录中,这就把它们和个人项目分开来了。

配置透明代理

因为挂载了U盘,磁盘空间有余裕了,我打算先把透明代理配置好,先不用upx压缩。

我的iptables设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
MY_VPS=xx.xx.xx.xx
MY_PROXY_PORT=1060
SKIP_IP='0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16
172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4'

# new chain
iptables -t nat -N V2RAY
iptables -t mangle -N V2RAY_MARK

# tcp rule
iptables -t nat -A V2RAY -d $MY_VPS -j RETURN # direct connect
iptables -t nat -A V2RAY -p tcp -j RETURN -m mark --mark 0xff # avoid loop
for IP in $SKIP_IP;do
iptables -t nat -A V2RAY -d $IP -j RETURN
done

iptables -t nat -A V2RAY -p tcp -j REDIRECT --to-ports $MY_PROXY_PORT

# udp rule
ip rule del fwmark 1
ip rule add fwmark 1 table 100
ip route add local 0.0.0.0/0 dev lo table 100
ip route flush cache

for IP in $SKIP_IP;do
iptables -t mangle -A V2RAY_MARK -d $IP -j RETURN
done

iptables -t mangle -A V2RAY_MARK -p udp -j TPROXY --on-port $MY_PROXY_PORT --tproxy-mark 0x01/0x01

# apply chain
iptables -t nat -A PREROUTING -p tcp -j V2RAY # 对局域网其他设备进行透明代理
iptables -t nat -A OUTPUT -p tcp -j V2RAY # 对本机进行透明代理

iptables -t mangle -A PREROUTING -p udp -j V2RAY_MARK

我的v2ray设置,部分省略:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
{
"inbound": { ... },
"inboundDetour": [
{
"protocol": "dokodemo-door",
"listen": "0.0.0.0",
"port": 1060, // 转发到这里
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
},
"settings": {
"network": "tcp,udp",
"followRedirect": true,
"timeout": 0
}
}
],
"outbound": { ... },
"outboundDetour": [
{
"protocol": "freedom",
"settings": {},
"streamSettings": {
"sockopt": {
"mark": 255 // MARK
}
},
"tag": "direct"
},
{
"protocol": "blackhole",
"settings": {},
"tag": "block"
}
],
"routing": {
"strategy": "rules",
"settings": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"outboundTag": "direct",
"protocol": [
"bittorrent"
]
},
{
"type": "field",
"domain": [
"geosite:cn",
"geosite:speedtest"
],
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
"geoip:cn"
],
"outboundTag": "direct"
}
]
}
}
}

成功彼岸

正式宣布爱国特区成立,papapapa!
不过有点悲伤的是运行v2ray之后的5分钟载荷一直在1.5左右浮动,不过实际的网络响应速度还是能接受。
先写到这里,其它内容放到之后再整理。

参考资料

  1. https://gobomb.github.io/post/cross-complie-v2ray/
  2. http://www.tldp.org/HOWTO/Adv-Routing-HOWTO/index.html
  3. https://wangchujiang.com/linux-command/c/iptables.html
  4. https://toutyrater.github.io/app/transparent_proxy.html
  5. https://wiki.openwrt.org/doc/howto/netfilter#configuration
  6. https://wiki.openwrt.org/inbox/doc/iptables_and_firewall