Firewalls a partir do IP Masquerade
Na edição anterior, apresentamos brevemente o recurso
de IP masquerade presente no kernel do Linux.
Fazendo um rápido resumo, foi visto que máquinas em uma rede local, usando endereços IP inválidos, podem participar de sessões com outros computadores na Internet, desde que estejam conectadas a um computador com sistema operacional Linux (que chamamos de gateway) devidamente configurado para masquerading e com acesso à Internet. Vale lembrar aqui que pacotes com endereços IP inválidos não podem trafegar pela Internet, sendo seu uso exclusivo de redes privadas. Portanto, nesse caso a comunicação com a Internet é sempre feita via gateway. Este se encarrega de fazer a reescrita (NAT, Network Address Translation) dos cabeçalhos dos pacotes, modificando endereços IP inválidos para o endereço IP válido do gateway e vice-versa, tornando todo esse processo transparente para as máquinas internas. Por outro lado, para máquinas remotas é como se todas as requisições viessem de clientes no gateway. Dessa forma, todas as máquinas internas ficam "escondidas" atrás da máquina Linux com IP masquerade.
Neste artigo, o objetivo é tentar esclarecer o que realmente são firewalls (ainda há muita confusão no uso desse termo entre os usuários), apresentar as alternativas de implementação e discutir como criar um firewall simples em um computador com o sistema operacional Linux configurado com suporte a IP masquerade. O que é um firewall. Um Internet firewall é um conjunto de componentes de hardware (roteadores capazes de fazer filtragem de pacotes, por exemplo) e software (proxy, como exemplo) que controlam todo fluxo de pacotes entre uma rede local e a Internet. Basicamente, esse controle é feito através de uma filtragem usando as informações existentes nesses pacotes (cabeçalhos e dados), decidindo o que é permitido entrar e sair da rede local. Um firewall pode também ser útil para isolar uma rede interna de tentativas externas de comunicação. Nesse caso, máquinas na Internet não conseguem estabelecer comunicação direta com as máquinas dentro da rede protegida pelo firewall, garantindo-se, dessa forma, que nemhum mal possa ser causado à rede interna.
Por diversos anos, muitos firewalls eram implementados usando apenas um roteador com capacidade de efetuar filtragem de pacotes, principalmente por razões de desempenho e por este ser um ponto obrigatório de passagem de todo tráfego de pacotes entre a rede local e a Internet. Essa filtragem era dirigida por um conjunto de regras (criadas durante a configuração do roteador pelo administrador) e baseava-se somente nas informações presentes nos cabeçalhos do pacote IP (endereços IP, números de portas dos serviços, etc). Com o aumento do desempenho das CPUs atuais, muitas plataformas, inclusive o Linux, passaram a implementar o processo de roteamento e filtragem de pacotes no kernel do sistema operacional.
Portanto, hoje podemos implementar facilmente firewalls, criando regras de filtragem numa máquina Linux. Com a série 2.2 do kernel do Linux, a ferramenta usada para este fim é o ipchains. Entretanto, apesar da simplicidade, filtros de pacotes não fazem filtragem no fluxo de dados das diferentes aplicações, trabalhando somente com os cabeçalhos dos pacotes, o que é muito pouco para garantir um grau de segurança desejável em certos casos. Então, problemas de segurança que existam nas diferentes aplicações (ftp, telnet, etc) não podem ser evitados com filtros de pacotes. Mas mesmo com essa desvantagem, filtragem de pacotes já é uma solução suficiente para muitas redes locais em que algum risco é tolerável.
Se os requisitos de segurança são maiores em uma rede local, o uso de proxies dedicados, em adição a filtros de pacotes, é sempre encorajado. Grosso modo, o proxy tem por objetivo eliminar a lacuna deixada por filtros de pacotes. Ele baseia seu processo de filtragem na parte de dados dos pacotes de uma determinada aplicação. Para isso, ele precisa entender bem o funcionamento dessa aplicação (o protocolo usado entre os participantes) e acompanhar todo o fluxo de dados dos pacotes trocados em cada sessão por isso dizemos que esses proxies são dedicados. Há também os chamados proxies genéricos, que não fazem muito mais que filtros de pacotes, pois não conhecem nenhuma aplicação em particular (Socks, como exemplo) e, portanto, são mais vulneráveis que um proxy dedicado.
O proxy, ao contrário do filtro de pacotes, é implementado no espaço de processos do sistema operacional (é um processo como qualquer outro) e isso explica a existência das várias alternativas de proxies para Linux. Entre eles, merecem destaque o Squid e o TIS-FWTK (vide Firewal-HowTo para exemplos de uma configuração simples desses proxies). Esse último é, na verdade, um kit para construção de firewalls. Ele apresenta diversos proxies dedicados: ftp, telnet, www, smtp, entre outros.
Com um proxy ftp, por exemplo, o administrador pode evitar que usuários situados remotamente façam uploads (comando PUT do ftp), pode permitir que eles façam download (comando GET do ftp) em seu servidor ftp, autenticar usuários e criar logs dos dados trocados na comunicação. Os leitores podem notar que isso é impossível de ser feito usando somente filtros de pacotes.
Mais recentemente, muitas redes locais, usando Linux em uma máquina 486 ou Pentium, têm implementado firewalls desabilitando serviços desnecessários e configurando o kernel com o recurso de IP masquerade. O masquerading é usado para proteger as máquinas internas e a eliminação dos serviços é necessária para evitar ataques à máquina gateway. Vale ressaltar que essas redes locais, em geral, não oferecem serviços internamente, ou seja, nenhum servidor interno pode responder a requisições originadas em máquinas externas. Caso isso seja um requisito necessário, pode-se fazer uso de "port forwarders", como o ipmasqadm (kernel 2.2), ou de proxies, se existir a exigência de diminuir riscos. Essa necessidade de oferecer serviços internamente não será satisfeita neste artigo e o leitor mais interessado é convidado a buscar maiores informações no IPMasquerade-howto.
Usando IP Masquerade
A partir do momento em que uma rede local é conectada à Internet (todas as máquinas recebem um endereço IP válido), torna-se possível o estabelecimento de um canal virtual de comunicação entre as máquinas que fazem parte dessa rede e milhões de outros computadores espalhados pelo mundo. Como conseqüência disso, essa rede pode também tornar-se alvo de ataques de pessoas localizadas nos mais remotos pontos da rede. O I masquerade pode ser usado para implementar um firewall simples, isolando as máquinas de uma rede local dos perigos externos, ou seja, esse recurso pode evitar que máquinas na Internet iniciem diretamente sessões com esses computadores da rede. Isso acontece porque as máquinas internas não utilizam endereços IP válidos e toda comunicação delas com a Internet deve ser feita via gateway. Pacotes partindo de máquinas na Internet, com endereço IP de destino inválido, são descartados em trânsito e, naturalmente, nenhuma comunicação pode ser estabelecida com computadores da rede local protegida. O gateway é, neste caso, a única m&aacue;quina na rede local realmente conectada à Internet e responsável pelo controle do fluxo de pacotes entre a rede interna e hosts externos. Somente as máquinas internas serão capazes de iniciar sessões com máquinas remotas, compartilhando o endereço IP do gateway. Dessa forma, podemos garantir que nenhuma máquina interna poderá ser atacada diretamente de hosts remotos. Os passos para habilitar e configurar o kernel do Linux para IP masquerade foram descritos no primeiro artigo sobre masquerading (edição Março 2000) e não serão repetidos nesta edição.
Segurança do gateway
O firewall propriamente dito é implementado no gateway. Porém, o recurso de masquerading não oferece nenhuma segurança adicional à própria máquina Linux. Esta máquina exige alguma forma de proteção, pois pode ser alvo de ataques de qualquer host remoto. Além disso, o gateway também faz parte da rede interna que está sendo protegida e o atacante pode usá-lo como trampolim para atacar as demais máquinas da rede local, ou efetuar ataques a outras redes conectadas à Internet.
Um dos pré-requisitos básicos desejados para uma máquina implementar firewall é que ela ofereça o mínimo possível de serviços. Isso é necessário porque para defender o gateway devemos eliminar as eventuais falhas de segurança existentes nesses serviços. Antes porém,
é interessante que algumas opções de segurança oferecidas pelo kernel do Linux sejam configuradas. Algumas dessas opções já receberam os seus valores adequados quando da compilação do kernel para
suporte à masquerading, mas mesmo assim vamos mostrá-las aqui:
Habilitar proteção contra IP spoofing: Evita que atacantes enviem pacotes, buscando confundir o gateway, para serem mascarados como se tivessem sido originados dentro da rede interna. Se o atacante tiver como manipular e criar as rotas usadas pelo gateway, pode implementar ataques bastante sofisticados. Por isso, é muito importante usar rotas estáticas na configuração do firewall.
#echo 1 > /proc/sys/net/ipv4/conf/*/rp_filter
Desabilitar pacotes com source routing ligado: Pacotes IP que contenham tal opção são por especificação roteados não como base nas tabelas de rota dos roteadores, mas conforme determinado a priori pelo computador de origem. Esse tipo de ataque atrelado ao IP spoofing permite que um atacante personifique completamente qualquer máquina.
#echo 0 > /proc/sys/net/ipv4/conf/*/accept_source_route
Desabilitar os efeitos de ICMP redirects: Pacotes ICMP redirects são perigosos, pois podem ser usados por atacantes com o objetivo de desvirtuar rotas dos pacotes. A limitação desde ataque é que esse tipo de mensagem só pode ser gerado em função de conexões existentes e deve ter sido originado por um roteador conectado na mesma sub-rede da máquina a ser atacada.
#echo 0 > /proc/sys/net/ipv4/conf/*/accept_redirects
Habilitar desfragmentação de pacotes no kernel: Isso é muito útil, pois diversos ataques de DoS (Denial of Service) usam o fato de que vários sistemas operacionais apresentam problemas com o algoritmo de remontagem de pacotes com seus fragmentos.
#echo 1 > /proc/sys/net/ipv4/conf/*/ip_always_defrag
Habilita o uso de SYN cookies: Um dos ataques de DoS mais famosos é o SYN flooding. Ele explora uma vulnerabilidade no processo de estabelecimento de conexões TCP. Esta opção permite que conexões legítimas sejam mantidas, mesmo quando a máquina estiver sob ataque, pois minimiza bastante o uso dos recursos da m&aacte;quina por parte das conexões TCP semi-abertas.
# echo 1 >/proc/sys/net/ipv4/conf/*/tcp_syncookies
Vale ressaltar aqui que algumas das opções de segurança citadas acima podem não ser úteis em todos os casos. Se nenhum serviço for oferecido no gateway, tcp_syncookies não seriam necessários, por exemplo. Isso porque o gateway não poderá sofrer ataques de SYN floods, já que não responderá a pedidos de conexão. Mas é uma boa prática configurá-las sempre que existir alguma preocupação com segurança. Em servidores Linux, estações de trabalho e em outras implementações de firewall, a grande maioria dessas variáveis seria de grande utilidade para prover um ambiente mais seguro. O passo final para termos um firewall relativamente seguro é eliminar todos os serviços desnecessários do gateway. Um resultado parecido poderia ser alcançado usando regras de filtragem com o ipchains, mas trataremos do assunto de filtragem de pacotes em um próximo artigo. O comando "netstat" mostra o status das portas TCP e UDP que estão sendo utilizadas no sistema.
#netstat -at (mostra todas as portas TCP abertas, aguardando pedido de conexão e o estado das conexões TCP)
#netstat -au (mostra todas as portas UDP abertas, aguardando requisi&c=
cedil;ões).
Colocando como "comentários" as linhas relativas aos serviços considerados desnecessários no arquivo de configuração /etc/inetd.conf, evitamos que esses serviços sejam inicializados durante o boot da máquina e fiquem escutando as suas
respectivas portas, aguardando requisições. Quanto menos
serviços na máquina, menor a chance da existência de falhas de segurança relacionadas a esses serviços e, conseqüentemente, mais seguro é o firewall.
Além deste arquivo, é necessário também tratar dos daemons inicializados em rc scripts. A localização deles varia levemente de distribuição para distribuição e o leitor pode facilmente encontrar informações com a documentação de sua distribuição, ou observando a seqüência de boot no arquivo /etc/inittab. Para terminar, devemos sempre recorrer aos TCP wrappers e similares, para limitar o acesso aos serviços considerados necessários.
Conclusão
Firewalls implementados com IP masquerade são extremamente simples e podem ser bastante interessantes em pequenas redes corporativas e residenciais, mas apresentam, assim como filtros de pacotes, algumas vulnerabilidades por não oferecerem nenhuma filtragem na parte de dados dos pacotes das diferentes aplicações. Um applet Java hostil, por exemplo, explorando um bug qualquer na máquina virtual Java pode provocar um buffer overflow e produzir grandes problemas para a rede local protegida. Além disso, IP masquerade por si só não permite que serviços, dentro da rede interna, sejam oferecidos a máquinas na Internet, o que pode ser inaceitável em alguns casos.