我目前有一个具有单个静态 IP 的 VPS。如果我购买了第二个静态 IP,是否会出现以下情况?
假设 eth0:0 上的 IP A 是1.2.3.4eth0:1 上的静态 IP B 是5.6.7.8。我想将所有发往 IP A 的流量路由到我的家庭路由器,而不使用服务器端 NAT。我想在我的家庭路由器和 IP B 之间建立一个 GRE 隧道(使用 IPsec 保护)。然后,IP A 的传入 IP 数据包需要在隧道内传递。我认为图表应该可以更清楚地说明这一点: 通常,这显然是使用 Site-to-Site-VPN 并在 VPS 上使用 NAT 的情况,但实际上不想使用 NAT 服务器端。相反,我希望我的家用路由器对传出的流量执行 srcnat,对特定的传入流量执行 dstnat。VPS 应该只“传递”传入和传出的 IP 数据包。
我想象数据包的流程如下:
LAN 192.168.100.0/24 内的主机想要将数据包发送到 8.8.8.8
家庭路由器将其扫描到静态 IP A(1.2.3.4)
数据包经过 gre1 并进入 VPS
VPS 通过 eth0:0 转发数据包,源 IP 字段不变
来自 8.8.8.8 的回复到达 VPS,目标 IP 为 1.2.3.4
VPS 接收数据包并将其放入 gre1,而不执行任何 NAT
家庭路由器处理该数据包并检查它是否是已建立或相关的连接并将其转发到相应的 LAN 客户端。
我想我可以简单地在路由器的 gre1 接口上添加另一个 IP,即 1.2.3.4,这样它就可以 1) 接受具有此目标值的 IP 数据包,并且 2) 使用该 IP 而不是隧道 IP(10.0.0.2)发送传出数据包?
简而言之,我只是希望到达 eth0:0 的所有数据包都能不加修改地到达我家路由器上的 gre1。按照上述方法可以实现吗?
顺便说一句,我在家里使用 Mikrotik 路由器,如果有任何其他信息的话。
感谢您的帮助!
答案1
首先,不要再将 eth0 和 eth0:1 视为单独的接口。不要绘画它们是单独的接口。它们不是。你有一个 eth0 接口,上面有两个 IP 地址——其余的只是 Linux 在旧工具上玩弄的假象,例如是否配置。
解决了这个问题,服务器端的操作就非常简单了。
要在您的服务器上进行配置,请先移除来自 eth0 的 5.6.7.8 地址。您不希望服务器认为这些数据包属于它并消耗它们;您希望它充当纯粹的路由器,而将路由地址分配给本地接口正是路由器所不需要的。
ip addr del 5.6.7.8/x dev eth0
现在为隧道上的地址添加静态路由:
ip route add 5.6.7.8/32 dev gre1
差不多就是这样了。剩下的唯一麻烦是服务器仍然需要回答来自托管公司本地网关的针对此地址的 ARP 查询。为此,您需要代理ARP特征:
ip neigh add proxy 5.6.7.8 dev eth0
这将启用代理 ARP一地址。不要用于
sysctl net.ipv4.conf.all.proxy_arp=1
全局启用它;这会导致您的服务器有路由的所有内容都受到代理 ARP 响应,这在某些情况下可能很方便,但在这种情况下没有必要。
可能需要更复杂的配置客户路由器,因为它必须根据源 IP 地址在两个默认网关(直接路由与 GRE)之间进行选择。
幸运的是,Mikrotik RouterOS 具有 Linux 策略路由功能至少IPv4(但仍不适用于 IPv6),因此您可以遵循广泛使用的 Linuxip rule
说明并将它们 1:1 映射到 RouterOS 命令。简而言之:
通过 GRE 隧道将默认路由添加到不同的路由
桌子标记(RouterOS 称之为‘路由标记’):/ip route add dst-address=0.0.0.0/0 gateway=gre0 routing-mark="tunnelled"
添加策略规则以选择此路由
标记来自此源地址的数据包的表(RouterOS......):/ip rule add src-address=5.6.7.8/32 table="tunnelled"
一条评论提到了桥接。出于两个原因,桥接不起作用。
GRE 是第 3 层隧道,不传输类似以太网的标头,因此不可桥接。它有第 2 层变体,例如 Linux gretap 和 Mikrotik eoip – 不幸的是,尽管它们都是基于 GRE,但它们相互不兼容。
评论中实际上提到屯,可能假设隧道是 OpenVPN(GRE 不是 OpenVPN),但 tun 也是一个 Layer3 接口。现在有一个 Layer2 版本 –轻敲接口——并且 Linux OpenVPN 实际上可以配置为使用它并成为 Layer2 VPN……但是 RouterOS OpenVPN 实现无论如何都不支持该模式。
此外,由于 eth0:1不是一个单独的接口,如果不桥接 eth0 本身,则无法桥接它。麦克维兰虚拟接口是否可以通过 eth0 创建,然后通过隧道进行桥接?不确定。这样做可能得不偿失。