Jack Twain
Jack Twain

Reputation: 6382

How to use hostnames instead of IPs in jetty?

I'm using the IPAcccessHandler in jetty to restrict access to requests coming from certain domains. However, I'm really stuck with two problems:

1- It seems that IPAccessHandler only accepts IPs to white or black list, although it's Javadocs says that one can block by URLs. This is an XML snippet of my jetty-ipaccess.xml:

  <Set name="black">
    <Array type="String">
      <Item>google.com</Item>
    </Array>
  </Set>

Now if I run jetty I get the following exception (i.e jetty fails to start):

Caused by: java.lang.IllegalArgumentException: Invalid IP address pattern: google.com

But if I use an IP address (e.g. 127.0.0.1) then jetty starts fine.

2- Now say I started jetty by blocking access from IP 127.0.0.1, then if I try to request 127.0.0.1 in my browser I get the correct forbidden error. Bit if I try to request http://localhost, then I get this error:

HTTP ERROR: 500

Problem accessing /. Reason:

    java.lang.IllegalArgumentException: Invalid IP address: 0:0:0:0:0:0:0:1

I've been trying for two days so far without any luck! Any help is much appreciated!

Upvotes: 1

Views: 1322

Answers (1)

Joakim Erdfelt
Joakim Erdfelt

Reputation: 49545

The IPAccessHandler only uses IP addresses, hence its name.

It would be highly inefficient (and wrong) to use use hostnames, as either the configuration on the IPAccessHandler side or the validation of the incoming request side.

Lets use this java code to explore what I mean.

package net;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class MultiDns
{
    public static void main(String[] args)
    {
        try
        {
            String hostname = "www.google.com";
            System.out.printf("Hostname: %s%n",hostname);
            for (InetAddress addr : InetAddress.getAllByName(hostname))
            {
                System.out.printf(" - %s [%s]%n",addr.getHostAddress(),InetAddress.getByAddress(addr.getAddress()).getHostName());
            }
        }
        catch (UnknownHostException e)
        {
            e.printStackTrace();
        }
    }
}

The results of this lookup of google.com for me show the following ...

Hostname: www.google.com
 - 74.125.25.106 [pa-in-f106.1e100.net]
 - 74.125.25.99 [pa-in-f99.1e100.net]
 - 74.125.25.104 [pa-in-f104.1e100.net]
 - 74.125.25.147 [pa-in-f147.1e100.net]
 - 74.125.25.105 [pa-in-f105.1e100.net]
 - 74.125.25.103 [pa-in-f103.1e100.net]
 - 2607:f8b0:400e:c00:0:0:0:67 [pf-in-x67.1e100.net]

Since I live in Arizona, I get the above results, but if you lived in Europe, or Asia (as examples), you'd get different results.

And the results you see today, are likely to be different later.

Also, when you take the IP's that arrive back from a query to google.com you'll see that you can't resolve google.com back from those IPs (they return results for 1e100.net addresses).

There is no 1::1 relationship between a hostname and an IP in any sense where using a hostname for access control makes sense.

Even if you add hostnames to the configuration side, you'd need to query that hostname for its ips on each and every request to know if the incoming request's IP is now allowed or denied. This is far too costly of an activity to perform.

You might be thinking that Jetty could just use the ttl/expiration of the dns request to limit the number of times it performs a dns query for that domain. Alas, Java does not have access to the ttl information of a dns response.

Upvotes: 1

Related Questions