Segurança no slackware

By Claudio Borges aka but3k4
Versao 2.4, Sat Sep 22 13:56:04 2007



Segurança

Segurança é algo que todo admin deveria ter como prioridade. Falhas podem existir em todo sistema, já que os mesmos são feitos por programadores e esses programadores são humanos e humanos são falíveis.

Muitos pensam que por estar usando linux ou bsd, estão seguros. A segurança é feita pelo administrador. Lógico que existem sistemas cujas instalações default os torna mais vulneráveis que outros.

Definir uma boa política de segurança para seus servidores nunca é demais. Por exemplo: Saber quem terá acesso físico a eles, quais usuários terão ou não login, definição de senhas e backup são alguns ítens que devem constar na política de segurança.

Colocar uma senha na BIOS da máquina é primordial, assim caso alguém consiga acesso físico ao servidor e inicializar por um live-cd por exemplo, não conseguirá alterar a ordem de boot que foi estabelecida.

Demonstraremos no decorrer deste artigo como deixar seu servidor slackware um pouco mais seguro.

particionamento

Definir um correto sistema de partições, além de ser esteticamente melhor, traz uma série de benefícios, dentre eles: Poder definir o que pode ou não ser feito em cada partição, dizer quanto de espaço cada uma poderá ter, dentre outras coisas.

opções

Algumas opções para usar no fstab.

nosuid

Caso algum arquivo tenha o bit suid (set-user-identifier) ou sgid (set-group-identifier), o mesmo será tratado como um arquivo normal.

noexec

Não aceita a execução direta de binários.

nodev

Não interpreta caracteres ou dispositivos especiais.

dicas para um bom particionamento

Algumas dicas para um particionamento inteligente:

exemplo de fstab

  
  #device         mount point     fs              fs options                      dump    fsck
  /dev/sda1       swap            swap            defaults                        0       0
  /dev/sda2       /               ext3            defaults                        1       1
  /dev/sda3       /tmp            ext3            defaults,nosuid,noexec,nodev    1       2
  /dev/sda5       /usr            ext3            defaults,ro,nodev               1       2
  /dev/sda6       /var            ext3            defaults,nodev                  1       2
  /dev/cdrom      /mnt/cdrom      auto            noauto,owner,ro,nosuid,nodev    0       0
  devpts          /dev/pts        devpts          gid=5,mode=620                  0       0
  proc            /proc           proc            defaults                        0       0
  

Repare que o /usr está com as opções ro,nodev, então caso seja necessário deixá-la em rw, use o comando:

  
  mount -o remount,rw /usr
  

Após fazer as alterações que você deseja, volte-a para ro,nodev:

  
  mount -o remount,ro,nodev /usr
  

Não esqueça de remover o /var/tmp e fazer um link do /tmp para ele.

senhas

Definir uma boa senha nem sempre é uma tarefa fácil. Uma boa idéia (não é a caninha 51) é usar caracteres especiais tais como !,@,#,$,% misturados com letras maiúsculas, minúsculas e números. Assim mesmo que seja uma palavra fácil, ela se torna bem difícil de adivinhar.

Como exemplo, vamos usar as palavras "slackware linux". Parece ser uma senha simples mas se usarmos números e caracteres especiais.

  
  $L@ckW@r3 L!nUx
  

Para alterar o tamanho de senhas exigido pelo comando password, altere o arquivo "/etc/login.defs" e modifique a linha "PASS_MIN_LEN", trocando o valor de 5 para 8.

instalação do so

A segurança de um sistema começa na instalação. Não que determinado programa não possa ser feito depois, mas por que instalando somente o necessário (principalmente na parte de serviços de rede), pode lhe poupar muitas dores de cabeça.

As vezes são instados programas desnecessários, por que não sabemos quais são todas as depências de determinado programa. Ou muitas vezes a instalação é feita porque talvez irá ser usado no futuro.

Lembre-se, caso seja necessário instalar algo depois, não faça instalação full em servidores. Em servidores de produção não é aconselhável deixar instalado gcc, make e etc. Se precisar compilar alguma coisa no futuro, instale-os, compile o que você quer e remova-os depois.

Procure fazer instalações usando o modo expert, pois você terá um melhor controle do que está sendo instalado, já que os pacotes serão escolhidos individualmente.

serviços desnecessários

Desabilitar ou remover serviços desnecessários é outra coisa que deve ser feita. Por exemplo: um servidor web não precisa de servidor X (salvo raras exceções).

Se você não vai usar inetd para que vai instalar ele? As vezes determinadas coisas não se pode desinstalar, como por exemplo o ntpd. Este pacote tem o binário do ntpdate, usado para sincronização de horário, então querendo ou não você terá que ter o server instalado, mesmo que use somente o client.

Atualizações

Atualizações são outra parte importante. NUNCA esqueça de atualizar seu servidor. Bugs de segurança sempre aparecem e não adianta nada você ter um servidor bem configurado se o mesmo não é atualizado.

Lilo

Lilo significa "Linux Loader" e como todos sabem, ele é o boot loader padrão do slackware. Na sua configuração padrão, o lilo permite a qualquer um que tenha acesso ao console entrar e alterar a senha de root.

opções

Imagine que o usuário tenha acesso ao console e digite na tela de boot do lilo "<Nome da imagem> init=/bin/sh rw". Com isso o sistema irá inicializar e chegará no prompt sem senha e o pior, com acesso total ao sistema. Com isso, basta o usuário digitar "mount -o remount,rw /", que todo o acesso ao servidor estará disponível para ele, sem excessões.

Para não permitir que isso aconteça, vamos fazer algumas modificações no "/etc/lilo.conf".

timeout

Essa opção informa ao lilo quantos mili-segundos ele tem que aguardar para iniciar a imagem definida na opção Default. O valor default é 1200 mili-segundos.

password

A linha password, diz ao lilo para que seja solicitada uma senha toda vez que for acessada determinada imagem. Essa opção pode ser definida abaixo da entrada "image" ou no caso de outros sistemas operacionais, na entrada "other", ou então pode ser definida globalmente, para todas as imagens.

Obs: Caso você use esta opção nas configurações globais e não use a opção restricted, será solitada senha toda vez que você tentar acessar alguma imagem no boot.

restricted

Com esta opção o password só é solicitado se você for iniciar imagens especificando parâmetros em linha de comando, como por exemplo iniciar o sistema em single-user: "<Nome da imagem> init=/bin/sh rw".

exemplo de lilo.conf

  
  # Start LILO global section
  boot = /dev/sda
  message = /boot/boot_message.txt
  prompt
  timeout = 1200
  password = lerolero
  restricted
  # Override dangerous defaults that rewrite the partition table:
  change-rules
    reset
  # VESA framebuffer console @ 800x600x64k
  vga = normal
  # End LILO global section
  # Windows bootable partition config begins
  other = /dev/sda1
    label = Windows
    table = /dev/sda
  # Windows bootable partition config ends
  # Linux bootable partition config begins
  image = /boot/vmlinuz
    root = /dev/sda3
    label = Linux
    read-only
  # Linux bootable partition config ends
  

Como a senha fica em texto plano, a melhor coisa a se fazer é mudar a permissão do lilo.conf para que somente o root possa ler, para isso digite:

  
  chmod 0600 /etc/lilo.conf
  

Obs: Não esqueça de executar o comando lilo para que ele possa ler novamente as configurações do /etc/lilo.conf.

Grub

Grub significa "Grand Unified Bootloader" e é uma alternativa ao lilo. Ele é padrão na maioria das distribuições linux e foi adicionado a árvore /extra do slackware à partir da versão 10.1.

O Grub tem algumas opções muito úteis, como por exemplo, poder editar as opções do menu, ler arquivos do sistema ex: cat /etc/passwd. Por esta e outras razões é necessário restringir a interação do usuário com o "/boot/grub/menu.lst".

opções

A configuração é similar ao lilo, seu arquivo de configuração é o /boot/grub/menu.lst. Edite-o e adicione as seguintes linhas:

timeout

Similiar à opção do lilo, só que o valor é definido em segundos.

password

Similar à opção do lilo, com exceção de que aqui podemos usar senhas encriptadas com md5, para isso usaremos o grub-md5-crypt.

Quando esta opção é definida, toda a interação do usuário com o menu é desativada e caso queira modificar alguma opção ou ter acesso a linha de comando do grub, pressione a tecla "p" e informe a senha.

  
  root@gandalf:~# grub-md5-crypt 
  Password: 
  Retype password: 
  $1$lxEV8$2BgcGNPoWG/kbVvu4Z/Jh0
  

Agora iremos adicionar as linhas no menu.lst:

  
  password --md5 $1$lxEV8$2BgcGNPoWG/kbVvu4Z/Jh0
  

O parâmetro --md5 foi adicionado para informar que usaremos senha encriptada.

Exemplo de menu.lst

Aqui veremos um exemplo do /boot/grub/menu.lst:

  
  # GRUB configuration file '/boot/grub/menu.lst'.
  #
  # The backup copy of the MBR for drive '/dev/sda' is
  # here '/boot/grub/mbr.sda.3626'.  You can restore it like this.
  # dd if=mbr.sda.3626 of=/dev/sda bs=512 count=1
  #
  # Start GRUB global section
  timeout 30
  # Default boot image
  default 1
  # Password for interative control
  password --md5 $1$K9BV8$OQouIFhGvigDxM0r7nxzh1
  # End GRUB global section
  # Other bootable partition config begins
    title Windows XP
    rootnoverify (hd0,0)
    makeactive
    chainloader +1
  # Other bootable partition config ends
  # Linux bootable partition config begins
    title Slackware 12.0
    root (hd0,2)
    kernel /boot/vmlinuz root=/dev/sda3 ro vga=788
  # Linux bootable partition config ends
  

restringindo o acesso do usuário root

Usar senhas compartilhadas não é uma boa idéia, pois caso alguém logue via console e faça alguma coisa errada você não irá saber quem foi o responsável por tal erro. Então vamos seguir alguns passos para não permitir o login de root.

/etc/security

Este arquivo é o responsável por dizer em quais terminais o usuário root poderá conectar, já que queremos bloquear o login de root, iremos comentar todas as linhas deste arquivo.

/etc/suauth

Como o próprio nome sugere, este arquivo é referenciado quando o comando su é chamado. Caso este arquivo exista ele é lido e as regras que estão definidas nele são executadas, caso o arquivo não exista ou o login não case com nenhuma regra, o comando su é executado normalmente, ou seja, é solicitada a senha de root.

Imagine o seguinte cenário: Você não quer instalar sudo no seu servidor, todos sabem que com o sudo, você pode definir usuários ou grupos que podem executar determinados comandos, se o usuário ou grupo irá precisar de senha ou não para usar estes comandos e assim vai.

A sintaxe usada no suauth é:

  
  <usuário de destino>:<usuário de origem>:<ação a ser tomada>
  

Os valores que podem ser usandos em "<usuários de destino>" ou "<usuários de origem>", podem ser um único nome ou uma lista separada por vírgula, ou usar a palavra ALL para todos ou a palavra GROUP seguida do grupo para especificar qual grupo você quer fornecer ou tirar o acesso.

Se você usar a palavra GROUP ou ALL, você pode utilizar o EXCEPT para fazer negações.

Em "<ação a ser tomada>", você pode usar 3 opções que são elas:

Um bom exemplo do uso desde arquivo é permitir que somente um determinado usuário possa usar o comando su para se tornar qualquer usuário e negar que os outros usuários utilizem-no. Ex:

  
  ALL: but3k4 :OWNPASS
  ALL: ALL EXCEPT but3k4 :DENY
  

Veja a resposta do comando su caso eu queria me tornar root ou qualquer outro usuário:

  
  but3k4@sharingan:~$ su - root
  Please enter your OWN password as authentication.
  (Enter your own password.)
  Password: 
  root@sharingan:~# 
  

Agora a resposta para o usuário groo ao usar o mesmo comando:

  
  groo@sharingan:~$ su - root
  Access to su to that account DENIED.
  You are not authorized to su root
  groo@sharingan:~$
  groo@sharingan:~$ su - but3k4
  Access to su to that account DENIED.
  You are not authorized to su but3k4
  groo@sharingan:~$ 
  

Não esqueça de se criar este arquivo antes de rodar o script security-slackware.sh, mudar a permissão para que somente o root possa ler este arquivo:

  
  chmod 0600 /etc/suauth
  

Caso queira ver mais algumas opções utilize o comando man suauth.

/etc/login.access

Este arquivo é responsável por definir quem terá ou não permissão de fazer login. Por default qualquer usuário do sistema pode fazer login. A sintaxe dele é:

  
  <permissão> : <usuários> : <origem do login>
  

Vamos agora a descrição de cada campo:

  
  -:ALL EXCEPT but3k4:ALL
  

O -:ALL diz que todos os usuários serão bloqueados com excessão do usuário but3k4 que terá acesso total, ou seja posso conectar de qualquer tty, console e etc.

/etc/login.defs

Este arquivo tem algumas configurações interessantes, dentre elas:

/etc/profile

Este arquivo contém todas as váriaveis e comandos que são executados toda vez que alguém loga no sistema. É aqui que é definido o PATH global dos usuários comuns e do usuário root, prompt dentre outras coisas. Você também pode ter um .bash_profile no homedir do seu usuário. Só não esqueça que o /etc/profile é lido antes do .bash_profile.

Para melhor um pouco a segurança vamos definir alguns parâmetros.

Além dessas opções acima vamos usar o comando ulimit para proteger nosso sistema contra fork bomb. Este comando aceita você parametrizar várias coisas mas no momento precisamos limitar o número máximo de processos por usuário e também o número máximo de arquivos que podem ser abertos. Creio que para a maioria dos casos, 300 processos por usuário e 100 arquivos que podem ser abertos é suficiente.

  
  if [ "$UID" != "0" ]; then
  	ulimit -u 300
  	ulimit -n 100
  fi
  

A opção -u 300, limita a quantidade de processos para todos os usuários com exceção do root. E a opção -n 100 limita a quantidade de arquivos que podem ser abertos.

Se quer descobrir o que é fork bomb, digite no seu terminal:

  
  :(){ :|:& };:
  

Existem muito mais opções, que podem ser incorparadas ao seu /etc/profile. Digite man bash e divirta-se.

permissões de arquivos, programas e diretórios

Permissões de arquivos e programas é algo que temos que ter um cuidado especial. Scripts ou arquivos com o bit SUID ou SGID ativo, podem fazer bons estragos, já que os mesmos são executados com os privilégios de quem é o dono ou grupo do dono e não de quem está executando. Caso queira ver quais arquivos tenham suid e gid ativo, use o seguinte comando:

  
  find / -type f \( -perm -4000 -o -perm -2000 \) -exec ls -la {} \;
  

Para remover o SUID ou SGID de algum arquivo, use o chmod:

  
  chmod u-s <arquivo ou programa>
  
  chmod g-s <arquivo ou programa>
  

Obs: Muito cuidado com a remoção de permissões.

Além disso, programas com permissões de execução, podem ajudar um invasor a pegar informações do sistema.

Binários como gpasswd, mount e umount, fdisk e ifconfig dificilmente são usados por usuários comuns.

Arquivos como /etc/lilo.conf, /etc/suauth e arquivos de senhas ou configurações não precisam ser acessíveis por usuários comuns.

Existem diretórios que só precisam ser acessíveis para o usuário root, exemplo deles: /etc/rc.d, /etc/ssh, /boot.

Diretórios que precisam ter permissão de escrita para todos são o /var/tmp, /tmp, /var/lock e /var/spool/mail. Para visualizar arquivos com este tipo de permissão, utilize:

  
  find / -type d -perm -2 -ls
  

Para você não ter que ficar procurando quais programas ou não devem ter a permissão alterada, utilize o script security-slackware.sh, ele executa as seguintes tarefas:

Para executá-lo, siga os seguintes passos:

  
  mount -o remount,rw /usr (caso seu usr esteja em uma partição separada como read-only)
  
  wget www.linuxti.pro.br/scripts/security-slackware.sh
  
  chmod +x security-slackware.sh
  
  ./security-slackware.sh
  
  

O arquivo de log com as permissões do binários antes da alteração é o /var/log/security-slackware.log.

Usar acls posix também é uma boa. Acls posix são o meio de atribuir mais de um dono/grupo para um arquivo ou diretório, procure no google por acls posix que você irá encontrar vários links sobre o assunto.

Outros programas interessantes são o chattr/lsattr, que são respecitivamente o comando que muda os atributos e o que lista estes atributos. Opções interessantes são:

Existem alguns arquivos que podemos colocar como imutáveis. Ex: /etc/fstab, /etc/lilo.conf, /etc/services e etc.

SSH

O OpenSSH apareceu pela primeira vez no OpenBSD 2.6 e sua primeira versão foi desenvolvida em Outubro de 1999. Ele é derivado da última versão livre do ssh (versao 1.2.12), desenvolvido por Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt and Dug Song removeram muitos bugs e adicionaram novas features.

Por ser o meio de conexão mais usado entre sistemas Unix/Linux, muitas vezes o administrador não se preocupa em tomar alguns cuidados achando que o serviço por si só é 100% seguro. Em ambiente web não existe nada 100% seguro. aceita-se a afirmação de que um sistema 100% seguro é aquele que se encontra desligado.

opções

Port

Define qual a porta que o sshd ira usar. O valor default é 22, portanto recomenda-se mudar este valor. Use de preferência alguma porta acima de 1024 que não conste no nmap-services (vide /usr/share/nmap/nmap-services).

Protocol

Define qual versão do protocolo será usado, por default ele usa os 2 protocolos, retire o 1 deixando apenas o 2.

ListenAddress

Especifica o endereço ip que o sshd ira ouvir. Você pode especificar múltiplos endereços, separando-os por espacos ou deixar o valor default que é 0.0.0.0, para ouvir qualquer endereço ip.

LoginGraceTime

Por default o sshd espera 2 minutos para você digitar seu usuário e senha, após este tempo ele finaliza a conexão. Creio que 60 segundos são mais que suficientes para você digitar os seus dados. Então mude o valor para 1m e descomente a linha.

PermitRootLogin

Troque o valor para "no", assim o usuario root não irá fazer conexões ssh. Esta opção é praticamente obrigatória.

StrictModes

Por default são verificadas as permissões dos arquivos e diretório do usuário antes de fazer o login.

MaxAuthTries

Especifica o número máximo de tentativas de autenticação permitidas por conexão. O valor default é 6, então diminua para 2 ou 3.

PubkeyAuthentication

Por default é permitida a autenticação por chave pública.

PasswordAuthentication

Por default é ativada a autenticação por senha (imagina se não fosse), vamos mudar o valor para "no" e descomentar a linha, pois iremos usar chaves de autentição.

PermitEmptyPasswords

Como o próprio nome já diz permite o uso de senhas em branco. O valor default eh "no", portanto NUNCA habilite esta opção.

AllowTcpForwarding

Por default é permitido fazer tunel tcp, caso não use, mude o valor para "no".

MaxStartups

Especifica o número máximo de conexões simultâneas não autenticadas. O valor default é 10, conexões adicionais serão dropadas.

Você tambem pode especificar valores aleatórios usando "start:rate:full", ex: 5:80:10, isso quer dizer que após 5 conexões não autenticadas o servidor ssh irá recusar (80%) "rate/100" e a probabilidade aumenta linearmente e todas as conexões são recusadas se as tentativas de conexão chegarem ao limite de 10.

Banner

Especifica um banner no ssh, caso queria personalizar um, basta criar um arquivo .txt e especificar o caminho dele aqui, ex: Banner /etc/ssh/banner.txt.

AllowUsers, AllowGroups, DenyUsers, DenyGroups

São respectivamente os Usuarios que tem permissão de se conectar, os grupos que tem permissão de conectar, usuários que não tem permissão de conectar e grupos que não tem permissão de conectar. Sobre grupos ou usuários que podem conectar fica a seu critério, segue abaixo o meu exemplo de uso:

  
  AllowUsers but3k4 groo slump
  DenyGroups root bin daemon sys adm
  

Criando as chaves:

  
  ssh-keygen -b 2048 -t rsa
  cd ~/.ssh
  mv id_rsa.pub authorized_keys
  
  scp authorized_keys <usuário>@<ip do servidor>:~/.ssh/
  

Para conectar é só usar:

  
  ssh <usuário>@<ip do servidor>
  

Exemplo de sshd_config

Segue abaixo um exemplo de sshd_config:

  
  # $OpenBSD: sshd_config,v 1.74 2006/07/19 13:07:10 dtucker Exp $
  
  Port 14035
  Protocol 2
  ListenAddress 0.0.0.0
  
  SyslogFacility AUTH
  LogLevel INFO
  
  LoginGraceTime 1m
  PermitRootLogin no
  StrictModes yes
  MaxAuthTries 4
  
  RSAAuthentication no
  PubkeyAuthentication yes
  
  PasswordAuthentication no
  PermitEmptyPasswords no
  
  AllowTcpForwarding no
  GatewayPorts no
  X11Forwarding no
  PrintMotd yes
  PrintLastLog yes
  TCPKeepAlive yes
  UseLogin no
  UsePrivilegeSeparation yes
  PermitUserEnvironment no
  MaxStartups 03:80:05
  PermitTunnel no
  
  Banner /etc/ssh/banner.txt
  
  Subsystem	sftp	/usr/libexec/sftp-server
  
  AllowUsers but3k4 groo slump
  DenyGroups root bin daemon sys adm
  

Bloqueando conexões com o iptables

Você pode criar algumas regras de iptables para bloquear conexões ssh no seu servidor, segue abaixo um exemplo de regra:

  
  iptables -N SSH-WHITELIST
  iptables -A SSH-WHITELIST -s <whitelisted ip> -m recent --remove --name SSH -j ACCEPT
  iptables -A INPUT -p tcp --dport <ssh port> -m state --state NEW -j SSH-WHITELIST
  
  iptables -A INPUT -p tcp --dport <ssh port> -m state --state NEW -m recent --set --name SSH
  iptables -A INPUT -p tcp --dport <ssh port> -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --rttl --name SSH \
  -j LOG --log-prefix "SSH many connections "
  iptables -A INPUT -p tcp --dport <ssh port> -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --rttl --name SSH -j DROP
  

Existem outras alternativas além dessas regras de iptables, tais como denyhosts, fail2ban, ssdfilter, ssh blocker, port knocking e etc.

PHP

O PHP sucede de um produto mais antigo, chamado PHP/FI que foi criado por Rasmus Lerdorf em 1995, inicialmente como simples scripts Perl como estatísticas de acesso para seu currículo online. Ele nomeou esta série de script de 'Personal Home Page Tools'. Como mais funcionalidades foram requeridas, Rasmus escreveu uma implementação C muito maior, que era capaz de comunicar-se com base de dados, e possibilitava à usuários desenvolver simples aplicativos dinâmicos para Web.

Em Novembro de 1997 foi lançada a versao 2.0 do PHP/FI que rapidamente foi substituído pelos alphas do PHP 3.0.

A versão 3.0 foi criado por Andi Gutmans e Zeev Suraski em 1997 e oficialmente lançada em Junho de 1998 e é a primeira versão que mais se assemelha ao PHP que nós conhecemos hoje.

Toda a nova versão da linguagem foi realizada sob um novo nome, que removeu a impressão do limitado uso pessoal que o PHP/FI 2.0 prendeu. Ela foi nomeada simplesmente 'PHP', com o significado que é um acrônimo - PHP: Hypertext Preprocessor.

Depois disso foi lançada a versao 4 em 19 de Julho de 1999 e irá ser descontinuada em 31 de Dezembro de 2007 conforme anuncio do site www.php.net.

A atual versao é a 5.2.4 e esta teve sua primeira versão lançada em 29 de Junho de 2003.

segurança

Eu particularmente discordo totalmente quando dizem que o php nao é seguro, digo isso pelos seguintes fatores:

opções

register_globals

Habilita ou não o uso de variáveis globais. Esta opção vem desabilitada por default desde a versão 4.2.0 e a partir da versão 6 ela será excluída (coisa que acho uma excelente idéia). Então continue a deixá-la desabilitada.

Habilitando o register_globals, o PHP transforma as variáveis EGPCS em globais, isso faz com que seja possível usar variáveis sem saber de sua origem e variáveis internas que são definidas no script se misturam com os dados enviados pelos usuários.

Agora para exemplificar o mal costume dos programadores em usarem register_globals habilitado, imagine o seguinte código:

  
  if ($auth)
     echo "Usuário autorizado...";
  else
     echo "Usuário sem autorização!";
  

Como desprezamos a origem da variável $auth, ela pode ser facilmente burlada. Supondo que o nome da página é login.php, eu poderia usar http://www.site.com.br?login.php?auth=1, e estaria autorizado a acessar a página normalmente. Agora veja o mesmo exemplo verificando a origem dos dados:

  
  if ($_SESSION['auth'])
     echo "Usuário autorizado, pode continuar";
  else
     echo "Usuário sem autenticação!";
  

Portanto se eu agora quizer tentar burlar o sistema usando a mesma url anterior, o PHP não irá confundir pois estou dizendo que auth faz parte do array $_SESSION e o auth=1 informado na url, faz parte do array $_GET.

Vale lembrar que a diretiva register_globals não é insegura, o uso incorreto dela é que é, portanto TODO código PHP funciona com register_globals desabilitado.

expose_php

Esta opção acrescenta uma assinatura no header do seu servidor web informando que o PHP está instalado, além de exibir informações detalhadas quando você executa um phpinfo(). Isto não causa problemas de segurança, mas torna possível determinar se você usa PHP em seu servidor. Por default esta opção vem habilitada.

Exemplo de um scan com expose_php habilitado:

  
  root@gandalf:/tmp# nmap -sV localhost -p 80
  
  Starting Nmap 4.20 ( http://insecure.org ) at 2007-09-11 22:14 BRT
  Interesting ports on localhost (127.0.0.1):
  PORT   STATE SERVICE VERSION
  80/tcp open  http    Apache httpd 2.2.4 ((Unix) DAV/2 PHP/5.2.3)
  
  Service detection performed. Please report any incorrect results at http://insecure.org/nmap/submit/ .
  Nmap finished: 1 IP address (1 host up) scanned in 6.093 seconds
  

Agora o mesmo scan com expose_php desabilitada:

  
  root@gandalf:/tmp# nmap -sV localhost -p 80
  
  Starting Nmap 4.20 ( http://insecure.org ) at 2007-09-11 22:14 BRT
  Interesting ports on localhost (127.0.0.1):
  PORT   STATE SERVICE VERSION
  80/tcp open  http    Apache httpd 2.2.4 ((Unix) DAV/2)
  
  Service detection performed. Please report any incorrect results at http://insecure.org/nmap/submit/ .
  Nmap finished: 1 IP address (1 host up) scanned in 6.056 seconds
  

open_basedir

Limita a árvore de diretórios que o PHP usa para verificar quais arquivos ele pode abrir ou não. Essa opção por default está vazia, ou seja, permite que qualquer arquivo seja aberto independente do diretório. Com isso você pode usar funções como a fopen por exemplo para ler conteúdo de arquivos fora da árvore de sua aplicação. Ex: o arquivo /etc/passwd.

Agora habilitando o path absoluto que sua aplicação irá trabalhar, o PHP irá se recusar a abrir arquivos fora daquele path. Para habilitar o open_basedir, imaginemos que nossa aplicação está no diretório /var/www/htdocs, portanto queremos que o PHP trabalhe com todos os arquivos que estão definidos no path /var/www/, para isso usaremos:

  
  open_basedir = '/var/www/';
  

Repare que coloquei o "/" no final, isso quer dizer que estou informando o diretório específico, caso não seja informado o "/" no final, você tanto poderá abrir /var/www, como /var/www1 ou /var/wwwroot. Isso acontece por que a restrição imposta com open_basedir é na verdade um prefixo, e não um nome de diretório.

Vale lembrar que todos os links simbólicos são resolvidos, então não é possível evitar essa restrição com um symlink.

safe_mode

O safe_mode é uma tentativa de melhorar a segurança de sites que utilizam PHP. Esta opção gerou uma grande polêmica entre os usuários e desenvolvedores.

Com o safe_mode habilitado, algumas funcionalidades são restritas e outras desabilitadas. Para saber a lista completa do que funciona ou não com safe_mode habilitado, consulte: http://www.php.net/manual/en/features.safe-mode.functions.php.

Vamos ver de algumas funções muito usadas por programadores e que se não forem usadas com cuidado, podem comprometer todo o sistema.

safe_mode_exec_dir

Se o PHP for usado em safe_mode, algumas funções como a system(), que executam programas do sistema se recusam a executar programas que não estão no diretório atual. Você deve usar / como separador diretório em todos os ambientes.

Esta diretiva especifica um diretório onde os scripts podem ser carregados. O PHP não irá executar um script se ele não estiver neste diretório.

disable_functions

Esta diretiva permite que você desabilite funções que não quer usar. Ela recebe uma lista de nomes de funções separadas por vírgula. Funções interessante para desabilitar: phpinfo, php_uname, get_current_user, openlog, ini_restore, symlink, passthru, system.

Obs: disable_functions não é afetada pela diretiva Safe Mode.

allow_url_fopen

Esta opção ativa o o uso de url como arquivos locais. São disponibilizados por padrão wrappers para acesso de arquivos remotos utilizando os protocolos FTP ou HTTP, e algumas estensões como a zlib podem registar wrappers adicionais. Em outras palavras, desativa a inclusão de scripts externos ao servidor local.

allow_url_include

Esta função permite o uso de uma url com as seguintes funções include(), include_once(), require(), require_once().

Obs: Esta definição requer que allow_url_fopen esteja on

error_reporting

Esta opção habilita o nível de erros que é exibido. É extremamente recomendável habilitar E_ALL tanto para ambiente de desenvolvimento como ambiente de produção.

display_errors

Determina quando os erros devem ser mostrados como parte da saída ou não.

Enquanto estiver desenvolvendo uma aplicação a exibição de erros é necessária para mostrar onde está determinado erro, com isso torna-se mais fácil encontrar possíveis problemas. Agora em ambiente de produção jamais deixe-a habilitada, pois informações importantes podem ser passadas ao usuário sem que você perceba.

log_errors

Define se os erros serão gravados em um arquivo pré-definido, ou se serão gravados no log de erros do apache.

error_log

Define o nome do arquivo onde os erros serão logados. Você pode definir um arquivo em especial ex: /var/log/httpd/php-errors.log", ou definir o valor especial syslog para os erros serem enviados para o log do sistema.

Suhosin

Suhosin é um avançado sistema de proteção para instalações PHP. Ele foi desenvolvido para proteger servidores e usuários de falhas conhecidas e desconhecidas em aplicações PHP.

Ele é divido em 2 partes que podem ser instalação tanto em conjunto como separadas: A primeira parte é um pequeno patch instalado diretamente no núcleo do php que implementa um proteção de baixo nível contra bufferoverflows. A segunda parte é uma extensão que implementa várias outras funcionalidades.

Para saber mais consulte o site do projeto http://www.hardened-php.net/suhosin.

Apache

O Apache (Apache server) é o servidor web mais usado. Foi criado em 1995 por Rob McCool. Atualmente está na versão 2.2.6.

Para evitar alguns problemas vamos parametrizar algumas coisas:

Também procure na documentação quais módulos você realmente necessita, desabilitando os outros.

Existem muitas outras opções, consulte a documentação do apache para maiores detalhes: http://httpd.apache.org/docs/2.2/

BIND

Quando se fala em dns o nome que se tornou padrão de mercado é o BIND (Berkeley Internet Name Domain). Ele é o servidor para o protocolo DNS mais utilizado na Internet, especialmente em sistemas do tipo Unix.

As versões antigas do bind (4 e 8) tinham uma série de vulnerabilidades de segurança e, por isso, o seu uso é hoje fortemente desencorajado. Uma das motivações para reescrever o BIND, e lançar o BIND 9, foi disponibilizar um sistema mais seguro. Para a versão 9, o BIND foi praticamente reescrito. Ele passou a suportar, dentre outras funcionalidades, a extensão DNSSEC e os protocolos TSIG e IPv6.

Um dns bem configurado impede que usuários maliciosos descubram informações importantes de sua rede, como nome de host, endereços ips, além de demonstrar que a pessoa ou equipe de cuida desde serviço, se preocupa com as informações que estão contidas nele.

Para melhorar a segurança deste serviço, precisamos fazer algumas modificações, vamos falar de algumas:

Exemplo da entrada options de um /etc/named.conf:

  
  options {
  	directory "/var/named";
  	version "not available";
  	allow-recursion { 10.1.0.0/16; 10.3.0.0/16; };
  	allow-transfer { 10.3.1.20; 10.3.1.30; 10.3.1.40; 10.3.1.50; };
  	listen-on { 127.0.0.1; 10.3.1.20; };
  };
  

Também não se esqueça de:

cuidado com os logs

Os logs são de extrema importância para a administração de um sistema. NUNCA deixe de verificá-los, nem mesmo de salvá-los em lugar seguro pois um dia eles podem salvar sua vida.

Umas das coisas que um invasor faz é não querer que descubram o que ele fez ou de onde veio, para isso ele tenta esconder seus vestígios. O melhor meio para fazer isso é apagando os logs. Agora se você tem um servidor de logs, mesmo ele apagando os logs locais, os mesmos estão sendo gravados em outra máquina da rede.

O gerenciador de logs do slackware é o syslogd. Ele que controla o que será e onde serão gravados estes dados.

Configurar um servidor de logs é uma tarefa bem simples, basta apenas alterar o arquivo /etc/rc.d/rc.syslog e na linha "/usr/sbin/syslogd" colocar um -r na frente. Nas máquinas clientes é só alterar o /etc/syslog.conf e colocar no final do arquivo a linha:

  
  *.*							@<ip do servidor de logs>
  

Não esqueça, se usar firewall na máquina de logs, liberar a porta 514/udp para conexões. Mesma coisa para as clientes.

grsecurity

Grsecurity é um patch para kernels 2.4 e 2.6 que foi desenvolvido com o intúito de aumentar a segurança. Ele começou a ser desenvolvido em fevereiro de 2001 e teve sua primeira versão para o kernel 2.4.1. É baseado no OpenWall e atualmente sua versão stable é para o kernel 2.6.19.2.

Ele possui vários tipos de recursos como:

Para utilizar o sistema de ACLs, utiliza-se o software gradm, o mesmo faz um total controle do que pode ou não ser utilizado, além de ter um sistema de aprendizagem, no qual ele fica apenas monitorando o que determinado serviço utiliza e com isso pode criar configurações baseadas no que foi monitorado.

As novas versões do grsecurity contam com o PAX. PAX é um completo sistema de proteção a memória. Sua idéia principal é proteger o sistema contra técnicas usadas para ler e gravar em determinados segmentos de memória. Para tal tarefa é utilizada técnicas como a ASLR (Address Space Layout Randomization).

Para saber mais visite: http://www.grsecurity.net.

Outros projetos:

firewalls

Ter um firewall bem configurado é tarefa fundamental quando se fala em segurança. Seu uso restringe o acesso externo aos servidores ou redes que você deseja proteger. Atualmente existem vários tipos de firewalls. No mundo linux, para construir firewalls, usamos o iptables. Ele é um filtro de pacotes muito eficiente e não deixa a desejar em nada quando comparado com outras ferramentas. No seu site oficial (http://www.netfilter.org), traz TODA a documentação necessária para você aprender como utilizá-lo.

Um firewall não pode ser sua única defesa e seu uso não garante que sua rede esteja segura contra invasões.

Os firewall são divididos basicamente em duas categorias:

A grande diferença entre eles é o modo como as decisões são tomadas. Filtros stateless apenas permitem liberar e bloquear pacotes, sendo que precisa ser informado explícitamente o que você deseja fazer. Por outro lado filtros stateful verificam e mantêm o estado das conexôes, verificando cada pacote contido na conexão de modo que possa prever por exemplo se o pacotes que está sendo trasmitido faz parte de uma conexão estabelecida ou não.

Falando em firewalls, algumas dicas para a criação de suas regras de iptables:

Leia sempre a documentação sobre iptables (http://www.netfilter.org/documentation/index.html), ela traz todo o conteúdo necessário para se construir um bom script de firewall e alem de ser divida em partes como: Networking Concepts, Packet Filtering, Nat e Netfilter Extensions. Também tem vários exemplos de scripts que podem ser aproveitados.

ids

IDS significa (Intrusion Detection System) e é usado para detectar tentativas de invasão. OS IDS podem tanto alertar sobre eventuais ataques como tomar as devidas providências bloqueando-o. Ele pode ser usado para analistar e tomar decisões em relação a tentativa de scans, que é a verificação de quais serviços rodam em seu sistema e ataques de negação de serviço (DOS - Deny of Service), que é a tentativa de sobrecarregar um determinado serviço enviados mais requisições do ele pode suportar.

Podemos dividir os IDS em duas categorias:

Para saber como configurar o snort ou o ossec-hids, existem vários tutoriais na net, utilize o google e seja feliz.

Verificação de vulnerabilidades

Existem várias ferramentas que fazem este papel, dentre elas podemos citar:

Teste pesquisar um pouco mais sobre eles para ajudar na detecção de falhas de sua rede ou servidores.

backup

Backup é de extrema importância para qualquer sistema. Sem eles, muitos dados são praticamente impossíveis de serem recuperados e com isso informações importantes podem ser perdida.

Quando for se fazer um backup, pense em três coisas: dados, arquivos de configuração e logs.

Mantendo-se atualizado

Para manter-se atualizado, consulte sites relacionados ao assunto, alguns exemplos são:

Assine a lista de segurança do slackware, enviando um email com o subject "slackware-security" para "majordomo@slackware.com".

Acesse o site http://www.rnp.br/cais/, assine a lista e marque os temas que lhe interessam, assim você irá receber vários emails sobre incidentes de segurança.

Leia sempre a documentação dos programas, elas geralmente são ricas em informações.

E por último não sendo o menos importante, visite o google, ele é seu melhor amigo.

Referências

Agradecimentos