Etapas para limitar as conexões externas ao contêiner docker com iptables?

11

Meu objetivo é limitar o acesso a contêineres do Docker a apenas alguns endereços IP públicos. Existe um processo simples e repetitivo para atingir meu objetivo? Entendendo apenas o básico do iptables enquanto uso as opções padrão do Docker, estou achando muito difícil.

Gostaria de executar um contêiner, torná-lo visível para a Internet pública, mas permitir conexões apenas de hosts selecionados. Eu esperaria definir uma política INPUT padrão de REJECT e só permitir conexões dos 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 atingir minha meta, considerando as seguintes suposições?

  • IP público do host 80.80.80.80 em eth0
  • IP privado do host 192.168.1.10 na eth1
  • docker run -d -p 3306:3306 mysql
  • Bloqueia toda a conexão ao host / contêiner 3306, exceto dos hosts 4.4.4.4 e 8.8.8.8

Tenho a satisfação de vincular o contêiner apenas ao endereço IP local, mas precisaria de instruções sobre como configurar corretamente as regras de encaminhamento do iptables, que sobrevivem ao processo do docker e à reinicialização do host.

Obrigado!

    
por GGGforce 09.07.2015 / 16:36

4 respostas

2

Duas coisas que você deve ter em mente ao trabalhar com as regras de firewall do docker:

  1. Para evitar que suas regras sejam prejudicadas pela janela de encaixe, use a DOCKER-USER chain
  2. O Docker faz o mapeamento de portas na cadeia PREROUTING da tabela nat . Isso acontece antes das regras filter , portanto, --dest e --dport verão o IP interno e a porta do contêiner. Para acessar o destino original, você pode usar -m conntrack --ctorigdstport .

Por exemplo:

iptables -A DOCKER-USER -i eth0 -s 8.8.8.8 -p tcp -m conntrack --ctorigdstport 3306 -j ACCEPT
iptables -A DOCKER-USER -i eth0 -s 4.4.4.4 -p tcp -m conntrack --ctorigdstport 3306 -j ACCEPT
iptables -A DOCKER-USER -i eth0 -p tcp -m conntrack --ctorigdstport 3306 -j DROP
    
por 03.10.2018 / 18:05
6

Com o Docker v.17.06, há uma nova cadeia de iptables chamada DOCKER-USER. Essa é uma das regras personalizadas: link

Ao contrário da cadeia DOCKER, ela não é redefinida nos contêineres de construção / partida. Então você pode adicionar essas linhas ao seu config / script do iptables para provisionar o servidor antes mesmo de instalar o docker e iniciar os containers:

-N DOCKER
-N DOCKER-ISOLATION
-N DOCKER-USER
-A DOCKER-ISOLATION -j RETURN
-A DOCKER-USER -i eth0 -p tcp -m tcp --dport 3306 -j DROP
-A DOCKER-USER -j RETURN

Agora a porta para o MySQL está bloqueada de acesso externo (eth0), mesmo pensando que o docker abre a porta para o mundo. (Essas regras assumem que sua interface externa é eth0.)

Eventualmente, você terá que limpar o iptables reiniciar o serviço docker primeiro, se você mexeu muito tentando bloquear a porta como eu fiz.

    
por 02.12.2017 / 11:56
4

UPDATE : embora válida em 2015, essa solução não é mais o jeito certo de fazê-lo.

A resposta parece estar na documentação do Docker, no link

Docker’s forward rules permit all external source IPs by default. To allow only a specific IP or network to access the containers, insert a negated rule at the top of the DOCKER filter chain. For example, to restrict external access such that only source IP 8.8.8.8 can access the containers, the following rule could be added: iptables -I DOCKER -i ext_if ! -s 8.8.8.8 -j DROP

O que acabei fazendo foi:

iptables -I DOCKER -i eth0 -s 8.8.8.8 -p tcp --dport 3306 -j ACCEPT
iptables -I DOCKER -i eth0 -s 4.4.4.4 -p tcp --dport 3306 -j ACCEPT
iptables -I DOCKER 3 -i eth0 -p tcp --dport 3306 -j DROP

Eu não toquei nas opções --iptables ou --icc .

    
por 10.07.2015 / 00:17
3

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 que você afete a porta exposta em vez da 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

Eu construí uma imagem do Docker que usa este método para gerenciar automaticamente o iptables para você, usando variáveis de ambiente ou dinamicamente com o etcd (ou ambos):

link

    
por 07.12.2017 / 17:22