Clarifying interaction of SSL, DNS, webserver - node.js

Please forgive the wishy washy nature of this question, I'm unsure how better to phrase it.
I have a nodejs server which will be accessed (HTTP + websockets) through a variety of third party DNSs by the third parties adding a new A record in their DNS entry pointing at my IP. I can find the origination third party DNS name by looking at the request headers. Node is then acting as a proxy and ultimately modifying the request headers/adding metadata before forwarding the request back to another url at the third party.
Could anyone explain please how SSL/TLS operates when the third party certificate is a wildcard cert for the origination DNS; how is the chain of encryption carried to node -> do I need to host a copy of the third party certificate on the node server? (Obviously I'd rather not). Can I use a third party's original SSL set up to any advantage?
Many thanks in advance!

DNS and HTTPS are fairly unrelated here. The client only uses DNS to find the web server's IP address. After that, the http protocol contains the Host name it is requesting in the Host header, as you have determined.
Your server will need an HTTPS certificate for each Host name that is will handle requests for, otherwise browsers will not be able to make a trusted connection to it. The certificate says "This server is authorized to handle requests for this host name".
In practice, though DNS and HTTPS are related, because if you control dns, you can issue a certificate. Let's Encrypt has made this very easy to set up.
I would not recommend sharing certificates with third parties, as that can be a bit of a pain, and it is harder to keep private keys secure if you are emailing them back and forth or something. Just issue your own certs for the third-party domains you need to serve.
My personal favorite solution for a case like yours is running a caddy server instance in front of my app to manage https certificates automatically, and proxy requests to your node backend. It can even issue certs dynamically as it receives requests.

Related

Setting up secure web sockets (wss) service for my https web app

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.

SSL certificate without a domain

I have a bunch of node.js apps serving information to an apache site via websockets (ws://). The site itself doesn't have a domain name and is accessed through its IP address (that's non-negotiable, unfortunately...)
The problem is the following :
Without a secure connection, browsers will block the ws://
traffic, so I have to use SSL and secure websockets wss://
Without a domain name, I cannot secure the connection except by
generating a self-signed certificate.
Self generated certificates are not trusted by browsers and
display an error 'certificate not trusted...'. Last chrome update
made it even more annoying to get through the message.
In addition to that, the IP changes regularly and is sent to the users (2-3 people) when it happens. So a certificate issued for a specific IP wouldn't be ideal (if it's free I can deal with the hassle of refreshing the cert).
Does anyone have a solution ?
If you only have a user or two, you could create your own CA, and have each person install it on their browser. You would still need to update the cert every time the IP changes though. google.ca/search?q=create+your+own+ca

Is it possible to spoof or impersonate a destination (server) IP?

Is it possible to spoof or impersonate a server's IP?
So that clients wanting to connect to that Server's IP, would actually connect to the attacker's machine?
But the attacker would still be able to contact the actual server.
This is all TCP/IP based, no name resolution, and all machines are on the same network or the internet (No NAT-ing).
I am working on a networking application, and I would like to build in some authentication.
What I need to do is to authenticate the server by IP. In other words, I want to make sure that when I open a HTTPS URL to an IP Address, it will go to the machine that has that IP.
Other notes:
All communication would be over TLS, but certificates would be blindly accepted.
What I need to do is to authenticate the server by IP. In other words, I want to make sure that when I open a HTTPS URL to an IP Address, it will go to the machine that has that IP.
This is one of the features of HTTPS (SSL/TLS) - it can prevent a MITM attack and prevent the destination server from being impersonated.
Other notes: All communication would be over TLS, but certificates would be blindly accepted.
This is great, however you will need to stop certificates from being blindly accepted. You should check that the common name or subject of the certificate matches the server that you are expecting to make contact with. You should also check that the root certificate is one that you choose to trust (you could make your own root certificate that is trusted). This will prevent the server certificate being spoofed by an attacker as they will not be able to sign the certificate with the root certificate.
An alternative is certificate pinning. This will enable your application to only communicate with a pre-set list of trusted certificates that are either hard coded into your application, or that are otherwise inaccessible to outsiders on your application server.
Yes, if you can perform man-in-the-middle attack. Evil transparent proxy in your LAN can do it.

SSL Certificate Alternatives for Server to Server Communication

I am developing a Node.js app based on the Express framework. On the backend, I need to have servers talk to each other (ie. Server 1 make a request of Server 2).
Is it OK to forego a DNS A-Record and just use the IP address of the server?
In that case, how do I authenticate the server and "client" (aka server). I was thinking of requiring the server and "client" to each pass a secure cookie with their request and responses. The secure cookie would then be verified before any other action was taken.
Using a IP might be more secure then DNS (e.g. no DNS spoofing), but it still allows ARP spoofing, e.g. some other computer claims to have this IP. And in case both computers are not in the same network there are also ways to hijack requests in routers etc.
The secure cookie is nothing else as a shared secret. And contrary to public key based authentication (e.g. using certificates) shared secrets have the disadvantage that you need to distribute them in a secure way so that nobody else gets access to them.
I don't think that your idea is easier to handle than SSL with certificates, so I don't see an advantage of making your own secure protocols. History tells us, that such homegrown protocols mostly provide worse security than established solutions.
If you don't care about security (these hosts are on your network, in which you have trust), don't bother with the homebaked cookies.
If you do care about security get (or generate your own) certificate and use SSL.
I was thinking of requiring the server and "client" to each pass a secure cookie with their request and responses. The secure cookie would then be verified before any other action was taken.
This is not secure at all! Anybody situated on an appropriate network between the client and server can see that "secure cookie", as well as any subsequent communications. This would allow them to reuse that cookie themselves to impersonate either the client or server, and would expose any sensitive information sent in the exchange.
Use SSL. It has already solved all of these problems, and more.

Does Azure offer https for "cloudapp.net"?

One great advantage of using Azure Websites is that I can get secure HTTP (HTTPS) without doing nothing: I simply type https://xyz.azurewebsites.net and it works. I don't have to worry about certificates because I use the subdomain that Azure gives me (in the example it would be xyz)
So, what I usually do is that people come by through some registered domain I have, eg. http://www.my-application-homepage.com, and there, if they want to use my application, I redirect them to the subdomain at azurewebsites.net, using HTTPS.
Now, having said that:
I'm in need of upgrading to Azure Cloud Services or Azure Virtual Machines, because these have capabilities that Azure Websites don't . These two also offer a free subdomain: xyz.cloudapp.net, but my question is: will I get HTTPS there too? and how?
I searched in google for some cloudapp examples and what I tested was the following:
1) Connect through HTTP (ie. type http://xyz.cloudapp.net). Result: worked
2) Connect through HTTPS (ie. type https://xyz.cloudapp.net). Result: didn't work (chrome gave ERR_CONNECTION_TIMED_OUT)
No. HTTPS is not offered for .cloudapp.net domain as of today. Also since you don't own .cloudapp.net domain, I don't think you can buy a SSL certificate for that. If you want you could create a self-signed certificate and use that.
I would walk through the documentation listed here:
http://azure.microsoft.com/en-us/documentation/articles/cloud-services-configure-ssl-certificate/
Since you're getting a timeout with HTTPS (rather than a certificate error), check that you have a HTTPS endpoint defined in ServiceDefinition.csdef.
Additionally, be aware that the redirect-to-subdomain approach isn't much more secure than using a self-signed certificate. The reason browsers reject self-signed certs is that they are vulnerable to spoofing attacks: a user can't detect if an attacker has, for example, hijacked the DNS to point to his IP address instead of yours, where he hosts a facade of your site that just collects passwords or whatever.
In your scenario, the cloned site could redirect to another a second clone, one that is a facade of your cloudapp.net site. It could be even be secured with the attacker's SSL certificate. Unless the user was trained to recognize the host name of the real cloudapp.net, she wouldn't know she was on the attacker's "secure" site.
** Update: This method is not valid as well, we got the certificate revoked after one week using it **
We use this approach for staging/dev servers:
If you don't want to use a self-signed certificate, one option is to purchase a cheap SSL certificate, e.g.:
https://www.ssls.com/comodo-ssl-certificates/positivessl.html
Then once you need to approve it you have to ask support to change the approver validation process: instead of sending an email to a admin#mydomain.cloudapp.net you can ask to change the validation process to placing a given file with a given file in the root of your website (you have to ask in the support / chat room about that option).
More info:
https://support.comodo.com/index.php?/Default/Knowledgebase/Article/View/791/16/alternative-methods-of-domain-control-validation-dcv

Resources