【问题标题】:Node.js server listening for UDP. Tcpdump says packets are coming through, but node doesn't get them侦听 UDP 的 Node.js 服务器。 Tcpdump 说数据包正在通过,但节点没有收到它们
【发布时间】:2016-09-24 15:06:11
【问题描述】:

与合作伙伴整合。我们的服务器有一个 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 数据包。但是进程没有收到消息。

我只是无法弄清楚断开连接的位置。我错过了什么?

提前感谢您的任何见解!

【问题讨论】:

  • 我仍然在努力解决这个问题——尝试将 node.js 进程直接绑定到 eth0 的 IP 地址。结果相同。还写了一个小 Python 脚本来监听 UDP 数据包,发现它的行为与节点相同——tcpdump 表示数据包正在通过,但进程没有得到它们。
  • 我可能应该把这个发布到 serverfault 而不是 stackoverflow。问一个系统管理员朋友我错过了什么。他提醒我,尽管 AWS 有自己的过滤器,但 iptables/netfilter 仍在混合中。 tcpdump 在 iptables 进行过滤之前拦截和记录日志。一些 iptables 更新和一切都很棒。

标签: node.js networking amazon-ec2 udp


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-02
    • 1970-01-01
    • 2018-09-30
    • 1970-01-01
    • 2014-08-22
    • 2021-07-03
    • 1970-01-01
    相关资源
    最近更新 更多