使用 Linux 当网关

本文使用 Systemd-networkd 进行网络管理,使用 Systemd-resolved 充当 DNS 服务器。

1、重命名

为了让每一个网卡都能有固定的名字,方便配置网络,网卡需要根据MAC地址来进行重命名。

例如:

1
2
3
4
[Match]
MACAddress=fa:8e:c5:01:41:01
[Link]
Name=eth0

文件需要保存为 10-eth0.link,这样就能让 networkd 读取到配置。其它接口也需要做类似的配置。

2、网桥

假设我们有 eth0eth1eth2 三个网口,我们把第一个网口拿来当 WAN 口,剩下两个用来当 LAN 口,那我们可以把后面两个网口用网桥组合起来。

1
2
3
4
5
[Match]
Name=eth1

[Network]
Bridge=bridge0
1
2
3
4
5
[Match]
Name=eth2

[Network]
Bridge=bridge0

文件可以保存到 15-xxx.network 等名称中。

然后我们创建一个网桥:

1
2
3
4
5
[NetDev]
Name=bridge0
Kind=bridge
Description=LAN Interface
MACAddress=3A:12:09:A1:B3:10

文件保存到 20-bridge0.netdev

配置网桥:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[Match]
Name=bridge0

[Network]
Address=192.168.12.1/24
DHCPServer=true
DHCP=ipv6
IPMasquerade=ipv4
IPForward=yes
IPv6AcceptRA=yes
IPv6SendRA=yes
DHCPv6PrefixDelegation=yes

[DHCPServer]
EmitDNS=yes

[IPv6PrefixDelegation]
EmitDNS=yes

[Address]
ManageTemporaryAddress=true

文件保存到 20-bridge0.network

如果需要 PPPoE 拨号,那么需要提前安装 PPPoE 的相关包,比如 Debian 下需要安装 pppoeconf

防火墙规则

WAN 口需要默认禁止传入,否则内网的东西可能会泄露。编辑 /etc/nftables.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
#!/usr/sbin/nft -f

flush ruleset

table inet route {
chain wan_zone_input {
type filter hook input priority 0; policy accept;
ip protocol icmp accept
tcp dport ssh accept
udp dport dhcpv6-client accept
udp dport dhcpv6-server accept
ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, mld-listener-query, mld-listener-report, mld-listener-reduction, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, ind-neighbor-solicit, ind-neighbor-advert, mld2-listener-report } accept
ip6 saddr fe80::/10 ip6 daddr fe80::/10 ct state new udp sport 547 udp dport 546 counter accept
iif lo accept
iifname ppp0 jump wan_zone_rules
iifname eth0 jump wan_zone_rules
}
chain wan_zone_rules {
ct state {established,related} accept
tcp dport ssh accept
ct state invalid drop
reject
}
}

启动服务:

1
sudo systemctl enable nftables --now