Acabei de instalar a versão mais recente do docker-ce
em CentOS, mas eu não é possível alcançar portas publicadas de um servidor vizinho e não pode chegar ao exterior do próprio recipiente.
Executando um vanilla CentOS 8 simples com NetworkManager e FirewallD habilitado. A zona padrão do firewall é public
.
Versao:
-
docker-ce
19.03.3 (Docker RPM oficial)
-
containerd.io
1.2.6 (Docker RPM oficial para CentOS 7-ainda não disponível para CentOS 8)
- CentOS 8.0.1905 (instalação mínima)
Depois de passar alguns dias olhando logs e configurações para os componentes envolvidos, eu estava prestes a jogar a toalha e voltar para o Fedora 30, onde isso parece funcionar direto da caixa.
Concentrando-se em firewalling, percebi que desativar firewalld
parecia fazer o truque, mas eu preferiria não fazer isso. Ao inspecionar regras de rede com iptables
, Eu percebi que a mudança para nftables
significar iptables
agora é uma camada de abstração que mostra apenas uma pequena parte do nftables
regra. Isso significa que a maioria-se não todos-do firewalld
a configuração será aplicada fora do escopo de iptables
.
Eu estava acostumado a ser capaz de encontrar toda a verdade em iptables
, então isso vai levar algum tempo para se acostumar.
Longa história curta - para que isso funcionasse, eu tive que permitir mascarar. Parecia dockerd
já fez isso através iptables
, mas aparentemente isso precisa ser habilitado especificamente para a zona de firewall para iptables
masquerading para trabalhar:
# Masquerading allows for docker ingress and egress (this is the juicy bit)firewall-cmd --zone=public --add-masquerade --permanent# Specifically allow incoming traffic on port 80/443 (nothing new here)firewall-cmd --zone=public --add-port=80/tcpfirewall-cmd --zone=public --add-port=443/tcp# Reload firewall to apply permanent rulesfirewall-cmd --reload
Reiniciar ou reiniciar dockerd
, e a entrada e a saída devem funcionar.
O que está faltando nas respostas anteriores é o fato de que você primeiro precisa adicionar sua interface docker à zona que você configura, por exemplo, pública (ou adicioná-la à zona "confiável" sugerida aqui mas duvido que seja sábio, do ponto de vista da segurança). Porque, por padrão, não é atribuído a uma zona. Lembre - se também de recarregar o daemon do docker quando terminar.
# Check what interface docker is using, e.g. 'docker0'ip link show# Check available firewalld zones, e.g. 'public'sudo firewall-cmd --get-active-zones# Check what zone the docker interface it bound to, most likely 'no zone' yetsudo firewall-cmd --get-zone-of-interface=docker0# So add the 'docker0' interface to the 'public' zone. Changes will be visible only after firewalld reloadsudo nmcli connection modify docker0 connection.zone public# Masquerading allows for docker ingress and egress (this is the juicy bit)sudo firewall-cmd --zone=public --add-masquerade --permanent# Optional open required incomming ports (wasn't required in my tests)# sudo firewall-cmd --zone=public --add-port=443/tcp# Reload firewalldsudo firewall-cmd --reload# Reload dockerdsudo systemctl restart docker# Test ping and DNS works:docker run busybox ping -c 1 172.16.0.1docker run busybox cat /etc/resolv.confdocker run busybox ping -c 1 yourhost.local
Para poder definir regras refinadas para o Docker, não precisei definir o docker0 para nenhuma zona.
# 1. Stop Dockersystemctl stop docker
# 2. Recreate DOCKER-USER chain in firewalld. firewall-cmd --permanent \ --direct \ --remove-chain ipv4 filter DOCKER-USERfirewall-cmd --permanent \ --direct \ --remove-rules ipv4 filter DOCKER-USERfirewall-cmd --permanent \ --direct \ --add-chain ipv4 filter DOCKER-USER# (Ignore any warnings)
# 3. Docker Container <-> Container communicationfirewall-cmd --permanent \ --direct \ --add-rule ipv4 filter DOCKER-USER 1 \ -m conntrack --ctstate RELATED,ESTABLISHED \ -j ACCEPT \ -m comment \ --comment 'Allow docker containers to connect to the outside world'firewall-cmd --permanent \ --direct \ --add-rule ipv4 filter DOCKER-USER 1 \ -j RETURN \ -s 172.17.0.0/16 \ -m comment \ --comment 'allow internal docker communication'# Change the Docker Subnet to your actual one (e.g. 172.18.0.0/16)
# 4. Add rules for IPs allowed to access the Docker exposed ports.firewall-cmd --permanent \ --direct \ --add-rule ipv4 filter DOCKER-USER 1 \ -o docker0 \ -p tcp \ -m multiport \ --dports 80,443 \ -i eth0 \ -o docker0 \ -s 1.2.3.4/32 \ -j ACCEPT \ -m comment \ --comment 'Allow IP 1.2.3.4 to docker ports 80 and 443'
# 5. log docker traffic (if you like)firewall-cmd --direct \ --add-rule ipv4 filter DOCKER-USER 0 \ -j LOG \ --log-prefix ' DOCKER: '
# 6. Block all other IPs. This rule has lowest precedence, so you can add allowed IP rules later.firewall-cmd --permanent \ --direct \ --add-rule ipv4 filter DOCKER-USER 10 \ -j REJECT \ -m comment \ --comment 'reject all other traffic to DOCKER-USER'
# 7. Reload firewalld, Start Docker againfirewall-cmd --reloadsystemctl start docker
Isso termina em regras definidas em/etc / firewalld / direct.xml:
<?xml version="1.0" encoding="utf-8"?><direct> <chain ipv="ipv4" table="filter" chain="DOCKER-USER"/> <rule ipv="ipv4" table="filter" chain="DOCKER-USER" priority="0">-m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment 'Allow docker containers to connect to the outside world'</rule> <rule ipv="ipv4" table="filter" chain="DOCKER-USER" priority="0">-j RETURN -s 172.17.0.0/16 -m comment --comment 'allow internal docker communication'</rule> <rule ipv="ipv4" table="filter" chain="DOCKER-USER" priority="0">-p tcp -m multiport --dports 80,443 -s 1.2.3.4/32 -j ACCEPT -m comment --comment 'Allow IP 1.2.3.4 to docker ports 80 and 443'</rule> <rule ipv="ipv4" table="filter" chain="DOCKER-USER" priority="0">-j LOG --log-prefix ' DOCKER TCP: '</rule> <rule ipv="ipv4" table="filter" chain="DOCKER-USER" priority="10">-j REJECT -m comment --comment 'reject all other traffic to DOCKER-USER'</rule></direct>
Desvantagem ainda é que você precisa instalar containerd.io de CentOS7 como afirmado por Saustrup
Mudei a variável FirewallBackend para iptables novamente e funciona para mim.
Com esta atualização, o subsistema de filtragem nftables é o back-end padrão do firewall para o daemon firewalld. Para alterar o back-end, use a opção FirewallBackend no/etc / firewalld.arquivo conf.
Link: Centos8 Depreciado_funcionalidade
Não tenho muita informação sobre essa mudança de comportamento. Algumas das regras iptables que o Docker tenta usar não estão funcionando de acordo com os logs do CentOS8:
Aviso: COMMAND_FAILED: '/ usr / sbin / iptables - W10-D FORWARD-I docker0 - o docker0 - J DROP ' falhou: iptables: Bad rule (existe uma regra correspondente nessa cadeia?).
O meu nem funciona com firewalld completamente desativado. Alguém tem alguma ideia ??