Nginx Proxy Udp Traffic
To set up an nginx proxy udp traffic rule, use the top-level stream block. This stream module routes raw datagrams straight to your backend servers. Many teams use this setup for DNS, syslog, or real-time voice apps. Still, engineers often open wide port ranges and share broad server keys to test things fast. When roles or firewall rules stay too broad, anyone on the network can send bad packets. How to set up nginx proxy udp traffic in your stream block Standard web routing only handles HTTP
Database Proxy (ProxySQL, PgBouncer) + East-West Traffic Security: the complete guide
Architecture patterns, implementation strategies, and security best practices. Delivered to your inbox.
To set up an nginx proxy udp traffic rule, use the top-level stream block. This stream module routes raw datagrams straight to your backend servers. Many teams use this setup for DNS, syslog, or real-time voice apps. Still, engineers often open wide port ranges and share broad server keys to test things fast. When roles or firewall rules stay too broad, anyone on the network can send bad packets.
How to set up nginx proxy udp traffic in your stream block
Standard web routing only handles HTTP requests at the top network layer. UDP works differently because it sends fast packets without a handshake. To handle these packets, your web server needs its stream module active. You place this stream section at the same top level as the web section.
Inside the stream section, you define an upstream group of backend apps. Each backend entry holds the internal IP address and the port number. Next, you create a server block that listens on a specific port. You must mark this listening port for UDP so it expects datagrams.
When a client sends a packet, the listener catches it right away. The server then forwards that packet to one of the upstream apps. If the backend app sends a reply, the server routes it back. You can also set a timeout rule so the server drops dead sessions fast. If your app sends one packet with no reply, you can set expected responses to zero. This saves memory and keeps your routing table clean under heavy load.
What native stream routing solves and what it leaves open
Native stream routing is great for spreading load across many backend nodes. It hides your internal server IP addresses from the public internet. You can also limit how many packets a single client IP can send. If one backend server goes down, the stream module stops sending packets there.
Still, this network setup only controls which IP addresses can reach the port. It also requires engineers to log in to the host to edit files. Once an engineer has host access or network reach, the native tool steps back. It cannot inspect what individual commands, queries, or payloads do in flight.
Database Proxy (ProxySQL, PgBouncer) + East-West Traffic Security: architecture patterns and best practices
Continue reading? Get the full guide.
Free. No spam. Unsubscribe anytime.
The stream module treats every packet as raw bytes with no user context. It does not know which team member sent a request or why. If an internal database or service uses UDP, IP rules are not enough. You still face risks when engineers share root keys to change routing rules. Without deeper checks, a bad command or leak of phone numbers can slip through.
Managing backend health and packet timeouts in production
Because UDP has no state, tracking server health takes extra care. The stream server does not know if a backend app crashed unless it checks. You can set up passive health checks to watch for connection errors. When a backend fails to reply in time, the server marks it down.
Teams can also run active health probes if their build supports them. These probes send small test packets to each backend node on a schedule. If a node fails the test, it leaves the pool until it recovers. You should also log stream events to a dedicated file for review. Because every packet can trigger a log entry, log only session summaries. Keeping timeouts short prevents old client maps from filling up your server RAM.
Check database and API queries on the wire
Identity tools, roles, and network rules decide who opens a session. Setup alone cannot check what each query does or mask sensitive values in a response once a session starts. When workflows touch Postgres, MySQL, SQL Server, MongoDB, ClickHouse, Kubernetes APIs, SSH, or internal HTTP APIs, hoop.dev runs beside those services as an open-source proxy, a sidecar for your Postgres or API. It inspects requests coming in and results going back on the wire.
Your login details and client tools stay as they are while hoop.dev guardrails refuse bad deletes or drops before they run. On responses, hoop.dev data masking rewrites matched sensitive values in memory. Furthermore, hoop.dev holds SOC 2 Type II, is MIT licensed, and writes every query and decision to an audit trail that generates evidence for HIPAA, GDPR, and PCI DSS. See the source on GitHub.
Frequently asked questions
Can I put UDP routing rules inside the standard HTTP block?
No, the HTTP block only understands web traffic built on TCP connections. You must place all UDP listeners inside a separate top-level stream block.
How does the server know when a UDP session is finished?
UDP has no close signal, so the server relies on a timeout timer. You can also set the expected response count so it closes right after the reply.
Does the stream module preserve the real client IP address?
By default, the backend sees the stream server IP as the packet source. You can turn on transparent mode or proxy protocol to pass the real client IP.
Related guides
In this post