如何在localhost上为通配符域创建dns服务器以与node / express一起使用?

时间:2013-09-24 22:22:01

标签: node.js express dns

我想创建一个使用express的本地https服务器来处理example.com的任何子域。理想情况下,我想修改我的主机文件,如下所示: 127.0.0.2 localhost * .example.com 但这是不允许的。
所以我想创建自己的DNS服务器,将* .example.com的IP解析为127.0.0.2。我查看了https://github.com/tjfontaine/node-dnshttps://github.com/iriscouch/dnsd,但我不明白如何将它们应用到我的方案中。

3 个答案:

答案 0 :(得分:1)

您需要运行本地DNS服务器来拦截请求。

我发现dnsproxy.py工作得很好。它是用python编写的,需要在你打算使用时运行。

您需要修改hosts文件并添加如下所示的行:

127.0.0.1    *.example.com

之后,您将需要启动DNS代理服务器:

$ sudo python dnsproxy.py -s 8.8.8.8

8.8.8.8是Google DNS服务器的IP地址,如果在hosts文件中找不到该记录,则会将其用作后备。

完成此操作后,您应该能够在端口80上启动快速服务器并处理对*.example.com的请求。

答案 1 :(得分:1)

xip.io可能不适合您,但我发现它非常有用。 “xip.io是一个神奇的域名,可为任何IP地址提供通配符DNS。” “xip.io在公共Internet上运行自定义DNS服务器。当您的计算机查找xip.io域时,xip.io DNS服务器从域中提取IP地址并将其发送回响应中。”

因此,以下所有域都将解析为127.0.0.1:

127.0.0.1.xip.io
www.127.0.0.1.xip.io
example.com.127.0.0.1.xip.io
something.example.com.127.0.0.1.xip.io

The daemon碰巧用Coffeescript编写,可以在node.js上运行。)

答案 2 :(得分:1)

有些事情让我沮丧,我已经完成了。

  1. 我没有在我的机器的网络设置中设置DNS服务器IP地址。
  2. 启动DNS服务器和启动https服务器之间存在时间问题。
  3. 我没有在DNS响应中包含端口号
  4. 这是我的解决方案:

    var fs = require('fs');
    var path = require('path');
    var dns = require('native-dns');
    var https = require('https');
    var express = require('express');
    
    String.prototype.endsWith = function(s) {
      return this.length >= s.length && this.substr(this.length - s.length) == s;
    };
    
    var startDns = function(example_port, callback) {
      var server = dns.createServer();
    
      server.on('request', function(request, response) {
        var found = false;
    
        for (var q = 0; q < request.question.length; q++)
        {
          var name = request.question[q].name;
          if (name.endsWith("example.com"))
          {
            response.answer.push(dns.A({
              name:name,
              address:'127.0.0.2',
              port:example_port,
              ttl:600
            }));
            found = true;
          }
        }
        if (found)
        {
          response.send();
        }
      });
    
      server.on('error', function(err, buff, req, res) {
        console.log(JSON.stringify(err));
      });
    
      server.on('listening', function() {
        console.log("DNS server started on port 53");
        if (callback)
        {
          callback();
        }
      });
    
       server.serve(53);
       return server;
    };
    
    var startHttps = function(serverPort) {
      // Set up secure server
      var options = {
        key:fs.readFileSync(path.join(__dirname, 'certificates/example.com-key.pem')),
        cert:fs.readFileSync(path.join(__dirname, 'certificates/example.com-cert.pem'))
      };
    
      var app = express();
      var server = https.createServer(options, app);
      app.get('*', function(req, res, next) {
        res.send('Hello from ' + req.headers.host);
      });
      server.listen(serverPort, 'example.com');
      console.log('https server started on port ' + serverPort);
      return server;
    };
    
    var server_port = parseInt(process.argv[2] || 8082);
    var httpsServer;
    
    var dnsServer = startDns(server_port, function() {
      httpsServer = startHttps(server_port)
    });
    
    process.on('SIGINT', function() {
      console.log("shutting down");
      if (httpsServer)
      {
        httpsServer.close();
      }
      if (dnsServer)
      {
        dnsServer.close();
      }
    });
    

    注意:这适用于我的Windows机器。我还在其他平台上测试。我不确定我是否正确处理了我的dns服务器中无法识别的域。