Reputation: 3622
I am trying to pass incoming traffic from amazon's Network Load Balancer to Application Load Balancer, I am using NLB since it has an Elastic IP attachment and I want it to serve as a proxy for the ALB. is that even possible?
Upvotes: 15
Views: 39672
Reputation: 179442
September 2021 Update: AWS has announced the native availability of ALB Target Groups for NLBs. This not only reduces the complexity of needing a Lambda-based workaround but also removes the limitation concerning client IP preservation. ALBs targeted in this fashion will provide the X-Forwarded-For
header containing the external IP address originally invoking the NLB.
It is possible, but it's slightly messy.
The problem is that Application Load Balancers can scale up, out, in, and/or down, and in each case the internal IP addresses of the balancers can change... but NLB requires static addresses for its targets.
So, at a low level, this means the NLB target group must be modified every time the IPs of the ALB change.
AWS has published an official solution for accomplishing this, using a Lambda function on a schedule to capture the addresses of the ALB and update the NLB configuration whenever the results change.
One notable limitation, here, is that this solution does not allow you to identify the client IP address. It is lost when the traffic goes through the NLB, because NLBs only preserve the source IP when the target is an instance (not an IP address) or when the target understands the Proxy protocol on the client side and the feature is enabled on the NLB, but ALB doesn't support such a configuration. With the setup shown at the link, above, the rightmost address in X-Forwarded-For
will be set by the ALB to the internal address of the NLB.
Upvotes: 22
Reputation: 944
As of 27th September 2021, AWS launched Application Load Balancer(ALB)-type target groups for Network Load Balancer (NLB). With this launch, you can register ALB as a target of NLB to forward traffic from NLB to ALB without needing to actively manage ALB IP address changes through Lambda.
Upvotes: 7
Reputation: 31
This is correct. Your app server behind the ALB (or the ALB itself) will always see the source IP as that of the NLB.
As a workaround that works for some use cases you can enforce HTTPS and configure access logs on the NLB. Then the access logs will have the original source IP.
In case this was not clear, what I mean is:
There are some additional complications if you want to accept plain HTTP and issue redirects to HTTPS. In that case you would have 2 listeners and 2 target groups, so you need to either spin up 2 copies of the Lambda to monitor (and eventually update) both target groups or you need to modify the Lambda code (which is what I did).
In addition IMO the code in that example is far from production ready (especially for scale - if you have many instances of this setup), so I had to practically rewrite it.
Relevant excerpts from CloudFormation template are below:
NLB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
IpAddressType: ipv4
Scheme: internet-facing
Type: network
LoadBalancerAttributes:
- Key: load_balancing.cross_zone.enabled
Value: 'true'
- Key: access_logs.s3.enabled
Value: 'true'
# make sure the bucket policy grants access - https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-access-logs.html
- Key: access_logs.s3.bucket
Value: !Ref S3BucketForNLBAccessLogs
- Key: access_logs.s3.prefix
Value: !Sub 'raw/${AppInstance}'
nlbHTTPSListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
Certificates:
- CertificateArn: !Ref FrontEndSSLCertificateArn
LoadBalancerArn: !Ref NLB
Port: 443
Protocol: TLS
DefaultActions:
- Type: 'forward'
TargetGroupArn: !Ref nlbHTTPSTargetGroup
Upvotes: 1