通过 MAC 地址验证 TCP 连接是否来自同一台计算机
请不要批评该解决方案。这不是我的设计,是的,它很糟糕。
在运行 Linux 并使用 C 的计算机上,我们需要验证与进程建立的 TCP 连接是否来自同一台计算机。通过 IP 地址执行此操作是有问题的,因为操作系统生成两个 IP 地址,而进程只知道一个。无论如何,通过IP地址验证有点差劲。
我们希望通过将“远程”MAC 地址与本地 MAC 地址进行比较来进行验证。我们已经获得本地 MAC 地址。我需要知道的是如何获取“远程”MAC 地址。它位于形成连接时发送的数据包中(以及所有后续连接中)。我们如何将它拖出以太网层呢?
在有人再说一遍之前,我知道如果远程主机不在同一子网/LAN 上,您将无法获取远程主机的 MAC 地址。没关系。大概我们会得到类似 00:00:00:00:00:00 的东西,因为它与本地 MAC 地址不同,所以会有所不同 - 这正是我们想要的。
--
那么,总而言之,我们有一个 TCP 连接套接字 fd,我们收到了一个数据包,那么我们如何找到远程主机的 MAC 地址,即数据包标头中的 MAC 地址?
Please don't criticise the solution. It's not my design and yes, it sucks.
On a computer running Linux, and using C, we need to verify that a TCP connection made to a process is from the same machine. Doing it by IP address is problematic since the OS is generating two IP addresses and the process only knows one. Anyway, verifying by IP address is a bit poor.
We want to do the verification by comparing the "remote" MAC address to the local MAC address. We already get the local MAC address. All I need to know is how to get the "remote" MAC address. It's in the packet that gets sent when forming the connection (and in all subsequent ones too). How do we drag it out of the ethernet layer?
Before anyone says this again, I KNOW you cannot get the MAC address of the remote host if it's not on the same subnet/LAN. That's fine. Presumably we'll get something like 00:00:00:00:00:00 and since that is different to the local MAC address it will be different - just what we want.
--
So, to summarise, we have a TCP connection socket fd, we've received a data packet, how do we then find the MAC address of the remote host, the MAC address that was in the packet's header?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果我理解正确的话,您并不是试图区分远程计算机,而是使用源 MAC 和目标 MAC 匹配从计算机发送到自身的流量的想法,以便仅允许本地流量。
这看起来相当迂回,并且已经被指出,是不安全的。
更好的想法可能是让 TCP 客户端仅侦听环回接口 (127.0.0.1),而不侦听 INADDR_ANY。或者更进一步,使用 unix 域套接字而不是 TCP 套接字(当今 X 服务器使用的一种常用方法,以防止远程连接的可能性)
If I understand correctly, you are not trying to tell remote machines apart, but to use the idea that the source and destination MAC would match on traffic sent from a machine to itself in order to allow only local traffic.
This seems rather roundabout, and has been pointed out, insecure.
A somewhat better idea might be to have the TCP client listen only on the loopback interface (127.0.0.1) and not on INADDR_ANY. Or go a step further and use a unix-domain socket instead of a TCP one (a common method used by X servers today to prevent the possibility of remote connections)
实时同子网 TCP 连接的 MAC 地址几乎肯定会在 ARP 缓存中。
在 Linux 上,您可以通过查看
/proc/net/arp
来检查 ARP 缓存。这是它在我的 Ubuntu 机器上的样子:如果您不愿意解析伪文件,您可能可以使用一些可调用的 API 来获取相同的数据。
The MAC address of a live same-subnet TCP connection will almost certainly be in the ARP cache.
On Linux, you could examine the ARP cache by looking in
/proc/net/arp
. Here is what it looks like on my Ubuntu box:There's probably some callable API that you could use to get to the same data if you're averse to parsing the pseudo-file.
如何配置防火墙(内部或外部)来阻止或 MAC 过滤相关端口上的外部流量?
How about configuring a firewall (internal or external) to block or MAC-filter external traffic on the port in question?
环回连接(无论是通过环回接口还是其他接口)不会通过任何以太网设备进行路由,因此没有与其关联的 MAC 地址。
我建议您只使用
getsockname
和getpeername
来获取本地和远程 IP 地址并比较它们是否相等。这无需事先了解系统配置的 IP 地址即可工作。此外,如果您想与 IPv4/v6 无关,可以使用
getnameinfo
和NI_NUMERIC
标志将两个地址转换为数字字符串表示形式和strcmp
> 他们。A loopback connection (whether it's over the loopback interface or some other interface) it not routed over any ethernet device and therefore does not have a MAC address associated with it.
I suggest you just use
getsockname
andgetpeername
to get the local and remote IP address and compare that they are equal. That will work without any a priori knowledge of the configured IP addresses of your system.Further, if you want to be IPv4/v6 agnostic, you could use
getnameinfo
with theNI_NUMERIC
flag to convert both addresses to numeric string representations andstrcmp
them.