Arch as a Router

 · 3 分钟
Last updated: 2022-06-19

安装系统

  • 在编写本文时,我使用的是 ArchLinux ARM1,安装在树莓派4B上,没有额外配置;
  • 可以先读读 Arch Wiki 2
  • 注意别把硬件串口关了,虽然开着影响性能,但关掉就无法用 U-Boot 启动了(ArchLinuxARM 用的是U-Boot);

安装软件

  • dnsmasq(dns,dhcp)
  • smartdns(enhanced dns)
  • networkmanager(net)
  • wpa_supplicant(wifi)
  • rp-pppoe(pppoe)
  • dhcp-helper(dhcp relay)
  • avahi(zeroconf)
  • parprouted(proxy arp)
  • dhcp-helper(dhcp relay)

配置与硬件说明

注意,树莓派无线网卡设备没有办法用真正的二层网桥,只能在网络层(layer 3)入手,proxy arp。

注意,从2019年开始的 Intel 无线网卡内置 LAR(Location Aware Regulatory) 技术,并且在 Linux 5.4 之后 Intel 把自己网卡驱动的 lar_disable 开关去掉了,让 Intel 设备无法主动开启 5G 热点!所以诸如 AX200/210 的网卡并不适合用于设置热点!19

interface/接口/界面 设置

单臂路由配置,参考了一些他人记录 3 4。这里需要划分VLAN并配合交换机以复用仅有的以太网口。部分配置参数可以参考 Network Manager 的说明文档 5 6 7

# vlan & pppoe, router-on-a-stick model
nmcli con add type bridge ifname br0 con-name LAN stp no autoconnect yes
nmcli con add type vlan ifname vlan1 con-name vlan-internal id 1 dev eth0 master br0
nmcli con add type vlan ifname vlan2 con-name vlan-external id 2 dev eth0
nmcli con add type pppoe ifname pppoe0 con-name WAN autoconnect yes pppoe.parent vlan2 username 'nicename' password 'veryhardpassword1234'

# wpa2 hotspot
nmcli con add type wifi ifname wlan0 con-name wifi autoconnect yes ssid Hostspot
nmcli con modify wifi wifi.mode ap wifi.band a wifi.channel 48
nmcli con modify wifi wifi-sec.key-mgmt wpa-psk wifi-sec.proto rsn wifi-sec.psk "veryveryhardpassword1234"
nmcli con modify wifi wifi-sec.group ccmp wifi-sec.pairwise ccmp
nmcli con modify wifi ipv6.method ignore

# or wpa3(sae) hostspot
nmcli con add type wifi ifname wlan0 con-name wifi autoconnect yes ssid Hostspot
nmcli con modify wifi wifi.mode ap wifi.band a wifi.channel 48
nmcli con modify wifi wifi-sec.key-mgmt sae wifi-sec.proto rsn wifi-sec.psk "veryveryhardpassword1234"
nmcli con modify wifi wifi-sec.group ccmp wifi-sec.pairwise ccmp
nmcli con modify wifi ipv6.method ignore

note:如果开启不了5G频段的AP,可能需要装 crda/wireless-regdb 后设置country code。
如果还不行,看看是不是被no-IR(禁止主动发射)了。

另外我建议用hostapd开热点。

所以 Intel 网卡和驱动差评!想开热点的不要用 Intel 网卡!尤其是2019年后推出的!

开启内网出口转发

参考部分网上文档 8

iptables -t nat -A POSTROUTING -o pppoe0 -j MASQUERADE #forward LAN requests to pppoe0

后面我其实把这些都改了,参考 Arch Wiki。

打通WiFi, 建立ARP Proxy

这里有一些小问题, 先简单记录下步骤

  • 安装parprouted(很旧,但能用,但我后面不确定它是否有用)
  • 配置iptables(参考ArchWiki)
  • 把systemd-resolved配置文件中DNSStub
  • 配置dnsmasq, resolvconf, 以具备基本的联网能力

注: wlan和eth可以使用不同网段

用dnsmasq作DHCP与DNS服务

这里接触了一个看服务输出的好命令journalctl -b0 u <service name>

但是要注意, 看报错必须翻到最底下

参考ArchWiki, 解决了大部分问题

有一个是试出来的: dnsmasq中 dhcp-range 配置的前面可以加条件字段,感觉几乎没有文档写清楚了。如下例: dhcp-range=br0,192.168.76.50,192.168.76.150,12h

但是有一个问题: 这回在dnsmasq开机启动时不能与networkmanager稳定配合, 需要在systemd脚本里改 After=NetworkManager-wait-online.service, 是一个bug 16 17

本地域名自动解析

配合dnsmasq写了一个脚本, dnsmasq负责读取hosts解析本地域名, 而dnsmasq在触发DHCP分配变化时会执行脚本, 脚本的作用就是根据dhcp更新信息刷新hosts

解决其它问题

  • 其它接口的路由破坏了理想的路由表, 需要配置一下NetworkManager的trigger, 写一下自动路由配置脚本 12 18
  • dnsmasq需要配置dhcp-option告诉客户端DNS服务器是多少, 不然客户端可能就没有DNS用, 进而网络假死;
  • 有时iptables配置对了, 但DNS通信还是会被拦截, 我最后的解决方案是在iptables里加入对应接口流量放行的规则;