背景资料
我正在使用 Linux 系统为一小部分公共 IPv4 地址路由流量(通过在 中启用 IP 转发
sysctrl.conf
)。路由器正在
eth1
使用 PPPoE 连接到 ISP。ppp 使用的本地对等地址是由 ISP 指定的手动配置的 IP 地址。本地对等地址是
10.0.0.10
。用于 ppp 的远程对等地址也是由 ISP 指定的手动配置的 IP 地址。远程对等地址是
10.0.0.9
。路由器的默认路由是
10.0.0.9
via10.0.0.10
。路由器通过 与以太网交换机连接
eth0
。eth0
配置为使用公共地址之一。交换机连接所有其他公共主机。每个连接的主机都使用公共 IP 地址。
10.0.0.9
ISP ----------+
| 10.0.0.10 X.X.X.X
+------------- (eth1) ROUTER (eth0) --------------- SWTICH
|
+-- X.X.X.Y
+-- X.X.X.Z
...
我的问题
除了路由器上运行的程序外,一切都按预期工作。我在路由器上运行的任何应用程序10.0.0.10
在启动与互联网的连接时都用作源 IP 地址。这是可以理解的,因为eth1
那里有互联网。但是,由于该地址不可公开路由,因此apt
、ping
、 和其他程序无法运行。如果我在支持它的应用程序上明确设置源地址(即ping
),应用程序就会工作。
我的问题
如何配置路由器通过eth1
/路由未知数据包10.0.0.9
,同时eth0
在启动新连接时使用公共 IP 地址作为默认源?
答案1
注意:我会认为你的路由器的LAN是192.0.2.0/24并且它的LAN IP在以太网0是192.0.2.1/24,能够给出具体的解释和解决方案。
您的 ISP 为了节省一些公共 IP 地址,为您分配了一个私有 IP 用于内部路由目的。这很好,因为这个 IP 永远不会被外界看到(并且会很快被丢弃)严格反向路径转发沿着路径(如果曾经放在 ISP 路由器之外的线路上),或者如果没有,由于不可路由,将永远不会得到答复)。但这会使您的配置变得更加复杂,以避免在除了从路由器连接到 ISP 之外的所有情况下都使用此 IP。
你可能有类似的东西(可能略有不同,没关系):
# ip route
default via 10.0.0.9 dev ppp0
10.0.0.9 dev ppp0 proto kernel scope link src 10.0.0.10
192.0.2.0/24 dev eth0 proto kernel scope link src 192.0.2.1
例如,您可能有default via 10.0.0.9 dev ppp0 src 10.0.0.10
,或者via 10.0.0.9
甚至没有出现,因为它是第 3 层链接而不是第 2 层链接,因此via
不需要(但仍然被接受)。只需相应地调整以下设置即可。
目前,内核选择显然最适合的 IP,即在同一侧设置的 IP 以访问互联网,因为没有任何其他信息告诉它(或者它明确告诉使用您不想要的 IP):
# ip route get 8.8.8.8
8.8.8.8 via 10.0.0.9 dev ppp0 src 10.0.0.10 uid 0
cache
您只需要在内核检查如何访问互联网并声明特定的首选源 IP 地址时替换路由行为。请注意,如果出现错误和不可预见的问题,您可能会失去连接。如果可能的话,拥有备用(控制台)访问权限:
# ip route replace default via 10.0.0.9 dev ppp0 src 192.0.2.1
# ip route get 8.8.8.8
8.8.8.8 via 10.0.0.9 dev ppp0 src 192.0.2.1 uid 0
cache
就是这样,您的路由器将照常路由,但当需要选择本地发起的传出 IP 时,将选择 192.0.2.1,除非明确告知(例如:进程显式绑定其套接字上的源 IP)。
每次链路断开再接通时都必须重新设置此路由。链接完全建立后,您可以将其集成到某些 pppoe 脚本中。
另请注意接口名称点对点0可能会更改为点对点1或任何其他名称。这取决于您在设置脚本中处理这个问题。
设置相同路线设置的替代方法:
最初设置指标时添加较低的指标
如果设置了原始度量(即它不是 0,假设它是 100),您可以添加具有较低度量的备用默认路由,而不是替换之前的路由:
# ip route add default via 10.0.0.9 dev ppp0 src 192.0.2.1 metric 50
专用路由规则
如果您担心 pppoe 中涉及的各种工具的交互可能会删除上述路由,您可以在备用路由表中安装此设置,并在路由规则中赋予其优先级,并使用主表的部分副本来防止中断。每次断开/重新连接后仍然需要重做,因为路线仍然会消失。这里
iif lo
很特殊,实际上意味着“本地发起的传出数据包”而不是传入,并且 109 是任意选择的表值:# ip rule add iif lo lookup 109 # needed only once # ip route add table 109 10.0.0.9 dev ppp0 proto kernel scope link src 10.0.0.10 # to keep using 10.0.0.10 for local link, just in case # ip route add table 109 192.0.2.0/24 dev eth0 src 192.0.2.1 # will disappear if eth0 is brought down # ip route add table 109 default via 10.0.0.9 dev ppp0 src 192.0.2.1 # will disappear if ppp0 is brought down
如果您在主表中添加了其他路由条目,那么您很可能还必须在上面复制它们。
# ip route get 8.8.8.8 8.8.8.8 via 10.0.0.9 dev ppp0 table 109 src 192.0.2.1 uid 0 cache
简化路由的路由规则
人们可以将路由保留在主表中,并仅使用规则中基于前缀的抑制器覆盖默认路由:这避免了复制全部路线:只需复制和更改默认路线即可。
将 2. 替换为(说明偏好值,仍然按降序排列它们,就像不说明它们时发生的情况一样):
# ip rule add pref 32765 iif lo lookup 109 # needed only once # ip rule add pref 32764 iif lo lookup main suppress_prefixlength 0 # needed only once # ip rule 0: from all lookup local 32764: from all iif lo lookup main suppress_prefixlength 0 32765: from all iif lo lookup 109 32766: from all lookup main 32767: from all lookup default # ip route add table 109 default via 10.0.0.9 dev ppp0 src 192.0.2.1 # will disappear if ppp0 is brought down
主路由表将首先用于任何不会成为默认路由的内容,然后对于本地发起的传出流量,路由表 109 中提供默认路由。其他任何内容将继续并再次在主表中查找默认路由,如下所示通常。
相对于 2. 的优点是不需要从表中复制(非默认)路由主要的不再进入表109。下面,表主要的提供非默认路由的结果,与 2. 方法相反:
# ip route get 8.8.8.8 8.8.8.8 via 10.0.0.9 dev ppp0 table 109 src 192.0.2.1 uid 0 cache # ip route get 192.0.2.2 192.0.2.2 dev eth0 src 192.0.2.1 uid 0 cache
答案2
正如你所说。以您的路由器作为网关的交换机上的其他客户端都有公共 IP 地址。你的路由器没有。它有一个不会被路由的 LAN 地址。由于您的互联网服务提供商没有为您提供公共地址,因此路由器将无法出去。
如果您有另一个公共 IP,请在 eth1 上创建虚拟 eth 配置并正确路由它。然后你的路由器也可以出去了。