AWS-issued (managed) TLS/SSL certificate for ELB/ALB - amazon-web-services

When I create an ELB (i.e. Application Load Balancer), Amazon gives it a DNS name e.g.:
myalb-1472119708.eu-central-1.elb.amazonaws.com
Now, I would like to terminate TLS/SSL on my ALB, however, I don't want to attach my own certificate (e.g. from the Certificate Manager), I am ok with accessing my application via the default DNS name (of the ALB) through HTTPS:
https://myalb-1472119708.eu-central-1.elb.amazonaws.com
However, with the default configuration I can access my app via HTTP only:
http://myalb-1472119708.eu-central-1.elb.amazonaws.com
Does AWS support this (rhetorical question)? Any plans to add this feature in the near future? Thanks.
UPDATE:
After all it's not a hard feature to implement. Moreover, SSL is the de facto standard for running (secure) web apps today. I believe, AWS can issue wildcard certificates for the ELB in every region, e.g.:
*.eu-central-1.elb.amazonaws.com
And then attach it to every ALB by default. Or publish a list of certificates' ARNs for every region. This would free developers from extra effort (buying a domain, registering a certificate in ACM) for their non-production projects.

At the time of this writing, the only way to resolve this is by running your ALB/ELB behind CloudFront, which (unlike ALB) gives you a TLS certificate by default:
User -> CloudFront edge location (HTTPS) -> ALB (HTTP) -> Backend (HTTP)
Although CloudFront incurs extra costs, apart from the ability to cache static content, CloudFront gives you faster TLS termination, which happens at its edge locations, thus reducing latency on the first two TLS handshake roundtrips (2 in theory, but practically 3 in case of low-bandwidth clients).

Related

Which AWS service can I use to put SSL encryption in front of an instance in my VPN?

I have instance in VPN on which some external consultants are working on. I need expose the app they are developing to the internet but I don't want them to have access to the private key of our SSL cert.
I am thinking I can put the SSL cert into ACM and then use some AWS component in front of the instance to handle the client connections and TLS encryption. I believe that an application load balancer can do this - will this work and is the best and cheapest option? I don't actually need load balancing just yet but may do in the future.
Yes load balancer is one of the option.
Another choice is using a CDN, CloudFront for the SSL, you simply set the origin to the EC2 instance.
Depending on your use case you need to consider what is the right caching policy (if applicable) though.
CloudFront charge by bandwidth, while Load Balancer charge by hour, so you need to consider the type of workload as well.

Can CloudFront protect EC2 server from DDOS?

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.

AWS ELB/ALB Multiple SSL Certicifates

I'm looking for a way to use multiple ssl certificates (over 100) on a single AWS ELB/ALB - how can I implement that?
You can't do this. Not directly.
ELB Classic supports 1 cert per listener and of course only one listener on port 443.
ALB supports 26 certificates (25 plus the default, which is used whenever the incoming SNI is unmatched or absent).
But, certificates can support multiple domains, so that's one way of getting support for more than 25 (+1) domains -- combine the domains onto a smaller number of certs. This is a limit that cannot be increased.
Or, create one CloudFront distribution per certificate, pointing them to the ALB as origin server. This allows you to support as many certs as you want with the services deployed behind one balancer, up to the limits for distributions on your account. The default limit is 200 CloudFront distributions in each account, but this can be increased by request. This can also be used to potentially reduce the load on the instances behind the balancer, since CloudFront can be configured to cache responses.

Email-based DCV Issue (multiple domains) - Amazon Certificate Manager (ACM)

Is there a way to validate domain control without using the email process? As I need to be able to add additional domains to the certificate for new clients...
The problem I'm facing is I can't add to the existing AWS certificate and have to create a new one with all the domains. When I do that everyone for every domain get's emailed and asked to confirm at:
administrator#domain.com
hostmaster#domain.com
admin#domain.com
postmaster#domain.com
webmaster#domain.com
So I have had to register a seperate certificate and upload it to ACM instead which is not ideal. Mainly as it's limited to 99 domains and was hoping to automate the whole process.
Is this possible with AWS?
Thank you.
Q: Are any other methods for validating a domain or approving a certificate supported?
Not at this time.
https://aws.amazon.com/certificate-manager/faqs/#provisioning
Having so many domains on one certificate isn't really a good practice, for other reasons, as well.
You're making your certificate physically longer and longer, wasting some amount of bandwidth, because the cert is sent to every connecting client, on every new connection.
Renewals will also be messy, if any of the domains on the cert are no longer pointing to your site, because auto-renewal requires that the issued cert be reachable on the Internet for each hostname.
ACM tries to automatically renew your Amazon-issued SSL/TLS certificates before they expire so that no action is required from you. To renew your certificate automatically, the following must be true:
ACM must be able to establish an HTTPS connection with each domain in the certificate.
For each connection, the certificate that is returned must match the one that ACM is renewing.
http://docs.aws.amazon.com/acm/latest/userguide/configure-domain-for-automatic-validation.html
One cleaner solution (the one I am using) is to provision each domain's cert individually, and attach each one to its own CloudFront distribution, pointing that to your origin server (which I assume in this context to be an ELB) and whitelisting all headers for forwarding to the origin, which bypasses caching and causes CloudFront to function as a simple but distributed reverse proxy. Setting "compress objects automatically" in CloudFront may also save some bandwidth charges, and even with caching disabled, CloudFront should improve the responsiveness of your sites by keeping traffic on the AWS network for more of the path between origin and viewer.

How to use AWS WAF with Application ELB

I need to use AWS WAF for my web application hosted on AWS to provide additional rule based security to it. I couldnt find any way to directly use WAF with ELB and WAF needs Cloudfront to add WEB ACL to block actions based on rules.
So, I added my Application ELB CNAME to cloudfront, only the domain name, WebACL with an IP block rule and HTTPS protocol was updated with cloudfront. Rest all has been left default. once both WAF and Cloudfront with ELB CNAME was added, i tried to access the CNAME ELB from one of the ip address that is in the block ip rule in WAF. I am still able to access my web application from that IP address. Also, I tried to check cloudwatch metrics for Web ACL created and I see its not even being hit.
First, is there any good way to achieve what I am doing and second, is there a specific way to add ELB CNAME on cloudfront.
Thanks and Regards,
Jay
Service update: The orignal, extended answer below was correct at the time it was written, but is now primarily applicable to Classic ELB, because -- as of 2016-12-07 -- Application Load Balancers (elbv2) can now be directly integrated with Web Application Firewall (Amazon WAF).
Starting [2016-12-07] AWS WAF (Web Application Firewall) is available on the Application Load Balancer (ALB). You can now use AWS WAF directly on Application Load Balancers (both internal and external) in a VPC, to protect your websites and web services. With this launch customers can now use AWS WAF on both Amazon CloudFront and Application Load Balancer.
https://aws.amazon.com/about-aws/whats-new/2016/12/AWS-WAF-now-available-on-Application-Load-Balancer/
It seems like you do need some clarification on how these pieces fit together.
So let's say your actual site that you want to secure is app.example.com.
It sounds as if you have a CNAME elb.example.com pointing to the assigned hostname of the ELB, which is something like example-123456789.us-west-2.elb.amazonaws.com. If you access either of these hostnames, you're connecting directly to the ELB -- regardless of what's configured in CloudFront or WAF. These machines are still accessible over the Internet.
The trick here is to route the traffic to CloudFront, where it can be firewalled by WAF, which means a couple of additional things have to happen: first, this means an additional hostname is needed, so you configure app.example.com in DNS as a CNAME (or Alias, if you're using Route 53) pointing to the dxxxexample.cloudfront.net hostname assigned to your distribution.
You can also access your sitr using the assigned CloudFront hostname, directly, for testing. Accessing this endpoint from the blocked IP address should indeed result in the request being denied, now.
So, the CloudFront endpoint is where you need to send your traffic -- not directly to the ELB.
Doesn't that leave your ELB still exposed?
Yes, it does... so the next step is to plug that hole.
If you're using a custom origin, you can use custom headers to prevent users from bypassing CloudFront and requesting content directly from your origin.
http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/forward-custom-headers.html
The idea here is that you will establish a secret value known only to your servers and CloudFront. CloudFront will send this in the headers along with every request, and your servers will require that value to be present or else they will play dumb and throw an error -- such as 503 Service Unavailable or 403 Forbidden or even 404 Not Found.
So, you make up a header name, like X-My-CloudFront-Secret-String and a random string, like o+mJeNieamgKKS0Uu0A1Fqk7sOqa6Mlc3 and configure this as a Custom Origin Header in CloudFront. The values shown here are arbitrary examples -- this can be anything.
Then configure your application web server to deny any request where this header and the matching value are not present -- because this is how you know the request came from your specific CloudFront distribution. Anything else (other than ELB health checks, for which you need to make an exception) is not from your CloudFront distribution, and is therefore unauthorized by definition, so your server needs to deny it with an error, but without explaining too much in the error message.
This header and its expected value remains a secret because it will not be sent back to the browser by CloudFront -- it's only sent in the forward direction, in the requests that CloudFront sends to your ELB.
Note that you should get an SSL cert for your ELB (for the elb.example.com hostname) and configure CloudFront to forward all requests to your ELB using HTTPS. The likelihood of interception of traffic between CloudFront and ELB is low, but this is a protection you should consider implenting.
You can optionally also reduce (but not eliminate) most unauthorized access by blocking all requests that don't arrive from CloudFront by only allowing the CloudFront IP address ranges in the ELB security group -- the CloudFront address ranges are documented (search the JSON for blocks designated as CLOUDFRONT, and allow only these in the ELB security group) but note that if you do this, you still need to set up the custom origin header configuration, discussed above, because if you only block at the IP level, you're still technically allowing anybody's CloudFront distribution to access your ELB. Your CloudFront distribution shares IP addresses in a pool with other CloudFront distribution, so the fact that the request arrives from CloudFront is not a sufficient guarantee that it is from your CloudFront distribution. Note also that you need to sign up for change notifications so that if new address ranges are added to CloudFront, then you'll know to add them to your security group.