AWS ALB Routing - amazon-web-services

I configured an internet facing ALB in AWS with two listeners (80 and 443) and the target groups are in private network (10.0.1.0/24). When http/https request are sent by ALB to the target group in 10.0.1.0 network, how the request is sent back to ALB? ALB has a public IP, and the target group do not have a route to internet. I can configure a NAT gateway and setup a route 0.0.0.0/0 to use the NAT gateway. But the web response will go all the way to internet and then comeback to ALB. Highly undesirable. I can't put these instances in public facing subnet either.
Can some one help how this can be done? I thought of VPC endpoint, and configured one with the load balancer (I used ELB, as I couldn't find ALB endpoint service). Now, the endpoint shows it has an IP in the 10.0.1.0 subnet. However, I don't know how this will work. Can someone suggest what's to be done. Thanks.

Not sure exactly what your question here is. But giving you a simple explanation of how AWS ELB works.
In both AWS Classic Load Balancers and Application Load Balancers, two connections are involved:
A connection between client (browser, etc) and ELB
A connection between ELB and backend target instances (webservers)
When creating an Internet facing ELB, you are given the option of selecting two subnets. These subnets should be public subnets which have a route to an Internet Gateway. The ELB will launch at least one ELB node in each of these subnets. Clients on the Internet will be able to connect to these ELB nodes using their public IPs through the IGW.
Once the ELB receives the request from the client, it forwards the request to its backend targets. This communication uses the PRIVATE IPs of the ELB nodes and the target instances. Therefore, even if the instances are in the private subnet, the ELB will still be able to forward requests to them because the connection is over private IPs which uses the 'local' route in the route tables. The response from the target then goes to the ELB over private IP, and is then forwarded to the client over public IP.
Client <--public IP--> ELB <--private IP--> Targets
The connection between client and ELB is over public IP, the connection between ELB and webservers is over private IPs which does not need a route to an IGW or NAT.
Don't worry about NAT Gateways for your private subnets. Just make sure the subnets you choose when creating the ELB are public and have a route to an internet gateway.

Related

AWS EC2 Internet access from behind Load Balancer

Using Terraform to setup a VPC with two EC2s in private subnets. The setup needs to SSH to the EC2s to install package updates from the Internet and install the application software. To do this there is an IGW and a NAT-GW in a public subnet. Both EC2s can access the Internet at this point as both private subnets are routing to the NAT-GW. Terraform and SSH to the private subnets is done via Client VPN.
One of the EC2s is going to host a web service so a Classic mode Load Balancer is added and configured to target the web server EC2. Using Classic mode because I can't find a way to make Terraform build Application mode LBs. The Load Balancer requires the instance to be using a subnet that routes to the IGW, so it is changed from routing to the NAT-GW, to the IGW. At this point, the Load Balancer comes online with the EC2 responding and public Internet can access the web service using the DNS supplied End Point for the LB.
But now the web server EC2 can no longer access the Internet itself. I can't curl google.com or get package updates.
I would like to find a way to let the EC2 access the Internet from behind the LB and not use CloudFront at this time.
I would like to keep the EC2 in a private subnet because a public subnet causes the EC2 to have a public IP address, and I don't want that.
Looking for a way to make LB work without switching subnets, as that would make the EC web service unavailable when doing updates.
Not wanting any iptables or firewalld tricks. I would really like an AWS solution that is disto agnostic.
A few points/clarifications about the problems you're facing:
Instances on a public subnet do not need a NAT Gateway. They can initiate outbound requests to the internet via IGW. NGW is for allowing outbound IPv4 connections from instances in private subnets.
The load balancer itself needs to be on a public subnet. The instances that the LB will route to do not. They can be in the same subnet or different subnets, public or private, as long as traffic is allowed through security groups.
You can create instances without a public IP, on a public subnet. However, they won't be able to receive or send traffic to the internet.
Terraform supports ALBs. The resource is aws_lb with load_balancer_type set to "application" (this is the default option).
That said, the public-private configuration you want is entirely possible.
Your ALB and NAT Gateway need to be on the public subnet, and EC2 instances on the private subnet.
The private subnet's route table needs to have a route to the NGW, to facilitate outbound connections.
EC2 instances' security group needs to allow traffic from the ALB's security group.
It sounds like you got steps 1 and 2 working, so the connection from ALB to EC2 is what you have to work on. See the documentation page here as well - https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Scenario2.html

AWS inbound trafic is blocked after routing the outbound trafic from the subnets through NAT gateway

What I am trying to achieve here is to simply have a static ip address for tasks running in my ecs services. I need this in order to be able to whitelist the ip address in the 3-d parties api.
What I did was: I created a new subnet, inside of this subnet I added a NAT gateway, then created new route table for this subnet that routes all of the trafic to the internet gateway
After that I updated the routing table that is used by existing subnets to route all trafic to the NAT gateway
It works great for the outbound trafic and updates the ip address of the request to the ip address of the Elastic IP associated with the NAT gateway.
But it also blocks all of the inbound trafic - canceling any request that try sending.
I am not sure why this is happening, the inbound request destination should fall into the local routing rule, please help.
The issue was with the Load Balancer subnet - since I modified the existing subnets route table to route trafic to the nat gateway, I accidentaly also made load balancers subnet private, assigning them the new subnets fixed the issue

How to route an API request go through a proxy

We have 10 instances which we deployed the app using the AWS ECS and ELB
Due to security reasons the API allows request only through specific IP whitelisted IP addresses.
So we are planning to pass the request through the proxy
How to route an API request go through a proxy
We are using nginx
Any specific way to route an API request go through a proxy will be helful
You won't need NGINX as a proxy for this use-case, I'd propose to consider looking into using AWS NAT Gateways. NAT Gateway is a highly available AWS managed service that makes it easy to connect to the Internet from instances within a private subnet in an Amazon Virtual Private Cloud (Amazon VPC). Its the perfect place to provide a static IP to all your subnet's outbound traffic.
In order to provide a NAT Gateway with static IP (Elastic IP) for your cluster's outbound traffic. This will allow your different tasks running inside your ECS cluster's private subnets to look like a single requesting entity from an outsider's POV (in your case, the 3rd party API is the outsider). To achieve this, you will have to:
Create 2 route tables (1 for private subnets, 1 for public subnets)
Internet gateway on the public subnet
Elastic IP address
Create a NAT Gateway and attach the elastic IP to it (This will be the IP whitelisted to the 3rd party API)
Ensure that all your tasks are running inside private subnets of the VPC
Add a rule in your route table for your private subnets that redirects outbound 0.0.0.0/0 to the NAT Gateway.
Add a rule in your route table for your public subnets that redirects outbound traffic 0.0.0.0/0 to the internet gateway.
You should consider using NAT Gateway instead. I am assuming you already would have all your containers in a VPC, so you can create a new NAT Gateway within this VPC itself.
You can refer to articles attached below to do this:
https://docs.aws.amazon.com/appstream2/latest/developerguide/add-nat-gateway-existing-vpc.html
https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html
Note: NAT Gateways have price associated with them.
If needed, you can use the elastic IP provided by NAT Gateways on your lambdas as well.

Multiple EC2 instance in public subnet should have same IP address for outgoing traffic

I have an application hosted on an EC2 instance in public subnet. To integrate this app with a partner we need to whitelist public IP address of the EC2 instance on partner's firewall.
I want to configure auto-scaling of the application in such a way that outgoing traffic for my application's EC2 instances should be from same single IP address that only needs to be whitelisted on partner's end.
For a private subnet, I know that a NAT Gateway is a solution.
But for instances in a Public Subnet, how this can be achieved? any solution/suggestions will be highly appreciated.
All traffic from the instances will need to be redirected to send via a single resource, such as a proxy or a Gateway.
The simplest solution is as you stated -- configure the subnet to route all Internet-bound traffic to a NAT Gateway or a NAT Instance. All traffic from that instance will then come from a single IP address.
However, configuring the subnet in this way will mean that it is no longer a "public subnet", since a public subnet has Internet-bound traffic sent through an Internet Gateway rather than a NAT. So, it's actually the same as using a private subnet as you suggested in your question.
The only way to do it in a Public Subnet would be to specifically configure your apps to send requests via a proxy server, which would act in a similar way to a NAT Gateway/Instance.

Can we make EC2 instances in the web tier as Private?

We have Typical 3 tier architecture having Web, App and DB.
Can we make EC2 instances in the web tier as Private? and allow incoming traffic only through ALB?
AFAIK we can apply an SG only allowing connections from the SG of the ALB. But What if our Private EC2 instance has to return response back to the client? How it'll be routed through ALB as ALB is mostly used for managing incoming traffic.
Also for outgoing traffic can we configure something like Private EC2 instance -> ALB -> Internet? If yes then how? So, is there any way for private EC2 instances to communicate to internet without assigning them public IP?
But What if our Private EC2 instance has to return response back to the client? How it'll be routed through ALB as ALB is mostly used for managing incoming traffic.
You don't have to do anything special, assuming your ALB and instances are correctly set. Any request coming to ALB, will be able to return to the client event if instances are in private subnet without any internet connectivity.
However, your instance won't be able to initiate internet connections by themselves. So if the instances don't need internet to operate, you don't need NAT. Otherwise, it is required.
Keeping your instances in a private subnet is best practice, even for the web layer.
For inbound traffic you would add a load balancer into your public subnets then allow HTTP/HTTPS ingress on the webs security group only from the load balancer. You can either do this through adding the subnet ranges into the web servers security group, or reference the security group the load balancer has assigned to it instead.
For outbound internet traffic in a private subnet you will need to create either a NAT Gateway or NAT instance within a public subnet, and then add a route for 0.0.0.0/0 for the private subnet to route traffic to the NAT. Additionally if you want IPv6 traffic you would create an egress only internet gateway with a route of ::/0.