Meu objetivo é limitar o acesso aos contêineres do docker a apenas alguns endereços IP públicos. Existe um processo simples e repetível para alcançar meu objetivo? Compreendendo apenas o básico do iptables ao usar as opções padrão do Docker, estou achando muito difícil.
Eu gostaria de executar um contêiner, torná-lo visível para a Internet pública, mas apenas permitir conexões de hosts selecionados. Eu esperaria definir uma política de entrada padrão de REJECT e permitir apenas conexões de meus hosts. Mas as regras e cadeias NAT do Docker atrapalham e minhas regras INPUT são ignoradas.
Alguém pode fornecer um exemplo de como realizar meu objetivo, considerando as seguintes premissas?
- IP público do host 80.80.80.80 em eth0
- Hospedar IP privado 192.168.1.10 no eth1
docker run -d -p 3306:3306 mysql
- Bloquear toda a conexão com o host / contêiner 3306, exceto os hosts 4.4.4.4 e 8.8.8.8
Estou feliz em vincular o contêiner apenas ao endereço IP local, mas precisaria de instruções sobre como configurar as regras de encaminhamento do iptables corretamente, que sobrevivam ao processo do docker e reinicia o host.
Obrigado!
--ctdir
? Eu uso-m conntrack --ctstate NEW --ctorigdstport 3306 --ctdir ORIGINAL
DOCKER-USER
tabela padrão contém a entrada:-A DOCKER-USER -j RETURN
que será executada antes do acima, se você usar-A
. Uma solução é inserir regras na cabeça na ordem inversa com-I
.FILTERS
cadeia e-I
insira novas regras (como você disse), para pular para ela:-I INPUT -j FILTERS
e-I DOCKER-USER -i eth0 -j FILTERS
-I
, porém, apenas por segurança.Com o Docker v.17.06, há uma nova cadeia de iptables chamada DOCKER-USER. Este é para suas regras personalizadas: https://docs.docker.com/network/iptables/
Ao contrário da corrente DOCKER, ela não é redefinida na construção / partida de contêineres. Portanto, você pode adicionar essas linhas ao seu iptables config / script para provisionar o servidor antes de instalar o docker e iniciar os contêineres:
Agora, a porta do MySQL está bloqueada para acesso externo (eth0), mesmo que o docker abra a porta para o mundo. (Essas regras assumem que sua interface externa é eth0.)
Eventualmente, você terá que limpar o iptables e reiniciar o serviço docker primeiro, se você estragou demais tentando bloquear a porta como eu fiz.
fonte
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION
É por isso que as instruções personalizadas são executadas antes da cadeia DOCKER.--dport
dentro do DOCKER-USER, isso deve corresponder ao IP interno do serviço de contêiner, não à porta exposta. Eles costumam corresponder, mas nem sempre, e isso pode facilmente entrar em conflito com outros serviços, por isso ainda argumento que esta solução DOCKER-USER é incompleta.ATUALIZAÇÃO : Embora válida em 2015, esta solução não é mais a maneira certa de fazê-lo.
A resposta parece estar na documentação do Docker em https://docs.docker.com/articles/networking/#the-world
O que acabei fazendo foi:
Não toquei nas opções
--iptables
ou--icc
.fonte
iptables -vnL DOCKER
, as portas de destino são todas as portas dentro do contêiner. Se eu entendi direito, isso significa que as regras acima afetariam apenas a porta3306
dentro do contêiner - ou seja, se você estivesse no-p 12345:3306
seu contêiner, sua regra ainda seria a necessária para bloquear o acesso (ou seja--dport 12345
, não funcionaria) , porque as regras ACCEPT da cadeia DOCKER são pós-NAT.--iptables=false
, porque essa parece ser a pior escolha de todas.ATUALIZAÇÃO: Embora essa resposta ainda seja válida, a resposta do @SystemParadox usando
DOCKER-USER
em combinação com--ctorigdstport
é melhor.Aqui está uma solução que persiste bem entre as reinicializações e permite afetar a porta exposta e não a porta interna .
iptables -t mangle -N DOCKER-mysql iptables -t mangle -A DOCKER-mysql -s 22.33.44.144/32 -j RETURN iptables -t mangle -A DOCKER-mysql -s 22.33.44.233/32 -j RETURN iptables -t mangle -A DOCKER-mysql -j DROP iptables -t mangle -A PREROUTING -i eth0 -p tcp -m tcp --dport 3306 -j DOCKER-mysql
Criei uma imagem do Docker que usa esse método para gerenciar automaticamente as tabelas de ip para você, usando variáveis de ambiente ou dinamicamente com o etcd (ou ambos):
https://hub.docker.com/r/colinmollenhour/confd-firewall/
fonte