Proxying UDP: Preserve proxy port during DTLS handshake

SebK nginx-forum at forum.nginx.org
Wed Apr 12 19:53:43 UTC 2017


Hello everyone,

TL;DR: When proxying UDP packets through nginx, is there a way for nginx to
preserve its initial source port for subsequent packets? This is to be used
during a DTLS handshake.

Outlined version: This issue arose when proxying UDP packets, more
specifically establishing an DTLS connection for CoAP message exchange. I
came across two different threads with similar subjects
(https://forum.nginx.org/read.php?2,273251,273251#msg-273251 and
https://forum.nginx.org/read.php?2,271957,271957#msg-271957) from which I
can guess that it is not (yet) supported out of the box.

Hence, I am only using nginx to proxy the CoAP's UDP packets between client
and server. This works for unencrypted CoAP, but not for CoAP over DTLS
because the handshake fails. This is because nginx uses (or may use?)
different source ports for every udp packet it forwards. An easy way to
examine this issue is to proxy a UDP netcat connection with nginx. First
message from client to server is received but subsequent messages can only
be sent from server to client because netcat "locks in" on the client port
from which it received the first message. The port is constant on the client
side, but nginx may use different ports when proxying the packets. 

I managed to get the DTLS connection to work by using the proxy_bind
directive of the proxy stream module with the values
"127.0.0.1:$remote_port" respectively "127.0.0.1:$server_port". It works,
but I am not happy with either of it. Reason against
"127.0.0.1:$server_port": Two client requests may overlap and there would be
no way for the server to tell them apart. Reason against
"127.0.0.1:$remote_port": Even tough unlikely, it may happen that two
clients decide to use the same port from their dynamic port range. Also in
this case there would be no way of telling them both apart. 

I know about the "proxy_bind address [transparent]" option of the proxy
module, but I would consider using this the "nuclear option" since,
according to the documentation, it requires the worker processes to run with
superuser rights and reconfigure the kernel routing table.

So my conclusive question is: Does nginx provide a way to preserve its
chosen dynamic port when forwarding udp packets?

Regards,
Sebastian

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,273576,273576#msg-273576



More information about the nginx mailing list