11.07.2013

Netfilter no CentOS - Conceitos básicos

A firewall tem como objectivo aplicar políticas de segurança num dispositivo, operando geralmente nas camadas 3,4 e 5 do modelo OSI. Para inspecção da camada 7 geralmente usa-se um proxy juntamente com a firewall. Existem appliances de segurança e sistemas open source ou comerciais que podem fornecer um conjunto integrado de serviços sendo estes sistemas geralmente colocados como fronteira entre uma rede privada e "confiável" e a Internet. Como exemplos (Pfsense, Cisco Asa) para além de fornecerem serviços de routing e de firewall podem atuar como proxies, gateways VPN site-to-site ou road warrior...

Muitos administradores optam por aplicar todas as políticas de segurança nestes dispositivos, procurando maximizar a segurança do perímetro e descurando os sistemas internos. É comum que os servidores que prestam apenas serviços à Rede Interna tenham eventuais mecanismos de segurança descurados. Obviamente, qualquer sistema que seja acedido directamente através da Internet deverá ter uma firewall activada e configurada com o máximo cuidado.

O Netfilter é a firewall do kernel do Linux. No CentOs (com GUI) poderá configurar a firewall com uma interface gráfica: Sistema -> Administração -> Firewall ou executando system-config-firewall na consola. Esta ferramenta é ideal para uma primeira configuração. Saliente-se que quando se aplicam as regras configuradas com esta ferramenta perdem-se todas as configurações que tenham sido previamente efectuadas com recurso à linha de comandos.

O system-config-firewall permite não só habilitar e desabilitar portas como configurar serviços avançados e definir regras complexas.No entanto, um conhecimento mais alargado do Netfilter e como definir regras com o iptables é necessário em instalações minimalistas (sem GUI ou ferramentas de gestão Web como o Webmin). A configuração "à unha" das regras permite um controlo mais granular da configuração, existindo no entanto o risco acrescido de criar configurações inseguras caso não se domine os princípios envolvidos. Saliente-se que este artigo é meramente introdutório e são apenas mostradas noções básicas do Netfilter. Trata-se de uma aplicação complexa, existindo livros e imenso material on-line que apenas abordam a sua configuração. Os exemplos apresentados servem para entender como o Netfiler opera servindo de base para configurações mais avançadas.

Para verificar se o Netfilter está activo (nota:existe por vezes alguma confusão entre o Netfilter e o iptables. O Netfilter é um módulo do Kernel que fornece ao Linux as funções de firewall. O iptables é o programa que permite ao utilizador definir as regras do Netfilter).

[root@webcentos ~]# chkconfig | grep iptables
iptables 0:off 1:off 2:on 3:on 4:on 5:on 6:off

Para desactivar a firewall (reiniciando o sistema a firewall ficará novamente activa. Para desabilitar permanentemente o serviço executar chkconfig iptables off:

[root@webcentos ~]# service iptables stop

Para iniciar a firewall

[root@webcentos ~]# service iptables start

O comando [root@webcentos ~]# iptables -L -v permite verificar as regras da firewall.

Caso a firewall esteja activa, terá um output similar ao seguinte:

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
186 13669 ACCEPT all -- any any anywhere anywhere state RELATED,ESTABLISHED
0 0 ACCEPT icmp -- any any anywhere anywhere
0 0 ACCEPT all -- lo any anywhere anywhere
865 67470 ACCEPT udp -- any any anywhere anywhere state NEW udp dpt:netbios-ns
9 2151 ACCEPT udp -- any any anywhere anywhere state NEW udp dpt:netbios-dgm
0 0 ACCEPT tcp -- any any anywhere anywhere state NEW tcp dpt:netbios-ssn
0 0 ACCEPT tcp -- any any anywhere anywhere state NEW tcp dpt:microsoft-ds
1 92 ACCEPT tcp -- any any anywhere anywhere state NEW tcp dpt:ssh
0 0 ACCEPT tcp -- any any anywhere anywhere state NEW tcp dpt:http
0 0 ACCEPT tcp -- any any anywhere anywhere state NEW tcp dpt:https
48 8274 REJECT all -- any any anywhere anywhere reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 REJECT all -- any any anywhere anywhere reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT 255 packets, 21145 bytes)
pkts bytes target prot opt in out source destination

Caso a firewall esteja desactivada (service iptables stop)surgirá um output obviamente diferente:

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source

Conforme referido para configurar a firewall usa-se o comando iptables. As tables são componentes do Netfilter para as várias funcionalidades e tipo de tráfego, sendo que as tables para filtagem de tráfego e de NAT são normalmente as mais usadas. Uma table é constituída por chains e cada chain contem regras que são processadas sequencialmente. Cada pacote é alvo de processamento por parte das regras definidas.

Existem as seguintes chains na table filter:

  1. INPUT:Os pacotes de entrada (enviados para o sistema) são processados por esta chain.
  2. OUTPUT:Processa os pacotes de saída (originados no sistema).
  3. FORWARD:Processa pacotes em sistemas configurados para fazer routing.

Podem ser especificados vários elementos para compor as regras a aplicar.

  • Módulos: elemento opcional que oferece funcionalidades acrescidas ao Netfilter através de um módulo adicional acrescentado ao kernel. O mais comum é o módulo stateque verifica o "estado" do pacote.
  • Interface: num sistema com várias interfaces de rede é comum aplicarem-se regras específicas a cada uma dessas interfaces. Num servidor com apenas uma interface este elemento é desnecessário.
  • Endereços IP: Numa regra pode-se permitir ou negar acesso em função dos endereços de rede permitindo controlar o fluxo de tráfego assim como configurar regras de encaminhamento de determinadas portas - port forwarding
  • Protocolos: Muitas regras permitem ou negam o acesso a portas específicas (UDP ou TCP).
  • Targert: componente obrigatório numa regra, específica a acção a tomar sobre um pacote. Os mais utilizados são
    • ACCEPT
    • DROP
    • REJECT
    • LOG

Para além destes elementos é necessário planear antecipadamente o propósito das regras a configurar, existindo genericamente duas opções: pode-se criar uma política ou adicionar uma regra a uma chain. A política define o comportamento por defeito e se um pacote não for alvo da acção de nenhuma regra, essa política será aplicada. A melhor e altamente recomendável prática é criar uma política por defeito que negue todo o acesso. Depois de definida uma política por defeito começam-se a definir as regras nas chains. Conforme mencionado previamente, relembra-se que os pacotes são processados sequencialmente e como tal a ordem em que as mesmas estão definidas é importante. Por exemplo, a opção -Aadiciona uma regra no fim da chain enquanto a opção -I permite indicar o local onde se pretende que a inserção ocorra. A opção -D permite eliminar uma regra. Como sempre, é aconselhável a leitura do man do iptables man iptables para tomar conhecimento das opções disponíveis.

Recorrendo a um exemplo prático, veremos como a teoria se aplica. Pretende-se configurar uma firewall simples que permita o tráfego in-out FTP, SSH, HTTP e HTTPS e que negue o restante. O sistema pode ser um servidor que corra o Apache e um servidor de FTP. O SSH possibilita a gestão remota. Ao planear as regras a implementar deve-se atender ao seguinte:

  • Se todo o tráfego deve ser negado, o tráfego na interface de loopback também o será. Contudo, para que o tráfego IP interno funcione correctamente é necessário permiti-lo.
  • Pretende-se que o tráfego gerado pelos serviços seja permitido para utilizadores externos. O acesso ao exterior a partir do sistema é necessário?
  • Nota: Não se refere o serviço de DNS mas sendo essencial é permitido na maior parte das configurações.

Conforme mencionado, podem ser usadas várias abordagens para configurar a firewall. Relembre-se no entanto que no caso do system-config-firewall todo o tráfego originado pelo sistema é permitido. Tal não é sempre a abordagem mais correta, especialmente em servidores que corram aplicações críticas. Por exemplo, um hacker pode instalar um Cavalo de Troia numa máquina que inicie conexões com o exterior. Como tal, a chain OUTPUT deve merecer o mesmo cuidado que a chain INPUT.

  • Verificar as regras actuais com o comando iptables -L -v.
  • [root@webcentos ~]#iptables -P INPUT ACCEPT
  • [root@webcentos ~]#iptables -P OUTPUT ACCEPT
  • [root@webcentos ~]#iptables -P FORWARD ACCEPT
  • [root@webcentos ~]#iptables -F

Os comandos anteriores criaram as tabelas INPUT, OUTPUT e FORWARD e eliminaram todas as regras eventualmente existentes. Verificamos a actual configuração com o iptables -L -v

[root@webcentos ~]# iptables -L -v

Chain INPUT (policy ACCEPT 147 packets, 14279 bytes)
pkts bytes target prot opt in out source destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain OUTPUT (policy ACCEPT 98 packets, 9829 bytes)
pkts bytes target prot opt in out source destination

Para guardar permanentemente estas alterações (notar que as mesmas são gravadas no ficheiro /etc/sysconfig/iptables. Pode-se editar esse ficheiro, alterar a configuração e reiniciar o serviço de iptables service iptables restart para que as alterações entrem em vigor):

[root@webcentos ~]# service iptables save iptables:
iptables: A gravar regras da firewall em /etc/sysconfig/iptables: [ OK ]

Neste momento o sistema está sem regras configuradas. Noutra máquina podemos verificar os serviços disponibilizados com o comando nmap (nota:neste exemplo utilizam-se máquinas virtuais e endereços privados).
[root@exp01centos ~]# nmap 172.16.1.200

Starting Nmap 5.51 ( http://nmap.org ) at 2013-11-06 15:20 WET
Nmap scan report for 172.16.1.200
Host is up (0.00081s latency).
Not shown: 993 closed ports
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
80/tcp open http
111/tcp open rpcbind
139/tcp open netbios-ssn
445/tcp open microsoft-ds
3306/tcp open mysql
MAC Address: 08:00:27:6C:C1:FF (Cadmus Computer Systems)

Nmap done: 1 IP address (1 host up) scanned in 13.21 seconds

Vamos começar por mudar as políticas definidas para as 3 chains com os comandos

  • Verificar as regras atuais com o comando iptables -L -v.
  • [root@webcentos ~]#iptables -P INPUT DROP
  • [root@webcentos ~]#iptables -P OUTPUT DROP
  • [root@webcentos ~]#iptables -P FORWARD DROP

Naturalmente todo o tráfego para as 3 chains é agora descartado. Não podendo ser utilizado numa política, existe outra opção que rejeita o tráfego (REJECT) e que pode ser aplicada na definição das regras. Contudo, o REJECT notifica um eventual emissor que o pacote não pode ser entregue enquanto o DROP actua furtivamente, sendo por isso preferível. Neste momento a configuração existente não permite sequer o comando ping interno à própria máquina (endereço de loopback) . Mudando esse comportamento, adicionamos as primeiras regras:

[root@webcentos ~]#iptables -A INPUT -i lo -j ACCEPT
[root@webcentos ~]#iptables -A OUTPUT -o lo -j ACCEPT

Analisando os comandos, o -A adiciona uma linha às chains INPUT e OUTPUT. O -ié utilizado para especificar a interface incoming na chain INPUT e o -o para especificar a interface outgoing da chain OUTPUT. O -j específica a acção a tomar, neste caso, ACCEPT. Efectuando agora um ping ao localhost podemos aferir que já podemos testar o stack TCP/IP ...

Vejamos agora como permitir o acesso ao serviço SSH. Começa-se por adicionar uma regra que especifica a porta 22 (verificar portas e serviços associados com cat /etc/services:

[root@webcentos ~]#iptables -A INPUT -p tcp --dport 22 -j ACCEPT

Poderia-se pensar que a partir de agora o acesso SSH já é permitido, contudo não é. O sistema permite pedidos destinados à porta 22 mas não está ainda configurado para permitir respostas, ou seja a comunicação é apenas unidireccional. Para permitir que seja bidireccional e que uma sessão SSH possa ser estabelecida é necessário adicionar o comando à chain OUTPUT:

[root@webcentos ~]#iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Saliente-se que para além de permitir de facto a ligação SSH este comando permite que sejam efectuadas todas as sessões TCP que tenham tido permissão para serem inicializadas. Quando a seguir adicionarmos a regra que permite o acesso HTTP e HTTPS não necessitamos de repetir este comando.

Configuramos as regra que permitem as ligações ao porto 80 para o serviço HTTP e 443 para HTTPS:

[root@webcentos ~]#iptables -A INPUT -p tcp --dport 80 -j ACCEPT
[root@webcentos ~]#iptables -A INPUT -p tcp --dport 443 -j ACCEPT

Verificamos as regras configuradas até ao momento:

[root@webcentos ~]# iptables -L -v
Chain INPUT (policy DROP 83 packets, 6810 bytes)
pkts bytes target prot opt in out source destination
4 336 ACCEPT all -- lo any anywhere anywhere
97 7815 ACCEPT tcp -- any any anywhere anywhere tcp dpt:ssh
0 0 ACCEPT tcp -- any any anywhere anywhere tcp dpt:http

Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain OUTPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
4 336 ACCEPT all -- any lo anywhere anywhere
82 23113 ACCEPT all -- any any anywhere anywhere state RELATED,ESTABLISHED

Analisando o output verificamos que todo o tráfego da interface de loopback é permitido (lo) na chain INPUT e que todo o tráfego com destino SSH ou HTTP é também permitido. Existe um campo onde se pode verificar quantos pacotes foram processados pelas respectivas regras.

Para o FTP necessitamos de relembrar que o protocolo necessita de 2 portos para poder operar. O porto 20 para transferência de dados e o porto 21 para execução dos comandos. Podemos configurar duas regras, uma para cada porto, ou configurar uma regra que permita definir mais do que um porto usando para tal a opção multiport:

[root@webcentos ~]#iptables -A INPUT -m multiport -p tcp --port 21,20 -j ACCEPT

Neste momento a firewall está a gerir o tráfego conforme pedido. Guardamos a configuração definitivamente com o comando:

[root@webcentos ~]service iptables save

Imaginemos agora que se pretende que uma determinado endereço IP ou subnet obtenha acesso a qualquer serviço que esteja disponível. Nesse cenário a ordem das regras é fundamental visto que são processadas sequencialmente e se pretende que a regra criada para esse endereço IP seja cumprida. Para determinar o local preciso onde se pretende colocar a regra usa-se a opção -I seguida do nome da chain e do número onde se pretende a inserção da regra. Para determinar qual o número a usar necessitamos de verificar a ordem das regras. Para tal basta verificar a configuração com a opção --line-numbers:

[root@webcentos ~]iptables -L -v --line-numbers

O comando seguinte permite colocar a regra noutro local que não no fim da chain:

[root@webcentos ~]iptables -I INPUT 2 -s 192.168.100.1/24 -j ACCEPT

Guardar as alterações:

[root@webcentos ~]service iptables save

Relembre-se que a configuração do Netfilter conforme descrita não é a única possível. Dando alguns exemplos, pode-se editar os ficheiros de configuração, criar scripts com várias configurações e executá-los quando se pretende alterar o funcionamento da firewall, instalar uma ferramenta de administração via WEB como o webmin.....

Para IPv6 é necessário que o pacote iptables-ipv6 esteja instalado. O comando homólogo ao iptables para IPv6 é o iptables-ipv6. As regras são guardadas no ficheiro /etc/sysconfig/ip6tables. Futuramente será escrito um texto sobre firewall e IPv6 no CentOS.