TCP routing with Nginx - nginx

I am trying to do routing using Nginx via TCP layer.
I have multiple different databases where I need to perform routing from API to them base on rule or the request that is received by the API
+++++ +++++++++++++ +++++++--------> mysqlServer(managerDb)
+API+ ----->+MySQLClient+---->+Nginx+--------> mysqlServer(customerDb)
+++++ +++++++++++++ +++++++--------> mysqlServer(........Db)
I already did the typical one with load balancing but I want it to be routed based on the request
thanks

Nginx mainly works at layer 7 (application), what you need is something at layer 4 (transport) for this HAProxy could better help to achieve what you need since it can do both HTTP and TCP (db load balancing with HAProxy example)
Probably by using Nginx plus you could also do the same, check this article regarding how to do layer 4 load balancing.
Also look at TCP and UDP load balancing with requires the latest open source Nginx built with the --with-stream configuration flag.
Here an article explaining how to do load balancing with HAProxy

Related

Docker, nginx and several sites on one server

I have server with nginx and one working app. I want to add several apps to this servers. I would like to assimilate a few things for myself.
What is the difference between load balancer and reverse proxy?
In which situations should I use the first, and in which situations should I use the second?
What should I use if my sites are static, and what if not static?
And additionally it would be a big plus to hear about containers in the context of several sites for nginx
Differences between load balancer and reverse proxy
A reverse proxy accepts a request from a client, forwards it to a server that can fulfill it, and returns the server’s response to the client.
A load balancer distributes incoming client requests among a group of servers, in each case returning the response from the selected server to the appropriate client.
Taken from nginx docs
TL;DR :
Reverse proxying is about : routing requests to the correct server using the domain name
Load balancing is about : distributing load to multiple instances
What should I use if my sites are static, and what if not static?
You can combine an HTTP reverse proxy + load balancing with both static and non static web apps, so it depends.
And additionally it would be a big plus to hear about containers in the context of several sites for nginx
I recommend one nginx container per app / site + a dynamic reverse proxy, traefik in particular (http://traefik.io)
You need a reverse proxy to route the incoming traffic to the proper application taking into account the content of the original request (and rules that you may define).
When the target application(s) is determined, you will need to load balance them in order to distribute the amount of work across them.
Both tasks can be done by software like classic nginx, apache, haproxy, etc or by those that are designed for the microservices world, like fabio, traefik and others.

UDP load balancing using customised balancing method with session id inside UDP body

I am trying to set up a load balancing solution which is able to load balance UDP traffic. In my case, I have several different servers which send UDP package to a load-balancer. Inside each UDP package body, there is a MSG-ID field. Ideally, I want to load-balance UDP traffic to a set of servers based on that MSG-ID. In other words, two UDP packages with same MSG-ID should be sent to the same server (because i want to assemble two UDP packages with same MSG-ID to form a complete package for further processing). But if it's not possible, then a solution based on source/sender IP might be sufficient.
Haproxy doesn't support UDP so I am checking nginx. But seems that only nginx-plus (not free solution) allows you to do load-balance based on ip_hash method?
I wish to know:
What is best open-source solution to help me handle load-balance based on custom MSG-ID inside UDP body.
Does nginx (free/open-source) version support at least UDP load-balance based on ip_hash method.
Is there anyway I can spoof the UDP source/sender IP. Basically, if I have server (such as server A) which receive UDP package from multiple server (server D) and forward it to a set of server (server B, C); I want the server B, C receiving package with IP indicated as server D, not A.
What is drawback of writing a custom layer which read UDP then form a TCP package and then maintain a TCP connection with load balancer to forward that newly-formed TCP package. In that case, both nginx or haproxy can be used.
Thanks.
nginx does support UDP load balancing in both open source nginx(since v1.19.13) and NGINX Plus. Read this post from nginx.com
And nginx provides UDP load-balance based on ip_hash out of box,check the docs
So I think the answer to question No.2 is yes.
Also mentioned in the docs here, nginx upstream module provide hash algorithm on a custom key, which in your case could be MSG-ID, but i don't know how you can get MSG-ID out from you UDP datagram and i guess it won't be easy. I tried to search for a while but got no luck. If you found a solution, hope you can share under this question.
You would ordinarily use proxy_bind $remote_addr transparent; in your server {} context. Note that you need a (very) recent nginx with upstream / udp loadbalancing support for this to work.

Can Nginx work as Direct Server Return load balancer?

Is there a way to configure Nginx to work as a Direct Server Return (DSR) load balancer similar to this:
http://blog.haproxy.com/2011/07/29/layer-4-load-balancing-direct-server-return-mode/
To do this you need transparent parameter of Nginx proxy_bind directive which is available on Nginx Plus R10 or Nginx 1.11.2+. Also you need to configure routing table and firewall for IP transparency and tc for direct server response. A working example is fully described here:
https://www.nginx.com/blog/ip-transparency-direct-server-return-nginx-plus-transparent-proxy/
This is not possible with either HAProxy and nginx because they act as reverse proxies, above the OSI Layer 4.
For Load-balancing in DSR mode, you want to use LVS, at kernel layer, which works at OSI layer 3 and 4, and analyze packets per packets.
Baptiste

HAProxy vs. Nginx

I was looking at using HAProxy and Nginx for load balancing, and I had some questions:
Should I use JUST HAProxy over Nginx for the proxy server?
Is there any reason to have HAProxy and Nginx installed on the same proxy server?
Haproxy is a "load balancer" it doesn't know to serve files or dynamic content. nginx is a web server capable of many interesting things. if you only need to load balance + HA some third web server then haproxy is enough. if you need to implement some static content or some logic in routing of the requests before terminating them on a third server then you may need nginx.
The reason you can see haproxy+nginx on the same host is that it allows you to bring down single nginx instances while haproxy continues to serve requests from other hosts. Imagine having a RR DNS using A records:
myapp.com IN A 1.1.1.1
myapp.com IN A 1.1.1.2
Where 1.1.1.1 and 1.1.1.2 are two hosts with haproxy+nginx configured to load balance between them. Now for some reason your 1.1.1.1's nginx goes down. The browsers that come to 1.1.1.1 are still being served by haproxy on it which in turn gets data from 1.1.1.2's nginx.
HAProxy is definitely the better, more fully featured loadbalancer (compared to the free nginx, not nginx plus (but one could argue that as well).
One thing that HAProxy sadly still can't do is generic UDP connections. So we used HAProxy and nginx on our logging lbs. But HAProxy released support for syslog/udp in 2.3 so we are about to change that. :)
We use HAProxy together with nginx. There are a number of reasons.
Nginx can do everything (more or less) but you don't want your load balancer serving web pages. Some error in config (which might have nothing to do with load balancing) and your entire setup comes to a screeching halt. Imagine that you have a Nodejs app, a Dotnet Core app, static files served by Nginx, and a php app. You just make some mistake and your 4 apps come to a standstill. You have lost your redundancy too if you have multiple instances of each app.
Even if you say that Nginx will only do the load balancing, Nginx doesn't support PROXY Protocol which is problematic if you forward to other servers who are also not serving the pages.
In addition there is something to be said for doing one thing and doing it well. Nginx is the master toolbox today. It does almost everything. Your load balancer is supposed to be the most stable part of your setup. Wouldn't you prefer to use something that was built just for load balancing?
If you use varnish then HAProxy works well with it and in fact they are made by the same people.
If you want an added level of balance then you can also use dns as a load balancer with multiple HAPROXY instances. Dns is not meant for this perse but you will always have some weak link. Your load balancer can crash too even if it's managed by your cloud provider. Most web browsers today will try other servers if there is more than one in your dns entry so it's like a load balancer. Your dns should be very reliable thus increasing your uptime.
We use 2 haproxy instances with 2 varnish instances with two dns entries.

split HTTP and TCP-only (non-HTTP) traffic

I have web application that runs on Tomcat (and gets HTTP requests) and some other backend standalone application that gets only TCP. For some reasons, I can use outside only port 8080. So, I need to get all TCP requests (from outside) to port 8080 and forward HTTP ones to web application on Tomcat and all TCP pure requests (that are not HTTP) - to standalone application. Internal forwarding could be done to any port, e.g. 8181 on Tomcat and 8282 on standalone application. Is it possible to setup such configuration? How it could be done?
Thanks in advance.
TCP and HTTP are protocols in different networking stack layer. If you want to use some application to filter HTTP requests, your application should deal with Application-Layer information, not Network-Layer(like TCP/UDP).
I don't see how this can be possible generally. You could look packet-by-packet, but the middle of an http body can be arbitary so you can't just look at the data of each packet
If any particular client will send you either http or general TCP but not both, can you do this by source-IP address? Do you know the addresses of either the servers that will send you http requests or the ones that will send you TCP requests?
If you don't know the source IPs, you could heuristically look at the first packet from some previously unknown IP and see if it looks like http, then tag that address as containing http traffic.
What is the content/format ot the TCP communication? Is there any pattern you can detect in that?
Y
Perhaps you could do something like this using iptables + L7 filter. Of course this will only work if you run Linux on your box. Also I don't know how recently l7 filter project has been updated.
Java servlet technology is not limited to Http. The servlet interface lets you read in the incoming input stream via ServletRequest.getInputStream(). So you can create an implementation of Servlet interface and map it in web.xml and you are all set to receive any TCP traffic.
Once you have the read the input stream to sniff the content you will want to forward HTTP requests to an HttpServlet. To do this you will need to make sure that the input stream you pass on is positioned at the very beginning of the input.
EDIT: On reading your question once again, I noticed that you don't plan to expose the Tomcat directly on external port as I originally thought. If you are willing to make the tomcat listen on the external port, you can try the approach described above

Resources