vagrant port forwarding不起作用:连接由peer重置

why*_*yer 3 ubuntu portforwarding node.js vagrant vagrantfile

ssh端口转发(默认启用)工作正常,但我的自定义端口转发没有.

我从官方文档中获取以下配置,但它不起作用:(

主机运行Ubuntu 17.04

Vagrantfile 是:

Vagrant.configure("2") do |config|
    config.vm.box = "ubuntu/xenial64"
    # though, I've also tried ubunty/zesty64 and centos/7 - with same results
    config.vm.provision :shell, path: "vagrant/provision.sh"
    config.vm.network "forwarded_port", guest: 3000, host: 3001
end
Run Code Online (Sandbox Code Playgroud)

http服务器是node.js,客户机上的侦听端口3000

当我运行时,vagrant up我看到有2个端口转发:

==> default: Forwarding ports...
    default: 3000 (guest) => 3001 (host) (adapter 1)
    default: 22 (guest) => 2222 (host) (adapter 1)
Run Code Online (Sandbox Code Playgroud)

我通过端口2222上的ssh成功连接到guest,因此转发22 (guest) => 2222 (host)工作正常.

从客户机访问端口3000(通过ssh)也可以正常工作:(
以下是连接到客户机时来自ssh控制台的报价)

ubuntu@ubuntu-xenial:~$ curl -v http://localhost:3000/
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Type: text/plain
< Date: Fri, 14 Jul 2017 12:34:29 GMT
< Connection: keep-alive
< Content-Length: 12
< 
Hello World
* Connection #0 to host localhost left intact
Run Code Online (Sandbox Code Playgroud)

但直接从主机请求端口3001失败:(
以下是来自本地主机上的常规控制台(不是ssh)的引用)

$ curl -v http://127.0.0.1:3001/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 3001 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:3001
> User-Agent: curl/7.52.1
> Accept: */*
> 
* Recv failure: Connection reset by peer
* Curl_http_done: called premature == 1
* Closing connection 0
curl: (56) Recv failure: Connection reset by peer
Run Code Online (Sandbox Code Playgroud)

我还发现这与防火墙无关,因为它被禁用(在两台机器上):

ubuntu@ubuntu-xenial:~$ sudo ufw status
Status: inactive
Run Code Online (Sandbox Code Playgroud)

我还注意到两台机器上的所有其他端口都返回相同的:

ubuntu@ubuntu-xenial:~$ curl http://127.0.0.1:3003/
curl: (7) Failed to connect to 127.0.0.1 port 3003: Connection refused
Run Code Online (Sandbox Code Playgroud)

- 这意味着这些端口在各自的机器上关闭,这是完全正常的.

并且只有主机上的端口3001返回Connection reset by peer:

$ curl http://127.0.0.1:3001/
curl: (56) Recv failure: Connection reset by peer
Run Code Online (Sandbox Code Playgroud)

- 这意味着网络设置中出现了问题.但到底是什么?

请帮我正确设置端口转发!

更新1

也许这很重要:当增加流浪汉时,会在控制台中打印以下内容:

==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 3000 (guest) => 3001 (host) (adapter 1)
    default: 22 (guest) => 2222 (host) (adapter 1)
Run Code Online (Sandbox Code Playgroud)

也许原因是Vagrant出于某种原因转发错误适配器的端口?也许它应该转发为hostonly,它转发nat?我不明白,这只是一个假设.

why*_*yer 11

最后,我能够解决它!

原因不是端口转发配置错误,也不是Vagrant的一些设置,甚至VirtualBox,Guest也不是Host OS.

原因是我错误地设置了Node.JS的端口监听.

我做了什么(不正确):我已将其设置为在客户机上侦听端口3000.我认为客户机本身的IP本身就像往常一样,是127.0.0.1.下面是我的Node.JS服务器代码:

const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
    res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});

server.listen(port, hostname, () => {
    console.log(`Server running at http://${hostname}:${port}/`);
});
Run Code Online (Sandbox Code Playgroud)

我必须做的事情(正确):将其设置为侦听相同的端口,但在其他IP上:0.0.0.0 - 这是来宾机器的正确本地IP,当与端口一起使用时,它本身可在内部使用转发.

因此,我的Vagrantfile是正确的; 这是我在Node.JS服务器中修复的内容:

const hostname = '0.0.0.0';
const port = 3000;
...
server.listen(port, hostname, () => {
Run Code Online (Sandbox Code Playgroud)

PS我为这个问题造成的不便深表歉意.谢谢所有帮助过我的人!起初,当我找到解决方案时,我打算删除这个问题,但我决定自己更好地回答这个问题,以便像我这样的其他人可以节省他们和其他人花在修复此类案件上的时间.未来,所以我决定保留它.

  • 谢谢,尽管我没有尝试为 Node 执行此操作,但我能够使用相同的配置“0.0.0.0”作为 Elasticsearch Kibana 中的主机名,在我的主机上浏览 (2认同)
  • @whyer 感谢您没有删除这个问题。它刚刚解决了我的问题。 (2认同)
  • 这真太了不起了。我在使用 Ruby 应用程序时遇到了同样的问题,将 Web 服务器绑定到 0.0.0.0 就是解决方案。谢谢! (2认同)