拿树莓派 4 折腾个软路由
· 4 min read
之前在住处用 Ubiquiti 家的 EdgeRouter X,那玩意差不多是刚毕业那会买的,那时候用的是个小米路由器,在家里设备多所以天天吃满 U 和内存导致路由器重启。 然后合计着就换了 ER-X,换完那是一个香啊(毕竟 100Mbps 的带宽家用能搞出啥幺蛾子)!然后再也没折腾过路由。。。
直到最近,因为疫情的关系电信给大部分地区都上了免费提速(给到 500 下 30 上),所以薅上发现家里到不了 500Mbps。看了下大概是 CPU 跑不上了,因为也想倒腾所以查也不查也决定去搞个软路由了。
一开始是直接以挑低功耗电脑为方向去挑,后来想想似乎也没有必要搞那么高的配置,而且有句话说的好「200 预算软路由,2000 已付提电脑」所以最后选了树莓派做软路由。自己以前是把玩过树莓派,也多少知道有些坑
- ARM 的 U 有时候资源不是那么好搞
- CPU 主频低
- 网口少,不过 USB 3.0 也有了外接吧(不过好在 Pi4 现在有了千兆口
不过 Pi 的优点也不少,比如低功耗、占地面积小(0.000000001 平方米,别介),相对于普通「硬路由」他能够提供我们比较熟悉的 Linux 环境去搞事情,也就是我们看中的软路由的「软」。
打算拿软路由做啥
先说说目前用 ER-X 的痛点吧
- 存储小,不好装东西
- 系统是改过的相对于原生的 Debian 还是有点不同
- CPU 性能不咋地
- 挺多功能其实用不多,比如 VLAN
之前拿 ER-X 做过分流的东西,但整体因为 U 性能不太好,所以走 iptables + ipset 来解决分流规则过多的问题,然后跑个梯子有时候挺呛。
所以就目前来说,我是打算做一个精简的路由,然后适当的佐以监控能力(毕竟有时候 163 抖得很),配点 DoH、路由优化(比如部分海外流量走 CN2 出去)就差不多了。
交代下
- Raspberry Pi 4 - 4G Ver
- SanDisk 64GB U3 C10 A2 V30 4K(读 160MB/s 写 60MB/s)
- 某不知名的散热外壳
- 光猫改桥接
- 华硕 USB 3.0 转 RJ45 AX88179
- 网件 8 口千兆交换机
- Ubuntu 18.04
整理后的网络拓扑(瞎鸡儿画)
以上有几个点
- USB 3.0 网卡是 eth1,为啥拿他接公网,因为公网大多小,需求量不那么大,所以选他
- eth1 本身是有光猫内网的,所以我们平时如果 Pi 的内网丢了可以通过光猫内网去调试。再不行只能 HDMI 大法了
- eth0 是 Pi 的千兆口做内网对接比较舒服
- 我的拓扑有多一层交换机,但从这层开始就看各自的网络情况了,并非必须。
- PPPoE 在光猫层做桥接模式在 Pi 上拨号是为了少一层 NAT 也更便于控制
- 光猫内网是 192.168.1.1/24,Pi 自己划分的内网是 10.7.1.1/24(没啥关系,主要是蛮交代下)
完成基本路由功能需要搞啥
- DHCP
- PPPoE
- iptables(NAT、Firewall)
就以上这三个就足够实现基本路由能力。
那就开搞吧,先把 eth0(Pi 自带网口)接上光猫,然后上去盲配下 eth1(毕竟一会要拿 USB 去跟光猫 py)。netplan 配置到跟下面的情况差不多就好了
ubuntu@ubuntu:~$ cat /etc/netplan/50-cloud-init.yaml
# This file is generated from information provided by the datasource. Changes
# to it will not persist across an instance reboot. To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
ethernets:
eth0:
addresses:
- 10.7.1.1/24
gateway4: 10.7.1.1
dhcp4: false
dhcp6: false
eth1:
dhcp4: true
dhcp4-overrides:
use-routes: false
optional: true
version: 2
eth0 这边我们预先写了静态 IP(因为后面 DHCP 要用,总不能厚着脸皮也要 DHCP 分配吧,它都不认你),注意不要给 eth0 加optional: true
,这个参数会让 eth0 还没有 UP 的时候就认为 network.target 启动完毕导致后续 DHCP 启动的时候会读 eth0 会发现没有 IP(如果两个启动时间挨得近的话)。
eth1 这边走 DHCP 去找光猫要个地址方便管理,然后 user-routes: false
那边主要是不想路由被加上 default via 192.168.1.1
的默认路由来影响后续的控制,毕竟后续咱们默认走的都是 PPPoE 的口子出去。
然后这时候以极快的速度 netplan apply
然后把 eth0 上光猫的线切到 eth1 上,然后 eth0 接上交换机(或者你的路由器)。然后静静等光猫分配 IP 给 Pi(这时候谁也不知道 IP 是啥,自己上光猫界面或者拿 nmap 扫下)。
DHCP Server
老套路,就用 isc-dhcp-server
吧,一把梭 apt install isc-dhcp-server -y
over。然后配一下配置
root@ubuntu:~# cat /etc/dhcp/dhcpd.conf | grep -iv '#'
option domain-name "example.org";
option domain-name-servers ns1.example.org, ns2.example.org;
default-lease-time 600;
max-lease-time 7200;
ddns-update-style none;
authoritative;
subnet 10.7.1.0 netmask 255.255.255.0 {
option routers 10.7.1.1;
option subnet-mask 255.255.255.0;
option domain-name-servers 119.29.29.29, 223.5.5.5;
range 10.7.1.100 10.7.1.254;
}
root@ubuntu:~# cat /etc/default/isc-dhcp-server
# Defaults for isc-dhcp-server (sourced by /etc/init.d/isc-dhcp-server)
# Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf).
#DHCPDv4_CONF=/etc/dhcp/dhcpd.conf
#DHCPDv6_CONF=/etc/dhcp/dhcpd6.conf
# Path to dhcpd's PID file (default: /var/run/dhcpd.pid).
#DHCPDv4_PID=/var/run/dhcpd.pid
#DHCPDv6_PID=/var/run/dhcpd6.pid
# Additional options to start dhcpd with.
# Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead
#OPTIONS=""
# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
# Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACESv4="eth0"
INTERFACESv6="eth0"
以上 dhcpd.conf
我主要是增加了一个 subnet,这块就按需调整吧。然后在 /etc/default/isc-dhcp-server
里面指定下我们做内网的口子 eth0
接着
systemctl enable isc-dhcp-server
systemctl restart isc-dhcp-servere
那 DHCP 就差不多了,找个东西插一下 eth0 看看能不能拿到 IP 就差不多了。
PPPoE
把 WAN 口接上线连到 eth1(如果不先链接 pppoeconf 扫口的时候会扫不到),装下 pppoeconf
然后配置下就好。
apt install pppoeconf -y
pppoeconf # 开始配置,然后该怎么填怎么填了
安装完后检查下确认 ppp0
这个口起来了,也拿到了公网 IP(也可能是内网)大概就像下面
5: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1492 qdisc fq_codel state UNKNOWN group default qlen 3
link/ppp
inet 8.8.8.8 peer 8.8.8.1/32 scope global ppp0
valid_lft forever preferred_lft forever
上面 netplan 如果没有加上 use-routes: false
会导致一个结果就是你有两条 metric 相同的 default route 结果就是上不了公网。所以一定要配!
iptables/NAT
那接下来配下 NAT 就更简单了。
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
# 临时开下 IPv4 的转发,如果你要持久生效自行改下 sysctl 配置
sysctl -w net.ipv4.ip_forward=1
记得做下持久化(save 和 restore)!
我这边实际用的是 nftables,所以配置大概长这样
root@ubuntu:~# cat /etc/nftables.conf
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0;
}
chain forward {
type filter hook forward priority 0;
}
chain output {
type filter hook output priority 0;
}
}
table ip nat {
chain postrouting {
type nat hook postrouting priority 100; policy accept;
oifname "ppp0" masquerade
}
}
总结
那基本上一个能跑的软路由就是这样了,没啥东西,就是有些坑得踩踩。
其实在配的过程中,更多考虑了怎么做快速切备用(哪天派炸了得切走),以及一些备用的方案,但这些各自网络环境不同所以也就不赘述了。
那接下来大概还可以做什么
- 分流
- 监控
- DNS 优化
- 调路由(如果你有多出口)
以上只是简单记录下配置的过程,并不是最终教程,如果是没把握尽量别按这个来,不然到时候就局域网了。