我有一個基於 Ubuntu 16.04 的 Docker 容器,它運行 ntpd 4.2.8 服務。容器實例化後,我發布了連接埠 123/udp。
從 LAN 上的主機或其他計算機,我可以用來ntpq -p <container_host>
取得對等點列表和同步狀態。但使用collectd監控它或運行ntpdc -c kerninfo <container_host>
失敗/超時。這讓我很困惑!
我已經在容器內測試了它,有一些合理的restrict
陳述,也沒有任何合理的陳述。但在這兩種情況下我都超時了。在容器中執行 tcpdump(將其提升到特權容器後)顯示 UDP 封包已到達,但沒有任何回應。當然,使用 tcpdump 在使用正在執行的 ntpq 時我會看到請求和回應。
如果我使用相同的 ntp.conf 檔案直接在主機上執行 ntpd 伺服器,則ntpdc -c kerninfo <container_host>
主機和我授權的 LAN 上的其他電腦上的 ntpd 和collectd 都會成功!但是,主機仍在執行舊版本的 Ubuntu (14.04),該版本附帶 ntp 4.2.6。
所以唯一的區別是 Docker 網路(據我所知是 NAT)和 ntp 版本(4.2.6 與 4.2.8)。但 ntp.org 文件並未提及任何有關 NAT 或 4.2.8 更新的內容。那麼我的命令超時是否只是因為客戶端與伺服器位於不同的子網路(由於 NAT)?或是 4.2.8 中發生了一些變化?
注意:我的容器映像是基於運行 ntpd 的 ubuntu:16.04[電子郵件受保護](來自 Ubuntu 官方儲存庫)。主機運行Ubuntu 14.04,運行4.2.6p5。
PS:即使所有的restrict語句都正確,Collectd提交的命令相當於ntpdc -c kerninfo <container_host>
ntpd在容器中運行時逾時。
更新:我忘了提及,我還在容器內運行了 ntpd,並-ddd
可以選擇獲得更詳細的輸出。記錄的唯一相關數據是:
read_network_packet: fd=19 length 192 from 192.168.1.3
receive: at 26 172.17.0.2<-192.168.1.3 flags 19 restrict 000
更新2:找到解決方案後,我更改了問題,希望其他遇到相同問題的人在搜尋時可以更好地找到問題/答案。我還修正了一個錯誤,我以為主機運行的是 Ubuntu 16.04,但實際上它仍在運行 14.04。
答案1
我解決了我的問題。此錯誤是由於 ntp 4.2.8 棄用(並預設為停用)該工具ntpdc
及其所使用的通訊模式(又稱 mode7)所致。
從ntp 4.2.8及更高版本開始,ntpq
應使用該工具取代ntpdc。它現在支援與 ntpdc 相同的命令。這樣我就可以ntpq -c kerninfo <container_host>
成功運行了。該ntpq
命令使用不同的模式(也稱為 mode6)進行通訊。
在 ntp 4.2.8 中,仍然可以重新啟用模式7,以支援與尚未遷移的工具的兼容性。必須在 中新增以下行/etc/ntp.conf
:
enable mode7
然而,人們應該非常小心這項限制。看來,啟用 mode7 並讓 ntpd 伺服器過於開放,可用於進行 DDoS 放大攻擊。我目前在 Ubuntu 上使用 IPv4 和 IPv6 的預設限制,即 -我認為- 阻止使用此模式:
restrict -4 default kod notrap nomodify nopeer noquery limited
restrict -6 default kod notrap nomodify nopeer noquery limited
由於collectd僅支援mode7(請參閱問題#932),我決定在容器內的配置中重新啟用此模式。只要 ntp 支援重新啟用此模式,此變更應該可以解決 Collectd 無法在 Ubuntu 16.04(或任何使用 ntp 4.2.8+ 的發行版)上監控 ntpd 的問題。
注意:為了讓人們在遇到此問題時更好地找到解決方案,我將編輯該問題,以減少對 NAT 的誤導,我認為這最初是根本原因。