waterlink/rack-reverse-proxy

OpenSSL::SSL::SSLError: hostname "XYZ" does not match the server certificate

Opened this issue · 11 comments

Hi,

I'm having issues trying to use rack-reverse-proxy to host a wordpress blog from another site on my heroku domain. I'm using puma server and when I try to go to https://mydomain.com/blog I get the following error:

OpenSSL::SSL::SSLError: hostname "XYZ" does not match the server certificate

Everything seems to work fine if I don't use SSL. I have verified that the certificates on my wordpress blog and heroku site match (other than the wordpress blog has a different hostname I guess), but can't figure out how to resolve this. Any help is much appreciated.

Very helpful gem btw.

Thanks! Aaron

Do you proxy in this fashion:

  • HTTPS (domain A) => HTTPS (domain B), or
  • HTTPS (domain A) => HTTP ?

Hi Alex, thanks for the reply! I'm redirecting my /blog to a wordpress blog hosted on a subdomain at flywheelsites. The admins at flywheel installed my matching SSL certificate. When I run

openssl s_client -connect YXZ.com:443

and

openssl s_client -connect XYZ.flywheelsites.com:443

The certs seem to match.

Here's my code:

config.ru

use Rack::ReverseProxy do
  reverse_proxy /^\/blog(\/.*)$/, 'https://XYZ.flywheelsites.com$1', :preserve_host => true
end

In my routes, I also have:

get "/blog" => redirect("https://www.XYZ.com/blog/")

can you try to make a request with curl in verbose mode and paste the output in gist? curl -vvv https://www.XYZ.com/blog

This is the response for /blog:

* Hostname was NOT found in DNS cache
*   Trying 50.16.185.191...
* Connected to www.getballer.com (50.16.185.191) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
* Server certificate: *.getballer.com
* Server certificate: COMODO RSA Domain Validation Secure Server CA
* Server certificate: COMODO RSA Certification Authority
* Server certificate: AddTrust External CA Root
> GET /blog HTTP/1.1
> User-Agent: curl/7.37.1
> Host: www.getballer.com
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
* Server Cowboy is not blacklisted
< Server: Cowboy
< Connection: keep-alive
< Strict-Transport-Security: max-age=31536000
< Location: https://www.getballer.com/blog/
< Content-Type: text/html
< Vary: Accept-Encoding
< X-Ua-Compatible: IE=Edge,chrome=1
< Cache-Control: no-cache
< X-Request-Id: b1d9be05-3e45-455e-b85c-72643c985af9
< X-Runtime: 0.003897
< Date: Fri, 24 Jul 2015 23:26:07 GMT
< X-Rack-Cache: miss
< Content-Length: 97
< Via: 1.1 vegur
< 
* Connection #0 to host www.getballer.com left intact
<html><body>You are being <a href="https://www.getballer.com/blog/">redirected</a>.</body></html>

And here is the output for /blog/

curl -vvv https://www.getballer.com/blog/
* Hostname was NOT found in DNS cache
*   Trying 107.20.210.14...
* Connected to www.getballer.com (107.20.210.14) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
* Server certificate: *.getballer.com
* Server certificate: COMODO RSA Domain Validation Secure Server CA
* Server certificate: COMODO RSA Certification Authority
* Server certificate: AddTrust External CA Root
> GET /blog/ HTTP/1.1
> User-Agent: curl/7.37.1
> Host: www.getballer.com
> Accept: */*
> 
< HTTP/1.1 500 Internal Server Error
* Server Cowboy is not blacklisted
< Server: Cowboy
< Date: Fri, 24 Jul 2015 23:26:42 GMT
< Connection: keep-alive
< Content-Length: 76
< Via: 1.1 vegur
< 
An unhandled lowlevel error occured. The application logs may have details.
* Connection #0 to host www.getballer.com left intact

Ok. That means that this error occurs when your proxy app (heroku) tries to connect to your blog app, which sits on HTTPS. I assume that some header (like ORIGIN or something else, that contains host of your proxy app) gets passed in request that makes ssl library to reject certificates.

Have you tried to set :preserve_host => false ? What happens in this case?

I just push the code with :preserve_host => false and same problem. I've reached out to the blog hosting company to see if it is something on their end. Any other way to debug and see what is going on under the hood?

Really appreciate your help, thanks!

It can be a problem with reverse proxying concept. I always got ssl errors with https => https proxying, even on standard reverse proxies, like NGINX. With nginx what you usually do is https => http server directly. So there is a chance, that this error is expected..

FYI, I came across this same problem and thought I'd make the solution a bit clearer.

In this code above:

use Rack::ReverseProxy do reverse_proxy /^\/blog(\/.*)$/, 'https://XYZ.flywheelsites.com$1', :preserve_host => true end

You need to make sure the Flywheel website is http:// instead of https://, like this:

use Rack::ReverseProxy do reverse_proxy /^\/blog(\/.*)$/, 'http://XYZ.flywheelsites.com$1', :preserve_host => true end

Then, it should work as expected.

Just to link this here, with PR #24, it is possible to disable https certificate validation altogether.

@MrMarvin I have released 0.10.0 with your change.

fabes commented

Thank you @justinkuepper! Your solution works for me!