Um pouco sobre IPtables

IPtables é um firewall a nível de pacotes e funciona baseado no endereço/porta de origem/destino do pacote, prioridade etc. Ele funciona através da comparação de regras para saber se um pacote tem ou não permissão para passar. Em firewalls mais restritivos, o pacote é bloqueado e registrado para que o administrador do sistema tenha conhecimento sobre o que está acontecendo em seu sistema.

[ Hits: 63.488 ]

Por: Douglas Q. dos Santos em 08/12/2012 | Blog: http://wiki.douglasqsantos.com.br


Usando o IPtables



Tabela filter

Na tabela filter (tabela-padrão do netfilter), temos as chains INPUT, OUTPUT e FORWARD.

O início: Geralmente iniciamos com a criação de uma política-padrão de acesso, que na maioria dos casos, é negar, como o exemplo abaixo:

# iptables -P INPUT DROP
# iptables -P FORWARD DROP
# iptables -P OUTPUT DROP


Estas regras irão bloquear qualquer pacote que tente acessar, passar ou sair pelo nosso firewall. Neste momento você não conseguirá fazer nada.

Revisão:
  • INPUT → Controla a entrada em nosso firewall, ou seja, o acesso no firewall;
  • OUTPUT → Controla a saída em nosso firewall, ou seja, o acesso efetuado pelo nosso firewall;
  • FORWARD → Controla o acesso que passa pelo nosso firewall com direção a uma máquina ou rede, não sendo o firewall.

Vamos agora começar a liberar acesso necessário em nosso firewall.

Vamos liberar conexões provindas da rede 10.0.0.0/24:

# iptables -A INPUT -s 10.0.0.0/24 -j ACCEPT

Agora vamos rejeitar os pacotes, saindo do nosso kernel com o destino ao IP 200.154.56.80 (www.terra.com.br) com a opção: icmp-host-unreachable

Porém, antes de rejeitar, vamos logar toda a passagem:

# iptables -A OUTPUT -d 200.154.56.80 -j LOG --log-prefix "ACESSO AO TERRA " --log-level warn
# iptables -A OUTPUT -d 200.154.56.80 -j REJECT --reject-with icmp-host-unreachable


Agora vamos fazer um teste, vamos pingar neste IP:

ping 200.154.56.80 -c 3
PING 200.154.56.80 (200.154.56.80) 56(84) bytes of data.
From 10.0.0.20 icmp_seq=1 Destination Host Unreachable
From 10.0.0.20 icmp_seq=1 Destination Host Unreachable
From 10.0.0.20 icmp_seq=1 Destination Host Unreachable --- 200.154.56.80 ping statistics ---
0 packets transmitted, 0 received, +3 errors

Como pode ser notado, a nossa regra funcionou corretamente.

Usaremos agora uma interface específica para assegurar que todos os pacotes provindos da minha rede 192.168.0.0 possam entrar, passar e sair pelo firewall através da interface eth0:

# iptables -A INPUT -s 192.168.0.0/24 -i eth0 -j ACCEPT
# iptables -A FORWARD -d 192.168.0.0/24 -j ACCEPT
# iptables -A OUTPUT -d 192.168.0.0/24 -o eth0 -j ACCEPT


Como pode ser notado, é isso que vamos ter que ir fazendo para o que necessitar de acesso, vamos ver mais opções logo abaixo.

Parâmetros TCP/UDP

Os parâmetros são específicos para o protocolo e são disponíveis apenas quando trabalhamos com pacotes e stream TCP. Para usá-lo, é necessário utilizar os parâmetros "-p" ou "-protocol tcp" ou "udp" junto com o IPtables.

Especificando porta de origem

"--sport" ou "--source-port" → Estes parâmetros verificam a porta de origem.

Eles podem trabalhar com um nome de serviço, como: www, ftp etc. Os nomes dos serviços podem ser consultados em /etc/services.

Pode-se usar um range de portas, por exemplo, da mesma porta 22 até a porta 80 seria algo como 22:80. Da mesma forma, podemos usar a forma de exceção, como por exemplo, todas as portas, menos as inclusas desde 22 a 80. Seria algo com: ! 22:80

# iptables -A INPUT -p tcp ! --sport 1024:65535 -j ACCEPT

Nesta regra, estamos aceitando tudo o que entra de origem qualquer, com portas de origens diferentes de portas altas do TCP, ou seja, quando requisitamos uma conexão a um servidor Web, temos como porta de destino a porta 80.

E com certeza, quando a conexão retornar, terá porta de origem 80 e destino uma porta alta em nosso host, desta forma, não aceitaremos conexões em portas baixas que são usadas para serviços específicos.

Da mesma forma que usamos o TCP, poderemos utilizar o UDP:

# iptables -A INPUT -p udp ! --sport 53 -j REJECT

Especificando porta de destino

"--dport" ou "--destination-port" → Estes parâmetros verificam a porta de destino.

Esta opção verificará o serviço ou porta de destino. Pode ser usada também com a opção de exceção "!". Outro item de grande importância, é o uso de várias portas com o caractere ":".

Se omitirmos um dos lados, o IPtables assumirá automaticamente um valor de início ou fim. Por exemplo, :80 significa o início e portas 0 até 80, ou ainda 80:, significa início porta 80 até 65535.

# iptables -A INPUT ! -s 192.168.0.0/24 -p tcp --dport 22 -j REJECT

Neste exemplo, todo tráfego que não estiver vindo da rede interna com destino ao processo local na porta 22, será rejeitado.

Especificando Flags TCP

tcp-flags mask comp → Esta opção compara as flags do TCP (SYN,ACK,FIN,RST,PSH,URG,ALL,NONE) com as flags marcadas em comp.

Elas serão comparadas quando as flags de mask estiverem com o estado das flags em comp. As flags inseridas em comp deverão estar ativas no pacote para que coincidam com a regra. Por exemplo, ALL ACK, neste caso ela casará quando a flag ACK estiver setada. A opção "!" usará exceção para as flags em comp.

Outro detalhe é a separação entre flags que é feita por vírgulas e a separação entre mask e comp é feita através de espaços.

# iptables -A INPUT -p tcp --tcp-flags SYN,ACK SYN --dport 22 -j DROP

O pacotes com as flags SYN e ACK serão verificados e se estiverem com a opção de SYN setada e com destino à porta 22 serão descartados. Quando executamos uma solicitação de conexão, mandamos um SYN e o servidor nos responde um SYN/ACK.

No caso anterior, estamos dropando tentativas de conexão na porta 22, pois não enviamos um SYN. Podemos considerar neste caso, um scanner tentando localizar as portas abertas.

Especificando Flags TCP de início de conexão

syn → Esta opção concilia pacotes que tenham no datagrama as flags SYN ligadas e ACK e RST desligadas. Seria um tipo de tcpflags com as seguintes opções: SYN, ACK, RST SYN verificando por solicitação de conexão, também possui a possibilidade de utilizar "!" com exceção.

# iptables -A INPUT -i eth0 -p tcp --dport 22 --syn -j LOG

Nestas regras estaremos logando todas as conexões com flags SYN ligadas, entretanto pela eth0 na porta destino 22.

Especificando Flags TCP através de valores

tcp-option número → Compara se a opção está ligada.

Onde as opções são:
  • CWR:128
  • ECE:64
  • URG:32
  • ACK:16
  • PSH:8
  • RST:4
  • SYN:2
  • FIN:1

Com certeza você está se perguntando o que é essa tal de CWR e ECE. Simples, a CWR (Congestion Windows Reduced) é uma janela de congestionamento reduzida, e a ECE (Explicit Congestion Notification Echo) é uma mensagem de notificação de congestionamento explícita.

Vamos a um exemplo de uso:

# iptables -A INPUT -p tcp ! --tcp-option 2 -j REJECT --reject-with tcp-reset

Nesta regra estamos verificando o tráfego de entrada com a flag diferente de dois (SYN) e rejeitando com o item de tcp-reset, ou um pacote RST. Normalmente, encontramos muitos firewalls com o uso desta opção, mas explicitamente rejeitando pacotes com as flags 64 e 128 habilitadas.

Parâmetros ICMP

Temos um parâmetro para o ICMP, este parâmetro é usado com a opção "-p" ou "--protocol", seguida do tipo de ICMP.

--protocol icmp --icmp-type → Esta opção serve para especificarmos o tipo de ICMP.

Os tipos de ICMP pode ser consultados em: http://support.microsoft.com/kb/170292/pt-br

Podemos utilizar o ICMP pelo nome ou pelo número que corresponde a determinado tipo.

Note que os pacotes ICMP são reclassificados dentro de sua tabela, por exemplo, "destination-unreachable" (destino inalcançável), que é um tipo de classificação e dentro desta classificação, temos tipos específicos como host-unreachable e network-unreachable.

A classe destino inalcançável tem um valor específico, neste caso 3, e os tipos internos têm outra classificação interna (código). Nos outros dois casos, seriam 0 e 1.

Para ficar mais claro, veja da seguinte forma: o host-unreachable e network-unreachable são do tipo destination-unreachable. Posso fazer referência a ambos informando no IPtables o tipo 3, ele casará com todos os códigos de 0 a 15.

Não há problema algum usar desta forma, aliás, na prática, sempre usamos assim. Caso deseje especificar apenas um código e não o tipo inteiro, basta mencioná-lo diretamente após "icmp-type", por exemplo, network-unreachable ou 3/0.

Vamos a um exemplo:

# iptables -A INPUT -p icmp --icmp-type 8 -j DROP
# iptables -A INPUT -p icmp --icmp-type echo-request -j DROP


Nos dois exemplos citados estamos dropando todos os pacotes ICMP do tipo 8 (ping) enviados ao nosso firewall, e como foi visto podemos utilizar o 8 ou echo-request.

Exemplos de uso na tabela filter

Veremos alguns exemplos do uso de regras de firewall do IPtables na tabela filter para permitir o acesso a serviços externos, ou até permitir serviços que respondem no firewall, embora não seja recomendado termos serviços no próprio firewall.

Permitindo que o firewall acesse o DNS

Neste caso, vamos supor que nossa interface de rede para Internet seja a eth0, e que o nosso firewall poderá fazer requisições para um DNS qualquer.

Note que poderíamos ser mais específicos e detalhar qual seria o DNS permitido. Outro item importante é pensarmos que quando fazemos uma conexão, temos a ida e volta, então devemos liberar o INPUT e o OUTPUT.

Vamos à regra:

# iptables -A INPUT -i eth0 -p udp --sport 53 --dport 1024:65535 -j ACCEPT
# iptables -A OUTPUT -o eth0 -p udp --dport 53 --sport 1024: -j ACCEPT


Recorde-se que se informarmos 1024:65535, é o mesmo que "1024:", pois estamos especificando onde começa a porta de destino, sendo que se depois dos ":" não informarmos nada, ele vai até a última porta, ou seja 65535.

Permitindo WWW e SSH no firewall

Esta regra permite o acesso ao servidor web e SSH que se encontra no próprio firewall. Utilizaremos um módulo que verificará o estado da conexão. Não se preocupe com este item específico, pois será visto adiante.

Esta primeira regra permitirá conexões de saída que já foram estabelecidas anteriormente, ou seja, já tenha relação com conexões existentes. Normalmente vinculadas à alguma regra de entrada, utilizada no INPUT.

Um exemplo interessante:
  • Criarmos uma regra de entrada para conexões SSH;
  • Deveremos criar uma regra de saída também para conexão SSH;
  • Criamos uma regra de entrada para conexões em um servidor web (www);
  • Deveremos criar uma regra de saída também para conexões em um servidor web (www).

Agora, utilizando-se do "--state":
  • Criamos uma regra de entrada para conexões SSH;
  • Criamos uma regra de entrada para conexões em um servidor web (www);
  • Criamos uma regra de saída baseada em conexões de entradas que foram permitidas, ou seja, existe uma conexão de entrada, então haverá permissão para saída através do módulo state.

Vamos à regra de saída do firewall (logo abaixo vou explicar as regras):

# iptables -A OUTPUT -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

Agora, liberamos as portas 80 (HTTP) e 22 (SSH), desde que o estado seja uma nova conexão:

# iptables -A INPUT -p tcp -i eth0 --dport 22 --sport 1024: -m state NEW -j ACCEPT
# iptables -A INPUT -p tcp -i eth0 --dport 80 --sport 1024: -m state NEW -j ACCEPT
# iptables -A INPUT -m state --state ESTABLISHED,RELATED -i eth0 -p tcp -j ACCEPT


Explicação: Quando estabelece uma comunicação, o estado da conexão poderá ser NEW (novo), ESTABLISHED (uma conexão já estabelecida) ou RELATED (tem relação com uma conexão nova ou estabelecida).

Nesta regra, estamos utilizando este mesmo esquema para permitir pacotes que já tenham uma conexão preestabelecida ou tenha relação como uma conexão nova efetuada anteriormente. Mas não permitiremos uma nova conexão, que seria o estado de NEW. E ainda especificamos que sejam pacotes chegando na interface eth0.

Regra por tempo

Vamos a um exemplo de uma regra de IPtables controlada por tempo:

# iptables -A INPUT -p tcp --dport 22 -m time --datestart 2012-01-16T16:00 --datestop 2012-01-16T23:59:59 -j ACCEPT

Aqui estou deixando passar o tráfego na porta 22 no intervalo de tempo de 16/01/2012-12:00 até 16/01/2012-23:59:59.

Permitindo acesso ao firewall da rede interna

Nesta regra estaremos liberando qualquer protocolo e porta para nossa rede interna. Note que não é necessário especificar porta e protocolo, conforme o exemplo:

# iptables -A INPUT -p all -s 192.168.1.0/24 -i eth1 -j ACCEPT
# iptables -A OUTPUT -p all -d 192.168.1.0/24 -o eth1 -j ACCEPT


Esta regra funcionaria também da seguinte forma:

# iptables -A INPUT -j ACCEPT -s 192.168.1.0/24 -i eth1
# iptables -A OUTPUT -j ACCEPT -d 192.168.1.0/24 -o eth1


Bloqueando ping

Bloquearemos os pings oriundos de qualquer lugar, mas ainda podemos fazer isso através do sistema proc em /proc, mas neste momento usaremos as regras de IPtables:

# iptables -A FORWARD -p icmp --icmp-type echo-request -j DROP

Poderíamos fazer uma regra de firewall, onde bloqueamos os pings com exceção da rede interna:

# iptables -A FORWARD ! -s 192.168.0.0/24 -p icmp --icmp-type echo-request -j DROP

No exemplo acima, queremos bloquear o ping (icmp - echo request), menos de nossa rede interna.

Mas não criamos regras para permitir que o nosso servidor consiga pingar ou responder pings, de forma que até o próprio firewall não conseguiria utilizar o protocolo ICMP para pingar outros hosts.

A seguir, um modelo de script que poderia funcionar:

# iptables -A INPUT -s 192.168.0.0/24 -p icmp --icmp-type echo-request -j ACCEPT
# iptables -A OUTPUT -d 192.168.0.0/24 -p icmp --icmp-type echo-reply -j ACCEPT
# iptables -A FORWARD -s 192.168.0.0/24 -p icmp --icmp-type echo-request -j ACCEPT


No exemplo acima, liberamos o firewall responder a requisições de ping, o firewall pode também solicitar requisições de ping, e pode efetuar o repasse de requisições de ping para a sua rede.

Página anterior     Próxima página

Páginas do artigo
   1. Um pouco de história
   2. Adicionando e inserindo regras
   3. Deletando e substituindo regra
   4. Listando e limpando regras
   5. Zerando contadores - Criando chain
   6. Renomeando e deletando chain - Política default
   7. Opções e parâmetros do IPtables
   8. Ações padrões
   9. Usando o IPtables
   10. NAT
   11. Utilizando MASQUERADING
Outros artigos deste autor

Alta disponibilidade com Debian Lenny + Heartbeat + DRBD8 + OCFS2 + MONIT + LVS

Debian Lenny com Kernel 2.6.28 + Layer7 + Firewall

Servidor Jabber com Openfire + MySQL + Debian Lenny

Bonding para Heartbeat + Bonding para DRBD + OCFS2 + Debian Squeeze

Apache em chroot + MySQL + PHP + mod_security + mod_evasive + vsftpd + Fail2ban + Debian Squeeze

Leitura recomendada

Iptables em modo gráfico

Firewall e NAT em FreeBSD com controle de banda e redirecionamento de portas e IPs

IPFire - Um Firewall Open Source

Iptables + módulo recent

Revisão atualizada de instalação do Iptables com Layer7

  
Comentários
[1] Comentário enviado por fabio em 08/12/2012 - 10:39h

Se esse aqui é "Um pouco sobre IPtables", fico imaginando como seria o artigo "Um muito sobre IPtables" :)

Meus parabéns, ótimo artigo!

[2] Comentário enviado por douglas_dksh em 10/12/2012 - 13:12h

Obrigado,

O pior que isso ai é a base para poder se virar com o iptables.

Tem muito mais que pode ser abordado :D

[3] Comentário enviado por removido em 10/12/2012 - 17:08h

Realmente @fabio, fico imaginando também. Está ótimo o artigo.

['s]

[4] Comentário enviado por phrich em 10/12/2012 - 19:16h

Muito bom o artigo, está de parabéns!

[5] Comentário enviado por thyagobrasileiro em 11/12/2012 - 10:19h

PQP, seu blog é do caralh$#$@#@#%@

Bem organizado e aborda tudo, bem limpo e sem propagandas!!!
http://www.douglas.wiki.br


Otimo artigo!!

[6] Comentário enviado por douglas_dksh em 11/12/2012 - 11:31h

Obrigado galera :D

[7] Comentário enviado por dalveson em 11/12/2012 - 13:03h

douglashx otimo artigo,
veja se vc poderia me da uma ajuda, tenho o seguinte:
meu sistema é web e tem o ip 1.2.3.4 e roda porta 443, queria utilizar o modulos TOS junto com MANGLE para dar prioridade a este ip antes de qualquer outra conexao na minha rede 192.168.0.0/24 para upload e download sabe dizer como faço isso pois ja tentei, pesquisei bastante e ainda nao consegui
abraços

[8] Comentário enviado por douglas_dksh em 11/12/2012 - 13:41h

E ai colega,

Tipo de Prioridade TOS

Espera Mínima 0×10 ou 16
Máximo Processamento 0×08 ou 8
Máxima Confiança 0×04 ou 4
Custo Mínimo 0×02 ou 2
Prioridade Normal 0×00 ou 0

Conforme tabela acima, a Espera mínima tem a maior prioridade entre todos,

Se o servidor web estiver virado direto para a internet você pode fazer da seguinte forma

#Para Liberar o acesso na porta 443 com Máximo Processamento na entrada
iptables -t mangle -A PREROUTING -p tcp --dport 443 -j TOS --set-tos 8

#Para Liberar o acesso na porta 443 com Máximo Processamento na saída
iptables -t mangle -A POSTROUTING -p tcp --dport 443 -j TOS --set-tos 8


#Se o servidor web estiver atras de um fw no fw tem que configurar da seguinte forma

#Para Liberar o acesso de origem da maquina 1.2.3.4 na porta 443 com Máximo Processamento
iptables -t mangle -A FORWARD -p tcp --dport 443 -s 1.2.3.4 -j TOS --set-tos 8

#Para Liberar o acesso de destino a maquina 1.2.3.4 na porta 443 com Máximo Processamento
iptables -t mangle -A FORWARD -p tcp --dport 443 -d 1.2.3.4 -j TOS --set-tos 8


Caso você queira utilizar a espera miníma troque o --set-tos 8 por --set-tos 10


[9] Comentário enviado por andrericsouza em 11/12/2012 - 13:50h

ótimo artigo

[10] Comentário enviado por dalveson em 11/12/2012 - 15:12h


[8] Comentário enviado por douglashx em 11/12/2012 - 13:41h:

E ai colega,

Tipo de Prioridade TOS

Espera Mínima 0×10 ou 16
Máximo Processamento 0×08 ou 8
Máxima Confiança 0×04 ou 4
Custo Mínimo 0×02 ou 2
Prioridade Normal 0×00 ou 0

Conforme tabela acima, a Espera mínima tem a maior prioridade entre todos,

Se o servidor web estiver virado direto para a internet você pode fazer da seguinte forma

#Para Liberar o acesso na porta 443 com Máximo Processamento na entrada
iptables -t mangle -A PREROUTING -p tcp --dport 443 -j TOS --set-tos 8

#Para Liberar o acesso na porta 443 com Máximo Processamento na saída
iptables -t mangle -A POSTROUTING -p tcp --dport 443 -j TOS --set-tos 8


#Se o servidor web estiver atras de um fw no fw tem que configurar da seguinte forma

#Para Liberar o acesso de origem da maquina 1.2.3.4 na porta 443 com Máximo Processamento
iptables -t mangle -A FORWARD -p tcp --dport 443 -s 1.2.3.4 -j TOS --set-tos 8

#Para Liberar o acesso de destino a maquina 1.2.3.4 na porta 443 com Máximo Processamento
iptables -t mangle -A FORWARD -p tcp --dport 443 -d 1.2.3.4 -j TOS --set-tos 8


Caso você queira utilizar a espera miníma troque o --set-tos 8 por --set-tos 10



*na realidade o servidor 1.2.3.4 nao ta minha rede interna, esta em 1 cidade diferente, entao bastaria eu usar?
#Para Liberar o acesso de origem da maquina 1.2.3.4 na porta 443 com Máximo Processamento
iptables -t mangle -A FORWARD -p tcp --dport 443 -s 1.2.3.4 -j TOS --set-tos 8

#Para Liberar o acesso de destino a maquina 1.2.3.4 na porta 443 com Máximo Processamento
iptables -t mangle -A FORWARD -p tcp --dport 443 -d 1.2.3.4 -j TOS --set-tos 8

*outra coisa, não é necessario fazer referencia a chain INPUT o OUTPUT tambem?

*outra duvida se eu quero que o sistema com ip 1.2.3.4 me de respostas mais rapidas aos usuarios, eu devo configura-lo com qual dos parametros TOS:
Espera Mínima 0×10 ou 16
Máximo Processamento 0×08 ou 8

*e a ultima duvida como voce faz para saber que realmente o ip 1.2.3.4 esta com o TOS configurado corretamente?
aqui eu criava uma regra de log e começava a monitorar com cat e sempre me mostrava um TOS diferente do que eu tinha configurado, por isso sempre achei que tinha algo errado.

[11] Comentário enviado por douglas_dksh em 11/12/2012 - 15:32h

Você usaria com o FORWARD

e liberaria as regras na tabela filter para o FORWARD desse servidor de origem e destino, pois INPUT seria se fosse no servidor local, e OUTPUT saida do servidor local com isso você vai precisar somente da FORWARD para repasse.

iptables -t filter -A FORWARD -p tcp --dport 443 -d 1.2.3.4 -j TOS --set-tos 8

dai a regra de mangle para priorizar os pacotes

iptables -t mangle -A FORWARD -p tcp --dport 443 -d 1.2.3.4 -j TOS --set-tos 8

A espera mínima o seu pacote vai entrar logo em processamento mais não vai ter prioridade de processamento sobre os outros, no 8 temos o processamento máximo possível.

Para saber se está configurado certo mande listar com as flags vão aparecer em hexadecimal.
iptables -t mangle -L -n -v

[12] Comentário enviado por danilotm em 12/12/2012 - 11:17h

Parabéns Douglas, agora que voltarei a utilizar o IPTABLES que tanto gostava me deparo com este artigo, muito bem explicado e organizado.
Obrigado e um grande abraço!


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts