這篇一樣是用 dnsjava,目標是實作更新 DNS 的程式。
在更新之前,必須先把 DNS Server 的動態更新功能打開,否則一般狀況 DNS Server 是不允許被更改內容的
我這邊測試是架了一台 Windows 2008 R2,在上面加上 DNS 角色。
設定動態更新的地方如圖所示,紅圈圈的位置就是設定動態更新的地方:
由上圖可以看出,這裡假設 DNS Server 管理的網域是 example.com.tw,IP 範圍是 10.0.1.*。
接著就是 Java 的程式碼了。
其實程式碼很簡單 XD,跟 dnsjava 的內建範例幾乎一模一樣!
String DNS_DOMAIN = "10.0.1.1"; // DNS Server try { Name zone = Name.fromString("example.com.tw."); // domain name Name host = Name.fromString("test", zone); // host name Update update = new Update(zone); update.add(host, Type.A, 60, "10.0.1.2"); Resolver res = new SimpleResolver(DNS_DOMAIN); res.setTCP(true); Message response = res.send(update); } catch (Exception e) { e.printStackTrace(); }
第 3 行指定的是 FQDN 裡面的 domain,第 4 行指定的則是 FQDN 的 host-name
兩個串起來就是 test.example.com.tw.,也就是這次要更新的目標域名。
要注意的是 example.com.tw. 最後面那個 . 一定要加
否則會被判定為不是 absolute name 而丟出 RelativeNameException。
6~9 行是設定要更新的內容,第 6 行指定要更新的 domain 是 example.com.tw.
第 7 行就指定這次要更新的內容,要修改(或加入) tesy.example.com.tw. 這個域名
DNS 種類為 A、TTL 為 60、IP 位址為 10.0.1.2。
如果 DNS Server 是在 Linux 上架設的,有可能會設定需要加密驗證才能拿到修改的權限
這時在 Resolver 那裡就要額外設定加密的方法
例如:
Resolver res = new SimpleResolver(DNS_DOMAIN); res.setTSIGKey(TSIG.HMAC_MD5, "test", "ZaGKmHwKUqdXvqDOx/NaNWaAXW8PLACbHBn69xepTFo=")); res.setTCP(true);
其中 setTSIGKey() 的那行就是設定加密驗證的方法
第一個參數是 DNS Server 設定的加密方法,預設是 HMAC_MD5
第二個參數是 DNS Server 驗證使用的名稱,這可以在 Linux 產生的 key 檔上看出來
第三個參數是 DNS Server 加密後用來驗證的字串
例如 Linux 產生的 key 檔的內容可能是這樣:
test. IN KEY 512 3 157 ZaGKmHwKUqdXvqDOx/NaNWaAXW8PLACbHBn69xepTFo=那麼名稱就是第一個值 test,而最後一個值 ZaGKmHwKUqdXvqDOx/NaNWaAXW8PLACbHBn69xepTFo= 就是加密字串。
DNS update query 送出之後,可以從回傳的 Message 的 Header 看到 query 的結果
Message response = res.send(update); System.out.println(response.getHeader().toString());上述的程式碼,可能回傳的結果是:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 65035status 那裡就是結果了,可能比較常看到的狀態如下
- NOERROR:命令執行成功
- NOTAUTH:無權限
- REFUSED:命令被拒絕
但送 DNS query 時沒有送 TSIGKey,DNS Server 會回應 REFUSED。
而如果有送 TSIGKey,但給的驗證名稱或密文或演算法是錯的,則 DNS Server 會回應 NOTAUTH。
補充:要得到結果可以直接透過 RCode(Response Code)來判斷
Message response = res.send(update); int status = response.getHeader().getRcode();RCode 的種類可以參考 [1],0 即表示 NOERROR。
參考資料:
1、DNS Message Header and Question Section Format
沒有留言:
張貼留言