<sect id="fw-iptables-chains">Manipulando chains
 <p>
O <prgn>iptables</prgn> trabalha com uma tabela de regras que é analisada 
uma a uma até que a última seja processada. Por padrão, se uma regra 
tiver qualquer erro, uma mensagem será mostrada e ela descartada. O 
pacote não conferirá e a ação final (se ele vai ser aceito ou rejeitado) 
dependerá das regras seguintes. 
 <p>
As opções passadas ao <prgn>iptables</prgn> usadas para manipular os chains 
são <strong>SEMPRE</strong> em maiúsculas. As seguintes operações podem ser 
realizadas: 


<sect1 id="fw-iptables-chains-A">Adicionando regras - A
 <p>
Como exemplo vamos criar uma regra que bloqueia o acesso a nosso própria 
máquina (127.0.0.1 - loopback). Primeiro daremos um ping para verificar 
seu funcionamento: 

<example>
#ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=255 time=0.6 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=255 time=0.5 ms

--- 127.0.0.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.5/0.5/0.6 ms

</example>
Ok, a máquina responde, agora vamos incluir uma regra no chain INPUT 
(<em>-A INPUT</em>) que bloqueie (<em>-j DROP</em>) qualquer acesso indo 
ao endereço 127.0.0.1 (<em>-d 127.0.0.1</em>):
 <p>
<tt>iptables -t filter -A INPUT -d 127.0.0.1 -j DROP</tt>
 <p>
Agora verificamos um novo ping:
<example>
#ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes

--- 127.0.0.1 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss

</example>
Desta vez a máquina 127.0.0.1 não respondeu, pois todos os pacotes com o 
destino 127.0.0.1 (-d 127.0.0.1) são rejeitados (-j DROP). A opção 
<em>-A</em> é usada para adicionar novas regras no final do chain. Além de 
<em>-j DROP</em> que serve para rejeitar os pacotes, podemos também usar 
<em>-j ACCEPT</em> para aceitar pacotes. A opção <tt>-j</tt> é chamada de 
<em>alvo da regra</em> ou somente <em>alvo</em> pois define o destino do pacote 
que atravessa a regra (veja <ref id="fw-iptables-outras-alvo">). Bem vindo a base 
de um sistema de firewall :-)
<![ %OBS [
 <p>
<strong>OBS1:</strong> - O acesso a interface loopback não deve ser de forma 
alguma bloqueado, pois muitos aplicativos utilizam soquetes tcp para realizarem 
conexões, mesmo que você não possua uma rede interna. 
 <p>
<strong>OBS2:</strong> - A tabela <em>filter</em> será usada como padrão caso
nenhuma tabela seja especificada através da opção <tt>-t</tt>. ]]>


<sect1 id="fw-iptables-chains-L">Listando regras - L
 <p>
A seguinte sintaxe é usada para listar as regras criadas:
 <p>
<tt>iptables [<em>-t tabela</em>] -L [<em>chain</em>] [<em>opções</em>]</tt>
 <p>
Onde:
<taglist compact>
 <tag><em>tabela</em></tag>
 <item>
É uma das tabelas usadas pelo <prgn>iptables</prgn>. Se a tabela não for 
especificada, a tabela <em>filter</em> será usada como padrão. Veja 
<ref id="fw-iptables-tabelas"> para detalhes.

 <tag><em>chain</em></tag>
 <item>
Um dos chains disponíveis na tabela acima (veja <ref id="fw-iptables-tabelas">) ou 
criado pelo usuário (<ref id="fw-iptables-chains-N">). Caso o chain não seja 
especificado, todos os chains da tabela serão mostrados. 

 <tag><em>opções</em></tag>
 <item>
As seguintes opções podem ser usadas para listar o conteúdo de chains:
<list compact>
 <item><tt>-v</tt> - Exibe mais detalhes sobre as regras criadas nos chains.
 <item><tt>-n</tt> - Exibe endereços de máquinas/portas como números ao invés 
 de tentar a resolução DNS e consulta ao <file>/etc/services</file>. A resolução 
 de nomes pode tomar muito tempo dependendo da quantidade de regras que suas 
 tabelas possuem e velocidade de sua conexão. 
 <item><tt>-x</tt> - Exibe números exatos ao invés de números redondos. Também
 mostra a faixa de portas de uma regra de firewall.
 <item><tt>--line-numbers</tt> - Exibe o número da posição da regra na primeira 
coluna da listagem.
</list>
</taglist>
Para listar a regra criada anteriormente usamos o comando:
<example>
#iptables -t filter -L INPUT

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       all  --  anywhere             localhost          

</example>
O comando <tt>iptables -L INPUT -n</tt> tem o mesmo efeito, a diferença é que são 
mostrados números ao invés de nomes:
<example>
#iptables -L INPUT -n

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       all  --  0.0.0.0/0            127.0.0.1


#iptables -L INPUT -n --line-numbers

Chain INPUT (policy ACCEPT)
num target     prot opt source               destination
1   DROP       all  --  0.0.0.0/0            127.0.0.1

#iptables -L INPUT -n -v
Chain INPUT (policy ACCEPT 78 packets, 5820 bytes)
 pkts bytes target     prot opt in     out     source               destination
    2   194 DROP       icmp --  *      *       0.0.0.0/0            127.0.0.1

</example>
Os campos assim possuem o seguinte significado:
<taglist compact>
 <tag>Chain INPUT</tag>
  <item>Nome do chain listado
 <tag>(policy ACCEPT 78 packets, 5820 bytes)</tag>
  <item>política padrão do chain (veja <ref id="fw-iptables-chains-P">).
 <tag>pkts</tag>
  <item>Quantidade de pacotes que atravessaram a regra (veja 
        <ref id="fw-iptables-chains-Z">).
 <tag>bytes</tag> 
  <item>
 Quantidade de bytes que atravessaram a regra. Pode ser referenciado com 
 K (Kilobytes), M (Megabytes), G (Gigabytes). 
 <tag>target</tag>
  <item>
 O alvo da regra, o destino do pacote. Pode ser ACCEPT, DROP ou outro chain. 
 Veja <ref id="fw-iptables-outras-alvo"> para detalhes sobre a especificação
 de um alvo.
 <tag>prot</tag>
  <item>
 Protocolo especificado pela regra. Pode ser udp, tcp, icmp ou all. Veja 
<ref id="fw-iptables-outras-proto"> para detalhes.
 <tag>opt</tag>
  <item>
 Opções extras passadas a regra. Normalmente "!" 
 (veja <ref id="fw-iptables-outras-excessoes">) ou "f" 
 (veja <ref id="fw-iptables-outras-fragmentos">).
 <tag>in</tag>
  <item>
 Interface de entrada (de onde os dados chegam). Veja 
 <ref id="fw-iptables-outras-iface">.
 <tag>out</tag>
  <item>
 Interface de saída (para onde os dados vão). Veja 
 <ref id="fw-iptables-outras-iface">.
 <tag>source</tag>
  <item>
 Endereço de origem. Veja <ref id="fw-iptables-outras-endOD">.
 <tag>destination</tag>
  <item>
 Endereço de destino. Veja <ref id="fw-iptables-outras-endOD">.
 <tag>outras opções</tag>
  <item>
Estas opções normalmente aparecem quando são usadas a opção -x:  
  <list compact>
   <item><tt>dpt ou dpts</tt> - Especifica a porta ou faixa de portas de destino.
   <item><tt>reject-with icmp-port-unreachable</tt> - Significa que foi usado 
   o alvo REJECT naquela regra (veja <ref id="fw-iptables-outras-alvo-REJECT">).
  </list>
</taglist>


<sect1 id="fw-iptables-chains-D">Apagando uma regra - D
 <p>
Para apagar um chain, existem duas alternativas: 
<enumlist compact>
 <item>
Quando sabemos qual é o número da regra no chain (listado com a opção <tt>-L</tt>)
podemos referenciar o número diretamente. Por exemplo, para apagar a regra criada 
acima:
 <p>
<tt>iptables -t filter -D INPUT 1</tt>
 <p>
Esta opção não é boa quando temos um firewall complexo com um grande número de 
regras por chains, neste caso a segunda opção é a mais apropriada.

 <item>
Usamos a mesma sintaxe para criar a regra no chain, mas trocamos <tt>-A</tt> por 
<tt>-D</tt>: 
 <p>
<tt>iptables -t filter -D INPUT -d 127.0.0.1 -j DROP</tt>
 <p>
Então a regra correspondentes no chain INPUT será automaticamente apagada 
(confira listando o chain com a opção "-L"). Caso o chain possua várias 
regras semelhantes, somente a primeira será apagada. 
<![ %OBS [
 <p>
<strong>OBS: </strong> Não é possível apagar os chains defaults do 
<prgn>iptables</prgn> (<em>INPUT</em>, <em>OUTPUT</em>...).
]]>
</enumlist>


<sect1 id="fw-iptables-chains-I">Inserindo uma regra - I
 <p>
Precisamos que o tráfego vindo de <file>192.168.1.15</file> não seja rejeitado 
pelo nosso firewall. Não podemos adicionar uma nova regra (-A) pois 
esta seria incluída no final do chain e o tráfego seria rejeitado pela 
primeira regra (nunca atingindo a segunda). A solução é inserir a 
nova regra antes da regra que bloqueia todo o tráfego ao endereço 
<file>127.0.0.1</file> na posição 1: 
 <p>
<tt>iptables -t filter -I INPUT 1 -s 192.168.1.15 -d 127.0.0.1 -j ACCEPT</tt>
 <p>
Após este comando, temos a regra inserida na primeira posição do chain (repare no 
número 1 após INPUT) e a antiga regra número 1 passa a ser a número 2. Desta forma 
a regra acima será consultada, se a máquina de origem for 192.168.1.15 então o 
tráfego estará garantido, caso contrário o tráfego com o destino 127.0.0.1 
será bloqueado na regra seguinte. 


<sect1 id="fw-iptables-chains-R">Substituindo uma regra - R
 <p>
Após criar nossa regra, percebemos que a nossa intenção era somente bloquear 
os pings com o destino <file>127.0.0.1</file> (pacotes ICMP) e não havia 
necessidade de bloquear todo o tráfego da máquina. Existem duas alternativas: 
apagar a regra e inserir uma nova no lugar ou modificar diretamente a regra já 
criada sem afetar outras regras existentes e mantendo a sua ordem no chain (isso 
é muito importante). Use o seguinte comando: 
 <p>
<tt>iptables -R INPUT 2 -d 127.0.0.1 -p icmp -j DROP</tt>
 <p>
O número <tt>2</tt> é o número da regra que será substituída no chain INPUT, e 
deve ser especificado. O comando acima substituirá a regra 2 do chain INPUT
(-R INPUT 2) bloqueando (-j DROP) qualquer pacote icmp (-p icmp) 
com o destino <file>127.0.0.1</file> (-d 127.0.0.1).
  

 
<sect1 id="fw-iptables-chains-N">Criando um novo chain - N
 <p>
Em firewalls organizados com um grande número de regras, é interessante criar 
chains individuais para organizar regras de um mesmo tipo ou que tenha por objetivo 
analisar um tráfego de uma mesma categoria (interface, endereço de origem, 
destino, protocolo, etc) pois podem consumir muitas linhas e tornar o gerenciamento 
do firewall confuso (e conseqüentemente causar sérios riscos de segurança). O 
tamanho máximo de um nome de chain é de 31 caracteres e podem conter tanto
letras maiúsculas quanto minúsculas. 
 <p>
<tt>iptables [<em>-t tabela</em>] [<em>-N novochain</em>]</tt>
 <p>
Para criar o chain <em>internet</em> (que pode ser usado para agrupar as 
regras de internet) usamos o seguinte comando: 
<example>
 iptables -t filter -N internet
</example>
Para inserir regras no chain <em>internet</em> basta especifica-lo após 
a opção -A:
<example>
 iptables -t filter -A internet -s 200.200.200.200 -j DROP
</example>
E então criamos um pulo (-j) do chain <em>INPUT</em> para o chain <em>internet</em>:
 <p>
<tt>iptables -t filter -A INPUT -j internet</tt>

<![ %OBS [ 
 <p>
<strong>OBS:</strong> O chain criando pelo usuário pode ter seu nome tanto em 
maiúsculas como minúsculas. ]]>
 <p>
Se uma máquina do endereço 200.200.200.200 tentar acessar sua máquina, o 
<prgn>iptables</prgn> consultará as seguintes regras:
<example>
`INPUT'                         `internet'
 ----------------------------    -----------------------------
 | Regra1: -s 192.168.1.15  |    | Regra1: -s 200.200.200.200|
 |--------------------------|    |---------------------------|
 | Regra2: -s 192.168.1.1   |    | Regra2: -d 192.168.1.1    |
 |--------------------------|    -----------------------------
 | Regra3: -j DROP          |
 ----------------------------

O pacote tem o endereço de origem 
200.200.200.200, ele passa pela
primeira e segunda regras do chain
INPUT, a terceira regra direciona 
para o chain internet

                                    _______________________________________
                           v       /                                      v
 /-------------------------|-\    / /-------------------------------------|-\
 | Regra1: -s 192.168.1.15 | |   /  | Regra1: -s 200.200.200.200 -j DROP  \_____\
 |-------------------------|-|  /   |---------------------------------------|   /
 | Regra2: -s 192.168.1.1  | | /    | Regra2: -d 200.200.200.202 -j DROP    |
 |-------------------------|-|/     \---------------------------------------/
 | Regra3: -j internet      /|
 |---------------------------|       No chain internet, a primeira regra confere
 | Regra4: -j DROP           |       com o endereço de origem 200.200.200.200 e 
 \---------------------------/       o pacote é bloqueado. 
 

Se uma máquina com o endereço de origem 200.200.200.201 tentar acessar a máquina, 
então as regra consultadas serão as seguintes:


O pacote tem o endereço de origem 
200.200.200.201, ele passa pela
primeira e segunda regras do chain
INPUT, a terceira regra direciona 
para o chain internet               ______________________________________
                           v       /                                      v
 /-------------------------|-\    / /-------------------------------------|-\
 | Regra1: -s 192.168.1.15 | |   /  | Regra1: -s 200.200.200.200 -j DROP  | |
 |-------------------------|-|  /   |-------------------------------------|-|
 | Regra2: -s 192.168.1.1  | | /    | Regra2: -s 200.200.200.202 -j DROP  | |
 |-------------------------|-|/     \-------------------------------------|-/
 | Regra3: -j internet      /|                                            v
 |---------------------------|                                           /
 | Regra4: -j DROP         --+-------------------------------------------      
 \------------------------/-/       O pacote passa pelas regras 1 e 2 do chain
                          |         internet, como ele não confere com nenhuma
                          v         das 2 regras ele retorna ao chain INPUT e é 
 Esta regra é a número 4            analisado pela regra seguinte.
 que diz para rejeitar o 
 pacote.
 
</example>


<sect1>Renomeando um chain criado pelo usuário - E
 <p>
Se por algum motivo precisar renomear um chain criado por você na tabela
<em>filter</em>, <em>nat</em> ou <em>mangle</em>, isto poderá ser feito 
usando a opção <em>-E</em> do <prgn>iptables</prgn>:
<example>
iptables -t filter -E chain-antigo novo-chain

</example>
Note que não é possível renomear os chains defaults do <prgn>iptables</prgn>.


<sect1>Listando os nomes de todas as tabelas atuais
 <p>
Use o comando <tt>cat /proc/net/ip_tables_names</tt> para fazer isto. É 
interessante dar uma olhada nos arquivos dentro do diretório 
<file>/proc/net</file>, pois os arquivos existentes podem lhe 
interessar para outras finalidades. 


<sect1 id="fw-iptables-chains-F">Limpando as regras de um chain - F
 <p>
Para limpar todas as regras de um chain, use a seguinte sintaxe:
 <p>
<tt>iptables [<em>-t tabela</em>] [<em>-F chain</em>]</tt>
 <p>
Onde:
<taglist>
 <tag><em>tabela</em></tag>
  <item>
Tabela que contém o chain que desejamos zerar.

 <tag><em>chain</em></tag>
 <item>
Chain que desejamos limpar. Caso um chain não seja especificado, todos os 
chains da tabela serão limpos.
  
</taglist>
<example>
  iptables -t filter -F INPUT
  iptables -t filter -F
</example>


<sect1 id="fw-iptables-chains-X">Apagando um chain criado pelo usuário - X
 <p>
Para apagarmos um chain criado pelo usuário, usamos a seguinte sintaxe:
 <p>
<tt>iptables [<em>-t tabela</em>] [<em>-X chain</em>]</tt>
 <p>
Onde:
<taglist compact>
 <tag>tabela</tag>
 <item>
Nome da tabela que contém o chain que desejamos excluir.

 <tag>chain</tag>
 <item>
Nome do chain que desejamos apagar. Caso não seja especificado, todos os 
chains definidos pelo usuário na tabela especificada serão excluídos.
</taglist>
<![ %OBS [
 <p>
<strong>OBS:</strong> - Chains embutidos nas tabelas não podem ser apagados
pelo usuário. Veja os nomes destes chains em <ref id="fw-iptables-tabelas">. ]]>
<example>
 iptables -t filter -X internet
 iptables -X
</example> 


<sect1 id="fw-iptables-chains-Z">Zerando contador de bytes dos chains - Z
 <p>
Este comando zera o campo <em>pkts</em> e <em>bytes</em> de uma regra do 
<prgn>iptables</prgn>. Estes campos podem ser visualizados com o comando
<prgn>iptables -L -v</prgn>. A seguinte sintaxe é usada:
 <p>
<tt>iptables [<em>-t tabela</em>] [<em>-Z chain</em>] [<em>-L</em>]</tt>
 <p>
Onde:
<taglist compact>
 <tag><em>tabela</em></tag>
 <item>
Nome da tabela que contém o chain que queremos zerar os contadores de bytes e 
pacotes.

 <tag><em>chain</em></tag>
  <item>
Chain que deve ter os contadores zerados. Caso não seja especificado, todos os 
chains da tabela terão os contadores zerados. Note que as opções 
<em>-Z</em> e <em>-L</em> podem ser usadas juntas, assim o chain será listado 
e imediatamente zerado. Isto evita a passagem de pacotes durante a listagem de 
um chain. 
</taglist>
<example>
 iptables -t filter -Z INPUT
</example>


<sect1 id="fw-iptables-chains-P">Especificando a política padrão de um chain - P
 <p>
A política padrão determina o que acontecerá com um pacote quando ele chegar 
ao final das regras contidas em um chain. A política padrão do 
<prgn>iptables</prgn> é "ACCEPT" mas isto pode ser alterado com o comando: 
 <p>
<tt>iptables [<em>-t tabela</em>] [<em>-P chain</em>] [<em>ACCEPT/DROP</em>]</tt>
 <p>
Onde:
<taglist compact>
 <tag>tabela</tag>
  <item>
 Tabela que contém o chain que desejamos modificar a política padrão.
 
 <tag>chain</tag>
  <item>
Define o chain que terá a política modificada. O chain deve ser especificado.

 <tag>ACCEPT/DROP</tag>
  <item>
ACCEPT aceita os pacotes caso nenhuma regra do chain conferir (usado em regras 
permissivas). DROP rejeita os pacotes caso nenhuma regra do chain conferir 
(usado em regras restritivas). 
</taglist>
A política padrão de um chain é mostrada com o comando <prgn>iptables -L</prgn>: 
<example>
# iptables -L INPUT

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       icmp --  anywhere             localhost          

</example>
No exemplo acima, a política padrão de INPUT é ACCEPT (policy ACCEPT), o que 
significa que qualquer pacote que não seja rejeitado pela regra do chain, 
será aceito. Para alterar a política padrão deste chain usamos o comando:
<example>
 iptables -t filter -P INPUT DROP
</example>
<![ %OBS [
 <p>
<strong>NOTA:</strong> As políticas de acesso PERMISSIVASS (ACCEPT) normalmente 
são usadas em conjunto com regras restritivas no chain correspondentes (tudo é 
bloqueado e o que sobrar é liberado) e políticas RESTRITIVAS (DROP) são usadas 
em conjunto com regras permissivas no chain correspondente (tudo é liberado e o 
que sobrar é bloqueado pela política padrão). ]]>

