I have 2 Elastic Beanstalk environments, "api-server" & "website". Both have a capacity of 1-4 EC2 instances and a load balancer. The load balancer and the instances have both public IP addresses. I want to connect from the "website" to the "api-server" but i can't get it to work without making the "api-server" public. The "api-server" should not be public.
I am connected with a VPN that is allowed HTTP connections to both EB environments and i can confirm that both apps respond.
Both EB environments have 2 security groups, one for the load balancer called "Load Balancer Security Group" and one for the instances called "VPC Security Group". All load balancer and VPC security groups have an outbound rule allowing all traffic on all protocols.
Since i want to connect from the "website" to any of the instances of "api-server" i want to connect to the load balancer and not to any of the instances directly. So i should add an inbound rule to the load balancer group of the "api-server" that allows traffic from the "website"'s instances.
The instances all have the "VPC Security Group" but adding the rule did not give the "website" instances access to the "api-server". I also tried adding the load balancer security group without success. And i also tried the type "All traffic".
I also tried to connect to the "api-server" over different URLs like the load balancer but also no connection possible.
When i add a rule that allows traffic to everywhere, eg. source type "Anywhere-IPv4", i can access the "api-server" from the website. But as i said i don't want the "api-server" public it should be accessible only by the "website".
What also works is adding a rule with the IP address of the current "website" instance, but since they change with deployment of a new version and they are sometimes more or less instances (autoscaled from 1 to 4) its not an option.
So how does it work?
I searched everywhere in the docs but i can't find anything i didn't already tried. What am i missing? This surely shouldn't be so hard?
I appreciate every help!
Edit: Everything is in the same VPC.
So how does it work?
Referencing security groups (SGs) works only withing VPC or peered VPCs. Since you are accessing your second EB over the internet, not within same VPC, you can't reference SGs.
You have to whitelist public IP addresses of your instances. The best way is to put them in private subnet and use NAT gateway. The NAT gives you a single public static IP which you can use in your ingress rule of the second EB environment.
Related
We have an ELB Application load balancer that allows HTTP/HTTPS traffic from a customer managed prefix containing a list of our developer IP addresses. The load balancer forwards incoming requests to specific EC2 instances based on the hostname.
These instances need to be able to talk to each other via HTTP/HTTPS. For example, the www.domain.com needs to talk to api.domain.com. I have put the load balancer and instances in the same security group and allowed all traffic between instances in the same security group (setting the security group id as the source for the rule).
I understand that by using hostnames that point to the load balancer, the request will travel out of the VPC and come back in - the security group rule only applies to the private IP addresses of the instances, right?
I have another customer managed prefix list containing the public IP addresses of each server, but that seems a little manual. Is there a better way to restrict HTTP/HTTPS access to the public IP addresses of all servers in our AWS account/specific security groups?
Is there a private hostname I could use for the load balancer, so that the request from the ec2 instance stays within the VPC?
I have some issue with my ELB.
We are develop some web app and we need to close public access to our app from internet. So about test environment:
example.com -> Application load balancer with route53 -> EC2 in private subnet.
In security group for testing i have opened 0.0.0.0/0 for 80 and 443 (port doesn't matter). My app response and everything works fine.
But i don't need 0.0.0.0/0, so i have changed it to my office IP.
And my app stop working, because IP from Load balancer in 2 availability zones are not allowed in security group of load balancer. It's very strange.. This IP is not static and i have no guaranties that this IP don't change in 5 min. So, what we have, I ALB doesn't allow his traffic via his IP?
The EC2 instances do not need to be in the same security group as the load balancer. The load balancer should be in a security group that permits ports 80/443 from the Internet (or your office IP). The EC2 instances should be in a security group that permits traffic from the load balancer’s security group.
Hm, the reason was that NAT IP with IPs ELB cant access to ALB. Added IP ELB and NAT gateway to secutiry group. Fixed. Thanks for help
If you don't want your application to be open to the public Internet, you can set up a VPN in your VPC or you can use SSH port forwarding to access your application in the private subnet. The linked articles are just examples - there are many ways to do it - but both are common approaches. If you choose either of these options, your ALB does not need to be in a public subnet. It can also be in a private subnet since your application doesn't need to be publicly accessible.
These are the most secure and robust options available to you. Alternatively, if you can determine the IP address range which your ISP assigns, you could open a wider network in your ALB security group but still not allow the full internet. E.g. if your ISP always assigns an address in the range of 1.2.3.0-254, you could add a rule to allow 1.2.3.0/24. Of course anyone else using your ISP that is assigned one of these addresses would also be able to access your application. Alternatively, you could develop a script that keeps updating your ALB security group with a new dynamic address.
I have a few elastic beanstalk applications on the same VPC (which can also be reduced to one application), and I'd like them to be accessible both via one IP address (both inbound and outbound traffic), and via their own URL. I've seen that this can be done via NAT, but I haven't found documentation on whether this is all traffic (in both directions) and if it can be done alongside the original endpoints. Another question is whether there is a better way to do this.
NAT is used to provide access to internet for instances in private subnets. In this case all instances in the subnet will have the same external IP. But you won't be able to access your private instances using that IP, it's only for outbound traffic.
In your case I'd go with a ELB. Following the best practices, keep your instances with running applications in private subnets and:
Have an external facing ELB in public subnets (you'll need at least 2 public subnets in different AZs).
Create a Target Group and add your instances with running apps to it.
Assign the Target Group to the listener on your ELB.
Configure the security groups on ELB and app instances to allow the traffic on the port the applications are serving (usually it's 8080).
As a result you'll have your instances accessible by the ELB URL. If you want to have a pretty URL, you can configure it in Route 53 and resolve it to the ELB URL.
Its not possible by using aws provided NAT cluster but can be achieved by hosting a box with both Load balancer and NAT running in the same instance with EIP, map your domain with that IP for incoming traffic, for outgoing traffic in the route table of private app subnet you configure the NAT as target for all the 0.0.0.0/0 route, But it is not the recommended approach since the front facing instance becomes SPOF.
The recommended way is using ELB as a front facing and NAT cluster as outgoing for high HA.
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.
We are trying to use Elastic Load Balancing in AWS with auto-scaling so we can scale in and out as needed.
Our application consists of several smaller applications, they are all on the same subnet and the same VPC.
We want to put our ELB between one of our apps and the rest.
Problem is we want the load balancer to be working both internally between different apps using an API and also internet-facing because our application still has some usage that should be done externally and not through the API.
I've read this question but I could not figure out exactly how to do it from there, it does not really specify any steps or maybe I did understand it very well.
Can we have an ELB that is both internal and external?
For the record, I can only access this network through a VPN.
It is not possible to for an Elastic Load Balancer to have both a public IP address and a private IP address. It is one or the other, but not both.
If you want your ELB to have a private IP address, then it cannot listen to requests from the internet.
If your ELB is public-facing, you can still call to it from your internal EC2 instances using the public endpoint. However, there are some caveats that goes with this:
The traffic will exit your VPC and re-enter it. It will not be direct instance-to-ELB connection that a private IP address will afford you.
You also cannot use security groups in your security group rules.
There are 3 alternative scenarios:
Duplicate the ELB and EC2 instances, one dedicated to private traffic, one dedicated to public traffic.
Have 2 ELBs (one public, one private) that share the same back-end EC2 instances.
Don't use an ELB for either private or public traffic, and instead use an Elastic IP address (if public) or a private IP address (if private) on a single EC2 instance.
I disagree with #MattHouser answer. Actually, in a VPC, your ELB have all its internal interfaces listed in Network Interfaces with Public IP AND Primary private IP.
I've tested the private IP of my public ELB and it's working exactly like the external one.
The problem is : theses IPs are not listed anywhere in a up to date manner like on a private ELB DNS. So you have to do it by yourself.
I've made a little POC script on this, with an internal Route53 hosted zone : https://gist.github.com/darylounet/3c6253c60b7dc52da927b80a0ae8d428
I made a Lambda function that checks which private IPs are set to the loadbalancer and will update Route53 record when it changes: https://github.com/Bramzor/lambda-sync-private-elb-ips
Using this function, you can easily make use of the ELB for private traffic. I personally use it to connect multiple regions to each other over a VPC inter-region peering without needing an additional ELB.
The standard AWS solution would be to have an extra internal ELB for this.
Looks like #DaryL has an interesting workaround, but it could fail for 5 minutes if the DNS is not updated. Also there is no way to have a separate security group for the internal IPs since they share the ENI and security of the external IP of the ELB.
I faced the same challenge and I can confirm the best solution so far is to have two different ALBs, one internet-facing and the other internal. You can attach both ALBs to a single AutoScaling Group so you can access the same cluster.
Make sure the networking options (Subnets, security groups) of both ALBs are the same in order for both to access the same cluster instances. Autoscaling and Launch Configuration works seamlessly with both ALBs attached to the same AutoSacling Group. This is also working with ALBs created from ElasticBeanstalk environments.