笔者要在安装了 ArchLinuxARM 的 Raspberry Pi 上配置 SOCKS5 代理转发,并把局域网内其它计算机的网关、DNS 服务器设置成 Raspberry Pi,做到全局 SOCKS5 代理转发。
ArchLinuxARM 的系统控制服务是 Systemd。如果你不用 Systemd,可能需要调整某些步骤。
在开始之前,安装这些软件包:
badvpn-tun2socks iproute2 iptables pdnsd
首先配置 pdnsd 的 DNS 转发:
/etc/pdnsd.confglobal {max_ttl=300;min_ttl=0;neg_domain_pol=off;query_method=tcp_only;run_as=pdnsd;timeout=10;}server {ip=8.8.8.8,8.8.4.4;}
然后写启动和终止脚本:
/usr/local/bin/socksfwd#!/bin/bashSOCKS_SERVER=xxx.xxx.xxx.xxx # SOCKS 服务器的 IP 地址SOCKS_PORT=1080 # SOCKS 服务器的端口GATEWAY_IP=192.168.1.1 # 家用网关(路由器)的 IP 地址BYPASS_IPS=(yyy.yyy.yyy.yyy zzz.zzz.zzz.zzz) # 不需要代理的 IP 地址TUN_NETWORK_DEV=tun0 # 选一个不冲突的 tun 设备号TUN_NETWORK_PREFIX=10.210.0 # 选一个不冲突的内网 IP 段的前缀start_fwd() {ip tuntap add dev "$TUN_NETWORK_DEV" mode tunip addr change "$TUN_NETWORK_PREFIX.1/30" dev "$TUN_NETWORK_DEV"ip link set "$TUN_NETWORK_DEV" upip route del default via "$GATEWAY_IP"ip route add default via "$GATEWAY_IP" metric 600for i in "${BYPASS_IPS[@]}"doip route add "$i" via "$GATEWAY_IP" metric 5doneip route add default via "$TUN_NETWORK_PREFIX.2" metric 6badvpn-tun2socks --tundev "$TUN_NETWORK_DEV" --netif-ipaddr "$TUN_NETWORK_PREFIX.2" --netif-netmask 255.255.255.252 --socks-server-addr "$SOCKS_SERVER:$SOCKS_PORT" &TUN2SOCKS_PID="$!"}stop_fwd() {ip route del default via "$TUN_NETWORK_PREFIX.2" metric 6for i in "${BYPASS_IPS[@]}"doip route del "$i" via "$GATEWAY_IP" metric 5doneip tuntap del dev "$TUN_NETWORK_DEV" mode tun}start_fwdtrap stop_fwd INT TERMwait "$TUN2SOCKS_PID"
写 Systemd 服务:
/etc/systemd/system/socksfwd.service[Unit]Description=Transparent SOCKS5 forwardingAfter=network-online.target[Service]Type=simpleExecStart=/usr/local/bin/socksfwdLimitNOFILE=1048576[Install]WantedBy=multi-user.target
打开流量转发:
/etc/sysctl.d/sysctl.confnet.ipv4.ip_forward = 1net.ipv6.conf.all.forwarding = 1net.ipv4.tcp_congestion_control=westwoodnet.ipv4.tcp_syn_retries = 5net.ipv4.tcp_synack_retries = 5
/etc/iptables/iptables.rules*nat:PREROUTING ACCEPT [0:0]:INPUT ACCEPT [0:0]:OUTPUT ACCEPT [1:1500]:POSTROUTING ACCEPT [0:0]-A POSTROUTING ! -s 127.0.0.0/8 -j MASQUERADECOMMIT
最后设置 DNS 为本机 pdnsd。如果用 systemd-network,可以这么写,其中 eth0 改成对外的网卡名称:
/etc/systemd/network/eth0.network[Match]Name=eth0[Network]DHCP=yesDNS=127.0.0.1IPForward=yes[DHCP]UseDNS=no[Route]Metric=100
如果不用 systemd-network,也可以改 /etc/resolv.conf:
/etc/resolv.confnameserver 127.0.0.1
最后启动服务并重启:
sudo systemctl enable socksfwd iptablessystemctl reboot
P.S. 这个方案也可以在桌面 Linux 或者 ChromeOS 上运行,只需要安装依赖并设法运行 socksfwd 脚本即可,其它步骤可以不做。
可以不使用 pdnsd 来转发 DNS,但是 DNS 服务器就需要加到 BYPASS_IPS 中。
在 ChromeOS 平台,创建的 tun 设备会被 shill 服务自动删掉,需要在执行 socksfwd 之前执行:
stop shillstart shill BLACKLISTED_DEVICES=tun0