Gerenciamento de namespaces com ip netns (iproute2)

0

Gostaria de saber onde procurar as alterações aplicadas aos namespaces personalizados. Digamos que eu tenha um namespace "ns1" com interfaces virtuais "vpeer" e "lo" dentro e gostaria de modificar as configurações da interface "vpeer" via dnsmasq ou hostapd, então sei que posso fazer isso com eg

$ ip netns exec ns1 bash
$ dnsmasq --interface=vpeer-ns1 --dhcp-range=192.168.0.100,192.168.0.200,255.255.255.0

e a netns está fazendo o resto do trabalho montando-a para mim e gerenciando quaisquer tarefas, pelas quais sou grato. No entanto, no namespace global, eu poderia monitorar as alterações feitas nos arquivos correspondentes ou aplicá-las diretamente em um arquivo. Por exemplo, em /etc/dnsmasq.conf ou /etc/hostapd/hostapd.conf .

Então, minha pergunta é: como posso copiar o comportamento padrão do namespace dentro de um determinado namespace netns? Eu realmente preciso saber o que eu já fiz e qual é a configuração atual das interfaces em "ns1". Não menos importante, porque a maioria dos tutoriais explica procedimentos como este. A página man do ip netns diz que os arquivos de configuração estão localizados em

$ /etc/netns/ns1/

mas nem mesmo o diretório / etc / netns existe após a criação do namespace "ns1". O novo namespace é representado apenas em / var / run / netns / ns1. Este arquivo está sempre vazio - mesmo depois de aplicar os comandos dnsmasq como acima - e o nano aparece com o arquivo vazio, mas depois me dá um erro estranho quando o arquivo é fechado dizendo que

ns1: Argument is invalid.

Então mudei para namespace "ns1" e tentei novamente. Mesmo resultado. Então eu coloquei todos os dispositivos no novo namespace com

$ ip netns exec ns1 ip link set dev lo down
$ ip netns exec ns1 ip link set dev vpeer down

Novamente, o mesmo resultado.

Então, como eu posso acessar os arquivos de configrações com relação a um determinado namespace, uma vez que os aplicativos não estão cientes do namespace não-padrão? Obrigado antecipadamente.

    
por Community 24.09.2018 / 17:51

1 resposta

2

Você tem duas perguntas em uma:

  • quais são os arquivos vazios em /var/run/netns/ ?
  • como usar /etc/netns/ , que nem existe?

Quais são os arquivos vazios em /var/run/netns/ ?

É necessário algum entendimento dos namespaces . Eu não posso explicar em detalhes aqui. É suficiente dizer que um namespace criado uma vez (particionará alguns recursos do kernel, como rede, e) existirá enquanto algo estiver sendo usado. Principalmente, duas coisas vão usá-lo: processos ou pontos de montagem no pseudo-sistema de arquivos especial nsfs . Quando eles pararem de usá-lo ou desaparecerem, o namespace também desaparecerá.

ip netns (que é especializado em namespaces rede ) escolhe manter os namespaces de rede montando uma referência a eles. Essas referências são todas disponíveis em /proc/<pid>/net/ como links simbólicos. Exemplo:

$ ls -l /proc/$$/ns/net
lrwxrwxrwx. 1 user user 0 Sep 25 01:05 /proc/19120/ns/net -> net:[4026531992]
$ stat -L -f -c %T /proc/19120/ns/net # filesystem type. "df" on this would be confused and point to the wrong mountpoint anyway.
nsfs
$ stat -L -c %i /proc/19120/ns/net # inode
4026531992

ip netns add apenas liga-os em /var/run/netns/<NAME> . Observe que, embora geralmente você vincule um diretório a um diretório, também é possível vincular a montagem de um arquivo em um arquivo. Note também que este arquivo é um pseudo-arquivo no sistema de arquivos nsfs . Não foi projetado para ser lido e não pode ser. É usado principalmente para ser passado como uma referência, abrindo (mas não lendo ou escrevendo) ou montando-o:

# strace -e unshare,mount  ip netns add ns1
mount("", "/var/run/netns", 0x5625f6ca80e3, MS_REC|MS_SHARED, NULL) = 0
unshare(CLONE_NEWNET)                   = 0
mount("/proc/self/ns/net", "/var/run/netns/ns1", 0x5625f6ca80e3, MS_BIND, NULL) = 0
+++ exited with 0 +++
# ip netns list
ns1
# ls -l /var/run/netns/ns1
-r--r--r--. 1 root root 0 Sep 25 01:08 /var/run/netns/ns1
# cat /var/run/netns/ns1
cat: /var/run/netns/ns1: Invalid argument
# stat -f -c %T /var/run/netns/ns1
nsfs
# stat -c %i /var/run/netns/ns1
4026532824
# ip netns exec ns1 sleep 99 &
[1] 19620
# ls -l /proc/19620/ns/net
lrwxrwxrwx. 1 root root 0 Sep 25 01:23 /proc/19620/ns/net -> net:[4026532824]

Portanto, o namespace de rede de sleep 99 é aquele do ponto de montagem /var/run/netns/ns1 . Com esse método, por exemplo, é possível ter um namespace de rede com uma ponte vinculada a outros namespaces com veth interfaces e não executar nenhum processo, porque nenhum é necessário.

Você pode excluir manualmente namespaces criados por ip netns com:

# umount /var/run/netns/ns1 
# rm /var/run/netns/ns1
# ip netns list
#

É claro que o namespace da rede irá realmente desaparecer apenas quando a última referência a usá-lo (por exemplo: processo) também desaparecer. Você pode até colocá-lo de volta, se o comando sleep anterior ainda estiver em execução:

# touch /var/run/netns/ns1
# mount --bind /proc/19620/ns/net /var/run/netns/ns1
# ip netns
ns1

Isso pode ser usado para "copiar" a parte do namespace da rede de um container completo, você só precisa saber algum pid no lado do host (por exemplo: lxc-info -Hp -n container ou docker inspect --format '{{.State.Pid}}' container ) e montar seu namespace de rede. Útil para executar comandos de depuração não disponíveis dentro do contêiner ( tcpdump ...).

Tudo o que está acima é efêmero, por exemplo, ele desaparece após a reinicialização.

Como usar o /etc/netns/ que nem existe?

A ip netns manpage conta (ênfase em negrito minha):

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.

Agora, o dnsmasq "está ciente" dos namespaces de rede? Se fosse (com a definição de ip netns ), verificaria /etc/netns/ de alguma forma. Não há menção de "netns" na sua página de manual . A fonte atual do Debian (semelhante à do Raspberry) não inclui a palavra netns em qualquer lugar: não é um espaço de nomes de rede ciente.

É por isso que a seguinte frase de ip netns manpage diz:

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.

Ele não é realmente explicado, mas junto com a sentença anterior isso realmente significa que ip netns exec será vinculado a montagem, se a origem e o destino existirem , /etc/netns/<NAME>/whatever on /etc/whatever . /etc/netns e os nomes de namespaces de rede escolhidos, que conterão as configurações devem ser criados primeiro, manualmente e o conteúdo da configuração real provavelmente copiado dentro e editado : ip netns exec os usará se encontrado, mas não criá-los.

Exemplo:

# mkdir -p /etc/netns/ns1
# echo something > /etc/netns/ns1/whatever
# : > /etc/whatever
# ip netns add ns1
# cat /etc/whatever
# ip netns exec ns1 cat /etc/whatever
something

O que realmente aconteceu por trás disso:

# strace -e open,unshare,setns,mount,umount2 ip netns exec ns1 cat /etc/whatever 2>&1 |egrep '^(open.*/etc/netns|unshare|setns|mount|umount|something)'
setns(5, CLONE_NEWNET)                  = 0
unshare(CLONE_NEWNS)                    = 0
mount("", "/", 0x55947eb550e3, MS_REC|MS_SLAVE, NULL) = 0
umount2("/sys", MNT_DETACH)             = 0
mount("ns1", "/sys", "sysfs", 0, NULL)  = 0
open("/etc/netns/ns1", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 5
mount("/etc/netns/ns1/whatever", "/etc/whatever", 0x55947eb550e3, MS_BIND, NULL) = 0
something

É claro que isso funciona da mesma forma para diretórios dentro de /etc/netns/ns1 ao invés de arquivos: o diretório inteiro aparecerá diretamente em /etc/ mascarando o diretório do host com o mesmo nome, somente se existir.

Portanto, se a configuração padrão do dnsmasq, a menos que seja dito o contrário, for /etc/dnsmasq.conf , você poderá criar uma configuração alternativa para ns1 como /etc/netns/ns1/dnsmasq.conf e ip netns exec fará com que apareça como /etc/dnsmasq.conf to dnsmasq se também já houver um arquivo /etc/dnsmasq.conf , mesmo que esteja vazio. Como está em /etc , isso não é efêmero e será reutilizado sempre que você estiver recriando o mesmo nome de namspace de rede. O mesmo para hostapd e todo o diretório /etc/hostapd/ que pode ser copiado como /etc/netns/ns1/hostapd/ e seus arquivos são modificados internamente. Tenha cuidado com links simbólicos apontando para fora. Agora você pode executar os comandos normalmente em ip netns exec ns1 : eles usarão o novo arquivo de configuração.

    
por 25.09.2018 / 03:24