SSL_CLOSE_NOTIFY Not received by client when nginx proxy is used - ssl

I am using Nginx proxy server as a reverse proxy and https load balancer. Client connects to backend server through the reverse proxy in a load balanced environment. I have setup the correct https configuration (with ssl certificates and all) so that my ssl communication is going through proxy. The only problem I am facing is client don't get SSL_CLOSE_NOTIFY When sever disconnects the connnction gracefully. ( in my case server always disconnncts the connection) . My client and server are running fine without any problem , But in case of nginx proxy ssl close notifiy is not received by client.

I found the solution so copying it here.
This was happening because the connection was closed by server forcibly by server before client receives SSL_CLOSE_NOTIFY. This was happening because proxy_read_timeout and client_body_timeout was missing from nginx.conf.

Related

Multiple application under SSL (TCP 443)

I implemented a server with two deploy of different services(Apache and OpenFire).
And I want to implement https for my server, so my question is.
How to implement the SSL certificate on my server with two different application working with different ports?
I was looking about how to create a NAT network but I'm not sure if this is the best way to do it.
Apache is an HTTP Server and for SSL by default HTTP Servers use 443 port.
However, Openfire in an XMPP Server and you can enable TLS in it which will by default use 5222 port. And for Openfire's admin application, HTTPS will be on 9091 port by default.
So you can have both servers on same machine with SSL enabled.

Running Fiddler as a Reverse Proxy for HTTPS server

I have the following situation: 2 hosts, one is a client and the other an HTTPS server.
Client (:<brwsr-port>) <=============> Web server (:443)
I installed Fiddler on the server so that I now have Fiddler running on my server on port 8888.
The situation i would like to reach is the following:
|Client (:<brwsr-port>)| <===> |Fiddler (:8888) <===> Web server (:443)|
|-Me-------------------| |-Server--------------------------------|
From my computer I want to contact Fiddler which will redirect traffic to the web server. The web server however uses HTTPS.
On The server I set up Fiddler to handle HTTPS sessions and decrypt them. I was asked to install on the server Fiddler's fake CA's certificate and I did it! I also inserted the script suggested by the Fiddler wiki page to redirect HTTPS traffic
// HTTPS redirect -----------------------
FiddlerObject.log("Connect received...");
if (oSession.HTTPMethodIs("CONNECT") && (oSession.PathAndQuery == "<server-addr>:8888")) {
oSession.PathAndQuery = "<server-addr>:443";
}
// --------------------------------------
However when I try https://myserver:8888/index.html I fail!
Failure details
When using Fiddler on the client, I can see that the CONNECT request starts but the session fails because response is HTTP error 502. Looks like no one is listening on port 8888. In fact, If I stop Fiddler on the server I get the same situation: 502 bad gateway.
Please note that when I try https://myserver/index.html and https://myserver:443/index.html everything works!
Question
What am I doing wrong?
Is it possible that...?
I thought that since maybe TLS/SSL works on port 443, I should have Fiddler listen there and move my web server to another port, like 444 (I should probably set on IIS an https binding on port 444 then). Is it correct?
If Fiddler isn't configured as the client's proxy and is instead running as a reverse proxy on the Server, then things get a bit more complicated.
Running Fiddler as a Reverse Proxy for HTTPS
Move your existing HTTPS server to a new port (e.g. 444)
Inside Tools > Fiddler Options > Connections, tick Allow Remote Clients to Connect. Restart Fiddler.
Inside Fiddler's QuickExec box, type !listen 443 ServerName where ServerName is whatever the server's hostname is; for instance, for https://Fuzzle/ you would use fuzzle for the server name.
Inside your OnBeforeRequest method, add:
if ((oSession.HostnameIs("fuzzle")) &&
(oSession.oRequest.pipeClient.LocalPort == 443) )
{
oSession.host = "fuzzle:444";
}
Why do you need to do it this way?
The !listen command instructs Fiddler to create a new endpoint that will perform a HTTPS handshake with the client upon connection; the default proxy endpoint doesn't do that because when a proxy receives a connection for HTTPS traffic it gets a HTTP CONNECT request instead of a handshake.
I just ran into a similar situation where I have VS2013 (IISExpress) running a web application on HTTPS (port 44300) and I wanted to browse the application from a mobile device.
I configured Fiddler to "act as a reverse proxy" and "allow remote clients to connect" but it would only work on port 80 (HTTP).
Following on from EricLaw's suggestion, I changed the listening port from 8888 to 8889 and ran the command "!listen 8889 [host_machine_name]" and bingo I was able to browse my application on HTTPS on port 8889.
Note: I had previously entered the forwarding port number into the registry (as described here) so Fiddler already knew what port to forward the requests on to.

How apache reverse proxy can be configured without breaking the https tunnel between client & server?

I have configured apache reverse proxy. In that configuration https connection is possible between client to reverse proxy and again reverse proxy to server. But I want https connection between client to server like forward proxy. The https connection should not be broken at reverse proxy.
Https tunnel New Https tunnel
<===============> <===================>
Client-----------------------Apache Reverse proxy ----------------------------Server
Above solution is not desirable.
Https Tunnel
<========================================>
Client--------------------Apache Reverse proxy ----------------Server
Above solution is desirable.
If end to end https tunnel is not possible in reverse proxy then how can it be ensured that ssl proxying option is safe and even the Reverse proxy administrator(if reverse proxy got compromised) can not decrypt the tunnel or man in middle attack can't be done.
You can't. Because HTTPS by design guarantees that the sender is talking to the receiver via certificates. Your proxy here would be "the man in the middle" :-)
See http://en.wikipedia.org/wiki/Reverse_proxy
In the case of secure websites, a web server may not perform SSL
encryption itself, but instead offloads the task to a reverse proxy
that may be equipped with SSL acceleration hardware. (See SSL
termination proxy.)
What you can do
Client------Apache Reverse proxy----SC--------------SS---------Server
HTTPS SSL HTTP
(listen to 443)
Where SC = Stunnel Client and SS = Stunnel Server
SC must run in the same machine as your apache reverse proxy, while SS must run in your server target.

https requests using a proxy

Let's say you want to perform an https request to a certain website but you have a proxy on the middle.
The aforesaid proxy doesn't look into the request but just relay all the traffic to the actual HTTPS server after the user-agent has used the HTTP CONNECT method (as in http://www.web-cache.com/Writings/Internet-Drafts/draft-luotonen-web-proxy-tunneling-01.txt).
Now my question is the following: after the proxy opens a SSL connection to the destination webserver, should it also upgrade the socket which handles the connection with the client to SSL as well? And if so, how would it forward packets to the server without sniffing the actual content?
What I mean here is that if the proxy actually reads data from SSL client socket and forwards them to SSL server socket, the data will be not encrypted to it.
The proxy has a plaintext connection open to the client, via which it received the CONNECT command. It opens a plaintext connection to the server. Thereafter it just copies bytes in both directions. The bytes coming from both client and server are SSL, so this works without the proxy knowing what's inside the ciphertext.

HTTPS Web(only)Proxy

I just read over node-tls-proxy (http://code.google.com/p/node-tls-proxy/), a https proxy. I like the idea of it, but I'm not getting why this proxy needs a local http server (see the local-proxy.js script).
So I was wondering if this is necessary?
My idea of the proxy was actually like this: Client -> HTTPS Connection to trusted Server/Proxy -> Internets
In this case network sniffing between the Client and the Server wouldn't (hardly) be possible because it would be ssl encrypted.
Thanks,
Seb
If I get the idea correctly, the goal is to set up a "remote" proxy in a location that one trusts to be secure. Your client shall only communicate with this remote proxy using TLS, the remote proxy is then allowed to do the actual (no longer encrypted) HTTP requests.
What you do on the client side now is this: you configure the "local" proxy in your browser. Since you type "http://..." in your browser even when using the proxy, your browser will initiate an unencrypted HTTP connection to the local proxy first. Then the local proxy will open an encrypted TLS connection to the remote proxy and forward your request over a secured channel.
This means you need the local proxy for the purpose of "transforming" HTTP into HTTPS requests because your browser will dutifully only use HTTP when asked to make an actual HTTP request.