[转载]DIY你自己的 Arch Linux 软路由

Arch

大部分人玩软路由都采用ESXI这款虚拟机系统,准备好16G大内存,搞个黑群辉,然后挂个Lean大的OpenWrt-x86等等。 但是本人对虚拟机并无任何好感,主要是觉得浪费硬件资源,然后配置起来受到一些局限,因此就想到干脆直接装个Linux做路由器。 当然,是装最好用的发行版—Arch Linux.

提示

本文适合Arch Linux教徒阅读,其他发行版可以参考

安装Arch Linux到你的软路由

请参考 Arch Wiki/Installation_guide, 本文不再赘述。

配置网卡

p.s.安装完成后别忙退出chroot环境

配置udev规则,对网卡进行重命名

创建 /etc/udev/rules.d/10-network.rules, 内容大致如下:

1
2
3
4
5
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="00:11:22:33:44:55", NAME="net0"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="11:22:33:44:55:66", NAME="net1"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="22:33:44:55:66:77", NAME="net2"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="33:44:55:66:77:88", NAME="net3"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="44:55:66:77:88:99", NAME="wifi0"

其中ATTR{address}是网卡的mac地址,可以用命令ip a查看,NAME是重命名后的名字。

p.s.请勿使用ethX和wlanX这类的名字,因为内核命名网卡采用的是这些名字,这将导致命名网卡的时候出现竞争冒险

这里我们做个约定:net0作为路由器的WAN口连接外网,剩余的接口我们桥接成LAN口br0,下面马上会讲到。

配置netctl

配置WAN口

如果WAN侧使用的是DHCP自动获取ip,那么创建一个配置文件/etc/netctl/net0-dhcp-profile,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
Description='WAN Interface.'
Interface=net0
Connection=ethernet
IP='dhcp'
#DNS=('127.0.0.1')
#DHCPClient=dhcpcd
#DHCPReleaseOnStop=no
## for DHCPv6
#IP6=dhcp
#DHCP6Client=dhclient
## for IPv6 autoconfiguration
#IP6=stateless

根据需要可以设置DNS,ipv6等。

设置完后执行netctl enable net0-dhcp-profile来启用配置,如果配置文件发生了变化,需要执行netctl reenable net0-dhcp-profile来生效

如果WAN口采用PPPoE拨号上网的方式,pacman -S rp-pppoe来安装拨号插件rp-pppoe, 创建配置文件/etc/netctl/net0-pppoe-profile,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Description='WAN PPPoE connection'
Interface=net0
Connection=pppoe
User='user@server'
Password='your-password-here'

# Always keep a connection established
ConnectionMode='persist'
# Establish connection on demand
#ConnectionMode='demand'
#IdleTimeout=300

# Use default route provided by the peer (default: true)
#DefaultRoute=true
# Use DNS provided by the peer (default: true)
#UsePeerDNS=false

# Override default LCP parameters from /etc/ppp/options
#LCPEchoInterval=15
#LCPEchoFailure=10

# PPPoE options - experts only
#
# PPPoE service name
#PPPoEService=''
# PPPoE access concentrator name
#PPPoEAC=''
# Attach to existing session (sessid:macaddr)
#PPPoESession=''
# Only connect to specified MAC address
#PPPoEMAC=''
# Enable IPv6 support
#PPPoEIP6=yes

如果不想用运营商DNS,则取消注释UsePeerDNS=false一行,然后另需设置DNS(使用netctl的hooks),后面也会讲到。

p.s.配置好后也需要netctl enable,请注意,下面不再提醒。

配置LAN口

因为我的路由器一共有4个有线网卡,WAN口用掉了一个,现在还剩下3个,所以全部把他们桥接成br0作为LAN口。

创建配置文件/etc/netctl/br0-profile,内容如下

1
2
3
4
5
6
7
8
9
Description="LAN Bridge connection"
Interface=br0
Priority=2
Connection=bridge
BindsToInterfaces=(net1 net2 net3)
IP='static'
Address=('192.168.123.1/24')
## Ignore (R)STP and immediately activate the bridge
#SkipForwardingDelay=yes

这里我们吧net1 net2 net3桥接在一起形成br0这个新的接口,并指定了使用静态ip:192.168.123.1 掩码是24, 也就是说LAN侧这个网络的ip范围是 192.168.123.1-192.168.123.255

配置dnsmasq

安装dnsmasq:pacman -S dnsmasq, 启用dnsmasq: systemctl enable dnsmasq

修改/etc/dnsmasq.conf

1
2
3
4
5
6
7
8
no-poll
server=202.141.162.123#5353
interface=br0
expand-hosts
domain=ezpro.lan
dhcp-range=192.168.123.2,192.168.123.255,255.255.255.0,12h
dhcp-host=aa:bb:cc:dd:ee:ff,192.168.123.52
conf-dir=/etc/dnsmasq.d/,*.conf
  • no-poll禁止dnsmasq阅读/etc/resolv.conf作为上游DNS,(后面我们把/etc/resolv.conf设置为127.0.0.1即路由器本机的dns通过本机53号端口即dnsmasq来查询)
  • serverdnsmasq的上游dns,这里推荐使用中科大LUG的DNS,用非常规端口5353进行查询,防止运营商劫持
  • interface指向了我们的lan侧接口br0
  • expand-hosts是给dns记录里面添加/etc/hosts里面的记录
  • domain是给lan侧设备加上lan侧域名,比如局域网内有一台计算机的hostname叫computer1,那么他的域名就是computer1.ezpro.lan
  • dhcp-range指明了lan侧dhcp服务器发放的ip地址范围和有效期,这里是192.168.123.2-192.168.123.255,有效期是12小时
  • dhcp-host这里是指定给mac地址为aa:bb:cc:dd:ee:ff的设备分配一个指定的ip192.168.123.52
  • conf-dir 是设置额外配置文件所在的路径,后面archss有用

开启SSH

安装openssh:pacman -S openssh,启用sshd服务:systemctl enable sshd

由于sshd默认不允许root登录,后面我们要使用AUR安装一些软件,也是需要一个普通用户,所以请建一个普通用户,并设置好密码,因为sshd默认也不允许空密码登录。

至此你可以退出chroot环境,重启进入装好的arch linux,将你电脑与路由器LAN侧网线连接,电脑将自动获取到IP, 通过ssh登录到路由器上, 这时候你电脑还没有网络,但路由器有网,因为接下来我们要配置网络转发,实现路由功能

配置网络转发

开启内核转发功能

创建/etc/sysctl.d/30-ipforward.conf,内容如下:

1
2
3
net.ipv4.ip_forward = 1
net.ipv6.config.default.forwarding = 1
net.ipv6.config.all.forwarding = 1

重启生效

使用AUR(老Archer直接跳过)

添加archlinuxcn

安装aurman:pacman -S aurman

安装支持FULL-CONE-NAT的iptables

因为内核模块编译需要用到内核头文件,因此先安装linux-headers

然后直接从AUR安装iptables-fullcone-nat:aurman -S iptables-fullcone-nat

此项目来源自Chion82的netfilter-full-cone-nat

创建iptables规则

创建/etc/iptables/dhcp.rules,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o net0 -j FULLCONENAT
-A PREROUTING -i net0 -j FULLCONENAT
COMMIT


*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i br0 -o net0 -j ACCEPT
COMMIT

创建/etc/iptables/pppoe.rules,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o ppp0 -j FULLCONENAT
-A PREROUTING -i ppp0 -j FULLCONENAT
COMMIT

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i br0 -o ppp0 -j ACCEPT
COMMIT

*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A FORWARD -o ppp0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
COMMIT

创建net0的钩子

创建脚本/etc/netctl/interfaces/net0,赋予可执行权限,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/sh

if [ "$(netctl is-enabled net0-pppoe-profile)" = "enabled" ]; then
# Set Custom DNS
cat << EOF > /etc/resolv.conf
# generated by $0
nameserver 127.0.0.1
EOF

# Start iptables for pppoe
iptables-restore /etc/iptables/pppoe.rules

else
# Start dhcpiptables
iptables-restore /etc/iptables/dhcp.rules
fi

p.s.这里针对了PPPoE进行设置自定义DNS服务器为127.0.0.1(即本地DNS,由dnsmasq提供),对应net0-pppoe-profile的UsePeerDNS=false选项

然后netctl restart xxxx-profile重启一下WAN口,会自动执行脚本 /etc/netctl/interfaces/net0 完成相应的iptables转发设置。

至此,LAN侧设备已经能访问Internet了,基本路由功能已经实现

开启无线AP(可选)

推荐使用QCA9880这卡,本文以QCA9880为例,但是别买成V1版,要买Openwrt-x86兼容的V2,当然其他卡应该也行,不过值得注意的是Intel的网卡都不能开5G的AP

当然hostapd这种方式开出来的AP效果和网卡以及网卡驱动还是有很大关系的,你也可以选择另外单独买一个无线路由器连到LAN侧作AP使用

重新编译内核

开启以下选项以支持更多频道(以ath10k为例):

1
2
3
4
CONFIG_CFG80211_CERTIFICATION_ONUS=y
CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS=y
CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING=y
CONFIG_ATH10K_DFS_CERTIFIED=y

重新编译一个基于arch官方内核的自定义内核,推荐的方式是Arch Wiki/Kernels/Arch_Build_System 编译好后用pacman -U linux-xxx.pkg.tar.xz来安装你的自定义内核,并执行grub2-mkconfig -o /boot/grub/grub.cfg来更新引导菜单

配置hostapd

安装hostapd和crda:pacman -S hostapd crda

创建/etc/hostapd/hostapd.conf,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#### Interface configuration ####

interface=wifi0
bridge=br0
driver=nl80211

##### IEEE 802.11 related configuration #####

ssid=iCanHearYouHavingSex
hw_mode=a
channel=0
auth_algs=1
country_code=CN
ieee80211d=1
ieee80211h=1

##### IEEE 802.11n related configuration #####

ieee80211n=1
ht_capab=[HT40+][SMPS-STATIC][SHORT-GI-40][TX-STBC][RX-STBC1][DSSS_CK-40][LDPC][MAX-AMSDU-7935]

##### IEEE 802.11ac related configuration #####

ieee80211ac=1
vht_capab=[MAX-MPDU-11454][RXLDPC][SHORT-GI-80][TX-STBC-2BY1][RX-STBC-1][MAX-A-MPDU-LEN-EXP7][TX-ANTENNA-PATTERN][RX-ANTENNA-PATTERN][BF-ANTENNA-3][SOUNDING-DIMENSION-3]
vht_oper_chwidth=1


##### WPA/IEEE 802.11i configuration #####

wpa=2
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
wpa_passphrase=youCanGuess

### WMM
wmm_enabled=1
uapsd_advertisement_enabled=1
wmm_ac_bk_cwmin=4
wmm_ac_bk_cwmax=10
wmm_ac_bk_aifs=7
wmm_ac_bk_txop_limit=0
wmm_ac_bk_acm=0
wmm_ac_be_aifs=3
wmm_ac_be_cwmin=4
wmm_ac_be_cwmax=10
wmm_ac_be_txop_limit=0
wmm_ac_be_acm=0
wmm_ac_vi_aifs=2
wmm_ac_vi_cwmin=3
wmm_ac_vi_cwmax=4
wmm_ac_vi_txop_limit=94
wmm_ac_vi_acm=0
wmm_ac_vo_aifs=2
wmm_ac_vo_cwmin=2
wmm_ac_vo_cwmax=3
wmm_ac_vo_txop_limit=47
wmm_ac_vo_acm=0

### TX queue parameters
tx_queue_data3_aifs=7
tx_queue_data3_cwmin=15
tx_queue_data3_cwmax=1023
tx_queue_data3_burst=0
tx_queue_data2_aifs=3
tx_queue_data2_cwmin=15
tx_queue_data2_cwmax=63
tx_queue_data2_burst=0
tx_queue_data1_aifs=1
tx_queue_data1_cwmin=7
tx_queue_data1_cwmax=15
tx_queue_data1_burst=3.0
tx_queue_data0_aifs=1
tx_queue_data0_cwmin=3
tx_queue_data0_cwmax=7
tx_queue_data0_burst=1.5
  • ssid为wifi名称
  • wpa_passphrase 为wifi密码

启用hostapd:systemctl enable hostapd,启动hostapd:systemctl start hostapd

p.s.其他网卡请务必留意ht_capab、vht_capab,请通过iw list查看网卡支持的工作模式,填写支持的模式,否则无法启动,所有的选项可以通过hostapd官方完整配置文件/usr/share/doc/hostapd/hostapd.conf进行查看

额外功能

  • samba文件服务器参考Arch Wiki/samba
  • archss透明代理,Arch-Router-SS
  • 其他路由设置,参考Arch Wiki/router p.s.如果使用iptables-fullcone-nat将不再需要UPnP
  • 其他额外功能,还是参考Arch Wiki

总结

比起虚拟机开那么多吃爆内存来说,Arch Router只占用了不到270Mb内存,处理器也工作在十分空闲的状态,而且Linux本身就能搭建各种服务器,总的来说可玩性要比虚拟机更高,而且折腾了这一路,也弄清楚了路由器工作的原理,学到很多东西。 还是那句话:

当你成功安装Arch Linux的那一刻,你就已经成为教徒。

本文转自Edward-P’s BlogDIY你自己的 Arch Linux 软路由

支持我就领个支付宝红包吧~