5年前曾写过一篇“科学”使用树莓派的教程,尽管时间比较久,现在仍然在使用教程中的核心功能和思路,说明可靠性不错。不过由于各种不可描述的原因,部分工具已经停止维护,偶尔也会出现兼容性和奇怪的问题。这次利用假期在此前思路和近几年新工具的基础上推倒重来,各种服务之间的关系更加清晰,效率和稳定性有了进一步提高。
不同于其他内容,这篇“科学”教程不能写的太细。但会争取把一些其他文章没有提到的关键内容说清楚,避免新手踩坑。
一、主要通道
- 与vps之间的主要通道选择用trojan建立
apt install trojan
- 配置文件放在/etc/trojan/config.json,具体内容参考vps服务端生成的内容。客户端配置的cert字段不建议留空,补全fullchain证书比较稳妥
- 由于后续采用透明网关,主要通道相关服务统一通过pi用户运行,以便区分
chown pi /usr/bin/trojan chgrp pi /usr/bin/trojan
- 创建/etc/systemd/system/trojan.service服务,注意After内容
[Unit] Description=trojan Documentation=man:trojan(1) https://trojan-gfw.github.io/trojan/config https://trojan-gfw.github.io/trojan/ After=network.target network-online.target nss-lookup.target # [Service] Type=simple StandardError=journal User=pi Group=pi AmbientCapabilities=CAP_NET_BIND_SERVICE ExecStart=/usr/bin/trojan -c /etc/trojan/config.json ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure RestartSec=1s # [Install] WantedBy=multi-user.target
二、透明网关
原始版本的trojan提供的是socks5,默认不支持redirect或tproxy方式的透明网关。解决办法有很多,例如redsocks、v2ray、clash和glider等工具进行转换。
- 个人喜欢用glider转换为ss服务后再搭配ss-redir实现。主要是日常会使用ss建立一些境内通道方便使用(和openvpn一样,ss的境内通道不会受到wall的干扰)
- 从https://github.com/nadoo/glider/releases中下载armv7版本
- 主程序放在/usr/local/bin,配置文件放在/etc/glider/server.conf,同样使用chown和chgrp修改为pi。server.conf内容如下
listen=:8443 # 转换为ss,工作端口号529 listen=ss://AES-256-CFB:yourpassword@:529 # trojan的端口号527 forward=socks5://127.0.0.1:527 # verbose=True
- 创建/etc/systemd/system/glider@server.service服务,After中添加trojan.service
[Unit] Description=Glider Service (%i) After=network.target trojan.service # [Service] Type=simple User=pi Group=pi Restart=always LimitNOFILE=102400 # # NOTE: change to your glider path ExecStart=/usr/local/bin/glider -config /etc/glider/%i.conf # # work with systemd v229 or later, so glider can listen on port below 1024 with none-root user # CAP_NET_ADMIN: ipset # CAP_NET_BIND_SERVICE: bind ports under 1024 CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE NoNewPrivileges=true # [Install] WantedBy=multi-user.target
2. 配置ss-redir
- 安装shadowsocks-libev
apt install shadowsocks-libev
- 因为我们需要的是ss-redir,关掉默认的shadowsocks-libev.service,并修改/usr/bin/ss-redir的拥有者和群组为pi
- 创建/etc/systemd/system/ss-redir.service服务,After中添加glider@server.service和trojan.service
[Unit] Description=SS-Redir Service After=network.target glider@server.service trojan.service # [Service] Type=simple User=pi Group=pi Restart=always LimitNOFILE=102400 # # NOTE: change to your ss-redir path # 监听端口号为1080 ExecStart=/usr/bin/ss-redir -s 127.0.0.1 -p 529 -b 0.0.0.0 -l 1080 -k yourpassword -m aes-256-cfb -u # CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE NoNewPrivileges=true # [Install] WantedBy=multi-user.target
- 通过以下命令可以查看运行是否准确
top -u pi
- 正确显示为
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 638 pi 20 0 38640 22480 7120 S 0.0 0.6 0:31.52 trojan 639 pi 20 0 800472 12576 3968 S 0.0 0.3 0:37.07 glider 640 pi 20 0 4764 2812 2228 S 0.0 0.1 0:21.47 ss-redir
3. 配置ipset和iptables
- ipset中配置chnroute,用于识别线路,内容来自于chinadns-ng
ipset -R < chnroute.ipset
- 创建/etc/systemd/system/ipset.service服务实现重启后自动加载,注意ConditionFileNotEmpty和After
[Unit] Description=ipset persistent rule service ConditionFileNotEmpty=/root/dnstools/chinadns-ng/chnroute.ipset After=network.target # [Service] Type=oneshot RemainAfterExit=true ExecStart=/sbin/ipset -exist -file /root/dnstools/chinadns-ng/chnroute.ipset restore # [Install] WantedBy=multi-user.target
- 配置sysctl开启net.ipv4.ip_forward=1
- iptables配置内容如下
iptables -t nat -N SHADOWSOCKS iptables -t nat -A PREROUTING -p tcp -j SHADOWSOCKS # 排除pi用户的访问(也即trojan、glider和ss-redir),用户uid通过id username查看 iptables -t nat -A OUTPUT -p tcp -m owner ! --uid-owner 1000 -j SHADOWSOCKS # 排除Lan iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN iptables -t nat -A SHADOWSOCKS -d 169.254.0.0/16 -j RETURN iptables -t nat -A SHADOWSOCKS -d 172.16.0.0/16 -j RETURN iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN iptables -t nat -A SHADOWSOCKS -d 224.0.0.0/4 -j RETURN iptables -t nat -A SHADOWSOCKS -d 240.0.0.0/4 -j RETURN # 排除本机到vps的访问 iptables -t nat -A SHADOWSOCKS -s 127.0.0.1/32 -d xxx.xxx.xxx.xxx/32 -j RETURN # 通过ipset中的chnroute判断国内ip iptables -t nat -A SHADOWSOCKS -p tcp -m set --match-set chnroute dst -j RETURN # 其他访问走ss-redir的1080端口(后续可信dns通过DoT和DoH实现) iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports 1080
- 修改/lib/systemd/system/netfilter-persistent.service服务,在After中增加ipset.service,否则在ipset.service运行完毕之前,iptables-restore会因为找不到ipset chnroute而恢复失败
After=systemd-modules-load.service local-fs.target ipset.service
1. 配置glider
三、DNS的配置
DNS要考虑的核心问题有三个:避免污染、区分线路高速解析、保证正确解析境内外地址。尤其是第三点,因为一些大厂如Google、Apple和阿里,会根据不同的DNS服务器访问IP给出不同的服务器地址,而Apple的用户认证还屏蔽了大多数vps的ip,往往造成鉴权失败。
目前使用的方案是AdGuardHome + dnsmasq (china-list) + chinadns-ng + smartdns
| Trusted Group (DoH)
AdGuardHome --> dnsmasq --> chinadns-ng --> smartdns --> |
(AD filter) (accelerate) (addr match) (fastest) | Mainland Group (UDP)
- 从https://github.com/pymumu/smartdns/releases下载smartdns.xxxxxxxx.arm-debian-all.deb安装包,使用以下命令安装
dpkg -i smartdns.xxxxxxxx.arm-debian-all.deb
- 修改配置文件/etc/smartdns/smartdns.conf
1. 安装smartdns
# chn组端口号为5304 bind [::]:5304 -group chn # trusted组端口号为5308 bind [::]:5308 -group trusted # chn组走国内DNS,杭州走阿里的223.6.6.6比114更快 server 223.6.6.6 -group chn -exclude-default-group server 114.114.114.114 -group chn -exclude-default-group # trusted组走DoT和DoH解析,这里采用Google和OpenDNS的 server-tls 8.8.8.8:853 -group trusted -exclude-default-group server-https https://dns.google/dns-query -group trusted -exclude-default-group server-https https://doh.opendns.com/dns-query -group trusted -exclude-default-group cache-size 4096 log-level info
2. 安装chinadns-ng
git clone https://github.com/zfl9/chinadns-ng cd chinadns-ng make && sudo make install
[Unit] Description=ChinaDNS-ng Service After=network.target smartdns.service # [Service] Type=simple Restart=always # # 使用端口号5303 ExecStart=/usr/local/bin/chinadns-ng -l 5303 -c 127.0.0.1#5304 -t 127.0.0.1#5308 -g /root/dnstools/chinadns-ng/gfwlist.txt -m /root/dnstools/chinadns-ng/chnlist.txt # [Install] WantedBy=multi-user.target
3. 安装dnsmasq-china-list
# 使用端口号5302 port=5302 no-resolv cache-size=1000 # 上游指向chinadns-ng的5303 server=127.0.0.1#5303 clear-on-reload
4. 安装AdGuardHome
cd $HOME wget https://static.adguard.com/adguardhome/release/AdGuardHome_linux_arm.tar.gz tar xvf AdGuardHome_linux_arm.tar.gz cd AdGuardHome ./AdGuardHome -s install
127.0.0.1:5302
5. 针对Apple的额外配置
server=/www.icloud.com/223.6.6.6 server=/appleid.apple.com/223.6.6.6 server=/idmsa.apple.com/223.6.6.6 server=/appleid.cdn-apple.com/223.6.6.6
iptables -t nat -A SHADOWSOCKS -d 17.137.166.0/24 -j RETURN iptables -t nat -A SHADOWSOCKS -d 17.141.5.0/24 -j RETURN iptables -t nat -A SHADOWSOCKS -d 17.151.240.0/24 -j RETURN iptables -t nat -A SHADOWSOCKS -d 17.253.144.0/24 -j RETURN iptables -t nat -A SHADOWSOCKS -d 118.214.109.0/24 -j RETURN
四、搭建Wireguard方便外部访问
树莓派平台暂不能直接apt install wireguard,需要编译
# 安装依赖工具 apt install libmnl-dev git apt install libelf-dev build-essential pkg-config # 安装内核头文件(编译内核用) apt install raspberrypi-kernel-headers # 获取文件 cd /usr/local/src git clone https://git.zx2c4.com/wireguard-linux-compat git clone https://git.zx2c4.com/wireguard-tools # 编译安装module make -C wireguard-linux-compat/src -j$(nproc) make -C wireguard-linux-compat/src install # 编译安装wireguard make -C wireguard-tools/src -j$(nproc) make -C wireguard-tools/src install
创建/lib/systemd/system/wg-quick@wg0.service
配置文件在/etc/wireguard/wg0.conf
[Interface] Address = 10.66.66.1/24,fd42:42:42::1/64 ListenPort = 39770 PrivateKey = server_privatekey PostUp = iptables -A FORWARD -i eth0 -o wg0 -j ACCEPT; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i eth0 -o wg0 -j ACCEPT; iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE # ### Client ian-iphone [Peer] PublicKey = client1_publickey PresharedKey = PresharedKey AllowedIPs = 10.66.66.9/32,fd42:42:42::9/128 # ### Client ian-p5550 [Peer] PublicKey = client2_publickey PresharedKey = PresharedKey AllowedIPs = 10.66.66.8/32,fd42:42:42::8/128
具体的key可以用以下方式获得,服务端配置文件写服务端的privatekey和客户端的publickey;客户端配置文件写服务端的publickey和客户端的privatekey
wg genkey | tee privatekey1 | wg pubkey > publickey1
wg的PresharedKey用于两端加密混淆,建议填写使用,两端保持一致
wg genpsk > presharedkey
客户端配置文件举例
[Interface] PrivateKey = client1_privatekey Address = 10.66.66.9/32,fd42:42:42::9/128 DNS = 10.66.66.1,10.66.66.1 # [Peer] PublicKey = server_publickey PresharedKey = PresharedKey # Use Your Server IP Endpoint = xxx.xxx.xxx.xxx:39770 AllowedIPs = 0.0.0.0/0,::/0
The End -