quinta-feira, 27 de novembro de 2014

Hardening no Linux

Olá pessoal, nesse post irei falar um pouco sobre hardening no linux. Hardening significa endurecimento, nada mais é que técnicas que dificulta acessos indevidos ao sistema.

A primeira coisa que iremos fazer é ativar o logoff automático do usuário root em caso de inatividade por um certo período de tempo.

Para isso iremos definir uma variável chamada TMOUT dentro do arquivo /etc/profile. Veja só como fazer isso:

su -
nano /etc/profile



Na imagem acima coloquei só 30 segundos, coloque um valor maior.

Você também pode configurar o prazo de expiração de senha para novos usuários. Basta acessar o arquivo /etc/login.defs

nano /etc/login.defs


Procure pelas variáveis PASS_MAX_DAYS, PASS_MIN_DAYS e PASS_WARN_AGE. O próprio arquivo contém comentários explicando o significado de cada variável.


PASS_MAX_DAYS trata sobre a validade máxima da senha.

PASS_MIN_DAYS trata sobre a validade mínima da senha.

PASS_WARN_AGE é a quantidade de dias antes da expiração que o sistema começa a avisar.

Perceba que o valor padrão de PASS_MAX_DAYS é 99999, ou seja, nunca expira.

Agora iremos configurar o número de dias que a conta será desativada após a expiração da senha. Para isso acesse o arquivo /etc/default/useradd

nano /etc/default/useradd


Para isso, temos que localizar a variável INACTIVE.


Perceba que ela vem comentada, basta você descomentar e setar o número de dias que você preferir.

Agora iremos tratar sobre envelhecimento de senha. As informações sobre envelhecimento de senhas estão no arquivo /etc/shadow.

Com o comando "chage", você pode visualizar as opções de envelhecimento de senha.

chage -l usuario

(clique na imagem para vê-la em tamanho maior)


Para desativar a expiração de senha, basta fazer:

chage -M 99999 usuario


Que tal forçar o uso de senhas mais fortes? Iremos fazer isso com o módulo "pam_cracklib". Primeiro instale o módulo:

apt-get install libpam-cracklib


Para configurar as opções de password, basta acessar o arquivo:

nano /etc/pam.d/common-password


Nesse arquivo tem várias variáveis que podemos configurar. Veja só a linha que encontramos no arquivo:

(clique na imagem para vê-la em tamanho maior)

Com o módulo "requisite", se ele falhar, então a operação não somente falha, como também termina com a falha sem invocar outros módulos. Uma opção ao "requisite" é o "required". Se o módulo "required" falhar, a operação irá falhar, mas somente depois dos módulos abaixo dele serem invocados. O módulo "required" pode ser interessante porque torna praticamente impossível saber qual módulo causou a falha, ou seja, quanto menos informações um usuário mal-intencionado tem do seu sistema, melhor.

"minlen" é o tamanho mínimo da senha, nesse caso o mínimo são 8 caracteres. 

A opção "retry" é a quantidade de tentativas de login incorretas antes de impedir o acesso ao terminal.

A opção "difok" impede o uso das últimas senhas utilizadas. O número 3 indica que tem que haver pelo menos 3 caracteres de diferença entre a senha anterior e a senha atual.

Vamos entender outra linha do arquivo, veja:


(clique na imagem para vê-la em tamanho maior)

"pam_unix.so" é o módulo de autenticação padrão do UNIX.

"use_authtok" significa que quando forçar a mudança de senha, o módulo setará a nova senha para uma fornecida por um módulo de senha empilhado previamente.

"sha512" é o algoritmo utilizado para encriptação.

Que tal testar? Vamos criar um usuário chamado "nerd" e definir uma senha para ele:

useradd nerd


A senha que digitei foi 1234. Mas não definimos que a senha tinha que ter no mínimo 8 caracteres ?? Como ele aceitou a senha 1234 ?? Perceba que na imagem temos avisos do tipo "BAD PASSWORD", mas mesmo assim a senha foi atualizada. Isso acontece porque o comando foi dado pelo root. Vamos agora trocar de usuário e entrar como "nerd".

su nerd

Vamos tentar trocar a senha do nerd para uma senha pequena como 12345:

passwd


Perceba que ele não aceitou, pois agora não somos root, mas sim nerd.

Se quisermos que as regras também afetem o root, então temos que adicionar "enforce_for_root" à linha (arquivo /etc/pam.d/common-password):

password requisite pam_cracklib.so retry=3 minlen=8 difok=3 enforce_for_root

(clique na imagem para vê-la em tamanho maior)

Agora imagine que você queira que os novos usuários tenham uma senha de no mínimo 8 caracteres sendo que essa senha tem que possuir no mínimo 2 letras maiúsculas, 2 números e 2 caracteres especiais. Como fazer isso?

Algumas opções que podem ser utilizadas com o módulo "pam_cracklib":

A opção "lcredit" com N < 0, define o número mínimo de letras minúsculas.

A opção "ucredit" com N < 0, define o número mínimo de letras maiúsculas.

A opção "dcredit" com N < 0, define a quantidade mínima de números.

A opção "ocredit" com N < 0, define o número mínimo de outros caracteres.

Nas opções citadas anteriormente, se N >= 0, então a definição é referente ao número máximo de caracteres.

Sabendo das opções acima, que tal resolver o desafio proposto?

password requisite pam_cracklib.so retry=3 minlen=8 difok=3 ucredit=-2 dcredit=-2 ocredit=-2

ucredit=-2 indica que o mínimo de letras maiúsculas é 2.

dcredit=-2 indica que o mínimo de números é 2.

ocredit=-2 indica que o mínimo de outros caracteres é 2.

Veja que tirei o "enforce_for_root", então tente mudar o password logado com algum usuário que NÃO seja o root, pois sem o "enforce_for_root", o root não é afetado.

Primeiro eu vou tentar a seguinte senha: Brasil2014

Essa senha não deve ser aceita pois NÃO contém caracteres especiais e também ela contém somente uma letra maiúscula.


Não deu como era de se esperar, agora vamos tentar com a senha: BRasil2014$@

Essa senha atende aos requisitos: 2 maiúsculas, no mínimo 2 números e 2 caracteres especiais.


Agora foi, muito simples não é mesmo? ;-)

Que tal bloquear a conta de um usuário após várias falhas de logon? Iremos aprender a fazer isso. Abra o seguinte arquivo:

nano /etc/pam.d/common-auth


Adicione a linha:

auth required pam_tally.so onerr=fail deny=3 unlock_time=60 no_magic_root

(clique na imagem para vê-la em tamanho maior)

A opção deny=3 significa que a conta será bloqueada após 3 falhas de logon.

unlock_time=60 permite o acesso após 60 segundos depois do bloqueio. Caso queira desbloquear o usuário sem esperar esse tempo, então terá que ser feita uma intervenção manual do administrador do sistema, iremos ver isso mais pra frente.

no_magic_root (MUITO IMPORTANTE) indica que o root NÃO será afetado.

Outra coisa que você pode incluir (opcional) no /etc/pam.d/common-auth é a diretiva "reset", ela serve para zerar o contador de falhas de logon quando o usuário conseguir acertar a senha, basta acrescentar a linha:

account required pam_tally.so reset

Vamos testar bloqueando a conta de algum usuário por falha de logon?


Conta bloqueada!! Mas vamos desbloquear o nerd, pois ele é um cara legal, para isso use o comando:

pam_tally --user nerd --reset=0


Para mostrar todas as falhas de tentativas de login para um determinado usuário basta fazer:

faillog -u usuario


Com o comando faillog -a, serão mostrados os registros de falhas de todos os usuários.

Para desativar a opção de bloqueio após várias falhas de logon para determinado usuário, é só fazer:

faillog -u usuario -m -1


CUIDADO com a opção abaixo, leia atentamente antes de fazer e, se fizer, NÃO saia do root enquanto não fizer todos os passos.

Para restringir o acesso ao su, basta editar o arquivo /etc/pam.d/su

nano /etc/pam.d/su

Adicione a linha:

auth required pam_wheel.so group=admin


Agora crie um grupo chamado admin.

groupadd admin


Agora basta adicionar ao grupo admin os usuários que poderão fazer su. Adicione os usuários que você quer que consiga obter acesso root, NÃO saia do root até fazer isso!!

useradd geeksbr admin


O comando acima adiciona o usuário geeksbr ao grupo admin.

Para ver os membros de um grupo, faça:

apt-get install members
members admin


Agora sim podemos sair e entrar de novo como root, veja:


Agora vamos tentar com outro usuário? Vamos tentar com o famoso usuário nerd!


Permissão negada!! Mas vamos dar permissão para o usuário nerd obter root, pois ele também é legal. Primeiramente dê um exit para sair e voltar para o usuário geeksbr.


Agora obtenha o acesso root (você pode fazer isso com o usuário geeksbr, pois adicionamos ele ao grupo admin anteriormente).


Adicione o usuário nerd ao grupo admin:

adduser nerd admin


Legal não é mesmo? Temos dois usuários que podem obter acesso root: geeksbr e nerd. Vamos testar mesmo se o nerd pode ser um root. Saia do root (exit) e faça o logon com o usuário nerd.



Legal, agora o usuário nerd pode obter acesso root!!

Vamos especificar um tempo de espera após uma tentativa fracassada de logon, o padrão é 3 segundos, iremos aumentar isso.

Altere o arquivo /etc/pam.d/login

nano /etc/pam.d/login


Localize a linha abaixo:

auth optional pam_faildelay.so delay=3000000

(clique na imagem para vê-la em tamanho maior)

Você define um número em microssegundos para a opção "delay". Basta aumentar esse tempo.

Você também pode habilitar o log de tentativas fracassadas de logon. Para isso acesse o /etc/login.defs

nano /etc/login.defs


Localize as variáveis FAILLOG_ENAB e LOG_UNKFAIL_ENAB e coloque ambas para yes.


Mantenha a data atualizada para que os logs fiquem consistentes. Eu já fiz um tutorial sobre isso, clique aqui para acessar.

Caso utilize SSH (apt-get install ssh), ative o registro das atividades realizadas com o SSH:

nano /etc/ssh/sshd_config


Adicione a linha:

LogLevel VERBOSE


Permitir apenas o uso da versão 2 do protocolo:


Agora iremos tratar sobre a permissão de login do root. Veja o padrão (arquivo /etc/ssh/sshd_config):


Se quiser dar permissão para o root acessar, então coloque "yes" no lugar de "without-password"

PermitRootLogin yes


Agora dê um restart no SSH:

service ssh restart


Vamos tentar acessar o SSH como root:

ssh root@localhost


Veja só, conseguimos acessar!! Mas se você quiser impedir isso, então altere o PermiteRootLogin para "no".

PermiteRootLogin no


Dê um restart no SSH:

service ssh restart

Agora é só testar novamente:


Permissão negada!! Era isso mesmo que queríamos fazer.

De volta ao arquivo /etc/ssh/sshd_config, algumas variáveis merecem atenção:

StrictModes yes -> checa permissões do diretório home antes de permitir autenticação.

IgnoreRhosts yes -> desabilita autenticação via .rhosts.


Para impedir autenticação com senha vazia:

PermitEmptyPasswords no


Exibir data e hora do último acesso:

PrintLastLog yes


Criar um novo processo do SSH com os privilégios do usuário autenticado para evitar tentativas de elevação de privilégios:

UsePrivilegeSeparation yes


Você ainda pode controlar o número de conexões simultâneas abertas e ainda não autenticadas:

MaxStartups 10

Também poderá detectar conexões pendentes que ainda não foram encerradas:

KeepAlive yes

Que tal especificar quais os usuários podem acessar o SSH ? Basta configurar a variável AllowUsers.

nano /etc/ssh/sshd_config

AllowUsers "geeksbr fulano"


Testando...


Utilize o chkconfig para controlar quais serviços devem ser inicializados no boot.

Tentei abordar várias coisas, mas isso é pouco diante do que você pode fazer, pesquise que você aprenderá muito mais. A documentação do PAM você encontra em: 


Quaisquer dúvidas deixem nos comentários, até a próxima! :)


Nenhum comentário: