2
votes

The connection-oriented semantics of TCP indicate that a socket can only connect to one endpoint at a time. But with UDP, a single open socket can send/receive datagrams to/from any number of endpoints. My understanding is that most operating systems (at least Linux and Windows) will assign an ephemeral port to a UDP socket automatically as soon as sendto is called.

My question is: when using UDP, what are the best practices, in terms of security, when writing applications that may send datagrams to multiple remote endpoints at a time? Should the socket "close" and reopen each before sending datagrams to a different remote endpoint?

Consider, for example, a DNS server that needs to resolve a query. A DNS server may need to send datagrams to many different remote endpoints when resolving a hostname recursively - i.e. first, it must send/receive datagrams from some root server, then from a TLD server, and so on. Should a DNS server in this case reuse the same socket/ephemeral port when sending/receiving datagrams to all these different servers? Or is it better to close/reopen a socket before sending to a different server? Are there any security implications at play here?

2

2 Answers

4
votes

Depends on what you mean by "secure" and how far you are willing to protect your data from eavesdropping, corruption, attacks, hijacking, etc... A different socket port per session usually doesn't hurt - makes debugging easier if you ever needed for fire up wireshark to figure out what's going on.

I look at it like this. It makes no difference if you use the same port for all socket sessions or a different port. It doesn't even matter if you use TCP vs. UDP. The bottom line is that a determined hacker can eavesdrop and/or hijack the messages being exchanged if he wanted to. How far are you willing to go to prevent these types of attacks?

If you are just trying to avoid casual data corruption only from stray sessions that happened upon choosing a previously used port, then a different port may be helpful. But a transaction id in every message to identify the session is always better. Validate the incoming message based on transaction id, not the address it arrived from.

Want to all the way with end to end encryption, integrity checking, and authentication? Then DTLS is probably a good starting point.

0
votes

But with UDP, a single open socket can send/receive datagrams to/from any number of endpoints.

Correct.

My understanding is that most operating systems (at least Linux and Windows) will assign an ephemeral port to a UDP socket automatically as soon as sendto() is called.

Only if the socket isn't already bound. In the case of a UDP server, it already is.

My question is: when using UDP, what are the best practices, in terms of security, when writing applications that may send datagrams to multiple remote endpoints at a time? Should the socket "close" and reopen each before sending datagrams to a different remote endpoint?

It shouldn't close and open at all. It should only have one socket that stays open.

Should a DNS server in this case reuse the same socket/ephemeral port when sending/receiving datagrams to all these different servers?

A DNS server doesn't have an ephemeral port. It sends the response back via the same socket, and port, that received the request.

Or is it better to close/reopen a socket before sending to a different server?

The same goes for any other UDP server. There is no need for any UDP server to use an ephemeral port.

You seem to have a completely wrong model of how a UDP server works. It isn't like TCP where you have a socket per connection. There are no connections and there is no need for more than one UDP socket in a UDP server.