您好,登錄后才能下訂單哦!
快杰云主機(jī)是 UCloud 推出的具備優(yōu)秀性能與極高性價(jià)比的新一代主機(jī),網(wǎng)絡(luò)最高可達(dá) 1000 萬(wàn) PPS,存儲(chǔ)最高可達(dá) 120 萬(wàn) IOPS。為了提升產(chǎn)品綜合表現(xiàn),Host 內(nèi)核、KVM 和 Guest 內(nèi)核等做了大量調(diào)優(yōu)?!案邇?nèi)核 Ubuntu18.04” 鏡像就是其中一款經(jīng)優(yōu)化的云主機(jī)鏡像,集成了官方 linux 5.0.1 主線版本內(nèi)核。
今年 7 月,有一位用戶反饋,使用該鏡像創(chuàng)建出的快杰云主機(jī)每次啟動(dòng)時(shí),第一次 SSH 登錄會(huì)很慢,有時(shí)候需幾十秒甚至幾分鐘才能登錄成功,影響了使用體驗(yàn)。
經(jīng)過(guò)排查,定位到是 Linux 內(nèi)核隨機(jī)數(shù)熵池初始化慢的原因,且在多個(gè)條件組合下才會(huì)觸發(fā)。更深入調(diào)查則發(fā)現(xiàn)因?yàn)閮?nèi)核 bug,凡使用了 libssl 1.1.1 的進(jìn)程(如開(kāi)啟了 https 的 nginx)都有類似問(wèn)題,會(huì)對(duì)系統(tǒng)安全產(chǎn)生不少潛在影響。
最終我們通過(guò)升級(jí)自主維護(hù)的內(nèi)核,很快妥善修復(fù)了該問(wèn)題,保證了快杰云主機(jī)的體驗(yàn)和安全性。
cdn.xitu.io/2019/11/21/16e8d0e0b784bc28?w=640&h=374&f=jpeg&s=19194">
本文對(duì)排查過(guò)程加以梳理。
初步排查
該問(wèn)題只在單個(gè)用戶上出現(xiàn)過(guò),且只影響啟動(dòng)后的首次 SSH 登錄,一旦登錄成功便恢復(fù)正?!,F(xiàn)場(chǎng)捕獲不易,不過(guò)我們?cè)O(shè)法將其復(fù)現(xiàn)。
ssh -v
打開(kāi) ssh 用戶端的冗余日志模式嘗試登錄問(wèn)題主機(jī),發(fā)現(xiàn)總是會(huì)卡在 “debug1: pledge: network” 處,根據(jù)提示,sshd 已經(jīng)完成了用戶的身份認(rèn)證過(guò)程。
可以看出,問(wèn)題應(yīng)當(dāng)是發(fā)生在身份鑒定剛完成后,由此判斷,問(wèn)題有較大可能是發(fā)生在 /etc/pam.d/sshd 定義的 PAM 過(guò)程中。
motd
檢視 /etc/pam.d/sshd 文件,根據(jù)現(xiàn)象以及直覺(jué),決定嘗試先屏蔽幾段配置,其中就包括 motd 行,motd (message of the day) 是 Ubuntu 登錄后呈現(xiàn)給用戶看到的部分 banner 內(nèi)容。隨后重啟主機(jī),發(fā)現(xiàn) ssh 登錄變快,不再卡住。
查閱資料可知,motd 機(jī)制下,pam_motd.so 會(huì)依次執(zhí)行 /etc/update-motd.d/ 目錄下的全部腳本,而這些腳本的輸出則會(huì)被拼湊輸出到文件 /run/motd.dynamic 中,最終呈現(xiàn)在 banner 中。
因此,懷疑是這些腳本的執(zhí)行過(guò)程中產(chǎn)生的卡頓,閱讀這些腳本,執(zhí)行斷點(diǎn) echo 調(diào)試,最后發(fā)現(xiàn),位于”50-landscape-sysinfo”腳本中的 “/usr/bin/landscape-sysinfo” 命令執(zhí)行時(shí)就會(huì)造成卡頓。
landscape-sysinfo
該命令僅僅是一個(gè)用來(lái)搜集顯示 banner 中系統(tǒng)資源使用情況的工具,出現(xiàn)此問(wèn)題有點(diǎn)難以置信,可實(shí)際上登錄進(jìn)入后多次執(zhí)行此命令也沒(méi)有出現(xiàn)卡頓。
嘗試進(jìn)一步追蹤此命令的執(zhí)行,使用 strace 追蹤此命令的執(zhí)行,并記錄日志。
分析日志可以發(fā)現(xiàn),啟動(dòng)時(shí),該命令被卡在了 getrandom 系統(tǒng)調(diào)用上,解除阻塞時(shí)間點(diǎn)為 23:10:48。
getrandom
點(diǎn)擊查看參考資料 http://man7.org/linux/man-pages/man2/getrandom.2.html
getrandom 封裝了對(duì) /dev/urandom 字符設(shè)備文件的讀取操作,用于獲取高質(zhì)量的隨機(jī)數(shù),/dev/urandom 會(huì)以 /dev/random 的值做為 seed 參考,/dev/random 值則來(lái)自硬件運(yùn)行的噪音 (隨機(jī)質(zhì)量很高)。這種機(jī)制也決定了 /dev/urandom 在操作系統(tǒng)剛啟動(dòng)時(shí)生成的隨機(jī)數(shù)質(zhì)量不高(剛啟動(dòng),/dev/random 中噪音不足,生成慢,隨機(jī)性差,容易被預(yù)測(cè),間接導(dǎo)致了 /dev/urandom 的起始 seed 質(zhì)量低下),所以 /dev/urandom 內(nèi)部對(duì)其質(zhì)量設(shè)置了三種狀態(tài):
0 = 未初始化,但是 /dev/urandom 已經(jīng)可用;
1 = 快速初始化,使用了少量熵?cái)?shù)進(jìn)行了快速初始化,在剛啟動(dòng)時(shí)就盡快可以被用起來(lái),質(zhì)量還行,但是仍然不被建議用于加密場(chǎng)景,通常發(fā)生在操作系統(tǒng)啟動(dòng)后的幾秒內(nèi);
2 = 完全初始化,隨機(jī)數(shù)的質(zhì)量達(dá)到最高,可以用于加密場(chǎng)景,操作系統(tǒng)啟動(dòng)后約幾十秒 – 幾分鐘的時(shí)間才能達(dá)到。
在默認(rèn)情況下,getrandom 讀取 /dev/urandom 前會(huì)去檢測(cè) /dev/urandom 的質(zhì)量狀態(tài),如果尚未完全初始化,則會(huì)阻塞,直到其完全初始化,以此來(lái)保障通過(guò)此接口獲得到的隨機(jī)數(shù)質(zhì)量高且速度快,為安全領(lǐng)域提供可靠的依賴。
了解了 getrandom 接口的作用和表現(xiàn)后,再去翻看內(nèi)核的啟動(dòng)日志,找到了時(shí)間相關(guān)性極高的點(diǎn)。
可以看到,23:10:48 時(shí) /dev/urandom 完全初始化后,隨即 getrandom 的調(diào)用阻塞也被解除了,再多次重復(fù)驗(yàn)證后,關(guān)聯(lián)性被確認(rèn)。此時(shí)的結(jié)論以及建議解決辦法為:原因:操作系統(tǒng)初始化隨機(jī)數(shù)熵池速度較慢,導(dǎo)致 ssh 登錄時(shí)使用到隨機(jī)數(shù)的一條命令時(shí)被阻塞。
建議:禁用 motd 或者刪除 landscape-sysinfo 來(lái)達(dá)到加速 ssh 登錄的目的。
深入調(diào)查
初步調(diào)查的結(jié)論有點(diǎn)違反常理,禁用或者刪除的措施也需謹(jǐn)慎。為此,我決定找出更多的證據(jù),此外,也需要解釋為什么舊版本的 Ubuntu 并沒(méi)有此現(xiàn)象。
嘗試查看表現(xiàn)正常的主機(jī)上 landscape-sysinfo 的 strace 表現(xiàn),查閱日志后注意到,此環(huán)境下的 strace 記錄與問(wèn)題主機(jī)中 strace 記錄在調(diào)用模式上存在不同,表現(xiàn)正常的主機(jī)上 landscape-sysinfo 中沒(méi)有這樣的調(diào)用 “getrandom (“xxx”, 32, 0) ”,注意第三個(gè) flag 參數(shù)值,此 flag 用于表明使用 getrandom 的默認(rèn)行為,即 /dev/urandom 未完全初始化時(shí)則阻塞。所有 getrandom 的地方都使用了 flag GRND_NONBLOCK,即如果沒(méi)有初始化完成不要阻塞,返回錯(cuò)誤就好。
至此,懷疑是 landscape-sysinfo 版本問(wèn)題。
landscape-sysinfo
對(duì)比兩臺(tái)主機(jī)上的 landscape-sysinfo 版本,發(fā)現(xiàn)版本號(hào)確實(shí)不同,有問(wèn)題的版本號(hào)較高,沒(méi)問(wèn)題的版本號(hào)較低。
將沒(méi)問(wèn)題的主機(jī)執(zhí)行 apt-get update & apt-get upgrade,升級(jí)后發(fā)現(xiàn)問(wèn)題果然重現(xiàn)。得出臨時(shí)結(jié)論:landscape-sysinfo 新版本使用了 getrandom 的阻塞模式獲取隨機(jī)數(shù),不要升級(jí) landscape-sysinfo 的版本即可。
開(kāi)始嘗試在其它主機(jī)上進(jìn)行復(fù)現(xiàn)和驗(yàn)證,卻發(fā)現(xiàn),在另一個(gè)高內(nèi)核版本的鏡像中,低版本的 landscape-sysinfo 也能復(fù)現(xiàn)此問(wèn)題,strace 追蹤調(diào)用,發(fā)現(xiàn)其調(diào)用行為與高版本的 landscape-sysinfo 表現(xiàn)相似,鑒于此命令實(shí)際上是 python3 腳本,懷疑是其依賴的庫(kù)升級(jí)導(dǎo)致。檢查 apt-get upgrade 升級(jí)的 package,找出與隨機(jī)數(shù)關(guān)聯(lián)度較大的幾個(gè)包,幾次排除嘗試后,定位發(fā)現(xiàn),其實(shí)是由于 libssl1.1 這個(gè)庫(kù)的升級(jí)導(dǎo)致的問(wèn)題,getrandom 的調(diào)用也是源自于 libssl1.1。
libssl1.1
翻閱
libssl1.1 的 release note https://www.openssl.org/news/openssl-1.1.1-notes.html
。
可以看到,的確,libssl1.1.1 的升級(jí),重寫了內(nèi)部隨機(jī)數(shù)的生成器,也符合前面的表現(xiàn),更新為使用 getrandom 讀取更加安全的隨機(jī)數(shù)(代價(jià)是剛開(kāi)機(jī)時(shí)使用就容易被阻塞)。
繼續(xù)嘗試在其它主機(jī)上進(jìn)行復(fù)現(xiàn)和驗(yàn)證,又發(fā)現(xiàn),在某個(gè)低內(nèi)核版本的 Ubuntu 主機(jī)上,安裝的正是 libssl1.1.1,卻不能復(fù)現(xiàn)問(wèn)題。按照預(yù)期,libssl1.1.1 的升級(jí)就是為了更安全,而如果一開(kāi)機(jī)就能立刻得到隨機(jī)數(shù),這根本就違背的 getrandom 接口的設(shè)計(jì)初衷,此時(shí)傾向于懷疑內(nèi)核可能存在 bug。
內(nèi)核 bug
以 libssl 調(diào)用 getrandom 被阻塞為關(guān)鍵主題查閱資料,最終找到相關(guān)性較強(qiáng)的資料
點(diǎn)擊查看相關(guān)資料 https://unix.stackexchange.com/questions/442698/when-i-log-in-it-hangs-until-crng-init-done
,其中 CRNG 指密碼學(xué)強(qiáng)度的隨機(jī)數(shù)發(fā)生器。
根據(jù)此資料,證實(shí)了內(nèi)核 bug 的猜測(cè),內(nèi)核在 4.16 時(shí)修正過(guò)這樣一個(gè) bug:getrandom 在快速初始化完成后就不再阻塞,這與 getrandom 的接口設(shè)計(jì)違背,容易造成安全問(wèn)題(CVE-2018-1108)
內(nèi)核 bug fix commit https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=43838a23a05fbd13e47d750d3dfd77001536dd33
驗(yàn)證主機(jī)的內(nèi)核版本為 4.15.0,與此情況符合,即很有可能是 bug 沒(méi)有被修復(fù),此時(shí),開(kāi)始嘗試升級(jí)低內(nèi)核版本主機(jī)的內(nèi)核版本,如果此猜測(cè)正確,那么升級(jí)到高版本后應(yīng)當(dāng)同樣會(huì)發(fā)生卡頓問(wèn)題。
在 apt 源上挑選了一個(gè) 5.0 版本的內(nèi)核,升級(jí)后發(fā)現(xiàn),居然也沒(méi)有問(wèn)題。
翻閱內(nèi)核日志,發(fā)現(xiàn)了一個(gè)新的現(xiàn)象,此前看到對(duì)于 /dev/urandom 的初始化,一般是會(huì)有一條 “fast init done” 日志,較長(zhǎng)時(shí)間后會(huì)跟隨一個(gè) “crng init done” 日志,正好對(duì)應(yīng)著 /dev/urandom 的兩種質(zhì)量狀態(tài)。
而此內(nèi)核版本下,則是在剛啟動(dòng)就立即出現(xiàn)了 “crng done (trusting CPU’s manufacturer) ” 的日志,明顯表明熵池被極速的初始化了,自然不會(huì)出現(xiàn)卡頓問(wèn)題。
查詢此現(xiàn)象相關(guān)資料,找到了一個(gè)內(nèi)核編譯選項(xiàng):CONFIG_RANDOM_TRUST_CPU。
CONFIG_RANDOM_TRUST_CPU
點(diǎn)此查看詳細(xì)選項(xiàng)說(shuō)明 https://lwn.net/Articles/760121/
首次出現(xiàn)于 4.19 版本:https://cateee.net/lkddb/web-lkddb/RANDOM_TRUST_CPU.html
檢查高版本內(nèi)核的兩臺(tái)主機(jī),的確,有問(wèn)題的主機(jī)此 flag 并沒(méi)有 enable,無(wú)問(wèn)題的主機(jī)此 flag 顯式的 enable 了。
而有問(wèn)題主機(jī)使用的內(nèi)核版本,取自于 Ubuntu 官方的最新主線分支編譯,默認(rèn)沒(méi)有啟動(dòng)此 flag 做優(yōu)化。
結(jié)論
此問(wèn)題的出現(xiàn)需要同時(shí)滿足以下幾個(gè)條件:1. linux 內(nèi)核版本在 4.17 及以上 2. linux 內(nèi)核編譯選項(xiàng) CONFIG_RANDOM_TRUST_CPU is not set,或者 CPU 非 IVB 及以上的 x863. linux 內(nèi)核 bug 未被社區(qū) revert(4.x 的最新社區(qū)版本幾乎都被 revert,5.x 沒(méi)有 https://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg1602769.html)
)4. libssl 版本在 1.1.1 及以上
影響面
事實(shí)上,SSH 登錄卡頓僅僅是一種表象,這個(gè)問(wèn)題的真實(shí)影響范圍,可以擴(kuò)展得非常大。凡是使用了 libssl1.1.1 來(lái)生成隨機(jī)數(shù)的進(jìn)程全都會(huì)受影響,導(dǎo)致重啟后 3-5 分鐘內(nèi)會(huì)被隨機(jī)數(shù) block。比如,服務(wù)器上跑著 nginx(開(kāi)啟 https),一般認(rèn)為機(jī)器啟動(dòng)后,nginx 馬上啟動(dòng)就能提供服務(wù)了,但是受此問(wèn)題影響,nginx 會(huì)被卡住三五分鐘。就是說(shuō),前三五分鐘內(nèi)的用戶 https 請(qǐng)求全部會(huì)出現(xiàn)訪問(wèn)失敗的現(xiàn)象。
問(wèn)題修復(fù)
為了做到性能與安全兼顧,在編譯 4.19 及更高版本的內(nèi)核時(shí),啟用 CONFIG_RANDOM_TRUST_CPU 選項(xiàng),我們采用此方法,enable 選項(xiàng)并確保虛擬機(jī)可以訪問(wèn) RDRAND 指令集,很快重新發(fā)布了云主機(jī)鏡像。如果用戶使用自定義內(nèi)核,應(yīng)盡量避開(kāi) 4.17-4.19 之間的版本,或者妥善處理好 CVE-2018-1108。
總結(jié)
提起云主機(jī),首先會(huì)想到計(jì)算、存儲(chǔ)、網(wǎng)絡(luò),甚少有人關(guān)注內(nèi)核。然而,內(nèi)核構(gòu)建也是云主機(jī)的核心工作,對(duì)性能和穩(wěn)定性至關(guān)重要。
SSH 登錄緩慢起初是單一用戶的反饋,且限于 Ubuntu 啟動(dòng)后的首次登錄,但通過(guò)堅(jiān)持排查和順藤摸瓜,我們發(fā)現(xiàn)了潛在的影響面并予以修復(fù),防患于未然。
UCloud 團(tuán)隊(duì)通過(guò)自主維護(hù)云主機(jī)的內(nèi)核源碼,一方面可以不斷調(diào)優(yōu)性能來(lái)匹配產(chǎn)品的發(fā)展;另一方面保證了遇到現(xiàn)網(wǎng)各種問(wèn)題時(shí),有能力迅速排查和解決,并及時(shí)預(yù)防更大的系統(tǒng)安全風(fēng)險(xiǎn)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。