Bug 49995 - Apache2 is sending one SSL cert amongs different vhosts, ignoring the fact that vhosts are on different ports.
Summary: Apache2 is sending one SSL cert amongs different vhosts, ignoring the fact th...
Status: RESOLVED DUPLICATE of bug 43218
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: Core (show other bugs)
Version: 2.2.16
Hardware: PC Linux
: P2 major (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-09-24 11:50 UTC by No Real Name
Modified: 2014-01-19 19:23 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description No Real Name 2010-09-24 11:50:08 UTC
Summary:
We have http with wildcard ssl. We're creating few vhost, one main and one for each user.
One of our users wants to have a ssl vhost on different port with his own certs.
Apparently, when ServerName's are duplicated among vhosts, strange results happends.
Apache2 is sending one cert amongs duplicated vhosts, ignoring the fact that vhosts are
configured on different ports and with different SSLCertificateFile.

Is reproducible: Yes, always.

How to reproduce:
Step 1: Compile httpd2.2:
./configure --with-mpm=worker --enable-suexec --enable-ssl --prefix=/usr/local/apache2-2.2.16
make
make install

Step 2: generate two SSL certs:
cd /usr/local/apache2-2.2.16/conf
openssl req -new -x509 -days 3650 -newkey rsa:2048 -nodes \
-subj '/O=MAIN-CERT/CN=*.local.net' -keyout wildcard.local.net.key \
-out wildcard.local.net.crt

openssl req -new -x509 -days 3650 -newkey rsa:2048 -nodes \   
-subj '/O=User3-CERT/CN=user3.local.net' -keyout user3.local.net.key \
-out user3.local.net.crt


Step 3: patch httpd.conf
--- ./conf-original/httpd.conf	2010-09-24 15:49:12.000000000 +0200
+++ ./conf/httpd.conf	2010-09-24 17:13:24.000000000 +0200
@@ -39,3 +39,5 @@
 #Listen 12.34.56.78:80
-Listen 80
+Listen 127.0.0.1:80
+Listen 127.0.0.1:443
+Listen 127.0.0.1:3443
 
@@ -409 +411,73 @@
 </IfModule>
+
+
+
+NameVirtualHost 127.0.0.1:80
+NameVirtualHost 127.0.0.1:443
+NameVirtualHost 127.0.0.1:3443
+
+<VirtualHost 127.0.0.1:80>
+	ServerName "main.local.net"
+	DocumentRoot "/usr/local/apache2-2.2.16/htdocs"
+</VirtualHost>
+
+<VirtualHost 127.0.0.1:80>
+	ServerName "user1.local.net"
+	DocumentRoot "/usr/local/apache2-2.2.16/htdocs/u1"
+</VirtualHost>
+
+<VirtualHost 127.0.0.1:80>
+	ServerName "user2.local.net"
+	DocumentRoot "/usr/local/apache2-2.2.16/htdocs/u2"
+</VirtualHost>
+
+<VirtualHost 127.0.0.1:80>
+	ServerName "user3.local.net"
+	DocumentRoot "/usr/local/apache2-2.2.16/htdocs/u3"
+</VirtualHost>
+
+
+# SSL VHOSTS (wildcard *.local.net)
+<VirtualHost 127.0.0.1:443>
+	SSLEngine on
+	SSLCertificateFile	/usr/local/apache2-2.2.16/conf/wildcard.local.net.crt
+	SSLCertificateKeyFile	/usr/local/apache2-2.2.16/conf/wildcard.local.net.key
+	ServerName "main.local.net"
+	DocumentRoot "/usr/local/apache2-2.2.16/htdocs"
+</VirtualHost>
+
+<VirtualHost 127.0.0.1:443>
+	SSLEngine on
+	SSLCertificateFile	/usr/local/apache2-2.2.16/conf/wildcard.local.net.crt
+	SSLCertificateKeyFile	/usr/local/apache2-2.2.16/conf/wildcard.local.net.key
+	ServerName "user1.local.net"
+	DocumentRoot "/usr/local/apache2-2.2.16/htdocs/u1"
+</VirtualHost>
+
+<VirtualHost 127.0.0.1:443>
+	SSLEngine on
+	SSLCertificateFile	/usr/local/apache2-2.2.16/conf/wildcard.local.net.crt
+	SSLCertificateKeyFile	/usr/local/apache2-2.2.16/conf/wildcard.local.net.key
+	ServerName "user2.local.net"
+	DocumentRoot "/usr/local/apache2-2.2.16/htdocs/u2"
+</VirtualHost>
+
+# BASE SSL VHOST for user3 with static pages. application will be on port 3443 and will
+# have other cert for that.
+<VirtualHost 127.0.0.1:443>
+	SSLEngine on
+	SSLCertificateFile	/usr/local/apache2-2.2.16/conf/wildcard.local.net.crt
+	SSLCertificateKeyFile	/usr/local/apache2-2.2.16/conf/wildcard.local.net.key
+	ServerName "user3.local.net"
+	DocumentRoot "/usr/local/apache2-2.2.16/htdocs/u3"
+</VirtualHost>
+
+# SOME OTHER VHOST on DIFFERENT PORT, different CRT but THE SAME ServerName as previous.
+# SO bassicaly: https://user3.local.net:3443/ can be proxied thru AJP13 etc.
+<VirtualHost 127.0.0.1:3443>
+	SSLEngine on
+	SSLCertificateFile	/usr/local/apache2-2.2.16/conf/user3.local.net.crt
+	SSLCertificateKeyFile	/usr/local/apache2-2.2.16/conf/user3.local.net.key
+	ServerName "user3.local.net"
+	DocumentRoot "/usr/local/apache2-2.2.16/htdocs/u3"
+</VirtualHost>

Step 4: httpd -S:
VirtualHost configuration:
127.0.0.1:80           is a NameVirtualHost
         default server main.local.net (/usr/local/apache2-2.2.16/conf/httpd.conf:419)
         port 80 namevhost main.local.net (/usr/local/apache2-2.2.16/conf/httpd.conf:419)
         port 80 namevhost user1.local.net (/usr/local/apache2-2.2.16/conf/httpd.conf:424)
         port 80 namevhost user2.local.net (/usr/local/apache2-2.2.16/conf/httpd.conf:429)
         port 80 namevhost user3.local.net (/usr/local/apache2-2.2.16/conf/httpd.conf:434)
127.0.0.1:443          is a NameVirtualHost
         default server main.local.net (/usr/local/apache2-2.2.16/conf/httpd.conf:441)
         port 443 namevhost main.local.net (/usr/local/apache2-2.2.16/conf/httpd.conf:441)
         port 443 namevhost user1.local.net (/usr/local/apache2-2.2.16/conf/httpd.conf:449)
         port 443 namevhost user2.local.net (/usr/local/apache2-2.2.16/conf/httpd.conf:457)
         port 443 namevhost user3.local.net (/usr/local/apache2-2.2.16/conf/httpd.conf:467)
127.0.0.1:3443         is a NameVirtualHost
         default server user3.local.net (/usr/local/apache2-2.2.16/conf/httpd.conf:477)
         port 3443 namevhost user3.local.net (/usr/local/apache2-2.2.16/conf/httpd.conf:477)
Syntax OK

Step 5: Check the results:
openssl s_client -connect 127.0.0.1:443
openssl s_client -connect 127.0.0.1:3443

Result: Apache2 sends the same cert on different ports, but serving requests
correctly (from correct DocumentRoot, as stated in httpd.conf).

Expected result: Apache2 should return different cert on different ports based on httpd.conf.


Possible Workaround:
Change ServerName in last vhost :3443 to some other string, ex. "whatever.local.net".
If ServerName's are not duplicated among different virtualhosts, apache
serve correct certs. Sometimes this is not an option.  When using
proxy, ex. mod_jk for proxying user3.local.net:3443 thru AJP13 to tomcat ->
apache2 then sends ServerName thru AJP13 to tomcat and it must match with
the one in tomcat config file. If we change ServerName from user3.local.net
to whatever.local.net, it would require to change tomcat vhost in config as well.
And it would be messy.

Bug can be reproduced with:
httpd-2.2.16.tar.bz2 (sha1: ef92f5b3124fe5e9ba6121ea7f4bab8c014068f9)
apache2-2.2.9 from Debian 5.0
apache2-2.2.3 from Debian 4.0
Possibly others.
mpm: worker, others mpm: not tested.

Compiled and tested without SNI support.
Comment 1 Eric Covener 2014-01-19 19:23:50 UTC

*** This bug has been marked as a duplicate of bug 43218 ***