O UFW (Uncomplicated Firewall) não está bloqueando nada ao usar o Docker

44

Esta é a primeira vez que configuro um servidor Ubuntu (14.04 LTS) e estou tendo problemas para configurar o firewall (UFW).

Eu só preciso sshe http, portanto, estou fazendo o seguinte:

sudo ufw disable

sudo ufw reset
sudo ufw default deny incoming
sudo ufw default allow outgoing

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp

sudo ufw enable
sudo reboot

Mas ainda posso conectar-me aos bancos de dados em outras portas desta máquina . Alguma idéia do que estou fazendo de errado?

EDIT : esses bancos de dados estão em contêineres do Docker. Isso pode estar relacionado? está substituindo minha configuração ufw?

EDIT2 : saída desudo ufw status verbose

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW IN    Anywhere
80/tcp                     ALLOW IN    Anywhere
22/tcp (v6)                ALLOW IN    Anywhere (v6)
80/tcp (v6)                ALLOW IN    Anywhere (v6)
ESala
fonte
qual banco de dados? qual porta? Tem certeza de que esta é a mesma máquina? qual é a saída de ufw status
solsTiCe
@solsTiCe sim, tenho certeza de que é a mesma máquina. O banco de dados é o InfluxDB (em um contêiner de docker) com portas 8083e 8086. Eu adicionei a ufw status verbosesaída na pergunta. Obrigado.
ESala 25/07

Respostas:

64

O problema estava usando a -pbandeira em contêineres.

Acontece que o Docker faz alterações diretamente no seu iptables, que não são mostradas com ufw status.

As soluções possíveis são:

  1. Pare de usar a -pbandeira. Use a ligação docker ou redes docker .

  2. Vincule recipientes localmente para que não fiquem expostos fora da sua máquina:

    docker run -p 127.0.0.1:8080:8080 ...

  3. Se você insistir em usar o -psinalizador, diga ao docker para não tocar no seu iptables, desativando-o /etc/docker/daemon.jsone reiniciando:

    { "iptables" : false }

Eu recomendo as opções 1 ou 2. Observe que a opção 3 tem efeitos colaterais , como os contêineres que não conseguem se conectar à Internet.

ESala
fonte
8
Isso é muito útil - eu estava ficando louco por poder acessar portas que eu não permitia no ufw. Porém, o uso de iptables = false quebra muito, como contêineres se tornando acessíveis no host local, por exemplo, para proxy reverso. Melhor garantir que o contêiner escute corretamente, não use -p 80:80, mas -p 127.0.0.1:80:80 ou porta diferente como 127.0.0.1:3000:80 para proxy reverso com nginx ou apache e sem porta confrontos.
Andreas Reiff
2
@AndreasReiff você está certo, mas ultimamente acho melhor evitar -po máximo possível. Por exemplo, no caso de um proxy reverso, não mapeio nenhuma porta para os contêineres de trabalho e, em seguida, coloco nginx em seu próprio contêiner com -p 80:80e a --linkpara os outros. Dessa forma, não pode haver nenhum conflito de porta e o único ponto de acesso é através do nginx.
ESala 03/04
1
Verifique também este post para uma terceira precaução que você deve tomar! svenv.nl/unixandlinux/dockerufw
Henk
1
Importante : /etc/default/dockeré um arquivo de configuração usado pela configuração inicial. Se você passou do iniciante para o systemd, esse arquivo não será usado.
Orshachar 5/10
@ESala Você deve desmarcar esta resposta como correta, pois está desatualizada.
Ctbrown # 12/17
8

16.04 apresenta novos desafios. Executei todas as etapas conforme mostrado Executando o Docker por trás do firewall ufw, MAS NÃO POSSO fazer o docker plus UFW funcionar no 16.04. Em outras palavras, não importa o que eu fiz, todas as portas do docker ficaram expostas globalmente à Internet. Até encontrar o seguinte: Como configurar o Docker 1.12+ para NÃO interferir no IPTABLES / FirewallD

Eu tive que criar o arquivo /etc/docker/daemon.jsone colocar o seguinte em:

{
    "iptables": false
}

Em seguida, emiti sudo service docker stope sudo service docker startfinalmente o docker está simplesmente seguindo as regras apropriadas no UFW.

Dados adicionais: o Docker substitui o UFW!

Hal Jordan
fonte
Com o Ubuntu 16.04 e o Docker versão 17.09, essa solução interrompe a conexão de saída dos contêineres. Veja a resposta askubuntu.com/a/833363/262702 e askubuntu.com/a/954041/262702
ctbrown
5

Se você estiver usando o sistema init do systemd (Ubuntu 15.10 e posterior), edite o /etc/docker/daemon.json(pode ser necessário criá-lo se ele não existir), verifique se ele possui a iptableschave configurada:

{   "iptables" : false }

EDIT : isso pode fazer com que você perca a conexão com a Internet a partir de contêineres

Se o UFW estiver ativado, verifique se você pode acessar a Internet a partir de contêineres. Não se - você deve definir DEFAULT_FORWARD_POLICYcomo ACCEPTsobre /etc/default/ufwe aplicar o truque descrito aqui: https://stackoverflow.com/a/17498195/507564

orshachar
fonte
2

Uma solução rápida é executar o Docker e fazer o mapeamento de portas. Você sempre pode fazer

docker run ...-p 127.0.0.1:<ext pot>:<internal port> ...

para impedir que seu Docker seja acessado de fora.

kimy82
fonte
2

Uso de /etc/docker/daemon.jsoncom conteúdo

{
  "iptables": false
}

pode parecer uma solução, mas só funciona até a próxima reinicialização . Depois disso, você poderá perceber que nenhum dos seus contêineres tem acesso à Internet; portanto, você não pode, por exemplo, executar ping em qualquer site. Pode ser um comportamento indesejado.

O mesmo se aplica à ligação de um contêiner a um IP específico. Você pode não querer fazer isso. A melhor opção é criar um contêiner e colocá-lo atrás da UFW, independentemente do que aconteça e como você o cria, então há uma solução:

Depois de criar o /etc/docker/daemon.jsonarquivo, chame:

sed -i -e 's/DEFAULT_FORWARD_POLICY="DROP"/DEFAULT_FORWARD_POLICY="ACCEPT"/g' /etc/default/ufw
ufw reload

então você configura a política de encaminhamento padrão no UFW para aceitação e usa:

iptables -t nat -A POSTROUTING ! -o docker0 -s 172.17.0.0/16 -j MASQUERADE

Se você estiver prestes a usar o docker-compose, o IP a partir do comando acima deve ser substituído pelo IP da rede que o docker-compose cria ao executá-lo docker-compose up.

Descrevi o problema e a solução de maneira mais abrangente neste artigo

Espero que ajude!

mkubaczyk
fonte
1

No meu caso, acabei modificando o iptables para permitir o acesso ao Docker apenas a partir de IPs específicos.

Conforme resposta da ESala :

Se você usar -psinalizador em contêineres, o Docker fará alterações diretamente no iptables, ignorando o ufw.

Exemplo de registros adicionados ao iptables pelo Docker

Roteamento para a cadeia 'DOCKER':

-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER

Encaminhando pacotes da cadeia 'DOCKER' para o contêiner:

-A DOCKER -i docker0 -j RETURN
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 6379 -j DNAT --to-destination 172.17.0.3:6379

Você pode modificar o iptables para permitir o acesso à cadeia DOCKER apenas a partir do IP de origem especificado (por exemplo 1.1.1.1):

-A PREROUTING -s 1.1.1.1 -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT -s 1.1.1.1 ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER

Você pode usar iptables-save > /tmp/iptables.confe iptables-restore < /tmp/iptables.confdespejar, editar e restaurar regras do iptables.

Mecânico de IA
fonte
0

Use --network = host ao iniciar o contêiner, para que o docker mapeie a porta para uma rede isolada somente para host, em vez da rede de ponte padrão. Não vejo maneiras legais de bloquear a rede em ponte. Como alternativa, você pode usar uma rede definida pelo usuário personalizada com isolamento.

codificador
fonte
0
  1. Faça login no console do docker:

    sudo docker exec -i -t docker_image_name / bin / bash

  2. E depois dentro do seu docker console:

    sudo apt-get update
    sudo apt-get install ufw
    sudo ufw allow 22
    
  3. Adicione suas regras de ufw e ative o ufw

    sudo ufw enable

    • Sua imagem do Docker precisa ser iniciada com --cap-add = NET_ADMIN

Para habilitar a opção do Docker "NET_ADMIN":

1. Stop Container:

docker para seu contêiner; 2.Get ID do recipiente:

a janela de encaixe inspeciona seu contêiner; 3.Modifique o hostconfig.json (caminho padrão do docker: / var / lib / docker, você pode alterar o seu)

vim /var/lib/docker/containers/containerid/hostconfig.json

4. Procure "CapAdd" e modifique null para ["NET_ADMIN"];

...., "VolumesFrom": null, "CapAdd": ["NET_ADMIN"], "CapDrop": null, .... 5.Reinicie a janela de encaixe na máquina host;

reinicialização do docker de serviço; 6.Start yourconatiner;

docker iniciar seu contêiner;

Stefan
fonte
0

Eu costumava docker-composeiniciar vários contêineres e também tinha o problema de que uma porta estava exposta ao mundo ignorando as regras do ufw.

A correção para disponibilizar apenas a porta para meus contêineres de docker foi essa alteração no meu docker-compose.ymlarquivo:

ports:
- "1234:1234"

para isso:

ports:
- "1234"

Agora os outros docker-containers ainda podem usar a porta, mas não consigo acessá-la de fora.

TmTron
fonte