Nginx – Connect to a Tomcat Server from nginx as reverse proxy

nginxreverse-proxytomcat

I have a Tomcat server serving a web application and I have a Nginx server running in front of it as a reverse proxy. As an answer to my earlier question (Tomcat server behind nginx reverse proxy – how to block direct access to the server?), I was suggested to firewall the Tomcat instance, but based on my findings from different forums, limiting Tomcat to listen to localhost seemed to be the way to go. In order to prevent Tomcat from listening to other IPs, I added "address=127.0.0.1" to the connector configuration. The entire connector block is like this –

<Connector port="8080" 
address="127.0.0.1" 
maxThreads="150" 
minSpareThreads="25" 
connectionTimeout="20000" 
enableLookups="false" 
maxHttpHeaderSize="8192" 
protocol="HTTP/1.1" 
useBodyEncodingForURI="true" 
redirectPort="8443" 
acceptCount="100" 
disableUploadTimeout="true"
proxyName=<FQDN> 
proxyPort="80"/> 

In the Nginx server, I have these lines for the server configuration.

server {
        listen  80 default_server;
        listen  [::]:80 default_server ipv6only=on;

        server_name <FQDN>;
        location / {
        proxy_pass <FQDN>;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;
}
}

Now, if I try to use the FQDN to access the web application, Chrome reports ERR_CONNECTION_REFUSED. My Nginx configuration seems to be the culprit based on what I understood. How can it be corrected?

Best Answer

For the purpose of the question I'll assume that the following IPs

Nginx 192.168.0.1
Tomcat 192.168.0.2

Configure the tomcat server

Change the following line address="127.0.0.1" to address="192.168.0.2" - This will tell Tomcat to listen on the local ip rather then the loopback address.

Then we want to configure the IPtables. I used the generator here.

The rules below are "safe" they won't lock you out of remote access (I've allowed SSH on port 22, assuming your ssh port is default) but they aren't as restrictive as they perhaps should/could be. So please take a minute to look over them. It would also remove any current rules

#!/bin/sh

# iptables script generated 2016-04-20
# http://www.mista.nu/iptables

IPT="/sbin/iptables"

# Flush old rules, old custom tables
$IPT --flush
$IPT --delete-chain

# Set default policies for all three default chains
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT ACCEPT

# Enable free use of loopback interfaces
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT

# All TCP sessions should begin with SYN
$IPT -A INPUT -p tcp ! --syn -m state --state NEW -s 0.0.0.0/0 -j DROP

# Accept inbound TCP packets
$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -p tcp --dport 22 -m state --state NEW -s 0.0.0.0/0 -j ACCEPT # Accepts SSH from everywhere
$IPT -A INPUT -p tcp --dport 8080 -m state --state NEW -s 192.168.0.1/32 -j ACCEPT # Accepts connection to port 8080 only from the Nginx Server

# Accept inbound ICMP messages
$IPT -A INPUT -p ICMP --icmp-type 8 -s 0.0.0.0/0 -j ACCEPT
$IPT -A INPUT -p ICMP --icmp-type 11 -s 0.0.0.0/0 -j ACCEPT

Configure the Nginx server

You need to edit your server configuration just a little. We now proxy to the Tomcat server on its local IP.

server {
        listen  80 default_server;
        listen  [::]:80 default_server ipv6only=on;
        server_name <FQDN>;

location / {
        proxy_pass http://192.168.0.2:8080;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;
        }
}

You can proxy to a FQDN but you need to configure a separate one to that of the one pointing to the Nginx Server. For example if the FQDN above was myapp.example.com you would configure another FQDN such as tomcat.example.com and have that resolve to 192.168.0.2 you could then replace 192.168.0.2 in the nginx config above with tomcat.example.com