Node.js 服务器侦听 UDP。 Tcpdump 说数据包正在通过,但节点没有得到它们

Node.js server listening for UDP. Tcpdump says packets are coming through, but node doesn't get them

正在与合作伙伴集成。我们的服务器有一个 restful 接口,但他们的产品会发出 UDP 数据包流。由于我们仍在制作原型,因此我不想对我们的 API 服务器存储库进行任何提交以适应更改。相反,我写了一个 node.js 服务器来监听他们的 UDP 数据包,做一些转换,然后 PUT 到我们的 restful 服务器。

我卡住了,因为 node.js 进程正在侦听端口 17270,但没有收到任何示例 UDP 数据包。

节点服务器

const dgram = require('dgram');
const server = dgram.createSocket('udp4');

server.on('error', function(err) {
  console.log('server error:\n' + err.stack);
});

server.on('message', function(msg, rinfo) {
  console.log('Server got UDP packet: ' + msg + ' from ' + rinfo.address + ':' + rinfo.port + '');
  doBusinessLogic(msg);
});

server.on('listening', function() {
  var address = server.address();
  console.log('Server listening for UDP ' + address.address + ':' + address.port + '');
});

function main() {
  server.bind(17270);
}
main();

当我使用 netcat 从本地计算机发送 UDP 数据包时,

echo -n "udp content" | nc -vv4u -w1 ec2.instance 17270

我没有看到服务器发生任何事情。

我可以在本地 运行 我的 node.js 服务器,它响应发送到 127.0.0.1 的 UDP 数据包。 我还可以通过 ssh 进入 ec2 实例,并将 netcat UDP 数据包发送到 127.0.0.1。这也会产生预期的响应。

所以我认为问题一定是网络问题。

当我在 ec2 实例上 运行 netstat 时,我可以看到该节点正在侦听端口 17270。

# netstat -plun
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name
udp        0      0 0.0.0.0:17270               0.0.0.0:*                               21308/node

我认为这可能是 AWS 安全设置,但是当我 运行 在 ec2 实例上进行 tcpdump 然后从我的本地计算机触发 netcat 时,我可以看到 ec2 实例上正在接收流量。

# tcpdump -vv -i any udp
15:09:52.276786 IP (tos 0x8, ttl 38, id 1756, offset 0, flags [none], proto UDP (17), length 29)
    my.local.machine.60924 > ec2.instance.17270: [udp sum ok] UDP, length 1
15:09:52.276852 IP (tos 0x8, ttl 38, id 48463, offset 0, flags [none], proto UDP (17), length 29)
    my.local.machine.60924 > ec2.instance.17270: [udp sum ok] UDP, length 1
15:09:52.276863 IP (tos 0x8, ttl 38, id 31296, offset 0, flags [none], proto UDP (17), length 29)
    my.local.machine.60924 > ec2.instance.17270: [udp sum ok] UDP, length 1
15:09:52.278461 IP (tos 0x8, ttl 38, id 50202, offset 0, flags [none], proto UDP (17), length 29)
    my.local.machine.60924 > ec2.instance.17270: [udp sum ok] UDP, length 1
15:09:52.289575 IP (tos 0x8, ttl 38, id 49316, offset 0, flags [none], proto UDP (17), length 149)
    my.local.machine.60924 > ec2.instance.17270: [udp sum ok] UDP, length 121

为了保险起见,我尝试在 AWS 控制台中暂时关闭端口 17270。如果我这样做,那些数据包将被丢弃,我将看不到来自 tcpdump 的任何信息。所以我重新打开了端口。

我有一个正在侦听端口的进程。我显然正在向该端口发送 UDP 数据包。但是进程收不到消息。

我就是想不通断线在哪里。我错过了什么?

提前感谢您的任何见解!

猜测可能是 iptables。数据包与 iptables 分开到达 BPF(tcpdump 使用它来查看传入流量),因此可以通过 tcpdump 查看它们,只是让 iptables 在它们离开内核并到达您的应用程序之前丢弃它们。在 'iptables -nvL' 的输出中查找相关输入链上的默认 drop/reject 策略或专门丢弃 UDP 流量的规则。

至于在这种情况下如何修复它,这取决于您使用的是哪个发行版。在过去,您只需使用 iptables 命令,就像这样(但使用相关的链名称而不是 INPUT):

iptables -A INPUT -p udp --dport 17270 -j ACCEPT

...但是如果您使用 Ubuntu 他们希望您使用他们的 ufw 工具 这个,如果它是 CentOS/RHEL 7 你可能会处理 firewalld 和它的 firewall-cmd 前端。