Issue
I have a server with around 3 websites on the same server.
To make things easier for me, I'm generating the nginx configuration files as well as the apache configuration files with ansible so it's easier and less error prone. As you will see below, I'm using the same port for all of them, so pretty much the only things are different on those apache and nginx configuration files are the server name, the root location the website location and also the location for the error and access logs.
The problem that I see now is that I can't see both websites at the same time, when I open the first website on my browser it opens fine, but when I want to open the second website I get this error:
Your browser sent a request that this server could not understand.
When I see apache logs I see the following error:
[Fri Nov 09 16:17:51.247904 2018] [ssl:error] [pid 18614] AH02032: Hostname myweb.intweb.net provided via SNI and hostname mysecondweb.intweb.net provided via HTTP are different
where mysecondweb.intweb.net is the other website I'm trying to open.
This is my nginx configuration file for one of them, where you can see I'm handling the request to apache:
# Force HTTP requests to HTTPS
server {
listen 80;
server_name myweb.intweb.net;
return 301 https://myweb.intweb.net$request_uri;
}
server {
listen 443 ssl;
root /var/opt/httpd/ifdocs;
server_name myweb.intweb.net ;
# add Strict-Transport-Security to prevent man in the middle attacks
add_header Strict-Transport-Security "max-age=31536000" always;
ssl on;
ssl_certificate /etc/pki/tls/certs/star_intweb_net.pem;
ssl_certificate_key /etc/pki/tls/certs/star_intweb_net.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
access_log /var/log/nginx/iflogs/https/access.log;
error_log /var/log/nginx/iflogs/https/error.log;
###include rewrites/default.conf;
index index.php index.html index.htm;
# Make nginx serve static files instead of Apache
# NOTE this will cause issues with bandwidth accounting as files wont be logged
location ~* \.(gif|jpg|jpeg|png|wmv|avi|mpg|mpeg|mp4|htm|html|js|css)$ {
expires max;
}
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_ssl_server_name on;
proxy_ssl_name $host;
proxy_pass https://127.0.0.1:4433;
}
# proxy the PHP scripts to Apache listening on <serverIP>:8080
location ~ \.php$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_ssl_server_name on;
proxy_ssl_name $host;
proxy_pass https://127.0.0.1:4433;
}
location ~ /\. {
deny all;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
This is my Apache configuration for the the sites:
<VirtualHost *:4433>
SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/star_intweb_net.crt
SSLCertificateKeyFile /etc/pki/tls/certs/star_intweb_net.key
SSLCertificateCcompanyFile /etc/pki/tls/certs/DigiCertCA.crt
ServerAdmin [email protected]
DocumentRoot /var/opt/httpd/ifdocs
<Directory "/var/opt/httpd/ifdocs">
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ServerName myweb.intweb.net
ErrorLog /var/log/httpd/iflogs/http/error.log
CustomLog /var/log/httpd/iflogs/http/access.log combined
# RewriteEngine on
# Include rewrites/default.conf
</VirtualHost>
Note: If I remove the lines:
proxy_ssl_server_name on;
proxy_ssl_name $host;
I don't have that problem anymore and seems to solve the issue I'm having. In this case I was just curious if this will cause issues in the future or why would by removing those two lines in the configuration, I stop having those errors in apache?
Thank you!
Solution
I was able to fix this problem by adding this line of code in my nginx.conf file:
proxy_ssl_session_reuse off;
apparently there's a bug in OpenSSL. I tested it running the following code:
openssl genrsa -out fookey.pem 2048
openssl req -x509 -key fookey.pem -out foocert.pem -days 3650 -subj '/CN=testkey.invalid.example'
openssl s_server -accept localhost:30889 -cert foocert.pem -key fookey.pem -state -servername key1.example -cert2 foocert.pem -key2 fookey.pem
openssl s_client -connect localhost:30889 -sess_out /tmp/tempsslsess -servername key1.example
openssl s_client -connect localhost:30889 -sess_in /tmp/tempsslsess -servername key2.example
# observe key1.example in the SNI info reported by s_server for both requests. ("Hostname in TLS extension: "...)
# If s_server is restarted, and the s_client connections/sessions are re-run using key2.example first and key1.example second, observe key2.example in the SNI info reported by s_server for both requests.
# Furthermore, I just tested on a different machine, and sometimes SNI appears to be absent in the second requests.
# shouldn't s_client filter session use so that if it knows SNI info before selecting a cached session, it only selects one that matches the intended SNI name? And if it doesn't have a SNI name when it's searching for a session to re-use, shouldn't it still double check when it's provided (later, before connecting) SNI info, to make sure it's identical to SNI in the saved session it picked, and not use the saved session if they differ?
# It seems to me if the SNI specified by the client app ever differs from the SNI seen by the server, that's not good.
# this was discovered by someone reporting a problem using nginx to reverse proxy to apache, with apache warning that the SNI hostname didn't match the Host: header, despite the nginx config explicitly setting Host: and apache-side SNI to the same thing.
Answered By - VaTo