Ver Feed RSS

The JEdi lair's

Criação de regras de filtro de pacotes com Netfilter/iptables

Avalie este Post de Blog
Bom dia galera!

Tendo mostrado os conceitos básicos e as principais matchs e targets do Netfilter/iptables, venho agora a tentar por uma luz na escrita de regras para o mesmo.

1 - Política do filtro de pacotes
A primeira etapa na escrita das regras deve ser a escolha da política de filtragem. Essa escolha influência no restante das regras, não estando um conjunto de regras de um tipo de política adequado ao uso em outra. Os tipo de políticas são permissivas e restritivas. Cada uma delas tem vantagens e desvantagens que podemos citar e discutir mais nos comentários

Para alterar a política, basta digitar o seguinte comando:
iptables [-t tabela] -P chain política
Onde os chain representa as chains padrão (INPUT, OUTPUT, etc) e política deve ser substituida pelo valor desejado.

1.1 - Filtros de pacotes permissivos
Filtros de pacotes permissivos são aqueles onde todos os pacotes são permitidos, excluindo-se os explicitamente bloqueados no conjunto de regras. Essa política vem por padrão na maioria das distribuições Linux.

Embora bastante adequadas a computadores pessoais, onde diversos aplicativos são executados e todo tipo de conteúdo é buscado, essa modalidade se mostra desvantajosa em ambientes mais complexos, tipo os corporativos e acadêmicos. Primeiro, a natureza dessas redes é que todo, ou a maioria, do conteúdo trafegado seja produtivo e que tenha um retorno direto na eficiência de seu utilizador. Segundo, nesses ambientes, a quantidade de serviços que se deseja bloquear é bem maior que a que se deseja permitir.

Portanto:
root@alderan:~# iptables -t filter -L
Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destinationk
root@alderan:~# iptables -t filter -P INPUT ACCEPT
A primeira regra foi usada numa estação recém inicializada, sem nenhuma configuração especial de filtro de pacotes. Veja que a política padrão é ACCEPT, o que a torna totalmente permissiva. O segundo comando consiste na opção de definição de política.

1.2 - Filtros de pacotes restritivo
Filtros restritivos são completamente opostos aos permissíveis, bloquem todos os pacotes, excetuando-se aqueles que estejam explicitamente aceitos em uma das regras do conjunto.

Sendo um pouco inconveniente num desktop, pois nos leva a adicionar uma regra por serviço acessado/provido, em ambientes corporativos essa prática é mais que aceita. Do ponto de vista administrativo, com essa prática podemos ter total controle do tráfego podendo utilizar as mais diversas técnicas para segurança. A principal desvantagem é o tempo que leva para o inicio da implantação até a estabilização dos serviços.

No Linux, o parâmetro utilizado par definir a política como restritiva é o DROP:
root@alderan:~# iptables -t filter -P INPUT DROP
root@alderan:~# iptables -t filter -L
Chain INPUT (policy DROP)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destinationk
root@alderan:~# iptables -t filter -P INPUT ACCEPT
Vale enfatizar que a tabela padrão do iptables é a filter, portanto, caso algum comando apareça sem a tabela explicitada, assuma a tabela filter.

2 - Criando um filtro de pacotes restritivo
Particulamente, os filtro de pacotes restritivos são os mais atraentes, permitindo grande flexibilidade de controle, principalmente associado a serviços, tais quais sistemas de prevenção de intrusão e analisádores de tráfego. A restritividade possbilita menor overhead do sistema de prevenção de intrusão pois evita que pacotes indesejáveis sejam inspecionados. Além, ferramentas especializadas podem interagir com iptables e proferir uma visão mais estatística da rede, possibilitando uma melhor análise.

Primeiramente, devemos definir a política padrão. Vejam o exemplo:
Código :
root@alderan:~# netstat -nat
Conexões Internet Ativas (servidores e estabelecidas)
Proto Recv-Q Send-Q Endereço Local          Endereço Remoto         Estado
tcp        0      0 0.0.0.0:389             0.0.0.0:*               OUÇA
tcp        0      0 127.0.0.1:631           0.0.0.0:*               OUÇA
tcp        0   1653 10.20.41.56:52482       74.125.47.19:443        ESTABELECIDA
tcp        0      0 10.20.41.56:55193       74.125.47.17:443        TIME_WAIT
tcp        0      0 10.20.41.56:52480       74.125.47.19:443        ESTABELECIDA
tcp6       0      0 :::389                  :::*                    OUÇA
tcp6       0      0 :::22                   :::*                    OUÇA
root@alderan:~# nc 127.0.0.1 631
GET / HTTP/1.0
 
HTTP/1.0 200 OK
Date: Sun, 11 Jan 2009 19:56:05 GMT
Server: CUPS/1.2
Content-Language: en_US
Content-Type: text/html; charset=utf-8
Last-Modified: Mon, 21 Apr 2008 20:17:59 GMT
Content-Length: 5242
 
<HTML CODE FOLOWS>
Primeiramente, executamos o programa netstat com os parâmetro -nat, n para exibir valores numéricos, a para exibir todas as conexões e t para visualizar somente os sockets TCP. Em seguida, usamos o netcat para enviar uma requisição GET no servidor CUPS local, enviado-os para o endereço de loopback e para a porta 631, onde o mesmo respondeu com a página inicial do CUPS.

Agora, considere a execução do comando de definição da política restritiva:
iptables -t filter -P INPUT DROP
Agora, qualquer tentativa de conexão a máquina local será derrubada, incluindo o tráfego de loopback, o que ocasionaria problemas em alguns aplicativos. Então, recomenda-se adicionar uma regra que libere todo o tráfego da porta de loopback, sendo essa a primeira regra:
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
Semanticamente temos, pacotes entrando na interface lo, aceite; Pacotes sainda pela interface de loopback, aceite.

Algumas pessoas, aquelas mais paranóicas que querem saber de tudo que acontesse em sua rede, pode beneficiar-se das seguintes regras:
iptables -A INPUT -i lo -s ! 127.0.0.1 -j LOG --log-prefix "[lo misuse]"
iptables -A INPUT -i lo -s 127.0.0.1 -j ACCEPT

iptables -A OUTPUT -o lo -d ! 127.0.0.1 -j LOG --log-prefix "[lo misuse]"
iptables -A OUTPUT -o lo -d 127.0.0.1 -j ACCEPT
Com essas regras, abusos locais na interface de loopback serão reportados no log do sistema com o prefixo "[lo misuse]".

Já nessas regras, podemos tentar aplicar um exercício mental no básico do iptables. O targer LOG é não terminativo, portanto a conferêmcia de um pacote nessa regras não o derruba nem o aceita. Haja visto, devemos ter sempre uma regra de apoio para a tomada de decisão adequada. Nesse caso nos apoiamos na política padrão restritiva. O pacote conferiria com a regra de log, não conferiria com a segunda regras pois claramente elas são mutualmente exclusivas, e portanto, a política padrão se incarregará de derrubá-la.

Com um pouco mais de percepção, podemos ver que pacotes de loopback raramente são falsificados, e nenhum sistema operacional em sua sã consciência transmitiria um pacote de uma interface de rede para a interface de loopback. Então, seria mais eficiente do ponto de vista computacional, por a regra permissiva anterior a tarefa de logging:
iptables -A INPUT -i lo -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -i lo -s ! 127.0.0.1 -j LOG --log-prefix "[lo misuse]"
O mesmo sendo adequado para as regras de saída.

A próxima tarefa, consiste em definir os serviços os quais poderão ser acessados e quais poderão ser providos. Digamos que tenhamos uma máquina com o LAMP instalado e que queiramos conexões externas a nosso servidor de banco de dados, o MySQL. A maioria dos administradores configuram o LAMP com os serviços de HTTP, FTP e HTTPS. No nosso exemplo teremos também o MySQL.

Para questões de otimização, recomendo sempre deixar as regras com maior volume no incio do conjunto. No caso de um servidor Web, geralmente o serviço mais requisitado é o HTTP e o HTTPS. Então, é sensato fazer:
iptables -A INPUT -p tcp --dport 80 -i eth0 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -i eth0 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 80 -o eth0 ACCEPT
iptables -A OUTPUT -p tcp --sport 443 -o eth0 ACCEPT
Em segundo lugar, o FTP:
iptables -A INPUT -p tcp --dport 20 -i eth0 -j ACCEPT
iptables -A INPUT -p tcp --dport 21 -i eth0 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 20 -o eth0 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 21 -o eth0 -j ACCEPT
Por ultimo o MySQL:
iptables -A INPUT -p tcp --dport 3306 -i eth0 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 3306 -i eth0 -j ACCEPT
No conjunto de regras acima, definimos as portas que devem estar abertas para comunicação, no caso 20,21,80,433,3306 e qual interface de entrada e saída, eth0.

2.1 - Tornando o filtro orientado a conexões
No exemplo acima, construímos um firewall não orientado a conexão, o que extendeu um pouco nosso conjunto de regras.

Um firewall orientado a conexão, permite a simplificação das regras pelo uso de mecanismos de rastreio do estado da conexão. No caso do iptables, a match extension state nos permite verificá-los. Resumidamente, os estado e suas definições são:

  • NEW
    Nenhum fluxo foi visto na tupla tcp=(sip,sport,dport,dip);
  • RELATED
    Fluxo relacionado a essa tupla foi visto mas nenhuma conexão foi estabelecida ainda.
  • ESTABLISHED
    Fluxo de inicio e relação foi visto e agora essa conexão se encontra estabilizada.
  • INVALID
    Conexão que não pode ser verificada, seja qual for o motivo.
  • UNTRACKED
    O mecanismo de rastreio de conexão está desativado.

Com isso em mãos, podemos otimizar nosso conjunto de regras com:
iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
Agora, precisamos somente aceitar o tráfego em uma direção. Exemplo:
iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
Somente essas regras fazem o processo de liberar a entrada de pacotes, contrastando significantemente com a quantidade necessária em filtro não orientado a conexão. Fazendo as contas, para um mesmo conjunto de portas, um filtro orientado necessita de 2 + Número de portas regras, enquanto que seu concorrente necessita de 2 * Número de portas regras. Além da quantidade de regras, a orientação a conexão permite também maior segurança, pois, como mostrado acima, o tráfego HTTP é permitido somente quando o host local atua como servidor, ou seja, quando uma conexão é requisitada. Já usando a não orientação, seria necessário a adição de mais algumas regras para caracterização desse comportamento.

Reforçando, para possibilitar nossa máquina LAMP conectar-se a um servidor de updates via HTTP rodando na porta 80 da máquina 10.2.0.32, podemos fazer:
iptables -A OUTPUT -o eth0 -p tcp --syn --dport 80 -d 10.2.0.32 -m state --state NEW -j ACCEPT
Aqui também, mais uma vez, o sistema de tracking se encarregará de tratar o fluxo relacionado. Devemos também lembrar de incluir portas para os serviços de DNS, NTP e qualquer outro que se deseja o envio de pacotes.

Tendo em vista o exposto acima, podemos agora gerar um conjunto de regras para nosso servidor LAMP:
iptables -P INPUT DROP
iptables -P OUTPUT DROP

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 80 --syn -m state --state NEW -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 443 --syn -m state --state NEW -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 21 --syn -m state --state NEW -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 3306 --syn -m state --state NEW -j ACCEPT
iptables -A INPUT -i lo -d 127.0.0.1 -m state --state NEW -j ACCEPT

iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p udp --dport 53 --syn -m state --state NEW -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --dport 80 --syn -d 10.2.0.32 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -o lo -s 127.0.0.1 -m state --state NEW -j ACCEPT
Vejam que na primeira regra, a que trata de pacotes estabilizados e relacionados, não especificamos protocolo, podendo essa regra casar tanto com os datagramas UDPs e os fluxos TCP. Apesar de ser um protocolo não orientado a conexão, os desenvolvedores do kernel do Linux se empenharam em cria rotinas para manter estados de envio de pacotes UDPs. Por isso a regra que envolve a liberação de tráfego de saída para a porta 53 está corretamente elaborada.

2.2 - Otimizando regras com auxílio de chains personalizadas
Muitas vezes, tal qual nos exemplos iniciais, as regras podem ficar com checagens repetitivas e nada eficientes. Com o auxílio de chain personalizadas, podemos organizar nosso código minimizando a quantidade de verificações.

Considerando o conjunto de regras do nosso servidor LAMP, vemos que podemos generalizar quatro regras:
Entrada na eth0, protocolo de transporte TCP com apenas o bit SYN ligado, estado novo e para a porta PORTA, Aceite.
Então, podemos criar uma nova chain que abirgará as portas que podem ser usadas, e faremos um direcionamento da chain INPUT para nossa chain.
iptables -F INPUT
iptables -N open-ports

iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --syn -m state --state NEW -j open-ports
iptables -A INPUT -i lo -s 127.0.0.1 -m state --state NEW -j ACCEPT

iptables -A open-ports -p tcp --dport 80 -j ACCEPT
iptables -A open-ports -p tcp --dport 443 -j ACCEPT
E assim sucetivamente, até que todas as portas que devem estar abertas estejam no conjunto. Dessa forma, faremos a checagem da interface e do estado somente uma vez, deixando o restante para a chain personalizada open-ports.

3 - Criando redirecionamentos com NAT
O Network Address Translation é processo de alterar as informações de origem e/ou destino de um pacote enquanto esse passa de uma rede para outra. É muito usado para realizar compartilhamento de conexões pois possibilita até 65536 conexões simultâneas, muito mais que o requerido pela maioria.

Para trabalhas com a tabela NAT, devemos usar nat como parâmetro para o iptables:
iptables -t nat COMANDO
onde COMANDO é o restante das opções a serem usadas.

Para os próximos exemplos, consideremos a rede representada a seguir:

http://di.uern.br/scc08/mnet.png

Digamos que os IP das inerfaces eth0, eth1, eth2 e da interface do LAMP são, respectivamente 200.a.b.1, 100.b.a.1, 10.2.2.1 e 10.2.2.128.

Para que os redirecionamentos possam funcionar corretamente, temos que ativar o ip_forward no kernel:
echo 1 > /proc/sys/net/ipv4/ip_forward
3.1 - Criando redirecionamentos de entrada (DNAT)
Também conhecido como Destination NAT, o redirecionamento da entrada consiste em alterar o IP/Porta de destino de pacotes chegando em um roteador. Seguindo o exemplo, precisamos que nosso servidor Web esteja acessível de todo e qualquer host na grande nuvem. Portanto, precisamos que os pacotes que cheguem na eth0 para o IP 200.a.b.1 sejam encaminhados para o endereço do nosso servidor, 10.2.2.128. Para tal, usamos a seguinte regras:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 10.2.2.128
O mesmo podemo fazer para o FTP:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 21 -j DNAT --to-destination 10.2.2.128
Porém, para que esse funcione corretamente precisamos da ajuda de alguns módulos do kernel, que podem ser carregados pelos seguintes comandos:
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
Essa necessidade se dá pelo funcionamento do protocolo FTP. Este se utiliza de uma porta dinâmica, a qual não pode ser prevista antecipadamente.

3.2 - Criando redirecionamentos de saída (SNAT)
NAT de origem, SNAT, consiste em alterar o endereço de origem do pacote. Num link com diversas interfaces, o SNAT pode ser usado para distribuir os serviços entre os links.

Digamos que, seguindo o diagrama de exemplo, queiramos que o tráfego HTTP saia pelo IP 200.a.b.1 e o tráfego MySQL pelo IP 100.b.a.1. As regras SNAT para o caso seriam:
iptables -t nat -A POSTROUTING -p tcp --sport 80 -s 10.2.2.128 -j SNAT --to-source 200.a.b.1
iptables -t nat -A POSTROUTING -p tcp --sport 3306 -s 10.2.2.128 -j SNAT --to-source 100.b.a.1
Continuando, todos os outros hosts irão se comunicar com a rede mundial pelo IP 200.a.b.1:
iptables -t nat -A POSTROUTING -s 10.2.2.0/24 -j SNAT --to-source 200.a.b.1
Juntando tudo no mesmo saco, nosso roteador terá o seguinte conjunto de regras:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 10.2.2.128
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 21 -j DNAT --to-destination 10.2.2.128
iptables -t nat -A POSTROUTING -p tcp --sport 80 -s 10.2.2.128 -j SNAT --to-source 200.a.b.1
iptables -t nat -A POSTROUTING -p tcp --sport 21 -s 10.2.2.128 -j SNAT --to-source 200.a.b.1
iptables -t nat -A POSTROUTING -p tcp --sport 3306 -s 10.2.2.128 -j SNAT --to-source 100.b.a.1
iptables -t nat -A POSTROUTING -s 10.2.2.0/24 -j SNAT --to-source 200.a.b.1
Sumarizando, a primeira e a segunda redirecionarão o tráfego de entrada da porta 80 e 21 na porta eth0 para o endereço IP 10.2.2.128; A terceira e quarta irão direcionar o tráfego de saída das portas 80 e 21 para o endereço IP 200.a.b.1; a quinta irá direcionar o tráfego de saída da porta 3306 para o endereço IP 100.b.a.1; e a ultima ira direcionar as demais conexões pelo endereço 200.a.b.1.

3.3 - Ajustando a política do filtro para o NAT
Pacotes que passam por ações de NAT continuam sendo verificados na chain FORWARD da tabela filter. Portanto, dependendo da política do filtro, regras devem ser adicionadas para que os pacotes trafeguem sem problemas.

Primeiramente, devemos entender o que acontesse com um pacote após sua passagem pela tabela nat. Condiremos o conjunto de regras expostas acima e o seguinte pacote:
Endereço de origem: 166.d.e.22
Endereço de destino: 200.a.b.1
Porta de origem: 3234
Porta de destino: 80
Observando o comportamento de nossa rede, esse pacote estaria chegando pela interface eth0 e casaria com a regra:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 10.2.2.128
Após sair da tabela nat, o pacote estaria com a seguinte configuração:
Endereço de origem: 166.d.e.22
Endereço de destino: 10.2.2.128
Porta de origem: 3234
Porta de destino: 80
Portanto, podemos inferir que até agora o caminho do nosso pacote no Netfilter/iptables foi:
raw (PREROUTING) >> mangle (PREROUTING) >> nat (PREROUTING)
Aparti desse ponto, o pacote está no domínio da tabela filter e da chain FORWARD. Então, caso nosso filtro seja restritivo, devemos adicionar uma regra que o permita:
iptables -A FORWARD -i eth0 -o eth2 -p tcp --dport 80 -d 10.2.2.128 -m state --state NEW -j ACCEPT
Vejam que a regra utiliza o endereço FINAL, ou seja, o endereço de DNAT. Então, continuando, para liberarmos o tráfego do MySQL:
iptables -A FORWARD -i eth1 -o eth2 -p tcp --dport 3306 -d 10.2.2.128 -m state --state NEW -j ACCEPT
Lembrando que decidimos que os pacotes do MySQL sairão pelo endereço da interface eth1, 100.b.a.1.

Enfatizando um pouco a tragetória dos pacotes pelas regras, nossa inferência inicial está correta, mas não completa. O pacote deve passar também pela chain POSTROUTING da tabela nat e mangle, ficando o caminho completo como:
raw (PREROUTING) -> mangle (PREROUTING) -> nat (PREROUTING) -> filter (FORWARD) -> mangle (POSTROUTING) -> nat (POSTROUTING)
Porém, como não há nenhuma regra que caso com o pacote, ele passará intacto. A figura no link http://linux-ip.net/nf/nfk-traversal.png é bastante didática nesse assunto.

Agora, considerando o caso de um pacote gerado pela nossa rede:
Endereço de origem: 10.2.2.10
Endereço de destino: 168.e.d.100
Porta de origem: 4327
Porta de destino: 22
Vejam que esse pacote tem como destino um IP fora de nossa rede. Porém, o caminho do pacote nas tabelas e chains é a mesma. Então primeiramente o pacote passará pela tabela filter antes de passar pela regra a qual casaria, que se encontra na chain POSTROUTING da tabela nat:
iptables -t nat -A POSTROUTING -s 10.2.2.0/24 -j SNAT --to-source 200.a.b.1
Portanto, as regras do filtro devem levar em consideração o endereço original do pacote. Então, caso nosso filtro seja restritivo e desejamos liberar o tráfego da porta 22 para rede 10.2.2.0/24, devemos incluir a seguinte regra:
iptables -A FORWARD -i eth2 -p tcp --dport 22 -s 10.2.2.0/24 -m state --state NEW -j ACCEPT
Logo em seguida, o pacote seria encaminhado para a tabela nat e casaria com a regra, ficando com os seguintes valores:
Endereço de origem: 200.a.b.1
Endereço de destino: 168.e.d.100
Porta de origem: 4327
Porta de destino: 22
Vejam que se estivessemos num filtro permissivo e a decisão fosse bloquear o pacote, ele nunca atingiria a chain POSTROUTING da tabela nat.

Então, esse seria o conjunto de regras final do nosso roteador para um filtro de pacotes restritivo:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 10.2.2.128
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 21 -j DNAT --to-destination 10.2.2.128
iptables -t nat -A POSTROUTING -p tcp --sport 80 -s 10.2.2.128 -j SNAT --to-source 200.a.b.1
iptables -t nat -A POSTROUTING -p tcp --sport 21 -s 10.2.2.128 -j SNAT --to-source 200.a.b.1
iptables -t nat -A POSTROUTING -p tcp --sport 3306 -s 10.2.2.128 -j SNAT --to-source 100.b.a.1
iptables -t nat -A POSTROUTING -s 10.2.2.0/24 -j SNAT --to-source 200.a.b.1

iptables -P FORWARD DROP
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i eth0 -o eth2 -p tcp --dport 80 -d 10.2.2.128 -m state --state NEW -j ACCEPT
iptables -A FORWARD -i eth0 -o eth2 -p tcp --dport 21 -d 10.2.2.128 -m state --state NEW -j ACCEPT
iptables -A FORWARD -i eth1 -o eth2 -p tcp --dport 3306 -d 10.2.2.128 -m state --state NEW -j ACCEPT

iptables -A FORWARD -i eth2 -p tcp --dport 80 -s 10.2.2.0/24 -m state --state NEW -j ACCEPT
iptables -A FORWARD -i eth2 -p udp --dport 53 -s 10.2.2.0/24 -m state --state NEW -j ACCEPT

iptables -P OUTPUT DROP
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables P INPUT DROP
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i eth2 -p tcp --dport 22 -s 10.2.2.0/24 -d 10.2.2.1 -j ACCEPT
Notem que só estamos liberando o HTTP para o resto da rede... hehehe... que mal! Liberamos também o acesso SSH (porta 22) para que o roteador possa ser administrado da rede interna.

Lembrem-se que as regras de otimização do filtro também vale para as regras da tabela nat, portanto nosso conjunto de regras acima ainda precisa de um pouco de engenharia para ficar 100%.

4 - Minhas regras...
O seguinte conjunto de regras são as que eu uso no meu dia-a-dia.
echo 1 > /proc/sys/net/ipv4/ip_forward

iptables -F
iptables -F -t nat

iptables -t nat -A POSTROUTING -s 192.168.0/24 -o wlan0 -j MASQUERADE

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

iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state INVALID -j DROP
iptables -A OUTPUT -m state --state NEW -j ACCEPT

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -s 192.168.0.0/24 -j ACCEPT

iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state NEW -s 192.168.0/24 -j ACCEPT
Possuo um pequeno laboratório e compartilho minha conexão com os demais computadores pela interface wlan0. Como esse IP não é fixo, eu utilizo a target MASQUERADE para que faça o trabalho sujo para mim.

Todas as conexões de saída do meu PC estão liberadas. Esse comportamento está previsto na na terceira regra que trata da chain OUTPUT. Já as conexões de entrada só são permitidas caso o endereço de origem esteja na minha rede pessoal de endereço IP 192.168.0.0/24. Contando que advindos da minha rede pessoal, qualquer pacote pode atravessar. Toda minha tabela filter é restritiva. Sou um cara muito paranóico!

5 - Conclusões
Sei lá... Netfilter/iptables é legal?
_________

Mas sério, espero que esse post tenha esclarecido um pouco as dúvidas do pessoal que trabalha com Netfilter/iptables. A maioria dos problemas que vemos nos fóruns estão relacionados com os temas abordados aqui, que, como podemos ver, são de carater básico. Ou seja, uma leitura caprichada em um bom livro de filtro de pacotes sana todas elas. Recomendo o Linux Firewalls, Novell Press.

Até a próxima!

ps: comentários, erratas e sugestões são muito bem vindos!
Categorias
Não Categorizado

Comentários

  1. Avatar de Magnun
    Muito bom cara! Parabéns e até a próxima....
  2. Avatar de Erikam
    Putz, valeu !!
    Tô com uma sopinha de letras para debugar e o seu blog está bem didático. Leitora assídua..
  3. Avatar de ecbr2003
    ficou muito bom, mas no meu ver poderia ficar um pouco mais simples com a mesma eficacia.
  4. Avatar de PEdroArthurJEdi
    Tentei deixar o mais didático possível. Porém se acha que pode ser mais simples, e tão didático quanto, a questão se torna: como?

    Pode sugerir... O botão de editar funciona pra isso!
    Atualizado 17-01-2009 em 14:26 por PEdroArthurJEdi
  5. Avatar de mainframedj
    Prezado Pedro,
    Estou numa luta danada. Aproximadamente 2 meses atrás, me apaixonei e resolvi trocar os servidores da empresa para CentOS. Agora estou pagando pela minha inexperiência em Linux. Embora eu não vá desistir NUNCA do Linux, confesso que devido eu não ter nenhuma experência com o Linux, estou penando. Mas preciso dessa ajuda a seguir, pois meu chefe quer por que quer voltar com o “ruindows 2003”.
    Espero não te alugar muito, mas se houver algum toque que possa me dar, ficarei agradecido.
    Temos 3 servidores:
    NOME
    ENDEREÇO
    OS
    RODANDO...
    Yoda
    10.64.1.3
    CentOS
    squid / gateway internet / openldap (eth0 – rede local e ppp0 – internet velox)
    Darth
    10.64.1.5
    CentOS
    mysql / postgresql / apache (WWW) / tomcat (rodando outras aplicações em Java) / CollabNet Subversion
    Obiwan
    10.64.1.12
    Windows 2003
    tomcat (aplicações teste) / postgresql (teste) / servidor de arquivos / servidor de backup

    Temos o serviço DNSExit que está instalado no 10.64.1.3 e está publicando nosso IP (velox). O que não está acontecendo quando é digitado por qualquer pessoa externamente, é o seguinte:
    1 – Quando é digitado www.site.com.br, preciso direcionar para 10.64.1.12 na porta 9090 no diretório /htmldocs/site;
    2 – Quando é digitado crm.site.com.br, preciso direcionar para 10.64.1.5 na porta 80 e no diretório /var/www/html/crm;
    3 – Quando for digitado testpar.site.com.br, preciso direcionar para 10.64.1.5 na porta 8080 no diretório /var/www/html/testpar;
    Antes, quando meu gateway era Windows 2003, eu tratava tudo isso tranquilamente, pegando o cabeçalho do pacote que entrava em minha conexão internet. E Isso eu não sei como fazer.
    Muito obrigado.
  6. Avatar de PEdroArthurJEdi
    Da mesma forma que no Janelas DoisMileTrês, você tem que configurar um proxy HTTP, seja no servidor, seja em uma das máquinas. O IPTables por si só não poderá dar conta do serviço.
  7. Avatar de Michel
    Estou com problema em minha conexao, tenho um server Debian e nao consigo fazer acesso a porta 23000 que é usada pelo serpro.
    Eth1-rede local
    eth2- internet

    iptables -F
    iptables -L

    nao passa a conexao, uso um proxi 'squid' e ja liberei na acl esta porta mas nao deu certo. pode me dar uma ajuda. ([email protected])
  8. Avatar de ksombrah
    Olá estou tentando bloquear os downloads de um webmail específico, pesquisando cheguei nesse script:
    for i in 172.217.1.110 216.239.32.10 216.239.34.10 216.239.36.10 216.239.38.10 142.251.16.26 142.251.16.27 142.251.163.26 142.251.163.27 142.251.167.26
    do
    iptables -A INPUT -p tcp -d $i --dport 80 -m string --string "Content-Disposition: attachment;" --algo bm -j DROP
    iptables -A INPUT -p tcp -d $i --dport 80 -m string --string "Content-Disposition: attachment;" --algo bm -j REJECT
    iptables -A INPUT -p tcp -d $i --dport 443 -m string --string "Content-Disposition: attachment;" --algo bm -j DROP
    iptables -A INPUT -p tcp -d $i --dport 443 -m string --string "Content-Disposition: attachment;" --algo bm -j REJECT
    iptables -A FORWARD -p tcp -d $i --dport 80 -m string --string "Content-Disposition: attachment;" --algo bm -j DROP
    iptables -A FORWARD -p tcp -d $i --dport 80 -m string --string "Content-Disposition: attachment;" --algo bm -j REJECT
    iptables -A FORWARD -p tcp -d $i --dport 443 -m string --string "Content-Disposition: attachment;" --algo bm -j DROP
    iptables -A FORWARD -p tcp -d $i --dport 443 -m string --string "Content-Disposition: attachment;" --algo bm -j REJECT
    done
    Mas não está funcionando, alguma idéia?

+ Enviar Comentário