网上有很多关于软路由、旁路由(旁路网关)的文章,但是说真的,即便是很多程序员也不太能玩得转这一套。而且软硬件总有失灵的时候,一旦出问题,就只能等着你一个人来修,影响家庭成员的正常网络访问,
为了更好的将科学上网&网络加速的需求透明无感地融入到家庭网络中,需要仔细选择。
先列出该方案的优缺点供诸君参考。
优势
1、不需要给路由器刷机、买软路由,任意一个单网口Linux主机即可;
2、不动网络拓扑,完全不影响国内流量,稳定性高,可插拔(物理意义上的);
3、按需配置,按照域名精细化控制是否需要加速;
4、界面化操作,普通人也可以维护;
5、不需要研究复杂的iptables规则!;
缺点
1、基本上只支持标准端口的 http & https 协议;
2、除了已有的gfwlist列表外,需要手动添加个人常用的域名列表;
3、如果部分硬件设备或app指定了dns,不使用dhcp分配的,不生效;
4、部分网站可能由于奇奇怪怪的问题无法访问,例如 dash.cloudflare.com 页面经常加载静态资源失败
适合场景
1、对 Linux 和 网络配置相关不够熟悉;
2、没有太多精力维护,希望足够简单并且尽可能稳定,不会影响家人的正常使用;
3、主要是访问网站,玩外网游戏有专门的加速器
需求
1、一个普普通通的路由器
2、一个Linux小主机,这是所有透明代理方案下都必须的
3、一个支持 V2ray 协议的代理(当然其他也可以啊,这里就不列了)
原理
将需要加速的网站域名解析到Linux主机,然后走加密&混淆通道出国,其他正常解析
步骤
- 现在习惯了用docker来运行程序,所以后续大多数服务使用docker启动,供参考。
- 假设Linux主机的局域网地址为192.168.7.6,后续配置需要参照修改
1 2
| curl -fsSL https://get.docker.com | sh
|
1、部署、配置DNS服务(AdGuardHome)
1 2 3 4 5 6 7 8 9 10 11 12
| sudo mkdir -p /data/adh/work/ sudo mkdir -p /data/adh/conf/
sudo docker run \ -d \ --restart always \ --name adguardhome \ --mount type=bind,src=/data/adh/work/,dst=/opt/adguardhome/work/ \ --mount type=bind,src=/data/adh/conf/,dst=/opt/adguardhome/conf/ \ -p 53:53/udp \ -p 3000:3000/tcp \ adguard/adguardhome
|
其他安装方式可以参考: https://github.com/AdguardTeam/AdGuardHome?tab=readme-ov-file#automated-install-linuxunixmacosfreebsdopenbsd
访问 http://192.168.7.6:3000 进行初始化,并将上游DNS服务器配置为 114.114.114.114。(为了提升可用性,可以再添加其他的国内DNS服务器,如 223.5.5.5)
![Setup upstream DNS servers](https://image.newnius.com/images/2024/07/bfaff5aa-e877-4309-a87f-5c044dbac8f9.png)
参考如下图,添加需要加速的域名,后面的IP地址为 192.168.7.6 。可以基于 gfwlist 生成一个初始的配置,后续再慢慢添加。
![Add domains need acceleration](https://image.newnius.com/images/2024/07/57555b03-8ccb-42f7-ae7b-f18d460e3ee9.png)
这里贴一个脚本来处理gfwlist文件,并且通过API更新到 AdGuardHome 中。
1 2 3 4 5 6 7 8 9
| wget 'https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt'
cat gfwlist.txt | base64 -d > gfwlist.txt.decoded
cat gfwlist.txt.decoded | grep -v '^!' | grep '\.' | grep -v '@@|' | grep -v '/' | grep -v '\[' > gfwlist.txt.blocked
cat gfwlist.txt.blocked | sed 's/^\.//g' | sed 's/||//g' | sort | uniq > gfwlist.txt.domains
cat gfwlist.txt.domains | rev | sort | rev | grep -v '%' | grep -v ':' | grep -v '\.xn--' > gfwlist.txt.list
|
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
| import requests import json
base_url = "http://192.168.7.6:3000" USERNAME="" PASSWORD="" target_ip = '192.168.7.6'
login_url = base_url + "/control/login" list_url = base_url + "/control/rewrite/list" add_url = base_url + "/control/rewrite/add" del_url = base_url + "/control/rewrite/delete"
target_domains = {} session = requests.Session()
headers = {'Content-Type': 'application/json'} auth = json.dumps({'name': USERNAME, 'password': PASSWORD}) response = session.request('POST', login_url, headers=headers, data = auth) assert(response.status_code == requests.codes.ok)
response = session.request('GET', list_url) assert(response.status_code == requests.codes.ok)
current_list = json.loads(response.text) file1 = open('backup.list', 'w') for item in current_list: target_domains[item['domain']] = True file1.writelines(item['domain']+"\n") file1.close()
index = 0 count = len(target_domains) for domain in target_domains.keys(): index+=1 print(f"delete {index} of {count}: {domain}") item = json.dumps({'domain': domain, 'answer': target_ip}) response = session.request('POST', del_url, headers=headers, data = item) assert(response.status_code == requests.codes.ok)
file1 = open('gfwlist.txt.list', 'r') lines = file1.readlines() for line in lines: domain = line.strip() target_domains[domain] = True if not domain.startswith("*."): target_domains["*."+domain] = True
index = 0 count = len(target_domains) for domain in target_domains.keys(): index+=1 print(f"add {index} of {count}: {domain}") item = json.dumps({'domain': domain, 'answer': target_ip}) response = session.request('POST', add_url, headers=headers, data = item) assert(response.status_code == requests.codes.ok)
|
2、部署、配置V2ray代理
这里不过多介绍V2ray是什么以及如何部署服务器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| sudo mkdir -p /data/v2ray/config/
wget 'https://code.newnius.com/snippets/Conf/raw/branch/master/v2ray/gateway.json'
vim gateway.json
sudo mv gateway.json /data/v2ray/config/
sudo docker run \ --name v2ray-gateway \ -d \ --restart always \ --dns 114.114.114.114 \ --publish mode=host,published=80,target=80 \ --publish mode=host,published=443,target=443 \ --mount type=bind,source=/data/v2ray/config/,target=/etc/v2ray/,readonly \ v2fly/v2fly-core run -config=/etc/v2ray/gateway.json
|
主要是用到了 V2ray 的 Dokodemo-door(任意门)协议: https://www.v2fly.org/config/protocols/dokodemo.html
其他安装方式可以参考: https://www.v2fly.org/guide/install.html
3、路由器配置 DNS & NAT
根据具体的路由器,将DHCP中的主DNS服务器配置为 192.168.7.6,备DNS服务器维持 0.0.0.0 (即自动获取)。
通常情况下设备会使用主DNS来解析域名,在主dns服务器无法使用的情况下会切换到备DNS服务器,这样的配置可以使得即便在Linux主机掉线的情况下,也会回落到原始的方案,不影响访问大局域网。
另外就是记得路由器里不要开启AP隔离,不然内网各个设备无法互相访问。(不过既然已经可以连接到Linux主机了,大概率不会遇到这个问题,仅作参考)
4、重启路由器或重新连接生效
重启路由器,或者重新连接Wi-Fi使得重新获取