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 atingir meu objetivo? Entendendo 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, em seguida, permitir apenas conexões de meus hosts. Mas as regras e cadeias NAT do Docker atrapalham e minhas regras de entrada são ignoradas.
Alguém pode fornecer um exemplo de como realizar meu objetivo, dadas as seguintes suposições?
IP público do Host 80.80.80.80 no eth0
IP privado do Host 192.168.1.10 no eth1
docker run -d -p 3306:3306 mysql
Bloqueie toda a conexão com o host / container 3306, exceto dos 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 iptables corretamente, que sobrevivem ao processo do docker e ao reinício do host.
Duas coisas a ter em mente ao trabalhar com as regras de firewall do docker:
Para evitar que suas regras sejam clobbered pelo docker, use o DOCKER-USER cadeia
O Docker faz o mapeamento de porta no PREROUTING cadeia do nat tabela. Isso acontece antes do filter regras, então --dest e --dport verá 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 --ctdir ORIGINAL -j ACCEPTiptables -A DOCKER-USER -i eth0 -s 4.4.4.4 -p tcp -m conntrack --ctorigdstport 3306 --ctdir ORIGINAL -j ACCEPTiptables -A DOCKER-USER -i eth0 -p tcp -m conntrack --ctorigdstport 3306 --ctdir ORIGINAL -j DROP
Nota: sem --ctdir ORIGINAL, isso também corresponderia aos pacotes de resposta voltando para uma conexão do contêiner à porta 3306 em algum outro servidor, o que quase certamente não é o que você deseja! Você não precisa estritamente disso se como Eu sua primeira regra é -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT, como isso vai lidar com todos os pacotes de resposta, mas seria mais seguro ainda usar --ctdir ORIGINAL assim.
Ao contrário do DOCKER chain, ele não é redefinido na construção/inicialização de contêineres. Portanto, você pode adicionar essas linhas à configuração/script iptables para provisionar o servidor antes mesmo de instalar o docker e iniciar os contêineres:
Agora, a porta do MySQL está bloqueada do acesso externo (eth0), mesmo que o docker tenha aberto a porta para o mundo. (Essas regras assumem que sua interface externa é eth0.)
Eventualmente, você terá que limpar o iptables reinicie o serviço docker primeiro, se você bagunçou demais tentando bloquear a porta como eu fiz.
Eu construí uma imagem do Docker que usa esse método para gerenciar automaticamente os iptables para você, usando variáveis de ambiente ou dinamicamente com etcd (ou ambos):
As regras de encaminhamento do Docker permitem Todos os IPs de origem externa por padrão. Para permitir que apenas um IP ou rede específica acesse os contêineres, insira uma regra negada na parte superior da cadeia de filtros do DOCKER. Por exemplo, para restringir o acesso externo de modo que apenas o IP de origem 8.8.8.8 possa acessar os contêineres, a seguinte regra pode ser adicionada: iptables -I DOCKER -i ext_if ! -s 8.8.8.8 -j DROP