I Created an EC2 instance that is running perfectly over http.but when i try to replace http to https i got this printed on the browser This site can’t provide a secure connection. the security group that is associated to this instance is configured to allow requests from both HTTP and HTTPS as in the attached image:
You are trying to run https over a port that has been configured for HTTP.
There are multiple options to get around this:
Setup a proxy on your local server, such as Nginx. Setup certbot to generate your SSL and then serve this from your proxy.
Create an ELB in front of your server, generate a certificate in ACM and add your server as a target (running http) to the ELB. Use the load balancer for SSL termination.
Create a CloudFront distribution in front of your server, generate a certificate in ACM and forward traffic to your server as the origin (running http).
Related
I am deploying a MERN stack using EC2 on AWS.
I have created SSL certificates for the following domains:
example.com
*.example.com
www.example.com
The cname and cvalue for example.com and *.example.com are identical but they are different for www.example.com
I have set up target groups and a load balancer and edited the listener to redirect from http to https.
I have set up 3 different records in the hosted zone of route 53 so that www.example.com, *.example.com and example.com are directed to the loadbalancer
I can load https://example.com
http://example.com directs to https://example.com
When the website loads (either by typing http or https) it does not connect to the server.
I am getting the following error in the console:
Mixed Content: The page at 'https://example.com/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://54.220.212.131:5000/events'. This request has been blocked; the content must be served over HTTPS.
54.220.212.131 is the site's IP and 5000 is the server's port. This is hard coded in the front end.
How should I get the client to send requests to the server for a https connection?
It sounds like you have two services running, a front-end service that you have correctly configured to run behind a load balancer, and a back-end service that you are connecting directly to via the server's IP address on port 5000.
Your backend on port 5000 is not secure, and that is exactly what the web browser's error is telling you. You need to configure all your services to run behind the load balancer. You need to create a second target group that sends traffic to port 5000 on your server, and setup a routing rule on the load balancer's listener to send all traffic for api.ticketglen.com to that target group. Then you need to change your hard-coded values in from http://54.220.221.131:5000 to https://api.ticketglen.com.
What worked for me was to create the SSL certificates from the server and delete them and the load balancer altogether from the AWS platform.
Process is outlined here
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 trying to point CloudFront for my ec2 machine.
under origin, I am giving the public DNS name of the ec2 :(e.g. ec2-52-64-xxx-xxx.ap-southeast-2.compute.amazonaws.com)"
But I am getting this error:
I have opened 443 port also open on my ec2.
How can I solve this error?
Based on the chat discussion.
The application on the instance works over HTTP and port 80. It does not server HTTPS traffic in itself. So if you want to use the current setup with CF, you need to allow port 80 (not 443) and in CF using HTTP for origin protocol (not HTTPS). The way this works is that HTTPS and SSL will be only between client and CF, not between CF and your instance:
client----(HTTPS:443)--->CF----(HTTP:80)---->EC2 instance
As you can see above, there is a security issue. All traffic between CF and your instance will be in pain text over the internet. To rectify this, you need to add HTTPS to your instance. There are two ways for that:
Add load balancer in-front of your instance, and deploy custom domain on it with SSL from ACM and HTTPS listener. So the traffic will be:
client----(HTTPS:443)--->CF----(HTTPS:443)---->ALB---(private HTTP:80)--->EC2 instance
Setup SSL on your instance directly. For this you can't use ACM (except when your instance is enclave). Instead, you have to use third-party SSL provider. Common choice is https://letsencrypt.org/. Then you setup your Apache with the SSL certificate to serve HTTPS traffic. Subsequently, you will have:
client----(HTTPS:443)--->CF----(HTTPS:443)---->EC2 instance
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 a AWS LoadBalancer which created using Kube, Kops and AWS.
protocl type for the ELB is tcp. this work fine for http requests, means I can access my site with http://testing.example.com. Now I tried to add SSL for this ELB using ACM (Certificate manager). I added my Domain details example.com and *.example.com by requesting a public Certificate. it created successfully and domain validation is also success.
Then I tried to add this ssl to my ELB like below.
went to my ELB and selected the ELB.
Then went to Listeners tab and Added SSL to it like below.
and ELB description is like below.
I cannot access the https://testing.example.com, it hangs for few minutes and nothing happens. what is going on here. hope your help with this.
In the Listener configuration, you are forwarding the default HTTP port 80 to port 30987 on the back-end server. So this tells me that the back-end server is listening for HTTP requests on port 30987.
You then added an SSL listener on the default port 443 but you are forwarding that to port 443 on the back-end server. Do you have something on your back-end listening on port 443 in addition to 30987?
The most likely fix for this is to change the SSL listener on the load balancer to forward to port 30987 on the back-end by setting that as the "Instance Port" setting.
If your backend application (that sits behind the ELB) only listens on HTTP port 30987 then you need some layer of TLS termination before your app server.
More food for thought on this approach:
https://security.stackexchange.com/questions/30403/should-ssl-be-terminated-at-a-load-balancer
Or you need to tweak your backend app server to also listen on an HTTPS / TLS context, in a different port (which you must map in your ELB configuration).
BTW, I would also suggest to switch to and ALB or an NLB.
More info: https://medium.com/cognitoiq/how-cognitoiq-are-using-application-load-balancers-to-cut-elastic-load-balancing-cost-by-90-78d4e980624b
Once you finish the setup of whatever suggestion you picked, run curl -k -I https://testing.example.com/ to check whether of not you are getting blocked by the ELB.