Segurança no slackware
By Cláudio Borges aka but3k4
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:
- Antes de particionar, ter em mente qual a finalidade da máquina. Se for um servidor de emails, a partição onde vão ficar os emails tem que ser separada. Se for um servidor web, definir a partição dos vhosts (geralmente usa-se o /home para isso). E daí por diante. Vamos falar de algumas delas:
- /boot - Caso você crie uma partição /boot (depende muito do administrador), monte-a com ro,nosuid,noexec,nodev. Pois esta partição só será lida na hora do boot.
- /tmp - Extremamente necessária, pois é aqui e no /var/tmp onde muitos exploits gostam de ser compilados. use nosuid,noexec,nodev.
- /home - Caso vá utilizar muito espaço no seu /home, coloque-o em uma partição separada. As opções definidas aqui dependem muito para o quê a máquina será usada. Boas opções são nodev,nosuid,noexec.
- /usr - Como o diretório /usr é onde são instalado os programas, essa partição sofrerá muita leitura e quase nada de gravação, salvo atualizações, compilação de kernel ou se você instala programas no /usr/local. Use ro,nodev quando for montar essa partição.
- /var - O diretório /var sofre muita gravação e deixá-lo em uma partição separada não é nada mal. Boas opções são nodev,nosuid.
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/sdamessage = /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:
- DENY - Nega o <usuário de origem> se tornar o <usuário de destino>.
- OWNPASS - Permite que o <usuário de origem> se torne o <usuário de destino> digitando a sua senha.
- NOPASS - Permite que o <usuário de origem> se torne o <usuário de destino> sem digitar senha.
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:
- <permissão> - É definida com “+” ou “-” e são respectivamente acesso e bloqueio.
- <usuários> - Aqui é definido quais usuários ou grupos terão acesso. Caso for colocar mais de um usuário, utilize espacos em vez de vírgula. Usando a palavra ALL você define todo tipo de acesso e EXCEPT quer dizer excessão.
- <origem do login> - Aqui você diz se o usuário terá acesso total, ou se terá acesso somente a um determinado tty ou se será local e assim por diante. Vamos a um exemplo para dizer que somente o meu usuário terá acesso total ao sistema, todos os outros serão bloqueados.
-: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:
- FAIL_DELAY - Diz quantos segundos o usuário tem que aguardar antes de tentar outro login. O valor default é 3, altere-o para 10.
- LOG_UNKFAIL_ENAB - Grava o nome de usuários usados em tentativas de login. Ela vem por default no, mude o valor para yes.
- LOG_OK_LOGINS - Esta opção é para gravar também os logins que foram bem sucedidos. É recomendável alterar para yes.
/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 300ulimit -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:
- altera a permissão de diversos arquivos e os torna disponíveis apenas para o usuário root.
- altera a permissão de diversos diretórios e os torna disponíveis apenas para o usuário root.
- altera o /etc/inittab e comenta a linha referente ao ctrl + alt + del, assim usuários acostumados com o windows não irão reiniciar o sistema sem querer.
- altera o /etc/passwd e retira o shell dos usuários operator, gdm, mysql e qualquer usuário que não tenha shell.
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.shchmod +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:
- i - O ‘i’ é de imutável, ou seja um arquivo que tenha este atributo não poderá ser renomeado, nem excluído e muito menos modificado.
- a - O ‘a’ é de incremental. Este atributo tem quase as duas primeiras regras do ‘i’ que é não deixar o arquivo/diretório ser renomeado nem excluído, mas deixa ser adicionado conteúdo nele.
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 ~/.sshmv 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 2ListenAddress 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 ACCEPTiptables -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:
- Por se tratar de uma linguagem simples e de fácil aprendizado, muitas pessoas começaram a programar sem se preocupar com a qualidade do que estava sendo desenvolvido e isso resultou em programas funcionais com baixa qualidade e com o mínimo de segurança possível.
- Programas inseguros podem ser feitos em qualquer linguagem.
- A correta parametrização do php.ini, bem como todo o ambiente envolvido (sistema operacional, servidor web e a aplicação que esta sendo desenvolvida).
- Muita features da linguagem que “ajudam” a vida do programador, mas diminuem consideravelmente a segurança.
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.
- operador backtick - Backtick é o uso de (“) para chamar comandos do sistema (usado também em bash). Ele é desabilitado no safe_mode.
- shell_exec - Função similar ao operador backtick. Também é desabilitada no safe_mode.
- system - Esta função é usada também para executar comandos de sistema. Sua funcionalidade com safe_mode habilitado, depende da correta parametrização da linha “safe_mode_exec_dir”.
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:
- ServerTokens - Esta opção controla o cabeçalho da resposta que é emitida aos clientes, inclui uma descrição genérica do sistema operacional do servidor bem como as informações sobre módulos compilados. Ela não vem setada no httpd.conf e seu valor default é “Full”. Adicione a seguinte entrada no seu /etc/httpd.conf:
ServerTokens Prod
- ServerSignature - permite a configuração do rodapé em documentos gerado pelo servidor (listagem de diretórios, mensagem de erros). Por default seu valor é off.
- Timeout - O número de segundos antes de receber e enviar um time out. O valor default é 300 segundos, ou seja 5 minutos. É interessante diminuir este valor, para que caso o servidor tenha muitos acessos ou tentativas de negação de serviço, a conexão irá ser finalizada mais rapidamente.
- MaxClients - Limita o número de clientes que podem conectar simultaneamente. Se este limite é sempre atingido, os clientes ficarão aguardando alguma conexão ser liberada para se conectarem. Esta opção tem a intenção principal de ser um freio para manter um servidor em execução com uma performance aceitável. Em ataques de negação de serviço, aumentar este valor pode ser muito interessante, poderá suportar mais conexões, de acordo com os requerimentos de construção e carga calculada no servidor.
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:
- version - Esconder a versão do bind é muito útil, assim ninguém ficará sabendo qual versão você está usando.
- allow-transfer - Usada para definir os IPs dos servidores autorizados a fazer transferência de zona. Essa linha tem que ser adicionada em TODOS os seus servidores dns, de modo que somente os servidores slaves tenho acesso a essa opção.
- allow-recursion - Usada para definir quais os endereços autorizados a realizarem consulta recursiva, em outras palavras, diz quem pode usar ou não seu servidor para resolver nomes.
- listen-on - define qual endereço IP e porta irá ouvir as requisições.
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:
- configurar zonas reversas para seus servidores (principalmente servidores de email) e caso você não tenha autoridade para fazer isso, entre em contato com sua operadora.
- configurar corretamente o contato que consta no seu dns. Muitos não sabem mas cada domínio registrado em um servidor DNS possui na entrada SOA (Start of Authority) o parâmetro que informa o email do responsável pelo domínio ex:
@ IN SOA dns1.ung.br. suporte.ung.br. (
Repare a parte suporte.ung.br, ela é o email do responsável pelo dns. Procure estudar um pouco sobre views e acls, que lhe darão um melhor controle. E para verificar se o seu dns está configurado corretamente ou não, consulte sites como:
- http://www.dnsreport.com
- http://www.checkdns.net
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:
- ACLs.
- Proteção contra buffer-overflow.
- Auditoria.
- Suporte a sysctl.
- Proteção no uso chroot.
- Negar escrita no /dev/kmem, /dev/mem.
- Restrições ao /proc e dmesg.
- Esconder processos do kernel.
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:
- stateless - Que são filtros de pacotes estáticos.
- stateful - Filtros de pacotes dinâmicos.
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:
- Use políticas DROP.
- Estude cuidadosamente o que irá trafegar pelo seu firewall.
- Firewalls foram feitos para analisar pacotes não conteúdo.
- Teste todas as suas regras antes de por em produção.
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:
- NIDS (Network Intrusion Detection System) - Sistema usado para detectar o tráfego de rede de modo que verifique se os pacotes que estão trafegando e assim possa tomar decisões sobre o que deve ou não ser feito em caso de detecção de tráfego malicioso. O mais conhecido no mundo open source é o snort.
- HIDS (Host Intrusion Detection System) - Este tipo de sistema é instalado para monitorar arquivos e logs, verificando a integridade dos mesmos.. Um exemplo deste tipo de sistema é o ossec-hids (http://www.ossec.net).
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:
- Nmap - O nmap é uma ferramenta para exploração de rede e auditoria de segurança.
- Nessus - Uma outra ferramente de exploração de vulnerabilidade. Possui vários plugins e é composta de cliente com GUI e o servidor.
- Nikto - É um scanner de servidores web. Também possui vários plugins e verifica mais de 3300 potenciais arquivos perigosos. Verifa CGI versão do servidor e várias outras coisas. Seus plugins e sua base de dados também pode ser atualizada e faz testes que nem sempre são pegos por IDS.
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