我正在尝试实施一种方法来防止从我的笔记本进行网络扫描。我想要的一件事是允许对特定主机(例如我的网关)发出 arp 请求。
我使用 arptables 添加了一些规则,它们似乎有效(一开始)
arptables -A OUTPUT -d 192.168.1.30 -j DROP
arptables -A INPUT -s 192.168.1.30 -j DROP
这实际上是阻止对该主机的 arp 请求。如果我运行:
tcpdump -n port not 22 and host 192.168.1.38 (target host)
并运行:
arp -d 192.168.1.30; ping -c 1 192.168.1.30; arp -n (notebook)
tcpdump 显示目标上没有传入数据包,笔记本上显示 arp -n (不完整)
但是,如果我在笔记本上运行 nmap -sS 192.168.1.30,我会进入目标主机:
22:21:12.548519 ARP, Request who-has 192.168.1.30 tell 192.168.1.38, length 46
22:21:12.548655 ARP, Reply 192.168.1.30 is-at xx:xx:xx:xx:xx:xx, length 28
22:21:12.728499 ARP, Request who-has 192.168.1.30 tell 192.168.1.38, length 46
22:21:12.728538 ARP, Reply 192.168.1.30 is-at xx:xx:xx:xx:xx:xx, length 28
但是笔记本上的arp -n仍然显示不完整,但是nmap检测到主机。
我也尝试过使用nftables和ebtables没有成功。
如何阻止nmap发送arp请求并找到主机?
答案1
我将完成 OP 的设置:地址 192.168.1.38/24eth0
和网关(实际上不需要)192.168.1.1。如果设置使用 Wifi 而不是实际的以太网,则无需额外努力,第一种方法(桥接)将不可用(如果是接入点,则可能很容易;如果不是 AP,则非常困难甚至不可能)。
nmap
使用一个数据包套接字(typeAF_PACKET
) 来处理 ARP 请求,而不是使用内核的网络堆栈处理 ARP 缓存和解析。arping
行为类似(并将用于简化示例)。tcpdump
还用于AF_PACKET
捕获。相比之下,即使是其他特殊工具,例如
ping
,当它们仅仅使用AF_INET, SOCK_DGRAM, IPPROTO_IP
或AF_INET, SOCK_RAW, IPPROTO_ICMP
而不是时AF_PACKET
,也会被过滤iptables
。
他们的方法可以使用strace -e trace=%network
(如根用户)对这些命令。
如中所介绍的Netfilter 和通用网络中的数据包流:
AF_PACKET
发生在大多数 Netfilter 子系统之前(入口处)或之后(出口处),ebtables(桥),arp表或者iptables以及它们的等价物nftables表:防火墙被绕过。tcpdump
(或nmap
) 能够读取传入数据包,因为它在防火墙之前捕获它们,nmap
能够发送 ARP 数据包,因为它在防火墙之后注入它们。
因此,通过标准设置,任何由其生成的数据包nmap
或任何其他工具使用的数据包AF_PACKET
都无法使用arptables
(或iptables
) 进行过滤。
有一些方法可以克服这个问题。
老方法:使用桥ebtables
它是桥接的,因此在大多数情况下与 Wifi 不兼容。
为了ebtables(或者nftables使用bridge
家庭)这通常不是问题:当无法过滤的 ARP 或 IP 数据包转换为以太网帧时,它会重新进入另一层的网络堆栈。现在它位于网络堆栈内,并将受到那里所有设施的影响,包括使用ebtables
(或nftables和bridge
家人一起)。因此,使用网桥可以克服防火墙绕过问题。
创建一个网桥,设置eth0
为网桥端口并移动地址和路由br0
(当然,这应该通过重新配置正在使用的适当网络工具来完成和/或由于暂时失去连接而不要远程完成):
ip link add name br0 up type bridge
ip link set dev eth0 master br0
ip addr flush dev eth0
ip addr add 192.168.1.38/24 brd + dev br0
ip route add default via 192.168.1.1 # not needed for this problem
然后将arptables
规则转化为ebtables
规则。他们仍然会使用INPUT
和 ,OUTPUT
因为这些是路由堆栈和(由于缺乏更好的术语)桥接堆栈之间的链。
ebtables -A OUTPUT -p ARP --arp-ip-dst 192.168.1.30 -j DROP
ebtables -A INPUT -p ARP --arp-ip-src 192.168.1.30 -j DROP
大致相当于一个nftables规则集可以是(加载nft -f somerulefile.nft
):
add table bridge t # for idempotence
delete table bridge t # for idempotence
table bridge t {
chain out {
type filter hook output priority 0; policy accept;
arp daddr ip 192.168.1.30 drop
}
chain in {
type filter hook input priority 0; policy accept;
arp saddr ip 192.168.1.30 drop
}
}
(可能应该添加额外的过滤来限制受影响的接口。)
制定这些规则之一后,同时运行两个tcpdump
,一对一,br0
如下eth0
所示:
tcpdump -l -n -e -s0 -i br0 arp &
tcpdump -l -n -e -s0 -i eth0 arp &
将显示发射br0
,但不再显示eth0
:注入时无法阻止的 ARP 数据包已被桥接层有效阻止。如果删除规则,两个接口都将显示流量。同样,对于远程反向测试:数据包将被捕获eth0
但不会到达br0
:被阻止。
新方法:nftables和netdev
家庭和egress
钩子
⚠:需要Linux内核 >= 5.16它提供了egress
钩子,并且nftables
>= 1.0.1使用它。ingress
从内核 4.2 开始可用。
由于不涉及网桥,因此无需更改网络布局,这对于以太网或 Wifi 来说都是一样的。
特别是这个犯罪呈现用例:
netfilter:引入出口钩子
支持在出口处使用netfilter对数据包进行分类,以满足用户需求,例如:
- 容器的出站安全策略 (Laura)
- 过滤和破坏负载均衡器上的节点内直接服务器返回 (DSR) 流量 (Laura)
- 过滤通过 AF_PACKET 传入的本地生成的流量,例如本地 ARP 流量为集群目的或 DHCP 而生成
(Laura;AF_PACKET 管道包含在后续提交中)[...]
nftablesnetdev
提供对系列中在接口级别工作的其他 Netfilter 挂钩(在前面的示意图中未描述)的访问:ingress
和egress
。这些钩子靠近AF_PACKET
入口和出口(保持模糊,因为有关入口/出口和捕获/注入的实现细节有一些微妙之处):egress
能够影响在 处注入的数据包AF_PACKET
。
族表中的基链netdev
必须链接到接口。使用 OP 的初始设置,先前的nftables规则集可以使用netdev
家族的语法重写,如下所示:
add table netdev t # for idempotence
delete table netdev t # for idempotence
table netdev t {
chain out {
type filter hook egress device eth0 priority 0; policy accept;
arp daddr ip 192.168.1.30 drop
}
chain in {
type filter hook ingress device eth0 priority 0; policy accept;
arp saddr ip 192.168.1.30 drop
}
}
tcpdump
不会在出口处捕获任何注入的 ARP:它们之前已被丢弃。入口处的捕获仍然首先发生:依赖于AF_PACKET
(以 开头tcpdump
)的工具仍然可以捕获它们(但防火墙会立即丢弃它们)。
其他:还有tc
能够过滤AF_PACKET
套接字的工具(如果该工具不使用该选项)PACKET_QDISC_BYPASS
)。tc
比较难处理。这是一个我的回答 Q/A(在我写它的时候,我的理解和整体解释不太准确)有一个没有过滤器的简单示例。