I'm trying to create a security group that allows all inbound traffic originating from within my VPC. I thought I could simply specify my CIDR block, but that doesn't seem to work and requests fail unless I create a rule which allows inbound traffic from anywhere.
What's the right way to allow inbound traffic from any EC2 instance within the same VPC?
It will work just fine.
For example, if your VPC is setup with a CIDR range of 10.0.0.0/16, you can create a Security Group with an Inbound rule and a source of 10.0.0.0/16.
That will allow inbound access from any Elastic Network Interface (eg instance, load balancer, RDS instance) within the VPC.
Make sure that you access the target instance via its Internal IP Address. Using its Public IP Address will fail the Security Group check since it is coming from outside the allowed CIDR range.
Related
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).
2 questions on NLB in AWS
I have a requirement to use NLB in front of the EC2 which runs MYSQL. This EC2 is in private network. I just want to allow NLB to be accessed by some particular internet IP. If it's ALB, I can use security group to do this. However, without security group in NLB, how can I achieve this?
In this setup, I connect to NLB from my PC and reach to that MYSQL EC2. To make it success, I find that I have to allow 0.0.0.0/0 in the incoming rule of the EC2 security group instead of just putting my PC IP. I thought my PC IP should be brought to EC2 directly through NLB. Is it not true? I dont want to allow 0.0.0.0/0 in EC2 security group. Is there any better way?
Thanks!
The security group evaluations are performed by the instances security groups for the Network Load Balancer. You would need to add the IP addresses you would like to communicate with the NLB to your instances, as long as your instance is in a private subnet this will prevent any client directly interacting with the host.
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.
More information is available in the Register targets with your target group documentation.
The only way to block the traffic in your case is to have the IPs to which you want to allow access in the EC2 SG.
However you need to account for the fact that there is a difference on the IP address from which the request will come from and thus will be evaluated from the EC2 SG based on how you have configured the target group of the NLB and more specifically on whether you have set up the target type to be instance or ip, as there is a difference in the NLB behaviour.
If the target type is set to instance, the NLB will pass the traffic to your instance as is, and the EC2 SG will see your locap PC public IP address, and if there is a rule to allow it you will be able to connect
If the target type is set to ip, the NLB is doing an NAT, and the EC2 SG will actually see the private IP of the NLB as a source IP for the incoming traffic.
Take a look at the Source IP Preservation in the NLB Target Group documentation.
There is a similar discussion in this question.
I have a service running inside a VPC that is exposed through nginx (also on a server within the VPC), since there are http(s) configurations needed which nginx handles.
I want to allow that service to be reached only by servers in the same VPC - right now that's done through hardcoding ips with:
allow <elastic ip>;
allow <specific ip>;
allow <specific ip>;
...
deny all;
The Elastic IP (which is at vpc scope) seems to allow only instances which don't have their own public ip. I've also tried allowing the vpc and subnet CIDR blocks, which I'm assuming don't help since they are internal.
How can I get a general public CIDR for a private VPC? Is it possible? Am I going about this the wrong way?
It sounds like you should use a Security Group.
A security group is like a firewall around every individual Amazon EC2 instance. It controls what ports are accessible from what CIDR range.
Let's say you have an EC2 instance running a service on port 80, and you only want it accessible to other instances in the VPC. You would simply configure the security group to only allow Inbound connections on port 80 from the CIDR range of the VPC. This would use the private IP addresses, since that's where the traffic is coming from.
Let's go one step better... let's say you only want specific instances to be able to communicate. You would:
Create a Security Group on the instances permitted to access the web server (let's call it App-SG)
Create a Security Group on the instance with the web server (let's call it Web-SG)
Configured Web-SG to allow Inbound connections on port 80 from App-SG
That is, the security group specifically references another security group. This will allow inbound connections from any EC2 instance that has the App-SG associated with it.
None of the above requires an Elastic IP address. Only public-facing resource require a public IP address. It is quite common to only expose a Load Balancer and to keep everything else 'private'.
Question
Is there a way to make sure accesses are coming only from a specific NLB? Under the current NLB limitations, I am not sure if there is a way.
Limitations
AWS Network Load Balancer (NLB) does not have Security Group (SG), hence cannot use SG to verify the source is NLB.
NLB (instance ID target) preserves the source IP address of the external client, hence cannot use source IP to verify the source is NLB.
References
Network Load Balancers don't have Security Groups
Source IP Preservation
If you specify targets using an instance ID, the source IP addresses of the clients are preserved and provided to your applications.
One way you could possibly do this is by provisioning the NLB and its EC2 in a separate private subnet reserved just for them, and ensuring your routing rules do not allow other subnets in the VPC to route to the segregated private subnet.
As in the AWS NLB Document - Target Security Groups, cannot identify a NLB and make sure the access is only from the NLB if target type is instance. Need to use the client IP address which accesses the NLB.
Limits
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.
You cannot allow traffic from clients to targets through the load balancer using the security groups for the clients in the security groups for the targets. Use the client CIDR blocks in the target security groups instead.
Place the EC2 machines in private subnets, if they need to access internet set the route table for destination 0.0.0.0/0 to nat gateway id. So EC2 machines can access the internet via nat but no one can access your ec2 instances from outside of the vpc.
Then you can set inbound rules for your EC2 instances even for 0.0.0.0/0. Again no one (outside of the vpc) can directly access your EC2 instances since they are private subnet. If you set a NLB and attach EC2 instances on it, only connections (according to your NLB listeners rule) are allowed to instances.
You can put EC2 on the NAT subnet, and then point to this EC2 through NLB. This way, although your EC2 security group is set to 0.0.0.0/0, only NLB can access it.
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.