Search code examples
amazon-ecsaws-fargatenlb

TCP Based Service behind Network Load Balancer : How to pull Client IP?


Background

I have spun up an SMTP Listener built on ECS Fargate that is listerning to incoming TCP messages behind and AWS Network Load Balancer. I am able to send messages from my local workstation to the NLB which is perfectly pushing the messages to the TCP Service Fargate Task. I am trying to debug an issue wherein an external provider that is trying to do the exact thing - but is not able to successfully send a message. One of the first things I am attempting while debugging this is trying to pull the Client IP on the ECS Fargate Service

What I have tried so far

I have googled many different websites in an attempt to pull the client IP that is calling the Network Load Balancer which is then calling my ECS Service. No matter what I try on the ECS Service, I am unable to pull the Originating Client IP. The ONLY IP I am seeing is the Network Load Balancers Elastic IP

Based on one of the google resource, I have tried displaying ALL the headers when either my Workstation call to the NLB vs External Provider call to the NLB is printing on the ECS Task. But when I print the remote IP - I keep getting the NLB's IP

                socket = serverSocket.accept();

            // Set the socket to timeout after 100 seconds
            socket.setSoTimeout(defaultDisconnectionTimeout);

            // Prepare the input and output streams.
            out = new PrintWriter(socket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            
            InetAddress remoteAddress = socket.getInetAddress();
            clientIp = remoteAddress.getHostAddress();

Additionally

During googling, one of the SO resources mentioned an while an ALB attaches an X-Forwarded-For header which is the preserved Client IP, an NLB cannot do this.

The Ask

The essential ask here is, what can I do to pull the actual Client IP in my ECS Fargate Task. I need to prove that the External Application is at least connecting to my NLB and Fargate Task similar to my Local connection by outputting the remote Client IP.


Solution

  • Network Load Balancing works on lower OSI level(s) than Application Load Balancer and cannot alter contents of TCP streams, only their network packet headers.

    Behind the scenes, NLB creates a stateful packet filter that binds the TCP packets to their respective connections and performs Network Address Translation (NAT).

    NLB supports a feature known as Client IP Preservation. If it's enabled, NLB leaves the originating source address and port intact. When it's off, it replaces then with its own address (acts as SNAT).

    Client IP Preservation reveals the original IP address of the client that initiated the connection, but might complicate routing on the target group side.