软路由并不是必须购买专用设备。手头有一台带两个网口的旧电脑或低功耗小主机,安装Ubuntu Server后,就能用iptables和Dnsmasq组合出完整的路由转发、地址分配和DNS解析能力。相比刷OpenWrt等固件,这种方案更接近标准Linux操作,可定制性也更高,适合需要扩展防火墙规则或跑其他服务的情况。

下面从网络规划开始,到NAT、DHCP、防火墙和测试,完整走一遍配置。文中假设外网网卡为enp1s0,内网网卡为enp2s0,内网网段使用192.168.10.0/24。
一、网络规划与基础环境准备
软路由至少需要两个物理网口:一个接光猫或上级路由器,称为WAN口;另一个接内网交换机或电脑,称为LAN口。先通过ip a或ls /sys/class/net确认两张网卡的准确名称。Ubuntu使用可预测命名后,常见名称是enp1s0、enp2s0、eth0等,不要照搬,要根据实际输出修改配置。
安装系统时建议选择Ubuntu Server镜像,不装图形界面。安装完成后更新软件源并安装三个必要的包:net-tools提供旧版ifconfig等工具、iptables-persistent用于保存防火墙规则、dnsmasq负责DHCP和DNS。执行以下命令。
sudo apt update sudo apt install net-tools iptables-persistent dnsmasq
接下来要给LAN口设置静态IP地址。WAN口可以继续使用DHCP从上级网络获取地址,也可以配置静态IP。Ubuntu 18.04及以上使用Netplan管理网络,配置文件位于/etc/netplan/目录。编辑类似00-installer-config.yaml的文件,写入下面的配置。注意缩进必须使用空格,不能使用Tab。
network:
version: 2
ethernets:
enp1s0:
dhcp4: true
enp2s0:
dhcp4: no
addresses:
- 192.168.10.1/24
保存后执行sudo netplan apply使配置生效。然后运行ip addr show enp2s0确认地址已经出现。如果配置没有成功,检查缩进和网卡名称是否写错,并用sudo netplan try验证。
二、开启IP转发并配置NAT
Ubuntu默认不会在网卡之间转发数据包,这是出于安全考虑。软路由的核心任务就是把LAN口收到的数据包根据路由表送到WAN口,并把返回流量送回内网。要打开这个能力,需要修改内核参数net.ipv4.ip_forward。临时开启可以执行sudo sysctl -w net.ipv4.ip_forward=1,永久生效需要写入/etc/sysctl.conf。
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf sudo sysctl -p
执行后可以用sysctl net.ipv4.ip_forward查看,结果应该是net.ipv4.ip_forward = 1。这一步只是允许转发,但内网设备使用的是私网地址,公网路由器通常不会回程到私网网段,因此还要在WAN口上做源地址转换,也就是NAT。
使用iptables的MASQUERADE目标可以自动把内网地址替换为WAN口当前获取的地址。因为WAN口如果使用DHCP,IP地址可能变化,所以MASQUERADE比固定SNAT更省心。添加规则前,先确认iptables命令可用,然后执行:
sudo iptables -t nat -A POSTROUTING -o enp1s0 -j MASQUERADE sudo iptables -A FORWARD -i enp2s0 -o enp1s0 -j ACCEPT sudo iptables -A FORWARD -i enp1s0 -o enp2s0 -m state --state RELATED,ESTABLISHED -j ACCEPT
第一条规则在nat表的POSTROUTING链上匹配从WAN口出去的数据包并执行MASQUERADE;第二条允许内网到外网的新建连接;第三条允许外网返回的已建立连接和关联连接回到内网。缺少第三条时,即使NAT成功,回程流量也会被防火墙拦截。
这些规则重启后会丢失,需要保存。Ubuntu中iptables-persistent会读取/etc/iptables/rules.v4。可以用下面的命令生成规则文件,或者安装过程中选择保存现有规则。
sudo mkdir -p /etc/iptables sudo sh -c 'iptables-save > /etc/iptables/rules.v4' sudo systemctl enable netfilter-persistent
注意命令中的>表示重定向,必须放在引号内交给root shell执行,否则普通用户没有权限写目标文件。保存完成后可以重启测试,登录后执行sudo iptables -t nat -L -n -v查看规则是否已经恢复。
三、用Dnsmasq提供DHCP和DNS服务
内网设备要自动获取IP地址和DNS服务器,就需要DHCP服务。Dnsmasq是一个轻量级工具,同时支持DHCP、DNS缓存和TFTP,很适合软路由场景。安装完成后,主配置文件是/etc/dnsmasq.conf。建议先备份原文件,再写入精简配置。
sudo cp /etc/dnsmasq.conf /etc/dnsmasq.conf.bak sudo tee /etc/dnsmasq.conf <<'EOF' interface=enp2s0 bind-interfaces dhcp-range=192.168.10.50,192.168.10.150,12h dhcp-option=3,192.168.10.1 dhcp-option=6,223.5.5.5,119.29.29.29 server=223.5.5.5 cache-size=500 EOF
这里interface指定Dnsmasq只监听内网网卡,bind-interfaces避免绑定到WAN口。dhcp-range定义了地址池范围从192.168.10.50到192.168.10.150,租期12小时。dhcp-option=3把网关地址推给客户端,必须写成LAN口地址192.168.10.1;dhcp-option=6推送DNS服务器地址。示例中使用了阿里DNS 223.5.5.5和腾讯DNS 119.29.29.29,也可以换成运营商DNS。
配置文件中的server=223.5.5.5表示Dnsmasq向上游DNS转发查询,cache-size设置缓存条目数量。缓存生效后,同一个域名第二次查询会直接从路由器返回,响应速度明显提升。
保存后执行sudo systemctl restart dnsmasq,并设置为开机自启:sudo systemctl enable dnsmasq。使用sudo systemctl status dnsmasq确认服务没有报错。如果启动失败,常见原因是配置行有多余空格或网卡名称错误,可以用sudo dnsmasq --test --conf-file=/etc/dnsmasq.conf检查语法。
四、防火墙策略与安全加固
路由器的防火墙策略直接决定内网是否安全。如果只配置了NAT和转发,而INPUT链默认允许,外网可能直接访问路由器本身的服务。建议将INPUT链默认策略改为DROP,同时放行本地回环、已建立的连接和内网管理端口。下面命令的顺序很重要:先放行SSH,再修改默认策略,避免把自己锁在门外。
sudo iptables -A INPUT -i lo -j ACCEPT sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT sudo iptables -A INPUT -i enp2s0 -p tcp --dport 22 -j ACCEPT sudo iptables -P INPUT DROP sudo iptables -P FORWARD DROP
这里只允许从内网网卡enp2s0访问22端口的SSH,WAN口上的SSH访问会被默认DROP。FORWARD链默认DROP后,之前添加的两条转发规则仍然有效,因为规则按顺序匹配。若还需要允许内网访问路由器的Web管理面板,可以按同样方式放行对应端口,但务必限制来源网卡为内网口。
为了进一步提高安全性,可以禁止外网ping路由器,允许内网ping:
sudo iptables -A INPUT -i enp2s0 -p icmp --icmp-type echo-request -j ACCEPT sudo iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
规则保存同样使用iptables-save。每次修改规则后都要重新保存,否则重启后配置会回到旧状态。保存命令可复用前面的iptables-save > /etc/iptables/rules.v4。
五、连通性测试与常见故障排查
配置完成后,找一台电脑接到LAN口,网络设置为自动获取IP。正常时电脑会拿到192.168.10.50到192.168.10.150之间的地址,网关和DNS都指向192.168.10.1。打开浏览器访问外网,或用命令ping 223.5.5.5测试IP连通性,再ping www.baidu.com测试DNS解析是否正常。
如果无法上网,建议按顺序检查。首先在路由器上执行ip addr和ip route,确认LAN口地址和默认路由存在。然后用sysctl net.ipv4.ip_forward确认转发是否为1。接着执行sudo iptables -t nat -L -n -v查看MASQUERADE规则是否命中计数。客户机已经拿到地址却无法ping通网关,通常是防火墙INPUT链拦截了内网流量,需要检查sudo iptables -L -n -v中的INPUT规则。
DHCP相关故障可以通过sudo systemctl status dnsmasq和journalctl -u dnsmasq -f查看实时日志。常见提示包括网卡没有配置IP、地址池与网卡所在网段不一致、端口被其他服务占用等。若客户端拿到169.254.x.x的自动专用地址,基本说明DHCP请求没有到达路由器,检查网线、VLAN和Dnsmasq监听网卡。
ip addr show enp2s0 ip route show sysctl net.ipv4.ip_forward sudo iptables -t nat -L -n -v sudo systemctl status dnsmasq journalctl -u dnsmasq -f
这些命令可以在路由器和客户端之间逐步缩小问题范围。只要IP转发、NAT、DHCP和DNS四部分都正常,Ubuntu软路由就能稳定运行。后续还可以在此基础上增加端口映射、流量限速、VLAN隔离或Suricata入侵检测,使这台软路由更接近企业级网关的角色。

