Nginx – Disable HTTPS for a domain that shares IP with another domain that is under HTTPS

httpsnginxredirectsslUbuntu

I am running into a weird problem trying to disable HTTPS for one domain, but the other domain has HTTPS. They both are different websites running on a dedicated server, sharing the same IP address for the domains.
However, I have a domain that does not have a SSL certificate, but the other does. I want to disable HTTPS for the non-certified domain while leaving the other domain with HTTPS on.

I have two different separate vhosts in /etc/nginx/sites-enabled/,

domain1.org (no HTTPS)

server {

    listen                      80;
    server_name                 www.domain1.org domain1.org;
    root                        /var/www/domain1.org;
    index                       index.html index.php index.htm;

    error_log                   /var/www/logs/domain1.errors.log;

    [ ... ]

domain2.com (with HTTPS)

server {

    listen                      443 ssl;
    server_name                 domain2.com www.domain2.com;

    # INCLUDE SSL CERTIFICATE
    include                     sites-enabled/domain2_ssl_include; 

    root                        /home/domain2/www/www;
    index                       index.html index.php index.htm;

    [ ... ]

I've included a listener to the port 443 for domain1.org, but once I do that, I get an aborted error from Firefox saying (when accessing https://domain1.org):

This Connection is Untrusted

You have asked Firefox to connect securely to domain1.org, but we can't confirm that your connection is secure.

I opened the technical data, it appears that the domain1.org is using the domain2.com SSL certificate:

domain1.org uses an invalid security certificate.

The certificate is only valid for the following names:
*.domain2.com , domain2.com

(Error code: ssl_error_bad_cert_domain)

So I added this to domain1.org vhost configuration:

server {

    server_name                 domain1.org www.domain1.org;

    listen                      443 ssl;

    rewrite ^ http://domain1.org permanent;
}

Which still gets me prompted with the Firefox error.

Now… when I access to http://domain1.org, I get an 400 error from nginx saying this:

400 Bad Request

The plain HTTP request was sent to HTTPS port

I am not entirely sure what to do, disabling the https with ssl off; has no effect. How can I actually disable HTTPS for domain1.org but not for domain2.com?

I am using Ubuntu 12.04 running nginx 1.2.6.

Best Answer

You won't be able to do what you want. You either:

  1. Need to obtain a valid certificate for both domains and use the serverHost directives to redirect off SSL (to http://) if you truly don't want to run SSL on that domain.
  2. Need to obtain a second IP address and run the domains on seperate IP addresses.
  3. Leave SSL Enabled and serve an invalid certificate for domain1

WHY:

  1. A client types https://domain1.com/ in a browser
  2. The browser resolves this to a TCP connection to on port 443
  3. The magic of the internet routes this connection to your server and hopefully into your web server software
  4. The client browser is standing at the front door waiting for the proper 'secret handshake' (SSL Cert.)
  5. Your server tries the only handshake it knows (which is wrong)
  6. The client's browser informs the client that "This guy at the door of domain1.com... He's not who he says he is. This is sketchy"
  7. Today, will click the variant of "Proceed Anyway" that their browser presents
  8. IF you disable SSL on domain1.com, the user will be shown the other site (quite confusing for the user)
  9. IF you leave SSL enabled on domain1.com, modern browsers and webservers will communicate and show the correct site. (albeit, with a scary warning)

If you intend to host domain1.org @ ip on port 80 and domain2.org at ip on port 443 (so that domain2 does not have HTTP access, it should 'work'). Remove the 443 listener for domain1. You will be prompted if any audacious users type https://domain1.org (and then shown domain2). That setup is essentially Port based virtual hosting.Instead of picking random ports you have picked the two defaults and given them to separate virtual hosts. Ultimately in this setup (WITH SSL laying around) the webserver doesn't really care what domain the browser is asking for in the Host header. The web server just cares about the ip:port combo in port based virtual hosts.