HOW-TO: chroot em daemons e processos do sistema

Última atualização: Sábado, 20 de Outubro de 2001
Informe qualquer correção ou sugestão de acréscimo ao autor jonathan@networkdweebs.com

Outras formas não convencionais de segurança: Creating root-kit proof saferooms

Tabela de Conteúdo

Parte I: Introdução a chrooting

Parte II: Pré-requisitos

Parte III: Configurando um ambiente chroot


Parte I

1.1 O que é chrooting?

O comando/função chroot é uma abreviação para 'change root', e ele foi criado para alterar a raiz do filesystem para o ambiente ao qual é aplicado. Isto significa que a barra inicial (/) em qualquer nome de caminho é tornada relativa ao caminho chrooted. Por exemplo, se um arquivo chamado /home/jonz/hello.txt existe no sistema, e eu for chrooted para /home/jonz, o arquivo vai existir, no meu ambiente chrooted, como /hello.txt.

O objetivo de fazer chroot é para criar uma "jaula" de proteção (teoricamente) impenetrável, protegendo o que está no chroot de poder ler ou modificar qualquer arquivo fora do ambiente do chroot. No exemplo acima, Eu não posso acessar qualquer arquivo que esteja fora de /home/jonz, uma vez que / está agora apontando para /home/jonz. Fazer chroot é comumente usado para enjaular usuários em ambientes multiusuários, para proteger os arquivos do sistema. O chroot também pode ser usado para enjaular os daemons do sistema, evitando que os mesmos possam ser alvos viáveis para hackers. Se um hacker explorar uma vulnerabilidade de um daemon que está em uma jaula chroot, sua capacidade de afetar arquivos fora da jaula, ou obter um root shell, é muito mais difícil. Uma grande razão para isto é que não há mais shell no path do ambiente, de forma que mesmo que o hacker detone a pilha do programa, não há nenhum shell no retorno. Muitas pessoas declararam poder quebrar a segurança de uma jaula chroot, mas a maioria dos casos isto foi feito a partir de um shell (o que não é o nosso caso). Quebrar a segurança de uma gaiol de um ambiente daemon é, no mínimo, extremamente difícil.

1.2 Quando é apropriado fazer chroot de daemons ou processos?

Fazer o chroot de daemons é um método prático de adicionar uma camada de segurança ao seu sistema. Muitos processos do sistema e aplicações de terceiros possuem algumas proteções contra a exploração de vulnerabilidades. Muitas feramentas tem a possibilidade de serem executadas com usuários não-root, o que torna mais difícil aos hackers atacarem o root.

Camadas de segurança de rede como firewalls, TCP wrappers, filtros, e etcetera também somam na segurança geral do sistema. Da mesma forma que todos estes, fazer chroot é apropriado para a maioria das implementações, onde é possível fazer isto sem comprometer a funcionalidade do sistema.

1.3 Todos os daemons podem ser protegidos por chroot?

Tecnicamente você pode colocar qualquer coisa em uma jaula chroot, incluindo a caçarola da tua mãe, mas em alguns casos isto não acontece sem que algo deixe de funcionar, ou, em outras circunstâncias, sem uma configuração não-convencional bastante elaborada que não vale o esforço. Alguns daemons não podem funcionar em um ambiente chroot devido à complexidade de suas funções. Por exemplo, o sendmail tem que ter acesso aos diretórios dos usuários para procurar por arquivos .forward. Não há uma forma prática de colocar o sendmail em um chroot sem criar um espelho elaborado e demorado. Por isto que o sendmail tem uma solução alternativa, o smrsh (sendmail restricted shell). A maioria dos daemons do sistema, entretanto, podem ser colocados em uma jaula chroot com pouco esforço.

1.4 Fazer chroot irá afetar meus usuários?

Se for feito corretamente, seus usuários não perceberão diferença no comportamento do sistema. Fazer chroot, por si só, não irá afetar diretamente os usuários ou alterar seu sistema operacional. O sistema existente é geralmente deixado intocado, em quanto pequenas "jaulas" são criadas para fornecer serviços. Tenha em mente que não estamos falando de aproveitar-se de pacotes chroot existentes para daemons ftp ou ssh. É semelhante, mas um conceito ainda diferente que o que estamos discutindo aqui. Estamos discutindo colocar em chroot os daemons do sistema que fornecem estes serviços de forma transparente para que continuem aptos a fazer suas atividades com segurança adicional.

1.5 O que implica o chrooting?

Fazer o chroot de qualquer daemon é um processo e comumente envolve os seguintes passos para produzir um daemon sob chroot viável:

Os passos 2 e 3 são os que normalmente demoram mais. O passo 2, em particular, exige um certo nível de criatividade em algumas circunstâncias. Por exemplo, um popper de email tem que ter acesso às pastas de correspondência no sistema. Copiar as pastas de email para a jaula não irá produzir os resultados desejados, de forma que precisamos criar uma jaula "em torno" das pastas de email. Iremos abordar estas complexidades mais tarde.

Parte II

2.1 Posso fazer chroot neste daemon?

Antes mesmo de criar um diretório ou de copiar um único arquivo, precisamos fazer algumas perguntas importantes. A primeira é se o daemon que queremos colocar em chroot pode sê-lo. Iremos trabalhar com três exemplos de daemons do sistema abaixo, e faremos as mesmas questões:
O daemon acessa arquivos em alguma localização geral?
É viavel copiar estes arquivos apenas uma vez, ou periodicamente com o cron?
É prudente criar uma "jaula" ao redor de um conjunto específico de arquivos?

Se você respondeu "não" para todas as questões, então pode não ser uma boa idéia colocar este daemon em chroot. Vejamos alguns exemplos:

Eudora Qpopper

O daemon acessa arquivos em uma localização geral?

Primariamente, um mail popper precisa acessar os arquivos de correio dos usuários. Existem outros arquivos, como alguns arquivos de /etc/ que são necessários para autenticação. A resposta a esta pergunta é "SIM" já que a maioria dos arquivos necessários estão em um único lugar (/var/mail).

É viável copiar estes arquivos apenas uma vez, ou periodicamente com o cron?

Copiar pastas de email nunca foi uma boa idéia, e copiar somente uma vez irá acabar gerando usuários com caixas de correio deixadas para trás. É prudente, entretanto, copiar os arquivos em /etc e quaisquer outros arquivos utilizados uma vez por dia ou mais/menos frequentemente conforme necessário. Uma vez que estamos tentando proteger estes arquivos, não queremos dar a um hacker em potencial acesso aos originais.

É prudente criar uma "jaula" ao redor de um conjunto específico de arquivos?

Existem duas alternativas quando se está tratando de arquivos em uma jaula. Ou vcê move ou copia os arquivos para a jaula, ou então cria a jaula ao redor dos arquivos. No caso do mail, copiar pastas de email a cada poucos minutos é uma atividade que vai consumir muitos recursos do seu servidor, e é simplesmente ineficiente tentar manter um diretório cheio de links simbólicos. É muito mais eficiente fazer o popper utilizar as pastas de email reais em sua localização original. Nossa resposta aqui é "SIM".

RPCBIN da Sun

O daemon acessa arquivos em uma localização geral?

O daemon acessa a princípio vários arquivos pequenos em /etc.

É viável copiar estes arquivos apenas uma vez, ou periodicamente com o cron?

A maioria dos arquivos são pequenos e poucas vezes são atualizados. É viável copiar estes arquivos para um diretório uma vez por dia.

É prudente criar uma "jaula" ao redor de um conjunto específico de arquivos?

Diferente do nosso mail popper, que acessaram primariamente os correios, o /etc contém muitos dos arquivos críticos do sistema que estamos tentando proteger. Seria muito RUIM e contra o objetivo do chroot em primeiro lugar dar a um hacker em potencial acesso a quaisquer arquivos em /etc. Assim, é uma boa idéia fazer chroot DESTE daemon criando uma jaula totalmente separada, e simplesmente copiar os arquivos.

Sendmail

O daemon acessa arquivos em uma localização geral?

Não. O Sendmail tem que ter acesso a vários arquivos em diferentes locais. Estes locais incluem os diretórios /home dos usuários e outros arquivos. Simultaneamente, o sendmail tem que poder acessar o spool de mail (/var/spool/mqueue) e os diretórios de email dos usuários (/var/mail).

É viável copiar estes arquivos apenas uma vez, ou periodicamente com o cron?

Para criar um ambiente chroot para o sendmail, contendo todos os arquivos que este necessita para funcionar, os diretórios de usuários devem ser espelhados para um local seguro que contenha os arquivos necessários para redirecionar e manipular a correspondência. Isto também vai exigir a criação de novos diretórios e o apagamento de diretórios antigos quando as contas de usuários são manipuladas. Simultaneamente, o sendmail tem que ter acesso ao spool de email e às pastas de mail dos usuários. Não é viavel copiar estes arquivos de e para a jaula.

É prudente criar uma "jaula" ao redor de um conjunto específico de arquivos?

Examinemos isto. Podemos criar uma jaula ao redor das pastas de email, mas enão perdemos a capacidade de escrever para o spool de mail. Podemos fazer uma jaula em torno de /var, permitindo acesso a ambos, mas então estaremos permitindo que o ambiente chroot dê acesso potencial a arquivos críticos. Nenhuma solução resolve o outro problema de ter um espelho do diretório dos usuários. Parece que não há nenhum outro conjunto de arquivos que possa ser colocado em uma jaula chroot.

O sendmail, conforme as respostas acima sugerem, não é um bom candidato para chroot. Apesar de ser possível, a configuração é bastante complicada e consome muitos recursos. É uma boa idéia apenas aderir à segurança que vem com o sendmail.

2.2 Introdução ao truss, lsof e ldd

truss

Se você executar o comando 'man truss', você verá que o truss é uma ferramenta projetada para fazer o trace de chamadas de sistema e sinais. As cahamadas de sistema incluem chamadas a bibliotecas e acesso a arquivos. O truss é uma boa forma de descobrir quais recursos um daemon em particular está usadno. Para usar o truss, simplesmente escreva 'truss' seguido pelo comando que você normalmente utilizaria para iniciar o daemon. A saida do mesmo deve ser semelhante ao abaixo:

open("/usr/lib/libc.so.1", O_RDONLY) = 3

Programa abre a biblioteca libc.

open64("/usr/local/etc/my.config", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3

Programa abriu /usr/local/etc/my.config para escrita.

Ao executar o truss em um daemon, obtém-se imediatamente uma longa lista de arquivos para inciar a pesquisa. É uma boa idéia utilizar todas as diferentes funcionalidades e comandos de um daemon e observar quais novos arquivos o truss aponta. Sem o truss, você acaba quebrando sua jaula chroot toda vez que estiver faltando um arquivo de dados.

lsof

O lsof é otura excelente ferramenta para descobrir quais recursos um daemon utiliza. O lsof é feito para trabalhar com daemons que já estejam em funcionamento. ele mostra arquivos abertos, conexões de rede, e muito mais. O lsof não vem junto com a maioria dos sistemas, já que é uma ferramenta de terceiros. Ele pode ser copiado de vários sites, como www.sunfreeware.com. O código fonte do mesmo está disponível para download via ftp anônimo em ftp://vic.cc.purdue.edu/pub/tools/unix/lsof.

ldd

O ldd é uma ferramenta útil para determinar quais recursos de biblioteca seu programa precisa para ser executado. ldd é a sigla de 'list dynamic dependencies' (listar dependências dinâmicas). Executar o ldd seguido do caminho e nome do daemon que está sendo colocado em uma jaula chroot fornece uma lista de bibliotecas que você deve planejar copiar para a jaula.

Uma nota sobre bibliotecas dinâmicas: Se você tem acesso aos arquivos fonte dos programas que está colocando em chroot, você pode querer compilar os mesmos com bibliotecas estáticas. Isto irá evitar que você tenha que copiar bibliotecas. Entretanto, se você usa um sistema operacional cujo fabricante atualiza frequentemente as bibliotecas, você pode querer permanecer usando bibliotecas dinâmicas.

2.3 Determinando dependências de arquivos de dados

O primeiro exercício que fizemos no item 2.1 nos fazia pensar sobre quais arquivos de dados o daemon dependia. Alguns são relocáveis, enquanto que para outros temos que construir uma jaula ao redor dos mesmos. Somente dois dos três exemplos da seção anterior eram viáveis (Eudora Qpopper e RPCBIND da Sun). Ambos eram candidatos muito bons para chroot e ambos tiveram severas vulnerabilidades no passado. Vamos agora mapear os arquivos reais que teremos de mover ou construir uma jaula no entorno para estes dois exemplo. Está tudo bem se perdermos alguns arquivos pequenos já que sempre podemos encontrar uma solução para eles antes de levantar o novo serviço. Existem várias formas de determinar quais arquivos de dados são usados. Estas incluem, mas não são limitadas, a:

É importante contabilizar o máximo de arquivos de dados que você conseguir. Examinando nossos dois exemplos, podemos criar uma lista bem boa dos arquivos que precisaremos:

Eudora Qpopper

/var/mail/* (dentro da jaula)

Os seguintes arquivos de /etc (copiados periódicamente para a jaula):

hosts.allow
hosts.deny
netconfig
nsswitch.conf
passwd
resolv.conf
services
shadow

RPCBIN Sun

Os seguintes arquivos de /etc (copiados periódicamente para a jaula):

hosts
netconfig
nsswitch.conf
resolv.conf
services

Timezone de /usr/local/zoneinfo

Um diretório tmp

2.4 Criando uma estratégia de arquivos de dados

Uma vez que você tenha uma boa lista de arquivos que serão usados, mantenha um controle sobre como você planeja colocar os mesmos na jaula. Você irá copiá-los? Com que freqüência? Uma vez ou diáriamente? Sua jaula será construída em torno deles? Criar uma estratégia vai lhe ensinar quais arquivos tem que ser copiados, em torno de quais será construída a jaula, e irá começar a crir em sua cabeça uma idéia de onde você quer que a jaula fique. É imperativo que você não construa sua jaula em torno de arquivos críticos do sistema, como /etc, uma vez que isto vai acabar com o propósito da jaula. Se você precisa criar uma jaula em torno de algo, crie em torno de um diretório que não irá necessariamente causar uma falha do sistema se for haqueado.

Se você desenhar um círculo em um papel, pode desenhar todos os arquivos que ficarão dentro e fora da jaula. Desenhe linhas entrando no círculo e anote como os arquivos serão copiados ou movidos, e qual a freqüência. Qualquer arquivo que você planeje construir a jaula em torno, deve ser desenhado dentro do círculo. Isto irá mostrar a você o quão grande a jaula deverá ser e irá lhe dar algumas boas notas para trabalhar quando chegar a hora de criar a jaula.

2.5 Determinando dependências de bibliotecas

Todos os códigos de programa que o seu daemon utiliza em sua execução não está necessariamente incluso no arquivo de programa. Muitas peças de código compartilhado são reutilizadas na forma de bibliotecas. Estas bibliotecas são exigidas pelo programa para que possa ser executado. Em um ambiente chroot, o programa não terá acesso direto a estas bibliotecas em seus locais originais. Elas precisarão ser copiadas inicialmente para a jaula para que o programa funcione. A melhor forma de determinar quais bibliotecas o daemon irá precisar é usar o comando 'ldd'. O ldd irá listar as dependências dinâmicas (geralmente bibliotecas compartilhadas) necessárias à execução. Anote-as e planeje a cópia das mesmas para a nova jaula.

Documente as bibliotecas da mesma forma que você fez com os arquivos de dados. Você já sabe como elas serão copiadas para a jaula (usando o comando cp, e somente uma vez). Pode ser uma boa idéia manter esta informação à mão caso você atualize ou aplique um patch ao sistema operacional, para que faça a cópia das bibliotecas atualizadas para suas localizações na jaula. Uma alternativa seria criar um cron job para fazer a cópia uma vez por mês.

Em nosso exemplo, extraímos as seguintes bibliotecas utilizando o truss:

Eudora Qpopper

/usr/lib/libnsl.so.1
/usr/lib/libsocket.so.1
/usr/lib/libresolv.so.2
/usr/lib/libmail.so.1
/usr/lib/librt.so.1
/usr/lib/libcrypt_i.so.1
/usr/lib/libc.so.1
/usr/lib/libdl.so.1
/usr/lib/libmp.so.2
/usr/lib/libaio.so.1
/usr/lib/libgen.so.1
/usr/lib/libpthread.so.1
/usr/lib/libthread.so.1

RPCBIND da Sun

/usr/lib/libsocket.so.1
/usr/lib/libnsl.so.1
/usr/lib/libdl.so.1
/usr/lib/libc.so.1
/usr/lib/libmp.so.2

2.6 Encontrando um bom home para a jaula

Agora você tem toda a informação necessária para determinar onde configurar sua jaula. Se sua jaula será construída "ao redor" de arquivos existentes (como no caso do Eudora Qpopper de nosso exemplo), você terá de criar ela em relação a aquele diretório. Se você não precisa criar a mesma em torno de nenhum arquivo, escolha um local arbitrário com espaço em disco significante. Iremos utilizar /var/mail para nosso popper, e /var/rpcbind para o RPCBIND da Sun. Lembre-se, os programas não ficarão sabendo que foram enjaulados, por isto tentarão acessar os arquivos como fariam normalmente, o que significa que é melhor que eles estejam onde o daemon espera encontrá-los (relativamente), ou symlinkados. Agora você está pronto para a Parte III!

Parte III

3.1 Criando uma jaula vazia

O primeiro passo para criar sua jaula vazia é criar um conjunto de diretórios que irão hospedar o seu daemon, arquivos de dados, e bibliotecas. Vamos atacar primeiro nosso exemplo do Sun RPCBIND. Escolhemos /var/rpcbind como o home da jaula. Aqui está como fizemos para configurar a estrutura de diretórios:

mkdir /var/rpcbind
mkdir /var/rpcbind/dev
mkdir /var/rpcbind/etc
mkdir /var/rpcbind/tmp
mkdir -p /var/rpcbind/usr/lib

Uma vez que o daemon será colocado em chroot, ele precisa acessar alguns dispositivos em /dev, alguns arquivos de dados em /etc, seu próprio diretório tmp, e um diretório de biblioteca. Estes todos serão preenchidos com os arquivos apropriados no momento em que estivermos prontos.

Vamos agora ao exemplo do Eudora Qpopper. Uma vez que a jaula será construida em torno do mailspool, a mesma deve iniciar em /var/mail. Precisamos avançar e construir os diretórios iniciais:

mkdir /var/mail/dev
mkdir /var/mail/etc
mkdir -p /var/mail/usr/lib 
mkdir -p /var/mail/usr/local/lib
mkdir -p /var/mail/usr/sbin
mkdir -p /var/mail/usr/share/lib/zoneinfo/US

Mas ainda não terminamos. Nosso popper espera que o email esteja em /var/mail. Quando ele foi colocado em chroot, o diretório / é /var/mail... de forma que quando ele tenta acessar /var/maill ele vai gerar um erro de arquivo não encontrado! Como contornamos este problema? Precisamos fazer um symlink /var/mail/var/mail para /var/mail que é, falando de forma relativa, / ...

mkdir /var/mail/var
ln -s / /var/mail/var/mail

Agora, quando o popper tentará acessar /var/mail, ele será apontado para /, que é o /var/mail verdadeiro!

Nossos produtos finais se parecem com o seguinte:

RPCBIND Sun

drwxr-xr-x   7 root     other        512 Aug  1 18:31 ./
drwxr-xr-x  34 root     sys          512 Aug  1 18:07 ../
drwxr-xr-x   2 root     other        512 Aug  1 18:16 dev/
drwxr-xr-x   2 root     other        512 Aug  1 18:10 etc/
drwxr-xr-x   2 root     other        512 Aug  1 18:31 tmp/
drwxr-xr-x   6 root     other        512 Jul 28 15:55 usr/
drwxr-xr-x   3 root     other        512 Aug  1 18:19 var/

Eudora Qpopper

drwxrwxrwt   7 root     mail         512 Oct 18 19:36 ./
drwxr-xr-x  34 root     sys          512 Aug  1 18:07 ../
drwxr-xr-x   2 root     other        512 Jul 29 13:33 dev/
drwxr-xr-x   2 root     other        512 Jul 28 16:18 etc/

            - Some mailboxes mixed in here -

drwxr-xr-x   6 root     other        512 Jul 28 15:55 usr/
drwxr-xr-x   2 root     other        512 Aug  1 18:06 var/

3.2 Copiando programas e arquivos de dados, configurando o cron

Agora que nossa estrutura de diretórios está configurada, vamos copiar os programas e arquivos de dados. Uma vez que iremos rodar o rcpbin a partir de um init script, não é necesário copiar o binário para isto. Iremos, entretanto, precisar copiar o qpopper, uma vez que o mesmo é chamado pelo inet. Se o inetd espera que o mesmo esteja em /usr/sbin, você terá de criar um usr/sbin em sua jaula (/var/mail/usr/sbin) e copiar o executável do daemon para lá. Copie todos os arquivos /etc que foram discutidos anteriormente e certifique-se que as permissões são idênticas. Para arquivos que você queira atualizar frequentemente, crie cronjobs para atualizar os mesmos. Quando estiver pronto, sua estrutura de diretórios deve ser similar a isto:

RPCBIN Sun

% ls -l /var/rpcbind/etc
-r--r--r--   1 root     other         90 Jul 28 16:18 hosts
-rw-r--r--   1 root     other       1239 Jul 28 16:09 netconfig
-rw-r--r--   1 root     other        835 Jul 28 15:32 nsswitch.conf
-rw-r--r--   1 root     other        140 Jul 28 16:14 resolv.conf
-r--r--r--   1 root     other       3649 Jul 28 16:14 services

Eudora Qpopper

% ls -l /var/mail/etc

-r--r--r--   1 root     other         90 Jul 28 16:18 hosts
-rw-------   1 root     other         73 Oct 18 19:15 hosts.allow
-rw-------   1 root     other          9 Jul 28 15:58 hosts.deny
-rw-r--r--   1 root     other       1239 Jul 28 16:09 netconfig
-rw-r--r--   1 root     other        835 Jul 28 15:32 nsswitch.conf
-r--r--r--   1 root     other        815 Oct 18 19:15 passwd
-rw-r--r--   1 root     other        140 Jul 28 16:14 resolv.conf
-r--r--r--   1 root     other       3649 Jul 28 16:14 services
-r--------   1 root     other        502 Oct 18 19:15 shadow

Os cron jobs que iremos criar se parecem com o seguinte. Ou o que funcionar para você...

0,30 * * * * cp -p /etc/passwd /var/mail/etc/passwd
0,30 * * * * cp -p /etc/shadow /var/mail/etc/shadow
0 0 * * * cp -p /etc/hosts.* /var/mail/etc/
0 0 0 * * cp -p /etc/services /var/rpcbind/etc
0 0 0 * * cp -p /etc/resolv.conf /var/mail/etc

3.3 Copiando bibliotecas

Lembra-se das bibliotecas que discutimos antes? Precisamos copiar as mesmas para os locais relativos nas jaulas. A maioria das bibliotecas podem ser encontradas em /usr/lib apesar que existem algumas em /usr/local/lib. Da mesma forma que com seus arquivos de dados, copie as bibliotecas com as mesmas permissões. Você deve terminar com algo similar a isto (dependendo do seu sistema operacional):

% ls -l /var/rpcbind/usr/lib

-rwxr-xr-x   1 root     other     200292 Jul 28 15:27 ld.so.1*
-rwxr-xr-x   1 root     other      41628 Jul 28 15:28 libaio.so.1*
-rwxr-xr-x   1 root     other     938940 Jul 28 15:28 libc.so.1*
-rwxr-xr-x   1 root     other      15616 Jul 28 15:27 libcrypt_i.so.1*
-rwxr-xr-x   1 root     other       4448 Jul 28 15:28 libdl.so.1*
-rwxr-xr-x   1 root     other      40540 Jul 28 15:28 libgen.so.1*
-rwxr-xr-x   1 root     other      29548 Jul 28 15:27 libmail.so.1*
-rwxr-xr-x   1 root     other      19584 Jul 28 15:28 libmp.so.2*
-rwxr-xr-x   1 root     other     730672 Jul 28 15:27 libnsl.so.1*
-rwxr-xr-x   1 root     other      35308 Jul 28 15:57 libpthread.so.1*
-rwxr-xr-x   1 root     other     326336 Jul 28 15:27 libresolv.so.2*
-rwxr-xr-x   1 root     other      39048 Jul 28 15:27 librt.so.1*
-rwxr-xr-x   1 root     other      65876 Jul 28 15:27 libsocket.so.1*
-rwxr-xr-x   1 root     other     166624 Jul 28 15:58 libthread.so.1*
-rwxr-xr-x   1 root     other      19648 Jul 28 16:17 nss_dns.so.1*
-rwxr-xr-x   1 root     other      38832 Jul 28 15:33 nss_files.so.1*
-rwxr-xr-x   1 root     other      38292 Jul 28 15:33 nss_nis.so.1*
-rwxr-xr-x   1 root     other      12284 Aug  1 18:15 straddr.so*

% ls -l /var/mail/usr/lib /var/mail/usr/local/lib

-rwxr-xr-x   1 root     other     200292 Jul 28 15:27 ld.so.1*
-rwxr-xr-x   1 root     other      41628 Jul 28 15:28 libaio.so.1*
-rwxr-xr-x   1 root     other     938940 Jul 28 15:28 libc.so.1*
-rwxr-xr-x   1 root     other      15616 Jul 28 15:27 libcrypt_i.so.1*
-rwxr-xr-x   1 root     other       4448 Jul 28 15:28 libdl.so.1*
-rwxr-xr-x   1 root     other      40540 Jul 28 15:28 libgen.so.1*
-rwxr-xr-x   1 root     other      29548 Jul 28 15:27 libmail.so.1*
-rwxr-xr-x   1 root     other      19584 Jul 28 15:28 libmp.so.2*
-rwxr-xr-x   1 root     other     730672 Jul 28 15:27 libnsl.so.1*
-rwxr-xr-x   1 root     other      35308 Jul 28 15:57 libpthread.so.1*
-rwxr-xr-x   1 root     other     326336 Jul 28 15:27 libresolv.so.2*
-rwxr-xr-x   1 root     other      39048 Jul 28 15:27 librt.so.1*
-rwxr-xr-x   1 root     other      65876 Jul 28 15:27 libsocket.so.1*
-rwxr-xr-x   1 root     other     166624 Jul 28 15:58 libthread.so.1*
-rwxr-xr-x   1 root     other      19648 Jul 28 16:17 nss_dns.so.1*
-rwxr-xr-x   1 root     other      38832 Jul 28 15:33 nss_files.so.1*
-rwxr-xr-x   1 root     other      38292 Jul 28 15:33 nss_nis.so.1* 

3.4 Criando dispositivos

Agora vem a parte que pede um truque. Com o daemon em chroot, ele não poderá acesar o diretório /dev tradicional, que incluem vários dispositivos comumente utilizados como /dev/null, /dev/log, e et cetera. Encontrar quais dispositivos seu daemon utiliza não é um passeio no parque. Você pode encontrar a maioria deles utilizando o truss e algumas vezes usando strings | grep dev, mas na maior parte você terá que prestar atenção às mensagens de erro para saber se você esqueceu algum dispositivo. Eis um grupo geral de dispositivos que devem ser criados para qualquer daemon:

/dev/conslog
/dev/log
/dev/msglog
/dev/null
/dev/tcp
/dev/ticlts
/dev/ticots
/dev/ticotsord
/dev/udp
/dev/zero

Estes são os passos para criar os dispositivos (faça isto para cada um deles):

  1. Faça um 'ls -lL /dev/[devicename]'. A saida deve ser algo do tipo:
    crw-rw-rw- 1 root sys 13, 2 Oct 18 19:56 /dev/null

    O número em vermelho é o número 'major' (maior). O número em azul é o número 'minor' (menor). A primeira letra que está em verde será ou um 'c' ou um 'b', significando que é um dispositivo de caracter ou um dispositivo de bloco. Com estas informações, você pode criar o nó.

  2. Faça um cd para o diretório dev da jaula (/var/mail/dev ou /var/rpcbind/dev). Use o comando 'mknod' para criar o dispositivo. Por exemplo, mknod null c 13 2 irá criado o dispositivo que listamos em nosso exemplo. A maioria das máquinas terá números major/minor diferentes, portanto seja cuidadoso.
  3. Usando o chown e chmod, certifique-se que o dispositivo tenha permissões idênticas ao dispositivo original. Para o nosso exemplo do RPCBIND Sun, terminamos quebrando ele mais tarde para descobrir que a criação de um diretório rpc_door com o sticky bit marcado deveria ser criado. Este pode não ser o caso em seu sistema operacional, mas se você chegar a algo assim você terá que criar o mesmo:
    mkdir -p /var/rpcbind/var/run/rpc_door
    chmod +t /var/rpcbind/var/run/rpc_door

Blah.

3.5 Alterando scripts de inicialização

Agora você deve estar pronto! Se você esqueceu algo, provavelmente irá saber quando rodar o daemon pela primeira vez para testar o mesmo. Você fez um teste, certo? Espere, esquecemos de dizer como fazer o teste! Bem, antes que você possa testar com segurança qualquer daemon, é preciso desativar a versão não chroot. Uma vez que você tenha terminado o daemon em uso atualmente, pode executar um comando como este:

/usr/sbin/chroot /var/rpcbind /usr/sbin/rpcbind

Provavelmente tudo deve dar certo. Se você receber alguma mensagem de erro reclamando a falta de arquivos ou bibliotecas, você pode utilizar o truss para determinar o nome do arquivo, e copiar o mesmo para o caminho apropriado. Uma vez que esteja funcionando, pode-se simplesmente comentar o comando de início antigo e trocar o mesmo com a versão chroot.

chroot a partir do inetd

O Eudora Qpopper é executado pelo inetd, e portanto precisa de sua própria linha de comando para iniciar o mesmo sob chroot todas as vezes. Para isto, use uma linha como a abaixo:

pop3 stream tcp nowait root /usr/sbin/chroot chroot /var/mail /usr/sbin/in.pop3

Se você estiver utilizando os TCP wrappers, você precisará enganar o inetd para pensar que o nome do serviço ainda é in.pop3 (ou o que você utilizar). Para isto, faça o symlink do nome de serviço para o chroot e então use o nome de serviço no inetd.conf. Por exemplo:

lrwxrwxrwx 1 root other 6 Jul 28 15:42 /usr/sbin/in.pop3 -> chroot* 

pop3 stream tcp nowait root /usr/sbin/tcpd in.pop3 /var/mail /usr/sbin/in.pop3

/usr/sbin/in.pop3 é na verdade /usr/sbin/chroot (symlink), então quando o inetd inicia o serviço in.pop3, é executado na verdade o chroot com os parâmetros '/var/mail /usr/sbin/in.pop3', que irá executar a versão chroot do in.pop3 localizada em /var/mail. Quando a cópia chroot é iniciada pelo chroot, o nome do serviço será configurado corretamente.

3.6 O Produto Final

Nossos projetos finais, funcionando, se parecerão com isto:

RPCBIND Sun

d none /var/rpcbind 0755 root other
d none /var/rpcbind/dev 0755 root other
c none /var/rpcbind/dev/conslog 21 0 0666 root other
c none /var/rpcbind/dev/log 21 5 0640 root other
c none /var/rpcbind/dev/msglog 97 1 0600 root other
c none /var/rpcbind/dev/null 13 2 0666 root other
c none /var/rpcbind/dev/udp 41 0 0666 root other
c none /var/rpcbind/dev/tcp 42 0 0666 root other
c none /var/rpcbind/dev/ticlts 105 2 0666 root other
c none /var/rpcbind/dev/ticotsord 105 1 0666 root other
c none /var/rpcbind/dev/ticots 105 0 0666 root other
d none /var/rpcbind/var 0755 root other
d none /var/rpcbind/var/run 0755 root other
d none /var/rpcbind/var/run/rpc_door 1777 root root
d none /var/rpcbind/tmp 0755 root other
d none /var/rpcbind/usr 0755 root other
d none /var/rpcbind/usr/share 0755 root other
d none /var/rpcbind/usr/share/lib 0755 root other
d none /var/rpcbind/usr/share/lib/zoneinfo 0755 root other
d none /var/rpcbind/usr/share/lib/zoneinfo/US 0755 root other
f none /var/rpcbind/usr/share/lib/zoneinfo/US/Eastern 0644 root bin
d none /var/rpcbind/usr/lib 0755 root other
f none /var/rpcbind/usr/lib/ld.so.1 0755 root other
f none /var/rpcbind/usr/lib/libnsl.so.1 0755 root other
f none /var/rpcbind/usr/lib/libsocket.so.1 0755 root other
f none /var/rpcbind/usr/lib/libresolv.so.2 0755 root other
f none /var/rpcbind/usr/lib/libmail.so.1 0755 root other
f none /var/rpcbind/usr/lib/librt.so.1 0755 root other
f none /var/rpcbind/usr/lib/libcrypt_i.so.1 0755 root other
f none /var/rpcbind/usr/lib/libc.so.1 0755 root other
f none /var/rpcbind/usr/lib/libdl.so.1 0755 root other
f none /var/rpcbind/usr/lib/libmp.so.2 0755 root other
f none /var/rpcbind/usr/lib/libaio.so.1 0755 root other
f none /var/rpcbind/usr/lib/libgen.so.1 0755 root other
f none /var/rpcbind/usr/lib/nss_files.so.1 0755 root other
f none /var/rpcbind/usr/lib/nss_nis.so.1 0755 root other
f none /var/rpcbind/usr/lib/libpthread.so.1 0755 root other
f none /var/rpcbind/usr/lib/libthread.so.1 0755 root other
f none /var/rpcbind/usr/lib/nss_dns.so.1 0755 root other
f none /var/rpcbind/usr/lib/straddr.so 0755 root other
d none /var/rpcbind/usr/sbin 0755 root other
f none /var/rpcbind/usr/sbin/rpcbind 0555 root other
d none /var/rpcbind/usr/local 0755 root other
d none /var/rpcbind/usr/local/sbin 0755 root other
d none /var/rpcbind/usr/local/lib 0755 root other
d none /var/rpcbind/etc 0755 root other
f none /var/rpcbind/etc/nsswitch.conf 0644 root other
f none /var/rpcbind/etc/netconfig 0644 root other
f none /var/rpcbind/etc/services 0444 root other
f none /var/rpcbind/etc/resolv.conf 0644 root other
f none /var/rpcbind/etc/hosts 0444 root other

Eudora Qpopper

d none /var/mail 1777 root mail
d none /var/mail/usr 0755 root other
d none /var/mail/usr/share 0755 root other
d none /var/mail/usr/share/lib 0755 root other
d none /var/mail/usr/share/lib/zoneinfo 0755 root other
d none /var/mail/usr/share/lib/zoneinfo/US 0755 root other
f none /var/mail/usr/share/lib/zoneinfo/US/Eastern 0644 root bin
d none /var/mail/usr/lib 0755 root other
f none /var/mail/usr/lib/ld.so.1 0755 root other
f none /var/mail/usr/lib/libnsl.so.1 0755 root other
f none /var/mail/usr/lib/libsocket.so.1 0755 root other
f none /var/mail/usr/lib/libresolv.so.2 0755 root other
f none /var/mail/usr/lib/libmail.so.1 0755 root other
f none /var/mail/usr/lib/librt.so.1 0755 root other
f none /var/mail/usr/lib/libcrypt_i.so.1 0755 root other
f none /var/mail/usr/lib/libc.so.1 0755 root other
f none /var/mail/usr/lib/libdl.so.1 0755 root other
f none /var/mail/usr/lib/libmp.so.2 0755 root other
f none /var/mail/usr/lib/libaio.so.1 0755 root other
f none /var/mail/usr/lib/libgen.so.1 0755 root other
f none /var/mail/usr/lib/nss_files.so.1 0755 root other
f none /var/mail/usr/lib/nss_nis.so.1 0755 root other
f none /var/mail/usr/lib/libpthread.so.1 0755 root other
f none /var/mail/usr/lib/libthread.so.1 0755 root other
f none /var/mail/usr/lib/nss_dns.so.1 0755 root other
d none /var/mail/usr/sbin 0755 root other
f none /var/mail/usr/sbin/in.pop3 0755 root other
d none /var/mail/usr/local/lib 0755 root other
d none /var/mail/etc 0755 root other
f none /var/mail/etc/passwd 0444 root other
f none /var/mail/etc/shadow 0400 root other
f none /var/mail/etc/hosts.allow 0600 root other
f none /var/mail/etc/nsswitch.conf 0644 root other
f none /var/mail/etc/hosts.deny 0600 root other
f none /var/mail/etc/netconfig 0644 root other
f none /var/mail/etc/services 0444 root other
f none /var/mail/etc/resolv.conf 0644 root other
f none /var/mail/etc/hosts 0444 root other
d none /var/mail/var 0755 root other
s none /var/mail/var/mail=/
d none /var/mail/dev 0755 root other
c none /var/mail/dev/udp 41 0 0666 root other
c none /var/mail/dev/null 13 2 0666 root other
c none /var/mail/dev/conslog 21 0 0666 root other
c none /var/mail/dev/log 21 5 0640 root other
c none /var/mail/dev/msglog 97 1 0600 root other

Estes são alguns daemons que eu já fiz chroot sem problemas:

Estes são alguns daemons que teoricamente podem ser colocados em chroot, mas que eu ainda não tentei:


Network Dweebs e WebConference são marcas registradas de Network Dweebs.

Esta é uma tradução do artigo
Chrooting daemons and system processes HOW-TO. Copyright © 2001 Network Dwebs.

1