Determine SSL connection behind a load balancer - ssl

Looking for best practice here. We deal with SSL connection at our load balancer level and hence all the connection from our load balancer to our web servers are http. With that we have no way of telling what kind of connection the client is making to our web server since all connection is through http. We currently have 2 solution, one is to have the load balancer to append a port number in the URL string so that we can determine the kind of request (ex. 80 for http and 443 for https). The other solution is for the load balancer to append a special header when it get https request so the web servers knows the type of connection.
Do you see cons in both solution? Is there any best practice regarding SSL being applied at the load balancer level instead of web server level?

I would prefer the header, I think. Adding something in the URL creates the possibility, however slim, that you'll collide with a query string parameter that an app wants to use. A custom header would be easier.
A third option could be to have ssl connections redirect to a different port, say 8080, so on the back end you know that port 80 connections were http to begin with, and port 8080 connections were 443 to begin with, even though they're both http at that point.

I suggest using the header. A related concept is determining the IP address of the client (for logging purposes), since all requests to your web server appear to originate at the load balancer. The x-forwarded-for header is customarily used here.

Related

Best practices for setting up a MERN application on AWS

I know this is subjective and opinionated, but I just need something to start off from knowing what the best practices may be.
I've got a MERN application running on localhost with the React script currently running on port 3000 and an Express.js application running on port 3001.
Now I'm about to set it up live on AWS and am wondering if I should create it like:
website.com for the frontend React stuff with nginx routing anything from port 80 to 3000 while it makes calls to api.website.com running on 3001 on the same instance with website.com and `api.website.com having the same IP address.
or
one separate instance for website.com on a different IP address and another instance for api.website.com on a different IP address for API calls? Both are being accessed without having to specify a port.
I'm curious because most of the time I've used APIs, they don't have a separate port, just a subdomain on what I assume was a different IP address and a different instance.
What would be the best way to set this up keeping in mind I want to use SSL?
Serving static applications via SSL is not necessary, but on the other hand, your server application has to be secured. Part of the stack which interacts directly with the database is very crucial and has to be secured against all sorts of vulnerabilities. Only SSL won't do any good unless you follow best practices to secure your node application.
You can use the subdomain for the node application and root domain for the actual site. Also, you can use the 80 port for the website and 443 for your node application by defining different server sections inside your nginx configuration file.
Below are some links where you can find the best practices to follow while deploying node applications on production.
https://www.moveoapps.com/blog/set-node-js-application-production-nginx-reverse-proxy/
https://blog.risingstack.com/node-hero-node-js-security-tutorial/
I would say Nginx exposed to the world, with an SSL certificate and all traffic redirected to port 443.
Everything else bound to 127.0.0.1 and proxied through Nginx. It's simple to set up Nginx to accept requests to api.website.com on port 443 and then proxy them over to 127.0.0.1:3000 or 3001 or whatever.
Then firewall all the other random ports and route absolutely all incoming traffic through Nginx.

Will routing traffic to proxy break SSL?

I've been wanting to setup a linux VirtualBox instance and use iptables to route traffic from other VMs through it and on to an external SOCKS proxy server. However, I have recently read that transparent proxies like this break HTTPS transmissions and that this is part of the design – to prevent man-in-the-middle attacks. If I want this to work, I'll need to configure the proxy inside the browsers of the VM clients for port 443. Are there any other options I could explore to achieve my goal?
To access a SOCKS server each TCP connection must be prefixed with the necessary SOCKS header. That means, that a simple redirect is not possible. You need instead a protocol converter like redsocks or transocks (never used these, but from the description they do what you need).
Apart from that it is not a problem to simply redirect HTTPS traffic or use these protocol converters, as long as you don't change the SSL stream itself. The only problem is if transparent proxies try to intercept and re-route this traffic to other sites (like redirecting to a capture portal) or try to decrypt the connection in order to analyse it (like in firewalls). These kind of interceptions will be noticed from the browser, because either the name in the certificate does not match the target name and/or the issuer of the certificate is not trusted.

Delay issue with Websocket over SSL on Amazon's ELB

I followed the instructions from this link:
How do you get Amazon's ELB with HTTPS/SSL to work with Web Sockets? to set up ELB to work with Websocket (having ELB forward 443 to 8443 on TCP mode). Now I am seeing this issue for wss: server sends message1, client does not receive it; after few seconds, server sends message2, client receives both messages (both messages are around 30 bytes). I can reproduce the issue fairly easily. If I set up port forwarding with iptable on the server and have client connecting directly to the server (port 443), I don't have the problem Also, the issue seems to happen only to wss. ws works fine.
The server is running jetty8.
I checked EC2 forums and did not really find anything. I am wondering if anyone has seen the same issue.
Thanks
From what you describe, this pretty likely is a buffering issue with ELB. Quick research suggests that this actually is the issue.
From the ELB docs:
When you use TCP for both front-end and back-end connections, your
load balancer will forward the request to the back-end instances
without modification to the headers. This configuration will also not
insert cookies for session stickiness or the X-Forwarded-* headers.
When you use HTTP (layer 7) for both front-end and back-end
connections, your load balancer parses the headers in the request and
terminates the connection before re-sending the request to the
registered instance(s). This is the default configuration provided by
Elastic Load Balancing.
From the AWS forums:
I believe this is HTTP/HTTPS specific but not configurable but can't
say I'm sure. You may want to try to use the ELB in just plain TCP
mode on port 80 which I believe will just pass the traffic to the
client and vice versa without buffering.
Can you try to make more measurements and see how this delay depends on the message size?
Now, I am not entirely sure what you already did and what failed and what did not fail. From the docs and the forum post, however, the solution seems to be using the TCP/SSL (Layer 4) ELB type for both, front-end and back-end.
This resonates with "Nagle's algorithm" ... the TCP stack could be configured to bundling requests before sending them over the wire to reduce traffic. This would explain the symptoms, but worth a try

Fiddler: Can I redirect outgoing traffic from foreign console app to Fiddler instance (localhost:8888)?

I am looking for a way to forward traffic from an application which goes to the web over port 443 to an instance of Fiddler running on my computer. Fiddler does not see this traffic while a packet trace application verified that the traffic is going out.
The application is foreign and I am not able to modify how it requests and it is not going through Internet Explorer (or apparently any other browser). If this app is going to an ip address (ie. 66.xxx.xx.xx port 443) or to a named host (ie. https://www.anysite.com), is there a way to tell my computer to forward this traffic to Fiddler, ie. to localhost port 8888?
I am not sure I am using the right terminology to describe this but and ideas would be appreciated!
Thanks,
David
If you can't get the application itself to send traffic to localhost on a specified port, then you need something lower level than Fiddler. Try WireShark.
http://www.wireshark.com/
#David: What's the application in question? Virtually all applications can be proxied, because those that can't aren't usable from most corporate networks. In some cases, you have to make minor changes to the environment (e.g. setting the proxy for the JVM). Some details are here: http://www.fiddler2.com/fiddler/help/hookup.asp
Using Netmon or Wireshark, you should be able to determine whether or not the application in question is making a request directly to a fixed IP address, or more likely, doing a DNS lookup first. If it's doing a DNS lookup first, you could edit your Windows Hosts file so that whateverthehostis.com points at 127.0.0.1. Because the hosts file only maps host to IP and not port to port, you'll need to adjust Fiddler to run on the target port that the application is looking for (use Tools > Fiddler Options for that).
Now, if the traffic is HTTPS (and I'm guessing it is) you're going to have a problem at that point, because Fiddler currently can only act as a HTTPS endpoint when it "knows" that the traffic is HTTPS by virtue of the client having opened a CONNECT tunnel first. This is something that could be adjusted in a future version of Fiddler, but it's not a common request.

Can HAProxy front both Web servers and SSL VPN on one IP and port?

I need a Reverse Proxy to front both Lablz Web server and SSL VPN Adito (SSL Explorer fork) by sitting on one IP/port. Failed to achieve that with Nginx. Failed to use Adito as a generic reverse HTTP proxy.
Can HAProxy fall back to being a TCP proxy if it does not sense HTTP traffic?
In other words can it fall back to Layer 4 if its Layer 7 inspection determines this is not HTTP traffic?
Here is my setup
EC2 machine with one public IP (Elastic IP).
Only one port is open - 443.
Stunnel is sitting on 443 and is passing traffic to HAProxy (I do not like to use Stunnel but HAProxy does not have full support for SSL yet, unlike Nginx).
HAProxy must be configured to pass some HTTP traffic to one server (Apache server which fronts the SVN server) and the rest of the HTTP traffic to our Lablz Web/App server.
All non-HTTP traffic must be forwarded to Adito VPN.
This traffic is:
VNC, NX, SMB
... and all other protocols that Adito supports
I can not rely on source IP address or port to split traffic into HTTP and non-HTTP.
So, can such config be accomplished in HAProxy? Can any other reverse proxy be used for this? Let me know if I am not thinking right about HAProxy and an alternative approach is possible.
BTW, Adito SSL VPN is amazing and if this setup works we will be able to provide Lablz developers with a fantastic one-click single-login secure VNC-over-HTTPS access to their boxes in the cloud.
No solution exists for this but via Adito - please prove me wrong. But please do not say that VNC over SSH is better. Yes, VNC-over-SSH is faster, more secure, but also is much harder (for our target user base) to setup and presumes that user is behind the firewall that allows outbound traffic on port 22 (not always the case).
Besides, Adito is much more than the remote access gateway - it is a full blown in-browser VPN, a software distribution platform and more. I am not associated with Adito guys - see my Adito post on our Lablz blog.
OK, first off, I'd use a simple firewall to divide all HTTP from NON-HTTP traffic. What you need is packet inspection to figure out what it is that is coming in.
Neither haproxy or nginx can do that. They are both made for web traffic and I don't see how they could inspect traffic to guess what it is that they are dealing with.
Update: Looked into this it a bit and with iptables you could probably use string matching to devide the traffic. However, that's all tricky, especially with the encrypted nature. A friend of mine discovered l7-filter and this looks like what you need. Let me know if this helps.