中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

快杰云主機 SSH 登錄緩慢的排查和解決

發布時間:2020-07-21 19:46:02 來源:網絡 閱讀:296 作者:UCloud_TShare 欄目:云計算

快杰云主機是 UCloud 推出的具備優秀性能與極高性價比的新一代主機,網絡最高可達 1000 萬 PPS,存儲最高可達 120 萬 IOPS。為了提升產品綜合表現,Host 內核、KVM 和 Guest 內核等做了大量調優。“高內核 Ubuntu18.04” 鏡像就是其中一款經優化的云主機鏡像,集成了官方 linux 5.0.1 主線版本內核。

今年 7 月,有一位用戶反饋,使用該鏡像創建出的快杰云主機每次啟動時,第一次 SSH 登錄會很慢,有時候需幾十秒甚至幾分鐘才能登錄成功,影響了使用體驗。

經過排查,定位到是 Linux 內核隨機數熵池初始化慢的原因,且在多個條件組合下才會觸發。更深入調查則發現因為內核 bug,凡使用了 libssl 1.1.1 的進程(如開啟了 https 的 nginx)都有類似問題,會對系統安全產生不少潛在影響。

最終我們通過升級自主維護的內核,很快妥善修復了該問題,保證了快杰云主機的體驗和安全性。

快杰云主機 SSH 登錄緩慢的排查和解決cdn.xitu.io/2019/11/21/16e8d0e0b784bc28?w=640&h=374&f=jpeg&s=19194">

本文對排查過程加以梳理。

初步排查

該問題只在單個用戶上出現過,且只影響啟動后的首次 SSH 登錄,一旦登錄成功便恢復正常。現場捕獲不易,不過我們設法將其復現。
ssh -v

打開 ssh 用戶端的冗余日志模式嘗試登錄問題主機,發現總是會卡在 “debug1: pledge: network” 處,根據提示,sshd 已經完成了用戶的身份認證過程。

快杰云主機 SSH 登錄緩慢的排查和解決

可以看出,問題應當是發生在身份鑒定剛完成后,由此判斷,問題有較大可能是發生在 /etc/pam.d/sshd 定義的 PAM 過程中。

motd

檢視 /etc/pam.d/sshd 文件,根據現象以及直覺,決定嘗試先屏蔽幾段配置,其中就包括 motd 行,motd (message of the day) 是 Ubuntu 登錄后呈現給用戶看到的部分 banner 內容。隨后重啟主機,發現 ssh 登錄變快,不再卡住。

快杰云主機 SSH 登錄緩慢的排查和解決

查閱資料可知,motd 機制下,pam_motd.so 會依次執行 /etc/update-motd.d/ 目錄下的全部腳本,而這些腳本的輸出則會被拼湊輸出到文件 /run/motd.dynamic 中,最終呈現在 banner 中。

快杰云主機 SSH 登錄緩慢的排查和解決

因此,懷疑是這些腳本的執行過程中產生的卡頓,閱讀這些腳本,執行斷點 echo 調試,最后發現,位于”50-landscape-sysinfo”腳本中的 “/usr/bin/landscape-sysinfo” 命令執行時就會造成卡頓。

快杰云主機 SSH 登錄緩慢的排查和解決

landscape-sysinfo

該命令僅僅是一個用來搜集顯示 banner 中系統資源使用情況的工具,出現此問題有點難以置信,可實際上登錄進入后多次執行此命令也沒有出現卡頓。

快杰云主機 SSH 登錄緩慢的排查和解決

嘗試進一步追蹤此命令的執行,使用 strace 追蹤此命令的執行,并記錄日志。

快杰云主機 SSH 登錄緩慢的排查和解決

分析日志可以發現,啟動時,該命令被卡在了 getrandom 系統調用上,解除阻塞時間點為 23:10:48。

快杰云主機 SSH 登錄緩慢的排查和解決

getrandom

點擊查看參考資料 http://man7.org/linux/man-pages/man2/getrandom.2.html

getrandom 封裝了對 /dev/urandom 字符設備文件的讀取操作,用于獲取高質量的隨機數,/dev/urandom 會以 /dev/random 的值做為 seed 參考,/dev/random 值則來自硬件運行的噪音 (隨機質量很高)。這種機制也決定了 /dev/urandom 在操作系統剛啟動時生成的隨機數質量不高(剛啟動,/dev/random 中噪音不足,生成慢,隨機性差,容易被預測,間接導致了 /dev/urandom 的起始 seed 質量低下),所以 /dev/urandom 內部對其質量設置了三種狀態:

0 = 未初始化,但是 /dev/urandom 已經可用;
1 = 快速初始化,使用了少量熵數進行了快速初始化,在剛啟動時就盡快可以被用起來,質量還行,但是仍然不被建議用于加密場景,通常發生在操作系統啟動后的幾秒內;
2 = 完全初始化,隨機數的質量達到最高,可以用于加密場景,操作系統啟動后約幾十秒 – 幾分鐘的時間才能達到。
在默認情況下,getrandom 讀取 /dev/urandom 前會去檢測 /dev/urandom 的質量狀態,如果尚未完全初始化,則會阻塞,直到其完全初始化,以此來保障通過此接口獲得到的隨機數質量高且速度快,為安全領域提供可靠的依賴。

了解了 getrandom 接口的作用和表現后,再去翻看內核的啟動日志,找到了時間相關性極高的點。

快杰云主機 SSH 登錄緩慢的排查和解決

可以看到,23:10:48 時 /dev/urandom 完全初始化后,隨即 getrandom 的調用阻塞也被解除了,再多次重復驗證后,關聯性被確認。此時的結論以及建議解決辦法為:原因:操作系統初始化隨機數熵池速度較慢,導致 ssh 登錄時使用到隨機數的一條命令時被阻塞。
建議:禁用 motd 或者刪除 landscape-sysinfo 來達到加速 ssh 登錄的目的。

深入調查

初步調查的結論有點違反常理,禁用或者刪除的措施也需謹慎。為此,我決定找出更多的證據,此外,也需要解釋為什么舊版本的 Ubuntu 并沒有此現象。

嘗試查看表現正常的主機上 landscape-sysinfo 的 strace 表現,查閱日志后注意到,此環境下的 strace 記錄與問題主機中 strace 記錄在調用模式上存在不同,表現正常的主機上 landscape-sysinfo 中沒有這樣的調用 “getrandom (“xxx”, 32, 0) ”,注意第三個 flag 參數值,此 flag 用于表明使用 getrandom 的默認行為,即 /dev/urandom 未完全初始化時則阻塞。所有 getrandom 的地方都使用了 flag GRND_NONBLOCK,即如果沒有初始化完成不要阻塞,返回錯誤就好。
至此,懷疑是 landscape-sysinfo 版本問題。

landscape-sysinfo

對比兩臺主機上的 landscape-sysinfo 版本,發現版本號確實不同,有問題的版本號較高,沒問題的版本號較低。

快杰云主機 SSH 登錄緩慢的排查和解決

將沒問題的主機執行 apt-get update & apt-get upgrade,升級后發現問題果然重現。得出臨時結論:landscape-sysinfo 新版本使用了 getrandom 的阻塞模式獲取隨機數,不要升級 landscape-sysinfo 的版本即可。
開始嘗試在其它主機上進行復現和驗證,卻發現,在另一個高內核版本的鏡像中,低版本的 landscape-sysinfo 也能復現此問題,strace 追蹤調用,發現其調用行為與高版本的 landscape-sysinfo 表現相似,鑒于此命令實際上是 python3 腳本,懷疑是其依賴的庫升級導致。檢查 apt-get upgrade 升級的 package,找出與隨機數關聯度較大的幾個包,幾次排除嘗試后,定位發現,其實是由于 libssl1.1 這個庫的升級導致的問題,getrandom 的調用也是源自于 libssl1.1。

快杰云主機 SSH 登錄緩慢的排查和解決

libssl1.1

翻閱

libssl1.1 的 release note https://www.openssl.org/news/openssl-1.1.1-notes.html

快杰云主機 SSH 登錄緩慢的排查和解決

可以看到,的確,libssl1.1.1 的升級,重寫了內部隨機數的生成器,也符合前面的表現,更新為使用 getrandom 讀取更加安全的隨機數(代價是剛開機時使用就容易被阻塞)。
繼續嘗試在其它主機上進行復現和驗證,又發現,在某個低內核版本的 Ubuntu 主機上,安裝的正是 libssl1.1.1,卻不能復現問題。按照預期,libssl1.1.1 的升級就是為了更安全,而如果一開機就能立刻得到隨機數,這根本就違背的 getrandom 接口的設計初衷,此時傾向于懷疑內核可能存在 bug。

內核 bug

以 libssl 調用 getrandom 被阻塞為關鍵主題查閱資料,最終找到相關性較強的資料

點擊查看相關資料 https://unix.stackexchange.com/questions/442698/when-i-log-in-it-hangs-until-crng-init-done

,其中 CRNG 指密碼學強度的隨機數發生器。
根據此資料,證實了內核 bug 的猜測,內核在 4.16 時修正過這樣一個 bug:getrandom 在快速初始化完成后就不再阻塞,這與 getrandom 的接口設計違背,容易造成安全問題(CVE-2018-1108)

內核 bug fix commit https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=43838a23a05fbd13e47d750d3dfd77001536dd33

快杰云主機 SSH 登錄緩慢的排查和解決

驗證主機的內核版本為 4.15.0,與此情況符合,即很有可能是 bug 沒有被修復,此時,開始嘗試升級低內核版本主機的內核版本,如果此猜測正確,那么升級到高版本后應當同樣會發生卡頓問題。
在 apt 源上挑選了一個 5.0 版本的內核,升級后發現,居然也沒有問題。
翻閱內核日志,發現了一個新的現象,此前看到對于 /dev/urandom 的初始化,一般是會有一條 “fast init done” 日志,較長時間后會跟隨一個 “crng init done” 日志,正好對應著 /dev/urandom 的兩種質量狀態。

快杰云主機 SSH 登錄緩慢的排查和解決

而此內核版本下,則是在剛啟動就立即出現了 “crng done (trusting CPU’s manufacturer) ” 的日志,明顯表明熵池被極速的初始化了,自然不會出現卡頓問題。

快杰云主機 SSH 登錄緩慢的排查和解決

查詢此現象相關資料,找到了一個內核編譯選項:CONFIG_RANDOM_TRUST_CPU。

CONFIG_RANDOM_TRUST_CPU

點此查看詳細選項說明 https://lwn.net/Articles/760121/

快杰云主機 SSH 登錄緩慢的排查和解決

首次出現于 4.19 版本:https://cateee.net/lkddb/web-lkddb/RANDOM_TRUST_CPU.html

檢查高版本內核的兩臺主機,的確,有問題的主機此 flag 并沒有 enable,無問題的主機此 flag 顯式的 enable 了。

快杰云主機 SSH 登錄緩慢的排查和解決

而有問題主機使用的內核版本,取自于 Ubuntu 官方的最新主線分支編譯,默認沒有啟動此 flag 做優化。

結論

此問題的出現需要同時滿足以下幾個條件:1. linux 內核版本在 4.17 及以上 2. linux 內核編譯選項 CONFIG_RANDOM_TRUST_CPU is not set,或者 CPU 非 IVB 及以上的 x863. linux 內核 bug 未被社區 revert(4.x 的最新社區版本幾乎都被 revert,5.x 沒有 https://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg1602769.html)

)4. libssl 版本在 1.1.1 及以上

影響面

事實上,SSH 登錄卡頓僅僅是一種表象,這個問題的真實影響范圍,可以擴展得非常大。凡是使用了 libssl1.1.1 來生成隨機數的進程全都會受影響,導致重啟后 3-5 分鐘內會被隨機數 block。比如,服務器上跑著 nginx(開啟 https),一般認為機器啟動后,nginx 馬上啟動就能提供服務了,但是受此問題影響,nginx 會被卡住三五分鐘。就是說,前三五分鐘內的用戶 https 請求全部會出現訪問失敗的現象。

問題修復

為了做到性能與安全兼顧,在編譯 4.19 及更高版本的內核時,啟用 CONFIG_RANDOM_TRUST_CPU 選項,我們采用此方法,enable 選項并確保虛擬機可以訪問 RDRAND 指令集,很快重新發布了云主機鏡像。如果用戶使用自定義內核,應盡量避開 4.17-4.19 之間的版本,或者妥善處理好 CVE-2018-1108。

總結

提起云主機,首先會想到計算、存儲、網絡,甚少有人關注內核。然而,內核構建也是云主機的核心工作,對性能和穩定性至關重要。

SSH 登錄緩慢起初是單一用戶的反饋,且限于 Ubuntu 啟動后的首次登錄,但通過堅持排查和順藤摸瓜,我們發現了潛在的影響面并予以修復,防患于未然。
UCloud 團隊通過自主維護云主機的內核源碼,一方面可以不斷調優性能來匹配產品的發展;另一方面保證了遇到現網各種問題時,有能力迅速排查和解決,并及時預防更大的系統安全風險。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

乌恰县| 儋州市| 会宁县| 紫阳县| 江川县| 大方县| 金阳县| 松滋市| 赤峰市| 广南县| 丰城市| 阿荣旗| 益阳市| 吉林省| 枣庄市| 酒泉市| 杂多县| 福鼎市| 吉木萨尔县| 水富县| 长海县| 惠安县| 万盛区| 安康市| 贺兰县| 区。| 仲巴县| 延边| 宣威市| 广南县| 永德县| 武鸣县| 鲁山县| 嘉荫县| 富裕县| 平安县| 石渠县| 运城市| 邵阳县| 新巴尔虎右旗| 科技|