上个周末去深圳玩, 正好看到朋友家的路由器, 他和我讲这是一个软路由. 针对国内的网站可以走国内线路, 国外的网站可以走国外的线路. 周末在家正好间研究一下路由器功能. 我知道读者想听什么, 不过我不打算介绍. 你可以利用我的方案去使用virtualbox建立模拟路由器来模拟调试.

博客主要想介绍虚拟机路由器功能的实现以及家用路由器过滤广告的一种方案.

如果使用OpenWRT系统就显得很省事了, 而且整个过程显得很傻瓜, 因为大家都帮你把方案做好了. 所以这里使用的虚拟机是Ubuntu server, Linux用习惯了, 哪个系统都可以的. 折腾路由器还是高中时候的梦想, 我觉得比较有趣吧, 也不是什么新鲜玩意.

网络结构

网络结构如下:

虚拟机创建

我们需要创建两台虚拟机, 一台用于做路由器, 另一台用作普通电脑, 可以有技巧的创建.

首先至少你要有一台Ubuntu机器, 然后右键点击复制, 可以马上增加一台新的虚拟机, 还有什么快照功能也可以试试.

网卡配置

对于路由器, 需要两张网卡

第一张, 用于访问外网

第二张, 提供路由功能

![][4]

对于普通电脑

仅需要一张网卡

![][5]

注意, 这张网卡需要关闭dhcp功能, 具体配置是: 管理=>主机网络管理器=> 不勾选dhcp功能

![][6]

路由器功能实现

平时我们利用路由器上网时, 路由器本身一般有IP192.168.1.1, 而后通过dhcp协议为我们分配IP192.168.1.xxx. 所以在路由器中需要, 1. 固定网卡的IP地址, 2. 建立dhcp服务

固定网卡IP地址

Ubuntu比较新的版本利用了netplan工具, 配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
root@UbuntuRoute:/home/corvo# cat /etc/netplan/00-installer-config.yaml 
# This is the network config written by 'subiquity'
network:
ethernets:
enp0s3:
dhcp4: true
enp0s8:
dhcp4: false
addresses: [192.168.59.1/24]
gateway4: 192.168.101.65
nameservers:
addresses: [8.8.8.8,8.8.4.4]
version: 2

这里enp0s3是路由器用来访问外部网站的网卡, enp0s8是与子网连接的网卡.

建立dhcp服务器

Ubuntu中, 可以安装isc-dhcp-server这个服务器工具, 修改如下配置, 表面dhcp服务器是为enp0s8网卡工作的.

1
2
3
root@UbuntuRoute:/home/corvo# tail -2 /etc/default/isc-dhcp-server
INTERFACESv4="enp0s8"
INTERFACESv6=""

而后, 需要指定dhcp可以分配的网段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root@UbuntuRoute:/home/corvo# tail -8 /etc/dhcp/dhcpd.conf
subnet 192.168.59.0 netmask 255.255.255.0 {
option routers 192.168.59.1;
# 注意子网掩码别填错, 上面的/24 表明子网掩码是255.255.255.0
option subnet-mask 255.255.255.0;

# 指定dns服务器
option domain-name-servers 114.114.114.114;

# dhcp可以分配到的网段, 100~200区间
range 192.168.59.100 192.168.59.200;
}

# 启动dhcp服务器
root@UbuntuRoute:/home/corvo# systemctl start isc-dhcp-server.service

普通电脑连接确认

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
corvo@UbuntuClient:~$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:2d:f9:1e brd ff:ff:ff:ff:ff:ff
inet 192.168.59.100/24 brd 192.168.59.255 scope global dynamic enp0s3
valid_lft 499sec preferred_lft 499sec

# 查看当前的dns服务器
corvo@UbuntuClient:~$ resolvectl status | tail -3
DNSSEC supported: no
Current DNS Server: 114.114.114.114
DNS Servers: 114.114.114.114

路由器增加数据包转发功能

目前我们的电脑已经获得了ip地址, 下一步就是上网操作, 主要有两步, 均在路由器上进行:

1
2
3
4
5
6
# 允许内核在不同网卡间转发数据包
UbuntuRoute# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
UbuntuRoute# sysctl -p

# nat流量均转发到enp0s3网卡
UbuntuRoute# iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE

下一步你就可以试着在普通的电脑中上网了:

1
2
corvo@UbuntuClient:~$ curl ip.sb
113.67.xx.xxx

内网DNS服务器搭建以及广告过滤功能

我之前的博客中已经介绍了DNS服务: https://corvo.myseu.cn/2018/07/30/2018-07-30-DNS%E7%9B%B8%E5%85%B3/

dns服务器建立

上面的例子中, dns服务器我们偷懒了, 用的是114.114.114.114, 当然也是可以自建dns服务的, 一般来用dnsmasq.

1
2
3
4
5
6
# 安装dnsmasq
> apt install dnsmasq
# 关闭原有的本机解析服务
> systemctl stop systemd-resolved.service
# 启动dnsmasq
> systemctl start dnsmasq

这个时候你应该是无法访问任何网站的, 因为还没有配置dnsmasq服务, 我是在配置文件中增加上游dns服务器, 然后重启dnsmasq.

1
2
UbuntuRoute# tail -3 /etc/dnsmasq.conf
server=114.114.114.114

修改dns服务器指向

由于我们使用了dhcp服务器, 修改的部分是dhcp服务器的配置, 修改完需要重启dhcp服务

1
2
3
4
5
6
7
8
9
10
11
12
root@UbuntuRoute:/home/corvo# tail -8 /etc/dhcp/dhcpd.conf
subnet 192.168.59.0 netmask 255.255.255.0 {
option routers 192.168.59.1;
# 注意子网掩码别填错, 上面的/24 表明子网掩码是255.255.255.0
option subnet-mask 255.255.255.0;

# 指定dns服务器, 注意看, 这里变成了路由器的IP
option domain-name-servers 192.168.59.1;

# dhcp可以分配到的网段, 100~200区间
range 192.168.59.100 192.168.59.200;
}

稍等几分钟, 或者你重启下那台用户电脑, 会发现它的dns地址改变了

1
2
3
4
corvo@UbuntuClient:~$ resolvectl status  | tail -3
DNSSEC supported: no
Current DNS Server: 192.168.59.1
DNS Servers: 192.168.59.1

一种广告过滤功能的实现

我接触的一些是通过dns劫持实现的, 比如这个黑名单,里面记载了广告, 分析网站的域名, 利用dnsmasq, 将它们的域名返回为0.0.0.0

1
2
3
4
5
6
wget -O /etc/dnsmasq.d/notracking.conf https://raw.githubusercontent.com/notracking/hosts-blocklists/master/dnsmasq/dnsmasq.blacklist.txt

# 其中的内容是类似这样的语句
> address=/00-gov.cn/#
> address=/000-hidro-1.info/#
> address=/000359.xyz/#

然后打开dnsmasq的include功能, 增加conf-dir=/etc/dnsmasq.d/,*.conf 而后重启dnsmasq就可以达到想要的效果了, 例如

1
2
3
4
5
6
7
# 路由器上的效果
UbuntuRoute# dig +short 000-hidro-1.info
0.0.0.0

# 用户电脑中的效果
corvo@UbuntuClient:~$ dig +short 000-hidro-1.info
0.0.0.0

广告过滤的功能基本就实现了.

总结

我主要想介绍下路由器简单的实现原理, 顺便介绍内网dns服务器的搭建和使用, 只了解了这些对你的目的来说应该是不够的, 建议多了解下iptables, 你可以轻松的实现各种分流的效果. 当然, 你需要把dnsmasq也玩好.

[4]: https://rawforcorvofeng.cn/Snipaste_2020-12-06_22-04-33.png [5]: https://rawforcorvofeng.cn/Snipaste_2020-12-06_22-05-57.png [6]: https://rawforcorvofeng.cn/Snipaste_2020-12-06_22-07-45.png