Páginas

quarta-feira, 17 de julho de 2013

Hardening

Muitos administradores (muitos mesmo) ao instalarem um servidor acabam esquecendo (ou são pressionados a terminarem depressa) de uma parte importante do sistema operacional, que é a segurança. Nesse artigo eu pretendo mostrar algumas dicas, técnicas e ferramentas muito legais que visam proteger um firewall. Juntamente com o script de firewall corporativo que foi postado nesse blog, trarão muito mais segurança e minimizarão os riscos de ataques diretamente em seu firewall de borda.

A primeira dica é já para a instalação do SO, mais precisamente na parte de particionamento. Para facilitar a manipulação de partições eu costumo utilizar LVM, pois permite redimensionamentos posteriores, extends de disco, etc. A dica aqui é criar partições separadas para pontos de montagem estratégicos do sistema operacional. Dessa forma podemos definir opções de montagem para cada uma separadamente. Como exemplo, podemos definir que o /home, /tmp e /var não terão permissão de execução, isso quer dizer que nenhum programa malicioso (rootkit, backdoor, exploit) será executado nesses pontos de montagem (comuns nesses casos).

Um esquema bem legal de particionamento seria separar as partições da seguinte forma:

/
/boot
/home
/opt
/tmp
/usr
/var
/var/log

O /home em um firewall não deve conter arquivos pessoais, muito menos executáveis e por isso tiraremos a permissão de execução de binários nessa partição. O mesmo acontece em /tmp e em /var (lembrando que deveremos dar permissão de execução nessas duas partições para utilizarmos ferramentas como apt ou aptitude, mas veremos um script para isso mais adiante). O /opt em geral contém os pacotes que são baixados e instalados pelo próprio usuário, e é bom separarmos a partição para limitarmos o espaço que teremos para esse fim, além de retirarmos a permissão de execução de binários com SUID BIT. A partição /usr conterá os binários do sistema e sua separação aqui é mais para limitar o tamanho mesmo. A partição /var/log também não terá permissão de execução e será limitada para que os logs não venham ocasionalmente a preencher o espaço disponível em disco para o / que dispensa explicações. O /boot é necessário para armazenar o kernel e as informações do GRUB, etc. Essa não faz parte do LVM, é uma partição física formatada em EXT2.

Agora que já temos nosso esquema de particionamento, instalamos o SO e ao término, faremos as atualizações e configurações necessárias. Depois disso vamos modificar as permissões das partições editando o arquivo /etc/fstab (faça backup dele antes). Vamos tomar por exemplo a linha da partição /var:

/dev/mapper/servidor-var /var               ext4    defaults 0       2

Essa é a linha original do arquivo, com as permissões padrão do sistema. Vamos alterá-la para que fique assim:

/dev/mapper/servidor-var /var               ext4    defaults,nosuid,noexec 0       2

Dessa forma, tiramos a permissão de execução na partição e também a permissão de execução de arquivos com SUID BIT ligado. Devemos fazer isso nas partições /home, /tmp, /var, /var/log. Na partição /opt devemos tirar a permissão de execução de SUID BIT (opção "nosuid"). Ao terminar (faça em todas as partições descritas acima), reinicie o sistema para que as alterações tenham efeito ou remonte cada partição:

"mount -o remount /var"

Depois disso, execute um mount para conferir se as alterações foram aplicadas:

"mount"

Para que possamos fazer instalação de pacotes utilizando apt ou aptitude, devemos sempre remontar as partições /tmp e /var com permissão de execução e retirar as permissões após a instalação. Para facilitar, podemos fazer um script simples:

#!/bin/bash
case $1 in
start)
        mount -o remount,rw,noexec /var
        mount -o remount,rw,noexec /tmp
        echo "Partições SEM permissão de execução"
    ;;
stop)
        mount -o remount,rw,exec /var
        mount -o remount,rw,exec /tmp
        echo "Partições COM permissão de execução"
    ;;
*)
        echo "Modo de uso $0 {start|stop}"
        exit 0
    ;;
esac
exit 1

Crie a pasta /root/admin_scripts e coloque esse script lá. Dê permissão de execução chmod +x script.sh. Sempre que ele for executado com a opção "stop" ele dará permissão de execução nas partições, e com a opção "start" ele removerá a permissão de execução das partições.

Nosso próximo passo é remover a permissão de SUID BIT dos binários que não precisam dessa permissão. O que é SUID BIT? É a permissão de execução do dono do arquivo. Isso é, se o dono do arquivo for o root, ele vai ser executado como root e isso pode ser explorado para ganho de acesso administrativo ao sistema operacional. Apenas alguns arquivos tem a real necessidade de serem executados com SUID BIT, e o script abaixo retira as permissões dos demais:

#!/bin/bash
# Script para remover SUID BIT de binários Linux
# Desenvolvido por Rodrigo Garcia em 17/06/2013
FN_LISTASUID()
{
        find / -perm -4000 2> /dev/null | egrep -v "/passwd|/sudo|/su|/sudoedit" > suid.txt
        if [ $? = 0 ]
        then
                cat suid.txt
        else
                echo "Não há arquivos com SUID BIT ligado no sistema!!!"
                exit 0
        fi
}
FN_RMSUID()
{
        FN_LISTASUID
        echo -n "Deseja realmente remover o SUID BIT dos arquivos listados (S/n)?: "
        read RESPOSTA
        if [ -z $RESPOSTA ]
        then
                RESPOSTA=$(echo "s")
        fi
        case $RESPOSTA in
        s)
                while read line
                do
                        chmod -s $line
                done < "suid.txt"
                echo "SUID BIT removido com sucesso!!!"
                ;;
        n)
                exit
                ;;
        *)
                echo "Opcao Invalida!!!"
                exit
                ;;
        esac
}
FN_HLP()
{
        echo "Script para remover SUID BIT de Binários GNU/Linux"
        echo "Desenvolvido por Rodrigo Garcia em 17/06/2013"
        echo "Use $0 [opcao]"
        echo "-l --lista        Lista os binários com SUID BIT ligado;"
        echo "-r --remove       Lista os binários com SUID BIT ligado e remove a permissão;"
        echo "-h --help Mostra essa mensagem;"
}
case $1 in
-l)
        FN_LISTASUID
        exit
        ;;
--lista)
        FN_LISTASUID
        exit
        ;;
-r)
        FN_RMSUID
        ;;
--remove)
        FN_RMSUID
        ;;
-h)
        FN_HLP
        ;;
--help)
        FN_HLP
        ;;
*)
        echo "Use $0 [opcao] -h ou --help para mais informacoes"
        exit
        ;;
esac

Salve-o como /root/admin_scripts/rmsuid.sh e dê permissão de execução (chmod +x rmsuid.sh). Sua execução é bem simples, ./rmsuid.sh --lista ou (-l) busca no sistema os arquivos que não precisam de SUID BIT ligado, salva a lista em um arquivo texto e mostra na tela. A opção --remove (ou -r) mostra os arquivos e confirma a remoção de SUID BIT dos arquivos desnecessários, e pronto!

Agora vamos em busca dos pacotes desnecessários que estão instalados no sistema. Temos um script também que faz isso:

#!/bin/bash
dpkg -l | awk 'NR >= 6 { print $1 FS $2 }' > pacotes.txt

Esse script lista todos os pacotes do sistema e salva seu nome e sua versão no arquivo pacotes.txt para ser analisado, e então coerentemente o administrador removerá os pacotes (por exemplo, se o pacote "apache2" estiver instalado no firewall, é melhor removê-lo). Salve-o como /root/admin_scripts/pacotes.sh e dê permissão de execução.

Em seguida, precisamos manter acesso externo ao firewall para que possamos administrá-lo remotamente (sempre existirá essa necessidade). Mas não podemos deixar a porta 22 do SSH aberta direto, pois sofreremos muitas tentativas de invasão. Então vamos começar mudando a porta padrão do SSH por outra aleatória (recomendo acima da porta 1024). Para isso precisamos editar o arquivo /etc/ssh/sshd_config e alterar a linha:

Port 22

Para:

Port "porta qualquer acima da 1024"

Mas isso ainda não resolve o nosso problema, pois teremos sempre a porta de conexão do SSH que escolhermos aberta para a internet. A solução encontrada aqui é o uso da ferramenta "knockd" que trabalha com uma técnica chamada "port knocking" que consiste em uma conbinação de portas do firewall que o cliente tem que "bater" para que outra porta seja aberta, como um cofre que possui uma combinação pré definida. Vamos instalar o knockd:

/root/admin_scripts/noexec.sh stop

aptitude install knockd

/root/admin_scripts/noexec.sh start

Após a instalação, vamos configurar o serviço editando o arquivo /etc/knockd.conf nas seguintes linhas:

[openSSH]
        sequence    = escolher uma sequência aleatória de 3 portas (recomendo acima de 1024), ex: 1028,2056,4112
        seq_timeout = 5
        command     = /sbin/iptables -A INPUT -s %IP% -p tcp --dport porta do ssh -j ACCEPT
        tcpflags    = syn

E também as linhas:

[closeSSH]
        sequence    = O inverso da sequência acima, ex: 4112,2056,1028
        seq_timeout = 5
        command     = /sbin/iptables -D INPUT -s %IP% -p tcp --dport porta do ssh -j ACCEPT
        tcpflags    = syn

Salvamos o arquivo e saímos. Em seguida devemos editar o arquivo /etc/default/knockd na seguinte linha:

START_KNOCKD=0

Mudar para

START_KNOCKD=1

Essa mudança permite a inicialização do serviço knockd. Após isso iniciamos o serviço:

service knockd start

Na máquina cliente devemos também instalar o knockd mas não precisamos configurar nada, e para utilizá-lo devemos executar o seguinte comando:

knock ip.do.seu.firewall 1028 2056 4112

Isso vai executar o comando do knockd.conf e abrir o firewall para a porta do SSH que definimos. Para terminarmos o acesso, nós saímos do SSH e executamos o mesmo comando invertendo as portas:

knock ip.do.seu.firewall 4112 2056 1028

E a porta será fechada novamente. E para finalizar, apenas a recomendação de executar periodicamente os scripts de busca de SUID BIT e de listagem de pacotes, e sempre manter o sistema operacional atualizado a fim de mantermos o mais seguro possível. Espero ter sido útil!!!

Até a próxima!!!