Ubuntu 软路由(篇一):配置基于 ubuntu 的软路由

将 Ubuntu 主机配置成一台路由器。


概述

主要实现功能

  • 准备硬件:一台具有多个网口的 ubuntu 主机 (以 ubuntu server 20.04 版本举例)
  • 配置路由机的路由表
  • 路由机开启端口转发功能
  • 路由机安装域名服务器
  • 路由机安装 DHCP 服务
  • 路由机 重启加载 iptables 规则

机器的硬件信息

  • 路由机(列出 mac 地址以供后续使用)
    • enp0s1 XX:XX:XX:XX:XX:01
    • enp0s2 XX:XX:XX:XX:XX:02
    • enp0s3 XX:XX:XX:XX:XX:03

计划

  • 将 enp0s1 作为 wan 口
  • 将 enp0s2, lenp0s3 作为 lan 口
  • DHCP 服务监听在 lan 口上

具体步骤

为网卡改名

ubuntu20.04 中使用 netplan 来配置网络信息,其配置文件为 /etc/netplan/00-installer-config.yaml (名称可能为任何 xxx.yaml)
编辑 netplan 配置文件,将 ethernets 字段改为如下:
保存之后使用 netplan apply 使之生效

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ethernets:
wan1:
match: # 根据mac地址匹配,将配置参数应用到匹配的网卡上
macaddress: XX:XX:XX:XX:XX:01
set-name: wan1 # 提高可读性,将网卡重命名为 wan1
# dhcp4: true # 动态IP,启用时需删除addresses,gateway4,nameservers
addresses: # 静态IP,据上级路由器而定,启用时关闭动态IP
- 192.168.1.11/24
gateway4: 192.168.1.1 # 设置静态IP时需要
nameservers: # 设置静态IP时需要
addresses:
- 192.168.1.1
eth1:
match:
macaddress: XX:XX:XX:XX:XX:02
set-name: eth1
dhcp4: no
eth2:
match:
macaddress: XX:XX:XX:XX:XX:03
set-name: eth2
dhcp4: no

开启端口转发功能

ubuntu 默认的未开启端口转发功能,需要手动开启,
打开 /etc/sysctl.conf 并设置如下字段:

1
net.ipv4.ip forward=1

还需要在 iptables 设置 nat 表的转发 (重启之后会失效,还需要持久化配置)

1
sudo iptables -t nat -A POSTROUTING -o wan1 -j MASQUERADE

持久化 iptables 的配置

ubuntu20 中使用 systemd 来管理开机任务
这里创建一个 service,作用是在开机时加载 iptables 规则,在关机时保存 iptables 规则

  • service 文件路径 /etc/systemd/system/myiptables.service
  • 处理 iptables 的脚本路径 /home/root/iptable.bash
  • iptables 备份文件保存路径 /home/root/backup.iptable.ipv4

创建文件 service 文件,内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description=backup iptables when shutdown & restore iptables when boot
After=chinadns-ng.service
After=myipset.service

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/bash /home/root/iptable.bash restore # 开机时执行的命令
ExecStop=/bin/bash /home/root/iptable.bash backup # 关机时执行的命令

[Install]
WantedBy=multi-user.target

上面用到的保存 iptables 数据的脚本 iptable.bash 内容如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
default_backup_file="/home/root/backup.iptable.ipv4"

action=$1
backup_file=${2:-$default_backup_file}

if [[ "$action" == 'restore' ]]; then
/sbin/iptables-restore <"${backup_file}"
exit 0
fi
if [[ "$action" == 'backup' ]]; then
ensure_dir_exist "$(dirname "$backup_file")"
/sbin/iptables-save >"${backup_file}"
exit 0
fi

echo iptables backup_file path: "${default_backup_file}"
echo "user param: 'backup' or 'restore'"
exit 1

保存好脚本
之后手动保存一次 iptables 的数据: iptables-save > /home/root/backup.iptable.ipv4
接下来开始激活 myiptables.service:

1
2
3
sudo systemctl daemon-reload # systemd刷新service文件
sudo systemctl enable myiptables # 启用开机自启动 myiptables
sudo systemctl start myiptables # 运行 myiptables

至此 iptables 数据能够实现开机不丢失。

配置网桥

目的是让 lan 口的多个设备之间可以通信
编辑 netplan 的配置文件: /etc/netplan/00-installer-config.yaml
ethernets 同级别增加字段 bridges,之后重启 netplan

1
2
3
4
5
6
7
8
bridges:
br:
interfaces: # 网桥上要包含的端口
- eth1
- eth2
addresses: # 网桥的地址
- 10.10.20.1/24
dhcp4: no

dnsmasq: 配置 DHCP 和 DNS 服务

安装域名服务 dnsmasq: apt-get install dnsmasq

修改 /etc/dnsmasq.conf 修改字段为以下配置

1
2
3
4
5
6
7
8
listen-address=127.0.0.1,10.10.20.1 # 监听 127.0.0.1 和 网桥的地址
port=53 # DNS 服务端口
interface=eth1 # DNS & DHCP 服务网卡
interface=eth2 # DNS & DHCP 服务网卡

dhcp-range=10.10.20.10,10.10.20.99,255.255.255.0,12h # DHCP 的IP范围,子网掩码,租期
dhcp-option=option:router,10.10.20.1 # 网关地址(网桥)
dhcp-option=option:dns-server,10.10.20.1 # DNS 地址

之后重启 dnsmasq: systemctl restart dnsmasq.service

如果因为 53 端口被占用启动失败,需要先停止 systemd-resolved 服务:

1
2
sudo systemctl stop systemd-resolved      # 关闭服务,但是开机还会自启动
sudo systemctl disable systemd-resolved # 开机不再自启动

至此路由器即可正常工作。