Iptables

Configurando o Iptables e Fazendo Regras Básicas

20 de janeiro de 2004
Postado por: Thadeu Camargo

Já está mais do que comprovado: Hoje em dia uma máquina sem conexão com a internet não tem maior valia do que uma máquina de escrever. É certo que os micros precisam se conectar para trocar informações, ou mesmo somente para baixar um driver para que seu dispositivo de hardware funcione. A partir do momento em que a máquina tem uma conexão com a internet, está sujeita a ataques de crackers ou scriptie kids. Se um micro pessoal está sujeito a ataques, que dirá então uma rede de computadores. Existem vários sujeitos prontos para se aproveitarem de máquinas vulneráveis. Para evitar intempéries como estas o usuário ou administrador da rede precisa implantar políticas de segurança. Uma destas políticas é a implantação de um firewall.
Firewall, como o nome diz, é uma porta de fogo. Uma muralha onde somente o que está devidamente autorizado pode entrar ou sair. Maiores detalhes sobre firewall podem ser vistos aqui.

Um sistema bem servido de firewall

Existem firewalls para todos os sistemas operacionais mas creio que nenhum deles esteja tão bem servido quanto o Linux. Sem desmerecer outros mas a solução Iptables ao meu ver é uma das melhores, senão a melhor que eu já vi para segurança de sistemas. A grande vantagem do Iptables é a sua estabilidade, rapidez, eficiência reconhecida e relativa facilidade de administração devido a sua configuração poder ser feita através de scripts. Outras características do Iptables:

.: Suporte aos protocolos TCP, UDP, ICMP
.: Pode se especificar portas de endereço e de destino.
.: Suporta módulos externos como FTP e IRC
.: Suporta um número ilimitado de regras por CHAINS ( correntes ).
.: Pode se criar regras de proteção contra ataques diversos
.: Suporte para roteamento de pacotes e redirecionamento de portas.
.: Suporta vários tipos de NAT, como o SNAT e DNAT e mascaramento.
.: Pode priorizar tráfego para determinados tipos de pacotes.
.: Entre outras o Iptables já tem suporte a IPV6, através do programa ip6tables.

O Iptables acompanha o kernel 2.4.x. Antes dele existia o Ipchains ( kernel 2.2.x ) e anteriormente ainda existia o Ipfwadm. Na realidade no kernel 2.4.x ainda existem os filtros Ipchains e Ipfwadm por motivos de compatibilidade mas ambos não estão ativos. Caso estejam ativos ( isto pode acontecer com o Ipchains ) é necessário desativá-los para que o Iptables possa funcionar plenamente.

Funcionamento

Através de regras poderemos fazer com que os pacotes possam ser ou não recebidos a rede toda, a determinada máquina, interface ou mesmo porta de conexão. O Iptables trabalha através de Tabelas, Chains e Regras:

Tabelas: Existem 3 tabelas possíveis de serem utilizadas no Iptables, sendo que uma delas, a mangle raramente é usada, restando a filter, que é a padrão, utilizada nos tráfegos de dados comuns, sem ocorrência de NAT. Quando não especificamos qual tabela a ser utilizada é ela que será ativada. A outra geralmente utilizada é a nat, que como o próprio nome diz, usada quando há ocorrência de NAT.

Chains: Através delas podemos especificar a situação do tratamento dos pacotes, seja qual tabela for.
Quando utilizamos a tabela nat as Chains possíveis são:
PREROUTING – Quando os pacotes entram para sofrerem NAT.
POSTROUTING – Quando os pacotes estão saindo após sofrerem NAT
OUTPUT – Pacotes que são gerados na própria máquina e que sofrerão NAT
Já com a tabela filter as Chains são:
INPUT – Pacotes cujo destino final é a própria máquina firewall.
OUTPUT – Pacotes que saem da máquina firewall
FORWARD – Pacote que atravessa a máquina firewall, cujo destino é uma outra máquina. Este pacote não sai da máquina firewall e sim de outra máquina da rede ou fonte. Neste caso a máquina firewall está repassando o pacote.

Regras: As regras de firewall geralmente são compostas de uma Tabela, Opção, Chain, Dados e Ação. Através destes elementos podemos especificar o que fazer com os pacotes.
Opções:
-P
Define uma regra padrão
-A
Acrescenta uma nova regra as existentes.
Este tem prioridade sobre a -P
-D
Apaga-se uma regra
-L
Lista as regras existentes
-F
Apaga todas as regras
-I
Insere uma regra nova
-h
Muito útil, pois mostra a ajuda
-R
Substitui uma regra
-C
Faz uma checagem das regras existentes
-Z
Zera uma regra específica
-N
Cria uma nova regra com um nome
-X
Exclui uma regra específica pelo seu nome

Dados:
-s : Especifica o origem do pacote. Este pode ser tanto uma rede ou host. Possíveis combinações podem ser:
-s 192.168.0.0/255.255.255.0
ou
-s 192.168.0.0/24
OBS: No segundo caso estamos especificando a máscara de rede conforme o número de bits 1, por exemplo:
Máscara de rede 255.0.0.0 = 8
Máscara de rede 255.255.0.0 = 16
Máscara de rede 255.255.255.0 = 24

No exemplo acima estamos especificando toda uma rede de máscara C, no exemplo abaixo especificamos um host:
-s 192.168.30.51/255.255.255.255
ou
-s 192.168.30.51
também pode ser assim:
-s 192.168.30.51/32
OBS: A máscara em números de bits 1 para host é 32.

Podemos especificar assim também:
-s www tccamargo.com

Podemos especificar qualquer origem também:
-s 0.0.0.0/0.0.0.0
ou
-s 0/0

-d : Especifica o destino do pacote. A sintaxe é a mesma do -s

-p : Protocolo usado na regra. Pode ser tcp, udp, icmp:
-p tcp
-p udp
-p icmp

-i : Interface de entrada, ou seja, placa de rede, modem ou interface de conexão que estará recebendo o pacote a ser tratado.
-i eth0
-i eth1
-i ppp0

-o : Interface de saída. As sintaxes são as mesmas que -i, sendo que neste caso estará enviando o pacote a ser tratado.

! : Exclui determinado argumento:
-i ! eth0 – Refere-se a qualquer interface de entrada exceto a eth0
-s ! 192.168.0.45 – Refere-se a qualquer endereço de entrada exceto o 192.168.0.45

–sport : Refere-se a porta de origem. Este deve vir acompanhado das funções -p tcp e -p udp :
-p tcp –sport 80 – Refere-se a porta de origem 80 sob protocolo tcp

–dport : Refere-se a porta de destino. Assim como a função –sport, ela trabalha somente com a -p tcp e -p udp. A sintaxe é similar a –sport

Através das funções –sport e –dport podemos especificar não só uma porta específica como também um range de portas:
–sport 33435:33525

Ações:
As ações sempre vem após o parâmetro -j e geralmente são:
ACCEPT – Aceita e permite a passagem do pacote.
DROP – Não permite a passagem do pacote e abandona-o não dando sinais de recebimento.
REJECT – Assim como o DROP, não permite a passagem do pacote, mas envia um aviso ( icmp unreachable )
LOG – Cria um Log referente a regra em /var/log/messages

Com estes fatores podemos criar as nossas regras com a seguinte composição:
# iptables -A FORWARD -s 192.168.0.45 -p icmp -j DROP
Sendo: -A ( opção ) / FORWARD ( Chain ) / -s 192.168.0.45 -p icmp ( Dados ) -j DROP ( Ação )

No caso do exemplo a cima a regra determina que todos os pacotes icmp originários do endereço 192.168.0.45 devem ser barrados.

Salvando as regras

Depois das regras prontas podemos salvá-las com este comando:
# iptables-save >

Para recuperá-las use este comando:
# iptables-restore >

Outra forma seria fazer um script com as regras:
Corpo do Script
#!/bin/bash
#limpando tabelas
iptables -F &&
iptables -X &&
iptables -t nat -F &&
iptables -t nat -X &&
#liberando acesso interno da rede
iptables -A INPUT -p tcp –syn -s 192.168.1.0/255.255.255.0 -j ACCEPT &&
iptables -A OUTPUT -p tcp –syn -s 192.168.1.0/255.255.255.0 -j ACCEPT &&
iptables -A FORWARD -p tcp –syn -s 192.168.1.0/255.255.255.0 -j ACCEPT &&
#compartilhando a web na rede interna
iptables -t nat -A POSTROUTING -s 192.168.1.0/255.255.255.0 -o eth1 -j MASQUERADE &&
echo 1 > /proc/sys/net/ipv4/ip_forward &&
# Protecao contra port scanners ocultos
iptables -A INPUT -p tcp –tcp-flags SYN,ACK,FIN,RST RST -m limit –limit 1/s -j ACCEPT
# Bloqueando tracertroute
iptables -A INPUT -p udp -s 0/0 -i eth1 –dport 33435:33525 -j DROP
#Protecoes contra ataques
iptables -A INPUT -m state –state INVALID -j DROP
#termina
echo “Iptables Pronto”

Salve-o com um nome sugestivo, como por exemplo “start-firewall”.
Dê permissão de execução:
chmod +x start-firewall

Pronto. Toda vez que quiser que ele seja habilitado é só executá-lo ( sempre como root ):
# start-firewall

Para não ter que ficar chamando o script toda vez que inicializar o sistema, podemos fazer com que ele seja ativado na inicialização. Para isso é preciso editar o arquivo
/etc/rc.d/rc.local e incluir o comando no final do arquivo.:-)

Compartilhamento de conexão, mascaramento e redirecionamento de pacotes

Verifique que nestas linhas do script exemplo:
iptables -t nat -A POSTROUTING -s 192.168.1.0/255.255.255.0 -o eth1 -j MASQUERADE &&
echo 1 > /proc/sys/net/ipv4/ip_forward &&

Estou fazendo com que os micros de minha rede possam utilizar a internet através do roteamento dinâmico. A linha que habilita o redirecionamento de pacotes é essa:
echo 1 > /proc/sys/net/ipv4/ip_forward
Mas vale observar que se inserirmos somente esta linha no script, a cada vez que reiniciar o sistema será necessária a ativação do roteamento. Para que não percamos o roteamento é necessário editar o arquivo /etc/sysctl.conf e inserirmos ou modificarmos a linha do modo que fique assim:
net.ipv4.ip_forward= 1

Voltando a nossa regra do script exemplo, verificamos uma ação nova ( MASQUERADE ), servindo para que as máquinas da rede interna possam acessar a internet usando o IP externo do Gateway. Deste modo as máquinas da rede interna ficarão invisíveis para a rede externa. Para que uma máquina da rede interna possa executar serviços onde cuja execução necessita que o IP da máquina seja visível para redes externas, será necessário fazer um redirecionamento de IPs ou portas.
Digamos que uma máquina de IP 192.168.0.45 precise executar um serviço de FTP, na qual é necessária a visibilidade da máquina. Podemos fazer com que a máquina firewall, cujo IP externo seja 200.135.100.102 receba estes pacotes e retransmita:
iptables -t nat -A PREROUTING -s 200.135.100.102 -i eth0 -j DNAT –to 192.168.0.45
iptables -t nat -A POSTROUTING -s 200.135.100.102 -o eth0 -p tcp –dport 21 -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.0.45 -o eth0 -j SNAT –to 200.135.100.102
iptables -t nat -A POSTROUTING -s 192.168.0.45 -o eth0 -p tcp –dport 21 -j ACCEPT

Veja que nestas regras temos mais duas ações novas SNAT e DNAT:
SNAT – Aplicada quando queremos alterar o endereço de origem do pacote. Aqui nós utilizamos para fazer o mascaramento. OBS: Somente a Chain POSTROUTING pode ser usada na ação SNAT.
DNAT – Aplicada quando desejamos alterar o endereço de destino do pacote. Esta ação é utilizada para fazer redirecionamento de portas, redirecionamento de servidor, load balance e proxy transparente. As Chains que podem ser utilizadas para esta ação são PREROUTING e OUTPUT.
Além destas duas ações, existe também a REDIRECT que pode ser utilizada para fazer redirecionamento de portas. Quando fazemos um redirecionamento de portas usamos o dado –to-port após a ação REDIRECT:
iptables -t nat -A PREROUTING -i eth0 -p tcp –dport 80 -j REDIRECT –to-port 3128
#Esta regra faz com que todos os pacotes direcionados a porta tcp 80 sejam redirecionados para a porta 3128.
Quando utilizamos a tabela nat, é preciso inserir o parâmetro -t para especificar a tabela:
-t nat
Perceba que quando omitimos este parâmetro usamos a tabela filter por padrão.
Além destas ações, veja que existe também um dado novo:
–to : Este dado serve para definir o IP ou porta de destino numa ação SNAT ou DNAT:
iptables -t nat -A PREROUTING -p tcp -d 200.135.100.102 –dport 80 -j DNAT –to 192.168.0.45
# Esta regra faz com que os pacotes direcionados a porta tcp 80 sejam redirecionados para a máquina 192.168.0.45 . Como não especificamos a porta, a máquina de destino receberá o pacote na porta 80
Além do IP podemos definir a porta deste endereço na ação:
iptables -t nat -A PREROUTING -p tcp -d 200.135.100.102 –dport 80 -j DNAT –to 192.168.0.45:3128
# Aqui, assim como na regra anterior, os pacotes são redirecionados para a máquina 192.168.0.45 mas neste caso especificamos a porta, ou seja, porta 3128

Algumas opções e observações

Vale fazer umas pequenas observações a respeito da ordem das regras e manejo. Uma delas é que a a primeira regra tem prioridade sobre a segunda caso ambas estejam em conflito, veja:
iptables -A FORWARD -p tcp –syn -s 192.168.1.0/24 -j ACCEPT
iptables -A FORWARD -p tcp –syn -s 192.168.1.0/24 -j DROP

A que terá valia será a primeira, ou seja:
iptables -A FORWARD -p tcp –syn -s 192.168.1.0/24 -j ACCEPT

Podemos ver todas as regras em andamento ao darmos o comando:
iptables -L

Com os comandos abaixo limpamos todas as tabelas e regras:
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X

Para que tudo possa funcionar a contento é necessário primeiramente que todos os módulos necessários estejam carregados:
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
modprobe ip_queue
modprobe ip_tables
modprobe ipt_LOG
modprobe ipt_MARK
modprobe ipt_MASQUERADE
modprobe ipt_MIRROR
modprobe ipt_REDIRECT
modprobe ipt_REJECT
modprobe ipt_TCPMSS
modprobe ipt_TOS
modprobe ipt_limit
modprobe ipt_mac
modprobe ipt_mark
modprobe ipt_multiport
modprobe ipt_owner
modprobe ipt_state
modprobe ipt_tcpmss
modprobe ipt_tos
modprobe ipt_unclean
modprobe iptable_filter
modprobe iptable_mangle
modprobe iptable_nat

É importante ressaltar que as regras devem seguir uma ordem definida, ou seja, a regra posterior deve estar de acordo com a regra anterior para que tudo corra sem problemas.:
iptables -P FORWARD -j DROP
iptables -A FORMARD -s 192.168.0.0/24 -d 10.0.0.0/8 -j ACCEPT

Através desta regra, determinamos que todo o repasse de pacotes seja bloqueado, depois permitimos que possa repassar pacotes da rede 192.168.0.0 para a rede 10.0.0.0 mas esta não poderá retornar os pacotes. Então o correto seria inserir mais uma regra aqui:
iptables -A FORWARD -d 192.168.0.0/24 -s 10.0.0.0/8 -j ACCEPT

Para que a rede 10.0.0.0 possa repassar os pacotes, fazendo deste jeito com que as redes possam conversar sem problemas.
Ao fazer as regras lembre-se de primeiro bloquear, depois abrir o acesso.:
iptables -P FORMARD -j DROP
iptables -A FORWARD -s 192.168.0.45 -p tcp –sport 80 -j ACCEPT

Considerações finais

Iptables tem infinitas possibilidades de regras. É impossível citar todos os parâmetros e regras que podem ser utilizados, pois daria uma verdadeira bíblia. Cabe ao bom administrador estudar com afinco para poder aplicar as regras mais convenientes para a sua rede. E o usuário final tem em mãos um excelente recurso para deixar sua máquina protegida de ataques externos. Esta é a grande vantagem do Iptables, pode se aplicar regras conforme a conveniência da rede e usuários. Sem dúvida nenhuma é uma ferramenta poderosíssima.

Exemplos de regras comumente utilizadas

Nas linhas abaixo incluí algumas regras que são comumente utilizadas. Algumas destas podem ser úteis para fazer o seu firewall mas lembre-se de adaptá-las para sua rede/interface/máquina antes de aplicá-las:

#Libera o apache pra web
iptables -A INPUT -p tcp –destination-port 6080 -j ACCEPT
iptables -A INPUT -p tcp –destination-port 443 -j ACCEPT
#Libera o loopback
iptables -A OUTPUT -p tcp –syn -s 127.0.0.1/255.0.0.0 -j ACCEPT
#Bloqueando todos os endereços vindo de uma determinada rede para a minha máquina
iptables -A INPUT -s 10.0.0.0/8 -j DROP
#Liberando o endereço vindo de uma rede para a minha máquina
iptables -A INPUT -s 10.0.0.1 -j ACCEPT
#Gerando Logs de Portas proibidas
iptables -A INPUT -p tcp –dport 21 -j –log-prefix “Serviço de FTP”
#Gerando log de Backdoors
iptables -A INPUT -p tcp –dport 5042 -j LOG -log-prefix “Wincrash”
iptables -A INPUT -p tcp –dport 12345 -j LOG -log-prefix “backOrifice”
iptables -A INPUT -p tcp –dport 12346 -j LOG -log-prefix “backOrifice”
#Habilitando porta de FTP
iptables -A INPUT -p tcp -s 192.168.0.45 –dport 21 -j ACCEPT
#Habilitando porta de SSH
iptables -A INPUT -p tcp -s 192.168.0.45 –dport 22 -j ACCEPT
#Habilitando porta de SMTP
iptables -A INPUT -p tcp -s 192.168.0.45 –dport 25 -j ACCEPT
#Habilitando porta de DNS
iptables -A INPUT -p tcp -s 192.168.0.45 –dport 53 -j ACCEPT
#Habilitando porta de POP3
iptables -A INPUT -p tcp -s 192.168.0.45 –dport 110 -j ACCEPT
#Habilitando porta de DNS (UDP)
iptables -A INPUT -p udp -s 192.168.0.45 –source-port 53 -j ACCEPT
#Redirecionar Porta
iptables -t nat -A PREROUTING -s IP_NET -i EXT_INT -j DNAT –to IP_DESTINO
iptables -t nat -A POSTROUTING -s IP_NET -o EXT_INT -p tcp –dport PORT -j ACCEPT
iptables -t nat -A POSTROUTING -s IP_DESTINO -o EXT_INT -j SNAT –to IP_NET
iptables -t nat -A POSTROUTING -s IP_DESTINO -o EXT_INT –p tcp –dport PORT -j ACCEPT
IP_NET = IP válido da internet.
EXT_INT = Interface da Internet.
IP_DESTINO = IP inválido da Internet ou melhor ip da rede que vai fazer redirecionamento.
PORT = porta
#Fazendo redirecionamento de portas
iptables -t nat -A PREROUTING -i FACE -p tcp –dport 80 -j REDIRECT –to-port 3128
FACE = interface de rede
#Bloqueando todos os pacotes originários da rede 10.0.0.0 para o host www.tccamargo.com
iptables -A FORWARD -s 10.0.0.0/8 -d www.tccamargo.com -j DROP
#Liberando todos os pacotes originários da rede 10.0.0.0 para o host www.tccamargo.com
iptables -A FORWARD -s 10.0.0.0/8 -d www.tccamargo.com -j ACCEPT
#Liberando todos os pacotes tcp destinados a porta 25
iptables -A FORWARD -p tcp –dport 25 -j ACCEPT
#Liberando acesso interno da rede
iptables -A INPUT -p tcp –syn -s 192.168.1.0/24 -j ACCEPT
iptables -A OUTPUT -p tcp –syn -s 192.168.1.0/24 -j ACCEPT
iptables -A FORWARD -p tcp –syn -s 192.168.1.0/24 -j ACCEPT
#compartilhando a web na rede interna
iptables -t nat -A POSTROUTING -s 192.168.1.0/255.255.255.0 -o eth1 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward &&
#Libera Bittorrent somente para esta maquina
iptables -A INPUT -p tcp –destination-port 6881:6889 -j ACCEPT
#Bloqueando tracertroute
iptables -A INPUT -p udp -s 0/0 -i eth1 –dport 33435:33525 -j DROP
#Protecoes contra ataques
iptables -A INPUT -m state –state INVALID -j DROP
#Bloqueando uma máquina pelo endereço MAC
iptables -A INPUT -m mac –mac-source XX:XX:XX:XX:XX:XX -j DROP
#Proteção contra IP Spoofing
iptables -A INPUT -s 172.16.0.0/16 -i ext_face -j DROP
iptables -A INPUT -s 192.168.0.0/24 -i ext_face -j DROP
iptables -A INPUT -s 192.168.0.0/24 -i ext_face -j DROP
< ext_face = São as interfaces da internet como ppp e ethX >
#Proteção contra Syn-floods
iptables -A FORWARD -p tcp –syn -m limit –limit 1/s -j ACCEPT
#Proteção contra port scanners ocultos
iptables -A FORWARD -p tcp –tcp-flags SYN,ACK,FIN,RST RST -m limit –limit 1/s -j ACCEPT
#Proteção contra ping da morte
iptables -A FORWARD -p icmp –icmp-type echo-request -m limit –limit 1/s -j ACCEPT
#Bloqueando ping de um ip
iptables -A INPUT -p icmp -s 192.168.1.1/24 -j DROP
#Bloqueando pacotes fragmentados
iptables -A INPUT -i INTEXT -m unclean -j log_unclean
iptables -A INPUT -f -i INTEXT -j log_fragment
< INTEXT = Interface da INTERNET >
#Anulando as respostas a ICMP 8 (echo reply)
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all

================================================================

Linux IPTables: Incoming and Outgoing Rule Examples (SSH and HTTP)
by RAMESH NATARAJAN on MARCH 15, 2011

In our previous IPTables firewall series article, we reviewed how to add firewall rule using “iptables -A”.

We also explained how to allow incoming SSH connection. On a high-level, it involves following 3 steps.

Delete all existing rules: “iptables -F”
Allow only incoming SSH: “iptables -A INPUT -i eth0 -p tcp –dport 22 -j ACCEPT”
Drop all other incoming packets: “iptables -A INPUT -j DROP”
The above works. But it is not complete. One problem with the above steps is that it doesn’t restrict the outgoing packets.

Default Chain Policy

The default policy of a chain is ACCEPT. If you don’t what what a chain means, you better read our iptables introduction article. So, both the INPUT and OUTPUT chain’s default policy is ACCEPT. In the above 3 steps we dropped all incoming packets at the end (except incoming ssh). However, we didn’t restrict the outgoing traffic.

As you notice below, it says “(policy ACCEPT)” next to all the three chain names (INPUT, OUTPUT, and FORWARD). This indicates that the default chain policy is ACCEPT.

# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp — anywhere anywhere tcp dpt:ssh
DROP all — anywhere anywhere

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination
So, you have two options here.

Option 1: Add drop rules

At the end, add the following three drop rules that will drop all incoming, outgoing, and forward packets (except those that are defined above these three rules). If you do this, the default chain policy is still ACCEPT, which shouldn’t matter, as you are dropping all the packets at the end anyway.

iptables -A INPUT -j DROP
iptables -A OUTPUT -j DROP
iptables -A FORWARD -j DROP
Option 2: Change the default chain policy to DROP

At the beginning, execute the following three commands that will change the chain’s default policy to DROP.

iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
Now, if you add the allow ssh rule: “iptables -A INPUT -i eth0 -p tcp –dport 22 -j ACCEPT”, and do iptables -L, you’ll notice that it says “(policy DROP)” next to all the three chains.

# iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT tcp — anywhere anywhere tcp dpt:ssh
DROP all — anywhere anywhere

Chain FORWARD (policy DROP)
target prot opt source destination

Chain OUTPUT (policy DROP)
target prot opt source destination
But there is a problem here. The allow ssh incoming connection rule will not work anymore, because all the outgoing packets are dropped.

Allow Incoming Connections

When the default policy is DROP for INPUT and OUTPUT chains, for every incoming firewall rule, you need to specify the following two rules.

Request rule: This is the request that comes from the client to the server for the incoming connection.
Response rule: This is for the response that goes out from the server to the client (for the corresponding incoming request).
Example 1: Allow incoming SSH connection

This is to allow SSH connection from outside to your server. i.e You can ssh to your server from outside.

This involves two steps. First, we need to allow incoming new SSH connections. Once the incoming ssh connection is allowed, we also need to allow the response back for that incoming ssh connection.

First, Allow incoming SSH connection request, as shown below.

iptables -A INPUT -i eth0 -p tcp –dport 22 -m state –state NEW,ESTABLISHED -j ACCEPT
In the above example:

iptables -A INPUT: Append the new rule to the INPUT chain. For incoming connection request, this always has to be INPUT.
-i eth0: This refers to the input interface. For incoming connections, this always has to be ‘-i’.
-p tcp: Indicates that this is for TCP protocol.
–dport 22: This refers to the destination port for the incoming connection. Port 22 is for ssh.
-m state: This indicates that the “state” matching module is used. We’ll discuss more about “-m” option (and all available matching modules for iptables) in future article.
–state NEW, ESTABLISHED: Options for the “state” matching module. In this example, only NEW and ESTABLISHED states are allowed. The 1st time when a SSH connection request is initiated from the client to the server, NEW state is used. ESTABLISHED state is used for all further request from the client to the server.
Next, Allow outgoing (ESTABLISHED state only) SSH connection response (for the corresponding incoming SSH connection request).

iptables -A OUTPUT -o eth0 -p tcp –sport 22 -m state –state ESTABLISHED -j ACCEPT
In the above example:

iptables -A OUTPUT: Append the new rule to the OUTPUT chain. Since this is for the response rule (for the corresponding incoming request) that goes out from the server, this should be OUTPUT.
-o eth0: This refers the output interface. For outgoing connections, this always has to be ‘-o’.
-p tcp: Indicates that this is for TCP protocol.
–sport 22: This refers to the source port for the outgoing connection. Port 22 is for ssh. Since the incoming request (from the previous rule) came to the “destination” port, the outgoing response will go through the “source” port.
-m state: This indicates that the “state” matching module is used.
–state ESTABLISHED: Since this is a response rule, we allow only ESTABLISHED connection (and not any NEW connection).
Example 2: Allow incoming HTTP connection

This is to allow HTTP connection from outside to your server. i.e You can view your website running on the server from outside.

Just like the above SSH incoming rules, this also involves two steps. First, we need to allow incoming new HTTP connection. Once the incoming HTTP connection is allowed, we need to allow the response back for that incoming HTTP connection.

First, Allow incoming HTTP connection request, as shown below.

iptables -A INPUT -i eth0 -p tcp –dport 80 -m state –state NEW,ESTABLISHED -j ACCEPT
Next, Allow outgoing (ESTABLISHED only) HTTP connection response (for the corrresponding incoming SSH connection request).

iptables -A OUTPUT -o eth0 -p tcp –sport 80 -m state –state ESTABLISHED -j ACCEPT
Note: In the above HTTP request and response rule, everything is same as the SSH example except the port number.

Allow Outgoing Connections

When the default policy is DROP for the INPUT and OUTPUT chains, for every outgoing firewall rule, you need to specify the following two rules.

Request rule: This is the request that goes out from the server to outside for the outgoing connection.
Response rule: This is for the response that comes back from the outside to the server (for the corresponding outgoing request).
Example 3: Allow outgoing SSH connection

This is to allow SSH connection from your server to the outside. i.e You can ssh to outside server from your server.

This involves two steps. First, we need to allow outgoing new SSH connection. Once the outgoing ssh connection is allowed, we also need to allow the response back for that outgoing ssh connection.

First, Allow outgoing SSH connection request, as shown below.

iptables -A OUTPUT -o eth0 -p tcp –dport 22 -m state –state NEW,ESTABLISHED -j ACCEPT
In the above example:

iptables -A OUTPUT: Append the new rule to the OUTPUT chain. For outgoing connection request, this always has to be OUTPUT.
-o eth0: This refers the output interface. For outgoing connections, this always has to be ‘-o’.
-p tcp: Indicates that this is for TCP protocol.
–dport 22: This refers to the destination port for the outgoing connection.
-m state: This indicates that “state” matching module is used.
–state NEW, ESTABLISHED: Options for the “state” matching module. In this example, only NEW and ESTABLISHED states are allowed. The 1st time when a SSH connection request is initiated from the server to the outside, NEW state is used. ESTABLISHED state is used for all further request from the server to the outside.
Next, Allow outgoing (ESTABLISHED only) SSH connection response (for the corresponding incoming SSH connection request).

iptables -A INPUT -i eth0 -p tcp –sport 22 -m state –state ESTABLISHED -j ACCEPT
In the above example:

iptables -A INPUT: Append the new rule to the INPUT chain. Since this is for the response rule (for the corresponding outgoing request) that comes from the outside to the server, this should be INPUT.
-i eth0: This refers the input interface. For incoming connections, this always has to be ‘-i’.
-p tcp: Indicates that this is for TCP protocol.
–sport 22: This refers to the source port for the incoming connection. Since the outgoing request (from the previous rule) went to the “destination” port, the incoming response will come from the “source” port.
-m state: This indicates that the “state” matching module is used.
–state ESTABLISHED: Since this is a response rule, we allow only ESTABLISHED connection (and not any NEW connection).
Putting it all together

Create rules.sh shell script which does the following:

Delete all existing rules
Set default chain policies
Allow inbound SSH
Allow inbound HTTP
Allow outbound SSH
First, create the rules.sh

$ vi rules.sh
# 1. Delete all existing rules
iptables -F

# 2. Set default chain policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

# 3. Allow incoming SSH
iptables -A INPUT -i eth0 -p tcp –dport 22 -m state –state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp –sport 22 -m state –state ESTABLISHED -j ACCEPT

# 4. Allow incoming HTTP
iptables -A INPUT -i eth0 -p tcp –dport 80 -m state –state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp –sport 80 -m state –state ESTABLISHED -j ACCEPT

# 5. Allow outgoing SSH
iptables -A OUTPUT -o eth0 -p tcp –dport 22 -m state –state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp –sport 22 -m state –state ESTABLISHED -j ACCEPT
Next, execute the rules.sh and view the rules.

# chmod u+x rules.sh

# ./rules.sh

# iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT tcp — anywhere anywhere tcp dpt:ssh state NEW,ESTABLISHED
ACCEPT tcp — anywhere anywhere tcp dpt:http state NEW,ESTABLISHED
ACCEPT tcp — anywhere anywhere tcp spt:ssh state ESTABLISHED

Chain FORWARD (policy DROP)
target prot opt source destination

Chain OUTPUT (policy DROP)
target prot opt source destination
ACCEPT tcp — anywhere anywhere tcp spt:ssh state ESTABLISHED
ACCEPT tcp — anywhere anywhere tcp spt:http state ESTABLISHED
ACCEPT tcp — anywhere anywhere tcp dpt:ssh state NEW,ESTABLISHED
Using this as a basis you should be able to write your own incoming and outgoing iptables firewall rules. There is lot more to cover in IPTables. Stay tuned!

Deixe um comentário