Multiple subdomains with SSL under IIS [closed] - iis

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
I currently need to have 2 subdomains under the same domain under SSL.
Both subdomains (www and affiliate) are on the same IIS server, under the same IP, and each one has specified a host header value (www.mydomain.com and affiliate.mydomain.com)
The first subdomain (www), which is the default, works great, with and without SSL.
The second subdomain works perfect under HTTP.
The problem is that I just purchased and installed the SSL certificate for the affiliate subdomain, and when you go to https://affiliate.mydomain.com, you get redirected to http://www.mydomain.com
I'm guessing the problem lies in the fact that I can't specify a host header value for SSL? (the dialog where I normally set the host header value doesn't have that option in the bottom part, dedicated to SSL).
What can I do about this?
Should I have each subdomain in a separate IP?
Is this not doable at all?
Thanks!
Daniel

"I'm guessing the problem lies in the
fact that I can't specify a host
header value for SSL"
You guessed right. You will need two IP addresses.

The problem is fundamental to the way HTTPS works.
Virtual hosting relies on the "Host" header introduced in HTTP/1.1. That's part of the HTTP protocol, but from the standpoint of the SSL protocol, the HTTP layer is "application data", and can't be transmitted until the SSL handshake has been completed.
However, the server certificate is presented during the handshake. The HTTP server hasn't seen the "Host" header yet, so it wouldn't know which certificate to send. Using a distinct IP address works, because that's visible at the IP layer below SSL.
Update: There's a new TLS extension that allows clients to indicate the server they intend to use during the handshake. See dlongley's answer for more information.

I am not sure what web server you are running, but in IIS 6 on windows server 2003, you can use host headers for SSL sites, thus allowing them to be on the same IP Address.
http:// www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/596b9108-b1a7-494d-885d-f8941b07554c.mspx?mfr=true
EDIT: This will only work if the certificate is a wildcard certificate. Otherwise, subdomain "affiliate" will try to use the same certificate as subdomain "www", and visitors will get a warning.

This probably won't help you, but hopefully it's informative.
There's an extension to the TLS protocol that some TLS clients use called Server Name Indication (SNI). This extension allows TLS clients to specify the hostname of the server they are trying to contact. So when the client connects and sends a ClientHello message within the TLS protocol, the server can decide which certificate to respond with. This makes virtual SSL/TLS servers possible on a single IP.
OpenSSL provides callback functions to allow you to read what hostname the client sent and handle fetching the appropriate certificate, but unfortunately I have no idea if this is possible with IIS.

In the particular situation you are where you need 2 subdomains of the same domain a WildCard certificate has to work... I use a wildcard cert since 3 years for dozens of sites, and no customer has reported errors
If you have something telling the cert is for "www", then your cert is not a true wildcard cert, or you are experiencing some kind of browser caching issues or you are using 2 copies of the cert and you updatet only one of them, or you forgot restarting the server, or .. I donno :)

Related

Https and SSL issue with port 80

Recently I just start using https:// for my server and the strange thing is that I can open if I explicitly type "https://www.example.com:80" but won't be able to connect if i type "https://www.example.com".
I am using NodeJS with Express 4 framework hosted on Digital Ocean.
What can I do to let people access my website normally? And also is it normal that they have to click "accept" first time they visit? Why for other https website I dont have to do that?
I am using RapidSSL.
Your question is light on details, but here are the two likely guesses:
If you want your SSL server to work by default when users type https://xxxx, then your server needs to be running on port 443, not port 80. That's the default port number reserved for https connections and is the port number that the browser will try if the user just enters a https://xxxx URL.
If the browser is prompting you for permission to connect to your site, then that is likely because the SSL certificate you are using is not signed by one of the certificate authorities that the browsers trust (perhaps it is a self signed certificate). You can solve that issue by getting a certificate from the right trusted source and using that certificate in your server. It's also a possibility that something else is wrong with your SSL configuration, but we'd need to see more detail about the situation to know.

Create a Reverse Proxy in NodeJS that can handle multiple secure domains

I'm trying to create a reverse proxy in NodeJS. But I keep running the issue that in that I can only serve one one set of cert/key pair on the same port(443), even though I want to serve multiple domains. I have done the research and keep running into teh same road block:
A node script that can serve multiple domains secure domain from non-secure local source (http local accessed and served https public)
Let me dynamically server SSL certificates via domain header
Example:
https ://www.someplace.com:443 will pull from http ://thisipaddress:8000 and use the cert and key files for www.someplace.com
https ://www.anotherplace.com:443 will pull from http ://thisipaddress:8080 and use the cert and key files for www.anotherplace.com
ect.
I have looked at using NodeJS's https.createServer(options, [requestListener])
But this method supports just one cert/key pair per port
I can't find a way to dynamically switch certs based on domain header
I can't ask my people to use custom https ports
And I'll run into browse SSL certificate error if I serve the same SSL certificate for multiple domain names, even if it is secure
I looked at node-http-proxy but as far as I can see it has the same limitations
I looked into Apache mod-proxy and nginx but I would rather have something I have more direct control of
If anyone can show me an example of serving multiple secure domains each with their own certificate from the same port number (443) using NodeJS and either https.createServer or node-http-proxy I would be indebted to you.
Let me dynamically server SSL certificates via domain header
There is no domain header so I guess you mean the Host header in the HTTP request.
But, this will not work because
HTTPS is HTTP encapsulated inside SSL
therefore you first have to do your SSL layer (e.g. SSL handshake, which requires the certificates), then comes the HTTP layer
but the Host header is inside the HTTP layer :(
In former times you would need to have a single IP address for each SSL certificate. Current browsers do support SNI (server name indication), which sends the expected target host already inside the SSL layer. It looks like node.js does support this, look for SNICallback.
But, beware that there are still enough libraries out there, which either don't support SNI on the client side at all or where one needs to use it explicitly. But, as long you only want to support browsers this should be ok.
Redbird actually does this very gracefully and not too hard to configure either.
https://github.com/OptimalBits/redbird
Here is the solution you might be looking at,
I found it very useful for my implementation
though you will need to do huge customization to handle domains
node-http-rev proxy:
https://github.com/nodejitsu/node-http-proxy
Bouncy is a good library to do this and has an example of what you are needing.
As Steffen Ullrich says it will depend on the browser support for it
How about creating the SSL servers on different ports and using node-http-proxy as a server on 443 to relay the request based on domain.
You stated you don't want to use nginx for that, and I don't understand why. You can just setup multiple locations for your nginx. Have each of them listen to different hostnames and all on port 443.
Give all of them a proxypass to your nodejs server. To my understanding, that serves all of your requirements and is state of the art.

How do I configure my Nodejs app to respond to only SSL connections? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
I have a Nodejs/Express app running on ec2 with Nginx and Mongodb. I am running on a 8 core ec2 instance, and I have 8 separate instances of my Nodejs app running fronted by Nginx. For now, I have only 1 server.
We are going to go live soon and want to make sure that our server responds to only SSL requests. I would like to know how and where do I configure the SSL connection.
Here they are:
I will have to go to a CA like Verisign to get a cert, correct? My domain is registered through Godaddy, can I get a ssl cert from them?
Do I need to install the cert on the ec2 instance? if yes, what happens if i have to add another server for HA and I want to use elastic load balancing? In that case, do I need to buy a separate cert for each ec2 instance? Is there some doc or tutorial as to how to configure Nginx for ssl?
Once ssl is turned on, how do I ensure all non ssl connections are automatically redirected to ssl endpoints? Can I do this easily through a config entry in Nginx?
1. I will have to go to a CA like verisign to get a cert, correct? My
domain is registered thru godaddy, can I get a ssl cert from them?
Yes, you can buy an SSL certificate directly through GoDaddy.
2. Do I need to install the cert on the ec2 instance?
Yes, each server that you want to serve HTTPS content on will require the certificate be installed. Be careful to purchase a certificate that can be installed on multiple servers - some certificates can only be installed on one. It appears that GoDaddy allows unlimited certificate installations so this isn't an issue if you use them, but if you go with someone else it might be.
Another consideration is that if you want the ability to have subdomains use SSL (ie https://*.mydomain.com won't throw a browser warning), you're going to need to buy either a wildcard certificate (to allow unlimited subdomains) or a certificate that supports a specific number of subdomains that you want to use.
Also note that if you're going to need to support sticky sessions behind a load balancer on AWS, you're going to need to install the certificate on the Elastic Load Balancer (ELB) as well as all your servers.
But I wouldn't worry about this until everything else works since you have only one server right now, but be aware that the certificate must be X.509 (which it appears GoDaddy's are) to be installed on your ELB. Just make sure when purchasing so it isn't an issue in the future.
Can someone point me to some doc or tutorial as to how to configure nginx for ssl?
SSL Certificate Installation in Nginx.
3. how do i ensure all non ssl connections are automatically redirected to ssl endpoints?
See this answer here on ServerFault, it's pretty straightforward to configure:
server {
listen 80;
server_name signup.mysite.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
Best of luck.
You can terminate SSL connections at the ELB and then just pass back plain HTTP to the application servers. Then setup the security groups on your instances to disallow any direct connections from clients (forcing them to go through the ELB). This approach solves pretty much all your problems.

in node.js, using ssl with more than one domain name with one ip address

used to Apache in Linux where each domain name using ssl requires its own ip address.
is this still true if using node.js and not using Apache at all?
The same limitations apply in node.js as in Apache -- they're nothing to do with the particular server software you're using, they're inherent in the http and TLS/SSL protocols.
Having said that, there are two ways to run SSL for multiple domains from a single IP address. I don't know the status of node.js support for either of these, but it shouldn't matter for the first alternative.
First, you can get a single SSL certificate that covers all of the domain names you want to use -- either a wildcard if they're all subdomains of the same domain or one that uses Subject Alternative Names (SAN) if they're not. Note that SAN is not supported by some older web browsers, especially on some smartphones.
Second, you can use Server Name Indication (SNI) to configure multiple SSL certificates, as it extends the SSL protocol to make the hostname available to the server before it's done the key exchange. Browser support for SNI is not as good as for SAN, and in particular it doesn't work with any Internet Explorer version on Windows XP.
This link shows how to do it with nginx using the SNI method.
https://www.digitalocean.com/community/articles/how-to-set-up-multiple-ssl-certificates-on-one-ip-with-nginx-on-ubuntu-12-04
You might as well let nginx do the https and file serving and have it reverse proxy into node.js for the api work, as shown here:
https://stackoverflow.com/a/15008873/151312

SSL Https, is it that simple?

I'm just setting up an SSL area of a website, and was just wondering... is it as simple as adding HTTPS on the url?
(this is presuming I have a valid certificate of the hosting company?)
Or is there something more to it?
Thanks.
You have to setup the server to allow ssl connections. That includes generating a signed server request. You send this CSR to the cert authority (Verisign etc), and they send you a cert to install on the server. If you are behind a firewall you need to open port 443.
If you don't control the server i.e. shared hosting, there is probably a page in your control panel to do it all for you using a GUI.
When you replace http: in a URL with https: you are asking your web browser to do two things:
To attempt an encrypted (SSL) connection
To change which port to use on the remote server if none is specified in the URL
Most web browsers use port 80 for unencrypted traffic and port 443 for encrypted traffic by default. So, the first thing you need is a web server that is listening on port 443. If you are using a hosting company, this is probably already the case or becomes the case when you configure SSL.
You do not have to use port 443 but that is where browsers will be looking when users do not specify a port. You could also force everybody that connects at port 80 to use SSL as well though with the right configuration. That means that ALL traffic to your site would be encrypted.
To get the encryption up and running you generally need three things: a certificate, an encryption key, and a server request (CSR).
How you configure these is extremely dependent on how you are hosting the web server. Most hosting companies have 'control panels' that you log into for configuration. Common ones are Plex and CPanel. If either of those ring a bell you can post more information to get a better answer.
If you are managing the server yourself the big question is whether you are hosting on Windows or Linux. If it is windows, you are most likely going to want to configure IIS (Internet Information Server) while if it is on Linux you are probably going to configure Apache.
If you are using IIS, this link might help:
http://www.petri.co.il/configure_ssl_on_your_website_with_iis.htm
If it is Apache, Byron gave a good link above:
http://httpd.apache.org/docs/2.0/ssl/ssl_faq.html
You can use other web servers. For example, I use nginx:
http://rubypond.com/blog/setting-up-nginx-ssl-and-virtual-hosts
So, I guess the real step one is finding out more about your server. :-)
Once your web server has the SSL cert installed, it is as easy as using HTTPS on the URLs. There are some considerations to be aware of:
Port 443 must be open between the user and web server. (obvious)
Browser caching will be reduced to in-memory session cache and not stored on disk. Also, caching proxies in between will not be able to cache anything, since everything is encrypted. This means an increase in load times and bandwidth requirements of the web server.
When using HTTPS to receive sensitive data, be sure to disallow its use over HTTP. e.g. If you have a page that accepts credit card numbers in a POST, the app should fail validation if it was not done over HTTPS. This can be done in your code or in web server configuration. This prevents a bug or malware from systematically sending sensitive data in the clear without the user knowing.

Resources