證機(jī)制到實(shí)戰(zhàn)重置全指南)
做運(yùn)維這些年半夜被電話叫醒處理緊急故障的次數(shù)不少其中“root密碼忘了”絕對(duì)排得上前三名。網(wǎng)上搜“root密碼破解”出來的內(nèi)容魚龍混雜但真正干活的人心里清楚所謂破解在絕大多數(shù)情況下就是兩件事要么繞過系統(tǒng)登錄認(rèn)證進(jìn)入救援環(huán)境把密碼改掉要么繞過數(shù)據(jù)庫的授權(quán)校驗(yàn)重新寫入root密碼。這里必須先說清楚一個(gè)邊界本文所有操作只適用于你自己有管理權(quán)限的機(jī)器——自己的服務(wù)器、單位的測(cè)試機(jī)、忘了密碼的本地虛擬機(jī)。對(duì)不屬于你的系統(tǒng)做任何密碼繞過都屬于越權(quán)行為這不光是道德問題也有實(shí)實(shí)在在的法律風(fēng)險(xiǎn)。動(dòng)手之前先確認(rèn)好這一條后面的操作才有意義。這篇文章寫給誰寫給你正在跑業(yè)務(wù)的Linux服務(wù)器管理員、MySQL/MariaDB的DBA、還有自己折騰多系統(tǒng)或者虛擬機(jī)的愛好者。覆蓋的場(chǎng)景包括CentOS 7/RHEL 7根密碼丟失、Ubuntu/Debian系統(tǒng)進(jìn)不了桌面、數(shù)據(jù)庫報(bào)ERROR 1045 (28000)這類經(jīng)典錯(cuò)誤。我盡量把每一步的原理和坑都講透而不是給你一堆復(fù)制粘貼的指令。畢竟密碼找回只是手段恢復(fù)之后系統(tǒng)還能穩(wěn)定跑、安全不裸奔才是真正見功夫的地方。1. 先搞清楚一件事root密碼丟失后系統(tǒng)到底卡在哪1.1 登錄驗(yàn)證流程與密碼文件機(jī)制很多人一聽到“破解root密碼”下意識(shí)覺得是要搞什么底層系統(tǒng)、內(nèi)核后門。其實(shí)Linux的密碼機(jī)制遠(yuǎn)沒有想象中那么玄乎。內(nèi)核本身不認(rèn)密碼密碼校驗(yàn)是用戶態(tài)程序通過PAM認(rèn)證模塊去完成的。你輸入密碼系統(tǒng)讀取/etc/shadow文件里存放的密碼哈希值用同一個(gè)哈希算法計(jì)算你輸入的密碼比對(duì)結(jié)果一致就放你進(jìn)系統(tǒng)不一致就拒絕登錄。root用戶的uid是0內(nèi)核里很多特權(quán)檢查只看uid不看你“是不是叫root”。換句話說只要能想辦法在用戶態(tài)拿到一個(gè)uid為0的shell你就已經(jīng)是root了改不改密碼都無所謂了。這個(gè)本質(zhì)理解透了后面的所有操作就都好解釋了我們不是去暴力破解那個(gè)哈希值——除非你有GPU集群閑著沒事干——而是繞開“校驗(yàn)密碼”這一道關(guān)卡直接用合法途徑進(jìn)入root環(huán)境再用passwd命令重新寫一份密碼哈希進(jìn)/etc/shadow。/etc/passwd里存的只是用戶名、uid、gid、家目錄、shell這些基礎(chǔ)信息密碼那一欄永遠(yuǎn)是x。真正的密碼哈希在/etc/shadow里root用戶才能讀。所以如果root密碼丟了正常登錄時(shí)你連/etc/shadow都看不到更別說改了。這就像家門鑰匙丟了你不能站在門外研究鎖芯而是要找物業(yè)拿備用鑰匙或者從窗戶進(jìn)去。Linux的“備用鑰匙”就是引導(dǎo)加載器和單用戶模式。1.2 兩種“破解”思路改認(rèn)證配置 vs 臨時(shí)提權(quán)重置理解了密碼存儲(chǔ)位置和校驗(yàn)流程思路就清楚了。核心有兩種方向。方向一在系統(tǒng)啟動(dòng)早期介入拿到一個(gè)root shell。系統(tǒng)從開機(jī)到登錄頁面之間有一段引導(dǎo)加載程序GRUB控制的時(shí)間。GRUB本身運(yùn)行在內(nèi)核之前它不校驗(yàn)?zāi)愕腖inux密碼只要能物理接觸到機(jī)器或通過帶外管理控制臺(tái)就能修改啟動(dòng)參數(shù)。常見的做法有rd.break、single、init/bin/bash等。這些參數(shù)本質(zhì)上是讓系統(tǒng)在切換到真正的根文件系統(tǒng)之前先停在一個(gè)臨時(shí)shell里再通過chroot切進(jìn)原有系統(tǒng)環(huán)境最后用passwd重置密碼。方向二跳過認(rèn)證模塊直接改存儲(chǔ)介質(zhì)里的密碼哈希。這個(gè)方法更“底層”。既然密碼哈希就在磁盤上那用live CD、U盤啟動(dòng)一個(gè)最小系統(tǒng)把原系統(tǒng)分區(qū)掛載上來然后直接編輯/etc/shadow刪掉root的密碼哈希字段或者替換成一個(gè)你自己生成的哈希。這個(gè)方案不依賴GRUB但需要額外準(zhǔn)備啟動(dòng)介質(zhì)而且對(duì)文件系統(tǒng)、LVM、加密分區(qū)不熟悉的話很容易把數(shù)據(jù)弄壞。數(shù)據(jù)庫的root密碼找回是另一回事但思路完全一樣。MySQL/MariaDB的root密碼也存在系統(tǒng)的數(shù)據(jù)目錄里只不過不是/etc/shadow而是mysql庫里的user表。DBA常用的--skip-grant-tables參數(shù)就是讓數(shù)據(jù)庫跳過權(quán)限校驗(yàn)以不受限身份進(jìn)入再修改user表或執(zhí)行ALTER USER。方法雖然不同底層邏輯一模一樣繞開門禁進(jìn)到后臺(tái)重置憑證。2. Linux服務(wù)器root密碼找回grub這一關(guān)是最關(guān)鍵的臨門一腳2.1 CentOS 7/RHEL 7的rd.break法CentOS 7和RHEL 7這套系統(tǒng)我實(shí)測(cè)下來最好用的不是傳統(tǒng)的single而是rd.break。原因很簡單Systemd時(shí)代單用戶模式的行為不像SysVinit那么可控了而rd.break是在initramfs階段就斷住能拿到一個(gè)非常干凈的shell環(huán)境。具體操作如下重啟服務(wù)器在GRUB引導(dǎo)菜單出現(xiàn)時(shí)按下e鍵進(jìn)入編輯模式。找到以linux16或linuxefi開頭的那一行。這行的末尾通常寫著ro crashkernelauto之類的內(nèi)容。把ro改成rw然后在行尾空一格追加參數(shù)rd.break。按Ctrlx或者F10啟動(dòng)系統(tǒng)會(huì)進(jìn)入initramfs的緊急shell提示符類似switch_root:/#。在這個(gè)shell中執(zhí)行mount -o remount,rw /sysroot。這里的/sysroot就是真正的系統(tǒng)根目錄但初始狀態(tài)是只讀的必須先掛成可寫。執(zhí)行chroot /sysroot這時(shí)你就進(jìn)入了原系統(tǒng)的root環(huán)境。執(zhí)行passwd root輸入兩次新密碼。關(guān)鍵一步如果系統(tǒng)開啟了SELinux必須執(zhí)行touch /.autorelabel。這條命令會(huì)在重啟時(shí)觸發(fā)文件系統(tǒng)重打SELinux標(biāo)簽否則你新改的/etc/shadow可能因?yàn)榘踩舷挛牟粚?duì)導(dǎo)致重啟后依然無法登錄。連續(xù)兩次exit系統(tǒng)會(huì)繼續(xù)啟動(dòng)等待自動(dòng)relabel完成后就可以用新密碼登錄了。這個(gè)流程最核心的點(diǎn)是第4步和第7步。我見過太多人卡在第4步進(jìn)了switch_root環(huán)境后直接chroot /sysroot結(jié)果報(bào)錯(cuò)說Permission denied因?yàn)?sysroot還是只讀狀態(tài)/sysroot/etc目錄里的文件沒法動(dòng)。記住先mount -o remount,rw再chroot。SELinux那步也是老司機(jī)都踩過的坑。CentOS 7默認(rèn)開SELinux如果你只改密碼不執(zhí)行touch /.autorelabel重啟后極有可能出現(xiàn)“密碼明明對(duì)了但就是進(jìn)不去”的詭異現(xiàn)象。系統(tǒng)日志里會(huì)報(bào)SELinux is preventing ...。不要省這一步。2.2 Ubuntu/Debian的recovery mode操作Ubuntu/Debian系的處理方式稍微不一樣。平時(shí)我們說ubuntu 切換root都是指系統(tǒng)正常運(yùn)行時(shí)用sudo -i或者su -但如果root密碼本身忘了連sudo密碼都不知道那就只能進(jìn)恢復(fù)模式。重啟后在GRUB菜單中選擇“Advanced options for Ubuntu”進(jìn)入子菜單后會(huì)看到帶(recovery mode)字樣的內(nèi)核條目選中它回車。系統(tǒng)會(huì)進(jìn)入一個(gè)recovery菜單里面有一項(xiàng)“root Drop to root shell prompt”。選擇這項(xiàng)系統(tǒng)會(huì)把根分區(qū)掛載為只讀然后給你一個(gè)root shell。在這個(gè)shell里首先執(zhí)行mount -o remount,rw /把根文件系統(tǒng)切回可寫狀態(tài)。然后執(zhí)行passwd root設(shè)置新密碼。如果系統(tǒng)里默認(rèn)配置了root賬號(hào)被鎖定只允許sudo用戶切換root那你可以直接重置當(dāng)前用戶的密碼或者執(zhí)行passwd -u root解鎖root賬號(hào)。Ubuntu默認(rèn)root是鎖定的很多人剛上手不習(xí)慣其實(shí)這是發(fā)行版的安全策略不建議無腦解鎖。Debian系還有一種情況如果你的根目錄是LVM或者做了加密recovery模式不一定能自動(dòng)識(shí)別。遇到這種情況我建議直接用live CD啟動(dòng)掛載根分區(qū)后再進(jìn)入chroot環(huán)境操作比在recovery菜單里反復(fù)折騰要舒服得多。live CD方式其實(shí)也簡單啟動(dòng)到live桌面后用lsblk找到系統(tǒng)分區(qū)mount /dev/sdX1 /mnt掛載完再mount --bind /dev /mnt/dev、mount --bind /proc /mnt/proc最后chroot /mnt然后passwd root。這套下來更通用也容易排查。2.3 單用戶模式與SELinux坑CentOS 6時(shí)代大家很喜歡用single參數(shù)進(jìn)入單用戶模式那時(shí)系統(tǒng)是SysVinit人為干預(yù)少手動(dòng)操作相對(duì)可靠。但到了CentOS 7之后的Systemd時(shí)代單用戶模式默認(rèn)啟動(dòng)的是一個(gè)rescue.target它不一定會(huì)給你一個(gè)交互式shell而且如果根分區(qū)加密或者需要網(wǎng)絡(luò)資源rescue服務(wù)可能直接卡住。所以我現(xiàn)在的習(xí)慣是能用rd.break就不用single。不過rd.break也不是萬能的。不同版本的內(nèi)核、不同的文件系統(tǒng)啟動(dòng)參數(shù)可能略有區(qū)別。比如UEFI引導(dǎo)的機(jī)器linux16可能寫的是linuxefi你編輯時(shí)只需要對(duì)實(shí)際出現(xiàn)的行追加參數(shù)就行。還有個(gè)別云服務(wù)器的GRUB被云廠商定制過菜單里會(huì)多出“維護(hù)模式”之類的選項(xiàng)操作前務(wù)必先看清楚。SELinux的坑不僅要防著修改/etc/shadow之后還有一個(gè)場(chǎng)景你重置完密碼重啟時(shí)系統(tǒng)自動(dòng)relabel這個(gè)過程在硬盤大的機(jī)器上可能持續(xù)幾分鐘屏幕上是黑底白字沒有進(jìn)度條很多人以為死機(jī)了其實(shí)是在逐個(gè)文件重新設(shè)置安全上下文。耐心等就行千萬別強(qiáng)制斷電否則真可能把文件系統(tǒng)搞出問題。3. 數(shù)據(jù)庫root密碼的另類“破解”繞過認(rèn)證進(jìn)入MySQL/MariaDB3.1 error 1045 (28000)到底在說什么服務(wù)器root密碼搞定之后另一類高頻問題就是數(shù)據(jù)庫root密碼忘了。如果你曾經(jīng)用命令行直接連MySQL或者M(jìn)ariaDB大概率見過這個(gè)報(bào)錯(cuò)ERROR 1045 (28000): Access denied for user rootlocalhost (using password: YES)這個(gè)錯(cuò)誤表面意思是“用戶名或密碼錯(cuò)誤”但實(shí)際原因可以細(xì)分出好幾種。最常見的情況是密碼確實(shí)忘了或輸錯(cuò)了但還有一種容易被忽略的情況認(rèn)證方式變了。MySQL 5.7開始默認(rèn)的認(rèn)證插件是caching_sha2_password或mysql_native_password而你用的客戶端工具版本太老不認(rèn)識(shí)新插件也會(huì)報(bào)1045。MariaDB的認(rèn)證方式又和MySQL不完全一樣。處理1045的思路分三步先確認(rèn)root賬號(hào)到底是通過哪個(gè)host匹配進(jìn)來的再確認(rèn)認(rèn)證插件是什么最后才是重置密碼。官方文檔里有一個(gè)邏輯連接數(shù)據(jù)庫時(shí)服務(wù)端會(huì)從user表里匹配host和user字段。如果user表里既有一條rootlocalhost又有一條root127.0.0.1你用不同方式連接socket、TCP時(shí)匹配的結(jié)果可能都不一樣。有時(shí)候明明密碼正確但因?yàn)橛昧薚CP連接而user表里沒有對(duì)應(yīng)的host授權(quán)也會(huì)報(bào)1045。3.2 skip-grant-tables重置root密碼的標(biāo)準(zhǔn)流程當(dāng)數(shù)據(jù)庫root密碼徹底沒救時(shí)通用的做法是讓MySQL/MariaDB跳過授權(quán)表啟動(dòng)。這個(gè)操作相當(dāng)于讓數(shù)據(jù)庫“不檢票就放人進(jìn)站”所以必須配合--skip-networking參數(shù)只允許本地socket連接防止在跳過密碼校驗(yàn)期間被外網(wǎng)連進(jìn)來那等于把數(shù)據(jù)庫裸奔在公網(wǎng)上。以MariaDB為例標(biāo)準(zhǔn)流程是這樣的停止數(shù)據(jù)庫服務(wù)systemctl stop mariadb。以后臺(tái)模式啟動(dòng)mysqld_safe --skip-grant-tables --skip-networking 。如果你用的是MySQL命令換成mysqld --usermysql --skip-grant-tables --skip-networking 。另開一個(gè)終端直接不帶密碼登錄mysql -u root。因?yàn)樘^了授權(quán)表所以這個(gè)命令一定能進(jìn)。進(jìn)入后先執(zhí)行FLUSH PRIVILEGES;讓當(dāng)前會(huì)話重新加載權(quán)限相關(guān)配置。有些老版本教程讓你直接用UPDATE mysql.user SET passwordPASSWORD(新密碼)但更新完后必須重啟才生效不如直接用ALTER USER。執(zhí)行重置密碼語句ALTER USER rootlocalhost IDENTIFIED BY 新密碼; FLUSH PRIVILEGES;如果你用的是MySQL 5.7以上版本推薦用ALTER USERMariaDB 10.4以上同樣支持。老版本MySQL 5.6如果ALTER USER報(bào)錯(cuò)再退回用UPDATE mysql.user SET authentication_stringPASSWORD(newpass) WHERE Userroot;這個(gè)語法在最新版本里已經(jīng)廢棄不要照搬。退出mysql殺掉剛才的后臺(tái)進(jìn)程pkill -9 mysqld然后用systemctl start mariadb正常啟動(dòng)服務(wù)。這里有幾個(gè)細(xì)節(jié)要特別提醒。第一--skip-grant-tables啟動(dòng)期間MySQL會(huì)警告“所有用戶都能免密連接”即便你加了--skip-networking在同一臺(tái)機(jī)器上的其他本地用戶還是可能通過socket連進(jìn)來。所以操作要快不要在跳過授權(quán)表的狀態(tài)下磨蹭太久。第二重置成功后一定要檢查一下/etc/my.cnf或者/etc/mysql/下有沒有殘留的skip-grant-tables配置。有些人嫌麻煩直接寫進(jìn)配置文件忘了刪結(jié)果服務(wù)一重啟又進(jìn)入免密狀態(tài)安全隱患極大。3.3 密碼插件與認(rèn)證方式容易踩的坑數(shù)據(jù)庫root密碼重置還有個(gè)特別容易踩的坑是認(rèn)證插件。尤其在Ubuntu上用apt安裝的MySQL或MariaDB很多時(shí)候root用戶根本走的不是密碼認(rèn)證而是auth_socket或unix_socket插件。這種插件的邏輯是只要你的系統(tǒng)用戶是root并且通過Unix socket連接數(shù)據(jù)庫就無條件放行不校驗(yàn)密碼。所以你執(zhí)行mysql -u root在本地能進(jìn)但在程序里用TCP的127.0.0.1連接就報(bào)1045因?yàn)門CP連接不滿足unix_socket的校驗(yàn)條件。遇到這種情況要先明確你的目標(biāo)是希望root用戶也必須用密碼跨網(wǎng)絡(luò)登錄還是只是本地root能免密就行。如果需要設(shè)置密碼得顯式把認(rèn)證插件改掉ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 新密碼;MariaDB 10.4之后默認(rèn)還引入了mysql_native_password和unix_socket插件并存的行為本地socket連接可以免密TCP連接需要用密碼。這個(gè)設(shè)計(jì)容易讓人誤判“密碼沒生效”。你如果測(cè)試的時(shí)候在服務(wù)器本地執(zhí)行mysql -u root成功了就以為密碼密碼不對(duì)其實(shí)是因?yàn)樽吡藄ocket免密通道。想驗(yàn)證密碼是否真的設(shè)置成功用mysql -u root -p -h 127.0.0.1強(qiáng)制走TCP方式測(cè)試。4. 密碼重置后的安全加固和善后4.1 更新密碼后必須做的事密碼改完不代表工作結(jié)束。我見過太多同事改完root密碼興高采烈地登錄進(jìn)去結(jié)果第二天發(fā)現(xiàn)服務(wù)起不來或者數(shù)據(jù)庫權(quán)限全亂了。所以善后步驟必須當(dāng)成正式流程來走。第一檢查登錄日志。重置密碼的過程中無論你是用rd.break進(jìn)緊急shell還是用skip-grant-tables啟動(dòng)數(shù)據(jù)庫系統(tǒng)都會(huì)留下大量記錄。用journalctl -xb查看本次啟動(dòng)日志確認(rèn)有沒有異常登錄嘗試。數(shù)據(jù)庫方面可以查~/.mysql_history和/var/log/mysql/error.log看有沒有人趁亂連接過。第二清理臨時(shí)痕跡。比如根目錄下的/tmp可能有你臨時(shí)創(chuàng)建的腳本數(shù)據(jù)庫目錄里可能有過my.cnf的臨時(shí)備份。更常見的是shell歷史記錄進(jìn)chroot環(huán)境后執(zhí)行過的passwd命令、mysql里執(zhí)行過的ALTER USER語句都會(huì)被記錄到~/.bash_history或者~/.mysql_history。如果你不希望這些操作留在明文歷史里用history -c清理或者直接刪除對(duì)應(yīng)的歷史文件。第三更新應(yīng)用配置。這個(gè)屬于最容易被忽略的。服務(wù)器上的業(yè)務(wù)進(jìn)程比如Java應(yīng)用、PHP站點(diǎn)、監(jiān)控腳本它們連接數(shù)據(jù)庫用的都是舊密碼。你這邊把數(shù)據(jù)庫root密碼改了應(yīng)用那邊如果還在用舊密碼輕則日志里刷1045重則整個(gè)業(yè)務(wù)直接不可用。所以重置密碼之后馬上去檢查application.properties、wp-config.php、env文件這些地方批量替換新密碼。第四如果系統(tǒng)啟用了SELinux改完shadow文件后記得確認(rèn)/etc/shadow的SELinux標(biāo)簽是否正確。正常情況是system_u:object_r:shadow_t:s0用ls -Z /etc/shadow能看到。如果標(biāo)簽被搞亂執(zhí)行restorecon -v /etc/shadow恢復(fù)。4.2 防止下次再忘密碼管理方案密碼重置完下一步就是防止重蹈覆轍。我的經(jīng)驗(yàn)是不要相信自己的記憶也不要相信貼在顯示器上的便利貼。服務(wù)器密碼應(yīng)該存在密碼管理器里比如本地的KeePass、命令行的pass工具或者團(tuán)隊(duì)用的Vaultwarden。對(duì)個(gè)人服務(wù)器來說一張加密的KeePass數(shù)據(jù)庫放在加密U盤里已經(jīng)完全夠用。更推薦的做法是減少root密碼的使用頻率。能走sudo就走sudo能走SSH密鑰登錄就走密鑰。具體操作上可以先給一個(gè)普通用戶加sudo權(quán)限然后用passwd -l root鎖定root的密碼登錄。這樣即使root密碼泄露也沒法從遠(yuǎn)程直接ssh root登錄攻擊面小了很多。很多云服務(wù)器默認(rèn)就禁止root遠(yuǎn)程登錄這是有道理的。數(shù)據(jù)庫層面也一樣。日常運(yùn)維盡量少用root賬號(hào)創(chuàng)建專門的數(shù)據(jù)庫用戶只授權(quán)業(yè)務(wù)需要的庫和表然后把密碼存到配置中心或者環(huán)境變量里。不要把數(shù)據(jù)庫密碼明文寫在代碼倉庫中也不要在命令行參數(shù)里直接帶-p密碼因?yàn)閜s能直接看到完整命令行密碼分分鐘暴露。4.3 修改root密碼的正確姿勢(shì)善后過程中還涉及一個(gè)細(xì)節(jié)修改root密碼本身不同場(chǎng)景要用不同命令不能混著來。Linux系統(tǒng)里交互式改密碼用passwd root這個(gè)命令會(huì)提示你輸入兩次新密碼適合人工操作。如果要在腳本里批量改密碼我習(xí)慣用chpasswdecho root:新密碼 | chpasswd直接編輯/etc/shadow文件改密碼是最后手段因?yàn)椴煌l(fā)行版的shadow哈希格式和密碼策略不完全一樣手誤很容易把整個(gè)文件寫壞。如果確實(shí)要手工生成一個(gè)哈??梢杂胦penssl passwd -6生成的是SHA-512哈希寫入格式比較安全。但依然不推薦手改。數(shù)據(jù)庫這邊MySQL 5.7和8.0的推薦語句就是ALTER USER。MariaDB 10.4以上可以用ALTER USER也可以用SET PASSWORD FOR rootlocalhost PASSWORD(新密碼)。不要再使用老掉牙的INSERT或直接改my.cnf里的user表字段版本一變認(rèn)證方式一變老辦法只會(huì)幫倒忙。5. 實(shí)操中的常見坑完整排查思路與避坑清單5.1 grub菜單修改后不生效這是重置Linux密碼時(shí)出現(xiàn)頻率最高的問題。你明明按了e改好參數(shù)加了rd.break但重啟后還是直接進(jìn)了系統(tǒng)或者界面根本沒變化。排除順序是這樣的先確認(rèn)你按的是不是e而不是cc直接進(jìn)了GRUB命令行再確認(rèn)是不是有多個(gè)內(nèi)核條目你編輯的是當(dāng)前默認(rèn)啟動(dòng)的那個(gè)。另一個(gè)常見原因在VMware虛擬機(jī)或者某些云服務(wù)器上GRUB菜單的顯示時(shí)間太短還沒等你按鍵就直接進(jìn)系統(tǒng)了。這種情況可以在BIOS設(shè)置里把GRUB超時(shí)時(shí)間調(diào)長或者開機(jī)時(shí)狂按Shift鍵讓GRUB菜單強(qiáng)制出現(xiàn)。UEFI機(jī)器有時(shí)候還要按Esc而不是Shift。還有一種情況是機(jī)器用了新的BootLoader比如systemd-boot或者精簡版的GRUB壓根不按傳統(tǒng)方式加載linux16行。這時(shí)候別死磕rd.break直接改用live CD方案更省事。5.2 SELinux導(dǎo)致無法登錄或sshd異常有段時(shí)間我?guī)腿颂幚硪慌_(tái)CentOS 7.6的服務(wù)器密碼重置完重啟后root密碼明明輸入對(duì)了但就是被拒絕登錄。排查日志才發(fā)現(xiàn)SELinux把/etc/shadow的訪問攔截了因?yàn)橹刂眠^程中文件的SELinux上下文被破壞。這就是我這次反復(fù)強(qiáng)調(diào)touch /.autorelabel的原因。還有一種SELinux的坑是有些人重置完密碼沒有重啟relabel系統(tǒng)倒是能進(jìn)去了但sshd起不來或者起來了連不上。這多半是因?yàn)?etc/ssh/下的host key文件或者端口配置的上下文不對(duì)。用restorecon -Rv /etc/ssh就能修。新手常犯的錯(cuò)是把SELinux直接setenforce 0關(guān)閉這相當(dāng)于把安全機(jī)制全拆了不可取。5.3 數(shù)據(jù)庫重置后服務(wù)起不來、權(quán)限報(bào)錯(cuò)數(shù)據(jù)庫root密碼重置完最常見的報(bào)錯(cuò)是服務(wù)啟動(dòng)失敗日志里說什么Cant open the mysql.plugin table或者Permission denied。這種現(xiàn)象通常不是密碼問題而是你在skip-grant-tables模式下操作時(shí)把數(shù)據(jù)目錄的屬主或者權(quán)限搞亂了。正確做法是啟動(dòng)前先確認(rèn)/var/lib/mysql目錄的屬主是mysql:mysql。如果被改成了root執(zhí)行chown -R mysql:mysql /var/lib/mysql還有個(gè)更容易忽略的你如果在skip-grant-tables模式下手動(dòng)UPDATE mysql.user但忘記執(zhí)行FLUSH PRIVILEGES新密碼可能不會(huì)立即生效。另外pkill -9 mysqld后有時(shí)候socket文件/var/run/mysqld/mysqld.sock沒有清理干凈再次啟動(dòng)時(shí)會(huì)報(bào)Address already in use或Cant create/write to file。順手刪掉這個(gè)socket文件再重啟通常能解決問題。下面是幾個(gè)高頻錯(cuò)誤和處理方式的對(duì)照方便你按圖索驥現(xiàn)象最可能原因處理命令/思路GRUB編輯后直接進(jìn)系統(tǒng)按錯(cuò)鍵或GRUB超時(shí)太短按e調(diào)大timeout重置密碼后登錄被拒SELinux上下文損壞touch /.autorelabel后重啟chroot /sysroot權(quán)限不足/sysroot未remount rw先mount -o remount,rw /sysrootMySQL 1045 (28000)密碼錯(cuò)誤或認(rèn)證插件不匹配ALTER USER ... IDENTIFIED WITH ...MySQL啟動(dòng)失敗報(bào)目錄權(quán)限數(shù)據(jù)目錄屬主被改chown -R mysql:mysql /var/lib/mysqlMariaDB本地免密、遠(yuǎn)程要密碼unix_socket插件視需求修改認(rèn)證方式5.4 必須注意的合法邊界聊了這么多技術(shù)細(xì)節(jié)最后一件事必須認(rèn)真說清楚。這些操作方法雖然有效但只能用在你自己有權(quán)限管理的設(shè)備上。自己的服務(wù)器忘了密碼、單位測(cè)試環(huán)境需要恢復(fù)、虛擬機(jī)隨便折騰這些都沒問題。但如果你對(duì)一臺(tái)不屬于自己的機(jī)器嘗試“root密碼破解”那就不是技術(shù)問題了。輕則違反服務(wù)協(xié)議重則觸碰相關(guān)法規(guī)是要承擔(dān)后果的。尤其要注意云服務(wù)器、托管機(jī)房里的機(jī)器一般都有帶外管理或者云控制臺(tái)的重置密碼功能。遇到生產(chǎn)環(huán)境root密碼丟失第一選擇永遠(yuǎn)是走平臺(tái)提供的正規(guī)重置通道而不是自己開機(jī)進(jìn)GRUB。生產(chǎn)服務(wù)器數(shù)據(jù)重要萬一在救援過程中因?yàn)檎`操作導(dǎo)致數(shù)據(jù)丟失后悔都來不及。最后說點(diǎn)個(gè)人操作體會(huì)這幾套方法我前前后后用了無數(shù)次踩過的坑比教程里寫的還要多一份。綜合來看我的習(xí)慣是能走帶外管理重置就走帶外能走云控制臺(tái)就走云控制臺(tái)只有純物理機(jī)且沒有帶外通道時(shí)才進(jìn)GRUB救援。每次操作前先拿手機(jī)拍一下GRUB原始參數(shù)改完再拍一張萬一失敗還能還原。數(shù)據(jù)庫重置時(shí)先在另一個(gè)終端開好binlog或者準(zhǔn)備好備份不要裸奔在skip-grant-tables里太久。如果你要問我這套操作里最值錢的經(jīng)驗(yàn)是什么我會(huì)說膽子要大心要細(xì)命令要一條一條敲改完一步就驗(yàn)證一步不要一口氣復(fù)制全部代碼。畢竟root密碼這種東西改錯(cuò)了系統(tǒng)可能都進(jìn)不去但只要你腦子清楚、流程到位最后大部分情況都能平穩(wěn)落地。希望這篇文章真能幫上正在對(duì)著屏幕抓耳撓腮的你。