我正在运行一个 systemd-nspawn 容器(Debian 9,主机也是 Debian 9),VirtualEthernet=yes
并转发一些端口,例如Port=tcp:443:443
。即 Web 服务器在容器中运行,并且应该可以从外部访问。
当我激活ufw
防火墙时,事情似乎一开始工作正常,但几个小时后,外部可能无法连接到容器(分别是 Web 服务器)。当我这样做时ufw disable
,几秒钟后事情又恢复正常了。即一切都很好,但我没有防火墙。
答案1
手头上的问题
您有一个systemd-nspawn
运行正在端口转发的 Web 服务器的容器。一段时间后,它不再具有网络连接,直到您禁用ufw
.我做了一些研究,希望其中之一可以帮助解决您的问题。
可能的解决方案
我根据您在评论中的反馈做了更多研究。我知道您说桥接接口似乎是非标准的,但是我读过的关于构建systemd-nspawn
容器的每本指南都涉及设置桥接虚拟接口。
#1 验证 Systemd 的网络是否正确
跟随本指南,我注意到他们提到要特别注意网络。由于systemd-nspawn
容器依赖于systemd
您需要验证您的主机和容器是否使用正确的网络。
在您的主机上以 root (sudo) 身份运行以下命令:
systemctl disable network systemctl disable networking systemctl disable NetworkManager systemctl enable systemd-networkd
确认您的服务器现在正在用于systemd-networkd
网络:
networkctl status lo ● 1: lo Link File: /lib/systemd/network/99-default.link Network File: n/a Type: loopback State: carrier (unmanaged) Address: 127.0.0.1 ::1
请注意,您的网络应与 相关联/lib/systemd/network/99-default.link
或与之相关,以确认您正在使用systemd-networkd
.
从这里我们创建我们的网络接口。确保正确使用您的设备名称。
cat > /etc/systemd/network/[nameOfNetworkDevice].network <<EOF [Match] Name=[nameOfNetworkDevice] [Network] Bridge=br0 IPForward=1 EOF
创建桥接接口以匹配之前使用的接口,即br0
cat > /etc/systemd/network/br0.netdev <<EOF [NetDev] Name=br0 Kind=bridge EOF
现在为桥接接口创建网络。
cat > /etc/systemd/network/br0.network <<EOF [Match] Name=br0 [Network] DHCP=ipv4 EOF
现在重新启动网络并移动任何 sysV init 配置以避免冲突。
systemctl restart systemd-networkd mv /etc/network/interfaces /etc/network/interfaces.bak
启动systemd-resolved
服务。
systemctl enable systemd-resolved systemctl start systemd-resolved ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
接下来,测试您的网络连接和解析服务。最简单的是使用ping stackexchange.com
.现在一切都应该恢复正常了。
最后,您要确保容器在启动时启动。
systemctl enable machines.target
在这之后导游继续描述构建我不会进入的容器。
现在您不需要执行所有这些操作,但请记住,您的问题可能是由于主机上的网络配置设置方式之间的冲突引起的。这些步骤应该允许您的主机具有网络连接并将其桥接到您的容器,而不会发生冲突。
#2 你的容器正在破裂
我发现了几个问题(1,2,3[) 在 GitHub 上提出,涉及容器间歇性丢失网络连接。
因此,请检查这些休息是否适用于您:
Debian 下被破坏的东西
域名系统
/etc/init.d/dnsmasq
脚本总是将自己的选项注入 dnsmasq 命令行并会破坏配置systemd 禁用了 IPTables 集成(错误#787480)
这意味着端口转发选项下的这个不错的选项
IPMasquerade=yes
不起作用,您必须使用旧的 iptables 规则,例如启用 NAT 和进行端口转发。systemd-networkd
ort=tcp:80:80
iptables -t nat -A POSTROUTING -s 172.23.0.0/24 -j MASQUERADE
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 80 -m addrtype --dst-type LOCAL -j DNAT --to-destination 172.23.0.2:80
如果您完全掌握了 Debian 的最新版本,您应该避免其中的一些情况,只需检查您的dns
解决方案是否被覆盖即可。
确保您的 iptables 没有被刷新。该用户使用的apf
策略是清除 iptables 以生成新的 iptables。您正在使用ufw
,但这仍然是值得留意的可能性。当你失去网络时,容器是否不再有 iptables 规则?
这又与 docker 有关,但systemd-nspawn
可能具有相同的限制。检查联机帮助页查看您启动端口转发的方式是否有问题。可能与您在一段时间后失去连接的原因相关的是您的防火墙规则或端口转发等具有某种速率限制或连接限制。
#3 您的主机是笔记本电脑还是 VPS?
根据这个堆栈溢出帖子用户 Maduraiveeran 正在使用 VPS,由于某种原因,该 VPS 会运行一个自动化进程,导致 iptables 混乱。如果您的主机位于 VPS 上,则可能会遇到相同的问题。
如果您使用笔记本电脑,根据dhcp
其他网络设备的配置方式,当您在 wifi 和以太网之间或从一个无线接入点切换到另一个无线接入点时,您可能会丢失连接或重命名设备。您的网络可能有某种会导致问题的节能计划。
其他注意事项
我包括第一个博客的链接我找到了有关nspawn
容器的信息,向您展示如何从头开始构建容器。
不过,我还找到了一个用于主机端口转发的 iptables 脚本在同一网站上。如果#1 没有帮助,那可能会有所帮助。
结论
归根结底,我不是容器方面的专家,但我希望我为您指明了正确的方向。首先对容器如何获取其网络配置进行故障排除。然后检查您是否ufw
支持此配置(端口转发、容器虚拟接口等)。之后,我将确保您的容器构建正确(它可以在没有端口转发的情况下联网吗?其他服务是否可以工作,例如ssh
?)。可能使用预构建的 Web 服务器解决方案(该解决方案已经具有您想要的特性集和功能)可能是更好的选择。不要敲门尝试LXC
或docker
或rancher
或sandstorm
。systemd-nspawn
今天之前我还没有听说过太多关于容器的事情。您可能需要采用更受支持或至少采用的解决方案来获得支持。
我包括一个链接到 nspawn 的联机帮助页以获取更多参考。
如果您对此答案有任何疑问或疑问,请发表评论。我强烈建议您在尝试命令之前仔细阅读我提供的每个链接。我感谢您提供反馈来纠正任何误解并改进我的帖子。我可以根据需要更新我的答案。
祝你好运!
答案2
快速修复此问题
因为这实际上是一个路由规则
我们要做的就是让ufw允许所有转发
解决方案一:允许所有转发
编辑此文件 /etc/default/ufw 并将其从 DROP 更改为 ACCEPT
DEFAULT_FORWARD_POLICY="DROP"
<--to-->
DEFAULT_FORWARD_POLICY="ACCEPT"
然后ufw将允许转发
解决方案二:
如果您只想路由特定接口,而不是让 ufw 允许转发所有接口,您可以手动添加接受规则
例如我主机上的Vnet接口是ve-tsingkwai,主网络接口是enp5s0
我要做的是
$ tsingkwai@mylaptoplol Sat Jul 16 [16|09] at ~ ->
>>> ufw route allow in on enp5s0 out on ve-tsingkwai