as cadeias chroot são específicas para o bsd. um chroot no linux não é uma prisão. Por último, verifiquei que não era possível fazer chroot como usuário.
Xenoterracide
11
As cadeias do @xenoterracide são específicas do BSD, mas o chroot é comumente conhecido como "chroot jail" na comunidade Linux. Está bastante confuso.
Pehrs
2
O que você está tentando fazer e por quê? Existem ferramentas como fakechroot e schroot que fornecem uma alternativa viável, dependendo de seus requisitos.
No Linux, a chamada do sistema chroot (2) pode ser feita apenas por um processo privilegiado. A capacidade que o processo precisa é CAP_SYS_CHROOT.
O motivo pelo qual você não pode chroot como usuário é bastante simples. Suponha que você tenha um programa setuid, como o sudo, que verifique / etc / sudoers se tiver permissão para fazer alguma coisa. Agora coloque-o em um chroot chroot com seus próprios / etc / sudoers. De repente, você tem uma escalada instantânea de privilégios.
É possível projetar um programa para fazer chroot e executá-lo como um processo setuid, mas isso geralmente é considerado um design ruim. A segurança extra do chroot não motiva os problemas de segurança com o setuid.
Com as novas possibilidades de espaços para nome no linux, talvez seja possível criar (descompartilhar) um novo espaço para nome "usuário", onde haveria um usuário raiz "incorporado" e executá chroot-lo.
IMZ - Ivan Zakharyaschev
11
@ imz - IvanZakharyaschev Você está absolutamente correto, e espero que você não se importe que eu tenha tido a liberdade de escrever isso como uma resposta facilmente testável.
hvd
@hvd Ótimo! Deve ser muito útil, pois demonstra como usar os novos recursos desconhecidos do Linux com comandos concretos.
imz - Ivan Zakharyaschev 3/04/14
6
@ imz - IvanZakharyaschev comenta a resposta dos pehrs de que pode ser possível com a introdução de namespaces, mas isso não foi testado e publicado como resposta. Sim, isso realmente possibilita que um usuário não root use chroot.
Dado um shell estaticamente vinculado dashe estaticamente vinculado busyboxe um bashshell em execução como não raiz:
O ID de usuário root em que namespace é mapeado para o não-ID de usuário root fora desse espaço de nomes, e vice-versa, razão pela qual os arquivos mostra o sistema de propriedade do usuário atual como propriedade da ID de usuário 0. Um regular ls -al root, sem unshare, faz mostre-os como pertencentes ao usuário atual.
Nota: é sabido que os processos capazes de usar chrootsão capazes de romper a chroot. Como unshare -rconcederia chrootpermissões a um usuário comum, seria um risco de segurança se isso fosse permitido dentro de um chrootambiente. Na verdade, não é permitido e falha com:
CLONE_NEWUSER foi especificado em sinalizadores e o chamador está em um ambiente chroot (ou seja, o diretório raiz do chamador não corresponde ao diretório raiz do espaço para nome da montagem em que reside).
A execução de pivot_root em um namespace de montagem tem um efeito semelhante ao chroot, mas evita o conflito com os namespaces do usuário.
Timothy Baldwin
11
Pode-se escapar de um espaço para nome chroot ou montar descendo para / proc se for um processo externo com o mesmo UID no mesmo ou no PID filho ou em espaços de nomes de usuário.
Timothy Baldwin
2
Hoje em dia, você quer ver o LXC (Linux Containers) em vez da prisão chroot / BSD. Está entre um chroot e uma máquina virtual, oferecendo muito controle de segurança e configurabilidade geral. Acredito que tudo o que você precisa para executá-lo como usuário é ser um membro do grupo que possui os arquivos / dispositivos necessários, mas também pode haver recursos / permissões do sistema envolvidas. De qualquer forma, deve ser muito factível, já que o LXC é bastante recente, muito tempo depois que o SELinux etc. foi adicionado ao kernel do Linux.
Além disso, lembre-se de que você pode escrever scripts como root, mas conceder aos usuários permissão segura para executá-los (sem uma senha, se desejar, mas verifique se o script está seguro) usando o sudo.
A combinação de fakeroot / fakechroot fornece um simulacro de chroot para necessidades simples, como a produção de arquivos tar onde os arquivos parecem pertencer à raiz. A página de manual do Fakechroot é http://linux.die.net/man/1/fakechroot .
Você não recebe nenhuma nova permissão, mas se possui um diretório (por exemplo, fake-distro) antes de chamar
É uma boa idéia, mas parece manipular os links simbólicos de maneira imprevisível. Meu ~/fake-distrousos busybox, que links simbólicos ls, mve outros utilitários comuns a /bin/busybox. Se eu ligar explicitamente /bin/busybox mv ..., as coisas funcionam, mas se eu ligar, /bin/mv ...eu atendo sh: /bin/mv: not found. A configuração export FAKECHROOT_EXCLUDE_PATH=/antes de executar o fakechroot corrige esse sintoma, mas depois quebra em outros links simbólicos (por exemplo /usr/bin/vim -> /usr/bin/vim.vim).
Parece que, com espaços de nome de usuário, é possível chroot sem raiz. Aqui está um exemplo de programa que demonstra que é possível. Eu apenas comecei a explorar como os namespaces do linux funcionam e, portanto, não tenho certeza se esse código é uma prática recomendada ou não.
Salvar como user_chroot.cc. Compile com g++ -o user_chroot user_chroot.cc. O uso é ./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;
}
}
Eu testei isso em um rootfs mínimo gerado com multistrap (executado como não raiz). Alguns arquivos do sistema gostam /etc/passwde /etc/groupsforam copiados dos rootfs do host para os rootfs convidados.
Falha em Failed to unshare user namespacemim no linux 4.12.10 (Arch Linux).
Ponkadoodle 08/09
@wallacoloo talvez modifique printf () para perror () e veja qual foi o erro real. consulte man7.org/linux/man-pages/man2/unshare.2.html para saber quais códigos de erro podem resultar de uma unsharechamada malsucedida . Você também pode tentar esta versão python que poderia ter melhor de mensagens de erro: github.com/cheshirekow/uchroot
Não. Se bem me lembro, existe algo no nível do kernel que o chroot faz que impede. Não me lembro o que era aquilo. Eu o investiguei ao mexer com a ferramenta Catalyst Build do Gentoo (e um chroot no gentoo é o mesmo que um chroot no ubuntu). Embora seja possível fazer isso sem uma senha ... mas essas coisas são deixadas para o domínio de possíveis vulnerabilidades de segurança e para garantir que você saiba o que está fazendo.
Respostas:
No Linux, a chamada do sistema chroot (2) pode ser feita apenas por um processo privilegiado. A capacidade que o processo precisa é CAP_SYS_CHROOT.
O motivo pelo qual você não pode chroot como usuário é bastante simples. Suponha que você tenha um programa setuid, como o sudo, que verifique / etc / sudoers se tiver permissão para fazer alguma coisa. Agora coloque-o em um chroot chroot com seus próprios / etc / sudoers. De repente, você tem uma escalada instantânea de privilégios.
É possível projetar um programa para fazer chroot e executá-lo como um processo setuid, mas isso geralmente é considerado um design ruim. A segurança extra do chroot não motiva os problemas de segurança com o setuid.
fonte
chroot
-lo.@ imz - IvanZakharyaschev comenta a resposta dos pehrs de que pode ser possível com a introdução de namespaces, mas isso não foi testado e publicado como resposta. Sim, isso realmente possibilita que um usuário não root use chroot.
Dado um shell estaticamente vinculado
dash
e estaticamente vinculadobusybox
e umbash
shell em execução como não raiz:O ID de usuário root em que namespace é mapeado para o não-ID de usuário root fora desse espaço de nomes, e vice-versa, razão pela qual os arquivos mostra o sistema de propriedade do usuário atual como propriedade da ID de usuário 0. Um regular
ls -al root
, semunshare
, faz mostre-os como pertencentes ao usuário atual.Nota: é sabido que os processos capazes de usar
chroot
são capazes de romper achroot
. Comounshare -r
concederiachroot
permissões a um usuário comum, seria um risco de segurança se isso fosse permitido dentro de umchroot
ambiente. Na verdade, não é permitido e falha com:que corresponde à documentação não compartilhada (2) :
fonte
Hoje em dia, você quer ver o LXC (Linux Containers) em vez da prisão chroot / BSD. Está entre um chroot e uma máquina virtual, oferecendo muito controle de segurança e configurabilidade geral. Acredito que tudo o que você precisa para executá-lo como usuário é ser um membro do grupo que possui os arquivos / dispositivos necessários, mas também pode haver recursos / permissões do sistema envolvidas. De qualquer forma, deve ser muito factível, já que o LXC é bastante recente, muito tempo depois que o SELinux etc. foi adicionado ao kernel do Linux.
Além disso, lembre-se de que você pode escrever scripts como root, mas conceder aos usuários permissão segura para executá-los (sem uma senha, se desejar, mas verifique se o script está seguro) usando o sudo.
fonte
A combinação de fakeroot / fakechroot fornece um simulacro de chroot para necessidades simples, como a produção de arquivos tar onde os arquivos parecem pertencer à raiz. A página de manual do Fakechroot é http://linux.die.net/man/1/fakechroot .
Você não recebe nenhuma nova permissão, mas se possui um diretório (por exemplo, fake-distro) antes de chamar
Agora, procure por algum comando como se você fosse root e possuísse tudo dentro da fake-distro.
fonte
~/fake-distro
usos busybox, que links simbólicosls
,mv
e outros utilitários comuns a/bin/busybox
. Se eu ligar explicitamente/bin/busybox mv ...
, as coisas funcionam, mas se eu ligar,/bin/mv ...
eu atendosh: /bin/mv: not found
. A configuraçãoexport FAKECHROOT_EXCLUDE_PATH=/
antes de executar o fakechroot corrige esse sintoma, mas depois quebra em outros links simbólicos (por exemplo/usr/bin/vim -> /usr/bin/vim.vim
).Parece que, com espaços de nome de usuário, é possível chroot sem raiz. Aqui está um exemplo de programa que demonstra que é possível. Eu apenas comecei a explorar como os namespaces do linux funcionam e, portanto, não tenho certeza se esse código é uma prática recomendada ou não.
Salvar como
user_chroot.cc
. Compile comg++ -o user_chroot user_chroot.cc
. O uso é./user_chroot /path/to/new_rootfs
.Eu testei isso em um rootfs mínimo gerado com multistrap (executado como não raiz). Alguns arquivos do sistema gostam
/etc/passwd
e/etc/groups
foram copiados dos rootfs do host para os rootfs convidados.fonte
Failed to unshare user namespace
mim no linux 4.12.10 (Arch Linux).unshare
chamada malsucedida . Você também pode tentar esta versão python que poderia ter melhor de mensagens de erro: github.com/cheshirekow/uchrootNão. Se bem me lembro, existe algo no nível do kernel que o chroot faz que impede. Não me lembro o que era aquilo. Eu o investiguei ao mexer com a ferramenta Catalyst Build do Gentoo (e um chroot no gentoo é o mesmo que um chroot no ubuntu). Embora seja possível fazer isso sem uma senha ... mas essas coisas são deixadas para o domínio de possíveis vulnerabilidades de segurança e para garantir que você saiba o que está fazendo.
fonte