尝试用 netty 写了一个简单的 dns server, dig 显示结果是正常的,但是浏览器, curl, wget 访问就访问不到了

2019-07-19 09:11:14 +08:00
 sipangzi

我把虚拟机(win)的 dns 设置成我自己的 dns server 192.168.43.245,然后程序会把 aaa.1.tqtqtq.aaa 这个域名的 ip 解析成 192.168.43.245 ,192.168.43.245 的 80 端口上开了一个 web 服务,这样我认为访问 aaa.1.tqtqtq.aaa 的时候就会访问 192.168.43.245 的 web 服务。

这是本机 dig 的结果

dig aaa.1.tqtqtq.aaa @127.0.0.1

; <<>> DiG 9.10.6 <<>> aaa.1.tqtqtq.aaa @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57548
;; flags: qr; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;aaa.1.tqtqtq.aaa.      IN  A

;; ANSWER SECTION:
aaa.1.tqtqtq.aaa.   0   IN  A   192.168.43.245

;; Query time: 5 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu Jul 18 21:24:32 CST 2019
;; MSG SIZE  rcvd: 66

然后用浏览器访问 aaa.1.tqtqtq.aaa 是访问不通的,比如在 ie 下返回的错误信息是

发生临时 DNS 错误。请尝试刷新页面。

错误代码: INET_E_RESOURCE_NOT_FOUND

直接访问 http://192.168.43.245/login 是访问的到的,证明 53 端口和 80 端口虚拟机都访问不到,dns 解析出了问题

在虚拟机 nslookup 的结果也有些不正常

DNS request timed out.
    timeout was 2 seconds.
服务器:  UnKnown
Address:  192.168.43.245

非权威应答:
名称:    aaaa.1.tqtqtq.aaa
Addresses:  192.168.43.245
         192.168.43.245

以下是 DNSHandler 的代码,没有找到问题出现在哪里,大家帮忙分析一下吧

public void channelRead0(ChannelHandlerContext ctx, DatagramDnsQuery query){
        ByteBuf answerIP;
        int logID;
        DatagramDnsResponse response = new DatagramDnsResponse(query.recipient(), query.sender(), query.id());
        DefaultDnsQuestion dnsQuestion = query.recordAt(DnsSection.QUESTION);
        String connectIP = query.sender().getHostName();
        String domainRegex = "\\.\\d+\\."+domain.replace(".","\\.")+"\\.$";
        String subDomain = dnsQuestion.name().replaceAll(domainRegex,"");
        String[] hd = dnsQuestion.name().replace('.'+domain+'.',"").split("\\.");
        try{
            logID = Integer.parseInt(hd[hd.length-1]);
        }catch (NumberFormatException n){
            return;
        }
        String ipRegex = "^((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})(\\.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})){3}$";
        String rebindRegex = "^((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})(\\.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})){3}\\.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})(\\.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})){3}$";
        if(Pattern.compile(rebindRegex).matcher(subDomain).matches()) {
            String[] s = subDomain.split("\\.");
            byte[] ip = new byte[4];
            byte[] rebindIP = new byte[4];
            for (int i = 0; i < s.length; i++) {
                if (i < 4) {
                    ip[i] = (byte) Integer.parseInt(s[i]);
                } else {
                    rebindIP[i - 4] = (byte) Integer.parseInt(s[i]);
                }
            }
            if (questionDomainMap.containsKey(dnsQuestion.name())) {
                answerIP = Unpooled.wrappedBuffer(questionDomainMap.get(dnsQuestion.name()));
                questionDomainMap.remove(dnsQuestion.name());
            } else {
                answerIP = Unpooled.wrappedBuffer(ip);
                questionDomainMap.put(dnsQuestion.name(), rebindIP);
            }
        }else if(Pattern.compile(ipRegex).matcher(subDomain).matches()){
            String[] s = subDomain.split("\\.");
            byte[] ip = new byte[s.length];
            for(int i=0; i < s.length; i++){
                ip[i] = (byte)Integer.parseInt(s[i]);
            }
            answerIP = Unpooled.wrappedBuffer(ip);
        }else{
            answerIP = Unpooled.wrappedBuffer(new byte[] {(byte) 192, (byte) 168, 43, (byte)245});
            System.out.println(dnsQuestion.name());
            System.out.println(1);
        }
        DnsLog dnslog = new DnsLog(UUID.randomUUID().toString(),dnsQuestion.name().substring(0,dnsQuestion.name().length()-1),new Timestamp(System.currentTimeMillis()),connectIP,dnsQuestion.type().toString(),logID);
        dnsLogService.addDnsLog(dnslog);
        response.addRecord(DnsSection.QUESTION, dnsQuestion);
        DefaultDnsRawRecord queryAnswer = new DefaultDnsRawRecord(dnsQuestion.name(), DnsRecordType.A, 0, answerIP);
        response.addRecord(DnsSection.ANSWER, queryAnswer);
        ctx.writeAndFlush(response);
4090 次点击
所在节点    Java
15 条回复
Aruforce
2019-07-19 09:17:34 +08:00
你是用虚拟的浏览器访问的?
sipangzi
2019-07-19 09:18:51 +08:00
@Aruforce 嗯,虚拟机的 dns 设置成我自己 server 的地址了,然后虚拟机浏览器访问的,不行
jinliming2
2019-07-19 09:32:53 +08:00
你 dig 是 @127.0.0.1,浏览器却设置的 192.168.43.245 ,是这个原因吗?
gy911201
2019-07-19 09:35:25 +08:00
监听的 127.0.0.1 吗?还有就是检查防火墙是否开启对应的端口
iwishing
2019-07-19 09:39:54 +08:00
直接改你虚机的 hosts 文件好了,看看是 dns 服务器的问题还是 web 服务器的问题
iwishing
2019-07-19 09:41:04 +08:00
另外你是在 dns 服务器上起的虚机嘛?你服务器的防火墙是不是 53 口 80 口都没开?
sipangzi
2019-07-19 09:45:41 +08:00
@gy911201
@iwishing
都是 0.0.0.0,不是防火墙问题,都是通的,直接 ip 可以访问到
@jinliming2
我换台 linux 的虚拟机试一下,windows 这个改了 dns 访问不到,没有 dig 我就没执行了
sipangzi
2019-07-19 09:53:35 +08:00
@jinliming2 我换了另外一台 Debian 的虚拟机,改了 dns 地址发现 wget 和浏览器都可以访问到,但是 windows 的不行,但是我看到 windows 发起 dns 请求之后,dns server 也是给了同样的回复的,奇怪为什么 windows 上 curl 和浏览器都是不行的,看来不像是代码问题
guyeu
2019-07-19 10:01:13 +08:00
可能触发了某种防止 dns 劫持的机制?
sipangzi
2019-07-19 10:05:01 +08:00
@guyeu 还没搞明白,目前看就是 windows 访问不正常,linux 访问没问题,windows 的改完 dns 不行
iwishing
2019-07-19 11:11:45 +08:00
@sipangzi ipconfig/flushdns
ms2008
2019-07-19 11:37:51 +08:00
服务端监听在 ipv4 还是 ipv6 ?
ms2008
2019-07-19 11:39:49 +08:00
jinliming2
2019-07-19 12:04:46 +08:00
windows 上用 nslookup 看一下 DNS ?
ipconfig /flushdns 清一下缓存,重启浏览器,或者干脆重启一下电脑试试?
sipangzi
2019-07-23 10:52:14 +08:00
代码放到服务器上测试没有问题,可能是本机和虚拟机之前的网络问题导致的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/584289

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX