1

We have a business requirement to channel all outgoing connections from multiple processing servers through a single IP address.

Our setup is as follows:

We have an nginx server which works as a load balancer for incoming http requests. We then have multiple web servers, which connect to processing servers which in turn connect to our customers databases.

Client --> Loadbalancer --> Web servers --> Process servers --> Database

Client <-- Loadbalancer <-- Web servers <-- Process servers <-- Database

Currently, we provide our customers a list of IP addresses that they should add to their database whitelist. However, as we scale this whitelist will become longer and our customers in turn would need to again update their whitelist respectively.

Desired Setup

To work around this, we would like to channel all outgoing connections through another nginx server, which would mask the IP addresses of our processing servers. In turn, we would now only have one IP address that our customers would whitelist.

Client --> Loadbalancer --> Web servers --> Process servers --> IP Masking --> Database

Client <-- Loadbalancer <-- Web servers <-- Process servers <-- IP Masking <-- Database

Is this possible solely with nginx, if so, what steps would we need to take to achieve this?

Glen
  • 113

2 Answers2

1

What you ask is possible with nginx starting from version 1.9.0. They added tcp (not http) proxy support. Starting from 1.9.13 they also added udp proxying. Read https://www.nginx.com/resources/admin-guide/tcp-load-balancing/#upstream and https://nginx.ru/en/docs/stream/ngx_stream_proxy_module.html

The tricky part would be differentiating incoming connections on (IP mask nginx) to decide to which database to connect. In HTTP proxy you can use host name. In tcp proxy you should either listen on different ports or different IP addresses. nginx.conf:

worker_processes  4;

error_log  /var/log/nginx/error.log;

events { worker_connections  1024; }
stream {
        server {
           listen 3307;
           proxy_pass client2.db.dev:3306;
           proxy_buffer_size 16k;
        }
        server {
           listen 3308;
           proxy_pass client1.db.dev:3306;
           proxy_buffer_size 16k;
        }
}
Nopius
  • 379
1

Another possible solution is using NAT. In this case masking server will be your router with configured network address translation. In this case you don't need to change customer database IP in node.js configuration, but you should change network, possibly routing configuration on all process servers and have one gateway with NAT configured

Nopius
  • 379