Press "Enter" to skip to content

LAMP++ – Implementando um servidor LAMP seguro ( Atualizado )

Vocês devem estar achando que fiquei maluco, porque postar um assunto tão batido?

Calma!

O objetivo deste post é apresentar todo o processo de implantação de um servidor LAMP seguro de forma rápida e prática. Veremos quais são os pacotes necessários, como fazer o hardening, tunning, monitoramento e segurança.

Não irei detalhar cada fase do processo, quando necessário irei adicionar links com maiores informações.

Instalação dos pacotes

aptitude install apache2 apache2-mpm-prefork apache2-utils apache2.2-common binutils build-essential ca-certificates curl dbconfig-common defoma dpkg-dev fontconfig-config gawk javascript-common libapache2-mod-php5 libapr1 libaprutil1 libc6-dev libcurl3 libdbd-mysql-perl libdbi-perl libexpat1 libfontconfig1 libfreetype6 libgd2-xpm libgmp3c2 libgomp1 libhtml-template-perl libio-multiplex-perl libjpeg62 libjs-jquery libmpfr1ldbl libmysqlclient15off libnet-cidr-perl libnet-daemon-perl libnet-server-perl libnet-snmp-perl libplrpc-perl libpng12-0 libpq5 libssh2-1 libstdc++6-4.3-dev libt1-5 libtalloc1 libterm-readkey-perl libtimedate-perl libwbclient0 libxpm4 munin-node mysql-server mysql-common openssl openssl-blacklist php5 php5-common php5-gd php5-mysql php5-suhosin psmisc ssl-cert ttf-dejavu ttf-dejavu-core ttf-dejavu-extra wwwconfig-common libwww-perl htop sudo

Hardening e Tunning do Apache

Edite os seguintes parâmetros do arquivo /etc/apache2/conf.d/security

Server Tokens

De
ServerTokens Full

Para
ServerTokens Prod

ServerSignature

De
ServerSignature On

Para
ServerSignature Off

TraceEnable

De
TraceEnable On

Para
TraceEnable Off

Nos arquivos de configuração em /etc/apache2/sites-available/ edite a linha Document / deixando da seguinte forma:

Order Deny,Allow
Deny from All
Options FollowSymLinks
AllowOverride None

Habilite o server-status para adquirir estatísticas do Apache2

Crie o arquivo server-status em /etc/apache2/conf.d/ com o seguinte conteúdo:

SetHandler server-status
Deny from all
Allow from localhost

Se desejar faça o baixe o arquivo server-status AQUI

Adicione a seguinte linha no final do arquivo /etc/apache2/apache2.conf

ExtendedStatus On

Habilite o módulo info

a2enmod info

Habilite o SSL

Para habilitar o SSL acesse AQUI

Tunning do Apache

As configurações de tunning do Apache2 estão totalmente ligadas a quantidade de recursos ( CPU, memória e banda ) disponíveis:

Por exemplo para um servidor QuadCore com 8 GB e um link de 5Mb eu recomendo a seguinte configuração:

StartServers 5
MinSpareServers 5
MaxSpareServers 10
ServerLimit 1000
MaxClients 1000
MaxRequestsPerChild 0

Descrição de cada diretiva:

StartServers – Configura o número de processos filhos criados na inicialização ( Recomendado deixar o valor padrão )

MinSpareServers – Número minimo de processos que não manipulam requisições. ( Recomendado deixar o valor padrão )

MaxSpareServers – Número máximo de processos que não manipulam requisições. ( Recomendado deixar o valor padrão )

ServerLimit – Valor máximo da diretiva MaxClients. ( Deve ser igual ou superior ao MaxClients )

MaxClients – Número máximo de conexões simultâneas. ( Varia de acordo com os recursos disponíveis )

MaxRequestsPerChild – Limite de requesições que um processo filho poderá manipular. ( 0 siginifica ilmitado )

Dica Importante: Para testes de benchmark do Apache2 recomendo o uso do AB ( Apache Benchmark )

Hardening e Tuninng do MySQL

Execute o seguinte comando e siga os passos recomendados:

/usr/bin/mysql_secure_installation

Enter current password for root (enter for none): Informe a senha do root do mysql ou pressione ENTER se a senha ainda não foi configurada

Change the root password? [Y/n] Pressine ENTER para criar uma nova senha

Remove anonymous users? [Y/n] Pressione ENTER

Disallow root login remotely? [Y/n] Pressione ENTER

Remove test database and access to it? [Y/n] Pressione ENTER

Reload privilege tables now? [Y/n] Pressione ENTER

MySQL Tunning

Para o tunning recomendo o uso do MySQL Performance Tuning Primer Script .

Dica Importante: O uso desta ferrramenta é recomendado após 48 horas de uso do banco permitindo que o script detecte os valores corretos para o tunning do banco.

Este script validará os parâmetros do arquivo my.cnf e criará um novo arquivo com as alterações recomendadas.

Hardening do PHP

Para ampliar a segurança do PHP recomendo o uso do Suhosin , o Debian implementa ele por padrão. Além do suhosin é necessário desabilitar os seguintes parâmetros do arquivo /etc/php5/apache2/php.ini:

# Impede ataques de RFI e LFI ( Remote and Local File Inclusion )

allow_url_fopen = Off

# Impede que mensagens de erros sejam exibidas

display_errors = Off

# Impede a execução de caracteres especiais digitados em campos de formulário convertendo-os em barra invertida. Protege contra ataques de SQL injection

magic_quotes_gpc = Off

# Impede o acesso a arquivos remotos através dos parâmetros include ou require, evitando injeção de código malicioso.

allow_url_include = Off

# Impede a exibição das informações sobre o PHP

expose_php = Off

# Impede a execução de strings maliciosas devido as falhas no desenvolvimento da aplicação.

register_globals = Off

Segurança e Manutenção do S.O.

Desabilite o exim4

invoke-rc.d exim4 stop

update-rc.d exim4 remove

Hardening do SSH

Modifique as seguintes linhas do arquivo /etc/ssh/sshd_config:

Port 22

para por exemplo

Port 3000

PermitRootLogin yes

para

PermitRootLogin no

Limite o uso do sudo somente para o grupo admin

Crie o grupo admin

addgroup admin

Adicione seu usuário nesse grupo

adduser alexos admin

Configure o sudo adicionando a seguinte linha

%admin ALL=(ALL) ALL

Desabilite o usuário root

usermod -L root

Dica Importante: Para manter o sistema operacional e os aplicativos atualizados recomendo o uso do Cron-apt.

Monitoramento de performance

Para montitorar a performance do servidor e dos serviços recomendo o uso do Munin , você encontrará como instalar e configurar o Munin AQUI.

Agora vou apresentar como configurar o Munin para monitorar o Apache.

Com o server-status funcionando habilite os plugins do Apache

cd /etc/munin/plugins

ln -s /usr/share/munin/plugins/apache_processes apache_processes

ln -s /usr/share/munin/plugins/apache_accesses apache_accesses

Feito isso é necessário editar o arquivo /etc/munin/plugin-conf.d/munin-node e informar o usuário com permissão de acesso as informações do apache, no caso do Debian este usuário é o www-data.

vim /etc/munin/plugin-conf.d/munin-node

[apache2]
user www-data

E para finalizar implemente uma camada a mais de segurança. Recomendo fortemente o uso do Ossec Hids e de um pequeno script de firewall.

A instalação e configuração do Ossec Hids você encontrará AQUI .

OBS Importante: Durante a instalação do Ossec opte pela instalação local ao invés do server, assim a instalação será standalone.

Script de Firewall

Crie um arquivo /etc/init.d/firewall.sh com o seguinte conteúdo:

#!/bin/bash

# Server firewall

# Alexandro Silva
# April 27th ‘2010

PATH=/bin:/usr/bin:/sbin:/usr/sbin

TCPOK=”123 80 443″
UDPOK=”53″

iptables -F INPUT
iptables -F OUTPUT
iptables -F FORWARD

iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP

#Drop incoming malformed NULL packets
iptables -A INPUT -p tcp –tcp-flags ALL NONE -j DROP

#Drop incoming malformed XMAS packets
iptables -A INPUT -p tcp –tcp-flags ALL ALL -j DROP

#Syn flood protection
iptables -A INPUT -p tcp –syn -m limit –limit 1/s –limit-burst 3 -j RETURN

#Drop incoming ping request
iptables -A INPUT -p icmp –icmp-type echo-request -j DROP

iptables -A INPUT -j ACCEPT -i lo
iptables -A INPUT -j LOG -i ! lo -s 127.0.0.1/255.0.0.0
iptables -A INPUT -j DROP -i ! lo -s 127.0.0.1/255.0.0.0

iptables -A OUTPUT -j ACCEPT -o lo

# Permit SSH in the 3000 port
iptables -A INPUT -s 0.0.0.0 -p tcp –dport 3000 -j ACCEPT

# Permit access in some TCP ports
for PORTA in $TCPOK
do
iptables -A INPUT -p tcp –dport $PORTA -j ACCEPT
done

# Permit access in some UDP ports
for PORTA in $UDPOK
do
iptables -A INPUT -p udp –dport $PORTA -j ACCEPT
done

# Drop other entering connections checking the state
iptables -A INPUT -m state –state ! ESTABLISHED,RELATED -j DROP

iptables -A FORWARD -m state –state ESTABLISHED,RELATED -j ACCEPT

Se desejar faça o download do script AQUI

Adcione esse script na inicialização do sistema

update-rc.d firewall.sh defaults

Testando a segurança do servidor

Após a conclusão de todos estes passos use as seguintes ferramentas para scanear o servidor e validar todo o trabalho realizado:

Hntool

W3af

Nikto

Netsparker

Conclusão

No que tange a segurança dos servidores LAMP venho tendo bastante sucesso seguindo estes passos. Sei que existem outras implementações tão melhores quanto essa, porém aqui sigo boas práticas e faço uso de poucas ferramentas tornando sua aplicabilidade rápida, simples e de fácil gerência.

8 Comments

  1. Peterson Peterson January 22, 2011

    Opa..
    na confg. do Firewall, no início vc colocou
    iptables -P INPUT ACCEPT
    não seria:
    iptables -P INPUT DROP
    e depois liberar as portas desejadas??

    Abraço e Parabéns pelo Artigo…

  2. Alexos Alexos January 23, 2011

    Olá Peterson,

    Excelente observação, nessa linha venho abrindo as conexões observe que abaixo dela seguem sucessivos e importantes DROPs

    #Drop incoming malformed NULL packets
    iptables -A INPUT -p tcp –tcp-flags ALL NONE -j DROP

    #Drop incoming malformed XMAS packets
    iptables -A INPUT -p tcp –tcp-flags ALL ALL -j DROP

    #Syn flood protection
    iptables -A INPUT -p tcp –syn -m limit –limit 1/s –limit-burst 3 -j RETURN

    #Drop incoming ping request
    iptables -A INPUT -p icmp –icmp-type echo-request -j DROP

    E encerro dando um Deny All nas conexões de acordo com o estado

    # Drop other entering connections checking the state
    iptables -A INPUT -m state –state ! ESTABLISHED,RELATED -j DROP

    E só libero as conexões nas portas permitidas

    # Permit access in some TCP ports
    for PORTA in $TCPOK
    do
    iptables -A INPUT -p tcp –dport $PORTA -j ACCEPT
    done

    # Permit access in some UDP ports
    for PORTA in $UDPOK
    do
    iptables -A INPUT -p udp –dport $PORTA -j ACCEPT
    done

    Colocando um iptables -P INPUT DROP eu acabo bloqueando a execução desse processo. Você poderá verificar isso colocando essa linha e executando o comando iptables -L, veja que a listagem para na chain INPUT. Já usando o ACCEPT a listagem flui normalmente, verifique as informações desta listagem e veja os vários DROPs da chain INPUT.

    Abs,

    Alexos

  3. Alexos Alexos January 23, 2011

    Olá,

    Quero esclarecer que as informações contidas neste post são exemplos e não regras.

    Qualquer pessoa poderá melhorá-la ou adequá-la a sua necessidade.

    Se quiser pode melhorar o script ou incrementar as boas práticas de hardening e tunning, encaminhando suas melhorias que com certeza publicarei.

    Como informei na conclusão estas implementações vem dando certo para mim a algum tempo, mas estou super interessado em novas sugestões de melhorias.

    Abs,

    Alexos

  4. Jamson Jamson January 28, 2011

    Olá Professor!

    Muito legal o post, apenas tenho uma coisa a acrescentar.

    Recomendo o uso no MYSQL (além da ferramenta, mysql_secure_installation) o uso da ferramenta mysql_setpermission, onde ajudará a implementar segurança nas tabelas SGDB.

    Esse script é recomendável PRINCIPALMENTE em ambientes em que tem-se o banco separado da aplicação. Onde o interessante é sempre criar um usuário para a aplicação que irá acessar banco, restringindo à determinado usuário usar o banco. Outra vantagem do uso desse método é isolar o usuário ROOT do mysql.

  5. Antonio Antonio April 9, 2011

    Que maravilha!
    Oxalá pudesse eu decodificar tudo que escreveste para, finalmente, configurar meu maldito servidor….
    Quando encontrar um passo a passo para ignorantes com eu quem sabe eu chego lá…
    Abraço,
    Antonio

  6. Valdir M Jr Valdir M Jr April 24, 2012

    Opa Alexos tudo bem? Essas confs diferem muito se o servidor a ser usado for um Centos? Obrigado e parabéns pelo blog.

  7. Alexos Alexos April 25, 2012

    Olá Valdir,

    O conteúdo dos arquivos é o mesmo.

    Abs,

    Alexos

  8. Valdir Valdir April 27, 2012

    Obrigado

Comments are closed.