NetworkManager Hostapd Dnsmasq 单臂路由
动机¶
手上有一个设备只有一个网口,但我又不想用USB网卡占据宝贵的接口。配合交换机还能依靠交换机走内网流量、接入多个设备。
说那么多其实某种意义上就是想折腾XD。
流程¶
大概分为交换机配置和路由器(设备)配置吧。
- 交换机
- 划分VLAN
- 路由器
- 装系统
- 配置VLAN
- 配置DHCP服务和DNS
- 配置无线网
交换机配置VLAN¶
路由器直连的口设置为 Trunk,另外划一个口到另一个VLAN(用作WAN)。除了路由器的网口,其余均设置为 Untagged。
# example
# T: Tagged/Trunk
# U: Untagged
# X: disabled
# Port 1: router
# Port 2: WAN
# Port 3-5: LAN
Port 1 2 3 4 5
VLAN1 T X U U U
VLAN2 T U X X X
单臂路由拨号上网¶
你应该有个交换机,这样可以配置 802.11Q 标准的VLAN。这里将VLAN1设置为内网,VLAN2设置为WAN,务必和交换机配置一致。 下面给出的例子是用 NetworkManager 划分VLAN并拨号上网的示例。
# vlan & pppoe, router-on-a-stick model, change ifname accordingly
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'
PPPoE路由自动设置脚本¶
因为一些我之前没搞清楚的原因,PPPoE拨号上网后需要配置路由才能正常上网,然而 NetworkManager 没有自动处理(或者说处理得不好)。
因而我写了一个自动在PPPoE连接成功后添加对应路由的 dispatcher
(相当于NetworkManager的钩子/hook脚本)。
不过现在好像没有这个问题了?
#!/usr/bin/env bash
# /etc/NetworkManager/dispatcher.d/30-auto-route-for-pppoe.sh
interface=$1
event=$2
target_interfaces=("pppoe0")
for target in ${target_interfaces[@]} ; do
if [[ $interface == $target ]] ; then
case "$event" in
up)
# startup
ip route delete default dev $interface
ip route delete default dev $DEVICE_IP_IFACE
ip route add default via $IP4_GATEWAY dev $DEVICE_IP_IFACE proto static metric 99
sysctl -p net.ipv4.conf.$DEVICE_IP_IFACE.forwarding=1
;;
down)
ip route delete default dev $interface
ip route delete default dev $DEVICE_IP_IFACE
;;
*)
printf 'Unexpected event(%s) for interface(%s) !\n' $event $interface
;;
esac
fi
done
# vim:sw=4:ts=4:et:
配置dnsmasq¶
因为某些原因 1 2 ,需要用 systemctl edit dnsmasq
添加下面的配置以保证 NetworkManager 先完全启动。
[Unit]
After=NetworkManager-wait-online.service
Warning
如果有装 systemd-resolved
,请务必禁用!
配置hostapd¶
贴一下我的部分配置
interface=wlp2s0
bridge=br0
driver=nl80211
ssid=AP-NAME
hw_mode=g
channel=3
wpa=2
wpa_passphrase=1234567890
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
rsn_pairwise=CCMP
在 NetworkManager 配置中忽略 Hostapd 要用到的端口以免产生干扰。
# /etc/NetworkManager/conf.d/unmanaged.conf
[keyfile]
unmanaged-devices=interface-name:wlp2s0
调整启动顺序¶
严格顺序:NM->{Dnsmasq,Hostapd}
systemctl edit dnsmasq
添加以下内容
[Unit]
After=NetworkManager-wait-online.service
用networkmanager的dispatcher启动hostapd,否则hostapd会启动太早占用br0
#!/usr/bin/env bash
# auto trigger script for starting hostapd and dnsmasq
interface=$1
event=$2
target_interfaces=("br0")
for target in ${target_interfaces[@]} ; do
if [[ $interface == $target ]] ; then
case "$event" in
up)
# startup
systemctl start hostapd
systemctl start dnsmasq
;;
down)
systemctl stop hostapd
systemctl stop dnsmasq
;;
*)
printf 'Unexpected event(%s) for interface(%s) !\n' $event $interface
;;
esac
fi
done
# vim:sw=4:ts=4:et:
Note
如果还存在奇怪的问题, 则禁用dnsmasq和hostapd服务的自动启动, 改用dispatcher脚本去启动
配置iptable¶
开放端口,让DHCP(67/68)、SSH(22)、http(80/443)、DNS(53)可达
- TCP:22,53,80,443
- UDP:53,67,68
别的可以参考 Simple Stateful Firewall, 但是别完全照抄!
其它调整¶
启用bbr拥塞控制算法¶
编辑 /etc/sysctl.conf
并添加如下内容:
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
以管理员权限执行 sysctl -p
重载配置中的信息。