我有一台从 Ubuntu 16.04 开始运行的服务器。我想让它更新到最新版本,所以我从 16.04 升级到了 18.04(基本没有问题)我让它运行了一天,以确保一切按预期运行,然后我升级到了 20.04。但这次升级并不顺利。
我已经解决了升级过程中的大部分问题(内核恐慌、MySQL 5.7 与 mariadb 不兼容等),但有一件事我无法弄清楚,为什么我的 UFW 规则在安装 kubernetes(microk8s)时表现不同。
我有几个 pod 在 microk8s 中运行。这些 pod 在 16.04 和 18.04 下运行良好。但是一旦我升级到 20.04,它们就无法访问我的 DNS 服务器(即在同一主机上运行的 dnsmasq)
我已将 microk8s 配置为转发到 192.168.0.50(我的主机主本地 IP 地址)。在升级到 20.04 之前,这同样运行良好。我需要 pod 能够访问此本地 DNS 服务器,因为我的网络上有只有此 DNS 服务器知道的特定服务。我已禁用内置的 systemd-resolver 以支持 dnsmasq。
还要注意,由于我运行自己的 Web 服务器、邮件服务器等,所以 192.168.0.50 暴露在公共互联网中(我的路由器的 DMZ 指向 192.168.0.50)。所以我希望 DNS 暴露给任何内部接口和/或 IP,但我不希望它暴露给来自互联网的公共 IP。
如果我检查 netstat,它看起来好像 dnsmasq 正在监听所有正确的接口:
# netstat -lepn | grep ":53 " | grep -v tcp6 | grep -v udp6
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 0 10627970 3213753/dnsmasq
tcp 0 0 192.168.0.50:53 0.0.0.0:* LISTEN 0 10627968 3213753/dnsmasq
tcp 0 0 192.168.123.1:53 0.0.0.0:* LISTEN 0 10627966 3213753/dnsmasq
tcp 0 0 172.18.0.1:53 0.0.0.0:* LISTEN 0 10627964 3213753/dnsmasq
tcp 0 0 172.17.0.1:53 0.0.0.0:* LISTEN 0 10627962 3213753/dnsmasq
tcp 0 0 10.1.206.192:53 0.0.0.0:* LISTEN 0 10627960 3213753/dnsmasq
udp 0 0 127.0.0.1:53 0.0.0.0:* 0 10627969 3213753/dnsmasq
udp 0 0 192.168.0.50:53 0.0.0.0:* 0 10627967 3213753/dnsmasq
udp 0 0 192.168.123.1:53 0.0.0.0:* 0 10627965 3213753/dnsmasq
udp 0 0 172.18.0.1:53 0.0.0.0:* 0 10627963 3213753/dnsmasq
udp 0 0 172.17.0.1:53 0.0.0.0:* 0 10627961 3213753/dnsmasq
udp 0 0 10.1.206.192:53 0.0.0.0:* 0 10627959 3213753/dnsmasq
现在升级后,我发现 UFW 似乎阻止了来自 k8s 网络接口的 DNS 请求:
Apr 28 12:20:37 server kernel: [ 58.148877] [UFW BLOCK] IN=cali00ea8fe43e0 OUT=enp1s0f0 MAC=ee:ee:ee:ee:ee:ee:fa:cd:4a:b9:17:d8:08:00 SRC=10.1.206.231 DST=10.1.206.232 LEN=86 TOS=0x00 PREC=0x00 TTL=63 ID=20903 DF PROTO=UDP SPT=49282 DPT=53 LEN=66
Apr 28 12:20:37 server kernel: [ 58.148898] [UFW BLOCK] IN=cali00ea8fe43e0 OUT=enp1s0f0 MAC=ee:ee:ee:ee:ee:ee:fa:cd:4a:b9:17:d8:08:00 SRC=10.1.206.231 DST=10.1.206.232 LEN=86 TOS=0x00 PREC=0x00 TTL=63 ID=53947 DF PROTO=UDP SPT=45603 DPT=53 LEN=66
cali00ea8fe43e0
我的 k8s 集群的一个网络接口在哪里。
如果我查看 microk8s core-dns 日志,我会看到如下行:
[ERROR] plugin/errors: 2 8297669929822044709.913121715873788735. HINFO: read udp 10.1.206.203:45629->192.168.0.50:53: i/o timeout
所以在我看来,UFW 确实阻止了此流量。唯一的问题是我无法弄清楚它停止工作的确切原因。我有/etc/ufw/user.rules
文件的备份副本,升级似乎添加了以下几行:
### tuple ### allow any 30080 0.0.0.0/0 any 0.0.0.0/0 in
-A ufw-user-input -p tcp --dport 30080 -j ACCEPT
-A ufw-user-input -p udp --dport 30080 -j ACCEPT
### tuple ### allow any any 0.0.0.0/0 any 0.0.0.0/0 in_vxlan.calico
-A ufw-user-input -i vxlan.calico -j ACCEPT
### tuple ### allow any any 0.0.0.0/0 any 0.0.0.0/0 out_vxlan.calico
-A ufw-user-output -o vxlan.calico -j ACCEPT
### tuple ### allow any any 0.0.0.0/0 any 0.0.0.0/0 in_cali+
-A ufw-user-input -i cali+ -j ACCEPT
### tuple ### allow any any 0.0.0.0/0 any 0.0.0.0/0 out_cali+
-A ufw-user-output -o cali+ -j ACCEPT
我没有手动添加这些,它们是在升级过程中自动添加的。也许通过迁移到较新版本的 microk8s?这些新规则都以某种方式与我的 k8s 集群相关联。
这些行显示ufw status numbered
如下:
# ufw status numbered
WARN: Duplicate profile 'Dovecot IMAP', using last found
WARN: Duplicate profile 'Dovecot Secure IMAP', using last found
WARN: Duplicate profile 'Dovecot POP3', using last found
WARN: Duplicate profile 'Dovecot Secure POP3', using last found
Status: active
To Action From
-- ------ ----
[ 1] 22 ALLOW IN Anywhere
[ 2] 80 ALLOW IN Anywhere
[ 3] 6969 ALLOW IN Anywhere
[ 4] 9696 ALLOW IN Anywhere
[ 5] 110 ALLOW IN Anywhere
[ 6] 143 ALLOW IN Anywhere
[ 7] 25 ALLOW IN Anywhere
[ 8] 993 ALLOW IN Anywhere
[ 9] 995 ALLOW IN Anywhere
[10] 9300:9599/tcp ALLOW IN Anywhere
[11] Apache Full ALLOW IN Anywhere
[12] Anywhere ALLOW IN 192.168.0.0/16
[13] 192.168.1.255 53 ALLOW IN 192.168.1.0 53
[14] 127.0.1.1 53 ALLOW IN 127.0.0.1 53
[15] 30080 ALLOW IN Anywhere
[16] Anywhere on vxlan.calico ALLOW IN Anywhere
[17] Anywhere ALLOW OUT Anywhere on vxlan.calico (out)
[18] Anywhere on cali+ ALLOW IN Anywhere
[19] Anywhere ALLOW OUT Anywhere on cali+ (out)
我假设这里发生的事情是 microk8s 网络发生了一些根本性的变化。我不记得以前有所有这些“calico”和“cali+”接口。因此,microk8s 必须在升级期间添加一些防火墙规则,以允许 pod 获得出站 Internet 访问权限……但看起来规则可能不允许 pod 访问我的主机服务器上的“任何地方”。
IE:如果我没有看错的话:第 16 行允许任何发往“vxlan.calico 上的任何地方”的流量进入,第 17 行允许从 vxlan.calico 上的任何地方出站到“任何地方”
但是这两者似乎都不允许来自 vxlan.calico 的流量进入?(在我看来应该允许)。
我一直在尝试弄清楚如何修改该行以user.rules
允许来自 vxlan.calico 和 cali+ 接口的任何/所有流量,但我没有找到正确的语法来做到这一点。我想我可以允许来自 10.0.0.0/8 的所有流量,因为这似乎是所有这些接口使用的 CIDR,但我不确定这是否是“正确”的方法。
总结一下:
主要问题 #1:有没有办法允许流量从特定接口进入任何端口。例如:我想添加一行显示在 UFW 状态中的内容,例如:
To Action From
-- ------ ----
[20] Anywhere ALLOW **IN** Anywhere on vxlan.calico
基本与规则 17 相同,只是“行动”是允许进入而不是允许
主要问题 #2:我是否忽略了其他一些基本问题?似乎从 18.04 升级到 20.04 不应该造成这么大的麻烦。我是否错过了某个基本步骤?
编辑#1:所以也许根本就不是 UFW 的问题...我刚刚完全禁用了 UFW,但仍然看到此流量被阻止。这是在 microk8s 本身内阻止的吗?
我完全不知所措了。我错过了什么?
我检查了一下,我可以从我的 k8s pod 顺利连接到主机服务器 (192.168.0.50) 上的其他端口。只有对端口 53 的请求被挂断了。
例如:curl -v http://192.168.0.50
在其中一个 k8s pod 上运行就可以从我的 web 服务器正常返回内容。
所以我的下一个想法是,这也许是 UDP 特定的问题,但尝试使用 TCP 进行 DNS 也不起作用:
$ kubectl exec -i -t dnsutils -- dig cnn.com @192.168.0.50 +tcp
;; communications error to 192.168.0.50#53: connection reset
但是从主机使用 +tcp 的相同 dig 命令返回的结果与预期完全一致。
我还使用 tcpdump 进行了检查:tcpdump -i any -XX port 53
当我从其中一个 k8s pod 调用 dig 时,我在 tcpdump 输出中看到了请求,但没有响应:
14:55:09.849245 IP 10.1.206.251.53235 > 192.168.0.50.domain: 27889+ [1au] A? cnn.com. (36)
当我从本地网络上的另一台机器执行相同的 dig 命令时,我看到请求和响应:
14:56:45.430750 IP 192.168.0.233.36836 > 192.168.0.50.domain: 43090+ [1au] A? cnn.com. (48)
14:56:45.447998 IP 192.168.0.50.domain > 192.168.0.233.36836: 43090 4/0/1 A 151.101.131.5, A 151.101.195.5, A 151.101.3.5, A 151.101.67.5 (100)
因此,我启用了 dnsmasq 中的日志记录,当我从服务器本身或网络上的其他机器发出 dns 请求时,它会记录条目,但当我从 k8s pod 发出请求时,它根本不会记录任何内容。
因此,tcpdump
可以看到来自 k8s pod 的 DNS 请求数据包,但dnsmasq
似乎没有收到它?这怎么可能呢?
编辑添加:嗯,这可能是我需要的线索:
# grep "ignoring query from non-local network" /var/log/syslog
Apr 29 07:59:25 server dnsmasq[1540970]: ignoring query from non-local network 10.1.206.240
Apr 29 07:59:30 server dnsmasq[1541198]: ignoring query from non-local network 10.1.206.240
Apr 29 12:43:20 server dnsmasq[2803264]: ignoring query from non-local network 10.1.206.203 (logged only once)
Apr 29 13:56:41 server dnsmasq[3122204]: ignoring query from non-local network 10.1.206.240
Apr 29 14:04:56 server dnsmasq[3157857]: ignoring query from non-local network 10.1.206.203 (logged only once)
Apr 29 14:40:45 server dnsmasq[3313551]: ignoring query from non-local network 10.1.206.203 (logged only once)
Apr 29 14:51:24 server dnsmasq[3360405]: ignoring query from non-local network 10.1.206.251
Apr 29 14:52:09 server dnsmasq[3363587]: ignoring query from non-local network 10.1.206.251
Apr 29 15:47:35 server dnsmasq[3603248]: ignoring query from non-local network 10.1.206.203 (logged only once)
因为这些“仅记录一次”所以我没有看到它们......叹
答案1
回答我自己的问题:它与 UFW 或 microk8s 无关,而与升级到 20.04 添加新的默认标志有关/etc/init.d/dnsmasq
:
DNSMASQ_OPTS="$DNSMASQ_OPTS --local-service"
--local-service
从此文件中删除即可修复该问题。
我简直不敢相信我花了多少时间来追踪这个问题。我想知道这是否是一个错误,因为 10.0.0.0/8 CIDR 在技术上被视为私有/本地 IP 范围,因此我不确定 dnsmasq 如何/为何得出结论认为这些特定 IP 是“非本地的”,而实际上它们非常本地。