Espero que este seja o lugar certo para perguntar sobre SO, ServerFault, etc. Pesquisei muito e não consigo encontrar nada remotamente parecido com esta pergunta, pronto para ser comprovado como um péssimo pesquisador.
Quando eu construo um contêiner Docker baseado no Ubuntu 22 e executo o bash nele, posso executar o comando no contêiner:
ip link set dev eth0 promisc on
Mas quando coloco isso em um Dockerfile, recebo um erro quando o comando é executado durante a construção.
A questão é: por que há uma diferença? E como posso fazer isso funcionar em um Dockerfile?
O comando Build é: docker build -t firewall .
Eu tentei --allow=network.host
apenas por diversão, sem diferença.
Quando executo o contêiner construído, eu uso --privileged
, se isso for importante.
Esta é a aparência do erro: (imagem também https://imgur.com/a/SrWcoFZ )
=> ERROR [23/23] RUN ip link set dev eth0 promisc on
------
> [23/23] RUN ip link set dev eth0 promisc on:
0.200 RTNETLINK answers: Operation not permitted
------
<snip a warning about running in a Git dir>
Dockerfile:35
--------------------
33 | RUN cd snort3-3.1.43.0/build && make install
34 | RUN ldconfig
35 | >>> RUN ip link set dev eth0 promisc on
--------------------
ERROR: failed to solve: process "/bin/sh -c ip link set dev eth0 promisc on" did not complete successfully: exit code: 2
Histórico: estou tentando executar o Snort em um contêiner Docker, faz parte da construção de um projeto para um curso de segurança em nível MS. Uma etapa da instalação do Snort é configurar a interface de rede como promíscua. Se bem entendi, isso permite que o Snort veja todo o tráfego da rede, independentemente do destino. Vejo isso em instalações padrão do Snort, realmente não entendo por que me importo mais do que com o tráfego endereçado diretamente ao contêiner. Talvez isso nem seja necessário?
E caso seja importante, tudo isso está acontecendo dentro de uma VM baseada no Ubuntu 24.04, resumindo. E estou construindo o projeto em um repositório git, no diretório de nível superior, recortei o aviso sobre isso.
Então, o que não estou entendendo é por que isso está se comportando de maneira diferente ao executá-lo como parte de uma compilação do Docker e executá-lo manualmente no contêiner quando o contêiner estiver ativo?
Obrigado
ATUALIZAÇÃO : Com base nos comentários, configurei um script ENTRYPOINT, mas ainda tenho o mesmo problema:
RTNETLINK answers: Operation not permitted
ocorre quando executo este contêiner, aqui está o Dockerfile e o script de inicialização:
https://github.com/jimlohse/firewallProjectPublic
ATUALIZAÇÃO 2 Eu estava sendo burro e esqueci de usar --privileged
quando adicionei o script ENTRYPOINT. Depois que comecei a usar esse sinalizador, ele funcionou. Obrigado!
Aceitei a resposta, obrigado por abordar meu entendimento conceitual.
Um contêiner Docker é executado com um conjunto padrão de restrições que impedem a execução de tarefas potencialmente confidenciais, como alterar a configuração da rede, montar sistemas de arquivos etc. Os contêineres efêmeros usados durante o
docker build
processo incluem essas mesmas restrições.Ao iniciar um contêiner com
--privileged
, você remove todas as restrições padrão, para que um contêiner tenha acesso total aos dispositivos do sistema, à pilha de rede, às operações de montagem, etc.Geralmente não faz sentido conceder esses privilégios durante o processo de construção, porque o processo de construção é efêmero - se você precisar de uma configuração de rede específica, isso é algo que você precisaria ativar em tempo de execução, não em tempo de construção.
No seu exemplo, você está tentando executar:
Mas isso não faz nada . Ele não faz uma alteração persistente que é armazenada na imagem do contêiner e não terá nenhum impacto no contêiner em execução.
Se você precisar ativar o modo promíscuo em uma interface, então:
CMD
ouENTRYPOINT
, e--privileged
ou concedendo um subconjunto menor de privilégios com algo como--cap-add net_admin
.