本文針對centos7及以后版本,以前的版本不適用,并且單指root密碼在開機程序中的修改,
修改密碼本身的操作不復雜,但是程序中發生的事情和用到的命令值得研究一下,
簡略版:
- 按下開機鍵;
- 在核心啟動項按下“e”鍵;
- 在啟動腳本引導陳述句后填入rd.break;
- 按下ctrl+x,等待系統引導至switch_root模式重新可輸入;
- 輸入命令:mount -o remount,rw /sysroot
- 輸入命令:chroot /sysroot
- 輸入命令:echo "YourNewPassWord" | passwd --stdin root
- 輸入命令:touch /.autorelabel
- 輸入命令:exit
- 輸入命令:reboot
以上方法,取自官方檔案,其中有一些需要注意的地方
- 啟動引導陳述句是linux=16這一行,如果找不到可以按住鍵盤方向鍵下,可能螢屏上不會顯示所有的陳述句內容,向下滾動即可看到;
- 如果虛擬機在啟動時不能正確顯示,可以在第三步改為rd.break console=tty0 并去掉 rhgb、quiet引數;
- 第五步中,請注意remount和rw之間是逗號;
- 第七步中,引號內替換為你自己的密碼即可;
決議步驟:
了解開機修改密碼的程序,本質上是對linux啟動程序,以及安全背景關系(SELinux)的研究,因為這兩個方面都很深奧,所以本文只針對修改開機密碼時發生的事情簡單的研究下所涉及到的這兩方面的應用,并不涉及到更高深的原理,如果想深入研究,請自行探索,
一.需要預先知道的一些事情
Linux開機最簡化流程:供電-BIOS-initframfs-內核-shell
SELinux狀態:強制、許可、禁用
二.分步
0.首先看下你的系統是否適合使用此方法
執行命令:
cat /etc/redhat-release
會回傳當前系統版本

如圖,系統版本是CentOS 7.9 Centos7 以下的系統不適用此方法,因為開機啟動方式和引導方式都有變化
1.開機時,在系統核心按下“e”鍵,

此處是GRUB2選單,也就是centos采用的bootloader,
根據文字提示,第一個就是,下方的時支援核心,用于系統故障排查,如果這一步看到了多個核心,說明該清理無用核心了,這種情況可能是更新造成的,請根據實際情況清理你的系統,
此頁提示:使用方向鍵上下改變選項,按下e鍵編輯所選項,或者按下c打開命令提示符,開機時請盡快選擇,此頁只會停留5s,之后自動啟動核心,按任意鍵取消五秒倒計時,改為手動操作,
2.在引導陳述句后方填入rd.break

按下E鍵后,看到的會是這樣一段腳本,但是沒有啟動項這一行
用方向鍵下,往下滾動,,,

框選出來的,linux16開頭的這行便是核心專案,可以看出指定了一些檔案、地址和引數.
在末尾添加 rd.break 注意與前方有一處空格,
如果是虛擬機,有可能會出現之后無法進入switch_root的問題,rd.break后添加console=tty0即可,原因是因為虛擬機有可能會無法對接正確的終端,也就是沒把控制臺傳遞給顯示的終端導致用戶看不到,加上這一句,直接告訴系統直接走tty0這個當前終端的別名上,tty0會收容所有的系統資訊,解決這個問題,
如果想看到全部的啟動資訊,還需要再去掉前面的rhgb、quiet引數,rhgb(redhat graphics boot)把啟動程序中的文本資訊用圖片替代,quiet會過濾掉一些硬體自檢資訊
我使用虛擬機測驗沒遇到過這些問題,現在也不想接受那些資訊,所以只需要添加rd.break即可,如需添加以上命令,命令之間用空格隔開,
為什么是rd.break
此步驟是在引導內核啟動階段前期使用rd.break中斷,利用initramfs獲取到一個root shell,
系統早期啟動時,引導加載程式(bootloader)會在記憶體中加載vmlinuz(可引導的內核)和initramfs(記憶體虛擬檔案系統),因為當啟動初期,核心需要動態加載的模塊在磁盤中中,但磁盤本身也是通過這些模塊才能正常使用(被掛載),所以一個現在使用的解決方案:使用一個虛擬檔案系統,讓內核可以加載驅動和啟動需要的檢測、服務,
initramfs會被掛載為rootfs,掛載點為/,就是根檔案系統,內核通過提供的程式介面加載這些檔案系統與磁盤介面的驅動核心模塊,然后內核會檢測是否存在init程式,如果有就會執行,init直接將控制權交給systemd去呼叫target加載需要的服務(Centos7以后),我們就在這個時機停下,告訴init不要轉交控制權,這樣引導啟動就不會繼續轉移控制權,此時真正的內核檔案系統還沒有根檔案系統,initramfs具仍有root權限,可以給我們提供修改密碼的必要的條件,(此處設定僅為臨時的控制,僅供下次啟動時可以中斷并繼續操作,不是永久修改)
3.按下組合鍵ctrl+x,系統重新引導至switch_root模式

根據上一步,螢屏下方的提示,按下ctrl+x重啟,系統本次重啟就會攜帶上我們自己編輯好的引數啟動,進入到switch_root模式,switch_root又是什么?
根據上一步所說,系統在啟動程序中被中斷,沒有繼續交給systemd啟動,那么這時候就需要我們手動來實作根節點的掛載,根據截圖,會發現命令列身份標識是# 證明我們在rootfs中,具有最高權限,但此時我們也沒有進入到需要的linux核心中,initramfs并不是我們需要修改密碼的地方,我們需要切換到核心中去操作,
switch_root:是busybox提供的一個切換跟的解決方案,可以讓我們很方便的通過命令直接切換到需要的根節點,此命令必須由PID=1的行程來呼叫,而我們目前所使用的行程正是init,PID=1
4.重新掛載核心節點,切換跟
我們可以先來看下目前的掛載情況,使用mount即可查看

列出了全部掛載情況,框選處,我們可以看到 root 被掛載在/sysroot處,接著往后看詳細資訊 描述了它的讀寫情況為只讀,readonly,我試了下在這種情況下直接改密碼,提示了一些亂碼,應該是描述了錯誤資訊,無視并啟動之,發現修改的密碼無效,舊密碼能夠正常進入,說明修改失敗,所以此處還是需要先把核心掛載為可讀寫狀態才可以修改,
1.首先需要重新掛載已經掛載的根,命令如下:
mount -o remount,rw /sysroot
2.掛載好后,將跟修改為sysroot/,命令如下:
chroot /sysroot
如果不放心,可以重新掛載后,再次執行mount查看下是不是已經可讀寫了

當看到此處,我們已經進入到了核心的掛載點,
5.修改密碼并創建自動恢復標記
切換好跟后,我們就可以修改密碼了,修改密碼后,還要再創建一個自動恢復的檔案.autorelable,這是什么?為什么要創建它?先看下操作步驟...
1.使用passwd命令來重新創建密碼,命令如下
echo "YourNewPassWord" | passwd --stdin root
2.在根目錄下創建自動恢復標記檔案,命令如下
touch /.autolabel

修改密碼沒什么可說的,但是為何要創建.autorelable檔案,還是需要先大概了解下SElinux是什么,最簡單的解釋是Linux通過這樣一個核心模塊,確保整個檔案系統的安全性,是Linux的子系統,如果希望手動控制策略,涉及到的內容非常復雜,但是用戶可以簡單的命令和修改他的主組態檔去修改當前運行的基本狀態,其中,安全背景關系是SElinux的核心部分,他要求行程訪問的檔案背景關系標記必須對應上,而這個標記是由SElinux自動標記的,不需要我們手動干涉,但是一些操作會讓安全背景關系完整性遭到破壞,比如我們在開機時修改密碼的操作,
我們使用passwd命令去修改密碼時,會創建一個新的/etc/shadow檔案,然后把SELinux標記應用于新的檔案上,再把老的shadow檔案復制過來并寫入新密碼,這個步驟本身沒有問題,但是在此時,并沒有實際運行一個真正地作業系統,多數行程包括SElinux都沒有運行(這里可以使用getenforce來看下狀態,會發現狀態是Disabled),我們修改密碼的程序并沒有被驗證過,新的shadow檔案不具備背景關系安全標識,在SElinux沒有運行時是沒有問題的,但問題是SElinux默認開啟,且運行策略為強制執行,也就是說當我們在開機時,會出現修改密碼后的檔案因為背景關系的原因無發被使用,直接造成的后果是無論使用新舊密碼都無法進入系統,
但是有幾種方式可以解決這個問題,首先是在根目錄創建.autorelable,這會使SElinux在開機時重新標記整個檔案系統,當然就包含我們修改密碼時影響的shadow檔案,同時這也是最安全,且由redhat官方推薦的方式,我測驗使用這個方法恢復,系統會在initramfs重啟后先經過一次標記程序,完成后再次重啟,開機后在/下無法找到這個檔案,目前猜測可能是流程結束后被SElinux自動移除,整體程序耗時比較長,在虛擬機新創建沒有任何其他檔案的情況下,從執行重啟命令到開機需要四分鐘左右(精簡安裝),而尤其對硬體性能不加或者檔案過多的情況下尤其明顯,所以我們可能并不會采用這種方式,使用的其他方式,下文在介紹,
6.退出并重啟
這一步就是從臨時跟系統中退出,在initramfs中執行重啟,沒有什么可多說,使用對應命令即可,
1.退出,命令如下:
exit
此時回到switch_root
2.重啟
reboot

重啟后可以使用修改后的密碼登錄root賬戶
修改密碼的其他方式
一. 手動恢復檔案
我們可以使用一些方式跳過SElinux對系統的整體重新標記,首先要修改下之前的步驟,前面步驟不變,到修改密碼后,不需要再執行touch /.autorelabel這步操作,直接執行退出重啟,
當再次開機到GRUB時,繼續按e編輯內核啟動項,但這次只添加一句:enforcing=0 即可,這條命令代表將SElinux運行模式調整為許可模式,開機時攜帶此引數,那么在本次開機時,SElinux的運行模式就會被調整,
此時開機就可以使用之前修改后的密碼登錄了,啟動后使用getenforce檢查一下,發現運行狀態是許可模式,進一步查看組態檔,發現仍然是強制模式,因為我們只是在本次開機修改了模式,并沒有將他寫在配置中,只是利用許可模式不強制執行策略的特點進入系統中,此時要做的是手動回復背景關系不完整的檔案,

可以看到當前是Permissive運行,但配置仍然是enforcing,
我們可以通過restorecon命令來手動恢復檔案的背景關系,這里可以選擇只恢復/etc/shadow這個檔案,也可以恢復一個目錄,如果恢復檔案,只需要執行
restorecon /etc/shadow 即可,但是恢復目錄需要加入 -R 引數,代表遞回,如需查看程序,還需要加入 -v
restorecon -Rv /etc,這樣就可以了,之后可以使用setenforce命令手動將運行模式更改為強制模式,或者直接重啟都可以,
二.init=/bin/bash
如果在開機時,指定init指向一個shell,那么系統會在PID一號行程處為我們啟動一個shell,同樣可以修改密碼,
按下開機鍵后,在內核引導陳述句后加入 init=/bin/bash,然后按下ctrl+x引導啟動,之后的操作見下圖

同樣的,我們需要掛載根節點為可讀寫,否則無法修改,但是請注意這里掛載點是/,不是/sysroot
接下來是修改密碼和創建relabel,但之后的啟動需要注意,這里不能使用reboot或者init來重啟或者繼續啟動,如果直接使用命令,回傳的提示命令未找到,這是因為此時我們使用的是一個默認的bash環境,環境變數的缺失導致大量命令無法被系統找到,
此時能夠使用的啟動方法就是 exec 命令,通過指定命令的絕對路徑來執行,但同樣存在問題,經測驗發現,exec 只能通過指定init命令的絕對路徑繼續啟動,但無法執行reboot重啟,以下是我的猜測:在bash下,進入到/sbin中,執行ls -al | grep "init" 以及替換成reboot 會發現,init指向的是/lib/systemd/systemd,而reboot指向的則是/bin/systemctl

在默認bash的環境下,因為環境變數的缺少,無法通過systemctl管理服務,導致reboot無法執行,因為reboot命令是systemctl的鏈接,但可以執行init,通過systemd來繼續啟動系統,正常開機驗證一下,發現開機后是可以通過reboot的路徑,使用exec正常執行的,這是我的猜測,是否正確需要以后通過了解linux啟動程序和服務管理在確定,
但這里還存在一個問題,如果之前為了節省時間,沒有創建.autorelabel的話,此時就需要再次手動重啟并添加enforcing=0來啟動,否則也無法使用新密碼開機,所以如果使用指定bash方式修改密碼,最好還是添加relabel,
雜談
一.SElinux在initramfs時,是未運行的,
SElinux是linux內核中的一些模塊,但此時內核也沒有加載啟動,自然就不會啟動SElinux的相關行程,這時候使用命令修改SElinux的狀態等操作,也是無意義的,
二.禁用或者許可模式下修改密碼,不會出現背景關系問題,
前面說了,密碼失效是因為開機時強制執行SElinux策略,但是如果SElinux已經被調整為禁用或者許可模式,那自然不會有任何阻攔,但redhat不建議徹底禁用SElinux,因為許可模式同樣滿足我們的需求,而且會把一些例外行為記錄下來,方便以后恢復強制模式時排錯,
三.為什么不使用GRUB選單中提供的緊急模式
緊急模式同樣需要密碼才可以進入
四.在修改開機啟動專案時,如果將此行中“ro”改為“rw”,再次引導重啟時,根節點直接就會是可讀寫,不需要再掛載一次
涉及到的命令
1. rd.break:我沒有查到這樣一條命令,但是有人說這里rd部分表示初始化虛擬記憶體盤,就是把initramfs解壓到記憶體中并掛載為rootfs/這部分操作,沒錯,這部分還沒有到硬碟,檔案系統也是運行在記憶體中的,就是指的虛擬記憶體硬碟(ramdisk),在這里給出一條break指令,那自然就是掛載后中斷,不在繼續進行,
2. mount:用于掛載檔案系統,
格式:mount [-lhV]mount -a [-fFnrsvw] [-t vfstype ] [-O optlist ]mount [-fnrsvw] [-o options [,...]] device | dir mount [-fnrsvw] [-t vfstype ] [-o options ] device dir
描述:Unix 系統中,所有可以存取的檔案都被組織為一個很大的樹形結構,稱為檔案層次結構 (file hierarchy),以 /為根,這些檔案可以分布在多個設備上, mount命令用作將設備上的檔案系統掛接到這個樹形結構上,
用到的選項:-o: 用來指定后面跟著的掛載項,
remount:試圖重新掛載一個已經掛載的檔案系統,這個選項通常用于改變檔案系統的掛載標志,尤其是使一個只讀檔案系統變為可讀寫,它不會改變設備或者掛載點,
rw:掛載檔案系統為可讀/寫,
這里使用了逗號連接 -o 后面的兩個掛載項 remount以及rw
3. chroot:run command or interactive shell with special root directory,用特殊的根運行命令或者運行互動式shell,切換跟,
格式:chroot [OPTION] NEWROOT [COMMAND [ARG]...]
chroot OPTION
描述:在根目錄或者切換到新的根運行命令.
用到的選項:無
4. touch:主要有兩個作用,這里主要用到的是創建檔案的功能,但是原文這里是:touch - change file timestamps(修改檔案時間戳)
格式:touch [OPTION]... FILE...
描述:將每個檔案的訪問和修改時間更新為當前時間,不存在的檔案引數將被創建為空,除非提供了-c(--no-create 不創建任何檔案)或-h,(--no-dereference 只影響符號鏈接本身,而非符號鏈接所指示的目的地(當系統支持更改符號鏈接的所有者時,此選項才有用))
用到的選項:無
5. echo:輸出一行文本
格式:echo [SHORT-OPTION]... [STRING]...
echo LONG-OPTION
描述:將字串回顯到標準輸出,
用到的選項:無,直接文本,這里直接手動輸入新密碼,當作標準輸出,通過管道符 | 傳遞給后面的passwd
6. passwd:更新用戶身份認證令牌,就是改密碼
格式:passwd [-k] [-l] [-u [-f]] [-d] [-e] [-n mindays] [-x maxdays] [-w warndays] [-i inactivedays] [-S] [--stdin] [username]
描述:passwd實用程式用于更新用戶的身份驗證令牌,這個任務是通過呼叫linuxpam和Libuser API來實作的,本質上,它使用Linux PAM將自身初始化為“passwd”服務,并利用配置的密碼模塊進行身份驗證,然后更新用戶的密碼,
用到的選項:--stdin:此選項用于指示passwd應該從標準輸入(可以是管道)讀取新密碼,
7. restorecon:還原檔案的默認SELinux安全背景關系,就是修復
格式:restorecon [-R] [-n] [-p] [-v] [-e directory] pathname...
restorecon -f infilename [-e directory] [-R] [-n] [-p] [-v] [-F]
描述:此程式主要用于設定一個或多個檔案的安全背景關系(擴展屬性),它還可以在任何其他時間運行以更正不一致的標簽,添加對新安裝的策略的支持,或者使用-n選項被動地檢查檔案背景關系是否都已設定由活動策略指定(默認行為),
用到的選項:修復檔案夾則至少添加-R
8. setenforce:修改SELinux正在運行的模式,
格式:setenforce [Enforcing|Permissive|1|0]
描述:使用強制或1將SELinux置于強制模式,使用Permissive或0將SELinux置于Permissive模式,
用到的選項:自己選擇合適的,
9. getenforce:獲取SELinux的當前模式
格式:getenforce
描述:報告SELinux是強制、許可還是禁用,
用到的選項:無
10.exec:呼叫并執行指定命令
格式:exec (選項) (引數)
描述:用于呼叫并執行指令的命令,通常用于shell腳本中呼叫其他命令,如果在當前終端中執行,則當前指定的命令執行完畢后會立即退出終端
用到的選項:無
參考檔案
- Redhat官方檔案修改密碼介紹: Chapter 9. Changing and resetting the root passwor(redhat.com)
- Redhat官方檔案修改SElinux狀態介紹:在啟動時更改 SELinux 模式 (redhat.com)
- 知乎文章-重置密碼:Reset RHEL root密碼 - 知乎(zhihu.com)
- 評論區有人講了下shadow檔案相關的問題:RHEL7: Interrupt the boot process in order to gain access to a system. - CertDepot
- 大概說了下switch_root模式:switch_root 命令_lbaihao的專欄-CSDN博客
- 切換跟的方式的簡介: chroot,pivot_root和switch_root 區別_u012385733的專欄-CSDN博客
- 為何不使用系統提供的緊急模式:[QUESTION] rd.break vs emergency.target : redhat (reddit.com)
- 簡述linux終端、虛擬終端、控制臺:linux下 console ,tty 和tty0有什么區別!_驃姚校尉的博客-CSDN博客
- console=tty*的含義:uboot傳遞引數'console=ttyXXX'的作用 - _小百 - 博客園 (cnblogs.com)
- 使用單用戶模式修改密碼的方式: CentOS7單用戶模式修改密碼_從入門到放棄-CSDN博客
- 另一篇rd.break流程,大同小異: How To Reset Root User Password In CentOS/RHEL 7 (rootusers.com)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/247910.html
標籤:Linux
上一篇:計劃任務
下一篇:ThreadX應用筆記:內核初始化和任務調度