skip to Main Content

centos 7, tomcat 8.5.

a.war and rest.war are in the same tomcat.

a.war use following code to call rest.war:

import org.apache.http.impl.client.DefaultHttpClient;

DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);

httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");  

StringEntity se = new StringEntity(json.toString());

se.setContentType("text/json");
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));

httpPost.setEntity(se);

HttpResponse response = httpClient.execute(httpPost);

however, if url of HttpPost(url) is <public ip>:80, then httpClient.execute(httpPost) will throw connection refused.

while if url of HttpPost(url) is localhost:80 or 127.0.0.1:80, then httpClient.execute(httpPost) is success.

why? and how can solve this problem?

Note: if I access a.war from browser with public ip like http://<public ip>/a in my computer, all operations are success.

my tomcat connector is:

<Connector  
            port="80"
                protocol="HTTP/1.1"  
                connectionTimeout="60000" 
                keepAliveTimeout="15000"
                maxKeepAliveRequests="-1"
                maxThreads="1000"  
                minSpareThreads="200"  
                maxSpareThreads="300"
                minProcessors="100" 
                maxProcessors="900" 
                acceptCount="1000" 
                enableLookups="false"
                executor="tomcatThreadPool"
                maxPostSize="-1"
                compression="on"
                compressionMinSize="1024"               
                redirectPort="8443" />

my server has no domain, only has a public ip, its /etc/hosts is:

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

updated with some commands run in server:

ss -nltp

State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128          *:111                      *:*                   users:(("rpcbind",pid=643,fd=8))
LISTEN     0      128          *:80                       *:*                   users:(("java",pid=31986,fd=53))
LISTEN     0      128          *:22                       *:*                   users:(("sshd",pid=961,fd=3))
LISTEN     0      1      127.0.0.1:8005                     *:*                   users:(("java",pid=31986,fd=68))
LISTEN     0      128         :::111                     :::*                   users:(("rpcbind",pid=643,fd=11))
LISTEN     0      128         :::22                      :::*                   users:(("sshd",pid=961,fd=4))
LISTEN     0      80          :::3306                    :::*                   users:(("mysqld",pid=1160,fd=19))
netstat -nltp

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      643/rpcbind         
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      31986/java          
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      961/sshd            
tcp        0      0 127.0.0.1:8005          0.0.0.0:*               LISTEN      31986/java          
tcp6       0      0 :::111                  :::*                    LISTEN      643/rpcbind         
tcp6       0      0 :::22                   :::*                    LISTEN      961/sshd            
tcp6       0      0 :::3306                 :::*                    LISTEN      1160/mysqld 
ifconfig

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 1396428  bytes 179342662 (171.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1396428  bytes 179342662 (171.0 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

p2p1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.25  netmask 255.255.255.0  broadcast 192.168.1.255
        ether f8:bc:12:a3:4f:b7  txqueuelen 1000  (Ethernet)
        RX packets 5352432  bytes 3009606926 (2.8 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2839034  bytes 559838396 (533.9 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
ip addr show

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: p2p1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether f8:bc:12:a3:4f:b7 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.25/24 brd 192.168.1.255 scope global noprefixroute dynamic p2p1
       valid_lft 54621sec preferred_lft 54621sec
route

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         gateway         0.0.0.0         UG    100    0        0 p2p1
192.168.1.0     0.0.0.0         255.255.255.0   U     100    0        0 p2p1
ip route

default via 192.168.1.1 dev p2p1 proto dhcp metric 100 
192.168.1.0/24 dev p2p1 proto kernel scope link src 192.168.1.25 metric 100
iptables -L -n -v --line-numbers

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

4

Answers


  1. You probably have configured one of these:

    1. Firewall public IP’s ports, so that nothing goes through.
    2. Tomcat may bind a specific IP, e.g. localhost (see Connector elements in tomcat’s server.xml)
    3. Apache httpd, nginx or another reverse proxy might handle various virtual host names, and also they might handle localhost different than the public IP
    4. Port Forwarding – if you only forward localhost:80 to localhost:8080 (tomcat’s default port), you might not have anything on publicip:80 that forwards that traffic as well.

    Edit after your comment:

    1. incoming traffic seems to be fine, but outgoing you do have those problems. Adding from @stringy05’s comment: Check if the IP in question is routable from your server: You’re connecting to whatever IP from that server, so use another means to create an outgoing connection, e.g. curl.

    Explanation for #1 & #3:
    If you connect to an external http server, it will handle the request differently based on the hostname used. It might well be that the IP “hostname” is blocked, either by a high level firewall, or just handled differently than the URL by the webserver itself. In most cases you can check this by connecting to the webserver in question from any other system, e.g. your own browser.

    Login or Signup to reply.
  2. Try putting your public domain names into the local /etc/hosts file of your server like this:
    127.0.0.1 localhost YOURPUBLIC.DOMAIN.NAME

    This way your Java code does not need to try to use the external IP-adres but instead connects directly to Tomcat.

    Good luck!

    Login or Signup to reply.
  3. If Tomcat is listening (bound) to your public IP-adres it should work, but maybe your public IP-adres belongs to some other device, like a SOHO router, than your problem is similar to this:

    https://superuser.com/questions/208710/public-ip-address-answered-by-router-not-internal-web-server-with-port-forwardi

    But without an DNS name you cannot simply add a line to /etc/hosts but you can add the public IP-adres to one of your Network Interfaces Cards (NIC) like lo (loopback), eth0, etc. as described in one of these articles:

    E.g. with public IP-address 1.2.3.4 you would need (which will only be effective until next reboot and worst case might interfere with your ability to connect to the server with e.g. SSH!):

    sudo ip addr add 1.2.3.4/32 dev lo

    It may be useful to have the output of these commands to better understand your setup, feel free to share it in your question, with consistently anonymized public IP-adres):

    Either one of these (ss = socket stat, newer replacement for good old netstat):

    1. ss -nltp
    2. netstat -nltp

    And one of these:

    1. ifconfig
    2. ip addr show

    And last but not least either one of these:

    1. route
    2. ip route

    I don’t expect that we need to know your firewall config, but if you use it, it may be interesting to keep an eye on it while you are at it:

    iptables -L -n -v –line-numbers

    Login or Signup to reply.
  4. I think the curl timeout explains it – you have a firewall rule somewhere that is stopping the server accessing the public IP address.

    If there’s no reason the service can’t be accessed using localhost or the local hostname then do that but if you need to call the service via a public IP then it’s a matter of working out why the request gets a timeout from the server.

    Some usual suspects:

    • The server might not actually have internet access – can you curl https://www.google.com?
    • There might be a forward proxy required – a sys admin will know this sort of thing
    • There might be IP whitelisting on some infra around your server – think AWS security groups, load balancer IP whitelists that sort of thing. To fix that you need to know the public IP of your server curl https://canihazip.com/s and get that added to the whitelist
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search