【问题标题】:NodeJS, bypass linux hosts fileNodeJS,绕过 linux hosts 文件
【发布时间】:2017-06-02 18:17:46
【问题描述】:

NodeJS 中有没有办法绕过 linux 的 /etc/hosts 文件?

例如,如果我的 hosts 文件中有一个条目,例如: 127.0.0.1 example.com

如何从 NodeJS 访问“真实的”example.com?

我不想临时修改 /etc/hosts 来执行此操作,因为它会带来一些问题并且不是一个干净的解决方案。

提前致谢!

【问题讨论】:

  • 一开始你为什么要这样做?
  • @OmriLuzon 解释起来真的很复杂。基本上,我希望我的 Linux 实例上所有可能的应用程序(即使是我无法控制的)都认为 example.com 指向 127.0.0.1,但我正在创建的一个特定 NodeJS 应用程序认为 example.com 指向真实的知识产权。
  • 我不相信这是可能的。这是一个非常奇怪的用例。一种选择是使用容器化或虚拟化并在其中运行您的应用程序?这样您就可以拥有一个单独的“干净”/etc/hosts 文件。

标签: node.js hosts


【解决方案1】:

一开始我认为这是不可能的,但后来我偶然发现了一条通往ignore the hosts file on Linux 的方法。此外,我在 Node.js 中发现了一个 DNS API。基本上,默认情况下,Node 会遵从操作系统进行 DNS 查找(将从 /etc/hosts 读取,如果不需要,则根本不进行 DNS 查询)。但是,Node 还公开了一种通过显式发出 DNS 请求来解析主机名的方法。这将为您提供您正在寻找的 IP 地址。

$ cat /etc/hosts
<snip>
127.0.0.1 google.com
$ ping google.com
PING google.com (127.0.0.1) 56(84) bytes of data.
...

这表明主机文件肯定在工作。

const dns = require('dns')

// This will use the hosts file.
dns.lookup('google.com', function (err, res) {
  console.log('This computer thinks Google is located at: ' + res)
})

dns.resolve4('google.com', function (err, res) {
  console.log('A real IP address of Google is: ' + res[0])
})

这会按预期输出不同的值:

$ node host.js
This computer thinks Google is located at: 127.0.0.1
A real IP address of Google is: 69.77.145.253

请注意,我使用最新的 Node v8.0.0 对此进行了测试。但是,我查看了一些较旧的文档,并且该 API 至少从 v0.12 开始就存在,因此,假设没有发生重大变化,这应该适用于您碰巧运行的任何版本的 Node。此外,将主机名解析为 IP 地址可能只是成功的一半。如果您尝试通过 IP 直接访问某些网站,它们的行为会很奇怪(或根本没有)。

【讨论】:

  • 谢谢,这是完美的,因为我可以向该 IP 发送请求,但要适当地选择主机标头。
【解决方案2】:

基于@supersam654 和this:我的解决方案(完整示例)与.get 请求(忽略hosts 与所有请求):

const dns = require("dns");
const url = require("url");

const req = (urlString, cb) => {
    const parsedUrl = url.parse(urlString);
    const hostname = parsedUrl.hostname;

    dns.resolve4(hostname, function(err, res) {
        if (err) throw err;
        console.log(`A real IP address of ${hostname} is: ${res[0]}`);
        const newUrl = urlString.replace(`${parsedUrl.protocol}//${hostname}`, `${parsedUrl.protocol}//${res[0]}`);

        https
            .get(
                newUrl,
                {
                    headers: { host: hostname },
                    servername: hostname
                },
                resp => {
                    let data = "";

                    // A chunk of data
                    resp.on("data", chunk => {
                        data += chunk;
                    });

                    // The whole response has been received. Print out the result.
                    resp.on("end", () => {
                        cb(data);
                    });
                }
            )
            .on("error", err => {
                console.log("Error request " + url + ": " + err.message);
            });
    });
};

// Example
req("https://google.com/", data => console.log(data));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-11
    • 1970-01-01
    • 1970-01-01
    • 2015-01-11
    • 1970-01-01
    • 2020-08-10
    相关资源
    最近更新 更多