vagrant 端口转发不起作用:连接由对等方重置

vagrant port forwarding doesn't work: Connection reset by peer

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

我从 the official docs 获取了下面的配置,但它不起作用:(

主机运行s Ubuntu17.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

http 服务器是 node.js,在来宾机器上侦听端口 3000

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

==> default: Forwarding ports...
    default: 3000 (guest) => 3001 (host) (adapter 1)
    default: 22 (guest) => 2222 (host) (adapter 1)

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

从客户机(通过 ssh)访问端口 3000 也可以正常工作:
(以下是连接来宾机器时来自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

但是直接从主机请求端口 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

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

ubuntu@ubuntu-xenial:~$ sudo ufw status
Status: inactive

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

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

— 这只是意味着这些端口在各自的机器上是关闭的,这完全没问题。

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

$ curl http://127.0.0.1:3001/
curl: (56) Recv failure: Connection reset by peer

——表示网络设置有问题。但具体是什么?

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

更新 1

也许这很重要:当启动 vagrant 时,控制台会打印以下内容:

==> 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)

可能是 Vagrant 出于某种原因为错误的适配器转发了端口?也许它应该为 hostonly 转发,并为 nat 转发?没看懂,只是假设。

我终于修好了!

原因不是端口转发配置错误,不是 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}/`);
});

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

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

const hostname = '0.0.0.0';
const port = 3000;
...
server.listen(port, hostname, () => {

P. S. 对于这个问题给我带来的不便,我深表歉意。感谢所有帮助过我的人!起初,当我找到解决方案时,我打算删除这个问题,但决定还是自己回答更好,这样其他像我这样的人就可以节省他们和其他人花在解决此类案件上的时间未来,所以我决定保留它。

127.0.0.1:3000 切换到 0.0.0.0:3000 确实将访客 运行 服务暴露给主机网络,但是,我觉得应该存在更好的方法,无论如何,值得一提,我注意到来宾 OS 上的 运行 netstat -nltp 将显示 'foreign addresses' 将暴露给主机 OS.