Tomcat behind Nginx: how to proxy both HTTP and HTTPS, possibly on non-standard ports?
Actually what I want really is not possible, so it's required to have two separate Connector
tags and two upstreams in Nginx, like so:
Tomcat's server.xml
:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
proxyPort="80"
/>
<Connector port="8443" protocol="HTTP/1.1"
connectionTimeout="20000"
proxyPort="443"
scheme="https" secure="true"
/>
Matching Nginx configuration:
server {
listen 80;
listen 443 ssl spdy;
location /saiku-ui {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://saiku-server-$scheme; # This is upstream name, note the variable $scheme in it
proxy_redirect off;
}
}
upstream saiku-server-http {
server ip.of.tomcat.server:8080;
}
upstream saiku-server-https {
server ip.of.tomcat.server:8443;
}
Please note that Tomcat receives plain HTTP traffic on both 8080 and 8443 ports (no SSL there, it's terminated by Nginx), but for connections on 8443 port it will generate links must start with https://
instead of http://
(via attributes scheme="https" secure="true"
) and will insert in links ports, specified in proxyPort
attribute.
Nginx will terminate SSL and proxy all secure connections to the 8443 port of Tomcat via saiku-server-https
upstream, where https
is the value of $scheme
Nginx request variable (see location
block)
Envek
Web developer with a strong passion to build rock solid applications: secure, reliable, fast.
Updated on June 21, 2022Comments
-
Envek about 2 years
Description
We're installing some application running Tomcat 6 behind Nginx for different clients. Some of those installations are HTTP only, some HTTPS only, somewhere both. One of those installations has HTTP and HTTPS working on non-standard ports (8070 and 8071) due to lack of public IPs. Application at hand is displayed as an iframe in another app.
Current behaviour
Tomcat redirects all HTTPS requests to HTTP (so nothing displayed in iframe due to browser restrictions for mixed content).
Current configuration
Iframe code:
<iframe src="/saiku-ui">
Tomcat's
server.xml
:<Connector port="8080" protocol="HTTP/1.1"/> <!-- A bit later... --> <Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="x-forwarded-for" protocolHeader="x-forwarded-proto" />
Nginx vhost:
server { listen 80; listen 443 ssl spdy; location /saiku-ui { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://saiku-server; # This is upstream name proxy_redirect off; } } upstream saiku-server { server ip.of.tomcat.server:8080; }
Desired behaviour
Tomcat should listen on one single port for both HTTP and HTTPS requests.
If there will be two
<Connector>
tags it will be much harder to configure Nginx.Tomcat should not redirect between schemas.
- Nginx may listen on arbitrary ports (e.g.
listen 8071 ssl spdy;
). - Links, generated by Tomcat should be either relative or include schema, host, and port as provided by Nginx.
Additional info
I've tried to add
schema
andproxyPort
attributes to<Connector>
, after that Tomcat will always redirect from HTTP to HTTPS (at least it's better).I can't google such a configuration and not experienced with Tomcat. Please help.