Gentoo Logo

Manual de segurança do Gentoo

Conteúdo:

A. Segurança de sistema

1. Problemas de pré-instalação

1.a. Segurança física

Não importa quantas medidas de segurança você implementar, todas podem ser facilmente contornadas por um indivíduo malicioso com acesso físico a seu computador. Apesar disso, existem algumas medidas que podem ser tomadas para fornecer um maior grau de segurança contra um indivíduo malicioso com acesso físico a sua máquina. Colocar o hardware em um um armário fechado previne que um indivíduo simplesmente desconecte ela e leve-a embora. Travar o gabinete do computador também é uma boa idéia, para ter certeza de que um indivíduo malicioso não possa simplesmente levar seu disco rígido. Para prevenir que um indivíduo malicioso carregue a partir de outro disco, contornando de maneira sutil suas restrições de permissões e login, experimente configurar o disco rígido como primeiro dispositivo de inicialização em seu BIOS, e configurar uma senha de BIOS. Também é importante colocar senhas de inicialização para o LILO ou GRUB, para prevenir que um usuário malicioso entre em modo de único usuário e obtenha acesso completo a seu sistema. Isto é coberto em mais detalhe no Capítulo 3, em Configurando uma senha de GRUB e Configurando uma senha de LILO.

1.b. Planejamento de daemons/serviços

Comece documentando que serviços a máquina deve rodar. Isto irá ajudar você a compor um melhor esquema de particionamento para seu sistema, e permitir que você planeje melhor suas medidas de segurança. Claro, isto é desnecessário se sua máquina serve um único propósito, como um desktop, ou firewall dedicada. Nestes casos, você não deve rodar nenhum serviço, fora talvez sshd.

A lista pode ser usada para ajudar na administração de sistemas. Mantendo uma lista atualizada de informações, você achará mais fácil manter tudo atualizado se uma vulnerabilidade remota for descoberta em um de seus daemons.

1.c. Esquemas de particionamento

Regras de particionamento:

  • Qualquer árvore de diretórios em que um usuário deve poder escrever (como /home, /tmp) deve estar em uma partição separada e usar quotas de disco. Isto reduz o risco de um usuário encher seu sistema de arquivos. O Portage usa /var/tmp para compilar os arquivos, então a partição deve ser grande.
  • Qualquer árvore de diretórios onde você planeja instalar software alheio a distribuição deve estar em uma partição separada. De acordo com o Padrão da hierarquia de arquivos, este lugar é /opt ou /usr/local. Se estas forem partições separadas, eles não serão apagados se você precisar re-instalar o sistema.
  • Para segurança adicional, dados estáticos podem ser colocados em uma partição separada que é montada como somente leitura. Para os paranóides, experimente usar mídia de somente leitura como CD-ROM.

1.d. O usuário administrador (root)

O usuário 'root' é usuário mais vital no sistema e não deve ser usado para qualquer coisa fora quando absolutamente necessário. Se um usuário malicioso obtiver acesso de root, o único jeito de confiar em seu sistema de novo é re-instalar.

Regradas douradas sobre o 'root'

  • Sempre crie um usuário para uso rotineiro e se o usuário precisar de acesso de root, adicione o usuário ao grupo 'wheel'. Isto possibilita que um usuário normal faça su para root.
  • Nunca rode o X ou qualquer outra aplicação de usuário como root. root só deve ser usado quando absolutamente necessário; se uma vulnerabilidade existir em uma aplicação rodando como um usuário, o indivíduo malicioso pode obter acesso de nível de usuário. Mas se a aplicação estiver rodando como root, o indivíduo obtém acesso de root.
  • Sempre use caminhos completos quando logado como root (ou sempre use su -, que substitui as variáveis de ambiente do usuário com as de root, tendo certeza que o PATH do root só inclui diretórios protegidos como /bin e /sbin). É possível enganar o root para rodar uma aplicação diferente da que você quis rodar. Se o PATH do root for protegido ou o root só usar caminhos completos, nós podemos ter certeza de que isso não acontecerá.
  • Se um usuário só precisa rodar alguns comandos como root, ao invés de dá-lo tudo que um root normalmente pode fazer, considere usar sudo ao invés disso. Só tenha cuidado para quem você dá acesso, também!
  • Nunca deixe o terminal quando você estiver logado como root.

O Gentoo tem algumas proteções padrões contra usuários normais tentando fazer su para root. O ajuste padrão do PAM necessita que um usuário seja membro do grupo "wheel" para poder usar su.

1.e. Políticas de segurança

Existem várias razões para desenhar uma política de segurança para seu sistema(s) e a rede.

  • Uma boa política de segurança permite desenhar a segurança como um "sistema", ao invés de uma simples mistura de funções diferentes. Por exemplo, sem uma política um administrador pode decidir desligar o telnet, porque ele transmite senhas sem criptografia, mas deixar acesso FTP, que tem a mesma fraqueza. Uma boa política de rede ajuda a identificar que medidas de segurança valem a pena, e as que não valem.
  • Para diagnosticar problemas, conduzir auditorias, ou procurar intrusos, pode ser necessário interceptar tráfego de rede, inspecionar o login e histórico de comandos dos usuários, e olhar em seus diretórios de home. Sem dizer isso por escrito, e tornando os usuários cientes, tais ações podem ser ilegais e colocar você em problemas legais.
  • Contas de usuários seqüestradas são uma das ameaças mais comuns à segurança de sistemas. Sem explicar aos usuários porque a segurança é importante, e como praticar boa segurança (como não escrever senhas em um post-it grudado em suas mesas), é improvável que você tenha qualquer chance de contas de usuário seguras.
  • Uma rede bem documentada e arranjo de sistema ajudarão você, bem como examinadores forenses criminais, se necessário, em rastrear uma intrusão e identificar fraquezas após o fato. Um banner de política de segurança "enviado sob demanda" dizendo que seu sistema é uma rede privada e acesso sem autorização é proibido, também ajudará na capacidade de processar um intruso, uma vez que seja pego.

A necessidade de uma boa política de rede, esperamos, está mais que claro.

A política em si é um documento, ou vários documentos, que desenham a rede e funções do sistema (como que serviços são fornecidos), uso aceitável e uso proibido, "melhores práticas" de segurança, e assim em diante. Todos usuários devem estar cientes de sua política de segurança, bem como mudanças que você fizer para mantê-la atualizada. É importante que você tome o tempo para ajudar os usuários entenderem sua política e porque a política precisa ser assinada ou o que acontecerá se agirem diretamente contra a política (a política deve dizer isso também). Isto deve ser repetido pelo menos uma vez por ano, já que a política pode mudar (mas também como um lembrete ao usuário da política em si).

Nota: Crie políticas que são fáceis de ler e seja bem preciso em cada assunto.

Uma política de segurança deve no mínimo conter os seguintes assuntos:

  • Uso aceitável
    • Proteções de tela
    • Cuidados com senhas
    • Baixando e instalando software
    • Informação dizendo se os usuários estão sendo monitorados
    • Uso de software de anti-vírus
  • Cuidados com informações sigilosas (qualquer forma escrita, papel ou digital)
    • Mesa limpa e informações confidenciais em local trancado
    • Desligando o PC antes de sair
    • Uso de criptografia
    • Cuidados com chaves para colegas de trabalho confiáveis
    • Cuidados com material confidencial quando for viajar
  • Cuidados com equipamentos de computador quando viajando
    • Cuidados com laptops durante viagens e estadias em hotéis

Diferentes usuários podem precisar de diferentes níveis ou tipos de acesso, e assim sua política pode variar para acomodar todos.

A política de segurança pode tornar-se enorme, e informações vitais podem ser facilmente esquecidas. A política do departamento de TI pode conter informações que são confidenciais para o usuário normal, então é inteligente dividi-la em políticas menores; como política de uso aceitável, política de senhas, política de e-mail e política de acesso remoto.

Você pode encontrar exemplos de políticas em O projeto de políticas de segurança do SANS. Se você tem uma rede pequena e acha que essas políticas são um pouco demais você deve olhar o Manual de segurança de site.

2. Apertando a segurança

2.a. Opções de USE

O arquivo make.conf contém opções de USE definidas por usuário e o /etc/make.profile/make.defaults contém as opções de USE padrões para o Gentoo Linux. Para o propósito deste guia, as opções importantes são pam (Pluggable Authentication Modules), tcpd (TCP wrappers), e ssl (Secure Socket Layer). Todos esses são opções de USE padrão.

2.b. Protegendo o GRUB com senha

O GRUB suporte dois jeitos diferentes de adicionar proteção de senhas a seu gerenciador de inicialização. O primeiro usa texto puro, enquanto o seguinte usa criptografia de md5+salt.

Listagem de código 2.1: /boot/grub/grub.conf

timeout 5
password mudeme

Isto irá adicionar a senha mudeme. Se nenhuma senha for entrada durante a inicialização, o GRUB simplesmente irá usar a configuração de inicialização padrão.

Para adicionar uma senha md5, você deve converter sua senha em formato criptográfico (crypt), que é o mesmo formato usado no /etc/shadow. Para mais informações veja man crypt. A senha criptografada mudeme, por exemplo, poderia parecer-se com isso: $1$T7/dgdIJ$dJM.n2wZ8RG.oEiIOwJUs.

Você pode criptografar sua senha diretamente no shell do GRUB:

Listagem de código 2.2: criptografia md5 no shell do grub

#/sbin/grub

GRUB version 0.92 (640K lower / 3072K upper memory)

   [ Minimal BASH-like line editing is supported. For the first word, TAB lists
     possible command completions. Anywhere else TAB lists the possible
     completions of a device/filename. ]

grub> md5crypt

Password: ********
(Digitamos mudeme no prompt) 
Encrypted: $1$T7/dgdIJ$dJM.n2wZ8RG.oEiIOwJUs.

grub> quit

Agora, corte e cole sua senha em /boot/grub/grub.conf.

Listagem de código 2.3: /boot/grub/grub.conf

timeout 5 
password --md5 $1$T7/dgdIJ$dJM.n2wZ8RG.oEiIOwJUs.

A espera de 5 segundos torna-se útil se o sistema for remoto e capaz de reiniciar sem qualquer interação com teclado. Aprenda mais sobre as senhas do GRUB executando info grub.

2.c. Protegendo o LILO com senha

O LILO também suporte dois jeitos de lidar com senhas: global e por imagem, ambos em texto normal.

A senha global é colocada no começo do arquivo de configuração, e aplica-se a todas imagens de boot:

Listagem de código 3.1: /etc/lilo.conf

password=mudeme 
restricted 
delay=3

A senha por imagem é configurada abaixo:

Listagem de código 3.2: /etc/lilo.conf

image=/boot/bzImage 
      read-only 
      password=mudeme 
      restricted

Se a opção restricted não for digitada, ele irá pedir a senha toda vez.

Para guardar as novas informações do lilo.conf, você deve rodar /sbin/lilo.

2.d. Restringindo o uso do console

O arquivo /etc/securetty permite que você especifique em que dispositivos tty (terminais) o administrador (root) pode fazer log-in.

Nós sugerimos que você comente todas linhas fora vc/1. Isto irá certificar que o root somente pode fazer log-in uma vez e somente em um terminal.

Nota: Usuários no grupo "wheel" podem ainda fazer su - para virar root em outros TTYs.

Listagem de código 4.1: /etc/securetty

vc/1

3. Registros

3.a. Introdução

Mais registros devem ser adicionados para pegar avisos ou erros que podem indicar um ataque em progresso ou uma invasão com sucesso. Indivíduos maliciosos freqüentemente escaneiam ou fazem sondas antes de atacar.

Também é vital que seus arquivos de registro sejam de fácil legibilidade e manuseio. O Gentoo Linux permite que você escolha 3 loggers diferentes durante a instalação.

3.b. Registros: syslogd

O syslogd é o logger mais comum para Linux e Unix em geral. Ele não vem com rotação de registros. Esta função é feita rodando /usr/sbin/logrotate em um serviço de cron (o logrotate é configurado em /etc/logrotate.conf). A freqüência com que a rotação de arquivos deve ser feita depende da carga do sistema.

Abaixo está o syslog.conf padrão com algumas funções adicionais. Nós descomentamos as linhas cron e tty e adicionamos um servidor de registros locais. Para melhorar a segurança, você pode adicionar registros em dois locais.

Listagem de código 2.1: /etc/syslog.conf

#  /etc/syslog.conf      Arquivo de configuração para o syslogd.
#
#                       Para mais informações leia as manpages syslog.conf(5).
#                       Isto vem do Debian, estamos usando por enquanto
#                       Daniel Robbins, 5/15/99

#
# Primeiro alguns arquivos de log padrão. Arquivo por instalação.
#

auth,authpriv.*                 /var/log/auth.log
*.*;auth,authpriv.none          -/var/log/syslog
cron.*                         /var/log/cron.log
daemon.*                        -/var/log/daemon.log
kern.*                          -/var/log/kern.log
lpr.*                           -/var/log/lpr.log
mail.*                          /var/log/mail.log
user.*                          -/var/log/user.log
uucp.*                          -/var/log/uucp.log
local6.debug                    /var/log/imapd.log

#
# Registros para o sistema de correios. Dividido para
# facilitar a escrita de scripts para interpretar os arquivos
#
mail.info                       -/var/log/mail.info
mail.warn                       -/var/log/mail.warn
mail.err                        /var/log/mail.err

# Registros para sistemas de news INN
#
news.crit                       /var/log/news/news.crit
news.err                        /var/log/news/news.err
news.notice                     -/var/log/news/news.notice

#
# Alguns arquivos de registro `pega-todos'.
#
*.=debug;\
        auth,authpriv.none;\
        news.none;mail.none     -/var/log/debug
*.=info;*.=notice;*.=warn;\
        auth,authpriv.none;\
        cron,daemon.none;\
        mail,news.none          -/var/log/messages

#
# Emergências e alertas são enviados para todos logados.
#
*.emerg                         *
*.=alert                        *

#
# Eu gosto de ter mensagens mostradas no console, mas em um console
# virtual normalmente deixo ocioso.
#
daemon,mail.*;\
       news.=crit;news.=err;news.=notice;\
       *.=debug;*.=info;\
       *.=notice;*.=warn       /dev/tty8

#Configurar um servidor de registros remoto
*.*                        @logserver

# O pipe nomeado /dev/xconsole é para o utilitário `xconsole'. Para usá-lo,
# você deve invocar `xconsole' com a opção `-file':
# 
#    $ xconsole -file /dev/xconsole [...]
#
# NOTE: ajuste a linha abaixo, ou você ficará louco se você tiver um
#      site grande..
#
#daemon.*,mail.*;\
#       news.crit;news.err;news.notice;\
#       *.=debug;*.=info;\
#       *.=notice;*.=warn       |/dev/xconsole

local2.*                --/var/log/ppp.log

Indivíduos maliciosos quase certamente irão tentar apagar seus traços, tanto editando como apagando arquivos de registros. Você pode dificultar a vida deles registrando em um ou mais servidores de registro remotos em outras máquinas. Obtenha mais informações sobre o syslogd executando man syslog.

3.c. Metalog

O metalog de Frank Dennis não é capaz de registrar em um servidor remoto, mas ele tem vantagens em relação a performance e flexibilidade de registros. Ele pode fazer registros por nome de programa, urgência, instalação (como o syslogd), e vem com analisador de expressões regulares (regex), que você pode usar para iniciar scripts externos quando certos padrões são encontrados. Ele também é muito bom para tomar ações quando necessárias.

A configuração padrão é geralmente suficiente. Se você quiser ser notificado por e-mail quando um erro com senhas ocorrer, use um dos seguintes scripts.

Para postfix:

Listagem de código 3.1: /usr/local/sbin/mail_pwd_failures.sh para postfix

#! /bin/sh
echo "$3" | mail -s "Warning (program : $2)" root

Para netqmail:

Listagem de código 3.2: /usr/local/sbin/mail_pwd_failures.sh para netqmail

#!/bin/sh
echo "To: root
Subject:Failure (Warning: $2) 
$3
" | /var/qmail/bin/qmail-inject -f root

Lembre-se de tornar o script executável rodando /bin/chmod +x /usr/local/sbin/mail_pwd_failures.sh

A seguir, descomente a linha de comando debaixo de "Erros de senha" no /etc/metalog/metalog.conf assim:

Listagem de código 3.3: /etc/metalog/metalog.conf

command  = "/usr/local/sbin/mail_pwd_failures.sh"

3.d. Syslog-ng

O syslog-ng fornece algumas das mesmas funções do syslog e metalog, com uma pequena diferença. Ele pode filtrar mensagens com base no nível e conteúdo (como o metalog), fornecer registro remoto como o syslog, lidar com registros do syslodg (mesmo correntes do Solaris), escrever em um TTY, executar programas, e pode agir como um servidor de registros. Basicamente, é o melhor dos dois loggers combinados com configuração avançada.

Abaixo está o arquivo de configuração clássica levemente modificado.

Listagem de código 4.1: /etc/syslog-ng/syslog-ng.conf

options { chain_hostnames(off); sync(0); };

#fonte de onde ler o registro
source src { unix-stream("/dev/log"); internal(); };
source kernsrc { file("/proc/kmsg"); };

#definir destinos
destination authlog { file("/var/log/auth.log"); };
destination syslog { file("/var/log/syslog"); };
destination cron { file("/var/log/cron.log"); };
destination daemon { file("/var/log/daemon.log"); };
destination kern { file("/var/log/kern.log"); };
destination lpr { file("/var/log/lpr.log"); };
destination user { file("/var/log/user.log"); };
destination mail { file("/var/log/mail.log"); };

destination mailinfo { file("/var/log/mail.info"); };
destination mailwarn { file("/var/log/mail.warn"); };
destination mailerr { file("/var/log/mail.err"); };

destination newscrit { file("/var/log/news/news.crit"); };
destination newserr { file("/var/log/news/news.err"); };
destination newsnotice { file("/var/log/news/news.notice"); };

destination debug { file("/var/log/debug"); };
destination messages { file("/var/log/messages"); };
destination console { usertty("root"); };
destination console_all { file("/dev/tty12"); };
destination xconsole { pipe("/dev/xconsole"); };

#criar filtros
filter f_authpriv { facility(auth, authpriv); };
filter f_syslog { not facility(authpriv, mail); };
filter f_cron { facility(cron); };
filter f_daemon { facility(daemon); };
filter f_kern { facility(kern); };
filter f_lpr { facility(lpr); };
filter f_mail { facility(mail); };
filter f_user { facility(user); };
filter f_debug { not facility(auth, authpriv, news, mail); };
filter f_messages { level(info..warn) 
	 and not facility(auth, authpriv, mail, news); };
filter f_emergency { level(emerg); };

filter f_info { level(info); };
filter f_notice { level(notice); };
filter f_warn { level(warn); };
filter f_crit { level(crit); };
filter f_err { level(err); };
filter f_failed { match("failed"); };
filter f_denied { match("denied"); };

#conectar filtro e destino
log { source(src); filter(f_authpriv); destination(authlog); };
log { source(src); filter(f_syslog); destination(syslog); };
log { source(src); filter(f_cron); destination(cron); };
log { source(src); filter(f_daemon); destination(daemon); };
log { source(kernsrc); filter(f_kern); destination(kern); };
log { source(src); filter(f_lpr); destination(lpr); };
log { source(src); filter(f_mail); destination(mail); };
log { source(src); filter(f_user); destination(user); };
log { source(src); filter(f_mail); filter(f_info); destination(mailinfo); };
log { source(src); filter(f_mail); filter(f_warn); destination(mailwarn); };
log { source(src); filter(f_mail); filter(f_err); destination(mailerr); };

log { source(src); filter(f_debug); destination(debug); };
log { source(src); filter(f_messages); destination(messages); };
log { source(src); filter(f_emergency); destination(console); };

#registro padrão
log { source(src); destination(console_all); };

O syslog-ng é muito fácil de configurar, mas também é muito fácil de esquecer de algo no arquivo de configuração, que é enorme. O autor ainda promete algumas funções adicionais como criptografia, autenticação e controle de MAC (Mandatory Access Control). Com essas opções, será perfeito para registros de rede, já que o indivíduo malicioso não poderá espionar o registro.

E o syslog-ng ainda tem outra vantagem: não tem que ser rodado como administrador (root)!

3.e. Análise de registros com o Logcheck

Lógico, cuidar de registros sozinhos é só metade da batalha. Uma aplicação como o Logcheck pode tornar a análise de registros mais fácil. O Logcheck é um script, acompanho de um binário chamado logtail, que roda de seu daemon do cron e verifica atividades suspeitas em seus arquivos contra um conjunto de regras. Ele então manda a saída como correio para a caixa de entrada do root.

Logcheck e logtail são parte do pacote app-admin/logsentry.

O Logcheck usa quatro arquivos para filtrar entradas de registro importantes das não importantes. Esses arquivos são logcheck.hacking, que contém mensagens conhecidas de ataques de invasão, logcheck.violations, que contém padrões indicando violações de segurança, logcheck.violations.ignore, que contém palavras-chave provavelmente relacionadas com o arquivo de violações, permitindo que entradas normais sejam ignoradas, e logcheck.ignore, que mantém aquelas entradas a serem ignoradas.

Aviso: Não deixe o logcheck.violations.ignore em branco. O Logcheck usa grep para interpretar registros, algumas versões dele tomarão um arquivo vazio como um wildcard. Todas violações serão, portanto, ignoradas.

4. Montando partições

4.a. Montando partições

Na hora de montar uma partição ext2, ext3, ou reiserfs, você tem várias opções que pode aplicar ao arquivo /etc/fstab. As opções são:

  • nosuid - Irá ignorar o bit de SUID e tratá-lo como um arquivo normal
  • noexec - Irá prevenir a execução de arquivos da partição
  • nodev - Ignora dispositivos

Infelizmente, esses ajustes podem ser facilmente contornados ao executar um caminho não direto. No entanto, configurando /tmp para noexec irá parar a maioria dos exploits desenhados para serem executados diretamente de /tmp.

Listagem de código 1.1: /etc/fstab

/dev/sda1 /boot ext2 noauto,noatime 1 1
/dev/sda2 none swap sw 0 0
/dev/sda3 / reiserfs notail,noatime 0 0
/dev/sda4 /tmp reiserfs notail,noatime,nodev,nosuid,noexec 0 0
/dev/sda5 /var reiserfs notail,noatime,nodev 0 0
/dev/sda6 /home reiserfs notail,noatime,nodev,nosuid 0 0
/dev/sda7 /usr reiserfs notail,noatime,nodev,ro 0 0
/dev/cdroms/cdrom0 /mnt/cdrom iso9660 noauto,ro 0 0
proc /proc proc defaults 0 0

Aviso: Colocar /tmp como modo noexec pode impedir que certos scripts executem adequadamente.

Nota: Para cotas de disco veja a seção de cotas.

Nota: Eu não configurei /var como noexec ou nosuid, mesmo se arquivos são normalmente executados deste ponto de montagem. A razão para isso é que o netqmail está instalado em /var/qmail e precisa poder executar e acessar um arquivo SUID. Eu configurei /usr em modo de somente leitura já que eu nunca escrevo nada ali a menos que queira atualizar o Gentoo. Então eu re-monto o sistema de arquivos em modo de leitura-escrita, atualizo e re-monto novamente.

Nota: Mesmo se você não usa netqmail, o Gentoo ainda precisa de bit executável em /var/tmp já que as ebuilds são construídas lá. Mas um caminho alternativo pode ser configurado se você insiste em ter /var montada em modo noexec.

5. Limitações de Usuário/Grupo

5.a. /etc/security/limits.conf

Controlar o uso de recursos pode ser muito eficaz na hora de prevenir um ataque de Denial of Service local ou restringir o número de log-ins máximos permitidos para um grupo ou usuário. No entanto, ajustes muito restritos irão atrapalhar o funcionamento de seu sistema e haverá falhas em programas, então certifique-se de verificar cada ajuste primeiro.

Listagem de código 1.1: /etc/security/limits.conf

*    soft core 0
*    hard core 0
*    hard nproc 15
*    hard rss 10000
*    -    maxlogins 2
@dev hard core 100000
@dev soft nproc 20
@dev hard nproc 35
@dev -    maxlogins 10

Se você encontrar-se tentando configurar nproc ou maxlogins em 0, talvez seja melhor apagar o usuário. O exemplo acima configura os ajustes do dev para processos, arquivo central e maxlogins. O resto está configurado em um valor padrão.

Nota: /etc/security/limits.conf é parte do pacote PAM e só irá funcionar com pacotes que usam PAM.

5.b. /etc/limits

/etc/limits é bem parecido com o arquivo de limites /etc/security/limits.conf. A única diferença é o formato e que só funciona em usuários ou wild cards (não funciona com grupos). Vamos ver uma configuração de exemplo:

Listagem de código 2.1: /etc/limits

*   L2 C0 U15 R10000
kn L10 C100000 U35

Aqui nós configuramos os ajustes padrão e um ajuste específico para o usuário kn. O limits faz parte do pacote sys-apps/shadow. Não é necessário colocar quaisquer limites neste arquivo se você desativou o pam no make.conf ou não configurou o PAM devidamente.

5.c. Cotas

Aviso: Certifique-se que o sistema de arquivos que você está usando suporta cotas. Para poder usar cotas com ReiserFS, você deve usar patches disponíveis na Namesys. Ferramentas de usuário estão disponíveis no Projeto de Linux DiskQuota do Linux. Embora cotas funcionem com o ReiserFS, você pode encontrar outros problemas em seu uso - você foi avisado!

Colocar cotas em um sistema de arquivos restringe o uso do disco com base em usuário ou grupo. As cotas são ativadas no kernel e adicionadas em um ponto de montagem em /etc/fstab. A opção de kernel é ativada na configuração do kernel em File systems->Quota support. Aplique os seguintes ajustes, reconstrua o kernel e reinicie usando o novo kernel.

Comece instalando as cotas com emerge quota. Então modifique seu /etc/fstab e adicione usrquota e grpquota às partições em que você quer restringir o uso de disco, como no exemplo abaixo.

Listagem de código 3.1: /etc/fstab

/dev/sda1 /boot ext2 noauto,noatime 1 1
/dev/sda2 none swap sw 0 0
/dev/sda3 / reiserfs notail,noatime 0 0
/dev/sda4 /tmp ext3 noatime,nodev,nosuid,noexec,usrquota,grpquota 0 0
/dev/sda5 /var ext3 noatime,nodev,usrquota,grpquota 0 0
/dev/sda6 /home ext3 noatime,nodev,nosuid,usrquota,grpquota 0 0
/dev/sda7 /usr reiserfs notail,noatime,nodev,ro	0 0
/dev/cdroms/cdrom0 /mnt/cdrom iso9660 noauto,ro 0 0
proc /proc proc defaults 0 0

Em cada partição que você ativar cotas, crie os arquivos de cota (aquota.user e aquota.group) e coloque-os na raiz da partição.

Listagem de código 3.2: Criando os arquivos de cota

# touch /tmp/aquota.user
# touch /tmp/aquota.group
# chmod 600 /tmp/aquota.user
# chmod 600 /tmp/aquota.group

Este passo deve ser feito em cada partição onde cotas são ativas. Depois de adicionar e configurar os arquivos de cota, nós precisamos adicionar o script quota ao runlevel boot.

Listagem de código 3.3: Adicionando quota ao runlevel boot

# rc-update add quota boot

Nós iremos agora configurar o sistema para verificar as cotas uma vez por semana colocando a seguinte linha em /etc/crontab:

Listagem de código 3.4: Adicionando verificação de cota ao crontab

0 3 * * 0 /usr/sbin/quotacheck -avug.

Depois de reiniciar a máquina, está na hora de configurar as cotas para usuários e grupos. edquota -u kn irá iniciar o editor definido em $EDITOR (o padrão é o nano) e permitir que você edite as cotas para o usuário kn. edquota -g também fará a mesma coisa para grupos.

Listagem de código 3.5: Configurando a cota para o usuário kn

Quotas for user kn: 
/dev/sda4: blocks in use: 2594, limits (soft = 5000, hard = 6500) 
         inodes in use: 356, limits (soft = 1000, hard = 1500)

Para mais detalhes leia man edquota ou oQuota mini howto.

5.d. /etc/login.defs

Se sua política de segurança diz que os usuários devem mudar suas senhas uma semana sim outra não, mude o valor PASS_MAX_DAYS para 14 e PASS_WARN_AGE para 7. É recomendado que você use envelhecimento de senhas, já que métodos de força bruta podem encontrar qualquer senha, dado tempo suficiente. Nós também recomendamos que você configure LOG_OK_LOGINS como ativo.

5.e. /etc/login.access

O arquivo login.access também é parte do pacote sys-apps/shadow, que fornece uma tabela de controle de acessos de log-in. A tabela é usada para controlar quem pode e não pode fazer log-in com base no nome de usuário, nome de grupo ou nome de host. Por padrão, todos usuários em todos os sistemas podem fazer log-in, então o arquivo consiste somente de comentários e exemplos. Não importa se você estiver cuidando da segurança de seu servidor ou estação de trabalho, nós recomendamos que você configure este arquivo para que ninguém fora você mesmo (o administrador) tenha acesso ao console.

Nota: Estes ajustes não se aplicam ao root.

Listagem de código 5.1: /etc/login.access

-:ALL EXCEPT wheel sync:console
-:wheel:ALL EXCEPT LOCAL .gentoo.org

Importante: Cuidado na hora de configurar as opções, já que enganos deixarão você sem acesso à máquina se você não tiver acesso de root.

Nota: Os ajustes não se aplicam a SSH, já que o SSH não executa /bin/login por padrão. Isto pode ser ativado configurando UseLogin yes em /etc/ssh/sshd_config.

Isto irá configurar o acesso de log-in para que os membros do grupo wheel possam fazer log-in localmente ou do domínio gentoo.org. Talvez muito paranóico, mas é melhor prevenir do que remediar.

6. Permissões de arquivos

6.a. Legíveis globalmente

Os usuários normais não devem ter acesso a arquivos de configuração ou senhas. Um indivíduo malicioso pode roubar senhas de bancos de dados ou website e usá-los para fazer defaces--ou pior ainda, apagar--dados. É por isso que é importante que suas permissões de arquivo estejam corretas. Se você tem certeza de que um arquivo somente é usado pelo root, configure-o com as permissões 0600 e atribua o arquivo ao usuário correto com chown.

6.b. Graváveis globalmente/por grupo

Listagem de código 2.1: Encontrando arquivos e diretórios graváveis globalmente

# /usr/bin/find / -type f \( -perm -2 -o -perm -20 \) \ 
   -exec ls -lg {} \; 2>/dev/null >writable.txt
# /usr/bin/find / -type d \( -perm -2 -o -perm -20 \) \ 
   -exec ls -ldg {} \; 2>/dev/null >>writable.txt

Isto irá criar um enorme arquivo com permissões de todos arquivos tendo ou permissão de escrita para o grupo ou para todos. Verifique as permissões e elimine arquivos arquivos globais graváveis por todos, executando /bin/chmod o-w nos arquivos.

6.c. Arquivos SUID/SGID

Arquivos com o bit SUID ou SGID configurados executam com os privilégios do usuário ou grupo proprietário e não do usuário executando o arquivo. Normalmente esses bits são usados em arquivos que devem ser rodados com root para fazer o que devem. Esses arquivos podem levar a comprometimentos de root locais (se contiverem buracos de segurança). Isto é perigoso e arquivos com bits de SUID ou SGID devem ser evitados a qualquer custo. Se você não usa esses arquivos, use chmod 0 neles ou desinstale o pacote de que eles originaram (verifique a que pacote eles pertencem usando equery; se você já não o tiver instalado simplesmente digite emerge gentoolkit). Caso contrário desligue o bit de SUID com chmod -s.

Listagem de código 3.1: Encontrando arquivos setuid

# /usr/bin/find / -type f \( -perm -004000 -o -perm -002000 \) \ 
   -exec ls -lg {} \; 2>/dev/null >suidfiles.txt

Isto irá criar um arquivo contendo uma lista de todos arquivos SUID/SGID.

Listagem de código 3.2: Lista de binários com setuid

/bin/su
/bin/ping
/bin/mount
/bin/umount
/var/qmail/bin/qmail-queue
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/crontab
/usr/bin/chage
/usr/bin/expiry
/usr/bin/sperl5.6.1
/usr/bin/newgrp
/usr/bin/passwd
/usr/bin/gpasswd
/usr/bin/procmail
/usr/bin/suidperl
/usr/lib/misc/pt_chown
/usr/sbin/unix_chkpwd
/usr/sbin/traceroute
/usr/sbin/pwdb_chkpwd

Por padrão o Gentoo Linux não tem muitos arquivos com SUID (embora isso dependa do que você tem instalado), mas você pode obter uma lista como a acima. A maior parte dos comandos não devem ser usados por usuários normais, só root. Desligue o bit de SUID em ping, mount, umount, chfn, chsh, newgrp, suidperl, pt_chown e traceroute executando chmod -s em cada arquivo. Não remova o bit de su, qmail-queue ou unix_chkpwd. Remover o sutuid destes arquivos impede que você faça su e receba correio. Ao remover o bit (onde for seguro fazê-lo) você remove a possibilidade de um usuário normal (ou um indivíduo malicioso) ganhar acesso de root através de qualquer um desses arquivos.

Os únicos arquivos de SUID que eu tenho em meu sistema são su, passwd, gpasswd, qmail-queue, unix_chkpwd e pwdb_chkpwd. Mas se você estiver rodando o X, você pode ter mais algunas, já que o X precisa de acessos elevados conseguidos através de SUID.

6.d. Binários e hardlinks com SUID/SGID

Um arquivo só é considerado apagado quando não há mais links apontando para ele. Isto pode soar como um conceito estranho, mas considere que um nome de arquivo como /usr/bin/perl é na verdade um link para o inode onde os dados são gravados. Qualquer número de links pode apontar para um arquivo, e até todos serem apagados, o arquivo ainda existe.

Se seus usuários têm acesso a uma partição que não é montada com nosuid ou noexec (por exemplo, se /tmp, /home, ou /var/tmp não forem partições separadas) você deve tomar cuidado para que seus usuários não criem hardlinks para binários com SUID ou SGID, de forma que após a atualização do Portage eles ainda tenham acesso a versões antigas.

Aviso: se você recebeu um aviso do portage sobre hardlinks remanescentes, e seus usuários podem escrever para uma partição que permite executar arquivos SUID/SGID, você deve ler esta seção cuidadosamente. Um de seus usuários pode tentar contornar sua atualização mantendo uma cópia antiga de um programa. Se seus usuários não podem criar arquivos SUID, ou só podem executar programas usando o carregador dinâmico (partições montadas com noexec), você não tem com o que se preocupar.

Nota: Usuários não precisam ter acesso de leitura a um arquivo para criar um link para ele, só precisam ter permissão de leitura no diretório que o contém.

Para ver quantos links um arquivo tem, você pode usar o comando stat.

Listagem de código 4.1: Comando stat

$ stat /bin/su    
  File: `/bin/su'
  Size: 29350           Blocks: 64         IO Block: 131072 regular file
Device: 900h/2304d      Inode: 2057419     Links: 1
Access: (4711/-rws--x--x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2005-02-07 01:59:35.000000000 +0000
Modify: 2004-11-04 01:46:17.000000000 +0000
Change: 2004-11-04 01:46:17.000000000 +0000

Para encontrar arquivos SUID e SGID com links múltiplos, você pode usar o find.

Listagem de código 4.2: Encontrando binários suid/sgid com links múltiplos

$ find / -type f \( -perm -004000 -o -perm -002000 \) -links +1 -ls

7. PAM

7.a. PAM

O PAM é uma suíte de bibliotecas compartilhadas que fornecem um modo alternativo de dar autenticação de usuário nos programas. A opção de use pam está ligada por padrão. Portanto os ajustes de PAM no Gentoo Linux são bem razoáveis, mas sempre há espaço para melhorias. Primeiro instale o cracklib.

Listagem de código 1.1: Instalando o cracklib

# emerge cracklib

Listagem de código 1.2: /etc/pam.d/passwd

auth     required pam_unix.so shadow nullok
account  required pam_unix.so
password required pam_cracklib.so difok=3 retry=3 minlen=8 dcredit=2 ocredit=2 
password required pam_unix.so md5 use_authtok
session  required pam_unix.so

Isto irá adicionar o cracklib que irá verificar que todas as senhas de usuário tenham pelo menos 8 caracteres e contenham um mínimo de 2 dígitos, 2 outros caracteres, e tenham mais de 3 caracteres diferentes da última senha. Isto força o usuário a escolher uma boa senha (política de senhas). Veja a documentação do PAM para mais opções.

Listagem de código 1.3: /etc/pam.d/sshd

auth     required pam_unix.so nullok 
auth     required pam_shells.so
auth     required pam_nologin.so
auth     required pam_env.so
account  required pam_unix.so
password required pam_cracklib.so difok=3 retry=3 minlen=8 dcredit=2 ocredit=2 use_authtok
password required pam_unix.so shadow md5
session  required pam_unix.so
session  required pam_limits.so

Cada serviço não configurado com um arquivo de PAM em /etc/pam.d irá usar as regras em /etc/pam.d/other. Os padrões estão configurados como deny, como devem ser. Mas eu gosto de ter vários registros, motivo pelo qual eu adicionei o pam_warn.so. A última configuração é pam_limits, que é controlado por /etc/security/limits.conf. Veja a seção do /etc/security/limits.conf para mais desses ajustes.

Listagem de código 1.4: /etc/pam.d/other

auth     required pam_deny.so 
auth     required pam_warn.so 
account  required pam_deny.so 
account  required pam_warn.so 
password required pam_deny.so 
password required pam_warn.so 
session  required pam_deny.so 
session  required pam_warn.so

8. Wrappers de TCP

8.a. Wrappers de TCP

Este é um jeito de controlar acesso a serviços normalmente rodados pelo inetd (que o Gentoo não tem), mas também pode ser usado pelo xinetd e outros serviços.

Nota: O serviço deve executar tcpd em seu argumento de servidor (no xinetd). Veja o capítulo sobre o xinetd para mais informações.

Listagem de código 1.1: /etc/hosts.deny

ALL:PARANOID

Listagem de código 1.2: /etc/hosts.allow

ALL: LOCAL @wheel
time: LOCAL, .gentoo.org

Como você pode ver o formato é bem parecido com o do /etc/login.access. O tcpd suporta um serviço específico; ele não sobrepõe o /etc/login.access. Esses ajustes só aplicam-se a serviços que usam wrappers de tcp.

Também é possível executar comandos quando um serviço é acessado (isso pode ser usado na hora de ativar relays para usuários de conexão discada) mas não é recomendado, já que as pessoas acabam criando mais problemas que tentam resolver. Um exemplo pode ser que você configure um script para mandar um e-mail cada vez que alguém bater na regra deny, mas então um indivíduo malicioso pode iniciar um ataque de DoS ao continuar a acertar a regra de deny. Isso irá criar muito I/O e e-mails, então não faça isso! Leia o man 5 hosts_access para mais informações.

9. Segurança de Kernel

9.a. Removendo funcionalidades

A regra básica na hora de configurar o kernel é remover tudo que você não precisa. Isto não só irá criar um kernel menor, mas também remover as vulnerabilidades que podem residir dentro de drivers e outras funções.

Também considere desligar suporte de módulos carregáveis. Embora seja possível adicionar root kits sem essa função, fica mais difícil para indivíduos maliciosos normais instalarem root kits via módulos do kernel.

9.b. O sistema de arquivos proc

Muitos parâmetros de kernel podem ser alterados através do sistema de arquivos /proc ou usando sysctl.

Para mudar parâmetros e variáveis de kernel na hora, você precisa de CONFIG_SYSCTL definido em seu kernel. Ele já vem ligado por padrão em um kernel 2.4 normal..

Listagem de código 2.1: Desligue o encaminhamento de IP

# /bin/echo "0" > /proc/sys/net/ipv4/ip_forward

Certifique-se que o encaminhamento de IP esteja desligado. Nós só precisamos disso para um host hospedado em vários lugares. É aconselhável ligar ou desligar essa opção antes de outras opções já que ela liga/desliga outras opções também.

Listagem de código 2.2: Ignorar pacotes de ping

# /bin/echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all

Isto fará com que o kernel simplesmente ignore todas mensagens de ping (também conhecidas como mensagens de ICMP de tipo 0). A razão para isso é que um pacote de IP carregando uma mensagem ICMP pode conter um payload com informações diferentes das que você espera. Administradores usam o ping como uma ferramenta de diagnóstico e freqüentemente reclamam se ele estiver desligado, mas não há motivo para uma pessoa de fora poder fazer ping. No entanto, já que as vezes pode ser útil para pessoas de dentro poder fazer ping, você pode desabilitar mensagens de ICMP de tipo 0 na firewall (permitindo que administradores locais continuem a usar essa ferramenta).

Listagem de código 2.3: Ignorar pings de broadcast

# /bin/echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

Isto desliga respotas a broadcasts de ICMP e irá prevenir ataques de Smurf. O ataque de Smurf funciona mandando um mensagem de ICMP de tipo 0 (ping) para o endereço de broadcast de uma rede. Tipicamente um indivíduo malicioso irá usar um endereço de fonte falso. Todos os computadores na rede irão responder à mensagem de ping e irão floodar o host com endereço de rede forjado.

Listagem de código 2.4: Desligar pacotes de fonte roteada

# /bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_source_route

Não aceite pacotes de fonte roteada. Indivíduos maliciosos podem usar fontes roteadas para gerar tráfego fingindo vir de dentro de sua rede, mas que é na verdade roteado de volta ao caminho de onde veio, para que indivíduos maliciosos possam comprometer sua rede. Roteamento de fonte é raramente usado para propósitos legítimos, então você pode desligá-lo com segurança.

Listagem de código 2.5: Desligar aceitação de redirecionamento

# /bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects
# /bin/echo "0" > /proc/sys/net/ipv4/conf/all/secure_redirects

Não aceite redirecionar pacotes ICMP. Redirecionamento de ICMP pode ser usado para alterar suas tabelas de roteamento, possivelmente para um fim malicioso.

Listagem de código 2.6: Proteção contra mensagens de erro falsas

# /bin/echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

Ative a protação contra respostas a mensagens de erro falsas.

Listagem de código 2.7: Ativar filtro de caminho reverso

# for i in /proc/sys/net/ipv4/conf/*; do
        /bin/echo "1" > $i/rp_filter
done

Ligue o filtro de caminho reverso. Isto ajuda a certificar que os pacotes usam endereços de fonte legítimos ao rejeitar pacotes de entrada automaticamente se a entrada da tabela de roteamento para o endereço fonte não bater com a interface de rede em que chegam. Isto tem vantagens de segurança porque impede a forja de IP. Precisamos ativá-lo em cada net/ipv4/conf/* caso contrário a validação de fontes não é inteiramente funcional.

Aviso: No entanto, ligar filtro de caminhos reversos pode ser um problema se você usar roteamento assimétrico (pacotes de você para um host tomam um caminho diferente dos pacotes daquele host para você) ou se você opera um host sem roteamento que tem vários endereços IP em diferentes interfaces.

Listagem de código 2.8: Registrar todos pacotes forjados, roteados por fonte e redirecionados

# /bin/echo "1" > /proc/sys/net/ipv4/conf/all/log_martians

Registrar pacotes forjados, roteados por fonte e redirecionados.

Todas essas configurações serão apagadas quando a máquina for reiniciada. Eu sugiro que você adicione-os ao /etc/sysctl.conf, que é automaticamente lido pelo script de init /etc/init.d/bootmisc.

A sintaxe para o /etc/sysctl.conf é bem simples. Tire o /proc/sys/ dos caminhos mencionados anteriormente e substitua / com .:

Listagem de código 2.9: Traduzindo para sysctl.conf

(Usando echo manualmente):
/bin/echo "0" > /proc/sys/net/ipv4/ip_forward

(Automaticamente em sysctl.conf:)
net.ipv4.ip_forward = 0

9.c. Grsecurity

O patch do Grsecurity é padrão nas fontes de kernel do Gentoo, mas é desligado por padrão. Configure seu kernel como você normalmente faria e então configure as opções de Grsecurity. Uma explicação em profundidade das opções de Grsecurity disponíveis (versão 1.9) está disponível na página do projeto do Gentoo Hardened.

As grsec-sources recentes fornecem a versão 2.* do Grsecurity. Para mais informações sobre este conjunto de patches do Grsecurity melhorados, por favor consulte a documentação disponível na homepage do Grsecurity.

9.d. Kerneli

Kerneli é um patch que adiciona criptografia ao kernel existente. Ao aplicar o patch em seu kernel você terá novas opções como cifras criptográficas, algoritimos de digest e filtros de loops criptográficos.

Aviso: O patch do kerneli não está atualmente em versão estável para o kernel mais recente, então tenha cuidado na hora de usá-lo.

9.e. Outros patches de kernel

E provavelmente existem muitos outros.

10. Segurança de serviços

10.a. Apache

O Apache (1.3.26) vem com um arquivo de configuração decente mas de novo, nós precisamos melhorar algumas coisas, como fazer bind do Apache em um endereço e impedir que ele vaze informações. Abaixo estão as opções que você deve aplicar ao arquivo de configuração.

Se você não desabilitou ssl em seu /etc/make.conf antes de instalar o Apache, você deve ter acesso a um servidor com acesso a ssl. Simplesmente adicione a seguinte linha para ativá-lo.

Listagem de código 1.1: /etc/conf.d/apache

HTTPD_OPTS="-D SSL"

Listagem de código 1.2: /etc/apache/conf/apache.conf

#Faça-o ouvir seu ip
Listen 127.0.0.1
BindAddress 127.0.0.1
#Não é uma boa idéia usar nobody ou nogroup -
#para todo serviço que não roda como root
#(simplesmente adicione o usuário apache com grupo apache)
User apache
Group apache
#Impedirá que o apache fale sobre a versão
ServerSignature Off
ServerTokens Prod

O Apache é compilado com --enable-shared=max e --enable-module=all. Isto irá por padrão carregar todos módulos, então você deve comentar todos módulos que você não usa na seção LoadModule (LoadModule e AddModule). Reinicie o serviço executando /etc/init.d/apache restart.

Documentação está disponível em http://www.apache.org.

10.b. Bind

Pode-se encontrar documentação no Internet Software Consortium. O Manual de referências do administrador também está no doc/arm.

As novas ebuilds do BIND suportam chroot sem modificações. Depois de fazer emerge do bind siga essas simples instruções:

Listagem de código 2.1: Fazendo chroot do BIND

ebuild /var/db/pkg/net-dns/bind-9.2.2-r2/bind-9.2.2-r2.ebuild config\`"
(Antes de rodar o comando acima talvez você queira mudar o diretório de
chroot em /etc/conf.d/named. Caso contrário /chroot/dns será usado.)
(Você pode ter que substituir o número de versão com o número da versão atual)

10.c. Djbdns

Djbdns é uma implementação de DNS de segurança sobre a qual o autor está disposto a apostar dinheiro. É muito diferente de como o Bind 9 funciona, mas vale a tentativa. Mais informações podem ser encontradas em http://www.djbdns.org.

10.d. FTP

Geralmente, usar FTP (File Transfer Protocol) é uma má idéia. Ele usa dados sem criptografia (isto é, senhas são enviadas em texto normal), ouve em 2 portas (normalmente porta 20 e 21), e indivíduos maliciosos estão freqüentemente procurando por log-ins anônimos para trocar warez. Já que o protocolo de FTP contém vários problemas de segurança você deve usar sftp ou HTTP. Se não for possível, faça a segurança de seus serviços o melhor que puder e prepare-se.

10.e. Mysql

Se você somente precisa de que aplicativos locais acessem o banco de dados do mysql, descomente a seguinte linha em /etc/mysql/my.cnf.

Listagem de código 5.1: Desligando acesso de rede

skip-networking

Então nós desligamos o uso do comando LOAD DATA LOCAL INFILE. Isto é para impedir acesso não autorizado de leitura de arquivos locais. Isto é importante quando novas vulnerabilidades de injeção de SQL em aplicações PHP são encontradas.

Listagem de código 5.2: Desligando LOAD DATA LOCAL INFILE na seção [mysqld]

set-variable=local-infile=0

A seguir, precisamos remover um banco de dados de amostra (teste) e todas contas fora a conta de root local.

Listagem de código 5.3: Removendo banco de dados de amostra e usuários desnecessários

mysql> drop database test;
mysql> use mysql;
mysql> delete from db;
mysql> delete from user where not (host="localhost" and user="root");
mysql> flush privileges;

Aviso: Tenha cuidado com o feito acima se você já configurou contas de usuário.

Nota: Se você tem mudado senhas do prompt do MySQL, você deve sempre limpar o ~/.mysql_history e /var/log/mysql/mysql.log já que eles gravam os comandos de SQL executados com senhas em texto normal.

10.f. Proftpd

O proftpd já teve vários problemas de segurança, mas a maior parte parece ter sido consertada. De qualquer jeito, é uma boa idéia colocar umas melhorias:

Listagem de código 6.1: /etc/proftpd/proftpd.conf

ServerName "Meu daemon de ftp"
#Não mostrar o ident do servidor
ServerIdent on "Vá embora"

#Torna mais fácil a criação de usuários virtuais
RequireValidShell off

#Usa senha e arquivo de grupo alternativo (o passwd usa formado criptográfico)
AuthUserFile "/etc/proftpd/passwd"
AuthGroupFile "/etc/proftpd/group"

# Permissões
Umask 077

# Timeouts e limitações
MaxInstances 30
MaxClients 10 "Só 10 conexões permitidas"
MaxClientsPerHost 1 "Você já vez um log-in"
MaxClientsPerUser 1 "Você já vez um log-in"
TimeoutStalled 10
TimeoutNoTransfer 20
TimeoutLogin 20

#Fazer chroot de todos
DefaultRoot ~

#não rodar como root
User  nobody
Group nogroup

#registrar todas transferências
TransferLog /var/log/transferlog

#Problemas com globbing
DenyFilter \*.*/

Você pode encontrar documentação em http://www.proftpd.org.

10.g. Pure-ftpd

Pure-ftpd é uma ramificação do original trollftpd, modificada por razões de segurança e funcionalidade por Frank Dennis.

Use usuários virtuais (nunca contas de sistema) ativando a opção AUTH. Configure-a para -lpuredb:/etc/pureftpd.pdb e crie seus usuários usando /usr/bin/pure-pw.

Listagem de código 7.1: /etc/conf.d/pure-ftpd

AUTH="-lpuredb:/etc/pureftpd.pdb"

## Outras coisas ##
MISC_OTHER="-A -E -X -U 177:077 -d -4 -L100:5 -I 15"

Configure seu ajuste de MISC_OTHER para negar conexões anônimas (-E), fazer chroot de todos (-A), impedir que usuários leiam ou escrevam arquivos começando com um . (ponto) (-X), tempo máximo ocioso (-I), limitar recursão (-L), e uma umask razoável.

Aviso: Não use as opções -w ou -W! Se você quiser ter um site de warez, pare de ler este guia!

Você pode encontrar documentação em http://www.pureftpd.org.

10.h. Vsftpd

Vsftpd (diminutivo de very secure ftp) é um pequeno daemon de ftp rodando uma configuração razoavelmente padrão. Ele é simples e não tem tantas funções como o pureftp e o proftp.

Listagem de código 8.1: /etc/vsftpd

anonymous_enable=NO
local_enable=YES

#só leitura
write_enable=NO

#permitir registro de transferências
xferlog_std_format=YES

idle_session_timeout=20
data_connection_timeout=20
nopriv_user=nobody

chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chrootlist

ls_recurse_enable=NO

Como você pode ver, não há jeito deste serviço ter permissões individuais, mas em relação aos ajustes anônimos ele é muito bom. Às vezes pode ser útil ter um servidor de ftp anônimo (para compartilhar código livre), e o vsftpd faz um bom trabalho nisso.

10.i. Netqmail

O netqmail é freqüentemente tido como um servidor de correio muito seguro. É escrito com segurança (e paranóia) em mente. Ele não permite relaying por padrão e não teve um buraco de segurança desde 1996. Simplesmente faça emerge netqmail e vá configurá-lo!

10.j. Samba

Samba é o protocolo para compartilhar arquivos com redes Microsoft/Novell e não deve ser usado na Internet. Todavia, ainda precisa de medidas de segurança.

Listagem de código 10.1: /etc/samba/smb.conf

[global]
  #Prender em uma interface
  interfaces = eth0 10.0.0.1/32

  #Certificar-se de usar senha criptografada
  encrypt passwords = yes
  directory security mask = 0700

  #permitir tráfego de 10.0.0.*
  hosts allow = 10.0.0.

  #Permitir autenticação de usuário
  #(não use o modo compartilhar)
  security = user

  #Proibir contas com privilégio
  invalid users = root @wheel

  #Tamanho máximo que o smb mostra para uma share (não um limite)
  max disk size = 102400

  #Manter a política de senhas
  min password length = 8
  null passwords = no

  #Usar PAM (se suporte for adicionado)
  obey pam restrictions = yes
  pam password change = yes

Certifique-se que as permissões estão configuradas corretamente em todas shares e lembre-se de ler a documentação.

Agora reinicie o servidor e adicione os usuários que devem ter acesso ao serviço. Isto é feito através do comando /usr/bin/smbpasswd com o parâmetro -a.

10.k. ssh

A única medida de segurança que o OpenSSH precisa é ligar um método de autenticação baseado na criptografia de chaves públicas. Muitos sites (como http://www.sourceforge.net, http://www.php.net e http://www.apache.org) sofreram instrusões não autorizadas devido a senhas vazadas ou senhas ruins.

Listagem de código 11.1: /etc/ssh/sshd_config

#Só permitir a versão 2
Protocol 2

#Desligar log-in de root. Usuários devem usar su para root
PermitRootLogin no

#Ligar autenticação de chave pública
PubkeyAuthentication yes
AuthorizedKeysFile      .ssh/authorized_keys

#Desligar autenticaçao de .rhost e senha normal
RhostsAuthentication no
PasswordAuthentication no
PermitEmptyPasswords no

#Só permitir que usuários nos grupos wheel ou admin façam log-in
AllowGroups wheel admin

#Nestes grupos só permitir os seguintes usuários
#O @<nomededomínio> é opcional mas substitui a
#antiga diretiva AllowHosts
AllowUsers kn@gentoo.org bs@gentoo.org

#Registros 
SyslogFacility AUTH
LogLevel INFO

ListenAddress 127.0.0.1

Também verifique que você não tem UsePAM yes em seu arquivo de configuração já que isso sobrepõe o mecanismo de autenticação de chave pública.

Agora tudo o que seus usuários tem que fazer é criar uma chave (na máquina em que querem fazer log-in) com o seguinte comando:

Listagem de código 11.2: Criando um par de chaves DSA

# /usr/bin/ssh-keygen -t dsa

E digite sua senha.

Listagem de código 11.3: Saída do ssh-keygen

Generating public/private dsa key pair.
Enter file in which to save the key (/home/kn/.ssh/id_dsa):[Aperte enter]
Created directory '/home/kn/.ssh'.
Enter passphrase (empty for no passphrase): [Digite a senha]
Enter same passphrase again: [Digite a senha novamente]
Your identification has been saved in /home/kn/.ssh/id_dsa.
Your public key has been saved in /home/kn/.ssh/id_dsa.pub.
The key fingerprint is:
07:24:a9:12:7f:83:7e:af:b8:1f:89:a3:48:29:e2:a4 kn@knielsen

Isto irá adicionar dois arquivos no seu diretório ~/.ssh/ chamados id_dsa e id_dsa.pub. O arquivo chamado id_dsa é sua chave privada e deve ser mantida fora do alcance outras pessoas. O outro arquivo id_dsa.pub deve ser distribuído a todos servidores a que você tem acesso. Adicione a chave ao diretórios de home dos usuários em ~/.ssh/authorized_keys e o usuário deve poder fazer log-in.

Agora seus usuários devem guardar sua chave privadas bem. Coloque em mídia que sempre carregam com eles ou mantenham eu suas estações de trabalho (coloque isso na política de senhas)

Para mais informações visite o website do OpenSSH.

10.l. Usando o xinetd

O xinetd é um substituto do inetd (que o Gentoo não tem), o daemon de serviços de Internet. Ele suporta controle de acesso com base no endereço do host remoto e a hora de acesso. Ele também fornece capacidades de registros extensivas, incluindo hora de início do servidor, endereço de host remoto, nome de usuário remoto, tempo ativo do servidor, e ações pedidas.

Como com todos outros serviços é importante ter uma boa configuração padrão. Mas já que o xinetd é rodado com root e suporta protocolos que você pode não saber como funcionam, nós recomendados não usá-lo. Mas se você quiser usá-lo de qualquer jeito, aqui está como melhorar sua segurança:

Listagem de código 12.1: Instalando o xinetd

# emerge xinetd tcp-wrappers

E edite o arquivo de configuração:

Listagem de código 12.2: /etc/xinetd.conf

defaults
{
 only_from = localhost
 instances = 10
 log_type = SYSLOG authpriv info
 log_on_success = HOST PID
 log_on_failure = HOST
 cps = 25 30
}

# Isto irá configurar o pserver (cvs) via xinetd com as seguintes configurações:
# max 10 instâncias (10 conexões por vez)
# limitar o pserver para somente tcp
# usar o usuário cvs para rodar este serviço
# prender todas interfaces a só 1 ip
# permitir acesso de 10.0.0.*
# limitar o horário que os desenvolvedores podem usar o cvs de 8 horas até 17 horas
# usar wrappers de tpcd (controle de acesso controlado em
# /etc/hosts.allow e /etc/hosts.deny)
# max_load na máquina configurado para 1.0
# A opção disable é por padrão no mas eu gosto de tê-la
# caso deva ser desligada
service cvspserver
{
 socket_type = stream
 protocol = tcp
 instances = 10
 protocol = tcp
 wait = no
 user = cvs
 bind = 10.0.0.2
 only_from = 10.0.0.0
 access_times = 8:00-17:00
 server = /usr/sbin/tcpd
 server_args = /usr/bin/cvs --allow-root=/mnt/cvsdisk/cvsroot pserver
 max_load = 1.0
 log_on_failure += RECORD
 disable = no
}

Para mais informações leia man 5 xinetd.conf.

10.m. X

Por padrão o Xorg é configurado para agir como um Xserver. Isto pode ser perigoso já que o X usa conexões de TCP sem criptografia e escuta xclients.

Importante: Se você não precisa deste serviço desligue-o!

Mas se você precisa usar sua estação de trabalho como um Xserver use o comando /usr/X11R6/bin/xhost com cuidado. Este comando permite que clientes de outros hosts conectem-se e usem seu display. Isto pode ser útil se você precisa de uma aplicação de X de uma máquina diferente e o único jeito é através da rede, mas também pode ser explorado por um indivíduo malicioso. A sintaxe deste comando é /usr/X11R6/bin/xhost +hostname

Aviso: Nunca use a função xhost +! Isto permitirá que qualquer cliente conecte-se e tome controle de seu X. Se um indivíduo obtiver acesso a seu X, ele pode registrar o que você digitar e tomar controle de seu desktop. Se você tiver de usá-lo lembre-se sempre de especificar um host.

Uma solução mais segura é desativar essa função completamente iniciando o X com startx -- -nolisten tcp ou desligando-a permanentemente na configuração.

Listagem de código 13.1: /usr/X11R6/bin/startx

defaultserverargs="-nolisten tcp"

Para ter certeza de que o startx não seja sobre-escrito na hora de instalar uma nova versão do Xorg, você deve protegê-lo. Adicione a seguinte linha ao /etc/make.conf:

Listagem de código 13.2: /etc/make.conf

CONFIG_PROTECT_MASK="/usr/X11R6/bin/startx"

Se você usa um gerenciador de login gráfico você precisa de um método diferente.

Para o gdm (Gnome Display Manager)

Listagem de código 13.3: /etc/X11/gdm/gdm.conf

[server-Standard]
command=/usr/X11R6/bin/X -nolisten tcp

Para o xdm (X Display Manager) e kdm (Kde Display Manager)

Listagem de código 13.4: /etc/X11/xdm/Xservers

:0 local /usr/bin/X11/X -nolisten tcp 

11. Fazendo chroot e servidores virtuais

11.a. Fazendo chroot

Fazer chroot de um serviço é um jeito de limitar o ambiente de um serviço (ou um usuário) a só acessar o que deve e não obter acesso (ou informações) que podem levar a acesso de administrador (root). Ao rodar um serviço como um usuário diferente de root (nobody, apache, named), um indivíduo malicioso só pode ter acesso a arquivos com a permissão do usuário. Isto significa que um indivíduo malicioso não pode obter acesso de root, mesmo se os serviços tiverem uma falha de segurança.

Alguns serviços como o pure-ftpd e bind têm funções de chroot, e outros serviços não têm. Se o serviço suportá-lo, use-o. Caso contrário, você terá que descobrir como criar sua própria função de chroot. Vamos ver como criar um chroot e para uma compreensão básica de como o chroot funciona, nós iremos testá-lo com o bash (jeito fácil de aprender).

Crie o diretório /chroot com mkdir /chroot. E descubra com que bibliotecas dinâmicas que o bash é compilado (se for compilado com -static este passo não é necessário):

O seguinte comando irá criar uma lista de bibliotecas usadas pelo bash.

Listagem de código 1.1: Obtendo uma lista de bibliotecas usadas

# ldd /bin/bash
  libncurses.so.5 => /lib/libncurses.so.5 (0x4001b000)
  libdl.so.2 => /lib/libdl.so.2 (0x40060000)
  libc.so.6 => /lib/libc.so.6 (0x40063000)
  /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

Agora, vamos criar o ambiente para o bash.

Listagem de código 1.2: Criando ambiente de chroot para o bash

# mkdir /chroot/bash
# mkdir /chroot/bash/bin
# mkdir /chroot/bash/lib

Copie os arquivos usados pelo bash (/lib) para o lib chrootado e copie o comando de bash para o diretório bin chrootado. Isto irá criar o exato mesmo ambiente, só que com menos funcionalidades. Depois de copiar, teste-o: chroot /chroot/bash /bin/bash. Se você receber um prompt dizendo /, ele está funcionando! Caso contrário ele dirá que algum arquivo está faltando. Algumas bibliotecas compartilhadas dependem uma da outra.

Você perceberá que dentro do chroot nada funciona, fora talvez o echo. Isto é porque não temos outros comandos fora do ambiente de chroot fora bash, e o echo é uma função interna.

Este é basicamente o mesmo jeito que você criaria um serviço chrootado. A única diferença é que os serviços às vezes dependem de dispositivos e arquivos de configuração em /etc. Simplesmente copie-os (dispositivos podem ser copiados com cp -a) para o ambiente de chroot, edite o script de init para usar chroot antes de executar. Pode ser difícil descobrir que serviços e arquivos de configuração um serviço precisa. Aqui é onde o comando strace torna-se útil. Inicie o serviço com /usr/bin/strace bash e procure por open, read, stat e talvez connect. Isto dará a você uma melhor idéia de que arquivos copiar. Mas na maioria dos casos, só copiar o arquivo passwd (edite a cópia e remova usuários que não têm nada em relação ao serviço), /dev/zero, /dev/log e /dev/random.

11.b. User Mode Linux

Outro jeito de criar um ambiente mais seguro é rodando uma máquina virtual. Uma máquina virtual, como o nome implica, é o processo que roda em cima de seu sistema operacional real fornecendo um hardware e ambiente de sistema operacional que parece ser sua própria máquina individual. O benefício de segurança é que se o servidor rodando a máquina virtual for comprometido, só o servidor virtual é afetado e não a instalação mestre.

Para mais informações sobre como configurar o User Mode Linux consulte o Guia de User Mode Linux.

12. Firewalls

12.a. Uma firewall

As pessoas normalmente pensam que uma firewall fornece o mais alto nível de segurança, mas estão enganadas. Na maior parte dos casos uma firewall mal-configurada dá menos segurança que não ter nenhuma. Uma firewall também é feita de software e deve ser tratada do mesmo jeito que qualquer outro software, porque tem a mesma chance de conter defeitos.

Então pense antes de implementar uma firewall! Você realmente precisa de uma? Se você acha que você precisa de uma, escreva uma política sobre como deve funcionar, que tipo de firewall, e quem deve operá-la. Mas antes leia este guia.

Firewalls são usadas para dois propósitos:

  • Manter usuários (worms/indivíduos maliciosos) fora
  • Manter usuários (empregados/crianças) dentro

Basicamente há três tipos de firewalls:

  • Filtro de pacotes
  • Relay de circuitos
  • Roteador de aplicações

Uma firewall deve ficar em uma máquina dedicada que não roda serviços (ou unicamente sshd) e segura do jeito que este guia recomenda que seja.

12.b. Filtro de pacotes

Todo tráfego de rede é enviado na forma de pacotes. Grandes quantidades de tráfego são divididas em pacotes menores para facilitar seu manuseio e são remontados quando chegam em seu destino. No cabeçalho de pacote todos pacotes contêm informações de como e onde devem ser levados. E esta informação é exatamente o que uma firewall de filtro de pacotes usa. A filtragem é baseada em:

  • Permitir ou proibir pacotes com base em endereço de IP fonte/destino
  • Permitir ou proibir pacotes com base em porta de fonte/destino
  • Permitir ou proibir pacotes com base em protocolo
  • Permitir ou proibir pacotes com base em opções dentro de um protocolo específico

Em outras palavras, a filtragem é baseada em todos os dados do cabeçalho de um pacote e não seu conteúdo.

Fraquezas:

  • Informações de endereço em um pacote podem potencialmente conter um endereço IP falso (ou como dizemos spoofados) pelo enviador.
  • Dados ou pedidos dentro do pacote permitido podem conter dados não-desejáveis que o indivíduo malicioso pode usar para explorar bugs conhecidos nos serviços na firewall ou atrás dela
  • Normalmente único ponto de falha

Vantagens:

  • Simples e fácil de implementar
  • Pode dar avisos de um possível ataque antes de acontecer (isto é, detectando escaneadores de portas)
  • Bom para deter ataques de SYN

Exemplos de filtros de pacotes gratuitos para Linux:

Nota: É recomendável que você use iptables. Ipchains está obsoleto.

12.c. Relay de circuitos

Um roteador em nível de circuito é uma firewall que valida as conexões antes de permitir que os dados sejam trocados. Isto significa que ele não simplesmente permite ou nega pacotes com base no cabeçalho do pacote, mas também determina se a conexão entre os dois lados é válida de acordo com regras configuráveis antes de abrir uma sessão e permitir que dados sejam trocados. A filtragem é baseada em:

  • Endereço IP de fonte/destino
  • Porta de fonte/destino
  • Um período de tempo
  • Protocolo
  • Usuário
  • Senha

Todo tráfego é validado e monitorado, e tráfego não desejável pode ser ignorado.

Fraquezas:

  • Opera no layer de transporte e pode necessitar de modificação substanciais nos programas que normalmente fornecem funções de transporte.

12.d. Roteador de aplicações

Um roteador de nível de aplicações é um proxy para aplicações, trocando dados com sistemas remotos em nome dos clientes. É mantido longe do público seguramente atrás de uma DMZ (De-Militarized Zone: a porção de uma rede privada que é visível através da firewall) ou uma firewall que não permite conexões do lado de fora. A filtragem é baseada em:

  • Permitir ou impedir com base em endereço IP de fonte/destino
  • Baseado no conteúdo do pacote
  • Limita acesso de arquivos com base no tipo de arquivo ou extensão

Vantagens:

  • Pode fazer cachê de arquivos, aumentando performance de rede
  • Registros detalhados de todas conexões
  • Boa escalabilidade (alguns servidores de proxy podem "compartilhar" dados em cachê)
  • Não tem acesso direto do exterior
  • Pode alterar até o conteúdo do pacote na hora

Desvantagens:

  • Configuração é complexa

Roteadores de aplicações são considerados a solução mais segura já que eles não tem que rodar como administrador (root) e os hosts atrás deles não são alcançáveis através da Internet.

Exemplo de um roteador de aplicações gratuito:

12.e. Iptables

Para usar o iptables, ele deve estar ativado no kernel. Eu adicionei o iptables como módulos (o comando iptables carrega-os conforme eles são necessários) e recompilei meu kernel (mas você pode compilar o iptables dentro do kernel, se você tem a intenção de desligar suporte de módulos carregáveis, como discutimos anteriormente). Para mais informações em como configurar seu kernel para o iptables vá para o Tutorial de Iptables Capítulo 5: Preparativos. Depois que você compilou ser kernel (ou durante a compilação do kernel, você deve adicionar o comando iptables. Simplesmente faça emerge iptables e ele deve funcionar.

Agora teste se ele funciona rodando iptables -L. Se falhar, algo está errado e você tem quer verificar sua configuração mais uma vez.

O Iptables é o novo e muito melhorado filtro de pacotes do kernel do Linux 2.4.x. Ele é o sucessor do antigo filtro de pacotes ipchains do kernel do Linux 2.2.x. Uma das grandes melhorias é que o iptables agora pode fazer filtro de pacotes "stateful". Com o filtro de pacotes stateful é possível controlar cada conexão TCP estabelecida.

Uma conexão TCP consiste de uma série de pacotes contendo informações sobre endereço IP de fonte, endereço IP de destino, porta de fonte, porta de destino, e um número de seqüência para que os pacotes possam ser remontados sem perder dados. TCP é um protocolo orientado à conexão, diferente do UDP, que funciona sem conexão.

Examinando o cabeçalho do pacote TCP, um filtro de pacotes stateful pode determinar se um pacote TCP recebido é parte de uma conexão já estabelecida ou não e decidir aceitar ou ignorar o pacote.

Com um filtro de pacotes não-stateful, é possível enganar o filtro de pacotes a aceitar pacotes que deveriam ser ignorados manipulando os cabeçalhos dos pacotes TCP. Isto pode ser feito manipulando as opções de SYN ou outras opções no cabeçalho de TCP para fazer um pacote malicioso parecer ser parte de uma conexão estabelecida (já que o filtro de pacotes em si não suporte rastreamento de conexões). Com o filtro de pacotes stateful é possível ignorar esses pacotes, já que eles não são parte de uma conexão pré-estabelecida. Isto também irá parar a possibilidade de "stealth scans", um tipo de escaneamento de portas em que o escaneador manda pacotes com opções que são muito menos possíveis de serem registradas por uma firewall que pacotes SYN normais.

O Iptables fornece várias outras funções como NAT (Network Address Translation) e limite de taxas. O limite de taxas é extremamente útil na prevenção de certos ataques de DoS (Denial of Service) como SYN floods.

Uma conexão de TCP é estabelecida pelo chamado cumprimento de três jeitos. Na hora de estabelecer uma conexão TCP o lado do cliente envia um pacote para o servidor com a opção SYN ligada. Quando o servidor recebe o pacote SYN, ele responde mandando um pacote SYN+ACK de volta para o cliente. Quando o pacote SYN+ACK é recebido, o lado do cliente responde com um terceiro pacote ACK reconhecendo a conexão em efeito.

Um ataque de SYN flood é feito mandando o pacote SYN, mas não enviando a resposta ao pacote SYN+ACK. O lado do cliente pode forjar um pacote com um endereço IP falso porque não precisa de uma resposta. O sistema do servidor irá adicionar uma entrada na fila de conexões parcialmente abertas quando recebe o pacote SYN e esperar o pacote ACK final antes de apagar a entrada da fila. A fila tem um número limitado de vagas e se todas vagas estiverem preenchidas antes de um tempo de espera especificado, a entrada será automaticamente apagada da fila. Os ajustes de espera variam, mas são tipicamente de 30-60 segundos ou até mais. O lado do cliente inicia o ataque forjando vários pacotes SYN com endereços IP de fontes diferentes e enviando-os para o endereço IP alvo o mais rápido possível, preenchendo a fila de conexões parcialmente abertas, impedindo que outros clientes estabeleçam conexões legítimas com o servidor.

Aqui é onde o limite de taxas torna-se útil. É possível limitar a taxa de pacotes SYN aceitos usando -m limit --limit 1/s. Isto irá limitar o número de pacotes SYN aceitos para um por segundo e portanto restringir o SYN flood em nossos recursos.

Nota: Outra opção para impedir SYN floods são os SYN cookies, que permitem que seu computador responda a pacotes de SYN sem preencher espaço na fila de conexões. SYN cookies podem ser ativados na configuração do kernel do Linux, mas eles são considerados experimentais no momento.

Algumas coisas práticas agora!

Quando o iptables é carregado no kernel ele tem 5 ganchos onde você pode colocar suas regras. São chamados INPUT, OUTPUT, FORWARD, PREROUTING e POSTROUTING. Cada um deles é chamado de uma cadeia e consiste de uma lista de regras. Cada regra diz se o cabeçalho do pacote parecer-se com isso, aqui está o que fazer com o pacote. Se a regra não bater com o pacote, a próxima regra da cadeia é consultada.

Você pode colocar as regras diretamente nas 5 cadeias principais ou criar novas cadeias e adicioná-las como uma regra para uma cadeia existente. O Iptables suporta as seguintes opções.

Opção: Descrição:
-A Anexar
-D Apagar
-I Inserir
-R Trocar
-L Listar
-F Apagar todas regras na cadeia ou todas cadeias
-Z Zerar contadores na cadeia ou todas cadeias
-C Testar este pacote na cadeia
-N Criar uma nova cadeia definida por usuário
-X Apagar uma cadeia definida por usuário
-P Mudar política na cadeia alvo
-E Mudar nome da cadeia
-p Protocolo
-s Endereço de fonte/máscara
-d Endereço de destino/máscara
-i Nome da entrada (nome de ethernet)
-o Nome de saída (nome de ethernet)
-j Pular (alvo para regra)
-m Relação estendida (pode usar extensão)
-n Saída numérica de endereços e portas
-t Tabela para manipular
-v Modo verbal
-x Expandir números (mostrar valores exatos)
-f Fazer relação só do segundo fragmento e posteriores
-V Versão do pacote
--line-numbers Mostrar número das linhas quando listando

Primeiro iremos experimentar bloquear todos pacotes ICMP em nossa máquina, só para ficarmos familiares com o iptables.

Listagem de código 5.1: Bloquear todos pacotes ICMP

# iptables -A INPUT -p icmp -j DROP

Primeiro especificamos a cadeia a que nossa regra deve ser anexada, depois o protocolo dos pacotes para relacionar, e finalmente o alvo. O alvo pode ser o nome de uma cadeia especificado pelo usuário ou um dos alvos especiais ACCEPT, DROP, REJECT, LOG, QUEUE, ou MASQUERADE. Neste caso nós usamos DROP, que irá ignorar o pacote sem responder para o cliente.

Nota: O alvo LOG também é o que conhecido como "não-terminante". Se o pacote relacionar-se com uma regra do alvo LOG, ao invés de parar a avaliação, o pacote continuará a ser relacionado com outros filtros. Isto permite registrar pacotes e ainda processá-los normalmente.

Agora experimente ping localhost. Você não irá receber nenhuma resposta, já que o iptables irá ignorar todas mensagens de ICMP que chegarem. Você também não poderá fazer ping de outras máquinas, já que o pacote de respostas ICMP será ignorado também. Agora limpe a cadeia para iniciar o fluxo de ICMP novamente.

Listagem de código 5.2: Limpando todas regras

# iptables -F

Agora vamos olhar o filtro de pacotes stateful no iptables. Se nós quiséssemos ativar a inspeção stateful de pacotes chegando na eth0, nós faríamos o seguinte comando:

Listagem de código 5.3: Aceitar pacotes oriundos de uma conexão já estabelecida

# iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

Isto irá aceitar qualquer pacote de uma conexão já estabelecida ou relacionada na cadeia INPUT. E você pode ignorar qualquer pacote que já não estiver na tabela de estados rodando iptables -A INPUT -i eth0 -m state --state INVALID -j DROP antes do comando anterior. Isto ativa o filtro de pacotes stateful no iptables carregando a extensão "state". Se você quisesse permitir que outros conectem-se a sua máquina, você pode usar a opção --state NEW. O Iptables contém alguns módulos para propósitos diferentes. Alguns deles são:

Módulo/Relação Descrição Opções extendidas
mac Extensão de relação para o endereço de mac dos pacotes que chegam. --mac-source
state Ativa inspeção stateful --state (estados são ESTABLISHED,RELATED, INVALID, NEW)
limit Limite de taxas de relação --limit, --limit-burst
owner Tentar relacionar várias características do dono do pacote --uid-owner userid --gid-owner groupid --pid-owner processid --sid-owner sessionid
unclean Várias verificações de sanidade dos pacotes

Vamos tentar criar uma cadeia definida por usuário e aplicá-la a uma das cadeias existentes:

Listagem de código 5.4: Criando uma cadeia definida por usuário

(Crie uma nova cadeia com uma regra)
# iptables -X minhacadeia
# iptables -N minhacadeia
# iptables -A minhacadeia -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
(A política padrão é que todo tráfego para fora é permitido. Todo tráfego de entrada é ignorado.)
# iptables -P OUTPUT ACCEPT
# iptables -P INPUT DROP
(E adicione à cadeia INPUT)
# iptables -A INPUT -j minhacadeia

Aplicando a regra à cadeia input nós obtemos a política: Todos pacotes saindo são permitidos e todos entrando são ignorados.

Pode-se encontrar documentação em Netfilter/iptables documentation.

Vamos ver um exemplo completo. Neste caso minha política de firewall/roteador diz:

  • Conexões para a firewall só são permitidas através de SSH (porta 22)
  • A rede local deve ter acesso a HTTP, HTTPS e SSH (DNS também deve ser permitido)
  • tráfego de ICMP pode conter payload e não deve ser permitido. Claro que temos de permitir um certo tráfego de ICMP.
  • Escaneamentos de portas devem ser detectados e registrados
  • Ataques de SYN devem ser evitados
  • Todo outro tráfego deve ser ignorado e registrado

Listagem de código 5.5: /etc/init.d/firewall

#!/sbin/runscript
IPTABLES=/sbin/iptables
IPTABLESSAVE=/sbin/iptables-save
IPTABLESRESTORE=/sbin/iptables-restore
FIREWALL=/etc/firewall.rules
DNS1=212.242.40.3
DNS2=212.242.40.51
#inside
IIP=10.0.0.2
IINTERFACE=eth0
LOCAL_NETWORK=10.0.0.0/24
#outside
OIP=217.157.156.144
OINTERFACE=eth1

opts="${opts} showstatus panic save restore showoptions rules"

depend() {
  need net
}

rules() {
  stop
  ebegin "Configurando regras internas"

  einfo "Configurando o padrão para negar"
  $IPTABLES -P FORWARD DROP
  $IPTABLES -P INPUT   DROP
  $IPTABLES -P OUTPUT  DROP

  #regra padrão
  einfo "Criando cadeias de estados"
  $IPTABLES -N allowed-connection
  $IPTABLES -F allowed-connection
  $IPTABLES -A allowed-connection -m state --state ESTABLISHED,RELATED -j ACCEPT
  $IPTABLES -A allowed-connection -i $IINTERFACE -m limit -j LOG --log-prefix \ 
      "Pacote ruim de ${IINTERFACE}:"
  $IPTABLES -A allowed-connection -j DROP

  #tráfego de ICMP
  einfo "Criando cadeia de icmp"
  $IPTABLES -N icmp_allowed
  $IPTABLES -F icmp_allowed
  $IPTABLES -A icmp_allowed -m state --state NEW -p icmp --icmp-type \ 
      time-exceeded -j ACCEPT
  $IPTABLES -A icmp_allowed -m state --state NEW -p icmp --icmp-type \ 
      destination-unreachable -j ACCEPT
  $IPTABLES -A icmp_allowed -p icmp -j LOG --log-prefix "tráfego ruim de ICMP:"
  $IPTABLES -A icmp_allowed -p icmp -j DROP

  #tráfego de entrada
  einfo "Criando uma cadeia para tráfego ssh de entrada"
  $IPTABLES -N allow-ssh-traffic-in
  $IPTABLES -F allow-ssh-traffic-in
  #proteção de flood
  $IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \ 
      ALL RST --dport ssh -j ACCEPT
  $IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \ 
      ALL FIN --dport ssh -j ACCEPT
  $IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \ 
      ALL SYN --dport ssh -j ACCEPT
  $IPTABLES -A allow-ssh-traffic-in -m state --state RELATED,ESTABLISHED -p tcp --dport ssh -j ACCEPT

  #tráfego de saída
  einfo "Criando uma cadeia para tráfego ssh de saída"
  $IPTABLES -N allow-ssh-traffic-out
  $IPTABLES -F allow-ssh-traffic-out
  $IPTABLES -A allow-ssh-traffic-out -p tcp --dport ssh -j ACCEPT

  einfo "Criando cadeia de saída de dns"
  $IPTABLES -N allow-dns-traffic-out
  $IPTABLES -F allow-dns-traffic-out
  $IPTABLES -A allow-dns-traffic-out -p udp -d $DNS1 --dport domain \ 
      -j ACCEPT
  $IPTABLES -A allow-dns-traffic-out -p udp -d $DNS2 --dport domain \ 
     -j ACCEPT

  einfo "Criando cadeia de tráfego de saída http/https"
  $IPTABLES -N allow-www-traffic-out
  $IPTABLES -F allow-www-traffic-out
  $IPTABLES -A allow-www-traffic-out -p tcp --dport www -j ACCEPT
  $IPTABLES -A allow-www-traffic-out -p tcp --dport https -j ACCEPT

  #Pegar escaneadores de porta
  einfo "Criando cadeia de detecção de escaneamento de portas"
  $IPTABLES -N check-flags
  $IPTABLES -F check-flags
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL FIN,URG,PSH -m limit \ 
      --limit 5/minute -j LOG --log-level alert --log-prefix "NMAP-XMAS:" 
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL ALL -m limit --limit \ 
      5/minute -j LOG --log-level 1 --log-prefix "XMAS:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL ALL -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG \ 
      -m limit --limit 5/minute -j LOG --log-level 1 --log-prefix "XMAS-PSH:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL NONE -m limit \ 
      --limit 5/minute -j LOG --log-level 1 --log-prefix "NULL_SCAN:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL NONE -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,RST SYN,RST -m limit \ 
      --limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/RST:"
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit \ 
      --limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/FIN:"
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP

  # Aplicar a adicionar estados inválidos às redes
  einfo "Aplicando as cadeias a INPUT"
  $IPTABLES -A INPUT -m state --state INVALID -j DROP
  $IPTABLES -A INPUT -j icmp_allowed 
  $IPTABLES -A INPUT -j check-flags
  $IPTABLES -A INPUT -i lo -j ACCEPT
  $IPTABLES -A INPUT -j allow-ssh-traffic-in
  $IPTABLES -A INPUT -j allowed-connection

  einfo "Aplicando as cadeias a FORWARD"
  $IPTABLES -A FORWARD -m state --state INVALID -j DROP
  $IPTABLES -A FORWARD -j icmp_allowed 
  $IPTABLES -A FORWARD -j check-flags
  $IPTABLES -A FORWARD -o lo -j ACCEPT
  $IPTABLES -A FORWARD -j allow-ssh-traffic-in
  $IPTABLES -A FORWARD -j allow-www-traffic-out
  $IPTABLES -A FORWARD -j allowed-connection

  einfo "Aplicando as cadeias a OUTPUT"
  $IPTABLES -A OUTPUT -m state --state INVALID -j DROP
  $IPTABLES -A OUTPUT -j icmp_allowed
  $IPTABLES -A OUTPUT -j check-flags
  $IPTABLES -A OUTPUT -o lo -j ACCEPT
  $IPTABLES -A OUTPUT -j allow-ssh-traffic-out
  $IPTABLES -A OUTPUT -j allow-dns-traffic-out
  $IPTABLES -A OUTPUT -j allow-www-traffic-out
  $IPTABLES -A OUTPUT -j allowed-connection

  #Permitir que o cliente roteie através de NAT (Network Address Translation)
  $IPTABLES -t nat -A POSTROUTING -o $IINTERFACE -j MASQUERADE 
  eend $?
}

start() {
  ebegin "Iniciando firewall"
  if [ -e "${FIREWALL}" ]; then
    restore
  else
    einfo "${FIREWALL} não existe. Usando regras padrão."
    rules
  fi
  eend $?
}

stop() {
  ebegin "Parando firewall"
  $IPTABLES -F
  $IPTABLES -t nat -F
  $IPTABLES -X
  $IPTABLES -P FORWARD ACCEPT
  $IPTABLES -P INPUT   ACCEPT
  $IPTABLES -P OUTPUT  ACCEPT
  eend $?
}

showstatus() {
  ebegin "Status"
  $IPTABLES -L -n -v --line-numbers
  einfo "status de NAT"
  $IPTABLES -L -n -v --line-numbers -t nat
  eend $?
}

panic() {
  ebegin "Configurando regras de pânico"
  $IPTABLES -F
  $IPTABLES -X
  $IPTABLES -t nat -F
  $IPTABLES -P FORWARD DROP
  $IPTABLES -P INPUT   DROP
  $IPTABLES -P OUTPUT  DROP
  $IPTABLES -A INPUT -i lo -j ACCEPT
  $IPTABLES -A OUTPUT -o lo -j ACCEPT
  eend $?
}

save() {
  ebegin "Salvando regras de firewall"
  $IPTABLESSAVE > $FIREWALL
  eend $?
}

restore() {
  ebegin "Restaurando regras de firewall"
  $IPTABLESRESTORE < $FIREWALL
  eend $?
}

restart() {
  svc_stop; svc_start
}

showoptions() {
  echo "Uso: $0 {start|save|restore|panic|stop|restart|showstatus}"
  echo "start)      irá restaurar ajuste se existir, caso contrário criar regras"
  echo "stop)       apagar todas regras e aceitar tudo"
  echo "rules)      forçar a configuração de novas regras"
  echo "save)       gravar configuraçõe em ${FIREWALL}"
  echo "restore)    restaurar configurações de ${FIREWALL}"
  echo "showstatus) Mostrar o status" 
}

Conselhos antes de criar uma firewall:

  1. Crie uma política de firewall antes de implementá-la
  2. Mantenha simples
  3. Conheça como cada protocolo funciona (leia o RFC(Request For Comments) relevante)
  4. Tenha em mente que uma firewall é só outro software rodando como administrador (root).
  5. Teste sua firewall

Se você acha que o iptables é difícil de entender ou leva muito tempo para configurar uma boa firewall, você pode usar o Shorewall. Ele basicamente usa o iptables para gerar regras de firewall, mas é concentrado em regras e não protocolos específicos.

12.f. Squid

O Squid é um servidor de proxy muito poderoso. Ele pode filtrar tráfego com base em hora, expressões regulares (regex) sobre caminho/URI, endereço IP de fonte e destino, domínio, navegador, usuário autenticado, tipo de MIME, e número de porta (protocolo). Eu provavelmente esqueci de algumas funcionalidades, mas é difícil cobrir a lista inteira aqui.

No seguinte exemplo eu adicionei um filtro de banner ao invés de um filtro baseado em sites pornôs. A razão para tanto é que Gentoo.org não deve ser listado como um site pornô. E eu não quero perder meu tempo tentando descobrir alguns sites bons para você.

Neste caso, minha política diz:

  • Navegar (HTTP/HTTPS) é permitido durante horas de trabalho (segunda-sexta 8-17 e sábado 8-13), mas se os empregados chegarem aqui atrasados devem trabalhar, não navegar
  • Baixar arquivos não é permitido (.exe, .com, .arj, .zip, .asf, .avi, .mpg, .mpeg, etc)
  • Não gostamos de banners, então eles são filtrados e substituídos com um gif transparente (aqui é onde você deve ser criativo!).
  • Todas outras conexões para e da Internet devem ser negadas.

Isto é implementado em 4 passos fáceis.

Listagem de código 6.1: /etc/squid/squid.conf

# Prender em um ip e porta
http_port 10.0.2.1:3128

# Configuração padrão
hierarchy_stoplist cgi-bin ?
acl QUERY urlpath_regex cgi-bin \?
no_cache deny QUERY

# Listas de controle de acesso básicas
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255

# Adicionar quem pode acessar este servidor de proxy
acl localnet src 10.0.0.0/255.255.0.0

# E portas
acl SSL_ports port 443
acl Safe_ports port 80
acl Safe_ports port 443
acl purge method PURGE

# Adicionar lista de controle de acesso com base em expressões
# regulares (regex) dentro de urls
acl archives urlpath_regex "/etc/squid/files.acl"
acl url_ads url_regex "/etc/squid/banner-ads.acl"

# Adicionar lista de acesso de controle com base em hora e dia
acl restricted_weekdays time MTWHF 8:00-17:00
acl restricted_weekends time A 8:00-13:00

acl CONNECT method CONNECT

#permitir acesso do manager do localhost
http_access allow manager localhost
http_access deny manager

# Só permitir pedidos de purge do localhost
http_access allow purge localhost
http_access deny purge

# Negar pedidos em portas desconhecidas
http_access deny !Safe_ports

# Negar CONNECT fora portas de SSL
http_access deny CONNECT !SSL_ports

# Minhas próprias regras

# Adicionar uma página a ser mostrada quando
# um banner for removido
deny_info NOTE_ADS_FILTERED url_ads

# Então negá-los
http_access deny url_ads

# Negar todos arquivos
http_access deny archives

# Restringir acesso a horas de trabalho
http_access allow localnet restricted_weekdays
http_access allow localnet restricted_weekends

# Negar o resto
http_access deny all

A seguir preencha os arquivos que você não quer que seus usuários baixem. Eu adicionei arquivos zip, viv, exe, mp3, rar, ace, avi, mov, mpg, mpeg, au, ra, arj, tar, gz e z.

Listagem de código 6.2: /etc/squid/files.acl

\.[Zz][Ii][pP]$
\.[Vv][Ii][Vv].*
\.[Ee][Xx][Ee]$
\.[Mm][Pp]3$
\.[Rr][Aa][Rr]$
\.[Aa][Cc][Ee]$
\.[Aa][Ss][Ff]$
\.[Aa][Vv][Ii]$
\.[Mm][Oo][Vv]$
\.[Mm][Pp][Gg]$
\.[Mm][Pp][Ee][Gg]$
\.[Aa][Uu]$
\.[Rr][Aa]$
\.[Aa][Rr][Jj]$
\.[Tt][Aa][Rr]$
\.[Gg][Zz]$
\.[Zz]$

Nota: Por favor note o [] com letras maiúsculas e minúsculas para cada caractere. Isto é feito para ninguém enganar nosso filtro acessando um arquivo chamado AvI ao invés de avi

A seguir nós adicionamos as expressões regulares (regex) para identificar banners. Você será provavelmente mais criativo que eu:

Listagem de código 6.3: /etc/squid/banner-ads.acl

/adv/.*\.gif$
/[Aa]ds/.*\.gif$
/[Aa]d[Pp]ix/
/[Aa]d[Ss]erver
/[Aa][Dd]/.*\.[GgJj][IiPp][FfGg]$
/[Bb]annerads/
/adbanner.*\.[GgJj][IiPp][FfGg]$
/images/ad/
/reklame/
/RealMedia/ads/.*
^http://www\.submit-it.*
^http://www\.eads.*
^http://ads\.
^http://ad\.
^http://ads02\.
^http://adaver.*\.
^http://adforce\.
adbot\.com
/ads/.*\.gif.*
_ad\..*cgi
/Banners/
/SmartBanner/
/Ads/Media/Images/
^http://static\.wired\.com/advertising/
^http://*\.dejanews\.com/ads/
^http://adfu\.blockstackers\.com/
^http://ads2\.zdnet\.com/adverts
^http://www2\.burstnet\.com/gifs/
^http://www.\.valueclick\.com/cgi-bin/cycle
^http://www\.altavista\.com/av/gifs/ie_horiz\.gif

E como a parte final nós queremos que este arquivo seja mostrado quando um banner for removido. É basicamente meio arquivo html com uma imagem gif 4x4 transparente.

Listagem de código 6.4: /etc/squid/errors/NOTE_ADS_FILTERED

<HTML>
<HEAD>
<META HTTP-EQUIV="REFRESH" CONTENT="0; URL=http://localhost/images/4x4.gif">
<TITLE>ERRO: A URL pedida não pode ser obtida</TITLE>
</HEAD>
<BODY>
<H1>Anúncio filtrado!</H1>

Nota: Não feche as tags <HTML> <BODY>. O squid fará isso.

Como você pode ver, o Squid tem muitas possibilidades e é muito eficiente tanto como filtro, como proxy. Ele pode até mesmo usar proxies de Squid alternativos para escalabilidade em redes muito grandes. A configuração que eu listei aqui serve para uma pequena rede com 1-20 usuários.

Mas combinar o filtro de pacotes (iptables) e a aplicação roteadora (Squid) é provavelmente a melhor solução, mesmo se o Squid está localizado em um lugar seguro e ninguém puder acessá-lo de fora. Nós ainda precisamos nos preocupar com ataques do interior.

Agora você tem que configurar os navegadores de seus clientes para usar o servidor de proxy. O roteador impedirá que usuários façam contato com o exterior se não usarem o proxy.

Nota: No Mozilla isto é feito em Editar->Preferências->Avançado->Proxies.

Isto também pode ser feito transparentemente usando o iptables para encaminha todo tráfego de saída para o proxy do Squid. Isto pode ser feito adicionando uma regra de encaminhamento/pré-roteamento no roteador:

Listagem de código 6.5: Permitir encaminhamento de portas para nosso servidor de proxy

# iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to proxyhost:3128
# iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to proxyhost:3128

Nota: Se o proxy estiver rodando no host que filtra pacotes--embora não seja recomendado, pode ser necessário se você não tiver máquinas sobrando--use um alvo REDIRECT ao invés de DNAT (REDIRECT dirige os pacotes para o localhost).

12.g. Lições aprendidas

Nós aprendemos que:

  1. Uma firewall pode ser um risco em si mesma. Uma firewall mal configurada é pior que não ter nenhuma.
  2. Como configurar um roteador básico e proxy transparente.
  3. A chave para uma boa firewall é conhecer os protocolos que você quer permitir.
  4. Que tráfego de IP nem sempre contém dados legítimos, como pacotes ICMP, que podem conter um payload malicioso.
  5. Como prevenir um ataque SYN.
  6. Filtrar tráfego HTTP removendo gravuras ofensivas e downloads de vírus.
  7. Combinar filtros de pacotes e roteadores de aplicações dá melhor controle.

Agora, se você realmente precisar, crie uma firewall que atenda às suas necessidades.

13. Detecção de instrusão

13.a. AIDE (Advanced Intrusion Detection Environment)

AIDE é um sistema de detecção de intrusão baseada em hosts (HIDS), uma alternativa gratuita para o Tripwire (se você já conhece o Tripwire, você não deverá ter dificuldades para aprender o arquivo de configuração do AIDE). HIDS são usados para detectar mudanças em arquivos de configuração de sistema e binários importantes, geralmente fazendo um hash criptográfico singular para os arquivos a serem verificados e guardando-os em um lugar seguro. Com freqüência (como uma vez por dia), o hash "conhecido" guardado é comparado com o gerado pela cópia atual de cada arquivo, para determinar se o arquivo mudou. HIDS são uma grande maneira de detectar mudanças não permitidas a seu sistema, mas dão um pouco de trabalho para implementar adequadamente e tirar proveito.

O arquivo de configuração é baseado em expressões regulares (regex), macros e regras para arquivos e diretórios. Nós temos as seguintes macros:

Macro Descrição Sintaxe
ifdef Se definido @@ifdef "nome"
ifndef Se não definido @@ifndef "nome"
define Definir uma variável @@define "nome" "valor"
undef Cancelar uma variável @@undef "nome"
ifhost se "hostname" @@ifhost "hostname"
ifnhost se não "hostname" @@ifnhost "hostname"
endif Endif deve ser usado depois de qualquer uma das macros acima fora define e undef @@endif

Estas macros tornam-se úteis se você tem mais de uma máquina rodando Gentoo e quer usar AIDE em todas elas. Mas nem todas máquinas rodam os mesmos serviços ou têm os mesmos usuários.

A seguir temos conjuntos de opções para verificar arquivos e diretórios. Eles são uma combinação de permissões, propriedades de arquivo e hashes criptográficos (isto é, checksums).

Opção Descrição
p permissões
i inode
n número de links
u usuário
g grupo
s tamanho
b contagem de bloco
m mtime
a atime
c ctime
S verificar tamanho crescente
md5 checksum de md5
sha1 checksum de sha1
rmd160 checksum de rmd160
tiger checksum de tiger
R p+i+n+u+g+s+m+c+md5
L p+i+n+u+g
E Grupo vazio
> Arquivo de registro crescente p+u+g+i+n+S

E se o AIDE for compilado com suporte a mhash ele suporta algumas funções a mais:

Opção Descrição
haval checksum de haval
gost checksum de gost
crc32 checksum de crc32

Agora crie suas próprias regras com base nas opções acima combinando-as da seguinte maneira:

Listagem de código 1.1: Criando conjunto de regras para o AIDE

All=R+a+sha1+rmd160
Norm=s+n+b+md5+sha1+rmd160

A última coisa de que precisamos para criar nosso arquivo de configuração é ver como adicionar uma regra a um arquivo ou diretório. Para entrar com uma regra, combine o nome de arquivo ou diretório e a regra. O AIDE irá adicionar todos arquivos recursivamente a menos que você especifique uma regra alternativa.

Opção Descrição
! Não adicionar este arquivo ou diretório.
= Adicionar este diretório, mas não recursivamente.

Então vamos ver um exemplo completo:

Listagem de código 1.2: /etc/aide/aide.conf

@@ifndef TOPDIR 
@@define TOPDIR /
@@endif

@@ifndef AIDEDIR 
@@define AIDEDIR /etc/aide
@@endif

@@ifhost smbserv
@@define smbactive
@@endif

# O local do banco de dados a ser lida.
database=file:@@{AIDEDIR}/aide.db

# O local do banco de dados a ser gravado.
database_out=file:aide.db.new

verbose=20
report_url=stdout

# Definição de regras
All=R+a+sha1+rmd160
Norm=s+n+b+md5+sha1+rmd160

@@{TOPDIR} Norm
!@@{TOPDIR}etc/aide
!@@{TOPDIR}dev
!@@{TOPDIR}proc
!@@{TOPDIR}root
!@@{TOPDIR}tmp
!@@{TOPDIR}var/log
!@@{TOPDIR}var/run
!@@{TOPDIR}usr/portage
@@ifdef smbactive
!@@{TOPDIR}etc/smb/private/secrets.tdb
@@endif
=@@{TOPDIR}home Norm

No exemplo acima nós especificamos algumas macros onde o topdir começa e onde o diretório do AIDE está. O AIDE verifica o arquivo /etc/aide/aide.db para verificar a integridade de arquivo. Mas quando estiver atualizando ou criando um novo arquivo, ele grava a informação em /etc/aide/aide.db.new. Isto é feito para que ele não sobre-escreva o arquivo db antigo automaticamente. A opção report_URL ainda não está implementada, mas a intenção do autor era poder enviar e-mail ou talvez até executar scripts.

A ebuild do AIDE agora vem com um arquivo de configuração padrão que funciona, um script de ajuda e um script de crontab. O script de ajuda faz algumas tarefas para você e oferece uma interface que um pouco mais amigável a scripts. Para ver todas opções disponíveis, experimente aideinit --help. Para começar, tudo que precisa ser feito é aideinit -i e o script de crontab deve detectar o banco de dados e enviar correio devidamente todo dia. Nós recomendamos que você revise o arquivo /etc/aide/aide.conf e certifique-se que a configuração reflete precisamente o que está em sua máquina.

Nota: Dependendo da sua CPU, velocidade de acesso a disco, e opções use que você tem nos arquivos, isto pode levar um tempo.

Nota: Lembre-se de configurar um alias para que você receber o correio do root. Senão, você nunca saberá quando o AIDE der notícias.

Há um risco inerente em gravar os arquivos db localmente, já que o indivíduo malicioso irá (se souberem que o AIDE está instalado) quase certamente tentar alterar o arquivo db, atualizar o arquivo db ou modificar /usr/bin/aide. Portanto, você deve criar um CD ou outra mídia e colocar uma cópia do arquivo .db e binário do AIDE.

Pode-se encontrar mais informações na página de projeto do AIDE.

13.b. Snort

Snort é um sistema de detecção de intrusão de rede (NIDS). Para instalar e configurá-lo, use os seguintes exemplos.

Listagem de código 2.1: /etc/conf.d/snort

PIDFILE=/var/run/snort_eth0.pid
MODE="full"
NETWORK="10.0.0.0/24"
LOGDIR="/var/log/snort"
CONF=/etc/snort/snort.conf
SNORT_OPTS="-D -s -u snort -dev -l $LOGDIR -h $NETWORK -c $CONF"

Listagem de código 2.2: /etc/snort/snort.conf

(Passo 1)
var HOME_NET 10.0.0.0/24
var EXTERNAL_NET any
var SMTP $HOME_NET
var HTTP_SERVERS $HOME_NET
var SQL_SERVERS $HOME_NET
var DNS_SERVERS [10.0.0.2/32,212.242.40.51/32]
var RULE_PATH ./

(Passo 2)
preprocessor frag2
preprocessor stream4: detect_scans detect_state_problems detect_scans disable_evasion_alerts
preprocessor stream4_reassemble: ports all
preprocessor http_decode: 80 8080 unicode iis_alt_unicode double_encode iis_flip_slash full_whitespace
preprocessor rpc_decode: 111 32771
preprocessor bo: -nobrute
preprocessor telnet_decode

(Passo 3)
include classification.config

(Passo 4)
include $RULE_PATH/bad-traffic.rules
include $RULE_PATH/exploit.rules
include $RULE_PATH/scan.rules
include $RULE_PATH/finger.rules
include $RULE_PATH/ftp.rules
include $RULE_PATH/telnet.rules
include $RULE_PATH/smtp.rules
include $RULE_PATH/rpc.rules
include $RULE_PATH/rservices.rules
include $RULE_PATH/dos.rules
include $RULE_PATH/ddos.rules
include $RULE_PATH/dns.rules
include $RULE_PATH/tftp.rules
include $RULE_PATH/web-cgi.rules
include $RULE_PATH/web-coldfusion.rules
include $RULE_PATH/web-iis.rules
include $RULE_PATH/web-frontpage.rules
include $RULE_PATH/web-misc.rules
include $RULE_PATH/web-attacks.rules
include $RULE_PATH/sql.rules
include $RULE_PATH/x11.rules
include $RULE_PATH/icmp.rules
include $RULE_PATH/netbios.rules
include $RULE_PATH/misc.rules
include $RULE_PATH/attack-responses.rules
include $RULE_PATH/backdoor.rules
include $RULE_PATH/shellcode.rules
include $RULE_PATH/policy.rules
include $RULE_PATH/porn.rules
include $RULE_PATH/info.rules
include $RULE_PATH/icmp-info.rules
include $RULE_PATH/virus.rules
# include $RULE_PATH/experimental.rules
include $RULE_PATH/local.rules

Listagem de código 2.3: /etc/snort/classification.config

config classification: not-suspicious,Not Suspicious Traffic,3
config classification: unknown,Unknown Traffic,3
config classification: bad-unknown,Potentially Bad Traffic, 2
config classification: attempted-recon,Attempted Information Leak,2
config classification: successful-recon-limited,Information Leak,2
config classification: successful-recon-largescale,Large Scale Information Leak,2
config classification: attempted-dos,Attempted Denial of Service,2
config classification: successful-dos,Denial of Service,2
config classification: attempted-user,Attempted User Privilege Gain,1
config classification: unsuccessful-user,Unsuccessful User Privilege Gain,1
config classification: successful-user,Successful User Privilege Gain,1
config classification: attempted-admin,Attempted Administrator Privilege Gain,1
config classification: successful-admin,Successful Administrator Privilege Gain,1

# NOVAS CLASSIFICAÇÕES
config classification: rpc-portmap-decode,Decode of an RPC Query,2
config classification: shellcode-detect,Executable code was detected,1
config classification: string-detect,A suspicious string was detected,3
config classification: suspicious-filename-detect,A suspicious filename was detected,2
config classification: suspicious-login,An attempted login using a suspicious username was detected,2
config classification: system-call-detect,A system call was detected,2
config classification: tcp-connection,A TCP connection was detected,4
config classification: trojan-activity,A Network Trojan was detected, 1
config classification: unusual-client-port-connection,A client was using an unusual port,2
config classification: network-scan,Detection of a Network Scan,3
config classification: denial-of-service,Detection of a Denial of Service Attack,2
config classification: non-standard-protocol,Detection of a non-standard protocol or event,2
config classification: protocol-command-decode,Generic Protocol Command Decode,3
config classification: web-application-activity,access to a potentially vulnerable web application,2
config classification: web-application-attack,Web Application Attack,1
config classification: misc-activity,Misc activity,3
config classification: misc-attack,Misc Attack,2
config classification: icmp-event,Generic ICMP event,3
config classification: kickass-porn,SCORE! Get the lotion!,1

Mais informações no website do Snort.

13.c. Detectando malware com o chkrootkit

HIDS como o AIDE são um bom jeito de detectar mudanças em seu sistema, mas nunca faz mal ter outra linha de defesa. O chkrootkit é um utilitário que varre arquivos de sistema comuns procurando a presença de rootkits--software desenhado para esconder as ações de um invasor e permitir a ele manter seu acesso--e escaneia seu sistema por traços prováveis de gravadores de teclas e outros "malware". Enquanto o chkrootkit (e alternativas como o rkhunter) são ferramentas úteis, tanto para a manutenção de sistema quanto para rastrear um intruso depois que um ataque aconteceu, eles não podem garantir que seu sistema está seguro.

O melhor jeito de usar o chkrootkit para detectar uma invasão é rodá-lo rotineiramente como cron. Para iniciar, faça emerge app-admin/chkrootkit. O chkrootkit pode ser rodado da linha de comando com o comando de mesmo nome, ou do cron com uma entrada parecida com o seguinte:

Listagem de código 3.1: Agendar chkrootkit como um cronjob

0 3 * * * /usr/sbin/chkrootkit

14. Mantendo-se atualizado

14.a. Mantendo-se atualizado

Mesmo depois que você instalou seu sistema com sucesso e garantiu um bom nível de segurança, o trabalho ainda não acabou. A segurança é um processo contínuo; a vasta maioria das invasões resultam de vulnerabilidades conhecidas em sistemas não atualizados. Manter seu sistema atualizado é o passo mais importante que você pode tomar para garantir a segurança.

Se você tiver uma versão recente do portage instalada, você pode primeiro sincronizar sua árvore do portage com emerge --sync e depois rodar o comando glsa-check --list para verificar se seu sistema está atualizado com relação à segurança. glsa-check faz parte de app-portage/gentoolkit.

Listagem de código 1.1: Exemplo de saída de glsa-check -l

# glsa-check -l
WARNING: This tool is completely new and not very tested, so it should not be
used on production systems. It's mainly a test tool for the new GLSA release
and distribution system, it's functionality will later be merged into emerge
and equery.
Please read http://www.gentoo.org/proj/en/portage/glsa-integration.xml
before using this tool AND before reporting a bug.

[A] means this GLSA was already applied,
[U] means the system is not affected and
[N] indicates that the system might be affected.

200406-03 [N] sitecopy: Multiple vulnerabilities in included libneon ( net-misc/sitecopy )
200406-04 [U] Mailman: Member password disclosure vulnerability ( net-mail/mailman )
.......

Aviso: O glsa-check ainda é experimental. Portanto, se a segurança realmente é sua maior prioridade, é aconselhável verificar a lista com outras fontes.

Todas linhas com um [A] e [U] podem quase seguramente ser ignoradas, já que o sistema não é afetado por essas GLSA.

Importante: Por favor, note que o comando emerge -vpuD world não irá pegar todas atualizações de pacotes disponíveis. Você precisa usar glsa-check se você quiser ter certeza de que todas GLSAs estão reparadas em seu sistema.

Listagem de código 1.2: Verificar todas GLSAs

(Verificar se seu sistema é afetado por GLSAs)
# glsa-check -t all
WARNING: This tool is completely new and not very tested, so it should not be
used on production systems. It's mainly a test tool for the new GLSA release
and distribution system, it's functionality will later be merged into emerge
and equery.
Please read http://www.gentoo.org/proj/en/portage/glsa-integration.xml
before using this tool AND before reporting a bug.

This system is affected by the following GLSA:
200504-06
200510-08
200506-14
200501-35
200508-12
200507-16

(Ver que pacotes seriam instalados)
# glsa-check -p $(glsa-check -t all)
     (saída parcial)
Checking GLSA 200504-06
The following updates will be performed for this GLSA:
     app-arch/sharutils-4.2.1-r11 (4.2.1-r10)

     **********************************************************************

     Checking GLSA 200510-08
     The following updates will be performed for this GLSA:
          media-libs/xine-lib-1.1.0-r5 (1.1.0-r4)

(Aplicar consertos necessários)
# glsa-check -f $(glsa-check -t all)

Se você atualizou um serviço que está rodando, não se esqueça de reiniciá-lo.

Manter seu kernel atualizado também é recomendado.

Se você quiser receber um e-mail cada vez que uma GLSA for lançada, inscreva-se na listagem de e-mails do gentoo-announce. Instruções para inscrever-se e outras boas listagens de e-mail podem ser encontradas em Visão geral das listagens de e-mail do Gentoo Linux.

Outro bom recurso de segurança é aListagem de e-mails do Bugtraq.

Imprimir

Atualizado 26 de dezembro de 2005

A versão original deste documento foi atualizada em 31 de março de 2012

Resumo: Este é um guia passo-a-passo para tornar o Gentoo Linux mais seguro.

Kim Nielsen
Autor

John P. Davis
Editor

Eric R. Stockbridge
Editor

Carl Anderson
Editor

Jorge Paulo
Editor

Sven Vermeulen
Editor

Benny Chuang
Editor

Sune Jeppesen
Editor

Tiemo Kieft
Editor

Zack Gilburd
Editor

Dan Margolis
Editor

Marcelo Góes
Tradutor

Donate to support our development efforts.

Copyright 2001-2013 Gentoo Foundation, Inc. Questions, Comments? Contact us.