多播数据包未正确到达 podman 内部。找到解决方法,但不清楚是 firewalld 问题还是 podman 问题?
Multicast packet not arrived inside podman correctly. Workaround found, but unclear if it is a firewalld issue or a podman issue?
我对 firewalld、podman 和 UDP/Multicast 越来越着迷。当我看到 UDP 数据包到达 podman 时;使用 tcpdump
命令确认。似乎我无法使用名称为 knx_multicast
的自定义 firewalld 区域进行配置,只有当 UDP 数据包来自多播组 224.0.23.12:3671
.
时才应该接受
给出最小的例子,写在Java:
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
public class Test {
public static void main(String[] args) throws Throwable {
final var group = InetAddress.getByName("224.0.23.12");
final var s = new MulticastSocket(3671);
final var ni = NetworkInterface.getByName("enp1s0");
s.setNetworkInterface(ni);
s.joinGroup(group);
System.out.println("Start listening ... @" + ni );
final var buf = new byte[1000];
DatagramPacket recv = new DatagramPacket(buf, buf.length);
s.receive(recv);
System.out.println(recv.getData());
s.leaveGroup(group);
s.close();
}
}
我将 firewalld 配置为:
knx_multicast (active)
target: default
icmp-block-inversion: no
interfaces:
sources: 224.0.23.12
services:
ports: 3671/udp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
public (active)
target: default
icmp-block-inversion: no
interfaces: enp1s0
sources:
services: cockpit dhcpv6-client ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
在 CentOS 8.1 上测试多播数据包
现在我首先在 CentOS 8.1 运行 中进行了测试,当我获得一些数据时它可以正常工作(请参阅下面的 [B@61a52fbd
)
[root@PIT-Server ~]# javac Test.java && java Test
Start listening ... @name:enp1s0 (enp1s0)
[B@61a52fbd
在 CentOS 8.1 上使用 PODMAN 测试多播数据包
下一步是在 podman 容器中进行测试(图像:'adoptopenjdk/openjdk11:latest',即 "Ubuntu 18.04.3 LTS" 上的 运行),使用:podman run --rm -it --net host docker.io/adoptopenjdk/openjdk11 /bin/bash
在 podman 中,我还看到了来自 PIT-KNX(KNX 路由器)的 UDP 数据包。
root@PIT-Server:/tcpdump -i enp1s0 udp port 3671
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp1s0, link-type EN10MB (Ethernet), capture size 262144 bytes
19:49:35.583901 IP PIT-KNX.pit-router.3671 > 224.0.23.12.3671: UDP, length 17
19:49:36.032139 IP PIT-KNX.pit-router.3671 > 224.0.23.12.3671: UDP, length 18
... lines omitted ...
启动同一个 java 应用程序(在容器环境之外工作)我无法获取任何数据(在 "Start listening" 之后没有字节数组到达)
root@PIT-Server:/# javac Test.java && java Test
Start listening ... @name:enp1s0 (enp1s0)
解决方法(防火墙)
在调查了几个 hours/coffees 之后,我发现在 zone=knx_multicast 中允许端口是不够的。我也必须将端口添加到 zone=public
,使用:firewall-cmd --add-port=3671/udp
。 firewalld 的配置现在是:
knx_multicast (active)
target: default
icmp-block-inversion: no
interfaces:
sources: 224.0.23.12
services:
ports: 3671/udp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
public (active)
target: default
icmp-block-inversion: no
interfaces: enp1s0
sources:
services: cockpit dhcpv6-client ssh
ports: 3671/udp <== ADDED!!!! (that one fixes the problem)
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
在 CentOS 8.1 上使用 PODMAN 重新测试多播数据包
通过重新运行 java 应用程序,我现在能够看到到达的 UDP 多播数据包(参见:下面的 [B@61a52fbd
)
root@PIT-Server:/# javac Test.java && java Test
Start listening ... @name:enp1s0 (enp1s0)
[B@61a52fbd
我的问题...发生了什么事?后续步骤?
任何人都可以帮助我了解问题到底是什么吗?为什么我也必须将端口添加到 zone=public
?这是我这边的错误还是配置问题?如何在不将端口添加到 zone=public
的情况下解决它?我有什么误解吗?
如果只添加一个新的 firewalld 区域(称为 knx_multicast
),我会更舒服;并保持 firewalld public
区域的配置不变。建议?
谢谢你,克里斯托夫
感谢@Ron Maupin 指出问题。我的防火墙配置错误。
问题已通过创建新服务得到解决:
firewall-cmd --permanent --new-service=knx
firewall-cmd --permanent --service=knx --set-description="KNXnet/IP is a part of KNX standard for transmission of KNX telegrams via Ethernet"
firewall-cmd --permanent --service=knx --set-short=KNX
firewall-cmd --permanent --service=knx --add-port=3671/udp
为了能够添加新创建的服务,重新加载 firewalld 并添加它
firewall-cmd --reload
firewall-cmd --permanent --add-service=knx
这将创建一个服务文件:/etc/firewalld/services/knx.xml
,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>KNX</short>
<description>KNXnet/IP is a part of KNX standard for transmission of KNX telegrams via Ethernet</description>
<port port="3671" protocol="udp"/>
</service>
防火墙配置如下所示:
public (active)
target: default
icmp-block-inversion: no
interfaces: enp1s0
sources:
services: cockpit dhcpv6-client knx ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
我对 firewalld、podman 和 UDP/Multicast 越来越着迷。当我看到 UDP 数据包到达 podman 时;使用 tcpdump
命令确认。似乎我无法使用名称为 knx_multicast
的自定义 firewalld 区域进行配置,只有当 UDP 数据包来自多播组 224.0.23.12:3671
.
给出最小的例子,写在Java:
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
public class Test {
public static void main(String[] args) throws Throwable {
final var group = InetAddress.getByName("224.0.23.12");
final var s = new MulticastSocket(3671);
final var ni = NetworkInterface.getByName("enp1s0");
s.setNetworkInterface(ni);
s.joinGroup(group);
System.out.println("Start listening ... @" + ni );
final var buf = new byte[1000];
DatagramPacket recv = new DatagramPacket(buf, buf.length);
s.receive(recv);
System.out.println(recv.getData());
s.leaveGroup(group);
s.close();
}
}
我将 firewalld 配置为:
knx_multicast (active)
target: default
icmp-block-inversion: no
interfaces:
sources: 224.0.23.12
services:
ports: 3671/udp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
public (active)
target: default
icmp-block-inversion: no
interfaces: enp1s0
sources:
services: cockpit dhcpv6-client ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
在 CentOS 8.1 上测试多播数据包
现在我首先在 CentOS 8.1 运行 中进行了测试,当我获得一些数据时它可以正常工作(请参阅下面的 [B@61a52fbd
)
[root@PIT-Server ~]# javac Test.java && java Test
Start listening ... @name:enp1s0 (enp1s0)
[B@61a52fbd
在 CentOS 8.1 上使用 PODMAN 测试多播数据包
下一步是在 podman 容器中进行测试(图像:'adoptopenjdk/openjdk11:latest',即 "Ubuntu 18.04.3 LTS" 上的 运行),使用:podman run --rm -it --net host docker.io/adoptopenjdk/openjdk11 /bin/bash
在 podman 中,我还看到了来自 PIT-KNX(KNX 路由器)的 UDP 数据包。
root@PIT-Server:/tcpdump -i enp1s0 udp port 3671
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp1s0, link-type EN10MB (Ethernet), capture size 262144 bytes
19:49:35.583901 IP PIT-KNX.pit-router.3671 > 224.0.23.12.3671: UDP, length 17
19:49:36.032139 IP PIT-KNX.pit-router.3671 > 224.0.23.12.3671: UDP, length 18
... lines omitted ...
启动同一个 java 应用程序(在容器环境之外工作)我无法获取任何数据(在 "Start listening" 之后没有字节数组到达)
root@PIT-Server:/# javac Test.java && java Test
Start listening ... @name:enp1s0 (enp1s0)
解决方法(防火墙)
在调查了几个 hours/coffees 之后,我发现在 zone=knx_multicast 中允许端口是不够的。我也必须将端口添加到 zone=public
,使用:firewall-cmd --add-port=3671/udp
。 firewalld 的配置现在是:
knx_multicast (active)
target: default
icmp-block-inversion: no
interfaces:
sources: 224.0.23.12
services:
ports: 3671/udp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
public (active)
target: default
icmp-block-inversion: no
interfaces: enp1s0
sources:
services: cockpit dhcpv6-client ssh
ports: 3671/udp <== ADDED!!!! (that one fixes the problem)
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
在 CentOS 8.1 上使用 PODMAN 重新测试多播数据包
通过重新运行 java 应用程序,我现在能够看到到达的 UDP 多播数据包(参见:下面的 [B@61a52fbd
)
root@PIT-Server:/# javac Test.java && java Test
Start listening ... @name:enp1s0 (enp1s0)
[B@61a52fbd
我的问题...发生了什么事?后续步骤?
任何人都可以帮助我了解问题到底是什么吗?为什么我也必须将端口添加到 zone=public
?这是我这边的错误还是配置问题?如何在不将端口添加到 zone=public
的情况下解决它?我有什么误解吗?
如果只添加一个新的 firewalld 区域(称为 knx_multicast
),我会更舒服;并保持 firewalld public
区域的配置不变。建议?
谢谢你,克里斯托夫
感谢@Ron Maupin 指出问题。我的防火墙配置错误。
问题已通过创建新服务得到解决:
firewall-cmd --permanent --new-service=knx
firewall-cmd --permanent --service=knx --set-description="KNXnet/IP is a part of KNX standard for transmission of KNX telegrams via Ethernet"
firewall-cmd --permanent --service=knx --set-short=KNX
firewall-cmd --permanent --service=knx --add-port=3671/udp
为了能够添加新创建的服务,重新加载 firewalld 并添加它
firewall-cmd --reload
firewall-cmd --permanent --add-service=knx
这将创建一个服务文件:/etc/firewalld/services/knx.xml
,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>KNX</short>
<description>KNXnet/IP is a part of KNX standard for transmission of KNX telegrams via Ethernet</description>
<port port="3671" protocol="udp"/>
</service>
防火墙配置如下所示:
public (active)
target: default
icmp-block-inversion: no
interfaces: enp1s0
sources:
services: cockpit dhcpv6-client knx ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules: