We want to establish a TLS encrypted connection between a node.js client behind our company proxy and a node.js server in the internet (which we control, too).
I am confused by this issue, how can we keep our certificate based security approach with TLS through a proxy?
A TLS proxy is transparent. The client sends a CONNECT request, which has the target host name and port, then the proxy creates a new TCP connection to that host, and after that does nothing else than move packets between the client and the server connection.
So from the client's point of view, the certificate the client retreives from the proxy will be exactly the bytes the server sent.
On the server side, the IP you'll be seeing is that of the proxy, not that of the client. So you shouldn't use a server certificate in the client, as the CN from the certificate and the IP / reverse looked up host name won't match. But if you use a client certificate, the proxy will again pass it to the server without modifying anyting - so if you do some "was this client certificate signed by a CA i trust" checking on the server, everything will work fine.
Related
I am using pyhthon3 requests library and want to request some resources from the server using HTTPS. So I use two way SSL authentication, and I have configured the server in a way which do not REQUEST for client certificate in response of 'client Hello' request.
As You can see IP xxx.xx.xxx.100 is the client and IP xxx.xx.xxx.207 is the server. So when the client sends 'Client Hello' to the sever, in response the server does not REQUEST for the client certificate, even though its two way SSL authentication.
So as per my requirements, how can I stop the process of handshaking and data sharing immediately in such case? Or how to force the server to REQUEST for client certificate?
... even though its two way SSL authentication.
It's not. Just because the client has the certificate to do mutual authentication, does not mean that this certificate is actually used. It is only mutual authentication if the server actually requests it using a CertificateRequest (which is clearly not done) and the client then providing the requested certificate.
... how can I stop the process of handshaking and data sharing immediately in such case?
You can't. There is no API for this.
And I'm not sure what kind of sense such a requirement would make. The client has successfully authenticated the server which should be all needed by the client to exchange data with the server. The server instead might want to know who the client is before sending specific data. So authenticating the client before providing such data makes sense from a server perspective, but not from a client one. This would be like you refusing to drive a car if nobody is checking your drivers license.
Or how to force the server to REQUEST for client certificate?
This fully depends on the kind of server. Different servers need different configuration. For example with nginx see ssl_verify_client.
In the case where its beeing used a websocket protocol between a client (webpage) and a server.
Is it possible for third parties to spoof the connection in the handshake or even after the connection has been established?
Websockets do not directly provide authentication. If you build it over TLS (i.e. WSS), then you will use the TLS session to authenticate the parties using server and client certificates, exactly like HTTPS vs HTTP.
If you build your websocket over HTTP, then yes, it is completely possible for a third party to spoof the connection (and also to eavesdrop). If your HTTPS/WSS system does not properly validate certificates, then that also can be spoofed.
We've got a setup, where SSL/HTTPS stuff is managed by Cloudflare.
What is the proper way to run Node.js HTTPS server in this case?
I've tried running it like this and it's working, but what are the downsides?
const app = express()
const httpsServer = https.createServer({}, app) //creating https server with an empty ssl certificate object
httpsServer.listen(443)
I've tried running it like this and it's working,
By this, I assume you're using Flexible mode?
When in Flexible mode, it gives you the illusion of security, but in actuality
client-server connection is only half-secured.
Cloudflare Universal SSL Certiticate
|
Client <----HTTPS-----> Cloudflare <------HTTP-----> Origin Server
Surely you've heard of MITM (man-in-the-middle) attacks or state-sponsored surveillance over insecure channel (read: HTTP)? These are the downsides when your connection is not fully encrypted end-to-end.
For you to secure the connection end-to-end, you'll need to use Full/Full(Strict) mode, and for this to work you'll need to specify the certificate on the origin server. Opening port 443 and put it on listening mode is not enough, HTTPS uses Public Key Infrastructure (PKI) and SSL certificates are fundamental part of it. In other words, you simply can't use HTTPS without SSL certificates in place!
Cloudflare Universal SSL Certiticate Origin Certificate
| |
Client <----HTTPS-----> Cloudflare <------HTTPS-----> Origin Server
Provisioning a self-signed certificate on the origin server will suffice for Full mode, but Full(Strict) mode requires a valid certificate. Good new is that you don't need to purchase Extended Validation (EV) certificates from retail Certificate Authority (CA), as nowadays there are free Domain Validation (DV) certificates such as Let's Encrypt/Certbot or Cloudflare Origin CA certificate which would work just as fine.
I have a website running on a nodejs server. The website contacts an API which is present on another server. Now, I want to make the connection secure by using SSL. So, I have a self-signed certificate on the API server. My question is that how do I make the nodejs server trust thes self-signed certificate and accept a connection to it.
I have this web app that is served via https, and now it needs to use a websocket service that is served from another server. Chrome, Firefox and Internet Explorer complain right away that if the application is secure (https), then it is not allowed to connect to an insecure websocket service (ws:// URI). Strangely, Apple Safari doesn't complain so.
Well, fair enough, I assumed any globally trusted certificate would be fine to be installed at the websocket server side, to enable secure service (wss:// URI). However the company that maintains the socket server claims that they have to install there the very same certificate that secures my web application. I read in webs that the wss will not run with self-signed certificate, but nowhere that it must be the same certificate that the calling web site runs on.
Since we are talking sharing a certificate key file with 3rd party, I wanted to double check this. If my secure site runs at domain first.com, and the websocket server at IP address a.b.c.d, what kind of certificate should be installed on the websocket server to enable the communication? On one hand, that would be a kind of cross-site scripting, but perhaps the browser security model allows it, assuming the user knows what they want?
What I understand from above, the browser connects to your web application and is then redirected to the other server. If that be the case, then browser would complain about being redirected to unsecured site from a secured URL. The way forward actually depends on the domain of the server that the redirect is happening to, for example, if your main site has URL form www.mainsite.com and the target site has URL form abc.secondsite.com or an IP, the second server must have configured an SSL certificate that has been issued to either abc.secondsite.com of the IP i.e. the name of the host requested must match exactly with the SSL ceritficate that is provided by the secondsite.
The secondsite technically does not have to have the same certificate as your mainsite, it just have to be a certificate issued by a trusted source (like Verisign etc.).
On the other hand, if you have a wildcard subdomain certificate i.e. a certificate issues is valid for all the *.mainsite.com domains and the URL form of the secondsite is sub_domain.mainsite.com, then the same certificate can be used on both the servers.
Hope this helps.
thanks
Since we are talking sharing a certificate key file with 3rd party, I
wanted to double check this. If my secure site runs at domain
first.com, and the websocket server at IP address a.b.c.d, what kind
of certificate should be installed on the websocket server to enable
the communication? On one hand, that would be a kind of cross-site
scripting, but perhaps the browser security model allows it, assuming
the user knows what they want?
You cannot provide a certificate for an IP address. In order to use WSS:// you need to connect to a domain name, and have a valid certificate for that domain name. So you need a SSL certificate for the domain name of your WebSocket server.
As far as I know, it does not need to be the same than the one on the site. You can check by entering here: http://vtortola.github.io/ng-terminal-emulator/ and executing the command websocket wss://echo.websocket.org, you will connect to a WebSocket in websocket.org that echoes your inputs.
WebSockets are not constrained by the SOP (Same Origin Policy), you can connect anywhere, and the server is responsible of checking the HTTP request header "Origin" and accept or refuse the connection.