I have a setup like this.
Application Load Balancer(internet facing) LB1 with entry in Route 53 as loadbalancer1.com
LB1 is in security group sg1 which has inbound rule to accept all Https requests.
LB1 has target group attached which has an EC2 instance instance1 which belongs to security group sg2
sg2 has inbound rule which specifies traffic can only come from sg1
I have another EC2 instance instance2 in Security Group sg3. This instance wants to access instance1. It does this by calling the load balancer loadbalancer1.com(on port 443 i.e Https)
This setup works. Now I want to make an improvement. Since loadbalancer1.com will only be accessed from instance2. I want to change inbound rules of security group sg1 to accept traffic only from security group sg3. If I do this, loadbalancer1.com is no more reachable from instance2.
Any idea why?
It's a very good question. TL;DR: it only works for internal traffic that doesn't leave the VPC.
Here is what's going on in more detail:
When the instance2 accesses the internet-facing load balancer, the traffic first leaves your VPC and goes to the public internet. Then the traffic reaches the ELB through some network routings, and the ELB forwards the traffic to the instance1.
When the traffic leaves the AWS VPC and re-enters it, the source SG metadata associated with the traffic is "gone". From the SG of the ELB point of view, it only knows that the traffic is originated from the public IP address of instance2.
According to the Security group rules documentation:
When you specify a security group as the source or destination for a rule, the rule affects all instances that are associated with the security group. Incoming traffic is allowed based on the private IP addresses of the instances that are associated with the source security group (and not the public IP or Elastic IP addresses).
Related
I am running my tasks (in public subnets) using AWS Fargate, and an Internet-facing NLB distributes the traffic to all the available tasks through a target group. I have a security group added to the service that only allows the the NLB's IP. We are planning to use cloudflare as a reverse proxy for all the traffic coming to this NLB. How do I whitelist the cloudflare IPs so that no one else can reach this NLB?
If you're using a Network Load Balancer, update the security groups
for your target instances because Network Load Balancers don't have
associated security groups.
If your target type is an IP, add a rule to your security group to
allow traffic from your load balancer's IP address to the target IP
address.
If your target type is an instance, add a rule to your
security group to allow traffic from your load balancer's IP address
and clients to the target IP address.
I think it's not possible to add a security group to an NLB. Ref: https://aws.amazon.com/premiumsupport/knowledge-center/security-group-load-balancer/
If I add the cloudflare IPs to the security group of the service then wouldn't it prevent the load balancers from making a connection, or is the IP of the actual client forwarded till here?
You would need to enable Client IP preservation in the Target Group of the Network Load Balancer. Then in the security group of your target(s) (your ECS service, EC2 instance, etc..) you would allow those specific IPs.
I am working fine with my current ELB, but for security reasons i want to restrict connections by allowing just instances in the same security group, so i created an aditional security group just for mange only the ELB, i have no problem while i allow 0.0.0.0/0 to the 443 port, but when i remove the rule i am losing the connection, if i allow the public ip of the instance it will work, but i have several instances so it is not an option, i also tried allowing private CIDR (10.0.0.0/24) of the instances and it does not work, and i also tried allowing same security groups with not success
Thanks in advance
The setup should be:
A security group on the Amazon EC2 instances running your app (SG-App) that permits incoming traffic from the appropriate locations to access the app
A security group on the Load Balancer (SG-LB) that permits inbound connections on port 443 from SG-App
That is, SG-App is permitting inbound connections from any instances associated with SG-App. This is much better than allowing connections "from the same security group" because the instances need different settings to the ELB.
When the instances resolve the DNS Name associated with the Load Balancer, it should resolve to a private IP address (10.0). You can test this by connecting to one of the instances and trying to ping/lookup the ELB DNS Name and seeing what IP address it is using.
I have recently added a ALB for 2 instances in EC2.
I want to make the ALB and EC2 instances to be private so I added the security group for each services.
What I did is that I added the IP Addresses in HTTPS of the EC2 instances in the ALB sg. vice versa in the EC2 sg.
In Route 53. I made a subdomain to link in the DNS name of ALB.
I tried to test it first using sg that is public and it works fine and can access the EC2 application.
But after I tried to set the sg for both the ALB and EC2.
When I test it, It can't access it.
Where did I go wrong?
A security group can allow traffic from a CIDR range of IP addresses, or from another Security Group. Thus, you should configure the following Security Groups:
ALB-SG: Allow HTTP/S from 0.0.0.0/0 (if you want it open to the world). Associate it with the ALB.
App-SG: Allow HTTP from ALB-SG. Associate it with your EC2 instances (or Auto Scaling group Launch Configuration).
The Application Security Group (App-SG) is thus permitting incoming traffic from the Load Balancer. Or, more specifically, from any resource that is associated with ALB-SG.
Route 53 should have a CNAME record pointing your desired domain name to the DNS Name of the Load Balancer.
I have a Load Balancer and Auto-Scaling Group. The Load Balancer sends traffic to my Auto-Scaling Group. I have two instances: Instance 7000 (which is listening on port 7000 and is part of the auto-scaling group and gets its traffic from the load balancer) and Instance 8545 (which is listening on port 8545 and is simply a single instance that is not part of the Load Balancer or the Auto-Scaling Group).
I have a load balancer security group ("LB-SG") and a security group for Instance 8545 ("App-SG"). I want Instance 8545 to only allow traffic from Instances that are part of the Load Balancer / Auto-Scaling Group. So I included "LB-SG" as an inbound rule for "App-SG" on port 8545 but it is not working. However, if I simply include the IP address for Instance 7000 on port 8545 as an inbound rule in "LB-SG" it works perfectly. But that doesn't solve my issue because if more instances get added by the Auto-Scaling Group or IP address changes then it won't work.
Edit: reworded for clarity
Your requirements are a little unclear, but here is the general use-case...
If you wish an instance to accept traffic from a Load Balancer, then:
Create a Security Group for your Load Balancer ("LB-SG")
Create a Security Group for your instances ("App-SG")
In App-SG, permit inbound traffic on the desired port from LB-SG
That is, the App-SG rule specifically references LB-SG by its unique name (sg-abcd1234).
Result: Every instance associated with App-SG will permit inbound traffic that is coming from the Load Balancer.
Similarly, if you want a specific instance (Instance-A) to accept traffic from another instance (Instance-B), create a different security group for each instance and add a rule to the Instance-A security group to permit inbound traffic on a given port from the Instance-B security group.
There is no need to use IP addresses.
2nd attempt...
You should create three security groups:
LB-SG for the Load Balancer
Allow inbound 80/443
App-SG for the instances in the Auto Scaling group
Allow inbound 7000 from LB-SG
Extra-SG for the 8545 instance (I didn't know what to call it!)
Allow inbound 8545 from App-SG
Once again, there is no need to reference specific IP addresses.
Side-note: You said "allow traffic from Instances that are part of the Load Balancer / Auto-Scaling Group" -- instances are in the Auto Scaling group, but there are no instances in the Load Balancer. Therefore, I have assumed that the 8545 instance only receives traffic from the App-SG (7000) instances.
Update: Make sure the instances are communicating via Private IP addresses.
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.