Ubuntu - dapatkah pengguna non-root menjalankan proses di chroot jail?

18

Apakah mungkin bagi pengguna non-root untuk menjalankan proses chroot di Ubuntu?

Hawkeye
sumber
Utas FreeBSD lama ini mencakup pertanyaan yang sama: lists.freebsd.org/pipermail/freebsd-security/2003-April/… Jawaban singkat: Tidak, Anda tidak dapat menjalankan proses sebagai root di dalam chroot jail non-root.
David Harrison
penjara chroot khusus untuk bsd. chroot di linux bukan penjara. Terakhir saya periksa tidak mungkin chroot sebagai pengguna.
xenoterracide
1
@xenoterracide Jail adalah spesifik BSD, tetapi chroot umumnya dikenal sebagai "chroot jail" di komunitas Linux. Cukup membingungkan.
pehrs
2
Apa yang Anda coba lakukan dan mengapa? Ada alat seperti fakechroot, dan schroot yang membuat menyediakan alternatif yang bisa diterapkan tergantung pada kebutuhan Anda.
Zoredache
Ada juga diskusi yang lebih terkait di Bagaimana cara "memenjarakan" suatu proses tanpa menjadi root? dengan lebih banyak pendekatan kerja atau tentatif untuk menyelesaikan tugas ini terdaftar.
imz - Ivan Zakharyaschev

Jawaban:

12

Di Linux chroot (2) system call hanya dapat dilakukan oleh proses yang diistimewakan. Kemampuan yang dibutuhkan proses adalah CAP_SYS_CHROOT.

Alasan Anda tidak dapat melakukan chroot sebagai pengguna sangat sederhana. Asumsikan Anda memiliki program setuid seperti sudo yang memeriksa / etc / sudoers jika Anda diizinkan untuk melakukan sesuatu. Sekarang letakkan di chroot chroot dengan / etc / sudoers Anda sendiri. Tiba-tiba Anda mengalami peningkatan hak istimewa instan.

Dimungkinkan untuk merancang program untuk chroot sendiri dan menjalankannya sebagai proses setuid, tetapi ini umumnya dianggap desain yang buruk. Keamanan ekstra chroot tidak memotivasi masalah keamanan dengan setuid.

pehrs
sumber
3
Dengan kemungkinan namespace baru di linux, mungkin dimungkinkan untuk membuat (unshare) namespace "pengguna" baru, di mana akan ada pengguna root "tertanam", dan melakukan chrootitu.
imz - Ivan Zakharyaschev
1
@ imz - IvanZakharyaschev Anda benar sekali, dan saya harap Anda tidak keberatan saya mengambil kebebasan menulis itu sebagai jawaban yang mudah diuji.
hvd
@ hvd Hebat! Itu pasti sangat berguna, karena menunjukkan bagaimana menggunakan fitur-fitur Linux baru yang tidak dikenal dengan perintah konkret.
imz - Ivan Zakharyaschev
6

@ imz - IvanZakharyaschev mengomentari jawaban pehrs bahwa dimungkinkan dengan pengenalan ruang nama, tetapi ini belum diuji dan diposting sebagai jawaban. Ya, itu memang memungkinkan pengguna non-root menggunakan chroot.

Diberi tautan-statis dash, dan tautan-terhubung-statis busybox, serta bashshell yang berjalan sebagai non-root:

$ mkdir root
$ cp /path/to/dash root
$ cp /path/to/busybox root
$ unshare -r bash -c 'chroot root /dash -c "/busybox ls -al /"'
total 2700
drwxr-xr-x    2 0        0             4096 Dec  2 19:16 .
drwxr-xr-x    2 0        0             4096 Dec  2 19:16 ..
drwxr-xr-x    1 0        0          1905240 Dec  2 19:15 busybox
drwxr-xr-x    1 0        0           847704 Dec  2 19:15 dash

ID pengguna root di namespace itu dipetakan ke ID pengguna non-root di luar namespace itu, dan sebaliknya, itulah sebabnya sistem menunjukkan file yang dimiliki oleh pengguna saat ini yang dimiliki oleh ID pengguna 0. Sebuah reguler ls -al root, tanpa unshare, tidak perlihatkan mereka sebagai milik pengguna saat ini.


Catatan: diketahui bahwa proses yang dapat digunakan chroot, mampu keluar dari a chroot. Karena unshare -rakan memberikan chrootizin kepada pengguna biasa, itu akan menjadi risiko keamanan jika diizinkan di dalam chrootlingkungan. Memang, itu tidak diizinkan, dan gagal dengan:

unshare: unshare gagal: Operasi tidak diizinkan

yang cocok dengan dokumentasi unshare (2) :

EPERM (sejak Linux 3.9)

CLONE_NEWUSER ditentukan dalam flag dan penelepon berada di lingkungan chroot (yaitu direktori root pemanggil tidak cocok dengan direktori root dari mount namespace di mana ia berada).

hvd
sumber
Menjalankan pivot_root di mount namespace memiliki efek yang mirip dengan chroot tetapi menghindari konflik dengan ruang nama pengguna.
Timothy Baldwin
1
Seseorang dapat keluar dari chroot atau me-mount namespace dengan turun ke / proc jika itu adalah proses di luar dengan UID yang sama di PID anak yang sama atau ruang nama pengguna.
Timothy Baldwin
2

Saat ini, Anda ingin melihat LXC (Linux Containers) alih-alih penjara chroot / BSD. Itu ada di suatu tempat antara chroot dan mesin virtual, memberi Anda banyak kontrol keamanan dan konfigurasi umum. Saya percaya semua yang Anda butuhkan untuk menjalankannya sebagai pengguna adalah menjadi anggota grup yang memiliki file / perangkat yang diperlukan, tetapi mungkin juga ada kemampuan / izin sistem yang terlibat. Either way, itu harus sangat bisa dilakukan, karena LXC cukup baru, lama setelah SELinux dll ditambahkan ke kernel Linux.

Juga, ingatlah bahwa Anda hanya dapat menulis skrip sebagai root tetapi memberikan izin aman kepada pengguna untuk menjalankan skrip tersebut (tanpa kata sandi jika Anda suka, tetapi pastikan skrip aman) menggunakan sudo.

Lee B
sumber
1

Kombinasi fakeroot / fakechroot memberikan simultan chroot untuk kebutuhan sederhana seperti memproduksi arsip tar di mana file tampaknya dimiliki oleh root. Halaman manual Fakechroot adalah http://linux.die.net/man/1/fakechroot .

Anda tidak mendapatkan izin baru, tetapi jika Anda memiliki direktori (mis. Distro palsu) sebelum memohon

fakechroot fakeroot chroot ~/fake-distro some-command

sekarang cari beberapa perintah seperti Anda root dan memiliki semuanya dalam distro-palsu.

sylvainulg
sumber
Ini adalah ide yang bagus, tetapi tampaknya menangani symlink tidak terduga. Saya ~/fake-distromenggunakan busybox, yang menghubungkan ls, mvdan utilitas umum lainnya /bin/busybox. Jika saya secara eksplisit menelepon /bin/busybox mv ..., semuanya berfungsi, tetapi jika saya menelepon /bin/mv ...saya dapat sh: /bin/mv: not found. Pengaturan export FAKECHROOT_EXCLUDE_PATH=/sebelum menjalankan fakechroot memperbaiki gejala itu, tetapi kemudian rusak pada symlink lain (misalnya /usr/bin/vim -> /usr/bin/vim.vim).
Ponkadoodle
mungkin FAKECHROOT_EXCLUDE_PATH = /: / usr akan membantu?
sylvainulg
1

Tampaknya dengan ruang nama pengguna sebenarnya memungkinkan untuk melakukan chroot tanpa root. Berikut adalah contoh program yang menunjukkan bahwa itu mungkin. Saya baru mulai mengeksplorasi bagaimana ruang nama linux bekerja dan jadi saya tidak sepenuhnya yakin apakah kode ini praktik terbaik atau tidak.

Simpan sebagai user_chroot.cc. Kompilasi dengan g++ -o user_chroot user_chroot.cc. Penggunaan adalah ./user_chroot /path/to/new_rootfs.

// references:
// [1]: http://man7.org/linux/man-pages/man7/user_namespaces.7.html
// [2]: http://man7.org/linux/man-pages/man2/unshare.2.html

#include <sched.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <cerrno>
#include <cstdio>
#include <cstring>

int main(int argc, char** argv) {
    if(argc < 2) {
        printf("Usage: %s <rootfs>\n", argv[0]);
    }

    int uid = getuid();
    int gid = getgid();
    printf("Before unshare, uid=%d, gid=%d\n", uid, gid);

    // First, unshare the user namespace and assume admin capability in the
    // new namespace
    int err = unshare(CLONE_NEWUSER);
    if(err) {
        printf("Failed to unshare user namespace\n");
        return 1;
    }

    // write a uid/gid map
    char file_path_buf[100];
    int pid = getpid();
    printf("My pid: %d\n", pid);

    sprintf(file_path_buf, "/proc/%d/uid_map", pid);
    int fd = open(file_path_buf, O_WRONLY);
    if(fd == -1) {
        printf("Failed to open %s for write [%d] %s\n", file_path_buf, errno, 
               strerror(errno));
    } else {
        printf("Writing : %s (fd=%d)\n", file_path_buf, fd);
        err = dprintf(fd, "%d %d 1\n", uid, uid);
        if(err == -1) {
            printf("Failed to write contents [%d]: %s\n", errno, 
                   strerror(errno));
        }
        close(fd);
    }

    sprintf(file_path_buf, "/proc/%d/setgroups", pid);
    fd = open(file_path_buf, O_WRONLY);
    if(fd == -1) {
        printf("Failed to open %s for write [%d] %s\n", file_path_buf, errno, 
               strerror(errno));
    } else {
        dprintf(fd, "deny\n");
        close(fd);
    }

    sprintf(file_path_buf, "/proc/%d/gid_map", pid);
    fd = open(file_path_buf, O_WRONLY);
    if(fd == -1) {
        printf("Failed to open %s for write [%d] %s\n", file_path_buf, errno, 
               strerror(errno));
    } else {
        printf("Writing : %s (fd=%d)\n", file_path_buf, fd);
        err = dprintf(fd, "%d %d 1\n", gid, gid);
        if(err == -1) {
            printf("Failed to write contents [%d]: %s\n", errno, 
                   strerror(errno));
        }
        close(fd);
    }

    // Now chroot into the desired directory
    err = chroot(argv[1]);
    if(err) {
        printf("Failed to chroot\n");
        return 1;
    }

    // Now drop admin in our namespace
    err = setresuid(uid, uid, uid);
    if(err) {
        printf("Failed to set uid\n");
    }

    err = setresgid(gid, gid, gid);
    if(err) {
        printf("Failed to set gid\n");
    }

    // and start a shell
    char argv0[] = "bash";
    char* new_argv[] = {
        argv0,
        NULL
    };

    err = execvp("/bin/bash", new_argv);
    if(err) {
        perror("Failed to start shell");
        return -1;
    }
}

Saya telah menguji ini pada rootf minimal yang dihasilkan dengan multistrap (dieksekusi sebagai non-root). Beberapa file sistem suka /etc/passwddan /etc/groupsdisalin dari host rootfs ke rootf tamu.

cheshirekow
sumber
Gagal Failed to unshare user namespaceuntuk saya di linux 4.12.10 (Arch Linux).
Ponkadoodle
@wallacoloo mungkin memodifikasi printf () menjadi perror () dan melihat apa kesalahan sebenarnya. lihat man7.org/linux/man-pages/man2/unshare.2.html untuk mengetahui kode kesalahan apa yang dihasilkan dari unsharepanggilan yang gagal . Anda juga dapat mencoba versi python ini yang mungkin memiliki pesan kesalahan yang lebih baik: github.com/cheshirekow/uchroot
cheshirekow
1
Sebenarnya @wallacoloo sepertinya lengkung menonaktifkan ruang nama pengguna yang tidak dirahasiakan
cheshirekow
0

Tidak. Jika saya mengingat dengan benar ada beberapa hal tingkat kernel yang chroot lakukan yang mencegahnya. Saya tidak ingat benda apa itu. Saya menyelidiki kembali ketika mengacaukan dengan alat Catalyst Build Gentoo (dan chroot pada gentoo sama dengan chroot di ubuntu). Meskipun mungkin untuk mewujudkannya tanpa sandiwara ... tetapi hal-hal seperti itu diserahkan pada bidang kerentanan keamanan potensial dan memastikan Anda tahu apa yang Anda lakukan.

xenoterracide
sumber