UDP套接字:recvfrom和接收地址

时间:2015-03-20 01:52:35

标签: c++ c security udp

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电话的地址,那么我们要做什么?一些攻击者拦截数据报,然后将恶意数据报发送给客户端?

4 个答案:

答案 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(),确保您只处理作为回复的回复。