2009-12-02 8 views
18

java.net apiでキャッシュされたDNSを表示/ダンプする方法はありますか?Java DNSキャッシュビューア

+0

キャッシュを実行するにはDNSサーバーが必要です。ホスト自体はDNS要求をキャッシュしません。 –

+2

ホストキャッシュがありません。実際にはJRE(セキュリティーマネージャーを使って動作)とブラウザーはDNSルックアップを「ピン」しています。 –

+0

dnsリゾルバライブラリは通常、DNSの結果をキャッシュして、あまりサーバーに迷惑をかけないようにし、より迅速な応答を提供します。 – nos

答えて

18

正と負のDNSアドレスキャッシュを出力するスクリプトです。

import java.lang.reflect.Field; 
import java.net.InetAddress; 
import java.net.UnknownHostException; 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 
import java.util.Map; 
public class DNSCache { 
    public static void main(String[] args) throws Exception { 
    InetAddress.getByName("stackoverflow.com"); 
    InetAddress.getByName("www.google.com"); 
    InetAddress.getByName("www.yahoo.com"); 
    InetAddress.getByName("www.example.com"); 
    try { 
     InetAddress.getByName("nowhere.example.com"); 
    } catch (UnknownHostException e) { 

    } 

    String addressCache = "addressCache"; 
    System.out.println(addressCache); 
    printDNSCache(addressCache); 
    String negativeCache = "negativeCache"; 
    System.out.println(negativeCache); 
    printDNSCache(negativeCache); 
    } 
    private static void printDNSCache(String cacheName) throws Exception { 
    Class<InetAddress> klass = InetAddress.class; 
    Field acf = klass.getDeclaredField(cacheName); 
    acf.setAccessible(true); 
    Object addressCache = acf.get(null); 
    Class cacheKlass = addressCache.getClass(); 
    Field cf = cacheKlass.getDeclaredField("cache"); 
    cf.setAccessible(true); 
    Map<String, Object> cache = (Map<String, Object>) cf.get(addressCache); 
    for (Map.Entry<String, Object> hi : cache.entrySet()) { 
     Object cacheEntry = hi.getValue(); 
     Class cacheEntryKlass = cacheEntry.getClass(); 
     Field expf = cacheEntryKlass.getDeclaredField("expiration"); 
     expf.setAccessible(true); 
     long expires = (Long) expf.get(cacheEntry); 

     Field af = cacheEntryKlass.getDeclaredField("address"); 
     af.setAccessible(true); 
     InetAddress[] addresses = (InetAddress[]) af.get(cacheEntry); 
     List<String> ads = new ArrayList<String>(addresses.length); 
     for (InetAddress address : addresses) { 
      ads.add(address.getHostAddress()); 
     } 

     System.out.println(hi.getKey() + " "+new Date(expires) +" " +ads); 
    } 
    } 
} 
+0

反射? – Pacerier

+0

いいえサンプル:-) –

+0

誰かが上記のコードを実行したい場合セキュリティマネージャを使用します。 (またはセキュリティマネージャを使用して実行しているサーブレットエンジンで実行するように変換する)場合、ポリシーファイルのエントリは次のように役立ちます。 アクセス権java.lang.RuntimePermission "accessDeclaredMembers"; アクセス権java.lang.reflect.ReflectPermission "suppressAccessChecks"; アクセス権java.net.SocketPermission "*"、 "accept、connect、resolve"; –

17

java.net.InetAddressは、成功したホスト名と成功しなかったホスト名の解決をキャッシュします。そのjavadocをから

InetAddressクラスは 店の成功だけでなく、 失敗したホスト名解決にキャッシュを持っています。デフォルトでは

、セキュリティマネージャが をインストールされている、 DNSスプーフィング攻撃から保護するために、 したホスト名解決の結果は永遠にキャッシュされ です。セキュリティ マネージャがインストールされていない場合、デフォルトの の動作は、 有限(実装に依存) 期間のエントリをキャッシュします。 ホスト名解決に失敗した結果、パフォーマンスを向上させるために非常に短い時間( (10秒))キャッシュされた です。

デフォルトの動作が必要な ない場合は、Javaセキュリティプロパティ は、正のキャッシュ用の異なるタイム・ツー・ライブ (TTL)値に設定することができます。 同様に、システム管理者は、必要に応じて に異なるネガティブキャッシングTTL値 を設定できます。

2つのJavaセキュリティプロパティは、正と 負のホスト名解決のキャッシュに使用 TTL値を制御します。

  • networkaddress.cache.ttl
    はから 成功したネーム参照のキャッシュポリシーを示します名前は です。値は のように指定され、 ルックアップを成功させるために 秒の数を示します。既定の設定は、具体的な の実装時間に対して キャッシュになります。

    値-1は、「キャッシュ 永遠に」を示します。

  • networkaddress.cache.negative.ttl(デフォルト:10)
    は、ネームサービスからアン成功ネーム参照のキャッシュ ポリシー を示します。値は で、 を示し、 が失敗したルックアップに失敗したことを示す秒数を示します。

    値0は、「キャッシュしない」ことを示します。 -1の値は「キャッシュ 永遠に」を示します。

何を考えていることはjava.net.InetAddressで使用される(タイプjava.net.InetAddress$Cacheの)キャッシュをダンプしている、彼らは、内部実装の詳細であり、したがってprivate場合:

/* 
* Cached addresses - our own litle nis, not! 
*/ 
private static Cache addressCache = new Cache(Cache.Type.Positive); 

private static Cache negativeCache = new Cache(Cache.Type.Negative); 

だから私はあなた'LLを疑いますこれを箱から出して何かを見つけて、あなたの目標を達成するためにリフレクションをする必要があると思います。

1

上記の答えはJava 8ではもう機能しません。 ここをクリックしてください:

import java.lang.reflect.Field; 
import java.net.InetAddress; 
import java.net.UnknownHostException; 
import java.time.Instant; 
import java.time.temporal.ChronoUnit; 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 
import java.util.Map; 

public class DNSCache { 
    public static void main(String[] args) throws Exception { 
     InetAddress.getByName("stackoverflow.com"); 
     InetAddress.getByName("www.google.com"); 
     InetAddress.getByName("www.yahoo.com"); 
     InetAddress.getByName("www.example.com"); 
     try { 
      InetAddress.getByName("nowhere.example.com"); 
     } catch (UnknownHostException e) { 

     } 

     String addressCache = "addressCache"; 
     System.out.println(addressCache); 
     printDNSCache(addressCache); 
     String negativeCache = "negativeCache"; 
     System.out.println(negativeCache); 
     printDNSCache(negativeCache); 
    } 

    private static void printDNSCache(String cacheName) throws Exception { 
     Class<InetAddress> klass = InetAddress.class; 
     Field acf = klass.getDeclaredField(cacheName); 
     acf.setAccessible(true); 
     Object addressCache = acf.get(null); 
     Class cacheKlass = addressCache.getClass(); 
     Field cf = cacheKlass.getDeclaredField("cache"); 
     cf.setAccessible(true); 
     Map<String, Object> cache = (Map<String, Object>) cf.get(addressCache); 
     for (Map.Entry<String, Object> hi : cache.entrySet()) { 
      Object cacheEntry = hi.getValue(); 
      Class cacheEntryKlass = cacheEntry.getClass(); 
      Field expf = cacheEntryKlass.getDeclaredField("expiration"); 
      expf.setAccessible(true); 
      long expires = (Long) expf.get(cacheEntry); 

      Field af = cacheEntryKlass.getDeclaredField("addresses"); 
      af.setAccessible(true); 
      InetAddress[] addresses = (InetAddress[]) af.get(cacheEntry); 
      List<String> ads = new ArrayList<String>(addresses.length); 
      for (InetAddress address : addresses) { 
       ads.add(address.getHostAddress()); 
      } 

      System.out.println(hi.getKey() + " expires in " 
        + Instant.now().until(Instant.ofEpochMilli(expires), ChronoUnit.SECONDS) + " seconds " + ads); 
     } 
    } 
}