A conectividade IPv6 desaparece repentinamente

A conectividade IPv6 desaparece repentinamente

No ambiente especificado abaixo, o IPv4 ronrona como um gato, mas o IPv6 desaparece após um curto período de tempo – ou seja, nem mesmo o host consegue acessar seu contêiner via IPv6 pela rede Docker. Perdi algo?

Editar #1

Substituído 64:ff9b:: por algo global, mas o problema persiste. O host perde sua conectividade IPv6 (mas não IPv4) para o contêiner Docker conectado diretamente. Primeiro "Sem rota para o host" e depois o tempo limite.

manual de instruções.yml

---
- hosts: all
  become: yes
  become_method: sudo
  tasks:
  - import_tasks: tasks/firewall.yml
  - import_tasks: tasks/router.yml
  - import_tasks: tasks/docker.yml
  - name: /usr/local/docker-services
    file:
      path: /usr/local/docker-services
      owner: root
      group: root
      mode: '0700'
      state: directory
  - name: nginx-site.conf
    copy:
      dest: /usr/local/docker-services/nginx-site.conf
      owner: root
      group: root
      mode: '0666'
      src: files/nginx-site.conf
  - name: docker-compose.yml
    copy:
      dest: /usr/local/docker-services/docker-compose.yml
      owner: root
      group: root
      mode: '0666'
      content: |
        version: '2.4'
        networks:
          ext-nginx:
            internal: true
            enable_ipv6: true
            driver_opts:
              com.docker.network.bridge.name: docker1
            ipam:
              config:
              - subnet: 192.168.234.0/30
                gateway: 192.168.234.1
              - subnet: 64:ff9b::192.168.234.0/126
                gateway: 64:ff9b::192.168.234.1
        services:
          nginx:
            container_name: nginx
            image: nginx
            restart: always
            logging:
              options:
                labels: container
            labels:
              container: nginx
            networks:
              ext-nginx:
                ipv4_address: 192.168.234.2
                ipv6_address: 64:ff9b::192.168.234.2
                priority: 1
            volumes:
            - type: bind
              source: /usr/local/docker-services/nginx-site.conf
              target: /etc/nginx/conf.d/default.conf
              read_only: true
    register: docker_compose_yml
  - name: docker-compose.service
    copy:
      dest: /etc/systemd/system/docker-compose.service
      owner: root
      group: root
      mode: '0644'
      src: files/docker-compose.service
    register: docker_compose_service
  - name: systemctl daemon-reload
    when: docker_compose_service.changed
    systemd:
      daemon_reload: yes
  - name: systemctl stop docker-compose.service
    when: >-
      docker_compose_service.changed
      or docker_compose_yml.changed
    service:
      name: docker-compose
      state: stopped
  - name: systemctl start docker-compose.service
    service:
      name: docker-compose
      state: started
      enabled: yes

tarefas/firewall.yml

---
- name: Firewall rules applicator
  apt:
    name: iptables-persistent
- name: Firewall rules file
  loop: [4, 6]
  copy:
    dest: '/etc/iptables/rules.v{{ item }}'
    owner: root
    group: root
    mode: '0644'
    src: 'files/firewall/rules.v{{ item }}'
  register: firewall_file
- name: Apply firewall rules
  when: 'firewall_file.results[0].changed or firewall_file.results[1].changed'
  service:
    name: netfilter-persistent
    state: restarted

tarefas/router.yml

---
- name: net.ipv4.ip_forward
  sysctl:
    name: net.ipv4.ip_forward
    value: '1'
- name: net.ipv6.conf.all.forwarding
  sysctl:
    name: net.ipv6.conf.all.forwarding
    value: '1'

tarefas/docker.yml

---
- name: apt-transport-https
  apt:
    name: apt-transport-https
- name: Docker apt key
  apt_key:
    url: https://download.docker.com/linux/debian/gpg
- name: Docker apt repo
  apt_repository:
    filename: docker
    repo: >
      deb https://download.docker.com/linux/debian
      {{ ansible_lsb.codename }} stable
- name: /etc/docker
  file:
    path: /etc/docker
    owner: root
    group: root
    mode: '0755'
    state: directory
- name: /etc/docker/daemon.json
  copy:
    dest: /etc/docker/daemon.json
    owner: root
    group: root
    mode: '0644'
    content: '{"iptables":false}'
- name: Docker
  apt:
    name: docker-ce
- name: Docker compose
  apt:
    name: docker-compose

arquivos/firewall/rules.v4

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -d 127.0.0.0/8 ! -i lo -j DROP
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A FORWARD -o docker1 -d 192.168.234.2/32 -p tcp -m tcp --dport 80 -j ACCEPT
-A FORWARD -i docker1 -o eth0 -j ACCEPT
-A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -i eth0 -d 78.47.124.58 -p tcp -m tcp --dport 80 -j DNAT --to 192.168.234.2
-A POSTROUTING -o eth0 ! -s 78.47.124.58 -j MASQUERADE
COMMIT

arquivos/firewall/rules.v6

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -d ::1/128 ! -i lo -j DROP
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A FORWARD -o docker1 -d 64:ff9b::192.168.234.2 -p tcp -m tcp --dport 80 -j ACCEPT
-A FORWARD -i docker1 -o eth0 -j ACCEPT
-A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -i eth0 -d 2a01:4f8:c0c:3bc1::/64 -p tcp -m tcp --dport 80 -j DNAT --to 64:ff9b::192.168.234.2
-A POSTROUTING -o eth0 ! -s 2a01:4f8:c0c:3bc1::/64 -j MASQUERADE
COMMIT

arquivos/nginx-site.conf

server {
    listen       80;
    listen       [::]:80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

arquivos/docker-compose.service

[Unit]
Requires=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/usr/local/docker-services
ExecStart=/usr/bin/docker-compose up -d --force-recreate
ExecStop=/usr/bin/docker-compose down

[Install]
WantedBy=multi-user.target

Responder1

Meu palpite é que suas regras de firewall IPv6 estão bloqueandoNDP (protocolo de descoberta de vizinho)pacotes, evitando assim que seu host resolva o endereço da camada de enlace do contêiner corretamente.

Na pilha IPv4, a resolução dos endereços da camada de enlace (Ethernet) é tratada porARP (protocolo de resolução de endereço), que funciona usando endereços da camada de enlace como destinos de pacotes. Quando um host emite solicitações ARP ou anúncios ARP não solicitados, esses pacotes são encaminhados diretamente para o endereço da camada de enlace de transmissão (que está FF:FF:FF:FF:FF:FFno protocolo Ethernet) e, por isso, não estão sujeitos a iptablesfiltragem.

Na pilha IPv6, a resolução dos endereços da camada de enlace é tratada pelo NDP (Neighbour Discovery Protocol). Ao contrário do ARP, os pacotes NDP são, na verdade, pacotes ICMPv6 encaminhados para endereços IPv6 e, como resultado, sujeitos a ip6tablesfiltragem.

Acredito que, de acordo com a minha experiência e como visto emArtigo Wiki do Arch Linux, o módulo CONNTRACK não foi projetado para rastrear pacotes NDP ICMPv6 e marcar pacotes de resposta comoESTABELECIDOouRELACIONADO. Minha sugestão é permitir esse tráfego explicitamente no files/firewall/rules.v6arquivo:

(novas regras)

-A INPUT -i docker1 -p ipv6-icmp -m icmp6 --icmpv6-type 133 -m comment --comment router-solicitation -j ACCEPT
-A INPUT -i eth0 -p ipv6-icmp -m icmp6 --icmpv6-type 134 -m comment --comment router-advertisement -j ACCEPT
-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 135 -m comment --comment neighbor-solicitation -j ACCEPT
-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 136 -m comment --comment neighbor-advertisement -j ACCEPT

(arquivo completo)

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -d ::1/128 ! -i lo -j DROP
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i docker1 -p ipv6-icmp -m icmp6 --icmpv6-type 133 -m comment --comment router-solicitation -j ACCEPT
-A INPUT -i eth0 -p ipv6-icmp -m icmp6 --icmpv6-type 134 -m comment --comment router-advertisement -j ACCEPT
-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 135 -m comment --comment neighbor-solicitation -j ACCEPT
-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type 136 -m comment --comment neighbor-advertisement -j ACCEPT
-A FORWARD -o docker1 -d 64:ff9b::192.168.234.2 -p tcp -m tcp --dport 80 -j ACCEPT
-A FORWARD -i docker1 -o eth0 -j ACCEPT
-A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -i eth0 -d 2a01:4f8:c0c:3bc1::/64 -p tcp -m tcp --dport 80 -j DNAT --to 64:ff9b::192.168.234.2
-A POSTROUTING -o eth0 ! -s 2a01:4f8:c0c:3bc1::/64 -j MASQUERADE
COMMIT

informação relacionada