配置静态 IP 和默认路由
软路由需要配置一个静态 IP 和一个默认路由,Ubuntu 可以使用 netplan 来配置,配置文件路径是 /etc/netplan/config.yaml
,通过 netplan apply
执行生效。下面根据不同方案给出一些配置示例。
主路由方案配置
对于主路由方案,需要选一个网口用来连接光猫来拨号上网,再选一个网口配置内网静态 IP 并连接交换机,用于内网通信和路由转发,下面是我用过的配置:
代码语言:yaml复制network:
version: 2
renderer: networkd
ethernets:
enp1s0: # 拨号网口
optional: true
accept-ra: false
dhcp4: no
dhcp6: no
addresses:
- 192.168.11.1/24
routes: # k3s 需要默认路由,不然会报错,导致 dhcp 服务起不来,从而导致局域网连不上,这里随便设置一个(启动会被pppoe拨号覆盖,这里设置用于没有拨号的情况下也连上机器)
- to: default
via: 192.168.11.1
enp2s0:
optional: true
accept-ra: false
dhcp4: no
dhcp6: no
addresses: # 固定网卡所拥有的内网IP地址段
- 10.10.10.2/24
- fddd:dddd:dddd:dddd::2/64
enp6s0: # 预留的管理网口,极端情况下用网线连管理网口登录 ssh
optional: true
accept-ra: false
dhcp4: no
dhcp6: no
addresses:
- 10.10.11.1/24
解释一下:
- 我的路由器有 6 个网口,Ubuntu 默认使用
enp*s0
的命名方式自动给网口分配网卡名称。 - 第一个网口我用来拨号上网,上联是光猫(光猫设置桥接,不要光猫的路由功能)。设置用第一个网口来做 PPPoE 拨号的话,会自动修改默认路由走虚拟出来的
ppp0
网卡,这里配置的默认路由不重要。 - 第二个网口设置一个内网静态 IP,用于内网通信。内网网段我计划用
10.10.10.0/24
,软路由静态 IP 使用10.10.10.2
,如果要用 IPv6,也得分配个固定的内网 IPv6 地址,写到addresses
里。 - 使用静态 IP,禁用掉 dhcp 动态获取 IP 的能力,所以每个网口的
dhcp4
和dhcp6
均设为 false。
旁路由方案配置
对于旁路由方案,不需要拨号,主要选一个网口来配置内网静态 IP 就行,这个网口连上交换机,配置示例:
代码语言:yaml复制network:
version: 2
renderer: networkd
ethernets:
enp1s0: # 主网口,默认路由指向主路由 IP
optional: true
accept-ra: false
dhcp4: no
dhcp6: no
addresses:
- 10.10.10.2/24
- fddd:dddd:dddd:dddd::2/64
routes:
- to: default
via: 10.10.10.14
enp6s0: # 预留的管理网口,极端情况下用网线连管理网口登录 ssh
optional: true
accept-ra: false
dhcp4: no
dhcp6: no
addresses:
- 10.10.11.1/24
桥接
如果需要,其它剩余网口设置桥接,当做交换机用,方面接入更多设备。可以在 netplan 配置里加下 bridges
配置:
bridges:
br0:
dhcp4: no
interfaces:
- enp3s0
- enp4s0
- enp5s0
配置拨号上网
旁路由方案的拨号上网这里不做介绍,不同场景配置方法各不相同,比如主路由是华为、小米路由器设备,需登录路由器管理页面进行配置;如果是让光猫来拨号,需登录光猫进行配置;如果使用双软路由方案,比如在 EXSI 里虚拟出 RouterOS 作为主路由,那么就登陆 RouterOS 主路由页面进行配置拨号上网。
这里只给出主路由方案的 Ubuntu 系统配置 PPPoE 拨号的方法。
首先是先有鸡还是先有蛋问题,在配置 PPPoE 拨号之前,我们需安装 pppoeconf
并使用它配置 PPPoE,但没有拨号的情况下又无法联网,安装不了。这时,确保你的 Ubuntu 还不是主路由,可以先用普通路由器配置拨号上网,在 netplan 配置中主网口处设置默认路由,即 routes
下的 via
填当前实际拨号上网的路由器 IP
地址,然后执行 netplan apply
让配置生效,测试没问题后再安装 pppoeconf
并用它配置 PPPoE:
# 安装 pppoeconf
sudo apt install -y pppoeconf
# 配置
sudo pppoeconf
根据提示配置好 PPPoE 拨号后,还需要实现 Ubuntu 开机自动执行 PPPoE 拨号,可以用 networkd-dispatcher
来实现:
#!/bin/env sh
# interface to pppoe workload
INTERFACE=enp1s0
if [ "${IFACE}" = "${INTERFACE}" ] ; then
echo "running pon ${INTERFACE}..."
pon dsl-provider
fi
如果不生效,可以在 /etc/rc.local
开机脚本里做(目前本人就是这么做的):
#!/bin/bash
echo "run pppoe"
pon dsl-provider
确保 rc-local 服务处于 enabled 状态:
systemctl enable rc-local
另外,路由器上网需要配置 IP MASQUERADE,即确保让出公网的报文的源 IP 自动 SNAT 成本机公网 IP,这样才能正常收到回包,我是通过 nftables 配置的,以下是 nftables 配置文件:
代码语言:txt复制#!/sbin/nft -f
table inet ppp
delete table inet ppp
table inet ppp {
chain postrouting {
type nat hook postrouting priority 100; policy accept;
oifname != "ppp0" return
meta l4proto { tcp, udp } ip saddr 10.10.0.0/16 counter masquerade
meta l4proto { tcp, udp } ip6 saddr fddd:dddd:dddd:dddd::/64 counter masquerade
}
}
配置混杂模式
对于软路由,配置网卡为混杂模式很重要,因为作为路由器,需要监听所有流量,这样才能做路由转发。可以在 /etc/network/if-up.d/
目录下配置脚本,实现开机自动为所有网卡打开混杂模式(set-promisc
):
#!/bin/bash
for i in {1..6}
do
/sbin/ip link set enp${i}s0 promisc on
done
/sbin/ip link set br_lan promisc on
配置防火墙
对于主路由方案,在 Ubuntu 里配置防火墙,可以用 nftables 来声明式配置:
代码语言:txt复制#!/sbin/nft -f
table inet firewall
delete table inet firewall
table inet firewall {
chain prerouting {
type filter hook prerouting priority mangle; policy drop;
iifname != ppp0 accept comment "only care about ppp0"
ip saddr 192.168.43.0/24 counter accept
udp dport > 32767 counter accept
# Permit established and related connections
ct state established,related
accept
comment "Permit established/related connections"
# Permit inbound IKEv2 traffic
udp dport { 500, 4500 }
counter
accept
comment "Permit inbound IKEv2 traffic"
# Permit inbound k3s traffic
tcp dport { 6443 }
counter
accept
comment "Permit inbound k3s traffic"
# Permit inbound traceroute UDP ports but limit to 500 PPS
udp dport 33434-33524
limit rate 500/second
counter
accept
comment "Permit inbound UDP traceroute limited to 500 PPS"
# Permit inbound SSH
tcp dport { 22, 2456, 24567 }
counter
accept
comment "Permit inbound SSH connections"
# Permit aria2 listen port
meta l4proto { tcp, udp }
th dport 16881
counter
accept
comment "Permit aria2 listen port"
# Log and drop new TCP non-SYN packets
tcp flags != syn ct state new
limit rate 100/minute burst 150 packets
log prefix "IN - New !SYN: "
comment "Rate limit logging for new connections that do not have the SYN TCP flag set"
tcp flags != syn ct state new
counter
drop
comment "Drop new connections that do not have the SYN TCP flag set"
# Log and drop TCP packets with invalid fin/syn flag set
tcp flags & (fin|syn) == (fin|syn)
limit rate 100/minute burst 150 packets
log prefix "IN - TCP FIN|SIN: "
comment "Rate limit logging for TCP packets with invalid fin/syn flag set"
tcp flags & (fin|syn) == (fin|syn)
counter
drop
comment "Drop TCP packets with invalid fin/syn flag set"
# Log and drop TCP packets with invalid syn/rst flag set
tcp flags & (syn|rst) == (syn|rst)
limit rate 100/minute burst 150 packets
log prefix "IN - TCP SYN|RST: "
comment "Rate limit logging for TCP packets with invalid syn/rst flag set"
tcp flags & (syn|rst) == (syn|rst)
counter
drop
comment "Drop TCP packets with invalid syn/rst flag set"
# Log and drop invalid TCP flags
tcp flags & (fin|syn|rst|psh|ack|urg) < (fin)
limit rate 100/minute burst 150 packets
log prefix "IN - FIN:"
comment "Rate limit logging for invalid TCP flags (fin|syn|rst|psh|ack|urg) < (fin)"
tcp flags & (fin|syn|rst|psh|ack|urg) < (fin)
counter
drop
comment "Drop TCP packets with flags (fin|syn|rst|psh|ack|urg) < (fin)"
# Log and drop invalid TCP flags
tcp flags & (fin|syn|rst|psh|ack|urg) == (fin|psh|urg)
limit rate 100/minute burst 150 packets
log prefix "IN - FIN|PSH|URG:"
comment "Rate limit logging for invalid TCP flags (fin|syn|rst|psh|ack|urg) == (fin|psh|urg)"
tcp flags & (fin|syn|rst|psh|ack|urg) == (fin|psh|urg)
counter
drop
comment "Drop TCP packets with flags (fin|syn|rst|psh|ack|urg) == (fin|psh|urg)"
# Drop traffic with invalid connection state
ct state invalid
limit rate 100/minute burst 150 packets
log flags all prefix "IN - Invalid: "
comment "Rate limit logging for traffic with invalid connection state"
ct state invalid
counter
drop
comment "Drop traffic with invalid connection state"
# Permit IPv4 ping/ping responses but rate limit to 2000 PPS
ip protocol icmp icmp type { echo-reply, echo-request }
limit rate 2000/second
counter
accept
comment "Permit inbound IPv4 echo (ping) limited to 2000 PPS"
# Permit all other inbound IPv4 ICMP
ip protocol icmp
counter
accept
comment "Permit all other IPv4 ICMP"
# Permit IPv6 ping/ping responses but rate limit to 2000 PPS
icmpv6 type { echo-reply, echo-request }
limit rate 2000/second
counter
accept
comment "Permit inbound IPv6 echo (ping) limited to 2000 PPS"
## Permit all other inbound IPv6 ICMP
meta l4proto { icmpv6 }
counter
accept
comment "Permit all other IPv6 ICMP"
# Log any unmatched traffic but rate limit logging to a maximum of 60 messages/minute
# The default policy will be applied to unmatched traffic
limit rate 60/minute burst 100 packets
log prefix "IN - Drop: "
comment "Log any unmatched traffic"
# Count the unmatched traffic
counter
comment "Count any unmatched traffic"
}
}
确保 nftables 服务处于 enabled 状态:
systemctl enable nftables
配置内核参数
增加配置 /etc/sysctl.d/10-router.conf
:
# 作为路由器,启用 ip 转发 (ipv6默认关闭)
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.forwarding=1
# 接收来自运营商(ISP) 的 ipv6 RA (路由通告),以获取公网 ipv6 地址
#net.ipv6.conf.all.accept_ra=2
#net.ipv6.conf.enp1s0.accept_ra=2
#net.ipv6.conf.default.accept_ra=2
#net.ipv6.conf.all.accept_ra_rt_info_max_plen=128
#net.ipv6.conf.default.accept_ra_rt_info_max_plen=128
#net.ipv6.conf.enp1s0.accept_ra_rt_info_max_plen=128
# 禁用ipv6
net.ipv6.conf.all.accept_ra=0
net.ipv6.conf.enp1s0.accept_ra=0
net.ipv6.conf.default.accept_ra=0
net.ipv6.conf.all.accept_ra_rt_info_max_plen=0
net.ipv6.conf.default.accept_ra_rt_info_max_plen=0
net.ipv6.conf.enp1s0.accept_ra_rt_info_max_plen=0
# 可选。暂时没发现什么场景一定要禁用 rp_filter,以防万一,先禁用
net.ipv4.conf.all.rp_filter=0
net.ipv4.conf.default.rp_filter=0
# 允许容器ns的流量被拦截
net.bridge.bridge-nf-call-iptables=0
net.bridge.bridge-nf-call-ip6tables=0
删除自带的一些内核参数配置,避免冲突:
rm /etc/sysctl.d/10-network-security.conf