BSD / POSIX套接字API recvfrom()
调用(通过<sys/socket.h>
头文件提供给C或C ++程序员)提供源地址&#34; out&#34;参数struct sockaddr *src_addr
,用于存储发送接收数据报的远程服务器的IP地址。
对于将 UDP数据报发送到某个远程端点,然后接收响应(例如,DNS解析器)的任何应用程序,它被认为是必要的安全预防措施,以确保始终确保任何收到的数据报来自与最后发送的数据报相同的IP地址(即前一次sendto
呼叫中使用的地址?)
换句话说,如果我们调用sendto
并将数据报发送到某个地址,我们是否应始终确保相应的recvfrom
来自相同的地址?
考虑到如果远程服务器位于防火墙后面,或者是某个具有多个IP地址的分布式系统的一部分,响应数据报可能合法地来自不同的IP,这似乎是不可行的。
但是,如果我们不确认收到的数据报来自相同的 IP地址,而不是上一次sendto
电话的地址,那么我们要做什么?一些攻击者拦截数据报,然后将恶意数据报发送给客户端?
答案 0 :(得分:2)
您如何知道收到的数据包是回复?通常使用收到的数据包中的源地址和端口完成。
但是,无法验证UDP数据包中的源地址。发件人可以放置他们想要的任何源地址。因此,如果您信任互联网上浮动的所有数据包,那么检查就足够了,这显然是不可行的。
所以你需要一些额外的机制:随机cookie,序列号等等。
答案 1 :(得分:2)
对于将UDP数据报发送到某个远程端点,然后接收响应(例如,DNS解析器)的任何应用程序,
您可以使用随机出站端口号。这就是DNS can mitigate spoofing attacks。
的方式它是否被认为是必要的安全预防措施,以始终确保任何收到的数据报来自与上次发送的数据报相同的IP地址(即先前发送给调用的地址?)
换句话说,如果我们调用sendto并将数据报发送到某个地址,我们是否应始终确保相应的recvfrom调用来自同一地址?
不仅是为了安全,还为了功能。如果您有多个出站连接,则需要知道哪些UDP回复对应于每个连接。这可以通过IP地址&amp;远程端口组合。
考虑到回应,似乎这可能不太可行 如果数据报可能合法地来自不同的IP 远程服务器位于防火墙后面,或者是某个分布式系统的一部分 有多个IP地址。
远程系统应通过与其接收的相同接口发送回复。如果它没有,它将是非标准的&#34;并且无法使用您的应用程序或其他需要接收和回复UDP数据包的人。
但是,如果我们不验证收到的数据报来自同一个IP 地址作为上次发送到呼叫的地址,要防止的是什么 一些攻击者拦截数据报,然后发送恶意攻击 数据报给客户?
无。如果攻击者可以MITM UDP连接,那么他们可以截取并更改他们想要的任何内容。他们只能向您的服务发送带有欺骗IP地址的UDP数据包。
如果您需要保持数据包的完整性和机密性,则需要实施某种加密。例如。如果您需要支持数据报,请查看DTLS。
答案 2 :(得分:0)
某些NAT支持UDP打孔,它也完全符合您提到的IP验证,因此没有必要在应用程序中执行此操作。
对于自定义协议,您可能希望在有效负载中实现某种序列号,以进一步提高安全级别。
答案 3 :(得分:0)
在一般情况下,任意接收的数据报不是对先前请求的响应。你必须愚弄,例如通过connect(),
确保您只处理作为回复的回复。