Amazon Web Services EC2 to RDS Connectivity with VPC - amazon-ec2

I have been trying to set up an AWS Free Tier account using an EC2 instance and an RDS database running MySQL. Unfortunately, I cannot figure out how to grant access to the database from the EC2 instance. I have read all of the AWS documentation, but it is unfortunately out of date as are all the questions posted on StackOverflow. All of the documentation states that I should go to the Security Groups section of the RDS Dashboard. However, when I do so, this is what I'm confronted with.
** I would have included the image but I don't have the reputation for it.
Okay, I understand that I am not using the EC2-Classic platform and that I must make these changes to the Security Group in the EC2 Dashboard, but how?! I do not want public access to port 3306, I only want the EC2 instance to be able to communicate with the RDS database on a private subnet. Any help would be greatly appreciated.
The links to "AWS Documentation on Supported Platforms" and "Using RDS in VPC" are not helpful. They are outdated and also keep referring me back to Security Groups under the RDS Dashboard, which then only shows me this message.

A rule of thumb: When you are setting up resources in VPC, use ONLY VPC Security Groups. The individual RDS, Redshift...etc. security groups work only in case of ec2-classic. Meaning, when you are not setting up things in VPC.
Go to the VPC console and then on the left hand side menu, you will find security groups. These are the security groups which should control access to your AWS resources deployed inside a VPC.
I can't elaborate much as I am unaware of your VPC configuration and which subnet (public/private) you are setting these up.
Example
Here is the hypothetical scenario...
VPC: 10.0.0.0/16
1 public subnet: 10.0.0.0/24
1 Private Subnet: 10.0.1.0/24
Assume you put your EC2 instance in Public Subnet
Assume you put your RDS instance in Private Subnet
And you want EC2 instance be accessible on 80,443 from the world and RDS instance should be accessible only via EC2 instance.
So, these are the security groups settings:
for EC2 instance Security group:
Inbound: port 80, 443 : from 0.0.0.0/0
Outbound: port 3306 : to 10.0.1.0/24
For RDS security group:
Inbound: port 3306: from 10.0.0.0/24
Explanation
Inbound: port 80, 443 : from 0.0.0.0/0
This will allow EC2 instance be accessible on port 80 and 443 from the Internet.
Outbound: port 3306 : to 10.0.1.0/24
This allows EC2 instance to send the traffic on port 3306 only to the private subnet which is 10.0.1.0/24
Inbound: port 3306: from 10.0.0.0/24
This allows the RDS instance to accept traffic on port 3306 from the public subnet which is 10.0.0.0/24. Your EC2 instance resides in Public subnet so inherently RDS will accept traffic from Ec2 instance on port 3306
NOTE: Above setup presumes that you have set your Routing tables for the public/private subnets accordingly.
Hope this helps.

Related

AWS Lambda in VPC with RDS and Internet Connection

I set up an Aurora Database (provisioned) in a newly created VPC and no public accessibility. As I want to run a Lambda function in the VPC which is able to both, access the RDS instances as well as the Internet, I changed the routing tables of the RDS instances to allowing traffic from a NAT gateway which I placed in a public subnet in the same VPC.
For the Lambda function itself, I created a separate private subnet, also just allowing traffic from the NAT gateway in the routing table. I assigned this subnet and VPC to the Lambda function in the Lambda settings. The internet connection works fine with this configuration but I can not access the database. That's why I followed this post (https://serverfault.com/questions/941886/connect-an-aws-lambda-function-triggered-by-api-gateway-to-aurora-serverless-mys) and added the IP CIDR of the Lambda subnet to the Security Group of the RDS instances (called rds-launch-wizard).
Still, the Lambda function is able to interact with the public internet but can not connect to the RDS instances (timeout). I'm running out of ideas, what is wrong here?
The configuration should be:
A Public subnet with a NAT Gateway (and, by definition, an Internet Gateway)
A Private subnet with the Amazon RDS instance
The same, or a different, Private Subnet associated with the Lambda function
The Private Subnet(s) configured with a Route Table with a destination of 0.0.0.0/0 to the NAT Gateway
Then consider the Security Groups:
A security group for the Lambda function (Lambda-SG) that permits all outbound access
A security group for the RDS instance (RDS-SG) that should permit inbound access from Lambda-SG on the appropriate database port
That is, RDS-SG is allowing incoming traffic from Lambda-SG (by name). There is no need to use CIDRs in the security group.
The Lambda function will connect to a private subnet via an Elastic Network Interface (ENI) and will be able to communicate both with the RDS instance (directly) and with the Internet (via the NAT Gateway).
Please note that you are not directing "traffic from the NAT Gateway". Rather, you are directing Internet-bound traffic to the NAT Gateway. Nor is there such a thing as "routing tables of the RDS instances" because the Route Tables are associated with subnets, not RDS.

How EC2 allow SSH tunelling to access RDS in private subnet?

To access RDS in private subnet, in the below architecture,
Giving public IP of EC2, ssh private key location of EC2 in public subnet, DB credentials of RDS in private subnet, as shown below,
How EC2(in public subnet) allow ssh tunneling to RDS in private subnet? Is it something to do with /etc/ssh/sshd_config in EC2?
From the picture, the EC2 instances share the same private network (class B) 172.16.X.X with the RDS therefore by having access to any instance in the public segment and depending on the security groups defined on the RDS it may be possible to reach the database by doing something like:
ssh -L 3307:<db>.rds.amazonaws.com:3306 user#your.ec2
The option -L will do a local port forwarding from port 3307 (your computer) to port 3306 in <db>.rds.amazonaws.com going through your.ec2.instance.
You could use a bastion host to do this, you could read more about it here: https://docs.aws.amazon.com/quickstart/latest/linux-bastion/architecture.html
Besides defining how and what users to allow using ssh you will not have to deal with sshd_config most of the work will be either in AWS security groups or how you defined your VPC or network ACL's.

Can't connect to RDS from EC2 using terraform created infrastructure

I created the infrastructure manually following the steps provided in the link: connecting-to-a-database-within-an-amazon-vpc.
I could connect to RDS in private subnet from ec2 in public subnet perfectly. That is exactly what I wanted.
But when I tried to create the same exact replica using terraform, it just doesn't connect.
The command:
nslookup <my-hostname>
gives me the Private IP.
The command:
telnet x.x.x.x 5432
results in "telnet: Unable to connect to remote host: Connection timed out"
The command:
netstat -an | grep x.x.x.x
shows "SYN_SENT".
I tried allowing all the IP's in RDS security group by adding 0.0.0.0/0. That didn't work.
I tried to create RDS instance manually, but added it to terraform created VPC and tried to connect using terraform created ec2 instance. That didn't work.
Am i missing something ? Any help is much appreciated.
troubleshooting steps:
Check security group's egress (outbound rules) on your public ec2 instance,
Make sure it allows outbound rules with port 5432 to access rds (which is in private subnets)
Check security group's ingress (inbound rules) on your rds instance. Maybe sure it allows port 5432 from public ec2 instances CIDR ips or security groups.
If not, please update your terraform codes according.
The ec2 instance is in public subnet. That would mean ideally traffic would go from NAT Gateways. So I would suggest to edit the security group rule of RDS add a rule to allow public IPs of NAT Gateways to be accessible on the port 5432.

Access an RDS DB on a private subnet from an ec2 on a public subnet via SSL

I have an instance of AWS RDS running in a private subnet of a VPC.
I would like my EC2 machine, which is running on a public subnet to have access to it via SSL (and not SSH like I saw people suggest. I want to access it directly from the code via SSL).
Is there a way to do so?
The EC2 instance should have direct access to the RDS instance as long as they are in the same VPC. You just need to open up the security group assigned to the RDS instance to allow ingress from the EC2 instance.
I think you have SSH tunneling (which isn't needed when both servers are in the same VPC) and SSL database connections confused. SSH and SSL would be completely unrelated in this case.
SSL connection support would be a function of the specific database engine you are using. If your database is configured to support SSL connections, then you should be able to configure your database client software running on your EC2 instance to use SSL when creating connections to the database.

Amazon RDS Endpoint internal

How can I make ec2 instance communicate with rds instance on aws by internal ip address or dns?
I only see public dns like xxx.cehmrvc73g1g.eu-west-1.rds.amazonaws.com:3306
Will internal ipaddress will be faster than public dns?
Thanks
A note for posterity, ensure that you enable DNS on the VPC Peering link!
Enabling DNS Resolution Support for a VPC Peering Connection
To enable a VPC to resolve public IPv4 DNS hostnames to private IPv4
addresses when queried from instances in the peer VPC, you must modify
the peering connection.
Both VPCs must be enabled for DNS hostnames and DNS resolution.
To enable DNS resolution support for the peering connection
Open the Amazon VPC console at https://console.aws.amazon.com/vpc/.
In the navigation pane, choose Peering Connections.
Select the VPC peering connection, and choose Actions, Edit DNS
Settings.
To ensure that queries from the peer VPC resolve to private IP
addresses in your local VPC, choose the option to enable DNS
resolution for queries from the peer VPC.
If the peer VPC is in the same AWS account, you can choose the option
to enable DNS resolution for queries from the local VPC. This ensures
that queries from the local VPC resolve to private IP addresses in the
peer VPC. This option is not available if the peer VPC is in a
different AWS account.
Choose Save.
If the peer VPC is in a different AWS account, the owner of the peer
VPC must sign into the VPC console, perform steps 2 through 4, and
choose Save.
You can use the "Endpoint" DNS name. It will resolve to the internal IP when used within the VPC and resolves to a public ip when used outside of your AWS network. You should never use the actual IP address because the way the RDS works it could possibly change in the future.
If you ping it from your EC2 (on the same VPC) server you can verify this.
It is amazing to see the amount of down votes I've got given that my answer is the only correct answer, here is 2 other sources:
https://forums.aws.amazon.com/thread.jspa?threadID=70112
You can use the "Endpoint" DNS name. It will resolve to the internal IP when used within EC2.
https://serverfault.com/questions/601548/cant-find-the-private-ip-address-for-my-amazon-rds-instance2
The DNS endpoint provided in the AWS console will resolve to the internal IPs from within Amazon's network.
Check out the AWS EC2 docs: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html#concepts-private-addresses.
It doesn't appear that this necessarily applies to RDS, however.
When resolving your RDS instance from within the same VPC the internal IP is returned by the Amazon DNS service.
If the RDS instance is externally accessible you will see the external IP from outside the VPC. However, if the EC2 instance NOT available publiclly the internal IP address is returned to external and internal lookups.
Will internal ip address will be faster than the external address supplied by public dns?
Most likely as the packets will need to be routed when using the external addresses, increasing latency.
It also requires that your EC2 instances have a public IP or NAT gateway along with appropriate security groups and routes, increasing cost, increasing complexity and reducing security.
its pretty easy, telnet your RDS endpoint using command prompt on windows or through unix terminal
for example: telnet "you RDS endpoint" "Port"
trying to connect "You get your RDS internal IP here"

Resources