Apache is serving SSL when its not in the vhost configuration [duplicate]
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.
You won't be able to do what you want. You either:
- 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.
- Need to obtain a second IP address and run the domains on seperate IP addresses.
- Leave SSL Enabled and serve an invalid certificate for domain1
WHY:
- A client types https://domain1.com/ in a browser
- The browser resolves this to a TCP connection to on port 443
- The magic of the internet routes this connection to your server and hopefully into your web server software
- The client browser is standing at the front door waiting for the proper 'secret handshake' (SSL Cert.)
- Your server tries the only handshake it knows (which is wrong)
- 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"
- Today, will click the variant of "Proceed Anyway" that their browser presents
- IF you disable SSL on domain1.com, the user will be shown the other site (quite confusing for the user)
- 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.
That's a quite common problem with http and https sites and not only a Nginx issue. You can have the same with Apache, IIS ... and whatever.
How to solve this correctly
Acquire an additional IP address for your Web server and address domain2.org to the new IP (IP #2). Additionally take care that your Web server is listening only on port 80 via IP #1 and is listening on ports 80 and 443 via IP #2.
Work-around if second IP not possible
If an additional IP address is not possible you can only implement a work-around. Activate SSL/TLS for domain1.org with the certificate of domain2.org and provide a redirect to http://domain1.org/ as you already did. Users will get SSL/TLS warnings anyway and most of them ignore these warnings. But so they get forwarded to the correct URL.
Example configuration for nginx:
ssl_certificate /etc/ssl/certs/domain2.org.pem;
ssl_certificate_key /etc/ssl/private/domain2.org.key;
ssl_protocols SSLv3 TLSv1;
ssl_prefer_server_ciphers on;
ssl_ciphers AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH;
ssl_session_cache shared:SSL:10m;
# domain1.org
server {
listen 80;
listen [::]:80;
server_name domain1.org;
# your configuration part ...
}
server {
listen 443 ssl spdy;
listen [::]:443 ssl spdy;
server_name domain1.org;
return 301 http://domain1.org/; # enforce correct protocol
}
# domain2.org
server {
listen 80;
listen [::]:80;
server_name domain2.org;
return 301 https://domain2.org/; # enforce correct protocol
}
server {
listen 443 default_server ssl spdy;
listen [::]:443 default_server ssl spdy;
server_name domain2.org;
# your configuration part ...
}