实验室台式机配网——源进源出与NAT端口映射

我在实验室配置的台式机有两个网络接口连接外部网络, eno2连接教育网、wlo1连接校园网。其中, 教育网接口提供千兆对等的互联网访问, 但无法访问校园网内部资源; 而校园网接口通过无线网络连接, 可以访问校园网资源, 但互联网访问速度有限, 并且按照流量计费(虽然目前疫情期间免费)。于是, 我配置了路由表, 让去往校园网的流量走校园网接口, 其他流量走教育网接口。此外, 台式机下面挂了192.168.1.0/24的子网, 目前接了一个树莓派。

然而, 上述配置方法存在问题。当我使用笔记本电脑在校园网环境下使用教育网IP地址远程连接台式机时, 台式机的响应包会以教育网IP地址(即我发送请求使用的地址)为源地址, 然后由于响应包的目标IP地址为校园网地址, 根据路由表, 响应包会被发送至校园网接口。由于源地址不正确, 校园网会拒绝转发这一响应包。类似地, 当我使用笔记本电脑在非校园网环境下使用校园网IP地址远程连接台式机时, 台式机的响应包会以校园网IP地址为源地址, 被发送至教育网接口, 产生同样的问题。(事实上, 我发现教育网接口允许伪造源地址, 但这不在本文讨论范围内了。)

为了解决这一问题, 一个直观的想法是, 若源IP地址已经确定, 就应当使用对应的接口发送数据包。于是, 我配置了基于源地址的策略路由表: 如果源地址是教育网地址, 无论目标地址如何, 都使用教育网接口; 如果源地址是校园网地址, 无论目标地址如何, 都使用校园网接口。对于台式机向外创建的新连接, 由于源地址尚未确定, Linux会查询默认的路由表, 即本文第一段一开始配置的路由表, 然后选择出接口上配置的地址作为源地址, 因此不受前面的策略路由影响。

至此, 对于台式机自身, 上面的问题就解决了。进一步, 为了使得我可以远程访问树莓派, 我在台式机上添加了iptables的DNAT规则, 把2222端口转发至树莓派的ssh端口(22):

iptables -t nat -A PREROUTING -p tcp -m tcp --dport 2222 -j DNAT --to-destination 192.168.1.树莓派:22

然而, 当我尝试使用笔记本电脑在校园网环境下使用台式机的教育网IP地址远程连接树莓派时, 却发现无法连接。聪明的读者意识到问题所在了吗?

事实上, 上述DNAT规则隐含了一个POSTROUTING阶段的SNAT, 即在查询路由表之后把树莓派发的响应包的源IP地址和端口号转换回台式机的。注意到, 在查询路由表时, 这个响应包的源IP地址还未被改变, 为192.168.1.树莓派, 因此, 系统会查询默认路由表, 然后选择校园网接口作为出接口。

为了解决这些问题, 需要换一种策略路由的方式。经Soha指点, 我们可以在收到包的时候对包所对应的流打上标签, 记录这个流对应的接口。然后利用策略路由, 让有标记的流的包在此后的通信中都使用相同的接口。

首先, 利用iptables维护包和流的标签信息:

# 对于本机生成的包, 如果对应的流有标签, 那么给包设置同样的标签。
iptables -t mangle -A OUTPUT -m connmark --mark 1000 -j CONNMARK --restore-mark
iptables -t mangle -A OUTPUT -m connmark --mark 1001 -j CONNMARK --restore-mark
# 对于接收到的包, 如果对应的流有标签, 那么给包设置同样的标签。这些包一般是从其它接口收到, 并需要被转发至连接外部网络的接口。
iptables -t mangle -A PREROUTING -m connmark --mark 1000 -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -m connmark --mark 1001 -j CONNMARK --restore-mark
# 对于接收到的包, 匹配接口, 然后给对应的流设置自定义的标签。
iptables -t mangle -A PREROUTING -i eno2 -j CONNMARK --set-mark 1000
iptables -t mangle -A PREROUTING -i wlo1 -j CONNMARK --set-mark 1001

然后, 配置策略路由规则以及不同标签对应的路由表。配置结果如下所示:

# ip rule
0:	from all lookup local
0:	from all fwmark 0x3e9 lookup 1001
0:	from all fwmark 0x3e8 lookup 1000
...

# ip route show table 1000
default via 教育网网关 dev eno2 proto static
教育网网络前缀/长度 dev eno2 proto static scope link
192.168.1.0/24 dev br0 proto static scope link

# ip route show table 1001
default via 校园网网关 dev wlo1 proto static onlink
校园网网络前缀/长度 dev wlo1 proto static scope link
192.168.1.0/24 dev br0 proto static scope link

其中, 每个路由表都需要配置192.168.1.0/24的直连路由, 否则转发不正确。同时, 每个路由表都需要配置相应出接口所在子网的直连路由, 否则部分同一子网的包需要经过路由器转发, 路径不是最优。此外, 注意到, 策略路由使用的是包的标签, 而不是流的标签, 因此, 需要前面iptables的相关配置。

至此, 怎么样都可以访问了。

发表评论

注意 - 你可以用以下 HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

:wink: :twisted: :roll: :oops: :mrgreen: :lol: :idea: :evil: :cry: :arrow: :?: :-| :-x :-o :-P :-D :-? :) :( :!: 8-O 8)

本文链接:https://twd2.me/archives/15457QrCode