树莓派配置 Shadowsocks 网关代理

Shadowsocks

360云盘忽然宣布转型,停止个人云盘服务,导致大量用户下载自己存放资料,360服务器对下载进行了限速,电脑挂着下了好久才把所有资料取下来。这也太不靠谱了!为什么不搞个私有云?网上一搜,发现树莓派不错,扩展性强、功耗低、小巧。。。关键是便宜!私有云可以搞那私有梯子要不要?

Shadowsocks服务端

要科学上网,首先需要一台墙外的 VPS。一直用 DigitalOcean (Ubuntu)搭建的VPN,关键还是便宜(5$/mo)。
使用 Shadowsocks-libev 进行部署,纯 C 编写,效率高。

下载源码,编译安装:

git clone https://github.com/shadowsocks/shadowsocks-libev.git
cd shadowsocks-libev
# Debian / Ubuntu
sudo apt-get install --no-install-recommends build-essential autoconf libtool libssl-dev libpcre3-dev asciidoc xmlto
./configure && make
sudo make install

编辑/etc/rc.local,增加如下配置(port、password换成自己的配置),shadowsocks 将开机启动:
/usr/local/bin/ss-server -s 0.0.0.0 -p port -k password -m aes-256-cfb -u > /root/ss.log 2>&1 &

树莓派配置

简介

gfwlist:被墙网址列表
dnsmasq:局域网 DNS 服务,对被墙网址使用指定DNS进行解析
ipset:指定的规则 ip 访问自动走 shadowsocks 的本地代理线路并重定向到之前配置的 shadowsocks 服务器

安装 Shadowsocks 客户端

启用 root 账号

树莓派默认root账号关闭,执行以下命令解锁root

sudo passwd **
sudo passwd --unlock root

配置静态 IP

网上很多资料修改/etc/network/interfaces进行配置,但是没有效果
最终官方论坛找到结果
修改配置文件/etc/dhcpcd.conf,增加如下配置:

interface eth0
static ip_address = 192.168.0.88/24
static routers = 192.168.0.1
static domain_name_servers = 192.168.0.1 8.8.8.8 8.8.4.4

安装 Shadowsocks

安装同服务器端安装:

git clone https://github.com/shadowsocks/shadowsocks-libev.git
cd shadowsocks-libev
# Debian / Ubuntu
sudo apt-get install --no-install-recommends build-essential autoconf libtool libssl-dev libpcre3-dev asciidoc xmlto
./configure && make
sudo make install

打开 NAT 网关

编辑/etc/sysctl.conf,修改:
net.ipv4.ip_forward=1

让更新实时生效:
sysctl -p /etc/sysctl.conf

安装配置 dnsmasq

安装:sudo apt-get install ipset dnsmasq

iptables配置:

1
2
3
sudo ipset -N ss iphash
sudo iptables -t nat -A PREROUTING -p tcp -m set --match-set ss dst -j REDIRECT --to-port 1080
sudo iptables-save > /etc/sysconfig/iptables

编辑/etc/dnsmasq.conf,修改:

1
2
3
# Include another lot of configuration options.
#conf-file=/etc/dnsmasq.more.conf
conf-dir=/etc/dnsmasq.d

然后创建一个 google 的规则/etc/dnsmasq.d/google.conf 内容为:

1
2
3
4
server=/.googleapis.com/208.67.222.222#5353
ipset=/.googleapis.com/ss
server=/.google.com/208.67.222.222#5353
ipset=/.google.com/ss

sudo service dnsmasq restart 重启服务,将局域网内其他设备的网关设置以及 DNS 设置为192.168.0.88即可以访问 google。

启动脚本

#!/bin/sh
ipset -N ss iphash
iptables-restore < /etc/sysconfig/iptables
nohup /usr/local/bin/ss-redir -vc /home/pi/config.json 1 > /home/pi/ssredir.log 2>&1 &

更新gwflist

每天自动更新 gfwlist 到 dnsmasq 配置。新建/etc/cron.daily/dnsmasq-gfwlist.py代码参考

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
71
72
73
74
75
76
77
#!/usr/bin/env python
#coding=utf-8
#
# Generate a list of dnsmasq rules with ipset for gfwlist
#
# Copyright (C) 2014 http://www.shuyz.com
# Ref https://code.google.com/p/autoproxy-gfwlist/wiki/Rules

import urllib2
import re
import os
import datetime
import base64
import shutil

mydnsip = '208.67.222.222'
mydnsport = '5353'

# the url of gfwlist
baseurl = 'https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt'
# match comments/title/whitelist/ip address
comment_pattern = '^\!|\[|^@@|^\d+\.\d+\.\d+\.\d+'
domain_pattern = '([\w\-\_]+\.[\w\.\-\_]+)[\/\*]*'
tmpfile = '/tmp/gfwlisttmp'
# do not write to router internal flash directly
outfile = '/tmp/gfwlist.conf'
rulesfile = '/etc/dnsmasq.d/gfwlist.conf'

fs = file(outfile, 'w')
fs.write('# gfw list ipset rules for dnsmasq\n')
fs.write('# updated on ' + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+ '\n')
fs.write('#\n')

#print 'fetching list...'
content = urllib2.urlopen(baseurl, timeout=15).read().decode('base64')

# write the decoded content to file then read line by line
tfs = open(tmpfile, 'w')
tfs.write(content)
tfs.close()
tfs = open(tmpfile, 'r')

#print 'page content fetched, analysis...'

# remember all blocked domains, in case of duplicate records
domainlist = []

for line in tfs.readlines():
if not re.findall(comment_pattern, line):
#print 'this is a comment line: ' + line
#fs.write('#' + line)
#else:
domain = re.findall(domain_pattern, line)
if domain:
try:
found = domainlist.index(domain[0])
#print domain[0] + ' exists.'
except ValueError:
#print 'saving ' + domain[0]
domainlist.append(domain[0])
fs.write('server=/.%s/%s#%s\n'%(domain[0],mydnsi
p,mydnsport))
fs.write('ipset=/.%s/ss\n'%domain[0])
#else:
#print 'no valid domain in this line: ' + line

tfs.close()
fs.close();

#print 'moving generated file to dnsmasg directory'
shutil.move(outfile, rulesfile)

#print 'restart dnsmasq...'
print os.popen('/etc/init.d/dnsmasq restart').read()

#print 'done!'

DHCP服务器配置

家里是小米路由器,竟然不支持分配局域网DNS以及网关,所以禁用掉路由器的 DHCP 服务器,将树莓派作为局域网的 DHCP 服务器。
安装 sudo apt-get install isc-dhcp-server
修改配置文件/etc/dhcp/dhcpd.conf

1
2
3
4
5
6
7
8
subnet 192.168.0.0 netmask 255.255.255.0 {
range 192.168.0.2 192.168.0.250;
option routers 192.168.0.88;
option broadcast-address 192.168.0.255;
default-lease-time 600;
max-lease-time 7200;
option domain-name-servers 192.168.0.88;
}

修改配置文件/etc/default/isc-dhcp-server配置 DHCP 网卡:
INTERFACES="eth0"
重启服务:
sudo service isc-dhcp-server restart
现在整个局域网就可以不进行任何代理设置,直接科学上网了!!!

Cotin Yang wechat
欢迎订阅我的微信公众号 CotinDev
小小地鼓励一下吧~😘