Communication between AWS VPC instances via public IP - amazon-web-services

We have two AWS instances (Instance A and Instance B) which are running in the same VPC. There is an internet facing service on Instance A which is restricted (via security group) to a subset of IP addresses. Instance A has a DNS entry so the service can be accessed via someservice.example.org.
When trying to access the service from Instance B it works correctly if we used the VPC internal IP address however we cannot seem to get the correct security group configuration to allow this instance access via the public DNS.
We have added the 'default' VPC security group to Instance A but we're still unable to access this service directly. We also have the same problem trying to configure access to Instance A from other VPCs.
I know that we can create a private DNS for the VPC which could solve the problem when we are in the same VPC but this doesn't get around the problem when running in another VPC.

This sounds like a DNS resolution issue. If you are using Route53 for DNS the easiest way to fix this is to create a private Route53 DNS zone for your VPC and add something like:
CNAME 'someservice.example.org' that points to the instance's internal IP address.
Note that you really want to use the internal private IP address whenever possible. It will keep the network traffic within your VPC, which will be much faster and more secure. It may also be cheaper for you, at least if the instances are also within the same availability zone. You can read more about that on the EC2 pricing page in the Data Transfer section.
Also note that you can't open up the security group to allow only instances from your VPC/security group to access something via the public IP. This is because the traffic hitting the public IP is seen as coming "from the internet", not from your VPC. You would have to grant access to the servers via their public IP addresses instead of their security groups.
You mention also using a second VPC, but that would be a separate problem that could be addressed via VPC Peering.

Related

EC2 open port for only private IP address

My Linux based EC2 instances have both public and private IPs. I am hosting two servers on it:
S3 server, which will be accessible over both internet/private network and
NFS server, which should be accessed only via private IPs/internal network.
I want to open NFS port in the Security Group but only allow the access over the EC2 instances's private IP. I don't think this can be achieved by using only security groups as when the request reaches EC2 node, the Internet Gateway has already replaced the public IP with the private IP of the EC2 instance and the instance is not even aware that there is an extra public IP associated with it.
Instead what can be done is to choose the sources and selectively allow NFS access only to the VPCs and on-premises network (in case there is a VPN connectivity) but that would also mean that every time a new VPC is created OR a new VPN endpoint is established, someone has to modify the Security Group to accommodate new IP addresses.
What I ideally need is a way to apply port and IP based rules on the Internet Gateway which is currently not available/exported. Looking for alternatives.
The simplest method would be to add an Inbound rule to the Security Group where the Source is the CIDR range of the VPC.
For example, if your VPC is 172.31.0.0/16, then use this as the Source in the security group. It would permit any inbound connection from that IP address range.

How can a lambda inside a private subnet access EC2 in a public subnet?

I've created an EC2 instance inside a public subnet (so that I can access it from my home network) and I have created some Lambda's inside the private subnets of my VPC.
My 1st lambda can freely access the internet (through a NAT Gateway) and do its job. Which is to fetch a file from the internet and upload it to S3, once per day.
My 2nd lambda is supposed to retrieve this file from S3 (which it does without issue) read the file & then upload the data to MySQL running on the EC2 instance. It is unable to connect to the Database (using either the EC2's public or private IP's) and the Cloudwatch logs show that the session times out, making me think this is a networking issue.
I have a 3rd lambda that will also need to interact with the EC2/DB instance.
My security group allows for all incoming traffic from my home network IP, the NAT gateway & the VPC IP range. All outbound traffic is allowed.
I appreciate its not usual to have an EC2/DB set up this way, in a public subnet, but its my preference to interact it with it this way from home using Sequel Pro.
However, is my set up even possible? Eg can my private subnet lambdas interact with a public subnet ec2 instance? if so, does anybody have any ideas how I can make this happen?
It appears that your situation is:
An Amazon EC2 instance running in a public subnet, with MySQL
The EC2 instance has a Security Group allowing all incoming traffic from your home network IP, the NAT gateway and the VPC IP range
An AWS Lambda function connected to a private subnet of the same VPC
A NAT Gateway allowing private subnets to connect to the Internet
The Lambda function is unable to connect with the MySQL database running on the EC2 instance
The normal security configuration for this scenario would be:
A Security Group on the Lambda function (Lambda-SG) that allows all Outbound access (no Inbound required)
A Security Group on the EC2 instance (EC2-SG) that allows inbound access from Lambda-SG on port 3306, plus whatever inbound permissions you want for accessing your instance via SSH, etc.
Given that your Security Group includes "the VPC IP range", this should be sufficient to permit inbound access.
The Lambda function should reference the EC2 instance via its private IP address to keep traffic within the VPC. By default, all subnets within a VPC can communicate with each other unless the Network ACLs have been modified (and they should generally be left at default values).
This means that the only remaining explanation would be that the MySQL database is not accepting traffic from the VPC IP range. (I'm not a MySQL person, but I know that PostgreSQL requires incoming IP ranges to be defined, so this might be true for MySQL too.)
To diagnose what might be happening in your network, I recommend:
Launch another Amazon EC2 instance in the public subnet
Connect to the new instance and try to connect to the MySQL database via the private IP address
If that works, repeat the process but from an EC2 instance in the private subnet. To use this you will need to connect to the 'public' EC2 instance, and from there connect to the 'private' EC2 instance. Then, try and connect to MySQL from that private instance.
These steps will progressively let you identify where the network problem might lie. Let us know what you find!

How to ensure that Private DNS - address does not change in AWS EC2?

in the application I manage, in several places, there are hard-coded references to the Private DNS of an EC2. The code will refer to: ip-(some private IP here).eu-west-1.compute.internal.
If I stop and start an instance the private IP will change, and I assume also that the Private DNS URL will also change.
When this happens the code crashes. Is there any way I can avoid this change? Is there some way to create a Private DNS so it does not change even when an instance is stopped and started again?
The private DNS and the IP shouldn't change.
However one feasible option is to launch your instances within a VPC and assign a Route 53 Private Hosted Zone that resolves your instances.
The bridge between VPC and Route53 is a DHCP options in the VPC.

EC2 instance unable to reach itself via hostname

I have created an EC2 instance behind an ELB and the hostname is
mysubdomain.domain.com
The instance is reachable via the internet from my local workstation (have opened all connections from My IP --> to the instance in the security group it belongs to);
However, when performing
curl mysubdomain.domain.com
from within the instance, it times out;
Do I need to assign a public (I assume I want it to be elastic so that I don't have to change it every now and then in my security group inbound rules) and add an allow rule in my security group (that the instance belongs to) from that specific IP?
Is there another way to go about it, given that I have reached the limit of Elastic IPs?
For an Amazon EC2 instance to access the Internet, it must either be:
In a public subnet with a public IP address, or
In a private subnet with a NAT Gateway or similar NAT service
By default, security groups allow all outbound traffic, so you will not need to modify the security groups.
Even if you have reached the limit of your Elastic IP addresses, you can launch the EC2 instance with a Public IP address via Auto-assign Public IP — this is different to an Elastic IP address, in that it is assigned when the instance is Started and might change when the instance is Stopped/Started. However, it will work perfectly fine to obtain Internet access.
If an instance is behind a load balancer, there is no reason to want to reach that instance directly from the Internet. Thus, there is no need for an Elastic IP address. In fact, in best-practice architectures, the instances should be in a Private Subnet so that they are better protected from the Internet. This will then require a NAT Gateway or NAT Instance to enable the instance to access the Internet.

Inter-Elastic Beanstalk communication within the same VPC [duplicate]

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.