背景
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(); } }
创作文章不容易,转载文章必须注明文章出处;如果这篇文章对您有帮助,点击右侧打赏,支持一下吧。