使用DNS的反向区域,解决通过IP反向查询主机名,适合web环境通过IP定位故障主机名

背景

http是应用层协议,他的报文里并未包含主机名和mac地址,通信链路层才会包含MAC地址,如下是一个普通的http报文

(以下图片来自网络:mac地址在哪一层_科普一下:什么叫MAC地址学习,记录什么内容_青涩Pure的博客-CSDN博客

 在企业内部,通常有很多台主机/IP设备,常见管理办法如下:

(1)一些企业的管理办法是将IP/MAC/主机名进行备案,设置成静态IP。适合人员数量固定,流动性不大的,如纯软件的开发公司。

 (2)一些企业用主机名,开启DHCP(本文要说明的情况),适合IP资源匮乏,流动性比较大

          2.1 (笔记本、打印机、台式机等任意具有TCP/IP通信能力的)ip设备从一个路由转移到另一台路由下面,比如办公环境迁移到生成环境A,

                   然后又从生成环境A转移到生成环境B,下班的时候可能就从生成环境搬回办公室。

         2.2  人员流失严重的公司

由于笔者经常要从办公室去生产环境,生产环境中 每台IP设备都有唯一的主机名,且开启了DHCP,上一秒某个IP设备的DHCP租赁到期了, 可能就要重新申请IP。

如果某个IP设备有故障,并且需要调试,再去找这台主机就相对麻烦,必须具有丰富的网络知识才可以解决问题。

解决方法

使用DNS反向区域(DNS reverse  lookup),通常我们是通过域名查询IP然后发起通信,反向区域则是一个逆向的操作:即通过IP解析主机名。

方法原型,使用linux的dig命令,命令如下

dig -x 待解析的IP @DNS服务器

#eg.
dig -x 10.10.5.30 @192.168.10.253

后面的dns服务器可以不选择,将会使用默认的DNS,解析的结果如下:

[root@127.0.0.1]# dig -x 8.8.8.8

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.8 <<>> -x 8.8.8.8
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54168
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;8.8.8.8.in-addr.arpa.          IN      PTR

;; ANSWER SECTION:
8.8.8.8.in-addr.arpa.   2693    IN      PTR     dns.google.

;; Query time: 9 msec
;; SERVER: 192.168.2.1#53(192.168.2.1)
;; WHEN: Sun Dec 26 14:57:24 CST 2021
;; MSG SIZE  rcvd: 62

上面的ANSWER Section就是我们需要的结果,8.8.8.8的主机名是dns.google.

该方法同样适用于内网。

java中使用的库是dnsjava,下面是测试代码(请修改maven仓库地址即相关jar版本为本地的)

java -cp .;D:\develop\apache-maven-3.6.3\repo\dnsjava\dnsjava\3.4.3\dnsjava-3.4.3.jar;D:\develop\apache-maven-3.6.3\repo\org\slf4j\slf4j-api\1.7.32\slf4j-api-1.7.32.jar org.xbill.DNS.tools.dig -x 10.10.124.23 @192.168.10.253
package com.kshg.mes.common.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.xbill.DNS.*;

import java.io.IOException;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * 提供dns相关服务
 */
@Slf4j
public class DNSUtil {

    /***
     * DNS反向解析/反向区域:ip->主机名
     * @param ipAddress ip地址
     * @return
     * @throws IOException
     */
    public static String reverseLookup(String ipAddress) throws IOException {

        log.info("starting reverse DNS lookup for {}", ipAddress);

        final long startTime = System.currentTimeMillis();

        final Name name = ReverseMap.fromAddress(ipAddress);
        final Record rec = Record.newRecord(name, Type.PTR, DClass.IN);
        final Message query = Message.newQuery(rec);
        final SimpleResolver res = new SimpleResolver();

        final Message response = res.send(query);
        final List<Record> answers = response.getSection(Section.ANSWER);

        final List<PTRRecord> records = answers.stream()
                .filter(answer -> answer.getType() == Type.PTR)
                .map(item -> (PTRRecord) item).collect(Collectors.toList());

        log.info("ptr records: {}", records);
        final long endTime = System.currentTimeMillis();

        log.info("end reverse DNS lookup for {},elapsed: {}ms", ipAddress, endTime - startTime);
        if(CollectionUtils.isEmpty(records))
        {
            return null;
        }
        return records.get(0).rdataToString();
    }
}
本博客文章绝大多数为原创,少量为转载,代码经过测试验证,如果有疑问直接留言或者私信我。
创作文章不容易,转载文章必须注明文章出处;如果这篇文章对您有帮助,点击右侧打赏,支持一下吧。
原文地址:https://www.cnblogs.com/passedbylove/p/15733056.html