I distributed spring boot to aws ec2 and vue.js to s3 cloudfront.
Request for ec2 in my locality is performed normally performed.
However, requesting ec2 on cloudfront results in 403 access denied on the web without a server response.
It is being requested through vue.js proxy, and all settings such as security policies have been completed.
What is the problem?
There could be multiple issues with it. Follow the steps below to debug it
Ensure that your APIs are working without CloudFront. Try to access the APIs hosted on EC2 instance. (you have to open them up for public before using them from CloudFront so ensure that ports are open, etc.)
Check the cache settings. For APIs path (behaviour) it should be no-cache
Make sure the behaviours are setup correctly in the CloudFormation. Behaviours configuration set the path / routes of incoming requests and map them to origins
Enable logging for CloudFront and analyse that
CloudFront doesn't translate the error messages exactly for security reasons. If an object or path doesn't exists CF will show 403 rather than 404. This is to prevent exploits to identify which HTTP resource exists and which not.
Update your question with the findings which will help others to share the solutions.
Related
Our current setup: corporate network is connected via VPN with AWS, Route53 entry is pointing to ELB which points to ECS service (both inside a private VPC subnet).
=> When you request the URL (from inside the corporate network) you see the web application. ✅
Now, what we want is, that when the ECS service is not running (maintenance, error, ...), we want to directly provide the users a maintenance page.
At the moment you will see the default AWS 503 error page. We want to provide a simple static HTML page with some maintenance information.
What we tried so far:
Using Route53 with Failover to CloudFront distributing an S3 bucket with the HTML
This does work, but:
the Route53 will not failover very fast => Until it switches to CloudFront, the users will still see the default AWS 503 page.
as this is a DNS failover and browsers (and proxies, local dns caches, ...) are caching once resolved entries, the users will still see the default AWS 503 page after Route53 switched, because of the caching. Only after the new IP address is resolved (may take some minutes or up until browser or os restart) will the user see the maintenance page.
as the two before, but the other way around: when the service is back running, the users will see the maintenance page way longer, than they should.
As this is not what we were looking for, we next tried:
Using CloudFront with two origins (our ELB and the failover S3 bucket) with a custom error page for 503.
This is not working, as CloudFront needs the origins to be publicly available and our ELB is in a private VPC subnet ❌
We could reconfigure our complete network environment to make it public and restrict the access to CloudFront IPs. While this will probably work, we see the following drawbacks:
The security is decreased: Someone else could setup a CloudFront distribution with our web application as the target and will have full access to it outside of our corporate network.
To overcome this security issue, we would have to implement a secure header (which will be sent from CloudFront to the application), which results in having security code inside our application => Why should our application handle that security? What if the code has a bug or anything?
Our current environment is already up and running. We would have to change a lot for just an error page which comes with reduced security overall!
Use a second ECS service (e.g. HAProxy, nginx, apache, ...) with our application as target and an errorfile for our maintenance page.
While this will work like expected, it also comes with some drawbacks:
The service is a single point of failure: When it is down, you can not access the web application. To overcome this, you have to put it behind an ELB, put it in at least two AZs and (optional) make it horizontally scalable to handle bigger request amounts.
The service will cost money! Maybe you only need one small instance with little memory and CPU, but it (probably) has to scale together with your web application when you have a lot of requests!
It feels like we are back in 2000s and not in a cloud environment.
So, long story short: Are there any other ways to implement a f*****g simple maintenance page while keeping our web application private and secure?
I'm new with AWS WAF and get stuck with setting up it for application that hosts on some dedicated server. I didn't find any information how to set up it without migration to aws servers, but I found that WAF integrated with CloudFront. But anyway I found only few information that explain how to integrate this CDN with my web application. So, the main question is:
Is it possible to use AWS WAF with application that hosted on some dedicated server? And if it possible - can you provide some guides and/or docs for setting up?
Yes, you can use WAF with a server outside AWS.
WAF works with CloudFront, and CloudFront does not require the origin server to be in the AWS ecosystem.
When you create a distribution, you specify where CloudFront sends requests for the files. CloudFront supports using several AWS resources as origins. For example, you can specify an Amazon S3 bucket or a MediaStore container, a MediaPackage channel, or a custom origin, such as an Amazon EC2 instance or your own HTTP web server. (emphasis added)
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DownloadDistS3AndCustomOrigins.html
Configuring CloudFront to work with your external server is no different than configuring it to work with a server in EC2. Your DNS entry (e.g. www.example.com) changes to point to CloudFront, and CloudFront connects to your server using a new name that you create (e.g. origin.example.com). CloudFront proxies requests through to your server, unless the edge location handling the a given request happens to have access to a copy of the same resource that it cached while handling a previous request for the same page -- that's how CloudFront gets your content, by caching it as it handles requests that are passing through. (You don't pre-load any content into CloudFront.) If CloudFront has a cached copy, your server sees nothing, and CloudFront returns the object to the browser from its cache. But CloudFront isn't strictly a CDN, even though they market it that way. It is a global network of reverse proxies and high-reliability/low-latency transport.
You'll want to take steps to ensure that the web server rejected requests that didn't come through CloudFront. See Using Custom Headers to Restrict Access to Your Content on a Custom Origin as well as the list of CloudFront IP Addresses which you could use on your web server's firewall.
Once you have your site working through CloudFront, all you do is activate WAF on the distribution. CloudFront is very tightly integrated with WAF so that is a very simple change, once you have your WAF rules set up.
My Situation
I have a web api hosted in an EC2 instance. I am trying to configure a cloudfront instance "infront" of that EC2 instance.
However, I have not been able to get my cloudfront to forward requests to the EC2 instance. I get hit with an error response like this:
Access to XMLHttpRequest at 'https://api.example.com' from origin 'https://example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No access-control-Allow-Origin header is present on the requested resource
However, if I change my DNS to point https://api.example.com to EC2 instance's IP address, it works.
What I have done so far
Configured to use correct SSL certificate (for a different problem earlier)
Configured my CF distribution's behaviors to Whitelist Headers: "Origin"
Configure my CF distribution's behaviors to "All" - (which disables caching)
Invalidated cloudfront cache
What I am trying to do
I came across this AWS doc titled "Configuring CloudFront to Respect CORS Settings".
Link
However, it only says "Custom origins – Forward the Origin header along with any other headers required by your origin."
But... How do I do that? How do I forward origin header along with any other headers required? The docs doesn't specify or link to another docs to do it.
I have spent 4 hours or so now and it's extremely frustrating because Cloudfront takes ~30 minutes to deploy.
I have managed to fix this issue it turned out I had overlooked another error returned by Cloudfront: 502 Bad Gateway. Even though Chrome will show the abovementioned error "Access to XMLHttpRequest...". This was caused by my improper DNS and SSL certificates configuration due to my inexperience.
I will try to answer my own question, seeing after hours of searching, there wasn't a straight answer regarding (Cloudfront, EC2 and HTTPS) in Stackoverflow and there are many unaswered questions.
The goal my group was trying to achieve was enabling HTTPS connectivity for the entire set-up: Users' browsers, Cloudfront distribution and my EC2 instance.
What I did to fix this:
Generated a free SSL certificate (e.g. Let's Encrypt) to use for EC2 instance using a sub-domain (i.e. ec2.example.com or wildcard *.example.com). *Note: ACM does not allow public SSL certificates to be exported that can be used in EC2 instances, so use other free online SSL services. Do not use self-signed certs.
Import this certificate into ACM to be used for Cloudfront later too.
Created a new DNS A record to map the sub-domain to the EC2 instance. (e.g. ec2.example.com to ec2-xx-xxx-xx.ap1-location.amazonaws)
Created a new Cloudfront distribution and set the origin as the sub-domain, ec2.example.com. Also, under "Cache Based on Selected Request Headers", set it to "Whitelist" and to forward "Origin" headers. For SSL cert in Cloudfront, use back the one generated back in step 1)
Created a new DNS A record and map an "api" sub-domain to the Cloudfront. (e.g. api.example.com to abcdxyz.cloudfront.net)
I am now able to use a sub-domain (api.example.com) to communicate with Cloudfront which in turns communicates back to my EC2 and performs caching, using HTTPS all along.
Reference links: link1,
link2
There is probably a better way to set this up and if so, please do correct me so I can improve too! Hopefully this answer will help someone else new like me in the future too.
We have recently started using AWS ELB. We are struggling to capture the following headers at ELB.
Referer
User-Agent
Any way to get it done?
AFAIK you cannot configure the access logs format for the LB (classic or other wise).
For classic ELB look at the logging documentation to see what fields are logged.
It does log the user agent but the referer is not logged.
Depending on what kind of application architecture you have behind your ELB you can configure that application for access logs and you would have more control over the access logs.
Example: Say you have an Spring boot based EC2 behind your ELB, you can configure the spring boot embedded tomcat to log whatever headers you need in the access logs.
I am maintaining an embedded database for a web app on an EC2 instance. Since this central server is single-threaded, it's very susceptible to DDOS (even a non-distributed attack would cripple it).
AWS has DDOS protection for its CDN CloudFront, so I am wondering if I can use CloudFront as a layer of indirection around my EC2 instance for DDOS protection.
The problem is figuring out how to effectively prevent users from bypassing CloudFront and hitting the server directly. My questions:
Will users be able to trace the network path to get the IP of my EC2 instance, or will they only be able to see the API url for Cloudfront?
Is there a way to prevent traffic from reaching my EC2 instance if it didn't come through Cloudfront? I see that there is an option to send a custom origin header from Cloudfront, but this doesn't solve the problem--I'd still have to process each request in my EC2 instance. Is there a way to configure input rules to my server which prevent it from processing non Cloudfront requests?
I am new to thinking about network architecture and security, so any and all advice is appreciated!
AWS Shield Standard is included automatically and transparently to Amazon CloudFront distributions providing,
Active Traffic Monitoring with Network flow monitoring and Automatic always-on detection.
Attack Mitigations with Protection from common DDoS attacks (e.g. SYN floods, ACK floods, UDP floods, Reflection attacks), Automatic inline mitigation and you can use AWS WAF in conjunction to mitigate Layer 7 attacks.
To prevent, users from bypassing CloudFront and directly accessing your EC2 instance, you can use security groups whitelisting the AWS CloudFront IP address list. Since this list suspects to change, you can setup a Lambda function to update it automatically once AWS changes CloudFront IPs. For more information about this refer the article How to Automatically Update Your Security Groups for Amazon CloudFront and AWS WAF by Using AWS Lambda.
If you are using Application Load Balancer, you can whitelist a header and add it to the CloudFront origin so that the requests are only accepted if the header is present. (This could also be added to the Web Server header whitelisting but then the HTTP requests will be rejected only at the Web Server level as you clearly identified).
Also, you can include an AWS WAF configuration (At ALB or CloudFront whichever you use as the external interface) with rate limiting to prevent any abuse which is easy to setup and the cost-effective.