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

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.

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 LoadBalancer access from EKS worker nodes in provate subnets

I have an EKS cluster with worker nodes in private subnet. The worker nodes can access internet via the nat gateway. I have a Route53 hosted zone record routing traffic (alias) to a load balancer.
When I try to access the url (route53 record) from a pod within the EKS cluster, it times out. I tried allowing the worker nodes security group in the inbound rules of the load balancer security group but it does not work. Only thing that works is if I allow the public IP of the nat gateway in the inbound rules of the load balancer security group.
I am sure this setup is very common. My question is, is the solution of allowing the nat gateway public ip in the inbound rules of the LB SG the correct way or is there a better cleaner way to allow the access?
based on what you have described here, it seems like you have a internet facing load balancer and trying to access it from the pod. In this case, the traffic needs to go out to internet(through nat gateway) and come back to the load balancer, that is why it only works when you add the public IP of nat gateway to load balancer's SG.
Now, in terms of the solution, it depends on what you are trying to do here:
if you only need to consume the service inside the cluster, you can use DNS name created for that service inside the cluster. in this case the traffic will stay inside the cluster. you can read more here
if you need to make the service available to other clusters but same VPC, you can use a private load balancer and add the security group of worker nodes to the load balancer SG.
if the service needs to be exposed to internet, then your solution works but you have to open the SG of the public load balancer to all public IPs accessing the service.

AWS ALB Routing

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.

AWS NLB in public subnets with EC2 in private subnets

Has someone configured a NLB in the public subnets of your VPC to route traffic to EC2 instances that are in the private subnets?
When using an ELB, a good solution is to create a Security Group for the ELB and then create another SecurityGroup for the private EC2 Instances, allowing incoming traffic from that ELB Security Group, as explained here:
https://aws.amazon.com/premiumsupport/knowledge-center/public-load-balancer-private-ec2/
"You can also add a rule on the instance’s security group to allow traffic from the security group assigned to the load balancer. For example, if the security group on the load balancer is sg-1234567a, make the following changes on the security group associated with the private instances"
Since you cannot associate a Security Group to a NLB, how could you accomplish this with the same type of security?
Thanks!
Since you cannot associate a Security Group to a NLB, how could you
accomplish this with the same type of security?
The security aspect does not change.
NLB is a different beast, it not the same as classic Load Balancers. For Classic Load Balancers, from the point of view of your instances, traffic does appear to come from inside the VPC. From outside, traffic goes to a (random and mutating) list of IP addresses, resolved by the DNS record that AWS provides to you.
Network Load Balancers are completely different. From the point of view of your instances, they are completely invisible. If it is an external network load balancer, traffic appears to be coming from instances on the internet directly (even though this is an illusion). Therefore, if you want to talk to everyone on the internet, 0.0.0.0/0 is what you open it to.
This is, in fact, what the documentation says:
https://docs.aws.amazon.com/elasticloadbalancing/latest/network/target-group-register-targets.html#target-security-groups
Recommended Rules
Inbound Source Port Range Comment
Client IP addresses instance listener Allow traffic from clients on the instance listener port
VPC CIDR health check Allow traffic from the load balancer on the health check port
Client IP addresses is whatever your client IPs are. If they are on the open internet, 0.0.0.0/0 it is. Adding the NLB private IP address, as I saw in other responses, accomplishes nothing. Traffic is not coming from there, as far as the instances are concerned.
On the security angle, nothing changes. Since your instances are in private subnets, traffic cannot flow directly to them, as there is a NAT gateway in the middle. It can only flow from them to the internet (through NAT gateway, then internet gateway). Even if you specify all traffic is allowed from everywhere, traffic still won't come. It will have to come through another way. In your case, that way is the NLB, which has a fixed number of ports it listens to, and only sends traffic to the destination ports on the instances you specify.
If you are moving from classic Load Balancers to NLBs, move the security group rules from the Load Balancer to your instances. Or better yet, since you can have multiple security groups, just add the SG you currently have for the classic LB to the instances(and update any ASGs as needed). Your security posture will be exactly the same. With the added benefit that now your applications won't need things like proxy protocol to figure out where traffic is coming from, it is no longer obfuscated by the load balancer.
That is indeed true as per AWS Documentation :
Network Load Balancers do not have associated security groups.
Therefore, the security groups for your targets must use IP addresses
to allow traffic from the load balancer.
So If you do not want to grant access to the entire VPC CIDR, you can grant access to the private IP addresses used by the load balancer nodes. There is one IP address per load balancer subnet.
On NLB Tab of there is one Network Interface per Load Balancer from there :
On the Details tab for each network interface, copy the address from
Primary private IPv4 IP.
You can use this private IP Address at add it SG of EC2 Instances.
Please Refer to AWS Documentation
Tail your http access logs and you will see there is no changing of source IP address from the network load balancer which means you need to allow 0.0.0.0/0 on the endpoints security group if the internet needs access to your endpoint.
This is only ok if you use a private subnet so be careful if you have this server on a public subnet as this solution would not be advisable. In this case just use an application load balancer. You can still setup the same listener and configure a target group by instance as well. The application load balancer will update the source IP address to it's own private address if you tail the access logs. The advantage of this is you only need to allow https traffic to the app load balancer and then you can accept http for the target group if you like from the load balancer.

aws loadbalancer,routeable confusion

I'm putting the instances behind the aws loadbalancer, I have configured the routable and attached the IGW to it, created the loadbalancer and added this instance to the aws loadbalancer every things work well, the endpoint URL of the AWS loadbalancer able to load the HTTP pages
Now i have removed the IGW from the route table and tested it again, the AWS loadbalalncer endpoint URL not able to load the page, but the instace status shows in AWS loadbalancer as inService
Why the IGW is required when loadbalancer is configured over private subnet, it technically Mean it's a public subnet, which is blocking me to create a NAT inatance
A subnet without a default route pointing to the igw-xxxxxxxx Internet Gateway object is, by definition, a private subnet. If you remove the igw from a public subnet, you now have a private subnet.
Placing an Internet-facing load balancer (ELB) in such a private subnet is incorrect.
It sounds as though you are making a commonly-made -- but incorrect -- assumption that the ELB should be configured in the same subnets as the instances behind it. This is also incorrect.
Provision the ELB in public subnets, without regard to the subnets the instances behind it were placed in.
In summary:
Internet-facing ELB requires a public subnet for placement.
NAT instance requires a public subnet for placement.
The instances that use these services (NAT and ELB) belong in different -- private -- subnets, different subnets than the ELB and NAT instances.
ELB and NAT can be placed together in the same subnets, or separately, as long as the subnets are public (have the IGW as their default route) and are in the same availability zones.
I believe you cannot do anything without the IGW attached to the routing table where the subnet is attached to.
Another way to do this is to spin off a NAT instance(can be found in AWS marketplace) in the public subnet, add it to your private route table where your original instance is on (0.0.0.0/0 - instanceid) all the traffic will be routed through the NAT instance.
Here mainly we have to see two things, provided subnet for the elasticloadbalancer is public or private.
Every VPC should have one IGW to connect to the public, every trafic should go through the IGW only. If VPC connected to the IGW, IGW distribute internet to the all instance which are in that VPC, if route table changed to the particular rt, internet traffic can send to only that instance. Here in ELB instance is in service because both are in the same VPC and can communicate each other means checks the status. This IGW will work main role when we are using the NAT.
Always we provide ip range for the IGW or rt as 0.0.0.0/0, it represents as public.
The following link will explain more : http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Scenario2.html
This small explanation might be helpful for someone.
Let me cover your two questions
the AWS loadbalalncer endpoint URL not able to load the page, but the instace status shows in AWS loadbalancer as inService
This is the default behaviour of load balancer , since internally load balancer and your instance may be in the same VPC so they are able to communicate that is why loadbalancer is showing inService status.
Second question Why the IGW is required when loadbalancer is configured over private subnet, it technically Mean it's a public subnet, which is blocking me to create a NAT inatance
You need IGW if you want to access any resources especially EC2 , Loadbalancer from internet. however if you put your load balancer in private subnet it means IGW is not associated with the subnet having loadbalancer in it and hence this load balancer is not accessible outside your VPC that is reason that you were not able to load your page.
NAT instance is usually used when you want your private subnet instances should be able to initiate request over internet and has nothing to do with normal load balancing setup unless and untill you want dont want to install any updates from internet to your instance.
You are trying to access webpage publicly and removing the route entry IGW from the loadbalncer subnet.
The Subnet without IGW will become Private, Hence you can't access it.
First, a subnet with route table that route traffic via the internet gateway (IGW) is a public subnet. An IGW is required because the subnets created in AWS VPC are internal IPs and as internal IPs are not routable via the internet, traffic to and fro EC2 instances that belongs to an internal IP needs a way to complete these request. This is where an IGW comes into play. The IGW allows your EC2 instance to make outbound request to the internet and allows other user/client to make inbound request to your ec2 instance.
A public subnet are group of IPs (called subnets) in your VPC that allows internet traffic to and fro your ec2 instance. A subnet without an Internet gateway is a private subnet. As you already guess no traffic is allowed in or out.
That said, instances in VPC which are in Private subnet still need to initiate an outbound request to the internet to download software or perform update. In this case you have to create and attach a NAT gateway or NAT instance to the private subnet. NAT Gateway and NAT instance only allow outbound traffic to the internet but not the the other way round. In some cases you might want your production EC2 to be in the private subnet and ELB in public subnet for security reason.
ELB usually belong to the public subnet so it reachable from the internet as is your case as well.
TO answer some of your question - when you deleted the IGW from the route table, your ELB automatically becomes a private subnet as such your web page stops loading.
Also, you could still see the ec2 instance behind the ELB as InService even when you deleted the IGW because the ELB and EC2 instance can communicate via the internal IP as they are in same network or VPC.
The ELB needs a route to the internet in order to send you the response over internet.. As simple as that.
Configure your ELB in public subnet, regardless of where your instances are present.
Basically there are two types of load balancers.
1)Internal
2) External
Internal load balancers are those which are launched in a private subnet which will be accessible only internally by the instances on same vpc of the internal elb
External load balancers are which are accessible over the internet which should be launched in a subnet which has internet gateway attached to it and which has route table configured properly to route the requests.
If you attach an internet gateway to a subnet it becomes a public subnet.Also if you create a load-balancer which you need to be accessible from internet it should be a External load balancer and aws will not allow it launch in a private subnet.The instances are showing in service because its communicating internally using private ip-address.