Allow TCP connections in Ruby
nginx’s stream module proxies TCP connections, and UDP sessions with
listen ... udp. In a server of the stream block,
mruby_stream runs a
Ruby script in the access phase of the stream module, once per session,
before nginx connects to the upstream. The script reads the addresses of
the session through Nginx::Stream::Connection, and closes the session by
setting stream_status to Nginx::Stream::ABORT.
The sample
Section titled “The sample”The script lets the session through only from the addresses of its list. nginx then proxies the connection to the upstream, here an HTTP server of the test configuration on port 18168. The request and the response are the bytes that the client sends and receives over the TCP connection.
upstream guide_tcp_backend { server 127.0.0.1:18168;}
server { listen 127.0.0.1:12364; mruby_stream build/nginx/html/guide_tcp.rb; proxy_pass guide_tcp_backend;}allowed = ["127.0.0.1", "::1"]c = Nginx::Stream::Connectionc.stream_status = Nginx::Stream::ABORT unless allowed.include?(c.remote_ip)GET /status HTTP/1.1Host: 127.0.0.1:12364Connection: closeHTTP/1.1 200 OKContent-Type: text/plain
the backend on port 18168 answeredOn every CI run, the case test/t/cases/guides.rb sends this request and compares the status line, the headers shown on this page and the whole body. The five files last changed on 2026-10-29 in commit 32219e53.
What to keep in mind
Section titled “What to keep in mind”- The stream module runs the script for UDP sessions too; the test suite sends TCP only.
- The script runs before nginx reads the client’s data, so it decides on the addresses and ports of the session, not on what the client sends.
- The
streamblock has its own mruby state, separate from that of thehttpblock, and its own directives for the code at startup (mruby_stream_init,mruby_stream_init_worker).