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.