V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
sipangzi
V2EX  ›  Java

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

  •  
  •   sipangzi · 2019-07-19 09:11:14 +08:00 · 4086 次点击
    这是一个创建于 1947 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我把虚拟机(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);
    
    15 条回复    2019-07-23 10:52:14 +08:00
    Aruforce
        1
    Aruforce  
       2019-07-19 09:17:34 +08:00
    你是用虚拟的浏览器访问的?
    sipangzi
        2
    sipangzi  
    OP
       2019-07-19 09:18:51 +08:00
    @Aruforce 嗯,虚拟机的 dns 设置成我自己 server 的地址了,然后虚拟机浏览器访问的,不行
    jinliming2
        3
    jinliming2  
       2019-07-19 09:32:53 +08:00 via iPhone
    你 dig 是 @127.0.0.1,浏览器却设置的 192.168.43.245 ,是这个原因吗?
    gy911201
        4
    gy911201  
       2019-07-19 09:35:25 +08:00
    监听的 127.0.0.1 吗?还有就是检查防火墙是否开启对应的端口
    iwishing
        5
    iwishing  
       2019-07-19 09:39:54 +08:00
    直接改你虚机的 hosts 文件好了,看看是 dns 服务器的问题还是 web 服务器的问题
    iwishing
        6
    iwishing  
       2019-07-19 09:41:04 +08:00
    另外你是在 dns 服务器上起的虚机嘛?你服务器的防火墙是不是 53 口 80 口都没开?
    sipangzi
        7
    sipangzi  
    OP
       2019-07-19 09:45:41 +08:00
    @gy911201
    @iwishing
    都是 0.0.0.0,不是防火墙问题,都是通的,直接 ip 可以访问到
    @jinliming2
    我换台 linux 的虚拟机试一下,windows 这个改了 dns 访问不到,没有 dig 我就没执行了
    sipangzi
        8
    sipangzi  
    OP
       2019-07-19 09:53:35 +08:00
    @jinliming2 我换了另外一台 Debian 的虚拟机,改了 dns 地址发现 wget 和浏览器都可以访问到,但是 windows 的不行,但是我看到 windows 发起 dns 请求之后,dns server 也是给了同样的回复的,奇怪为什么 windows 上 curl 和浏览器都是不行的,看来不像是代码问题
    guyeu
        9
    guyeu  
       2019-07-19 10:01:13 +08:00
    可能触发了某种防止 dns 劫持的机制?
    sipangzi
        10
    sipangzi  
    OP
       2019-07-19 10:05:01 +08:00
    @guyeu 还没搞明白,目前看就是 windows 访问不正常,linux 访问没问题,windows 的改完 dns 不行
    iwishing
        11
    iwishing  
       2019-07-19 11:11:45 +08:00
    @sipangzi ipconfig/flushdns
    ms2008
        12
    ms2008  
       2019-07-19 11:37:51 +08:00
    服务端监听在 ipv4 还是 ipv6 ?
    ms2008
        13
    ms2008  
       2019-07-19 11:39:49 +08:00
    jinliming2
        14
    jinliming2  
       2019-07-19 12:04:46 +08:00 via iPhone
    windows 上用 nslookup 看一下 DNS ?
    ipconfig /flushdns 清一下缓存,重启浏览器,或者干脆重启一下电脑试试?
    sipangzi
        15
    sipangzi  
    OP
       2019-07-23 10:52:14 +08:00
    代码放到服务器上测试没有问题,可能是本机和虚拟机之前的网络问题导致的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1937 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 00:28 · PVG 08:28 · LAX 16:28 · JFK 19:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.