29

I have nginx running on my server, listening port 80 and 433. I know nginx has a number ways of port forwarding that allows me to forward request like: http://myserver:80/subdir1 to some address like: http://myserver:8888.

My question is it possible to configure nginx so that i can forward NON-http request (just those plain TCP connection) to some other port? It's very easy to test if it's a http request because the first bytes will be either "GET" or "POST". Here's the example.

The client connected to nginx . The client send:

a. HTTP get request: "GET / HTTP 1.1": some rule for HTTP

b. Any bytes that can't be recognized as HTTP header: forward it to some other port, say, 888, 999, etc.

Is it technically possible? Or would you suggest a way to do this?

tactoth
  • 897
  • 1
  • 12
  • 24

3 Answers3

67

It is possible since nginx 1.9.0:

http://nginx.org/en/docs/stream/ngx_stream_core_module.html

Something along these lines (this goes on top level of nginx.conf):

stream {
    upstream backend {
        server backend1.example.com:12345;
    }

    server {
        listen 12345;
        proxy_pass backend;
    }
}
Slava V
  • 16,686
  • 14
  • 60
  • 63
  • You can also add this code into any /etc/nginx/modules-enabled/*.conf (or similar) file, since this would be included. When using Docker, make sure to copy the /etc/nginx/nginx.conf file to the container even if you don't intend to make changes there, this solved the problem for me – Torben E Jul 15 '21 at 15:18
  • A strong caveat for DNS-based backend names here, is that, by default, NGINX will cache name lookup resolution internally forever, or until NGINX is restarted. So if the IP of `backend1.example.com` ever changes, in this config, the proxy will break until the nginx service is restarted. – Dale C. Anderson May 10 '23 at 23:55
4

This is technically possible for sure.

You can modify open source tcp proxies like nginx module called nginx_tcp_proxy_module or HAproxy.

Or you can write a nginx module similar to above one to do this for you.

Zimbabao
  • 8,150
  • 3
  • 29
  • 36
0

if nginx remote proxying with HTTP, your client could use the HTTP CONNECT command, then it connects with the remote port and forwards all data as "raw" (or at least I think so).

rogerdpack
  • 62,887
  • 36
  • 269
  • 388