3

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?

  • Unfortunately, that is not happening. I have checked once again. – Chethan S. Apr 20 '16 at 10:31
  • Oh! The hosts file in my Tomcat server contained just three lines 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 plus real IP, servername, FQDN. The hosts file on nginx server was default. Both the IPs (Tomcat's and Nginx's) are properly populated in the DNS. So can you help me understand what needs to be changed, preferably by writing an answer. :) – Chethan S. Apr 20 '16 at 10:41
  • Oh wait, you have two actual severs - I didn't read that correctly. You can't set tomcat to listen on 127.0.0.1 on one server and proxy to it from another. You should instead use firewall on the tomcat server to restrict access to it – Drifter104 Apr 20 '16 at 10:57
  • Hmmm... then what is the ideal way to prevent the Tomcat application from being accessed by the Tomcat IP. As I noted in the linked question, now both my IPs resolve to the application. I want only the reverse proxy IP to resolve to the proper FQDN. – Chethan S. Apr 20 '16 at 10:59
  • 1
    Right I see where the problem comes from. The digital ocean guide you linked to in the comments on the other question assumes tomcat and nginx are on the same single server. It is possible on separate servers. I'll put an answer up. The FQDN needs to be set in DNS to point at the proxy server though. We can proxy to the tomcat server using the IP – Drifter104 Apr 20 '16 at 11:15
3

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

| improve this answer | |
  • Thank you very much @Drifter104 for the detailed answer. – Chethan S. Apr 21 '16 at 4:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.