I'm trying to build a reverse proxy behind an AWS Classic Load Balancer, and I want to use the Via header.
As I understand Via, I should add the protocol version (eg HTTP/1.1 or just 1.1) to indicate the upstream client's request protocol version.
However, I don't see anywhere in the AWS documentation that the load balancer will pass that information on to my EC2 instances. Indeed, there is apparently no such thing as a X-Forwarded-Proto-Version header.
So how can I know the protocol version from behind an AWS Classic Load Balancer? What about the new Application Load Balancer? If that will do it where the Classic will not, I can upgrade.
EDIT (Apr 2019): We since upgraded to Application Load Balancer (ALB) for other reasons, and I can confirm that the ALB doesn't send the Via header, nor any other header that contains information about the client to ALB HTTP version. But ALB (and CLB) are a proxies and they should include the Via header, right?
Related
So, I'm working on a hackathon project right now, and for the demo, I've spun up a NodeJS Express server on an EC2 via Elastic Beanstalk. When testing the server's API with our front-end locally, it worked perfectly fine.
Now we've deployed our front-end to AWS Amplify, setup a domain name in Route53, and hooked everything up. When we go to the domain, our front-end looks great, but when we try using the functionality that would connect to our server's API, we get a net::ERR_SSL_PROTOCOL_ERROR.
Doing some research, it looks like(?) that we have to setup a certificate on the Classic Load Balancer that's in front of the EC2. So I requested a certificate, and created a listener on the Load Balancer as follows:
Load Balancer Protocol
Load Balancer Port
Instance Protocol
Instance Port
HTTPS
443
HTTPS
3000
But now I realize that if setup this way, I still have no idea how to point the React Frontend's API calls to the Load Balancer instead of the EC2, or whether the listener is setup correctly. Would anyone have an idea of what steps we should take here?
For the details of the app, the backend is a pretty straightforward Express App with CORS enabled, and the frontend is a fairly standard React project, nothing special about either of them.
Instance Protocol should be HTTP. So your setup uses HTTPS only between client and CLB:
Client--- (HTTPS) ---> CLB --- (HTTP) ---> EC2
Also for properly setup HTTPS, you need to use your own domain. You can't use default domain provided by EB for your application.
Setup: Play Framework application deployed on Amazon EC2 instances via ECS, Elastic Load Balancer in front. I want to allow only HTTPS requests for the application.
I found several ways to use HTTPS with Play, but what are the pros and cons, or which one is best practice for a (dockerized) Play app?
Enable HTTPS directly within Play (with -Dhttps.port or https.port in config file).
Set up a front-end web server (e.g. Nginx) and let it handle the HTTP->HTTPS rewrite (example).
Implement a request filter in Play and redirect the requests within the application (as described here).
I'm not so keen to use the first version as I would have to manage the certificates separately on each instance, but I listed it for the sake of completeness.
One advantage I can think of for the third approach must be that the system architecture is simpler than in the second version and requires less configuration. Are there any disadvantages (e.g. performance) to using the third approach?
If you are using a load balancer then you should request a free SSL certificate from the Amazon Certificate Manager service and then attach that certificate to the load balancer.
To enable HTTP to HTTPS redirects you simply need to check the x-forwarded-proto header that the load balancer passes to the server. If it is http return a 301 with https. The article you linked covers this part.
We have a web application that serves both secure and public endpoints. We are currently deploying it with elastic beanstalk.
From now on, we want to apply client certification for secure endpoints. i.e. for some endpoints, certification check is needed.
However, elastic load balancer has not any configuration to assign different ssl certificates for different routes.
The only solution that we found is; setting up nginx instances before the application load balancer and check certificates in here.
Is there a way to achive this on AWS?
Although I have not personally used one yet, I believe the new Application Load Balancers might be able to handle this. You can do different types of listeners depending on the request. So it's definitely worth looking into before you go the nginx route:
https://aws.amazon.com/elasticloadbalancing/
You can test one out by going into your EC2 services panel, and create a new load balancer. Choose the Application Load Balancer type and see if you can configure it as needed.
Authenticating clients with client certificates require all of the SSL to be handled by the instances themselves.
Load balancing such a setup requires either a Classic ELB in TCP mode (transparent, no HTTP interpretation, with SSL not configured on the balancer)... or a Network Load Balancer, which would probably be the optimal configuration since it is handled by the network infrastructure itself, and is essentially infinitely scalable with no warm-up required.
Elastic Beanstalk recently announced support for Network Load Balancer.
I am trying to configure an AWS Application Load Balancer (vs. a Classic Load Balancer) to distribute traffic to my EC2 web servers. For compliance reasons I need end to end SSL/HTTPS encryption for my application.
It seems to me the simplest way to ensure that traffic is encrypted the entire way between clients and the web servers is to terminate the HTTPS connection on the web servers.
My first question: Is it possible to pass through HTTPS traffic through an AWS Application Load Balancer to the web servers behind the load balancer in this manner?
From what I've gathered from the AWS documenation, it is possible to pass traffic through in this manner with a Classic Load Balancer (via TCP pass through). However, the Application Load Balancer looks like it wants to terminate the HTTPS connection itself, and then do one of the following:
send traffic to the web servers unencrypted, which I can't do for compliance reasons
create a new HTTPS connection to the web servers, which seems like extra work load
My second question: is that understanding of the documentation correct?
Terminating the SSL connection at the web servers requires you to change the load balancer listener from HTTPS to TCP. ALB doesn't support this, only classic ELB. Further, if you were terminating the SSL at the web server the load balancer wouldn't be able to inspect the request since it wouldn't be able to decrypt it, so it wouldn't be able to do all the fancy new routing stuff that the ALB supports.
If you actually want to use an ALB for the new features it provides, and you need end-to-end encryption, you will have to terminate SSL at the ALB and also have an SSL certificate installed on the web servers. The web server certificate could be something like a self-signed cert since only the ALB is going to see that certificate, not the client.
I assume you need end-to-end encryption for compliance reasons (PCI, HIPAA, etc.). Otherwise there isn't a very compelling reason to go through the hassle of setting it up.
A Layer 7 load balancer is more sophisticated and more powerful. It
inspects packets, has access to HTTP and HTTPS headers, and (armed
with more information) can do a more intelligent job of spreading the
load out to the target.
https://aws.amazon.com/blogs/aws/new-aws-application-load-balancer/
I understand the AWS Application Load Balancer has access to the HTTP(S) request headers but I can only see how you can route via the path. Can someone explain how I can route based on the user-agent header. If it's not possible, please suggest an alternative AWS method.
Till 2017-05-26 ALB doesn't have header based routing. With a update on 2017-04-05 it has included Host based routing. Currently it supports only path and host based routing. You can visit here for latest AWS information.
If you want to route based on headers ,currently there are no options in ALB.
You have to have an additional layer either like a proxy / nginx servers.
Flow can be something like this below.
Client calling https://example.com
ALB's DNS is configured to example.com
ALB has Target group attached to it which has nginx instances. Nginx instances routes to respective Load balancer with the header information. ( eg. if customerId is 123 route to ELB 1 else route to ELB 2 )
Two ELB has different EC2 instances attached to it.
But heard AWS is working on routing request based on the headers.
For anyone looking now, as of March 27 2019, ALBs now support routing based on HTTP headers other than the Host header.