Setting up an nginx reverse proxy server for SSL connections on a remote virtual machine, with Apache tomcat

Hello everyone,

I am setting up a website to serve content through Apache tomcat. I managed to get the site configured so as to connect through http, but had problems correctly configuring tomcat for https, in part due to being unable to install Openssl.

After many unsuccessful attempts to correctly configure tomcat, I came across the suggestion to use nginx as a reverse proxy server that can handle SSL, and connect it to tomcat. That is what I am trying now. I don't really know what I am doing, as I have no experience with server/website configuration.

Could you take a look at my nginx configuration file and my tomcat server.xml file and suggest a course of action?

Here is what I have done:

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443

Someone on Stackoverflow said I needed to do this to get around tomcat's port restrictions.

sudo certbot --nginx. This created the certificates in .pem format. They are in /etc/letsencrypt/live/coanzse.org

The nginx file /etc/nginx/conf.d/coanzse.org.conf looks like this:

server {
    server_name coanzse.org;
    
    # HTTP configuration
    listen 80;
    listen [::]:80;
    
    # HTTP to HTTPS
    if ($scheme != "https") {
        return 301 https://$host$request_uri;
    } # managed by Certbot
    
    # HTTPS configuration
    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/coanzse.org/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/coanzse.org/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    location / {
        proxy_pass  http://coanzse.org:8080;
        proxy_redirect                      off;
        proxy_set_header  Host              $http_host;
        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_read_timeout                  900;
    }
}

For tomcat, my server.xml file contains this block:

    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"
               maxParameterCount="1000"
	       scheme="https"
	       proxyPort="443"
               />

With each new configuration, I restart both tomcat and nginx with sudo systemctl restart tomcat.service and sudo systemctl restart nginx.

My domain is: coanzse.org

I ran this command: Many, many different commands.

It produced this output: Still can't get to https://coanzse.org

My web server is (include version): Apache Tomcat/9.0.78

The operating system my web server runs on is (include version): Centos Linux release 7.7.1908 (Core)

My hosting provider, if applicable, is:

I can login to a root shell on my machine (yes or no, or I don't know): yes

I'm using a control panel to manage my site (no, or provide the name and version of the control panel): yes, the default Apache tomcat control panel

The version of my client is: certbot 2.6.0

Sorry for needing help for what is obviously a very basic problem. Thanks for any help you can provide!

Was that advice with or without the nginx reverse proxy? Because for with the reverse proxy in situ, one would think this iptables stuff completely bypasses the nginx proxy on port 443 and 80? I'm surprised your Certbot certificate issuance even worked.

Also, are Tomcat and nginx running on the same server? If so, it's probably better to have your reverse proxy configured to connect to 127.0.0.1. And it doesn't require HTTPS on Tomcats side, that's whats nginx is for. It's probably better to just have Tomcat configured as a "plain HTTP" server, nothing more, nothing less and let nginx do all the rest.

3 Likes

Thank you for your response!

Was that advice with or without the nginx reverse proxy? Because for with the reverse proxy in situ, one would think this iptables stuff completely bypasses the nginx proxy on port 443 and 80? I'm surprised your Certbot certificate issuance even worked.

The certificate was issued by certbot when I was still attempting to use Apache tomcat alone. I re-installed it for nginx with sudo certbot --nginx. There was a prompt "would you like to reconfigure your existing certificate?" I chose yes, and it reported success. I have now turned off the port forwarding, using sudo iptables -t nat -D PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080, sudo iptables -t nat -D PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443, sudo iptables -t nat -D OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to 8080, and sudo iptables -t nat -D OUTPUT -o lo -p tcp --dport 443 -j REDIRECT --to 8443.

Also, are Tomcat and nginx running on the same server? If so, it's probably better to have your reverse proxy configured to connect to 127.0.0.1 . And it doesn't require HTTPS on Tomcats side, that's whats nginx is for. It's probably better to just have Tomcat configured as a "plain HTTP" server, nothing more, nothing less and let nginx do all the rest.

I see what you mean. Yes, they are on the same server. I've changed the nginx configuration line to:

proxy_pass http://127.0.0.1;

In Tomcat I have changed the Connector to:

    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               maxParameterCount="1000"
               />

I'm still getting "refused to connect" for https.

1 Like

I think that's missing a :8080

But that's not even the main problem: I cannot reach your server over https, and I mean there's a firewall bouncing me away:

$ curl -IL https://coanzse.org
curl: (7) Failed to connect to coanzse.org port 443 after 134 ms: Connection refused

Were the proxy broken, I'd see a 503 error.

4 Likes

Yes, I always get the "refused to connect" response. Any idea what I can try to change?

I'd get rid of the iptables rules.

Then I'd see if I can connect to apache-tomcat on localhost (you have to do this from the machine itself, of course)

If this works, I'd start thinking about the reverse proxy. That's usually the easy part.

4 Likes

As far as I understand, I already did that, with

sudo iptables -t nat -D PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080,
sudo iptables -t nat -D PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443,
sudo iptables -t nat -D OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to 8080,
and sudo iptables -t nat -D OUTPUT -o lo -p tcp --dport 443 -j REDIRECT --to 8443.

I can connect to Apache tomcat on localhost:8080.

ok, what happens if you

proxy_pass http://localhost:8080

?

can you see anything on localhost:80 or localhost:443, then?

4 Likes

proxy_pass http://localhost:8080 and proxy_pass http://127.0.0.1:8080 in the nginx config both result in "refused to connect".

http://localhost:80 and https://localhost:443 both show "502 Bad Gateway nginx/1.20.1":

ok, this means nginx is running and cannot connect to apache. but you can. you sure this stuff is on the same machine?

3 Likes

Yes, on the same machine.

Update: I had been having various problems with my ancient Centos 7 install, so I set up a new virtual machine running Centos 8 Stream. On this new machine I have installed Apache tomcat and nginx.

I can now use the SSL certificates from Letsencrypt: my domain uses SSL. The problem now is that the page resolves to a default html page from nginx, not to the Apache tomcat server.

This is the default index.html page that is distributed with nginx on Red Hat Enterprise Linux. It is located in /usr/share/nginx/html.

You should now put your content in a location of your choice and edit the root configuration directive in the nginx configuration file /etc/nginx/nginx.conf.

I don't really understand the nginx configuration procedure, and the various online guides seem to deal with different versions. If I create an additional configuration file, in /etc/nginx/conf.d/coanzse.conf or similar, it inevitably results in an nginx error: either the "address is already in use", the "location" has already been defined, or something similar. Googling these error messages didn't turn up any quick fixes.

If anyone has a working nginx reverse proxy using tomcat and can help out I would be very thankful!

1 Like

You might have better luck getting such help within an nginx or Tomcat type forum.

4 Likes

Issue solved. On the new installation, it only required removing the line listen 80; and changing proxy_pass http://coanzse.org:8080; to proxy_pass http://127.0.0.1:8080;

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.