I'm new to SSL so sorry if this is obvious.
I have an EC2 instance running a flask Python application. This application listens to port 443. I am trying to add SSL to it by going through Route 53 and ACM. I've created a certificate, but it doesn't allow me to assign it to my EC2 instance, so I've added an elastic load balancer in front, and assigned the SSL certificate to that. The balancer listens to HTTPS port 443 and forwards everything to a target group. The target group listens to port 443, which then forwards it to my Flask application. The problem is that my application receives an encrypted response, and I don't know how I'm supposed to decrypt it. I know how to retreive the certificate, but I think I still need a key file to actually decrypt it as well.
The target group forwards the requests from the Load Balancer to the ec2 instances behind it. Your flask app should listen on port 80 and serve unencrypted traffic.
So, the target group should point to port 80(where your webserver should listen).
Related
So I have a flask web application. I need to have this be HTTPS only. So I'm pretty lost here:
Application Load Balancer -> Target Group -> EC2 Instance (:443) -> ??? -> Flask
So originally I had the following in my http stack:
nginx -> gunicorn -> Flask
That worked for http. And it makes sense how to set up a target group to point to the exposed port of nginx in http. You just provide the port. easy.
However where I am completely lost is when you add HTTPS into the equation. You have AWS provide you with the certificate itself through ACM (Aws certificate manager). However, very specifically AWS Certificate Manager does not allow the created certificates to be exported. So you cannot provide nginx with the certificate, but to use https (443) on nginx you have to provide the ssl_certificate.crt on the server block itself...
So from reading it seems like you don't need nginx... do I need gunicorn? Do I just run flask? If so how does it 'expose' port :443?
I am truly at a loss at how to connect Flask to the target group. Can any one point me to the correct directon? I've exhausted all googling options.
Your confusion is in thinking you need SSL between the load balancer and the Flask application. You can terminate SSL at the load balancer. This will provide SSL between any clients like web browsers and your AWS infrastructure, and you will only have non-SSL traffic inside your virtual private network, between the load balancer and the EC2 instance.
Create the SSL certificate in AWS ACM, and attach it to a listener on the Application Load Balancer. Have both listeners in your load balancer (the port 80 listener without SSL, and the port 443 listener with SSL) forward to the target group. Have the target group connect to your EC2 instance over port 80, or 8080 or 5000 or whatever port you have Flask running on. I think Flask defaults to port 5000?
If you are under some sort of requirements for end-to-end encryption that requires you to setup SSL between the load balancer and the EC2 instance, like some regulatory requirements, then you would need to go back to using Nginx and either purchase an SSL certificate somewhere, or setup a free Let's Encrypt certificate, that you could use with Nginx.
I am running a Gatsby site in development mode as a dev server on EC2 with a loadbalancer pointing from port 80 to 8000. I have setup a cname on my domain dns to point to the load balancer this works fine. However I need to display this page as an iframe in sanity.io as a web preview and it requires https.
I've read through this https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-create-https-ssl-load-balancer.html and most of it is pretty straight forward for the most part.
What I have done so far is created a listener for 443 https on the loadbalancer and added https 443 to the security group. i have succsufully issued a certificate to the subdomain I am using with aws and attached it to the loadbalancer listener.
Gatsby has a article about custom certs for development mode here https://www.gatsbyjs.org/docs/local-https/#custom-key-and-certificate-files What I am looking for is the cert file, the authority file and the key file in order to pass this command below
Where in the aws certificate manager do I find these files. I think that is the last piece I need to get https working, correct me if I am wrong.
thanks ahead of time.
gatsby develop --https --key-file ../relative/path/to/key.key --cert-file ../relative/path/to/cert.crt --ca-file ../relative/path/to/ca.crt
This is the process I used to request my certficate and it says it's issued
https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-public.html
But how do I use it with the custom https command with gatsby?
There is a export option but it says only for private keys. Do I need to create a private key and then I can export these files I need?
Do I even need to run https on gatsby's side. I watched a video using apache and no change was made to the apache server to get https working with the loadbalancer.
Here is a screenshot of my loadbalancer listenr
Here is a image of my security groups
If I run the --https for gatsby develop it breaks my site I can no longer visit it via the loadbalancer or port 8000. So not sure what to do here.
I would suggest not to encrypt the connection between your ELB and the EC2 instances. If your EC2 instances are not publicly reachable, but only through the load balancer instead, it is best practice to terminate the SSL connection on the load balancer. No need to encrypt HTTP requests inside an AWS VPC (i.e. between ELB and target instances).
You can create a load balancer that listens on both the HTTP (80) and HTTPS (443) ports. If you specify that the HTTPS listener sends requests to the instances on port 80, the load balancer terminates the requests and communication from the load balancer to the instances is not encrypted. [1]
There is some discussion (e.g. on the blog of Kevin Burke) whether it is necessary to encrypt traffic inside a VPC. [2] However, most people are probably not doing it.
What it means for you: Use the same instance protocol for your targets as before: HTTP via port 8000 for both listeners. Do not set up SSL for your Gatsby service. Use a plain HTTP server config instead. No changes are necessary to ELB targets when using SSL termination on the load balancer.
References
[1] https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-create-https-ssl-load-balancer.html
[2] https://acloud.guru/forums/aws-certified-security-specialty/discussion/-Ld2pfsORD6ns5dDK5Y7/tlsssl-termination?answer=-LecNy4QX6fviP_ryd7x
I have set up a load Balancer to my elastic beanstalk app. It has provided a DNS / URL which works on http.
I have set up my domain on Route 53. I'm trying to make it work with HTTPS for a subdomain app.example.com
I have set up a wildcard certificate using ACM *.example.com.
I have enable HTTPS and port 443 on the loadBalancer. But I can't access it using the domain name https://app.example.com but works with http://app.example.com
In Route 53, I have created an A record with Alias set to the load Balancer DNS Name.
I have gone through tonnes of answers on stackoverflow but nothing worked for me. No idea what I'm missing.
You do not need to map 443 of the target as the TLS will terminate before sending the request to target.
Map 8080 port of the target to 443 of the load balancer.
Below diagram show SSL/TLS termination work with ALB.
SSL Certificates
To use an HTTPS listener, you must deploy at least one SSL/TLS server
certificate on your load balancer. The load balancer uses a server
certificate to terminate the front-end connection and then decrypt
requests from clients before sending them to the targets.
/application/create-https-listener
This is what worked for me. Changing Instance Protocol to HTTP in first row and changing Instance Port to 80.
I have a EC2 instance running a Node.Js server on Ubuntu.
My goals are:
Connect my hosted zone to the EC2 instance
Route all incoming traffic from port 80 to port 3000 (because my server runs on port 3000)
and most importantly Use an Application Load Balancer to forward all requests to HTTPS (I already created a SSL Certificate in the Certificate Manager).
Currently, I am only able to open the website with the EC2 intances' Public Ip on port 3000 (http://prntscr.com/livali). Https requests or Http to port 80 don't work (http://prntscr.com/livau2). Altought a made an A record on my hosted zone with the instances' Public Ip, it's not possible to open the instance via the hosted zone (http://prntscr.com/liv9no).
I am really confused, as I am somehow not able to get this up and running. I would really appreciate a step by step guide on how to set this whole thing up.
If you already have a SSL certificate it is secure to use only port 443 instead of port 80.
Create an internet facing Application Load Balancer that listens on port 443 and routes traffic to your EC2 instance on port 3000.
Redirect users to HTTPS when accessing your domain on HTTP
See Docs > Load Balancer Listeners > Redirect Actions
Add an A record to point your domain name to the Load Balancer's public DNS.
These are web server concerns rather than DNS concerns. You'll need to set up something like NGINX or Apache to proxy port 80 to port 3000. See Apache redirect to another port for information.
You can also force HTTPS with a rewrite rule in Apache: https://wiki.apache.org/httpd/RewriteHTTPToHTTPS
Another option for forcing HTTPS is to create a CloudFront distribution and use that. https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-https.html
I am working with an AWS EC2 instance (amazon Linux, elastic IP) trying to set up SSL through ACM. The certificate is verified and the load balancer is passing the health checks listening on prot 443, forwarding to port 80. Initially, when testing https I received a connection refused. This confused me because I thought the load balancer would catch and forward this to port 80. I enabled port 443 via nginx on the EC2 instance, so now it is listening on 443 (tested via telnet), which got rid of the connection refused error, but now I get a ERR_SSL_PROTOCOL_ERROR. This makes sense if it is missing the load-balancer and hitting the EC2 instance directly.
Is this the problem (missing the load-balancer)? If so, how do I fix this. I don't see a way to assign an an IP address to a load-balancer. Is a CNAME record required for this kind of setup? If so, how do I configure this?
Thanks.
Your load balancer will be the spot where SSL terminates, and then carries on to your insecure servers running on port 80. You should change your EC2 instance back to port 80.
Yes, you should point a CNAME at your load balancer from the domain the certificate was created for. You do not get an IP for ELB's, as there may actually be many load balancers behind the scenes, which you don't see, all hiding behind the AWS CNAME.
Summary:
Change your EC2 to serve traffic on port 80 again
Make ELB accept connections on port 443, and send to 80 on the instance
Assign a valid domain to your ELB that the certificate is valid for
Profit.
Cheers