Configuração DNS separada em cada namespace de rede

3

Eu configurei vários namespaces de rede no meu sistema Linux (kernel versão 3.10), e agora eu quero configurar cada namespace de rede para ter suas próprias configurações de DNS.

Eu criei resolv.conf arquivos em cada diretório /etc/netns/[namespace] e agora quero que meu sistema funcione da seguinte maneira:

Na linha de comando bash, sempre que eu insiro o contexto de um namespace de rede específico com nsenter --net=/run/netns/[namespace name] , quero que todos os processos iniciados a partir da linha de comando (como nslookup, ping) sejam executados com as configurações de DNS que eu configurei com a% correspondente/etc/netns/[namespace name]/resolv.conf.

Se eu executar meus comandos assim:

 "ip netns exec [namespace name] [command]"

, as configurações de DNS do namespace se aplicam.

No entanto, ao executar os comandos sem "ip netns exec", as configurações de DNS são obtidas de /etc/resolv.conf , embora a execução de "netns get cur" indique que o contexto está definido para o namespace desejado.

Eu tentei fazer mount --bind /etc/netns/[namespace name]/resolv.conf /etc/resolv.conf no contexto do namespace de rede apropriado, mas isso aplica a montagem em todo o sistema e não apenas no contexto desse namespace de rede.

Eu suspeitava que o uso de namespaces de montagem pudesse ajudar, então tentei ler a página de manual dos namespaces de montagem, mas não consegui fazer nada disso no pouco tempo que dediquei a ele.

Existe uma maneira fácil e elegante de atingir esse objetivo?

Qualquer ajuda / direção para a solução será muito apreciada!

    
por Ben S. 15.05.2018 / 12:51

2 respostas

2

Veja o que está fazendo ip netns exec test ... em sua situação, usando strace .

Trecho:

# strace  -f ip netns exec test sleep 1 2>&1|egrep '/etc/|clone|mount|unshare'|egrep -vw '/etc/ld.so|access'
unshare(CLONE_NEWNS)                    = 0
mount("", "/", 0x55f2f4c2584f, MS_REC|MS_SLAVE, NULL) = 0
umount2("/sys", MNT_DETACH)             = 0
mount("test", "/sys", "sysfs", 0, NULL) = 0
open("/etc/netns/test", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 5
mount("/etc/netns/test/resolv.conf", "/etc/resolv.conf", 0x55f2f4c2584f, MS_BIND, NULL) = 0

para reproduzir (parcialmente, por exemplo, /sys não é tratado aqui) o que ip netns exec test ... está fazendo:

~# ip netns id

~# head -1 /etc/resolv.conf 
# Generated by NetworkManager

~# nsenter --net=/var/run/netns/test unshare --mount sh -c 'mount --bind /etc/netns/test/resolv.conf /etc/resolv.conf; exec bash'

~# ip netns id
test
~# head -1 /etc/resolv.conf 
# For namespace test
~#

Então está certo. nsenter sozinho não é suficiente. unshare deve ser usado, para mudar para um namespace de montagem recém-criado (baseando este novo em uma cópia do anterior) e alterá-lo, e não apenas usando textualmente um existente, uma vez que não existe um que ainda se encaixa. Isso é o que está fazendo o syscall com o mesmo nome que está dizendo strace .

    
por 15.05.2018 / 14:48
2

Solução

Você pode usar ip netns exec com bash em vez de usar nsenter , ou seja:

ip netns enter [namespace name] bash

Isso permitirá que você insira uma sessão de shell interativa em que os arquivos de configuração de rede específicos do espaço de nomes são automaticamente vinculados a seus locais padrão (globais) (sem afetar outras sessões).

Explicação

O seguinte é retirado da página ip netns man :

For applications that are aware of network namespaces, the convention is to look for global network configuration files first in /etc/netns/**NAME/ then in **/etc/. For example, if you want a different version of /etc/resolv.conf for a network namespace used to isolate your vpn you would name it /etc/netns/myvpn/resolv.conf.

ip netns exec automates handling of this configuration, file convention for network namespace unaware applications, by creating a mount namespace and bind mounting all of the per network namespace configure files into their traditional location in /etc.

Observe, em particular, a distinção entre os aplicativos aware do namespace de rede e os aplicativos inconsciente do namespace de rede.

As nsenter man pages , por outro lado, não parecem para mencionar essa distinção (em particular eu procurei pelas strings "aware", "resolv", ".conf" e "/ etc" e não encontrei nenhum resultado). Isso parece sugerir que o utilitário nsenter não executa o mesmo tipo de tratamento automático de aplicativos inconscientes de namespace.

Comentários adicionais

Além dos namespaces de rede , convém ver Espaços de Nomes de Usuário e Montar namespaces . E se você quiser mais isolamento além do DNS, convém também considerar a conteinerização, por exemplo, Contêineres LXC ou Docker .

    
por 15.05.2018 / 14:00