目标
创建一个代理网关,所有通过有线或者无线连接通过该网关上网的设备可以:
- 根据域名判断是走国内的DNS还是国外的DNS,走国外DNS时,通过SS代理请求,防止DNS污染
- 根据目标IP地址自动选择线路,国外流量都走SS代理
准备
- 一个SS服务器,Linode或者Digital Ocean上5刀/月的服务器就够用了,SS服务器的架设方法请自行百度。
- 一个运行最新版本Raspbian的树莓派3B+。理论上任何安装Linux并带有线网卡和无线网卡的设备都可以,只是不同的Linux发行版配置会稍有不同。选择树莓派3B+因为其自带有线和无线网卡,官方的Raspbian运行稳定、内核版本高(ipset在低版本内核中很难安装),缺点是网卡不是千兆的。我在KVM虚拟机中运行的Arch和Orange Pi Zero Plus上运行的Armbian上都成功搭建过类似的网关。
- 一个支持VLAN Tagging(802.1Q)功能的交换机。我用的是
必联BL-SG108M
,八口千兆,淘宝卖140,价格公道,功能够用。也可以使用一个USB有线网卡配一个普通的交换机,除VLAN之外,其他配置类似,但这种配置就不是单臂路由器了。
网络拓扑与交换机配置
网络拓扑图
将交换机端口分为两个VLAN,VLAN2和VLAN3(这个设备很诡异,VLAN1不允许删除或修改)。端口1至端口6为VLAN2,端口6至端口8为VLAN3,交换机通过端口1连接家里的路由器,树莓派连接端口6(跨两个VLAN)。此时,空闲的端口2~5为非代理端口,直接走家里的路由器,端口7、8为代理端口,数据会通过树莓派网关进行转发,可以根据需要调整VLAN2与VLAN3的端口数量。
VLAN配置
VLAN Tag配置
在配置交换机前,需要先设置交换机的IP地址为局域网内可用的地址。VLAN划分好后,可以设置端口隔离,但是因为没有找到官方详细的说明,我按照自己的想法将端口1~5和7、8进行了隔离,运行中没有碰到问题,但是VLAN3内的设备无法访问交换机的管理页面。
配置网关
树莓派网关需要运行DNS服务(dnsmasq),代理服务(shadowsocks-libev)及无线AP服务(hostapd)并且需要通过iptables和ipset进行NAT转发。
系统配置
更新系统到最新的状态:
1 2
| apt update apt dist-upgrade -y
|
安装需要的软件包:
1
| apt install -y vim git dnsutils lsof bridge-utils hostapd dnsmasq ipset ntp haveged python-m2crypto shadowsocks-libev
|
修改时区并启用NTP服务:
1 2 3
| rm -rf /etc/localtime ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime systemctl enable ntp
|
网络配置
修改 /etc/network/interfaces
的内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| auto eth0.2 iface eth0.2 inet manual vlan-raw-device eth0 iface eth0.3 inet manual vlan-raw-device eth0 auto br0 iface br0 inet manual bridge_ports eth0.2 auto br1 iface br1 inet manual bridge_ports eth0.3
|
这里配置了两个VLAN,号码需要和前边交换机的号码对应,同时建了两个网桥,方便今后添加更多的接入方式,br0为外网,br1为内网。
Raspbian使用dhcpcd来配置网络地址,修改 /etc/dhcpcd.conf
,在文件最后添加如下内容:
1 2 3 4 5 6 7 8 9 10
| denyinterfaces eth0 eth0.2 eth0.3 interface br1 static ip_address=192.168.51.1/24 static routers=192.168.51.1 static domain_name_servers=192.168.51.1 nogateway interface wlan0 nohook wpa_supplicant
|
上边配置中用了 192.168.51.0/24
这个网段,可以根据需要自行调整, nogateway
可以保证使用br0为默认网关而不是br1。
SS服务
SS全家桶客户端一共有三个服务:
- shadowsocks-libev-local:socks5正向代理服务,非代理VLAN中的终端可以通过这个socks5代理上网,配合Proxychains与Switch Omega这类的软件使用。
- shadowsocks-libev-redir:socks5透明代理服务,所有需要代理的网路流量都会根据iptables规则转发到这个服务的监听端口。
- shadowsocks-libev-tunnel:本地端口转发工具,这里用于解决dns污染问题。
下边是三个服务的配置:
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
| cat <<EOT >> /etc/shadowsocks-libev/local.json { "server": "SS服务器的IP地址", "server_port": SS服务端口号, "local_address": "0.0.0.0", "local_port": 1080, "password": "SS服务器的密码", "timeout": 300, "method": "aes-256-cfb", "fast_open": false } EOT cat <<EOT >> /etc/shadowsocks-libev/redir.json { "server": "SS服务器的IP地址", "server_port": SS服务端口号, "local_address": "0.0.0.0", "local_port": 1088, "password": "SS服务器的密码", "timeout": 300, "method": "aes-256-cfb", "mode": "tcp_and_udp", "fast_open": false } EOT cat <<EOT >> /etc/shadowsocks-libev/tunnel.json { "server": "SS服务器的IP地址", "server_port": SS服务端口号, "local_address": "0.0.0.0", "local_port": 15353, "password": "SS服务器的密码", "timeout": 300, "method": "aes-256-cfb", "tunnel_address": "8.8.8.8:53", "mode": "tcp_and_udp", "fast_open": false } EOT
|
停止默认的SS服务并启用上边的三个代理服务:
1 2 3 4 5
| systemctl stop shadowsocks-libev systemctl disable shadowsocks-libev systemctl enable shadowsocks-libev-local@local systemctl enable shadowsocks-libev-redir@redir systemctl enable shadowsocks-libev-tunnel@tunnel
|
DNS服务
很多的大型网站,在国内外会提供不同的版本,如果我们都用国外的DNS来解析,可能会看到非中国的版本或者被解析到国外的服务器而影响浏览速度。所以需要使用一个列表来指定所有的国内网站走国内的DNS:
1 2
| git clone --depth 1 https://github.com/felixonmars/dnsmasq-china-list.git cp dnsmasq-china-list/accelerated-domains.china.conf dnsmasq-china-list/bogus-nxdomain.china.conf /etc/dnsmasq.d/
|
接下来配置dnsmasq并启用服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| cat << EOT >> /etc/dnsmasq.conf strict-order no-resolv no-poll server=127.0.0.1#15353 interface=br1 dhcp-range=192.168.51.50,192.168.51.100,255.255.255.0,24h cache-size=10240 local=/ss/ domain=ss expand-hosts conf-dir=/etc/dnsmasq.d EOT systemctl enable dnsmasq
|
配置无线AP
配置hostapd:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| cat <<EOT >> /etc/hostapd/hostapd.conf interface=wlan0 bridge=br1 driver=nl80211 ssid=SS hw_mode=g channel=7 wmm_enabled=0 macaddr_acl=0 auth_algs=1 ignore_broadcast_ssid=0 wpa=2 wpa_passphrase=ssproxy1234 wpa_key_mgmt=WPA-PSK wpa_pairwise=TKIP rsn_pairwise=CCMP EOT echo 'DAEMON_CONF="/etc/hostapd/hostapd.conf"' >> /etc/default/hostapd systemctl enable hostapd
|
树莓派3B+的无线网卡支持2.4G与5G模式,这里使用的是2.4G模式,以确保最好的兼容性( hw_mode=g
),无线网络的名称为 SS
,密码为 ssproxy1234
,可以根据需要自行修改,另外也要注意频段最好避开家里路由器的频段,这里的频段是7( channel=7
)。
配置iptables与ipset
下载国内IP地址列表并加入ipset:
1 2 3 4 5 6
| curl -sL http://f.ip.cn/rt/chnroutes.txt | egrep -v '^$|^#' > chinaip.txt ipset -N chinaip hash:net for i in `cat chinaip.txt`; do echo ipset -A chinaip $i >> chinaip.sh; done bash chinaip.sh ipset -S > /etc/ipset.chinaip rm -rf chinaip.txt chinaip.sh
|
配置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
| iptables -F iptables -X iptables -t nat -F iptables -t nat -X iptables -t mangle -F iptables -t mangle -X iptables -t raw -F iptables -t raw -X iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT iptables -t nat -N shadowsocks iptables -t nat -A shadowsocks -d 0/8 -j RETURN iptables -t nat -A shadowsocks -d 127/8 -j RETURN iptables -t nat -A shadowsocks -d 10/8 -j RETURN iptables -t nat -A shadowsocks -d 169.254/16 -j RETURN iptables -t nat -A shadowsocks -d 172.16/12 -j RETURN iptables -t nat -A shadowsocks -d 192.168/16 -j RETURN iptables -t nat -A shadowsocks -d 224/4 -j RETURN iptables -t nat -A shadowsocks -d 240/4 -j RETURN iptables -t nat -A shadowsocks -d SS服务器地址 -j RETURN iptables -t nat -A shadowsocks -m set --match-set chinaip dst -j RETURN iptables -t nat -A shadowsocks -p tcp -j REDIRECT --to-ports 1088 iptables -t nat -A shadowsocks -p udp ! --dport 53 -j REDIRECT --to-ports 1088 iptables -t nat -A OUTPUT -p tcp -j shadowsocks iptables -t nat -A OUTPUT -p udp ! --dport 53 -j shadowsocks iptables -t nat -A PREROUTING -p tcp -s 192.168.51/24 -j shadowsocks iptables -t nat -A PREROUTING -p udp ! --dport 53 -s 192.168.51/24 -j shadowsocks iptables -t nat -A POSTROUTING -s 192.168.51/24 -j MASQUERADE iptables-save > /etc/iptables.up.rules
|
注意替换上边命令中的“SS服务器地址”。
当网络连接启动时,自动加载以上规则:
1 2 3 4 5 6 7
| cat <<EOT >> /etc/network/if-pre-up.d/iptables #!/bin/sh /sbin/ipset -R < /etc/ipset.chinaip /sbin/iptables-restore < /etc/iptables.up.rules EOT chmod +x /etc/network/if-pre-up.d/iptables
|
调整内核参数
调整内核,允许转发并参考SS的文档做相应的优化:
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
| cat <<EOT >> /etc/sysctl.d/50-ss.conf # max open files fs.file-max = 1024000 # max read buffer net.core.rmem_max = 67108864 # max write buffer net.core.wmem_max = 67108864 # default read buffer net.core.rmem_default = 65536 # default write buffer net.core.wmem_default = 65536 # max processor input queue net.core.netdev_max_backlog = 4096 # max backlog net.core.somaxconn = 4096 # resist SYN flood attacks net.ipv4.tcp_syncookies = 1 # reuse timewait sockets when safe net.ipv4.tcp_tw_reuse = 1 # turn off fast timewait sockets recycling net.ipv4.tcp_tw_recycle = 0 # short FIN timeout net.ipv4.tcp_fin_timeout = 30 # short keepalive time net.ipv4.tcp_keepalive_time = 1200 # outbound port range net.ipv4.ip_local_port_range = 10000 65000 # max SYN backlog net.ipv4.tcp_max_syn_backlog = 4096 # max timewait sockets held by system simultaneously net.ipv4.tcp_max_tw_buckets = 5000 # TCP receive buffer net.ipv4.tcp_rmem = 4096 87380 67108864 # TCP write buffer net.ipv4.tcp_wmem = 4096 65536 67108864 # turn on path MTU discovery net.ipv4.tcp_mtu_probing = 1 # for high-latency network # net.ipv4.tcp_congestion_control = cubic # forward ipv4 net.ipv4.ip_forward = 1 EOT cat <<EOT >> /etc/security/limits.conf * soft nofile 512000 * hard nofile 1024000 EOT echo "ulimit -SHn 1024000" >> /etc/profile sysctl --system ulimit -n 512000
|
总结
全部配置完成后,重启树莓派,终端通过网线连接交换机的7、8口,或者连接名称为 SS
的无线网络,都可以自动的代理上网了。