Restringir o tráfego de rede de saída por nome de domínio (Linux)

1

Meu objetivo principal é impedir que invasores façam conexões de saída não autorizadas no meu servidor (por exemplo, para shells de conexão reversa).

Eu posso conseguir isso bloqueando todas as portas para o tráfego de saída usando "ufw", exceto aquelas que o servidor precisa para operar (por exemplo, DNS, HTTP, SSH e SMTP).

O ufw permite apenas permitir conexões DNS de saída para um endereço IP estático (assim configurarei o servidor para usar o DNS do Google) e me permite restringir o SSH de saída destinado a 127.0.0.1 (meu script de implantação automática exige isso com Git).

Como aprendi, o ufw não permite realmente restrições de saída com base em nomes de domínio, o que faz sentido (de uma perspectiva de desempenho). Eu preciso ser capaz de fazer isso para restringir as conexões SMTP de saída para o domínio do meu servidor de e-mail (atualmente apenas usando o Gmail para testar) e para conexões HTTP para servidores Ubuntu (para atualizações do sistema).

Eu sei que o iptables permite que você especifique regras baseadas em domínios, mas elas são traduzidas na inicialização e não são executadas todas as vezes (ou seja, DNS reverso). Eu sei que é por design, por motivos de desempenho.

Então, qual é a solução para restringir o tráfego de rede de saída por nome de domínio (ou seja, toda conexão de saída precisa ter seu endereço IP de destino DNS reverso e comparado com uma lista branca de nomes de domínio)?

Estou pensando que, se não conseguir fazer com que metade das restrições de saída funcionem com base em domínio, não há muito sentido em restringir DNS e SSH por IP usando o ufw.

  • Editar 1 * Então eu tenho trabalhado como usar o iptables diretamente para "encaminhar" a saída destinada a uma certa porta (por exemplo, 80) para outra porta.

Depois percebi que não haveria como saber qual era o endereço IP de destino original ao receber o tráfego encaminhado. Foi quando eu encontrei o link e descobri que ele (como um proxy Python transparente) interage com a interface iptables para descobrir qual destino original O endereço IP de um socket é.

Ainda não tenho tudo funcionando, mas tenho certeza de que essa abordagem funcione.

    
por pleasedesktop 25.01.2015 / 03:22

1 resposta

1

Isso só funciona na única máquina, porque depende do proxy transparente poder interagir com iptables e obter o IP de destino original do tráfego de saída.

Observe também que esse método é um pouco hacky, no sentido de que para superar um problema de loop infinito (redirecionando para proxy - > redirecionando para proxy - > ...), as regras de firewall são aplicadas a uma operação grupo de usuários do sistema, o que significa que qualquer usuário que não esteja no grupo não obterá o tráfego de saída encaminhado por meio do proxy.

Etapas:

  1. Crie um novo grupo de usuários do sistema operacional chamado proxy
  2. Adicione todos os usuários do sistema operacional (exceto root!) a este novo grupo
  3. Obtenha o id do grupo proxy e lembre-se dele para mais tarde
  4. Configure um servidor proxy transparente de algum tipo que possa aceitar o (s) protocolo (s) que você deseja fazer proxy e possa interagir com iptables . Eu usei mitmproxy (que é baseado em Python) e configure-o para ser executado como um serviço de root e escute em proxyPort .
  5. Adicione uma regra a iptables para redirecionar todo o tráfego de saída destinado a uma determinada porta (por exemplo, http) para 127.0.0.1: proxyPort , da seguinte forma:

    iptables -t nat -A OUTPUT -m owner --gid-owner proxyGID -p tcp --dport 80 -j DNAT --to 127.0.0.1:proxyPort , substituindo proxyGID e proxyPort de forma adequada

  6. Configure iptables ou ufw para permitir tráfego de saída para proxyPort , permitir que qualquer porta seja intermediada por proxy (por exemplo, 80) e proibir todos os outros por padrão.
  7. Configure seu proxy transparente para deixar as solicitações da maneira que quiser. Para responder a essa pergunta, você deve configurar o proxy para executar um DNS reverso no IP de destino original e verificar se o domínio resultante está em uma lista branca pré-configurada, caso contrário, o tráfego deverá ser eliminado.
por 26.01.2015 / 07:14