为什么 ARP 请求非本地地址?

2024-03-16

我有一个带有 2 个网卡的 Linux 虚拟服务器。

eth0 <IP1>
eth1 <IP2>

arp_filter已打开并且rp_filter设置为2(宽松模式)。
策略路由配置如下:

table T1
default via <GW> dev eth0 src <IP1>
127.0.0.0/8 dev lo
<LAN> dev eth0 src <IP1>

table T2
default via <GW> dev eth1 src <IP2>
127.0.0.0/8 dev lo
<LAN> dev eth1 src <IP2>

ip rule add from <IP1> table T1
ip rule add from <IP2> table T2

之后我可以ping都绑定了 floatips<IP1> and <IP2>从外面。然而ping -I eth1 <some_domain>不起作用。tcpdump显示当我从eth1到外面,Linux直接询问MAC外部地址,这是不正确的,因为它们不在同一地址LAN.

Here is tcpdump data:

root@rm-2:~# tcpdump -i eth1 arp
tcpdump: verbose output suppressed, use -v or -vv for full protocol     decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65535     bytes
17:53:08.696191 ARP, Request who-has 172.30.250.119 tell 172.30.248.2, length 46
17:53:08.728482 ARP, Request who-has 172.30.251.144 tell 172.30.251.138, length 46
17:53:09.447252 ARP, Request who-has 61.135.169.125 tell 172.30.251.43, length 28
17:53:09.551514 ARP, Request who-has 172.30.250.127 tell 172.30.248.2, length 46
17:53:09.698076 ARP, Request who-has 172.30.250.119 tell 172.30.248.2, length 46
17:53:09.859046 ARP, Request who-has 172.30.248.246 tell 172.30.248.245, length 46
17:53:10.446009 ARP, Request who-has 61.135.169.125 tell 172.30.251.43, length 28
17:53:10.477104 ARP, Request who-has 172.30.250.128 tell 172.30.248.2, length 46

如你看到的,61.135.169.125是一个国外地址,这是一个错误还是什么?

EDIT
输出route: // 172.30.248.1 是GW

Destination     Gateway         Genmask         Flags Metric Ref    Use      Iface  
default         172.30.248.1    0.0.0.0         UG    0      0        0      eth0

Answer:

您需要添加输出接口规则(ip rule add oif ...) 此外ip rule add from ...,因为 ping 绑定到界面,而不是IP。

Example:

ip rule add from <IP1> table T1
ip rule add oif <eth0> table T1
ip rule add from <IP2> table T2
ip rule add oif <eth1> table T2

解释:

您问题中的 ping 示例使用接口作为源(ping -I eth1 <some domain>),没有任何匹配的策略路由。因此 ping 的行为与没有为该地址定义路由时的情况完全相同界面 at all.

测试/证明示例(在没有策略路由的情况下开始):

使用我的手机 USB 系留作为备用路线,我有以下基本配置。

Linux desktop:
$ ip addr show usb0
...
inet 192.168.42.1/32 ...
..

Android phone:
$ ip addr show rndis0
...
inet 192.168.42.129/24 ...
...

因为桌面USB0接口被分配了/32地址,如果我尝试ping 192.168.42.129 -I 192.168.42.1,它将失败,因为没有为该地址定义路由,并且它不在 usb0 的广播域内address。然而,随着ping 192.168.42.129 -I usb0-- 我告诉 ping 使用界面本身,并且没有与该接口匹配的路由(因此,没有广播域的概念),因此它会盲目地对任何不属于自己的IP触发ARP请求。

让我们尝试使用以下命令进行 ping 操作界面(没有路线)。即使不在同一个广播域内,这也会导致 ARP 请求发生:

desktop$ ping 192.168.42.129 -I usb0
phone# tcpdump -i rndis0 -n icmp or arp
ARP, Request who-has 192.168.42.129 tell 192.168.42.1, length 28
ARP, Reply 192.168.42.129 is-at 3e:04:37:23:05:0e, length 28
IP 192.168.42.1 > 192.168.42.129: ICMP echo request, id 24641, seq 1, length 64
IP 192.168.42.129 > 192.168.42.1: ICMP echo reply, id 24641, seq 1, length 64

使用接口的源IP(无路由),它不会发出ARP请求,因为源不在广播域内:

desktop$ ping 192.168.42.129 -I 192.168.42.1
phone# tcpdump -i rndis0 -n icmp or arp
... nothing comes over the wire, as expected ...

现在,如果我通过接口添加到主机的路由,则 ping 知道它可以对 192.168.42.129 地址发出 ARP 请求:

desktop$ ip route add 192.168.42.129/32 dev usb0
desktop$ ping 192.168.42.129 -I 192.168.42.1
phone# tcpdump -i rndis0 -n icmp or arp
ARP, Request who-has 192.168.42.129 tell 192.168.42.1, length 28
ARP, Reply 192.168.42.129 is-at 3e:04:37:23:05:0e, length 28
IP 192.168.42.1 > 192.168.42.129: ICMP echo request, id 24667, seq 1, length 64
IP 192.168.42.129 > 192.168.42.1: ICMP echo reply, id 24667, seq 1, length 64

因此,当我尝试 ping 网络外的某些内容时,同样的概念也适用;如果我使用以下命令 ping 8.8.8.8界面作为源,它会盲目地发出没有任何匹配路由的 ARP 请求:

desktop$ ping 8.8.8.8 -I usb0
phone# tcpdump -i rndis0 -n icmp or arp
ARP, Request who-has 8.8.8.8 tell 192.168.42.1, length 28

使用界面时address,路由表中缺少任何类型的下一跳路由都会导致其失败并且无法发出 ARP 请求:

desktop$ ping 8.8.8.8 -I 192.168.42.1
phone# tcpdump -i rndis0 -n icmp or arp
... nothing ...

因此,让我们为 192.168.42.1 地址添加策略路由(使用“来自...的 ip 规则”)以使用 192.168.42.129 作为下一跳默认值,其方式与您的问题示例相同:

desktop$ sudo ip rule add from 192.168.42.1 lookup T1
desktop$ sudo ip route add default via 192.168.42.129 dev usb0 table T1
desktop$ ping 8.8.8.8 -I 192.168.42.1
PING 8.8.8.8 (8.8.8.8) from 192.168.42.1 : 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=59 time=28.6 ms
...
phone# tcpdump -i rndis0 -n icmp or arp
IP 192.168.42.1 > 8.8.8.8: ICMP echo request, id 24969, seq 1, length 64
IP 8.8.8.8 > 192.168.42.1: ICMP echo reply, id 24969, seq 1, length 64

它有效,因为我们正在使用address,它正确匹配ip规则。

现在我们使用以下命令再次尝试相同的 ping界面:

desktop$ ping 8.8.8.8 -I usb0
PING 8.8.8.8 (8.8.8.8) from 192.168.42.1 usb0: 56(84) bytes of data.
^C
--- 8.8.8.8 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
...
phone# tcpdump -i rndis0 -n icmp or arp
ARP, Request who-has 8.8.8.8 tell 192.168.42.1, length 28

它失败;没有界面下一跳的路由,因此它会再次发出 ARP 请求,但永远不会得到回复。所以我们需要添加一条ip规则界面也使用 192.168.42.129 作为下一跳:

desktop$ sudo ip rule add oif usb0 lookup T1
desktop$ ping 8.8.8.8 -I usb0
PING 8.8.8.8 (8.8.8.8) from 192.168.42.1 usb0: 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=59 time=10.7 ms

--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 10.791/10.791/10.791/0.000 ms
...
phone# tcpdump -i rndis0 -n icmp or arp
IP 192.168.42.1 > 8.8.8.8: ICMP echo request, id 24979, seq 1, length 64
IP 8.8.8.8 > 192.168.42.1: ICMP echo reply, id 24979, seq 1, length 64

我相信,一般来说,缺少接口路由不会对正常的、非接口绑定的传出连接的实现产生负面影响。大多数(不是全部)应用程序绑定到address对于出站 TCP/UDP 连接,并且仅绑定到界面用于传入连接(侦听)。 ping 实用程序是一个特例。

为了证明这一点,如果我从路由策略中删除接口规则,在指定绑定时我仍然可以使用正常的出站套接字address。在下面的示例中,我使用 telnet 和 netcat,在两种情况下都指定绑定地址(-b 192.168.42.1)并且它正确匹配 T1 表,从而使用网关。

# remove the interface route, keep the address route
desktop$ sudo ip rule del from all oif usb0 lookup T1
desktop$ nc -zv 8.8.8.8 443 -s 192.168.42.1
google-public-dns-a.google.com [8.8.8.8] 443 (https) open

phone# tcpdump -i rndis0 -n host 8.8.8.8
IP 192.168.42.1.40785 > 8.8.8.8.443: Flags [S], seq 1678217252, win 29200, options [mss 1460,sackOK,TS val 20223895 ecr 0,nop,wscale 6], length 0
IP 8.8.8.8.443 > 192.168.42.1.40785: Flags [S.], seq 86178051, ack 1678217253, win 28400, options [mss 1432,sackOK,TS val 1937335284 ecr 20223895,nop,wscale 8], length 0
....
desktop$ telnet 8.8.8.8 53 -b 192.168.42.1
...
phone# tcpdump -i rndis0 -n host 8.8.8.8
IP 192.168.42.1.57109 > 8.8.8.8.53: Flags [.], ack 1, win 457, options [nop,nop,TS val 20288983 ecr 4154032957], length 0
IP 8.8.8.8.53 > 192.168.42.1.57109: Flags [F.], seq 1, ack 1, win 111, options [nop,nop,TS val 4154033968 ecr 20288983], length 0

我在测试策略路由实现时遇到了同样的问题,我花了一些时间思考为什么我的接口 ping 没有得到答复。希望这能澄清一切。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 ARP 请求非本地地址? 的相关文章

  • SSH,运行进程然后忽略输出

    我有一个命令可以使用 SSH 并在 SSH 后运行脚本 该脚本运行一个二进制文件 脚本完成后 我可以输入任意键 本地终端将恢复到正常状态 但是 由于该进程仍在我通过 SSH 连接的计算机中运行 因此任何时候它都会登录到stdout我在本地终
  • 有没有一种快速方法可以从 Jar/war 中删除文件,而无需提取 jar 并重新创建它?

    所以我需要从 jar war 文件中删除一个文件 我希望有类似 jar d myjar jar file I donot need txt 的内容 但现在我能看到从 Linux 命令行执行此操作的唯一方法 不使用 WinRAR Winzip
  • FileOutputStream.close() 中的设备 ioctl 不合适

    我有一些代码可以使用以下命令将一些首选项保存到文件中FileOutputStream 这是我已经写了一千遍的标准代码 FileOutputStream out new FileOutputStream file try BufferedOu
  • 调用 printf 系统子例程在汇编代码中输出整数错误[重复]

    这个问题在这里已经有答案了 来回 在windows7控制台窗口中运行gcc s2 asm 然后生成一个exe文件 运行a exe 然后崩溃 为什么 s2 asm 代码由以下源代码生成 int m m 1 iprint m s2 asm请参考
  • 对卡在 CLOSE_WAIT 状态的连接进行故障排除

    我有一个在 Windows 上的 WebLogic 11g 中运行的 Java 应用程序 几天后它变得没有响应 我注意到的一个可疑症状是大量连接 大约 3000 个 出现在netstat即使服务器空闲 也具有 CLOSE WAIT 状态 由
  • docker 非 root 绑定安装权限,WITH --userns-remap

    all 尝试让绑定安装权限正常工作 我的目标是在容器中绑定安装卷 以便 a 容器不以 root 用户身份运行入口点 二 docker daemon 配置了 userns remap 这样容器 主机上没有 root c 我可以绑定挂载和读 写
  • 我们真的应该使用 Chef 来管理 sudoers 文件吗?

    这是我的问题 我担心如果 Chef 破坏了 sudoers 文件中的某些内容 可能是 Chef 用户错误地使用了说明书 那么服务器将完全无法访问 我讨厌我们完全失去客户的生产服务器 因为我们弄乱了 sudoers 文件并且无法再通过 ssh
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • 如何在 Ubuntu 中创建公共 HTML 文件夹?

    简单的问题 但由于某种原因我无法在谷歌上找到确切的答案 我在 Slicehost 上安装了全新的 Ubuntu 并且想在我的主目录中为包含一堆静态 HTML 文件的简单网站创建一个公共目录 我该怎么做呢 只是打字的问题吗mkdir publ
  • 如何在linux中以编程方式获取dir的大小?

    我想通过 C 程序获取 linux 中特定目录的确切大小 我尝试使用 statfs path struct statfs 但它没有给出确切的大小 我也尝试过 stat 但它返回任何目录的大小为 4096 请建议我如何获取 dir 的确切大小
  • 为什么 fopen("any_path_name",'r') 不给出 NULL 作为返回值?

    在调试一些代码时 我得到如下内容 include
  • 如何让R使用所有处理器?

    我有一台运行 Windows XP 的四核笔记本电脑 但查看任务管理器 R 似乎一次只使用一个处理器 如何让 R 使用全部四个处理器并加速我的 R 程序 我有一个基本系统 我使用它在 for 循环上并行化我的程序 一旦您了解需要做什么 此方
  • 使用包管理器时如何管理 Perl 模块?

    A 最近的问题 https stackoverflow com questions 397817 unable to find perl modules in intrepid ibex ubuntu这让我开始思考 在我尝试过的大多数 Li
  • 与 pthread 的进程间互斥

    我想使用一个互斥体 它将用于同步对两个不同进程共享的内存中驻留的某些变量的访问 我怎样才能做到这一点 执行该操作的代码示例将非常感激 以下示例演示了 Pthread 进程间互斥体的创建 使用和销毁 将示例推广到多个进程作为读者的练习 inc
  • 静态方法的 Java 内存模型

    我来自操作系统和 C 语言背景 在代码编译时 世界很简单 需要处理和理解堆栈 堆文本部分等 当我开始学习 Java 时 我确实了解 JVM 和垃圾收集器 我对静态方法感到很有趣 根据我的理解 类的所有实例都会在堆中创建 然后被清理 但是 对
  • Apache 访问 Linux 中的 NTFS 链接文件夹

    在 Debian jessie 中使用 Apache2 PHP 当我想在 Apache 的文档文件夹 var www 中创建一个新的小节时 我只需创建一个指向我的 php 文件所在的外部文件夹的链接 然后只需更改该文件夹的所有者和权限文件夹
  • 这种文件锁定方法可以接受吗?

    我们有 10 个 Linux 机器 每周必须运行 100 个不同的任务 这些计算机主要在我们晚上在家时执行这些任务 我的一位同事正在开发一个项目 通过使用 Python 自动启动任务来优化运行时间 他的程序将读取任务列表 抓取一个打开的任务
  • cdc_acm:无法设置 dtr/rts - 无法与 USB cdc 设备通信

    我试图使用 pic24fj128gb206 枚举 usb cdc 设备 设备似乎已正确枚举 但是当我将设备连接到 Linux PC 时 我从内核收到以下警告消息 cdc acm 1 8 1 6 7 1 0 failed to set dtr
  • 可以访问每个套接字的 TCP 统计数据/信息吗? (C/C++)

    我需要一些信息 例如我创建的特定 TCP 套接字发生的重新发送包 数据包丢失的数量 有人知道如何直接从我的 C C 程序访问或请求此类信息吗 也许是 Linux 特有的东西 或者我是否需要 作为解决方法 捕获和分析我自己的流量 提前致谢 通
  • 尽管我已在 python ctypes 中设置了信号处理程序,但并未调用它

    我尝试过使用 sigaction 和 ctypes 设置信号处理程序 我知道它可以与python中的信号模块一起使用 但我想尝试学习 当我向该进程发送 SIGTERM 时 但它没有调用我设置的处理程序 只打印 终止 为什么它不调用处理程序

随机推荐

  • 强制 UIImagePickerController 裁剪方形图像

    我们如何强制 UIImagePickerController 裁剪方形图像 我到处寻找 但没有找到可靠的解决方案 谢谢 var imagePickerController UIImagePickerController UIImagePic
  • 为什么 char 数组必须以空字符结尾?

    为什么 chararray必须以空字符结尾 有什么理由我必须将空字符添加到每个char array 看来他们受到的待遇是一样的 char 数组不必以 null 终止 不依赖于此的标准库函数包括memcpy memmove strncpy 最
  • 数据表删除导出到 pdf 和 excel 时的列

    我在导出到 pdf excel 之前删除列时遇到问题 第二个问题是由于该列 该列的反向部分无法正常工作 这是我使用的代码 document ready function var arrayCol new Array var table ex
  • Python sqlite3在本地成功,但在Github Action上失败

    相同的 python 版本 相同的 sqlite3 版本和相同的文件 但我只是无法传递 Github Action 这是我的 github 操作 https github com CloudAurora Blog blob master g
  • Cassandra (CQL) 中的结果分页

    我想知道如何使用 Cassandra 实现分页 假设我有一个博客 该博客每页最多列出 10 篇帖子 要访问下一篇文章 用户必须单击分页菜单才能访问第 2 页 第 11 20 篇文章 第 3 页 第 21 30 篇文章 等 在 MySQL 下
  • 创建ECDSA公钥给定曲线和公共点?

    我正在努力从公钥的字符串表示形式创建 ECDSA 公钥 即 string devicePublicKey 86FB5EB3CA0507226BE7197058B9EC041D3A3758D9D9C91902ACA3391F4E58AEF13
  • 实现系统管理的ConnectionService

    我想实现此功能以添加来电和对正在进行的通话进行不同的操作 例如保持拒绝等 我已经查看并实施了以下内容 但得到了 致命异常 java lang SecurityException 未为此用户启用此 PhoneAccountHandle And
  • mysql 根据第三个字段的值从两个字段中选择任意一个字段

    我想针对名为 nosale 的字段中的值选择价格或 sale price 其中 price sale price 和 nosale 是产品表的字段 nosale 字段要么为真 要么为假 据此 我想要价格或 sale price 的值 而不是
  • R 中没有从 Zeroinfl 对象预测零?

    我创建了一个零膨胀负二项式模型 并想要研究有多少零被划分为采样零或结构零 我如何在 R 中实现这一点 zeroinfl 页面上的示例代码我不清楚 data bioChemists package pscl fm zinb2 lt zeroi
  • 我如何要求 Hibernate 在外键(JoinColumn)上创建索引?

    这是我的模型 class User CollectionOfElements JoinTable name user type joinColumns JoinColumn name user id Column name type nul
  • 如何使用 Ajax、Json 和 Node.js 刷新表数据

    我使用 Node js 作为服务器端 并使用 Express 和 Twitter Bootstrap 作为前端 该页面有一个带有表单和提交按钮的对话框 该表单是通过 Jquery Ajax 调用提交的 在 Node js 服务器响应后不要重
  • 如何在 Win XP 上查找所有“SVN 工作副本”

    我有Windows XP 我想升级我的TortoiseSVN 至版本 1 7 http tortoisesvn net tsvn 1 7 releasenotes html 为此 我需要确保可以在我的 PC 上找到所有 SVN 工作副本 所
  • 子级的 CSS 缩放变换不影响父级大小

    我有一个太大的组件 我想缩小它 我可以通过缩放变换来做到这一点 但父容器不会缩小以适应 在我的真实代码中 带有 SHRINK ME 类的 div 实际上是一个 Angular 日历组件 但这简化了repo https codepen io
  • VB.Net 中的匿名类初始化

    我想在 vb net 中创建一个匿名类 如下所示 var data new total totalPages page page records totalRecords rows new new id 1 cell new 1 7 Is
  • OpenCV:Flann 匹配器崩溃

    我正在尝试运行一个检测图像中特征的应用程序 但是当我运行以下代码时BRISK特征 BRIEF描述符和FlannBased匹配器 它崩溃并说 OpenCV Error Unsupported format or combination of
  • Mongodb 因地址无效访问而崩溃 - 分段错误信号 11 - 版本 2.6

    我正在尝试在 MongoDB 中插入文档 我当前的版本是 2 6 生产版本 我的应用程序能够插入一些文档 但在某个时间点后开始出现以下错误 我每次都会遇到同样的错误 我正在从 cmd 提示符运行 mongod 我在 2 6 0 rc 和 2
  • 服务器上 GetThumbnailImage 中的 C# 内存不足异常

    当用户向我们发送图像时 我正在运行以下代码来创建缩略图 public int AddThumbnail byte originalImage File parentFile File tnFile null try System Drawi
  • MySQL 查询中省略分号有什么不好吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我最近在 MySQL 查询末尾省略了分号 我想到这可能会在服务器高负载 缓存等情况下产生负面影响 是否有这样的影响 如果系统能够在不使用分号的情
  • 如何在重写方法中表示调用基类方法?

    我有一个子类想要向基类函数添加更多功能 我如何表示它也执行基类函数而不仅仅是新添加的功能 有趣的问题 我用 Enterprise Architect 尝试过 它确实让我选择了父级的操作 但图中的显示没有改变 看来您需要为此使用注释 如你看到
  • 为什么 ARP 请求非本地地址?

    我有一个带有 2 个网卡的 Linux 虚拟服务器 eth0