0

I have a standard reverse proxy, with nginx and Tomcat 8.

I want nginx to handle encryption, but still inform tomcat whether the connection is secure or not.

i have

location /{
 listen 80;
 proxy_pass http://backend:8080;
}

location /{
  listen 443 ssl;
  proxy_pass https://backend:8443;
}

tomcat has the following config:

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="false" scheme="https" secure="true" clientAuth="false" URIEncoding="UTF-8"/>

however I am getting error

SSL_do_handshake() failed (SSL: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol) while SSL handshaking to upstream, client: 185.3.147.237, server: backing, request: "GET /favicon.ico HTTP/1.1", upstream: "https://127.0.0.1:8443/favicon.ico", host: "

How do I tell nginx that connection to backend is not encrypted even though the address starts with https?

f.khantsis
  • 331
  • 3
  • 6
  • 13
  • You could simply set the HTTPS block of Nginx to connect to `http://backend:8443` (ie without the https, port can remain the same as that's how its defined in Tomcat). Your Tomcat connector config already says that anything coming over that connector is secure due to the `scheme"https"` and `secure="true"`, so Tomcat understands its secure. – Vivek Thomas Sep 25 '16 at 16:08
  • ok, except now I have trouble with redirects, as Location response header has http://, and I am stuck in redirect loops – f.khantsis Sep 25 '16 at 20:13
  • You could make use of `proxyName` and `proxyPort` to let Tomcat know there is a proxy, this should take care of the redirect issue. – Vivek Thomas Sep 27 '16 at 04:32
  • @VivekThomas that's what I ended up doing. Write it up as an answer, and I'll accept it – f.khantsis Sep 28 '16 at 17:39

1 Answers1

0

Your Tomcat configuration has SSLEnabled=false. Therefore your Tomcat listens to standard HTTP on 8443 port, and nginx fails to connect to it.

I would implement this so that I would use a single upstream port to Tomcat, and set HTTP header which would contain the SSL status. Something like this:

server {
    listen 80;
    listen 443 ssl;
    server_name example.com;
    proxy_set_header X-SCHEME $scheme;

    proxy_pass http://backend:8080;
}

This server block receives both to http and https, passes all request to Tomcat http backend and sets a header X-SCHEME, which is either http or https. Then you have the information you want in your backend.

Tero Kilkanen
  • 36,796
  • 3
  • 41
  • 63