Total de visualizações da página hoje

Pesquisar este blog

segunda-feira, 9 de janeiro de 2017

Firewall Iptables

clip_image002
O Iptables é um firewall em nível de pacotes, ou seja, toma as decisões baseadas nos parâmetros do pacote, como porta/endereço de origem/destino, estado da conexão, e outros parâmetros do pacote. Funciona através da comparação de regras para saber se um pacote tem ou não permissão para passar. O iptables tem inúmeras possibilidades de controle oferecidas pelos recursos de filtragem, flexibilidade na manipulação dando lugar à imaginação do administrador.
Algumas aplicações do iptables:
  • Construir firewalls de Internet baseados em filtragem de pacotes "stateless" e "stateful"
  • Usar NAT e masquerading para compartilhamento de Internet com uma rede local
  • Usar NAT para implementar proxies transparentes
  • Realizar manipulação de pacotes adicional (mangling), como alterar bits no cabeçalho IP
  • Monitorar o volume de tráfego de rede
  • Realizar Encaminhamento de Portas (que é um tipo de DNAT)
  • Balanceamento de carga de rede.
Entre outras aplicações.
Funcionamento do iptables:
O firewall iptables trabalha comparando o tráfego de rede que a máquina recebe com um conjunto de regras pré-especificadas, as quais definem as características que os pacotes devem possuir para corresponderem às regras, e as ações que serão tomadas para esses pacotes.
Podemos criar regras que verifiquem a correspondência de uma pacote com uma regra específica de várias formas, como por exemplo por tipo de protocolo, portas de origem ou destino, endereços IP de origem ou destino, interfaces em uso, tipos de mensagens, entre muitas outras.
Quando ocorre uma correspondência entre um pacote e uma regra, uma ação será tomada, e a essa ação dá-se o nome de target. O target (“objetivo”) pode determinar se um pacote será aceito ou descartado, movido para outra cadeia para processamento, logado, ou ainda outras opções.
A arquitetura do iptables agrupa o processamento dos pacotes de rede em tabelas por função (filtro de pacotes, tradução de endereços de rede e outras formas de configuração de pacotes), cada qual possui cadeias (chains) de regras de processamento. As regras consistem em correspondências (matches) usadas para determinar a quais pacotes cada regra será aplicada, e objetivos (targets), que determinam o que será feito com os pacotes que correspondam às regras.
Tabelas
O iptables organiza suas regras em uma estrutura que contém tabelas e cadeias. As tabelas são um agrupamento de cadeias em um nível mais alto, e determinam grosso modo o escopo das regras que serão criadas. O iptables possui três tabelas ou listas de regras:
  • filter - Tabela padrão para manipular pacotes de rede, usada para configurar políticas para o tráfego que entra, atravessa ou sai do computador.
  • nat - Usada para alterar pacotes que criam uma nova conexão, e para redirecionar conexões para NAT..
  • mangle - Usada para tipos específicos de alteração de pacotes, como a modificação de opções do cabeçalho IP de um pacote..
  • raw - Marca pacotes que não devem ser manipulados pelo sistema de rastreamento de conexões.
Uma tabela contém cadeias, e as cadeias contém regras, como podemos ver na figura a seguir:
clip_image003
As tabelas possuem as cadeias a seguir:
Tabela FIlter: Cadeias INPUT, OUTPUT e FORWARD
Tabela NAT: Cadeias PREROUTING, OUTPUT, POSTROUTING
Tabela Mangle: Cadeias PREROUTING, OUTPUT, POSTROUTING, INPUT e FORWARD
Tabela raw: Cadeias PREROUTING e OUTPUT
Tabela security - Usada para regras de rede MAC (Mandatory Access Control)
Cadeias
As regras são organizadas em grupos denominados cadeias (chains), que por sua vez ficam contidas nas tabelas. Uma cadeia é então um conjunto de regras usadas para verificar a correspondência com um pacote - de forma sequencial. Um pacote é verificado junto às regras na chain, e se não há correspondência, a próxima regra na ordem é verificada. Quando um pacote corresponde a uma regra na cadeia, a ação associada a essa regra é executada e as regras restantes não são verificadas contra esse pacote. Caso nenhuma regra corresponda ao pacote, a regra padrão (policy) será aplicada.
Podemos criar nossas próprias cadeias se for necessário, mas no geral utilizamos as cadeias já existentes e definidas por padrão. São elas:
  • INPUT - aplica regras aos pacotes de rede que chegam ao servidor.
  • OUTPUT - aplica regras aos pacotes de rede originados e que partem do servidor.
  • FORWARD -  aplica regras aos pacotes de rede roteados através do servidor (para outro servidor ou outra interface de rede no mesmo servidor)
  • PREROUTING - Altera pacotes de rede quando eles chegam e antes do roteamento. Usado para DNAT (Destination NAT)
  • POSTROUTING - Altera pacotes de rede após o roteamento. Usado para SNAT (Source NAT)
As cadeias podem ter zero ou mais regras, e possuem uma política padrão. A política (policy) determina o que acontece com um pacote caso nenhuma das regras da cadeia corresponda a ele, e somente pode ser ACCEPT ou DROP (RETURN para cadeias definidas pelo usuário).
Por meio de módulos que podem ser carregados via regras, o iptables também pode rastrear conexões. Assim, podemos criar regras que definem o que acontece com um pacote baseado em sua relação com pacotes anteriores. Chamamos essa técnica de “rastreamento de estado” ou “rastreamento de conexão”.
Veja nas figuras a seguir a relação entre as cadeias apresentadas e as tabelas filter, nat e mangle:
clip_image004
  1. Fluxo de pacotes de rede e pontos de hook da tabela filter
clip_image005
2. Fluxo de pacotes de rede e pontos de hook da tabela NAT
clip_image006
3. Fluxo de pacotes de rede e pontos de hook da tabela mangle
Regras (Rules)
Uma regra do iptables consiste em um ou mais critérios de correspondência que determinam quais pacotes de rede serão afetados, e uma especificação de objetivo (“target”) que determina como o pacote de rede será afetado. Para que a regra seja aplicada a um pacote todas as opções de correspondência listadas na regra devem ser satisfeitas. Se não houver um critério de correspondência especificado na regra, então todos os pacotes serão considerados como correspondentes.
Há muitas correspondências (“matches”) disponíveis para uso com o iptables. Além das correspondências genéricas, como tipo de protocolo, IP de origem e destino, portas de comunicação, entre outras, também é possível utilizar correspondências (parâmetros) disponibilizados por meio de extensões carregadas dinamicamente, e informadas na regra com o uso da opção -m ou --match.
Já as ações (targets / objetivos) são usadas para especificar a ação que será tomada quando uma regra corresponder a um pacote e também para especificar a regra padrão da cadeia. Há quatro targets disponíveis no iptables, e podemos acrescentar outros por meio de módulos de extensão. Os targets padrão são ACCEPT, DROP, QUEUE e RETURN, descritos à frente no texto.
A estrutura geral de uma regra é a seguinte:
iptables subcomando chain parâmetro_1 valor_1 parâmetro_n valor_n ação
Os subcomandos principais que podem ser usados são os seguintes:
-A anexa a regra no final da cadeia especificada
-F apaga todas as regras na cadeia especificada
-L lista todas as regras da cadeia
-N cria uma nova cadeia com o nome desejado
-P configura a regra padrão da cadeia
-D apaga uma regra em uma posição na cadeia
-X exclui uma cadeia vazia
-I insere uma regra em uma posição na cadeia

Já as ações (targets) possíveis estão listadas na tabela a seguir:
Ações embutidas no iptables:
ACCEPT - pacote permitido
DROP - Descartar o pacote
QUEUE - Enviar o pacote ao userspace (código fora do kernel)
RETURN - Descontinuar o processamento do pacote e aplicar a regra padrão a ele.
Ações adicionais:
REJECT - Descarta o pacote e envia feedback ao remetente.
DNAT - reescreve endereço de destino (NAT)
SNAT - reescreve endereço de origem (NAT)
LOG - coloca no log informações sobre o pacote

Com relação aos parâmetros, existem dezenas deles para que possamos criar regras dos mais variados tipos. Na tabela a seguir listamos alguns dos parâmetros mais comuns:
Parâmetro Significado
-t tabela  Especificar a tabela (filter é a padrão)
-j ação Realiza a ação especificada
-p protocolo Especifica o protocolo (icmp, tcp, udp, all)
-s IP IP de origem do pacote
-d IP IP de destino do pacote
-i interface Nome da interface de rede de entrada do pacote
-o interface Nome da interface de rede de saída do pacote
--sport portas Portas de origem
--dport portas Portas de destino
--syn Identifica nova requisição de conexão
--icmp-type tipo de mensagem ICMP


Podemos visualizar as regras atuais de uma cadeia por meio do comando iptables -L (ou iptables --list):
# iptables -L
clip_image007
Veja que não há nenhuma regra criada, além da regra padrão (policy), que está configurada para aceitar todos os pacotes em todas as cadeias. Como não especificamos a tabela, a saída mostrada é a da tabela padrão, que é a FILTER. Para especificarmos uma outra tabela, usamos a opçãa -t. Veja no exemplo abaixo a listagem da tabela nat:
# iptables -t nat -L
clip_image008
Perceba que neste caso aparecem também as cadeias específicas PREROUTING e POSTROUTING.
Os campos mostrados na saída do comando de listagem de regras são os seguintes:
target - Ação a ser realizada no pacote
prot - Protocolo especificado
opt - Opções especiais da regra
source - Endereço IP de origem do pacote
destination - Endereço IP de destino do pacote.
num - Exibido com a opção --line-numbers. Mostra o número da regra dentro da cadeia.
Vamos analisar um exemplo típico de uma regra do iptables:
iptables -A INPUT -s 0/0 -i eth0 -d 192.168.1.1 -p TCP -j ACCEPT
Destrinchando a regra acima, temos:
iptables - Comando iptables
-A INPUT - Anexar a regra no final da cadeia INPUT
-s 0/0 - Endereço IP de origem: qualquer um
-i eth0 - Interface de entrada a ser monitorada: eth0
-d 192.168.1.1 - Endereço IP de destino do pacote: 192.168.1.1
-p TCP - Protocolo a ser verificado: TCP
-j ACCEPT - Ação a ser aplicada no pacote: ACCEPT (permitir)
Limpando as regras de uma cadeia
Podemos apagar todas as regras de uma cadeia (exceto a regra padrão) com a opção -F:
# iptables -F INPUT
Ou limpar todas as regras de todas as cadeias da tabela especificada:
# iptables -F
Configurando a regra padrão de uma cadeia
Usamos a opção -P para configurar a regra padrão de uma cadeia. Veja os exemplos:
# iptables -P INPUT DROP
# iptables -P OUTPUT ACCEPT
# iptables -L
clip_image009
Rastreamento de conexões (Connection Tracking)
O iptables associa os pacotes com as conexões lógicas às quais eles pertencem. Para isso, ele segue o progresso das conexões através de seu ciclo de vida, e essa informação de rastreamento é disponibilizada por meio da extensão de equivalência conntrack.
A tabela a seguir mostra os estados de rastreamento de conexão mais comuns:
Estado Descrição
ESTABLISHED A conexão já viu pacotes trafegando em ambas as direções.
INVALID O pacote não pertence a nenhuma conexão rastreada
NEW O pacote está iniciando uma nova conexão ou é parte de uma conexão que ainda não teve pacotes trafegados em ambas as direções.
RELATED O pacote está iniciando uma nova conexão, mas a nova conexão é relacionada a uma conexão já existente (como a conexão de dados em uma transferência FTP).

Alguns exemplos de regras do iptables
1. Vamos começar configurando as regras-padrão da tabela FILTER. Vamos descartar todos os pacotes que chegam ao servidor por meio da cadeia INPUT e liberar todos os pacotes originados no servidor por meio da cadeia OUTPUT:
# iptables -P INPUT DROP
# iptables -P OUTPUT ACCEPT
2. Vamos testar o acesso ao servidor via SSH usando o PuTTY. A conexão será negada, pois todas as conexões entrantes estão bloqueadas no momento:
clip_image010
Devemos, então, liberar o acesso SSH por meio da porta 22 com a regra a seguir:
# iptables -A INPUT -p tcp --dport 22 -j ACCEPT
Testamos agora a conexão via PuTTY:
clip_image011
Conexão efetuada com sucesso, pois a porta 22 está agora liberada. Vejamos a regra criada no firewall:
# iptables -L --line-numbers
clip_image013
Isso é muito importante caso desejemos inserir uma regra nova em uma posição específica, ou excluir uma regra sem afetar as demais.
Podemos também ver una versão resumida das regras atuais do firewall com a opção -S:
# iptables -S
clip_image0153. Muitos servidores Linux permitem acesso via interface Web a seus serviços administrativos. Para que isso funcione, é necessário liberar a porta usada pelo servidor web, que normalmente é a porta 80. Liberaremos também o protocolo HTTPS, que usa a porta 443. Vamos liberá-las:
# iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT
# iptables -A INPUT -m state --state NEW -p tcp --dport 443 -j ACCEPT
4. Geralmente os serviços em um computador se comunicam entre si enviando pacotes de rede de um para outro. Para isso, é usada normalmente a interface de rede de loopback, a qual direciona o tráfego de rede de volta para o próprio servidor, em vez de enviá-lo para a rede local.
Vamos então liberar o tráfego na interface de loopback:
# iptables -I INPUT 1 -i lo -j ACCEPT
Neste caso, a opção -I nos permite inserir a regra em uma posição específica na cadeia INPUT - no caso, na posição número 1. E com a opção -i podemos selecionar a interface a ser afetada, lo, que é a interface de loobback.
4. Agora vamos bloquear todo o tráfego proveniente de um IP específico na rede. Bloquearemos o tráfego do IP 10.10.10.20 para o nosso servidor:
# iptables -A INPUT -s 10.10.10.20 -j DROP
5. Podemos aceitar todo o tráfego na cadeia INPUT proveniente de um computador em particular na rede, por meio de seu MAC Address:
# iptables -A INPUT -m mac --mac-source 00:12:A1:24:BB:0C -j ACCEPT
6. Bloqueando o ping. Vamos bloquear as mensagens de requisição de eco do icmp, de modo que nosso servidor não responderá a requisições de ping:
# iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
7. Porém o servidor ainda pode enviar requisições de ping para outras máquinas. Se quisermos bloquear as requisições de saída devemos criar a regra a seguir:
# iptables -A OUTPUT -p icmp --icmp-type echo-request -j DROP
Se quisermos bloquear as mensagens de resposta do ping, devemos usar o tipo de icmp echo-reply.
8. Suponhamos que seja necessário abrir uma faixa de portas no servidor, como por exemplo, as portas de 5100 a 5150. Não precisamos criar uma regra para cada porta. Em vez disso, indicamos na regra que queremos usar uma faixa de portas em vez de uma única:
# iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 5100:5150 -j ACCEPT
9. Liberando o servidor de impressão na rede local 10.10.0.0/24: para isso temos de liberar as portas do CUPS, que são as portas 631 TCP e UDP:
# iptables -A INPUT -s 10.10.1.0/24 -p udp -m udp --dport 631 -j ACCEPT
# iptables -A INPUT -s 10.10.1.0/24 -p tcp -m tcp --dport 631 -j ACCEPT

10. Caso seu servidor Linux também seja o servidor DNS da rede, será necessário liberar as portas adequadas para os clientes da rede:
# iptables -A INPUT -m state --state NEW -p udp --dport 53 -j ACCEPT
# iptables -A INPUT -m state --state NEW -p tcp --dport 53 -j ACCEPT

11. É muito comum termos um servidor de arquivos em Linux na rede, servindo a clientes Windows via SAMBA. Vamos então liberar acesso ao servidor de arquivos para os clientes de nossa rede interna (10.10.1.0/24):
iptables -A INPUT -s 10.10.1.0/24 -m state --state NEW -p tcp --dport 137 -j ACCEPT
iptables -A INPUT -s 10.10.1.0/24 -m state --state NEW -p tcp --dport 138 -j ACCEPT
iptables -A INPUT -s 10.10.1.0/24 -m state --state NEW -p tcp --dport 139 -j ACCEPT
iptables -A INPUT -s 10.10.1.0/24 -m state --state NEW -p tcp --dport 445 -j ACCEPT

Salvando as regras do iptables em arquivo
Após criarmos as regras do firewall, é possível salvá-las em um arquivo com o comando:
# iptables-save > arquivo

clip_image016
clip_image017
E podemos recuperá-las com:
# iptables-restore < arquivo
Tornando as regras do firewall permanentes:
Por padrão, as regras que nós adicionamos ao iptables não são permanentes - se o servidor for reiniciado, serão todas perdidas.
Como devemos proceder para que as regras se tornem permanentes? Bem, há algumas maneiras de conseguirmos isso. A maneira mais fácil, a meu ver, é usando o pacote iptables-persistent. Ele está disponível para Debian, Ubuntu, CentOS e muitas outras distribuições Linux.
Vamos instalar o pacote iptables-persistent:
# yum install iptables-persistent
clip_image018
Escolha a opção Sim e pressione enter para salvar automaticamente as regras atuais do firewall iptables. Se houverem regras IPv6 a serem salvas, repita o processo na próxima tela. Veja o resultado:
clip_image019
Agora, ao reiniciar o servidor,as regras do firewall existentes atualmente serão preservadas (na verdade, recarregadas). As regras são salvas no arquivo /etc/iptables/rules.v4 e relidas durante a reinicialização do sistema.
Caso sejam criadas novas regras ou as regras atuais sejam alteradas, rode o comando a seguir para atualizar o arquivo de regras do iptables-persistent, para garantir que as novas regras também sejam carregadas durante a inicialização do sistema:
# iptables-save > /etc/iptables/rules.v4
Ou podemos também rodar o comando a seguir para salvar as regras, caso não tenhamos permissão de alteração no arquivo rules.v4 (usar o sudo no Ubuntu):
# service iptables-persistent save
Vejamos agora alguns exemplo do uso do target REJECT. Para isso usaremos algumas mensagens ICMP para visualizar a resposta do firewall ao remetente dos pacores que serão bloqueados.
O target REJECT só é válido nas cadeias INPUT, OUTPUT e FORWARD, e possui uma opção, --reject-with, a qual exploraremos nos exemplos sugeridos.
Primeiro, vamos limpar a regras atuais do firewall, cujo IP é 192.168.1.101, para que não interfiram em nossos exemplos:
# iptables -F
Vamos também alterar a regra padrão da chain INPUT para ACCEPT:
# iptables -P INPUT ACCEPT
E agora vamos enviar pacotes icmp usando o ping e testar a conectividade entre as máquinas (usarei um cliente WIndows, de IP 192.168.1.105, via prompt de comandos):
clip_image020
O ping está operando normalmente. Vamos então criar algumas regras que bloqueiem o ping no servidor e que emitam de volta ao remetente (no caso, a máquina WIndows) mensagens específicas. Após testar cada regra, limpe a cadeia com iptables -F.
Regra #1: Usando um REJECT simples, sem especificar nenhuma mensagem de retorno:
# iptables -A INPUT -s 192.168.1.105 -j REJECT
Testando a partir do cliente:
clip_image021
Observe que o ping foi bloqueado no servidor e foi emitida uma mensagem padrão do REJECT “Porta de destino inacessível” ao cliente de IP 192.168.1.105.
Regra #2:  Emitindo a mensagem “Rede de destino inacessível” com o REJECT:
# iptables -A INPUT -s 192.168.1.105 -j REJECT --reject-with icmp-net-unreachable
Testando a partir do cliente:
clip_image022
O parâmetro --reject-with deve sempre vir após a palavra REJECT.
Regra #3: Emitindo a mensagem “Host de destino inacessível” com o REJECT:
# iptables -A INPUT -s 192.168.1.105 -j REJECT --reject-with icmp-host-unreachable
clip_image023
Regra #4: Emitindo a mensagem padrão “Porta de destino inacessível” com o REJECT:
# iptables -A INPUT -s 192.168.1.105 -j REJECT --reject-with icmp-port-unreachable
clip_image024
Note que essa é a mensagem padrão do REJECT, que é emitida se nenhuma outra for especificada com --reject-with.
Regra #5: Emitindo a mensagem padrão “Protocolo de destino inacessível” com o REJECT:
# iptables -A INPUT -s 192.168.1.105 -j REJECT --reject-with icmp-proto-unreachable
clip_image025
Há algumas outras mensagens icmp que podem ser emitidas, como icmp-tcp-reset, icmp-host-prohibited, icmp-network-prohibited e icmp-admin-prohibited.

Em nossa próxima matéria, iremos aprofundar os estudos em NAT.

Qualquer dúvida, deixe nos comentários.

Nenhum comentário:

Postar um comentário