获取默认路由源地址的可移植方法是什么?

获取默认路由源地址的可移植方法是什么?

我需要获取用作数据包源的 IP 地址default通过路由发送。 (编辑)请注意,我指的是路线default,即标记为defaultip r请参阅末尾以了解数据包在我的 VPN 设置下将采用的实际路线)。

我的第一个想法是使用ip r并从中推断出:

# ip r
0.0.0.0/1 via 10.0.2.1 dev tun0
default via 10.237.76.1 dev enxb827eb4297a4 src 10.237.77.206 metric 202
10.0.2.0/24 dev tun0 proto kernel scope link src 10.0.2.100
10.81.102.133 via 10.237.76.1 dev enxb827eb4297a4
10.237.76.0/22 dev enxb827eb4297a4 proto kernel scope link src 10.237.77.206 metric 202
128.0.0.0/1 via 10.0.2.1 dev tun0

它看起来不错,ip r | grep default | cut -d" " -f7给了我预期的效果10.237.77.206

然后,在另一个系统(都是 debian 衍生品)上我得到了

# ip r
0.0.0.0/1 via 10.0.2.1 dev tun0
default via 10.237.76.1 dev eth0  metric 202
10.0.2.0/24 dev tun0  proto kernel  scope link  src 10.0.2.5
10.81.102.133 via 10.237.76.1 dev eth0
10.237.76.0/22 dev eth0  proto kernel  scope link  src 10.237.76.56  metric 202
128.0.0.0/1 via 10.0.2.1 dev tun0

这里的解决方案并不那么简单:我需要提取默认路由 IP ( 10.237.76.1),将其与适当的路由 ( 10.237.76.0/22 dev eth0 proto kernel scope link src 10.237.76.56 metric 202) 相匹配,该路由有望包含src.

最终削减 的输出ip在 lng 术语中是站不住脚的(输出的变化、发行版或版本之间输出的变化,......)

有没有更便携的方式来获取该IP?

我所说的“便携式”是指:

  • 理想情况下“适用于任何 Linux”
  • 不太理想但仍然很好“适用于 Debian 及其衍生版本”

请注意,设备位于独占 VPN 中,因此我无法直接分析 VPN 启动时(即大多数时间)数据包将采取的实际路由:该default路由被其他两条路由屏蔽,这有效地覆盖了整个IP范围。如果我在这里弄错了,请纠正我。

答案1

您可以选择一个您认为始终通过默认路由访问的任意地址,例如 google DNS,然后打印源地址路线:

ip route get 8.8.8.8 | awk '{ for (nn=1;nn<=NF;nn++) if ($nn~"src") print $(nn+1) }'

答案2

显示您的默认路由源地址:

ip route get 8.8.8.8  | awk ' /^[0-9]/ { print $7 }'  
  • 选择{ print $7 }输出的第 7 个字段ip...
  • 选择^[0-9]以数字开头的行会ip生成两行,以选择正确的行。

注意:我更喜欢第一个解决方案,但是为了显示替代方案而显示其他替代方案。

或者:

ip route get 8.8.8.8 |  cut -f7 -d" " | grep '^[0-9]'

再次:

  • 选择cut第 7 个字段;

或者:

 ip route get 8.8.8.8 | grep ^[0-9] |  cut -f7 -d" " 

或者:

ip route get 8.8.8.8 | fgrep src |  cut -f7 -d" "

或者也可以:

 ip route get 8.8.8.8 | awk ' /src/ { print $7 }' 

为了澄清一点,这里是输出ip

$  ip route get 8.8.8.8 
8.8.8.8 via 192.168.1.1 dev eth0 src 192.168.1.249 
   cache  

有多种方法可以在 Linux 中获取默认路由,可以通过ipprocfs也可以从netstatnetstat正在被弃用,并且在我看来,ip它是任何最新 Linux 发行版中的更好选择。

答案3

基于实际意图(查找原始输出 IP)和所做的答案,这里有一个(相当长的)单行代码应该可以解决问题:

ip route get 8.8.8.8 oif $(ip route | sed -n '/^default/s/^.* dev \([^ ][^ ]*\) *.*$/\1/p')  | sed -n 's/^.* src \([^ ][^ ]*\) *.*$/\1/p'

第一步$():获取默认路由,仅检索关键字后的接口开发者(因为根据可能取决于或不取决于分布的条件,路由在此步骤中将显示或不显示源IP)

第二步:获取到“众所周知”的公共IP地址的路由,该地址不应有特殊的路由设置篡改它,但要求使用之前检索到的接口,因此实际上要求内核使用埋在下面的实际原始默认0.0.0.0/1路由128.0.0.0/1进行计算。检索关键字后的IP源代码

答案4

在我的场景中(设置一个docker容器以正确获取主机的ip)我决定这样:

ip route|awk '/src/ { print $7 }'

相关内容