Force AWS SSM to communicate via FQDN rather than IP address? - aws-ssm

The https://docs.aws.amazon.com/general/latest/gr/ssm.html website lists all of the SSM endpoints that need to be whitelisted over port 443/tcp (https) in order for AWS SSM agents to communicate; however, after about 2-3 weeks of troubleshooting, I just came to the conclusion that AWS SSM does not actually communicate via FQDN, which causes problems for proxies that only whitelist FQDNs and not IP addresses.
Since the IP addresses of thoes FQDNs don't point back to those FQDNs, this leaves the AWS SSM tool broken in the particular environment I'm using it.
Is there a way to either "force" AWS SSM to use FQDNs when communicating outbound?

AWS does not use or allow FQDNs in security groups or routing unless you are remaining on their network (AWS service to AWS service communication). You must use IPv4 or IPv6 addresses in all other cases.
This AWS article is good, but I have found that the SSM Messages and EC2 Messages endpoints are also required, which is addressed here.
Basically, you need to create 3 VPC endpoints (SSM, SSM Messages, and EC2 Messages) and route the 443 traffic to them while allowing the traffic on the affected security groups, route tables and NACLs. This has the advantage of not having the traffic leave AWS' networks and the traffic will not be affected by your firewalls/proxies in most architectures. Beware that the AWS documentation is not good and conflicts with itself, as shown in the 2 articles linked here.

Related

How to reach S3 from a nodejs lambda which is inside a VPC?

My lambda is getting ETIMEDOUT for hostname s3.amazonaws.com. I figured out that is is probably caused by the fact that my lambda is inside a VPC.
I suspect that I need to use an AWS Endpoint to reach S3. I know that we have endpoint set up and in AWS Console I can see and endpoint associated with this VPC called dev-s3-gateway with service name com.amazonaws.us-east-1.s3
How do I tell my lambda to use this endpoint?
Inside a VPC, your Lambda can be in either a private subnet or a public subnet.
Lambda in Public Subnets CANNOT access the internet.
Having Lambda access the internet
Being in a Private Subnet, your Lambda cannot have "direct" access to the internet. You need to provision a Public Subnet in your VPC and have both an Internet Gateway as well as a NAT Gateway in that subnet.
Route the traffic to 0.0.0.0/0 from your Lambda's subnet via the NAT Gateway.
From the routing table of the Public Subnet, route traffic to 0.0.0.0/0 via the Internet Gateway.
Your Lambda should now have access to the internet (and to S3).
Feel free to also check out this more detailed guide.
Accessing AWS services through VPC endpoints
Several AWS services offer VPC endpoints. These allow you to connect and interact with the respective services without your traffic ever leaving the AWS network.
For more information on them, please check out their documentation.
EDIT: Expanding a bit on your specific S3 use case.
S3 offers Gateway and Interface VPC Endpoints. Based on the endpoint name you provided in the question, I'm going to guess this is a Gateway VPC Endpoint. Once you set up the endpoint in your VPC, the Security Group(s) associated with your Lambda must allow outbound traffic to the endpoint.
You have two options.
First and simplest (but perhaps less secure - depending on your use case), you allow outbound traffic to 0.0.0.0/0. This will effectively allow you to call anything. However, if the Lambda is in a public subnet, it won't be able to access the internet, as explained above, but rather only the Gateway VPC Endpoint ranges.
The second option is to allow outbound traffic to the known Prefix List of the regional Amazon S3 endpoint. You can retrieve the PrefixList ID (looks like pl-xxxxxx) by invoking the DescribePrefixLists and looking for that Prefix List for service com.amazonaws.us-east-1.s3. Once you have the ID of the Prefix List, you can add it to the destination of an outbound rule of your Security Group(s).

Blocking Amazon AWS servers from Rails 4 application?

I have a Rails 4 application running on Heroku with exception_notification. I was notified that an AWS server was fishing for a login page by trying to access /wp-login.php. Since that is not my app's login page, someone had to manually enter that URL. Tracking the IP shows an Amazon AWS server in Oregon.
There shouldn't be any reason why someone would ever access my app via an AWS server, so my initial thought is someone is trying to get into the application.
In order to avoid any potential attack, I'm thinking about blocking all Amazon AWS requests.
Is there any way to blacklist Amazon AWS servers specifically? The only thing I can think of is checking the IP address of every request and ignoring those coming from a list I keep of Amazon, but I'm not sure if there is an official listing of Amazon IP addresses.
But checking the IP of every request against a blacklist seems inefficient. I'm aware of the rack-attack gem, but that is still running Ruby code to do the check, which doesn't seem very fast...
Blocking all AWS IPs is not a good solution. Potentially, the traffic can come from any part of the world. How are you going to block the traffic? Instead you should make your application robust.
There is an official listing of AWS IP address: AWS IP Address Ranges
If you are 100% sure that traffic originating from AWS (remember there are many AWS regions), then you can block them using IP tabled. One such solution is: AWS Blocker
Blocking all AWS IPs is not a good solution.

Securing outbound traffic rule from EC2 instances when using ECS

Even when I create EC2 instances in a private subnet, they must be able to send traffic to the Internet if I want to register them to a ECS cluster.
I am using a NAT gateway to do this, but I still feel insecure that the instances can send private information to anywhere in case of takeover.
What would be the most compact CIDR range that I can use for the instances' security group, instead of 0.0.0.0/0?
For the moment, you may have to rely on the list of public IP address ranges for AWS, allowing traffic bound for all the CIDR blocks associated with your region.
Part of design for resiliency of much of what AWS does relies on the ability of their service endpoints not to depend on static address assigments and instead to use DNS... but their service endpoints should always be on addresses associated with your region, since very few services violate their practice strict regional separation of service infrastructure.
(CloudFront, Route 53, and IAM do, maybe others, but these are provisioning endpoints, not operational ones. These provisioning-only endpoints do not need to be accessible for most applications to function normally.)
A super common pattern here is to create a proxy in a narrow CIDR and only allow outbound traffic to flow through the proxy. White-list AWS endpoints and log all traffic flowing through the proxy for monitoring/auditing.
AWS Endpoints = https://docs.aws.amazon.com/general/latest/gr/rande.html

Security group for AWS Lambda to access RDS

Was not able to find any security groups for AWS Lambda.
Is there a way to allow access from AWS Lambda to RDS without alowing all IPs (0.0.0.0/0) and without allowing all Amazon IP Range?
As #user5919440 suggests, now that this new feature is out:
https://aws.amazon.com/blogs/aws/new-access-resources-in-a-vpc-from-your-lambda-functions/
...you simply need to tell AWS Lambda which VPC subnets to bind to your function. The function then can communicate with any AWS service that also has access to that subnet.
This means that you should be able to add a security group in your RDS that allows traffic from the same internal subnet (10.x.x.x) that your Lambda function is bound to.
This feature is out as of yesterday
https://aws.amazon.com/blogs/aws/new-access-resources-in-a-vpc-from-your-lambda-functions/
There currently isn't, and a moment's reflection suggests that if there were, if would be a false sense of security -- the traffic wouldn't be assured to be from your Lambda functions... but from anybody's -- the IP addresses are pooled.
There have been hints of a future mechanism to allow a cleaner trust relationship between Lambda and VPC, perhaps implemented with the VPC Endpoint feature (currently available only with S3), or perhaps differently... no details have been forthcoming, so far.

AWS, NodeJS - Connecting app to Mongodb on another EC2 instance

I am trying to connect my app, running on one EC2 instance, to MongoDB, running on another EC2 instance. I'm pretty sure the problem is in the security settings, but I'm not quite sure how to handle that.
First off, my app's instance is in an autoscaling group that sits behind an ELB. The inbound security settings for the instance and ELB allow access to port 80 from anywhere, as well as all traffic from its own security group.
The EC2 instance that runs Mongo is able to take connections if the security group for that instance accepts all inbound traffic from anywhere. Any other configuration that I've tried causes the app to say that it cannot make a connection with the remote address. I've set rules to accept inbound traffic from all security groups that I have, but it only seems to work when I allow all traffic from anywhere.
Also, my db instance is set up with an elastic ip. Should I have this instance behind an ELB as well?
So my questions are these:
1) How can I securely make connections to my EC2 instance running mongo?
2) In terms of architecture, does it make sense to run my database this way, or should I have this behind a load balancer as well?
This issue is tripping me up a lot more than I thought it would, so any help would be appreciated.
NOTE
I have also set the bind_ip=0.0.0.0 in /etc/mongo.conf
Your issue is that you are using the public elastic IP to connect to your database server from your other servers. This means that the connection is going out to the internet and back into your VPC, which presents the following issues:
Security issues due to the data transmission not being contained within your VPC
Network latency issues
Your database server's security group can't identify the security group of the inbound connections
Get rid of the elastic IP on the MongoDB server, there is no need for it unless you plan to connect to it from outside your VPC. Modify your servers to use the private internal IP address assigned to your database server when creating connections to it. Finally, lock your security group back down to only allow access to the DB from your other security group(s).
Optional: Create a private hosted zone in Route53, with an A record pointing to your database server's private IP address, then use that hostname instead of the internal IP address.

Resources