我最近想将我的 Ubuntu 20.04 配置为路由器。当我以为我完成了所有步骤时,出现了一个奇怪的问题,即连接到 Ubuntu 路由器的客户端无法访问互联网,而 Ubuntu 路由器本身可以访问互联网。
在放置配置之前,我将放一张路由器如何与其他设备关联的图片:
First Level Router >----<[WAN] Ubuntu Router(Dynamic IP) [LAN]>----< Client (DHCP)
按照指南,我在 Ubuntu 路由器上进行了以下配置。/etc/netplan/00-installer-config.yaml:
network:
ethernets:
wan1:
match:
macaddress: xx:xx:xx:xx:xx:01
set-name: wan1
dhcp4: yes
eth1:
match:
macaddress: xx:xx:xx:xx:xx:02
set-name: eth1
dhcp4: no
bridges:
br:
interfaces:
- eth1
addresses:
- 192.168.3.1/24
ifconfig 输出如下:
br: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 192.168.3.1 netmask 255.255.255.0 broadcast 192.168.3.255
inet6 fe80::f0de:2aff:fe06:98ad prefixlen 64 scopeid 0x20<link>
ether a4:1a:3a:b6:08:b5 txqueuelen 1000 (Ethernet)
RX packets 7283 bytes 456695 (456.6 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 295 bytes 36494 (36.4 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth1: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
ether a4:1a:3a:b6:08:b5 txqueuelen 1000 (Ethernet)
RX packets 7283 bytes 558657 (558.6 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 287 bytes 35750 (35.7 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 7941154 bytes 604164948 (604.1 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 7941154 bytes 604164948 (604.1 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
wan1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.4 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 fe80::da50:e6ff:fe3f:fdcb prefixlen 64 scopeid 0x20<link>
inet6 2409:8a50:1873:70b3:da50:e6ff:fe3f:fdcb prefixlen 64 scopeid 0x0 <global>
ether d8:50:e6:3f:fd:cb txqueuelen 1000 (Ethernet)
RX packets 39031 bytes 3017742 (3.0 MB)
RX errors 0 dropped 2229 overruns 0 frame 0
TX packets 35636 bytes 36600911 (36.6 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
另外,我通过在 /etc/sysctl.conf 中添加此行来启用 ipv4 转发:
net.ipv4.ip forward=1
Iptables 的设置如下行,并通过 systemd 在启动时运行 iptables-restore 来维护:
sudo iptables -t nat -A POSTROUTING -o wan1 -j MASQUERADE
我安装了 dnsmasq,并将 /etc/dnsmasq.conf 编辑为以下内容:(systemd-resolved 已停止并禁用)
listen-address=127.0.0.1,192.168.3.1
port=53
interface=eth1
dhcp-range=192.168.3.100,192.168.3.199,255.255.255.0,24h
dhcp-option=option:router,192.168.3.1
dhcp-option=option:dns-server,192.168.3.1
配置完成后,它似乎可以正常工作。我可以确认 DHCP 正在工作,因为我可以看到 dnsmasq 的日志,并且 Ubuntu 路由器本身可以访问互联网。
但有些不对劲。从客户端设备,我尝试 ping 一个域。该域已解析为正确的 IPV4 地址,但客户端无法访问它。然后我从客户端 ping 到路由器,反之亦然,两者都成功了。我遵循的指南从未提到过这一点。如果您知道它为什么不起作用,请告诉我,提前谢谢!
答案1
尝试添加此规则:
iptables -A FORWARD --in-interface br -j ACCEPT
并最终替换
sudo iptables -t nat -A POSTROUTING -o wan1 -j MASQUERADE
为
sudo iptables -t nat -A POSTROUTING -s 192.168.3.0/24 -o wan1 -j MASQUERADE
Wireshark(或 tshark、tcpdump)可同时用于对两个接口进行诊断。
扩展分析
路由器不工作的原因可能有很多:
- 未启用 IP 转发
- LAN 主机无法访问 DNS 服务器
- NAT(网络地址转换)设置对 LAN 主机不起作用
- ...
重新启动您的电脑以使所有服务恢复正常状态。
不要使用名称,而要使用数字 IP 地址进行 ping 测试,直到您确认下面列出的所有其他测试都正常为止。通过这种方式,您可以消除可能同时发生的 DNS 问题。
测试 1
检查IP路由(转发)状态(结果1表示转发已启用):
cat /proc/sys/net/ipv4/ip_forward
测试 2
检查 LAN 接口的正确 NAT(伪装)设置:
ping -c 3 8.8.8.8
ping -c 3 -I 192.168.3.1 8.8.8.8
上面的第一个命令是目标 IP 地址的可访问性测试。您必须获得 3 个有效的 ping 响应。第二个命令测试 NAT 是否适用于您的 LAN IP 地址。如果您没有收到响应,则意味着伪装无法转换您的源地址 192.168.3.1。并且 LAN 中的其他地址(192.168.3.0/24)也存在同样的问题。请仔细验证 iptables 设置的 NAT 部分。如果 NAT 设置看起来不错,但没有收到 ping 响应,请继续下一个测试。
如果 ping 响应正常,但 LAN 中的其他网络节点仍然无法 ping 通 8.8.8.8,则可能的解决方案是指定完整的网络地址(而不仅仅是自己的br
接口地址 192.168.3.1)作为 NAT 的源:
sudo iptables -t nat -A POSTROUTING -s 192.168.3.0/24 -o wan1 -j MASQUERADE
测试 3
传出的 WAN 数据包及其 IP 地址:
验证tcpdump
是否已安装,如果不存在则安装。
which tcpdump
sudo apt-get install tcpdump
所述过程将指导您检查 tcpdump 功能和网络数据捕获。您可以在运行 tcpdump 实例窗口中按 Ctrl+C 来停止捕获过程。打开第二个终端窗口 (T2)。第一个 (T1) 将用于流量生成和响应检查。您将使用第二个终端 (T2) 使用 tcpdump 启动和停止捕获任务。可以只使用一个终端执行两个任务,但如果您不熟悉前台和后台任务切换,使用两个终端更安全。
T2
sudo tcpdump -i wan1 -n icmp and host 8.8.8.8
T1
ping -c 2 8.8.8.8
您将看到两个 ICMP 传出数据包(回显请求)和两个传入回显响应。查看它们的源和目标 IP 地址。传出数据包的目标 IP 为 8.8.8.8,源是您的公共 WAN IP 地址。您将在下一步中将它们与显示的地址进行比较。
在 T2 终端中按 Enter 键可在运行的输出中创建新的行空间tcpdump
。它可以帮助您在窗口中分离旧的和新的捕获数据。
T1
ping -c 2 -I 192.198.3.1 8.8.8.8
你看到了什么?有以下可能性:
- 没有捕获任何数据包
- 仅显示传出的数据包,并且它们具有错误的源 IP 地址(例如 192.168.3.1,而不是 WAN 接口的公共 IP 地址。)
- 传出的和传入的数据包都是可见的。
在 T2 窗口中打破tcpdump
(Ctrl+C)。请复制 T2 的响应并将其粘贴到此处的答案中。添加响应ip route
并最终添加以下命令:
ip neigh
sudo iptables-save
描述其他测试的结果。