How to run my website as https which is running as Docker swarm cluster in AWS? - amazon-web-services

I am working on docker swarm and aws. I am not having much idea in it.
Please correct me if my question is wrong and kindly help me to solve my problem.
I have my docker swarm cluster running in AWS under a loadbalancer.
I created a certificate from Amazon certificate Manager for https to my load balancer.
In loadbalancer tab under listener if I set https for load balancer protocol and http to instance protocol like below, when I type https://website-url in the browser it automatically redirects to http.
LoadBalancerProtocol LoadBalancerPort InstanceProtocol InstancePort Cipher SSL Certificate
HTTPS 443 HTTP 80 Change 6e7528d6-8261-4d61-b1d3-3c2548e1b575 (ACM) Change
But I want the website to be run as https not as http.
So I changed like below. That is making Instance port and its protocol as 443 and https.
LoadBalancerProtocol LoadBalancerPort InstanceProtocol InstancePort Cipher SSL Certificate
HTTPS 443 HTTPS 443 Change 6e7528d6-8261-4d61-b1d3-3c2548e1b575 (ACM) Change
But After this https://website-url is continuously running without any response in the browser.
After doing some search, I came to know that ACM certificate only works for load balancer not for backend instance.
That is for instance level I need to enable https for apache.
The docker swarm cluster has 1 manager and 3 worker nodes. All the host instance OS is Alpine OS. The containers inside the nodes are Centos-7.
The containers are running as a service in the cluster.
Please guide me on this,
Do I need to configure self signed certificate for apache inside the container or on the host instance.
I want my website to be run as https not http.
Kindly show me What are the steps required.
Thanks

The load balancer port is what people talk to your load balancer on, so load balancer port 80 and 443 is correct.
The instance port is what port the load balancer talks to your webserver on. In this case for you both should be 80, unless your webserver is listening on 443 with a valid SSL cert (Not the case as you are using an AWS cert.)
Then in your code or your webserver what you need to do is check the X-Forwarded-Proto header http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html and if it's not https re-direct to https.
https://www.allcloud.io/how-to/how-to-force-https-behind-aws-elb/ has a couple examples.

Related

How do you set up HTTPS (SSL) on a Flask application running in an EC2 instance with AWS ALB (Application Load Balancing)

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.

HTTP connection working on Elastic Load Balancer (Classic Load Balancer) but not on HTTPS

I am trying to set up an Elastic Load Balancer to be in front of my EC2 instance and redirect the traffic to it. My web app on EC2 is running HTTPS on port 3000. My ELB works nice when I start the web app over HTTP on port 3000 and I set up the ELB's port 80 to redirect HTTP traffic to HTTP 3000 of my instance. But when I start my app over HTTPS on port 3000 and then change the ELB's listeners, so it redirects HTTPS requests to port 80 to HTTPS 3000 of my instance, then the webpage does not work.
I have already created the SSL certificates, they are validated, uploaded to AWS Certificates Manager and my ELB is already taking them when serving HTTPS. My web app also has the certificate, so it's taking it to create the HTTPS environment on its side.
Also, my security group has connections on port 443 over HTTPS allowed.
Any suggestions, please?
Thanks in advance!

Enabling SSL on webserver running on AWS EC2/Docker

I currently have a docker container hosted on ec2 and running a web server. The IP Address resolves perfectly when running it with just the IP address not using https but, when I put in the DNS it does not work. I am currently have the node port mapped to port 80 in the initial dockerfile. Then I mapped port 80 to port 443 in hopes on creating a Load Balancer using a certificate from ACM. This is not a docker issue and I was hoping someone had some insight on how to configure a Load Balancer to use SSL to talk back to my web server that has port 80 exposed. When putting domain.io:443 I get the nginx screen.
configure a Load Balancer to use SSL to talk back to my web server that has port 80 exposed.
For that you require to setup HTTPS in your target group, not HTTP. Also it requires self-signed certificate SSL on the container to server the HTTPS traffic.

AWS Aplication Load Balancer HTTP to HTTPS with EC2 instance

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

added SSL does not work for AWS Load Balancer using ACM

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.