14.6. Gerenciando Jails com o ezjail

Originalmente contribuído por Warren Block.

Criar e gerenciar múltiplas jails pode se tornar um trabalho tedioso e propenso a erros. O ezjail de Dirk Engling automatiza e simplifica muito as tarefas de jails. Uma basejail é criada como um template. Jails adicionais usam mount_nullfs(8) para compartilhar muitos dos diretórios da basejail sem usar espaço em disco adicional. Cada jail adicional leva apenas alguns megabytes de espaço em disco antes que os aplicativos sejam instalados. A atualização da cópia do userland na basejail atualiza automaticamente todas as outras jails.

Benefícios e recursos adicionais são descritos em detalhes no site do ezjail, https://erdgeist.org/arts/software/ezjail/.

14.6.1. Instalando o ezjail

A instalação do ezjail consiste na inclusão de uma interface de loopback para uso nas jails, instalação do port ou pacote e ativação do serviço.

  1. Para manter o tráfego de loopback da jail fora da interface de rede de loopback do host lo0, uma segunda interface de loopback é criada adicionando uma entrada no arquivo /etc/rc.conf:

    cloned_interfaces="lo1"

    A segunda interface de loopback lo1 será criada quando o sistema for iniciado. Também pode ser criado manualmente sem reiniciar:

    # service netif cloneup
    Created clone interfaces: lo1.

    Jails podem ter permissão para usar aliases dessa interface de loopback secundária sem interferir no host.

    Dentro de uma jail, o acesso ao endereço de loopback 127.0.0.1 é redirecionado para o primeiro endereço de IP atribuído à jail. Para fazer com que o loopback da jail corresponda à nova interface lo1, essa interface deve ser especificada primeiro na lista de interfaces e endereços IP fornecidos ao criar uma nova jail.

    Dê a cada jail um endereço de loopback exclusivo no bloco de rede 127.0.0.0/8.

  2. Instale o sysutils/ezjail:

    # cd /usr/ports/sysutils/ezjail
    # make install clean
  3. Ative o ezjail adicionando esta linha ao arquivo /etc/rc.conf:

    ezjail_enable="YES"
  4. O serviço será iniciado automaticamente na inicialização do sistema. Ele pode ser iniciado imediatamente na sessão atual:

    # service ezjail start

14.6.2. Configuração inicial

Com o ezjail instalado, a estrutura do diretório basejail pode ser criada e preenchida. Esta etapa é necessária apenas uma vez no computador host da jail.

Em ambos os exemplos, -p faz com que a árvore de ports seja baixada com o portsnap(8) para a basejail. Essa cópia única do diretório de ports será compartilhada por todas as jails. Usar uma cópia separada do diretório de ports para jails isola-os do host. O ezjail é explicado com mais detalhes no FAQ: http://erdgeist.org/arts/software/ezjail/#FAQ.

    • Preencher a Jail com o FreeBSD-RELEASE

      Para uma basejail baseada na mesma versão FreeBSD RELEASE do computador host, use o comando install. Por exemplo, em um computador host executando o FreeBSD 10-STABLE, a versão mais recente do FreeBSD -10 será instalada na jail:

      # ezjail-admin install -p
    • Preencher a Jail com o comando installworld

      A basejail pode ser instalada a partir de binários criados pelo buildworld no host com ezjail-admin update.

      Neste exemplo, o FreeBSD 10-STABLE foi compilado a partir do código fonte. Os diretórios da jail são criados. E então installworld é executado, instalando o /usr/obj do host na basejail.

      # ezjail-admin update -i -p

      O /usr/src do host é usado por padrão. Um diretório de código fonte diferente no host pode ser especificado com -s e um caminho ou com ezjail_sourcetree em /usr/local/etc/ezjail.conf.

Dica:

A árvore de ports da basejail é compartilhada por outras jails. No entanto, os distfiles baixados são armazenados na jail que os baixou. Por padrão, esses arquivos são armazenados em /var/ports/distfiles dentro de cada jail. /var/ports dentro de cada jail também é usado como um diretório de trabalho ao compilar ports.

Dica:

O protocolo FTP é usado por padrão para baixar pacotes para a instalação da basejail. Configurações de firewall ou proxy podem impedir ou interferir nas transferências de FTP. O protocolo HTTP funciona de maneira diferente e evita esses problemas. Ele pode ser escolhido especificando uma URL completa para um espelho de download específico no arquivo /usr/local/etc/ezjail.conf:

ezjail_ftphost=http://ftp.FreeBSD.org

Veja Seção A.2, “Sites de FTP para uma lista de sites.

14.6.3. Criando e Iniciando uma Nova Jail

Novas jails são criadas com o comando ezjail-admin create. Nestes exemplos, a interface de loopback lo1 é usada conforme descrito acima.

Procedimento 14.1. Crie e Inicie uma Nova Jail
  1. Crie a jail, especificando um nome e as interfaces de loopback e de rede a serem usadas, junto com seus endereços IP. Neste exemplo, a jail é denominada dnsjail.

    # ezjail-admin create dnsjail 'lo1|127.0.1.1,em0|192.168.1.50'

    Dica:

    A maioria dos serviços de rede são executados em jails sem problemas. Alguns serviços de rede, como ping(8), usam raw network sockets. Nas jails, raw network sockets são desativados por padrão para segurança. Serviços que exigem eles não irão funcionar.

    Ocasionalmente, uma jail pode realmente precisar de raw sockets. Por exemplo, os aplicativos de monitoramento de rede geralmente usam ping(8) para verificar a disponibilidade de outros computadores. Quando raw network sockets são realmente necessários em uma jail, eles podem ser ativados editando o arquivo de configuração do ezjail para uma jail individual, /usr/local/etc/ezjail/jailname. Modifique a entrada parameters:

    export jail_jailname_parameters="allow.raw_sockets=1"

    Não habilite raw network sockets, a menos que os serviços na jail realmente precisem deles.

  2. Inicie a jail:

    # ezjail-admin start dnsjail
  3. Use um console na jail:

    # ezjail-admin console dnsjail

A jail está funcionando e configurações adicionais podem ser realizadas. Configurações típicas adicionadas neste momento incluem:

  1. Defina a Senha de root

    Conecte-se à jail e configure a senha do usuário root:

    # ezjail-admin console dnsjail
    # passwd
    Changing local password for root
    New Password:
    Retype New Password:
  2. Configuração de Fuso Horário

    O fuso horário da jail pode ser definido com tzsetup(8). Para evitar mensagens de erro espúrias, a entrada adjkerntz(8) em /etc/crontab pode ser comentada ou removida. Este comando tenta atualizar o relógio de hardware do computador com alterações de fuso horário, mas as jails não têm permissão para acessar esse hardware.

  3. Servidores DNS

    Insira as linhas com o servidor de nomes de domínio no arquivo /etc/resolv.conf para que o DNS funcione na jail.

  4. Edite o arquivo /etc/hosts

    Altere o endereço e adicione o nome da jail para as entradas localhost no /etc/hosts.

  5. Configure o arquivo /etc/rc.conf

    Digite as definições de configuração no arquivo /etc/rc.conf. Isso é muito parecido com a configuração de um computador completo. O nome do host e o endereço IP não estão definidos aqui. Esses valores já são fornecidos pela configuração da jail.

Com a jail configurada, os aplicativos para os quais a jail foi criada podem ser instalados.

Dica:

Alguns ports devem ser compilados com opções especiais para serem usados em uma jail. Por exemplo, os dois pacotes de plugin de monitoramento de rede net-mgmt/nagios-plugins e net-mgmt/monitoring-plugins possuem uma opção JAIL que deve ser ativada para que funcionem corretamente dentro de uma jail.

14.6.4. Atualizando as Jails

14.6.4.1. Atualizando o Sistema Operacional

Como a cópia do userland da basejail é compartilhada pelas outras jails, a atualização da basejail atualiza automaticamente todas as outras jails. Atualizações binárias ou por código fonte podem ser usadas.

Para compilar o world a partir do código fonte no host, e depois instala-lo na basejail, use:

# ezjail-admin update -b

Se o world já estiver sido compilado no host, instale-o no basejail com:

# ezjail-admin update -i

Atualizações binárias usam o freebsd-update(8). Essas atualizações têm as mesmas limitações como se o freebsd-update(8) estivesse sendo executado diretamente. O mais importante é que apenas as versões -RELEASE do FreeBSD estão disponíveis com este método.

Atualize a basejail para a última versão de patchs da versão do FreeBSD no host. Por exemplo, atualizando de RELEASE-p1 para RELEASE-p2.

# ezjail-admin update -u

Para atualizar a basejail para uma nova versão, primeiro atualize o sistema host como descrito em Seção 23.2.3, “Realizando Upgrades de Versão Principais e Menores”. Depois que o host tiver sido atualizado e reinicializado, a basejail poderá ser atualizada. O freebsd-update(8) não tem como determinar qual versão está atualmente instalada na basejail, então a versão original deve ser especificada. Use o file(1) para determinar a versão original na basejail:

# file /usr/jails/basejail/bin/sh
/usr/jails/basejail/bin/sh: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD), dynamically linked (uses shared libs), for FreeBSD 9.3, stripped

Agora use essas informações para executar a atualização de 9.3-RELEASE para a versão atual do sistema host:

# ezjail-admin update -U -s 9.3-RELEASE

Depois de atualizar a basejail, o mergemaster(8) deve ser executado para atualizar os arquivos de configuração de cada jail.

Como usar o mergemaster(8) depende do propósito e da confiabilidade de uma jail. Se os serviços ou usuários de uma jail não são confiáveis, então o mergemaster(8) deve ser executado somente dentro dessa jail:

Exemplo 14.1. mergemaster(8) em Jail Não Confiável

Exclua o link do /usr/src da jail para a basejail e crie um novo /usr/src na jail como um ponto de montagem. Monte o /usr/src do computador host como read-only no novo ponto de montagem /usr/src da jail:

# rm /usr/jails/jailname/usr/src
# mkdir /usr/jails/jailname/usr/src
# mount -t nullfs -o ro /usr/src /usr/jails/jailname/usr/src

Execute um console na jail:

# ezjail-admin console jailname

Dentro da jail, execute mergemaster. Em seguida, saia do console da jail:

# cd /usr/src
# mergemaster -U
# exit

Finalmente, desmonte o /usr/src da jail:

# umount /usr/jails/jailname/usr/src

Exemplo 14.2. mergemaster(8) em Jail Confiável

Se os usuários e serviços em uma jail forem confiáveis, o mergemaster(8) pode ser executado a partir do host:

# mergemaster -U -D /usr/jails/jailname

Dica:

Após uma atualização de versão principal, é recomendado pelo sysutils/ezjail garantir que o pkg seja da versão correta. Portanto, digite:

# pkg-static upgrade -f pkg

para atualizar ou fazer o downgrade para a versão apropriada.

14.6.4.2. Atualizando o Ports

A árvore de ports na basejail é compartilhada pelas outras jails. A atualização dessa cópia da árvore de ports fornece às outras jails a versão atualizada também.

A árvore de ports da basejail é atualizada com o portsnap(8):

# ezjail-admin update -P

14.6.5. Controlando as Jails

14.6.5.1. Parando e Iniciando Jails

O ezjail inicia automaticamente as jails quando o computador é iniciado. As jails podem ser manualmente paradas e reiniciadas com stop e start:

# ezjail-admin stop sambajail
Stopping jails: sambajail.

Por padrão, as jails são iniciadas automaticamente quando o computador host é iniciado. A inicialização automática pode ser desativada com config:

# ezjail-admin config -r norun seldomjail

Isso entrará em vigor na próxima vez em que o computador host for iniciado. Uma jail que já está em execução não será interrompida.

A ativação do início automático é muito semelhante:

# ezjail-admin config -r run oftenjail

14.6.5.2. Arquivando e Restaurando Jails

Use archive para criar um arquivo .tar.gz de uma jail. O nome do arquivo é composto pelo nome da jail e pela data atual. Os archives são gravados no diretório de archive, /usr/jails/ezjail_archives. Um diretório de archive diferente pode ser escolhido configurando ezjail_archivedir no arquivo de configuração.

O archive pode ser copiado em outro lugar como um backup, ou uma jail existente pode ser restaurada a partir dele com o restore. Uma nova jail pode ser criada a partir de um archive, fornecendo uma maneira conveniente de clonar as jails existentes.

Pare e arquive uma jail chamada wwwserver:

# ezjail-admin stop wwwserver
Stopping jails: wwwserver.
# ezjail-admin archive wwwserver
# ls /usr/jails/ezjail-archives/
wwwserver-201407271153.13.tar.gz

Crie uma nova jail chamada wwwserver-clone do archive criado na etapa anterior. Use a interface em1 e atribua um novo endereço IP para evitar conflito com a original:

# ezjail-admin create -a /usr/jails/ezjail_archives/wwwserver-201407271153.13.tar.gz wwwserver-clone 'lo1|127.0.3.1,em1|192.168.1.51'

14.6.6. Exemplo Completo: BIND em uma Jail

Colocar o servidor DNS BIND em uma jail melhora a segurança ao isolá-lo. Este exemplo cria um servidor de nomes de cache simples.

  • A jail será chamada de dns1.

  • A jail usará o endereço IP 192.168.1.240 na interface re0 do host.

  • Os servidores DNS de upstream do ISP são 10.0.0.62 e 10.0.0.61.

  • A basejail já foi criada e uma árvore de ports instalada como mostrado em Seção 14.6.2, “Configuração inicial”.

Exemplo 14.3. Executando o BIND em uma Jail

Crie uma interface de loopback clonada adicionando uma linha ao arquivo /etc/rc.conf:

cloned_interfaces="lo1"

Imediatamente crie a nova interface de loopback:

# service netif cloneup
Created clone interfaces: lo1.

Crie a jail:

# ezjail-admin create dns1 'lo1|127.0.2.1,re0|192.168.1.240'

Inicie a jail, conecte-se a ao seu console e realize algumas configurações básicas:

# ezjail-admin start dns1
# ezjail-admin console dns1
# passwd
Changing local password for root
New Password:
Retype New Password:
# tzsetup
# sed -i .bak -e '/adjkerntz/ s/^/#/' /etc/crontab
# sed -i .bak -e 's/127.0.0.1/127.0.2.1/g; s/localhost.my.domain/dns1.my.domain dns1/' /etc/hosts

Configure temporariamente os servidores upstream de DNS no arquivo /etc/resolv.conf para que os ports possam ser baixados:

nameserver 10.0.0.62
nameserver 10.0.0.61

Ainda usando o console da jail, instale o dns/bind99.

# make -C /usr/ports/dns/bind99 install clean

Configure o servidor de nomes editando o arquivo /usr/local/etc/namedb/named.conf.

Crie uma Access Control List (ACL) de endereços e redes que têm permissão para enviar consultas DNS para este servidor de nomes. Esta seção é adicionada logo antes da seção options no arquivo:

...
// or cause huge amounts of useless Internet traffic.

acl "trusted" {
	192.168.1.0/24;
	localhost;
	localnets;
};

options {
...

Use o endereço IP da jail na configuração listen-on para aceitar consultas DNS de outros computadores na rede:

	listen-on	{ 192.168.1.240; };

Um servidor DNS de nomes para cache simples é criado alterando a seção forwarders. O arquivo original contém:

/*
	forwarders {
		127.0.0.1;
	};
*/

Descomente a seção removendo as linhas /* e */. Digite os endereços IP dos servidores DNS upstream. Logo após a seção forwarders, adicione referências à trusted ACL definida anteriormente:

	forwarders {
		10.0.0.62;
		10.0.0.61;
	};

	allow-query       { any; };
	allow-recursion   { trusted; };
	allow-query-cache { trusted; };

Ative o serviço no arquivo /etc/rc.conf:

named_enable="YES"

Inicie e teste o servidor de nomes:

# service named start
wrote key file "/usr/local/etc/namedb/rndc.key"
Starting named.
# /usr/local/bin/dig @192.168.1.240 freebsd.org

Uma resposta que inclui

;; Got answer;

mostra que o novo servidor DNS está funcionando. Um longo delay seguido por uma resposta incluindo

;; connection timed out; no servers could be reached

mostra um problema. Verifique as definições de configuração e certifique-se de que quaisquer firewalls locais permitam que o novo DNS acesse os servidores upstream de DNS.

O novo servidor DNS pode usar pra resolução de nomes seu próprio serviço, assim como outros computadores locais. Defina o endereço do servidor DNS no arquivo /etc/resolv.conf do computador-cliente:

nameserver 192.168.1.240

Um servidor DHCP local pode ser configurado para fornecer este endereço como servidor de DNS local, fornecendo configuração automática em clientes DHCP.


All FreeBSD documents are available for download at https://download.freebsd.org/ftp/doc/

Questions that are not answered by the documentation may be sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.