亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

linux chroot命令詳解

 更新時(shí)間:2018年03月16日 11:01:23   作者:sparkdev  
這篇文章主要介紹了linux chroot命令詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

chroot,即 change root directory (更改 root 目錄)。在 linux 系統(tǒng)中,系統(tǒng)默認(rèn)的目錄結(jié)構(gòu)都是以 /,即以根 (root) 開始的。而在使用 chroot 之后,系統(tǒng)的目錄結(jié)構(gòu)將以指定的位置作為 / 位置。

基本語法

chroot NEWROOT [COMMAND [ARG]...]

具體用法請(qǐng)參考本文的 demo。

為什么要使用 chroot 命令

增加了系統(tǒng)的安全性,限制了用戶的權(quán)力:

在經(jīng)過 chroot 之后,在新根下將訪問不到舊系統(tǒng)的根目錄結(jié)構(gòu)和文件,這樣就增強(qiáng)了系統(tǒng)的安全性。一般會(huì)在用戶登錄前應(yīng)用 chroot,把用戶的訪問能力控制在一定的范圍之內(nèi)。

建立一個(gè)與原系統(tǒng)隔離的系統(tǒng)目錄結(jié)構(gòu),方便用戶的開發(fā):

使用 chroot 后,系統(tǒng)讀取的是新根下的目錄和文件,這是一個(gè)與原系統(tǒng)根下文件不相關(guān)的目錄結(jié)構(gòu)。在這個(gè)新的環(huán)境中,可以用來測(cè)試軟件的靜態(tài)編譯以及一些與系統(tǒng)不相關(guān)的獨(dú)立開發(fā)。

切換系統(tǒng)的根目錄位置,引導(dǎo) Linux 系統(tǒng)啟動(dòng)以及急救系統(tǒng)等:

chroot 的作用就是切換系統(tǒng)的根位置,而這個(gè)作用最為明顯的是在系統(tǒng)初始引導(dǎo)磁盤的處理過程中使用,從初始 RAM 磁盤 (initrd) 切換系統(tǒng)的根位置并執(zhí)行真正的 init,本文的最后一個(gè) demo 會(huì)詳細(xì)的介紹這種用法。

通過 chroot 運(yùn)行 busybox 工具

busybox 包含了豐富的工具,我們可以把這些工具放置在一個(gè)目錄下,然后通過 chroot 構(gòu)造出一個(gè) mini 系統(tǒng)。簡(jiǎn)單起見我們直接使用 docker 的 busybox 鏡像打包的文件系統(tǒng)。先在當(dāng)前目錄下創(chuàng)建一個(gè)目錄 rootfs:

$ mkdir rootfs

然后把 busybox 鏡像中的文件釋放到這個(gè)目錄中:

$ (docker export $(docker create busybox) | tar -C rootfs -xvf -)

通過 ls 命令查看 rootfs 文件夾下的內(nèi)容:

$ ls rootfs

萬事俱備,讓我們開始吧!

執(zhí)行 chroot 后的 ls 命令

$ sudo chroot rootfs /bin/ls

雖然輸出結(jié)果與剛才執(zhí)行的 ls rootfs 命令形同,但是這次運(yùn)行的命令卻是 rootfs/bin/ls。

運(yùn)行 chroot 后的 pwd 命令

$ sudo chroot rootfs /bin/pwd

哈,pwd 命令真把 rootfs 目錄當(dāng)根目錄了!

不帶命令執(zhí)行 chroot

$ sudo chroot rootfs

這次出錯(cuò)了,因?yàn)檎也坏?/bin/bash。我們知道 busybox 中是不包含 bash 的,但是 chroot 命令為什么會(huì)找 bash 命令呢? 原來,如果不給 chroot 指定執(zhí)行的命令,默認(rèn)它會(huì)執(zhí)行 '${SHELL} -i',而我的系統(tǒng)中 ${SHELL} 為 /bin/bash。

既然 busybox 中沒有 bash,我們只好指定 /bin/sh 來執(zhí)行 shell 了。

$ sudo chroot rootfs /bin/sh

運(yùn)行 sh 是沒有問題的,并且我們打印出了當(dāng)前進(jìn)程的 PID。

檢查程序是否運(yùn)行在 chroot 環(huán)境下

雖然我們做了好幾個(gè)實(shí)驗(yàn),但是肯定會(huì)有朋友心存疑問,怎么能證明我們運(yùn)行的命令就是在 chroot 目錄后的路徑中呢?
其實(shí),我們可以通過 /proc 目錄下的文件檢查進(jìn)程的中的根目錄,比如我們可以通過下面的代碼檢查上面運(yùn)行的 /bin/sh 命令的根目錄(請(qǐng)?jiān)诹硗庖粋€(gè) shell 中執(zhí)行):

$ pid=$(pidof -s sh)
$ sudo ls -ld /proc/$pid/root

輸出中的內(nèi)容明確的指出 PID 為 46644 的進(jìn)程的根目錄被映射到了 /tmp/rootfs 目錄。

通過代碼理解 chroot 命令

下面我們嘗試自己實(shí)現(xiàn)一個(gè) chroot 程序,代碼中涉及到兩個(gè)函數(shù),分別是 chroot() 函數(shù)和 chdir() 函數(shù),其實(shí)真正的 chroot 命令也是通過調(diào)用它們實(shí)現(xiàn)的:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
 
int main(int argc, char *argv[])
{
  if(argc<2){
    printf("Usage: chroot NEWROOT [COMMAND...] \n");
    return 1;
  }

  if(chroot(argv[1])) {
    perror("chroot");
    return 1;
  }
 
  if(chdir("/")) {
    perror("chdir");
    return 1;
  }
 
  if(argc == 2) {
    // hardcode /bin/sh for my busybox tools.
    argv[0] = (char *)"/bin/sh";
 
    argv[1] = (char *) "-i";
    argv[2] = NULL;
  } else {
    argv += 2;
  }
 
  execvp (argv[0], argv);
  printf("chroot: cannot run command `%s`\n", *argv);
 
  return 0;
}

把上面的代碼保存到文件 mychroot.c 文件中,并執(zhí)行下面的命令進(jìn)行編譯:

$ gcc -Wall mychroot.c -o mychroot

mychroot 的用法和 chroot 基本相同:

$ sudo ./mychroot ./rootfs

特別之處是我們的 mychroot 在沒有傳遞命令的情況下執(zhí)行了 /bin/sh,原因當(dāng)然是為了支持我們的 busybox 工具集,筆者在代碼中 hardcode 了默認(rèn)的 shell:

argv[0] = (char *)"/bin/sh";

從代碼中我們也可以看到,實(shí)現(xiàn) chroot 命令的核心邏輯其實(shí)并不復(fù)雜。

實(shí)例:通過 chroot 重新設(shè)置 root 密碼

忘記了 root 密碼該怎么辦?接下來的 demo 將演示如何通過 chroot 命令重新設(shè)置 centos7 中被忘記了的 root 密碼。
systemd 的管理機(jī)制中,rescure 模式和 emeryency 模式是無法直接取得 root 權(quán)限的,需要使用 root 密碼才能進(jìn)入 rescure 和 emeryency 環(huán)境。所以我們需要通過其他方式來設(shè)置 root 密碼。我們可以為內(nèi)核的啟動(dòng)指定 "rd.break" 參數(shù),從而讓系統(tǒng)在啟動(dòng)的早期停下來,此時(shí)我們可以通過使用 root 權(quán)限并結(jié)合 chroot 命令完成設(shè)置 root 密碼的操作。下面我們一起來看具體的操作過程。

在系統(tǒng)啟動(dòng)過程中進(jìn)入開機(jī)菜單時(shí)按下字母鍵 e 進(jìn)程開機(jī)菜單的編輯模式:

這就是系統(tǒng)的開機(jī)菜單,按下 e 后進(jìn)入編輯界面:

找到以 "linux16 /vmlinuz-" 開頭的行。如果默認(rèn)沒有看到該行,需要按向下鍵把它滾動(dòng)出來。
然后定位到該行結(jié)尾處,輸入一個(gè)空格和字符串 "rd.break",如下圖所示:

接著按下 ctrl + x 以該設(shè)置繼續(xù)啟動(dòng),啟動(dòng)過程中操作系統(tǒng)會(huì)停下來,這是系統(tǒng)啟動(dòng)過程中的一個(gè)非常早的時(shí)間點(diǎn):

所以系統(tǒng)的根目錄還掛載在 RAM disk 上(就是內(nèi)存中的一個(gè)文件系統(tǒng)),我們可以通過 mount 命令檢查系統(tǒng)當(dāng)前掛載的文件系統(tǒng),下面是我們比較關(guān)心的兩條:

上圖中 mount 命令輸出的第一行說明此時(shí)的根目錄在一個(gè) RAM disk 中, 即 rootfs。
圖中輸出的第二行說明我們的文件系統(tǒng)此時(shí)被掛載到了 /sysroot 目錄,并且是只讀的模式:

復(fù)制代碼 代碼如下:
/dev/mapper/centos-root on /sysroot type xfs (ro,relatime,attr2,inode64,noquota)

而在我們正常登陸系統(tǒng)的情況下,系統(tǒng)根目錄的掛載情況如下:

復(fù)制代碼 代碼如下:
/dev/mapper/centos-root on / type xfs (rw,relatime,seclabel,attr2,inode64,noquota)

該時(shí)間點(diǎn)的最大優(yōu)勢(shì)是我們具有 root 權(quán)限!所以讓我們開始設(shè)置新的 root 密碼吧。

先通過下面的命令把 /sysroot 重新掛載為可讀寫的模式:

switch_root:/# mount -o remount,rw /sysroot

然后用下面 chroot 命令把根目錄切換到我們?cè)瓉淼沫h(huán)境中:

switch_root:/# chroot /sysroot

此時(shí)可以理解為:我們以 root 權(quán)限登錄了原來的系統(tǒng),修改密碼就很容易了!用下面的命令為 root 用戶設(shè)置新的密碼:

sh-4.2# echo "new_root_pw" | passwd --stdin root

接下來還要處理 SELinux 相關(guān)的問題。由于當(dāng)前的環(huán)境中 SELinux 并未啟動(dòng),所以我們對(duì)文件的修改可能造成文件的 context 不正確。為了確保開機(jī)時(shí)重新設(shè)定 SELinux context,必須在根目錄下添加隱藏文件 .autorelabel:

sh-4.2# touch /.autorelabel

最后從 chroot 中退出,并重啟系統(tǒng):

sh-4.2# exit
switch_root:/# reboot

重新進(jìn)入登陸界面時(shí)就可以使用剛才設(shè)置的密碼以 root 登陸了!

總結(jié)

chroot 是一個(gè)很有意思的命令,我們可以用它來簡(jiǎn)單的實(shí)現(xiàn)文件系統(tǒng)的隔離。但在一個(gè)容器技術(shù)繁榮的時(shí)代,用 chroot 來進(jìn)行資源的隔離實(shí)在是 low 了點(diǎn)。所以 chroot 的主要用途還是集中在系統(tǒng)救援、維護(hù)等一些特殊的場(chǎng)景中。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論