MorFans Dev
折腾 - 开发 - 分享

使用 GNU/Linux 搭建多出口软路由

使用 GNU/Linux 搭建多出口软路由

简介

这篇文章记录了使用 GNU/Linux 操作系统,在不更改二层网络配置的前提下,扩展实验室网络环境,并在一定程度上改善网络使用体验的方法。

背景

假设学校网络与信息中心给我们分配了一个校园网 VLAN,对应的校园网 IPv4 地址段为 172.16.0.0/26。按照常规用法,我们需要手动给网络下的每一台设备配置位于 172.16.0.1 ~ 172.16.0.61 之间的 IPv4 地址,并将 172.16.0.62 设为默认网关。连接到这个网络下的设备包括但不限于:若干台业务服务器、实验室成员的有线上网设备、通过实验室 Wi-Fi 无线上网的设备。按照这样的方法使用,有以下问题。

  • 网络内没有 DHCP 服务器,手动分配、管理和配置每台设备的 IP 地址较为不便。
  • 这些校园网 IP 地址在全校范围内可路由,相当于设备会直接暴露在整个校园网中,对开放了 SSH、Windows 远程桌面等远程访问的设备存在安全威胁。
  • 手机、平板等普通上网需求设备一般没有必要取得校园网 IP 地址,给他们分配校园网 IP 地址存在资源浪费和管理困难问题。
  • 实验室 Wi-Fi 由一台家用路由器提供,它工作在路由模式,只享有 1 个校园网 IP 地址,其下属的所有设备共享这一个 IP 的校园网出口带宽。

设计

针对上面提到的问题,我想到了以下解决方案。

  • 在同一个二层网络内,规划 192.168.0.0/24 为我们的私有 IP 地址段,用于满足普通联网需求,通过 NAT 访问校园网和互联网。这段地址在校园网中不会被路由到我们这里,因此在校园网的其他位置无法直接访问位于此段中的设备。
  • 将无线路由器调整为 AP 模式,不再进行 NAT。无线接入的设备与有线接入的设备具有同等性质。
  • 在网络中接入一台 GNU/Linux 主机,承担 DHCP 服务器、DNS 服务器和 NAT 网关的角色,具有校园网 IP 172.16.0.1 和私网 IP 192.168.0.1
  • NAT 网关将私网设备的出网流量按照轮询调度(Round-Robin)的方式 SNAT 到 172.16.0.1 ~ 172.16.0.16 共 16 个校园 IP 地址,避免私网设备同时用网时出口带宽受限。

实现

服务配置

首先,准备一个接入到实验室网络的 GNU/Linux 系统。在此处,我选择了自己熟悉的 Arch Linux 系统,使用 systemd-networkd 作为网络管理器,使用 SmartDNS 作为 DNS 服务器。

根据前面的设计,配置好系统的网络信息。systemd-networkd 同时也可承担 DHCP 服务器的角色,如果没有特殊需求的话可以选择使用,免去了额外安装配置其他 DHCP 服务器软件的麻烦。配置文件参考如下。

[Match]
# 匹配网络接口名称
Name=eno1

[Network]
# 开启 DHCP 服务器
DHCPServer=true
# 校园网网关
Gateway=172.16.0.62
# 校园网 IP
Address=172.16.0.1/26
Address=172.16.0.2/26
Address=172.16.0.3/26
Address=172.16.0.4/26
Address=172.16.0.5/26
Address=172.16.0.6/26
Address=172.16.0.7/26
Address=172.16.0.8/26
Address=172.16.0.9/26
Address=172.16.0.10/26
Address=172.16.0.11/26
Address=172.16.0.12/26
Address=172.16.0.13/26
Address=172.16.0.14/26
Address=172.16.0.15/26
Address=172.16.0.16/26
# 私网 IP
Address=192.168.0.1/24

[DHCPServer]
# DHCP 服务器地址
ServerAddress=192.168.0.1/24
# 向下游设备派发 DNS 服务器地址为(DHCP 服务器地址)本机
DNS=_server_address

由于学校提供的 DNS 服务质量不佳(存在 DNS 劫持和污染现象),我选择手动搭建一个 DNS 服务器,针对学校域名使用学校 DNS 解析,其他域名使用公共 DNS 解析。

server x.x.x.x -group campus -bootstrap-dns
server y.y.y.y -group campus -bootstrap-dns
server-tls dns.alidns.com
server-tls dot.pub
server-https https://cloudflare-dns.com/dns-query
server-https https://dns.quad9.net/dns-query

response-mode fastest-ip
nameserver /xxx.edu.cn/campus
force-qtype-SOA 65
prefetch-domain yes

完成配置文件的编写后,激活并启动 systemd-networkd.servicesmartdns.service

SNAT 配置

私网到私网

lab network rules 1

虽然这种情况一般不会发生,但此处还是进行了考虑。对于这种数据包,可以选择原样转发或者丢弃,此处选择进行原样转发。

外部到私网

lab network rules 2

对于同一个二层网络内的校园网 IP 设备,如有特殊需求,是可以将 192.168.0.0/24 路由到 172.16.0.1(软路由)实现访问的。针对这种需求,我们可以将目的地址为私网的数据包通过 SNAT 改写源地址为 192.168.0.1(软路由)。这不是必须的,但我感觉这样做会好一点。

私网到校园网

lab network rules 3

访问校园网内的设备没有额外的带宽限制,所以我们希望对外表现出的 IP 是稳定的。这里使用 RFC 1918 定义的“专用网络”地址段来覆盖校园网。

校园网到校园网

lab network rules 4

正如前面所说的,由于软路由也具有校园网 IP,同一个二层网络内的设备也是可以将软路由作为默认网关的。由于其本身就已经具有校园网 IP,所以没有必要进行一次额外的 SNAT,对这些数据包原样转发。

互联网

lab network rules 5

在经过前面四组规则的处理后,我们认为剩余的未匹配数据包都属于互联网流量,需要进行多出口 SNAT 处理。这里参考的是《私有实例轮询使用多公网 IP 访问公网的实现方案 | 亚马逊AWS官方博客》,在此对有关作者表示感谢。

综合

最后,将这些规则持久化到一个文件中,并在系统每次启动时自动加载。根据发行版,文件路径、服务名称和软件包名称会有所不同。在 Arch Linux 中,可以将规则写入到 /etc/iptables/iptables.rules 中,然后激活并启动 iptables.service

warning 请注意
如果你的系统上还运行着其他防火墙软件,请不要使用上面给出的方法。你应该将这些规则写入到你正在使用的防火墙配置中。

*nat

# Private -> Private
-A POSTROUTING -s 192.168.0.0/24 -d 192.168.0.0/24 -j RETURN

# Others -> Private
-A POSTROUTING -d 192.168.0.0/24 -j SNAT --to-source 192.168.0.1

# Private -> Site
-A POSTROUTING -s 192.168.0.0/24 -d 10.0.0.0/8 -j SNAT --to-source 172.16.0.1
-A POSTROUTING -s 192.168.0.0/24 -d 172.16.0.0/12 -j SNAT --to-source 172.16.0.1
-A POSTROUTING -s 192.168.0.0/24 -d 192.168.0.0/16 -j SNAT --to-source 172.16.0.1

# Others -> Site
-A POSTROUTING -d 10.0.0.0/8 -j RETURN
-A POSTROUTING -d 172.16.0.0/12 -j RETURN
-A POSTROUTING -d 192.168.0.0/16 -j RETURN

# Internet
-A POSTROUTING -m statistic --mode nth --every 16 --packet 0 -j SNAT --to-source 172.16.0.16
-A POSTROUTING -m statistic --mode nth --every 15 --packet 0 -j SNAT --to-source 172.16.0.15
-A POSTROUTING -m statistic --mode nth --every 14 --packet 0 -j SNAT --to-source 172.16.0.14
-A POSTROUTING -m statistic --mode nth --every 13 --packet 0 -j SNAT --to-source 172.16.0.13
-A POSTROUTING -m statistic --mode nth --every 12 --packet 0 -j SNAT --to-source 172.16.0.12
-A POSTROUTING -m statistic --mode nth --every 11 --packet 0 -j SNAT --to-source 172.16.0.11
-A POSTROUTING -m statistic --mode nth --every 10 --packet 0 -j SNAT --to-source 172.16.0.10
-A POSTROUTING -m statistic --mode nth --every 9 --packet 0 -j SNAT --to-source 172.16.0.9
-A POSTROUTING -m statistic --mode nth --every 8 --packet 0 -j SNAT --to-source 172.16.0.8
-A POSTROUTING -m statistic --mode nth --every 7 --packet 0 -j SNAT --to-source 172.16.0.7
-A POSTROUTING -m statistic --mode nth --every 6 --packet 0 -j SNAT --to-source 172.16.0.6
-A POSTROUTING -m statistic --mode nth --every 5 --packet 0 -j SNAT --to-source 172.16.0.5
-A POSTROUTING -m statistic --mode nth --every 4 --packet 0 -j SNAT --to-source 172.16.0.4
-A POSTROUTING -m statistic --mode nth --every 3 --packet 0 -j SNAT --to-source 172.16.0.3
-A POSTROUTING -m statistic --mode nth --every 2 --packet 0 -j SNAT --to-source 172.16.0.2
-A POSTROUTING -m statistic --mode nth --every 1 --packet 0 -j SNAT --to-source 172.16.0.1

COMMIT

开启 IP 转发

最后,别忘了在内核中开启 IPv4 转发。你可能还会想要配置额外的防火墙规则来保护软路由本身的安全。

net.ipv4.ip_forward = 1
net.ipv4.conf.all.forwarding = 1
赞赏
魔帆博客,版权所有 | 如未注明,均为原创
本站均采用 BY-NC-ND 协议 (署名-非商业性使用-禁止演绎) 进行授权。
转载请注明来自本站文章:使用 GNU/Linux 搭建多出口软路由(https://www.morfans.cn/archives/3491)

chenjunyu19

文章作者

一只恰巧路过这里的普通旅行者。

发表回复

textsms
account_circle
email

使用 GNU/Linux 搭建多出口软路由
简介 这篇文章记录了使用 GNU/Linux 操作系统,在不更改二层网络配置的前提下,扩展实验室网络环境,并在一定程度上改善网络使用体验的方法。 背景 假设学校网络与信息中心给我…
扫描二维码继续阅读
2024-05-24