Segurança básica local

Nesta parte será visto como funciona a autenticação em uma máquina Linux: que tipos de senhas pode-se usar (com que tipo de criptografia), como verificar se as senhas são boas ou fáceis e como funcionam as permissões do sistema de arquivos, tudo isso com vários exemplos. Além disso, também serão vistos os logs ou registros do sistema: onde eles são gerados, como organizá-los, etc.

PAM

PAM é a parte principal da autenticação em um sistema Linux. PAM significa Pluggable Authentication Modules ou Módulos de Autenticação Plugáveis/Modulares.

Originalmente, a autenticação no Linux era apenas via senhas criptografadas armazenadas em um arquivo local chamado /etc/passwd. Um programa como o login pedia o nome do usuário e a senha, criptografava a senha e comparava o resultado com o armazenado naquele arquivo. Se fossem iguais, garantia o acesso à máquina. Caso contrário, retornava erro de autenticação. Isto até funciona muito bem para o programa login, mas, suponha que agora deseja-se usar isso também para autenticação remota, ou seja, a base de usuários não está mais na mesma máquina, mas sim em alguma outra máquina da rede, o chamado servidor de autenticação. Será preciso mudar o programa login para que ele também suporte esse tipo de autenticação remota.

Suponha também que surgiu um novo algoritmo de criptografia, muito mais avançado, mais rápido, com criptografa melhor, etc., sendo que o desejo é usar esse novo algoritmo. Deve-se, então, mudar novamente o programa login para que ele suporte este novo algoritmo também. No Linux, muitos programas utilizam algum tipo de autenticação de usuários. Imagine se todos eles tivessem que ser reescritos cada vez que se mudasse algum dos critérios de autenticação.

Para resolver este tipo de problema, a Sun® criou o PAM há alguns anos e liberou as especificações em forma de RFC. O Linux derivou sua implementação do PAM a partir deste documento. Com PAM, o aplicativo login deste exemplo teria que ser reescrito apenas uma vez, justamente para suportar PAM. A partir de então, o aplicativo delega a responsabilidade da autenticação para o PAM e não se envolve mais com isso.

Voltando ao exemplo anterior, no caso de se querer utilizar um outro algoritmo de criptografia para as senhas, basta que o módulo PAM seja modificado para que todos os aplicativos automaticamente e de forma transparente passem a usufruir desta nova forma de autenticação. PAM possui uma outra vantagem: é possível configurar a autenticação de forma individual para cada aplicativo. Com isto é possível fazer com que, por exemplo, um usuário comum possa usar os dispositivos de áudio do computador desde que tenha se logado na máquina através do console. Se o login não tiver sido feito no console (por exemplo, é um login remoto via SSH), este tipo de acesso ao hardware será negado.

Na verdade, PAM vai um pouco além da autenticação. Os módulos podem ser divididos em quatro classes:

auth:

É a parte que verifica que o usuário é realmente quem ele diz que é. Pode ser bem simples, pedindo apenas por um nome e uma senha, ou utilizando autenticação biométrica, por exemplo (como uma impressão de voz, uma imagem da retina ou impressão digital).

account:

Esta parte verifica se o usuário em questão está autorizado a utilizar este serviço ao qual ele está se autenticando. Os módulos aqui podem verificar por horário, dia da semana, origem do login, login simultâneo, etc.

passwd:

Este serviço é usado quando se deseja mudar a senha. Por exemplo, aqui podem ser colocados módulos que verificam se a senha é forte ou fraca.

session:

Por fim, a parte session fica encarregada de fazer o que for necessário para criar o ambiente do usuário. Por exemplo, fornecer o acesso a alguns dispositivos locais como o de áudio ou CD-ROM, montar sistemas de arquivos ou simplesmente fazer o registro do evento nos arquivos de log do sistema.

Um módulo PAM pode ou não conter todas estas funções. O módulo pam_unix, por exemplo, pode ser usado nestes quatro tipos e possui ações diferentes em cada uma das situações, enquanto que pam_console é normalmente usado apenas como session.

Instalação

Os módulos PAM já vêm instalados por padrão no Conectiva Linux. Você pode verificar utilizando o comando apt-get procurando, ou na lista de pacotes instalados do Synaptic, pelo pacote pam, sendo que a documentação está no pacote com nome pam-doc.

Configuração do PAM no Linux

Praticamente todos os aplicativos do Linux que requerem algum tipo de autenticação suportam PAM. Na verdade, não funcionam sem PAM. Toda a configuração está localizada no diretório /etc/pam.d. Quando um aplicativo suporta PAM, ele necessita de um arquivo de configuração neste diretório. A Figura 15.1. Autenticação com PAM ilustra como funciona a autenticação com PAM usando o programa login como exemplo:

Autenticação com PAM

Figura 15.1. Autenticação com PAM

Um programa com suporte a PAM possui duas interfaces com a biblioteca: a de autenticação e a de conversação. A interface de autenticação é por onde a aplicação pede que o PAM valide o usuário. A de conversação é usada pelos módulos que, por exemplo, precisem passar alguma informação para o usuário, como um prompt, ou um aviso de que a senha expirou. Isso é tudo o que a aplicação sabe sobre o processo de autenticação feito pelo PAM. A conversação está ilustrada na figura no módulo pam_unix (b).

[Note]Nota

Somente instalações mais recentes utilizam o módulo pam_unix para praticamente todos os serviços. Versões antigas do Conectiva Linux podem, ainda, utilizar o módulo pam_pwdb.so.

A biblioteca PAM vai procurar o arquivo de configuração da aplicação login. Este arquivo é /etc/pam.d/login e vai dizer quais módulos devem ser usados e com que parâmetros. Este arquivo está reproduzido a seguir:

#%PAM-1.0
auth     required  /lib/security/pam_securetty.so
auth     required  /lib/security/pam_stack.so service=system-auth
auth     required  /lib/security/pam_nologin.so
account  required  /lib/security/pam_stack.so service=system-auth
password required  /lib/security/pam_stack.so service=system-auth
session  required  /lib/security/pam_stack.so service=system-auth
session  optional  /lib/security/pam_console.so
[Warning]Atenção

É importante ressaltar que este arquivo é somente um exemplo, podendo ser diferente do que estiver contido em sua máquina.

Este arquivo de configuração lista os módulos PAM que este programa (login) deve usar, e eles estão representados na figura através de letras. Estes módulos serão carregados e executados na ordem em que estiverem no arquivo de configuração. Note que um módulo pode aproveitar uma informação de um módulo anterior, como normalmente é feito para o nome de acesso/senha. Isso é usado para não pedir a mesma informação novamente para o usuário.

A primeira coluna em um arquivo de configuração PAM representa o tipo de módulo: auth, account, password ou session. Neste exemplo, todos estão presentes, mas isto não é obrigatório. Se um programa não tiver suporte à troca de senha, por exemplo, o tipo password não é usado.

A segunda coluna define o controle para o seu respectivo módulo. O resultado de cada módulo pode influenciar de diversas formas no resultado do processo de autenticação geral. Há algumas categorias:

required:

O resultado deste módulo influencia diretamente o resultado final. Uma falha em um módulo deste tipo só aparecerá para o usuário após todos os outros módulos desta classe serem executados.

requisite:

Semelhante a required mas, em caso de falha, os outros módulos não são executados e o controle volta imediatamente para o aplicativo em caso de falha.

sufficient:

A falha deste módulo não implica em falha da autenticação como um todo. Se o módulo falhar, o próximo da classe é executado. Se não houver próximo, então a classe retorna com sucesso. Se, por outro lado, o módulo terminar com sucesso, então os módulos seguintes dessa classe não serão executados.

optional:

Os módulos marcados como optional praticamente não influenciam o resultado da autenticação como um todo. Eles apenas terão alguma influência caso os módulos anteriores da mesma classe não apresentem um resultado definitivo.

Observe que todos os módulos possuem o parâmetro required, ou seja, não podem falhar (exceção: pam_console).

Por fim, a terceira coluna define o nome do módulo que será usado e seus parâmetros. Todos os módulos estão documentados no diretório /usr/share/doc/pam-doc-[versão] (pacote pam-doc). Será visto aqui apenas como funcionam os módulos usados no programa fonte.

Foi comentado anteriormente que, com PAM, é possível ter aplicações diferentes autenticando de formas diferentes no sistema. Isso é bom do ponto de vista da flexibilidade, mas pode prejudicar em alguns casos. Em particular, quando queremos modificar vários programas para usarem uma mesma forma de autenticação.

Em vez de modificarmos todos os arquivos de configuração PAM da aplicação, para usarem o novo mecanismo de autenticação, pode-se alterar apenas um arquivo global, que será incluído automaticamente. É o que o /etc/pam.d/login anterior está fazendo, ao se usar o módulo pam_stack.so.

A Figura 15.2. PAM - Módulo pam_stack.so é uma forma expandida do /etc/pam.d/login, e ajuda entender como funciona o módulo pam_stack.so. Observando a figura, é possível verificar que o módulo pam_stack.so funciona como uma diretiva de inclusão, ou seja, inclui trechos de outro arquivo dentro do arquivo do serviço atual.

PAM - Módulo pam_stack.so

Figura 15.2. PAM - Módulo pam_stack.so

Os trechos que são incluídos são os da mesma classe a partir de onde o pam_stack.so é chamado, e seu parâmetro service indica qual arquivo a ser incluído.

Por exemplo: /etc/pam.d/login chama na classe “auth” o módulo pam_stack.so passando como parâmetro o nome “system-auth”. Isso indica ao PAM que, assim que chegar nesse ponto, ele deve procurar o arquivo /etc/pam.d/system-auth e incluir todas as linhas referentes a classe “auth”.

Na prática, é como se o arquivo /etc/pam.d/login estivesse na parte de autenticação (as linhas marcadas com asterisco são as incluídas, apenas para efeitos visuais - não devem ser incluídas no arquivo):

 auth     required    /lib/security/pam_securetty.so
*auth     required    /lib/security/pam_env.so
*auth     sufficient  /lib/security/pam_unix.so likeauth nullok
*auth     required    /lib/security/pam_deny.so
 auth     required    /lib/security/pam_nologin.so
...
 session  optional    /lib/security/pam_console.so

Da forma como está configurado o padrão, se você desejar mudar a forma de autenticação do programa login (e de qualquer outro que inclua o pam_stack.so), basta mudar um único arquivo: /etc/pam.d/system-auth. Automaticamente, através deste mecanismo de inclusão, a autenticação estará modificada globalmente.

[Caution]Cuidado

No Conectiva Linux, o pam_stack.so é utilizado somente nos programas de acesso local, como screensaver, kdm e login, entre outros, e não nos programas de acesso remoto, como o openssh e telnet, por questões de segurança. Portanto, se for utilizado o programa authconfig para configurar a autenticação do sistema para LDAP, o pacote padrão do openssh no Conectiva Linux, por exemplo, não será afetado por essa mudança, sendo necessário configurá-lo em separado.

A seguir, serão detalhados mais alguns módulos.

pam_securetty

Este é o primeiro módulo a ser usado e ele simplesmente verifica o terminal de onde o login está ocorrendo. Este módulo não usa parâmetros, mas possui um arquivo de configuração: /etc/securetty. Neste arquivo são listados os terminais a partir dos quais o usuário root pode fazer login, ou seja, são os terminais considerados seguros.

Apesar do nome terminais, conexões remotas também são controladas por este arquivo, pois elas alocam pseudo-terminais (por exemplo, telnet). O módulo retorna sucesso para qualquer usuário diferente de root e, se for root, somente se o terminal de onde está vindo o login estiver listado em /etc/securetty. Para permitir o login de root via telnet, por exemplo, basta acrescentar ao /etc/securetty pts/0. Note que isto somente liberará o pseudo-terminal pts/0. Veja no exemplo seguir:

$ telnet localhost
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Conectiva Linux 10
Kernel 2.6.5-55674cl


login: root
Password: 
# telnet localhost 
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Conectiva Linux 10
Kernel 2.6.5-55674cl

login: root
Password: 
Login incorrect

login:

A primeira conexão telnet ganhou o pseudo-terminal pts/0. Já a segunda teve o pts/1 alocada para si, e este pseudo-terminal não estava listado no arquivo /etc/securetty. Portanto, o acesso não foi autorizado. Isto não funciona com SSH, por exemplo, pois o módulo pam_securetty não está presente ali. O SSH possui seu próprio mecanismo de acesso para o usuário root, mas nada impede que o pam_securetty seja acrescentado no arquivo PAM.

O módulo pam_securetty também pode ser usado para controlar o login a partir do ambiente gráfico, por exemplo. Basta acrescentar o módulo ao arquivo /etc/pam.d/kde (se o kdm estiver sendo usado para login gráfico). A linha a ser acrescentada ao arquivo /etc/securetty (além de se acrescentar pam_securetty aos respectivos arquivos PAM) é :0. Isto para o display zero. Para permitir o login de root em outros displays, a sintaxe é :DISPLAY .

pam_unix

O módulo pam_unix é o módulo principal da autenticação do programa login e da maioria dos serviços que utilizam PAM. Ele vai pedir um nome de usuário e uma senha e verificar se estão corretos. Como tal, o módulo utiliza a função de conversação para interrogar o usuário e pegar as informações desejadas.

Este módulo aceita alguns parâmetros, conforme seu uso (auth, account, etc.):

  • shadow: avisa o módulo que o sistema está utilizando senhas shadow.

  • nullok: permite o uso de senhas em branco. Note que, mesmo que a senha seja em branco (nula), o usuário não conseguirá fazer login se não existir nullok na linha auth para este módulo.

  • md5: usa hash md5 em vez do crypt padrão. Pode ser usado na linha password.

  • use_authtok: indica que o módulo deve usar a autenticação já fornecida para os módulos anteriores, de forma a não interrogar o usuário novamente. Alguns outros módulos suportam o parâmetro use_first_pass, que funciona da mesma forma. Existe ainda o try_first_pass, que primeiro tenta as mesmas credenciais: se houver falha, pede novamente para o usuário. O use_first_pass não faz esse novo pedido caso ocorra uma falha.

    O módulo pam_unix é bem genérico por usar as funções da glibc e, portanto, suporta NIS, LDAP, arquivos texto, arquivos binários e qualquer outra coisa que a glibc vier a suportar (através de NSS).

pam_nologin

O módulo pam_nologin é bastante simples, e muito útil. É uma forma rápida de desabilitar o login de qualquer usuário que não seja o root. Para isto, basta criar o arquivo /etc/nologin. Existindo este arquivo, o módulo pam_nologin vai sempre retornar ERRO para usuários diferentes de root e exibir o conteúdo de /etc/nologin (onde se deve colocar o motivo da proibição), ou seja, só o usuário root consegue se logar na máquina. Quando o arquivo for removido, a operação voltará ao normal, com usuários comuns podendo se logar novamente.

Isto pode ser útil quando se quer fazer alguma manutenção no sistema, por exemplo, situação em que logins de usuários são indesejáveis. Alguns aplicativos do próprio Linux também podem criar este arquivo e depois removê-lo quando alguma operação crítica for concluída.

Note que os usuários que já estiverem logados na máquina não são afetados pela criação ou remoção do arquivo /etc/nologin.

pam_cracklib

Este módulo é especialmente importante para a segurança pró-ativa. Colocado apenas na classe password, o módulo vai verificar a senha do usuário antes que ela seja trocada. Se for uma senha considerada fraca, ela será rejeitada e o usuário não conseguirá trocar a senha. As verificações que o módulo faz atualmente são:

  • palíndromo: a nova senha é um palíndromo (frase que tem o mesmo sentido da esquerda para a direita ou ao contrário)?

  • caixa: a senha nova é a antiga com apenas mudanças de maiúsculas/minúsculas?

  • similar: a nova senha é muito similar à antiga? Esta verificação pode ser controlada por um parâmetro que indica o número mínimo de caracteres diferentes que a senha nova deve ter em relação à senha antiga. O valor padrão é 10 ou metade do tamanho da senha atual, o que for menor.

  • Senha repetida: se existir o arquivo /etc/security/opasswd com as senhas anteriores do usuário, o módulo pam_cracklib vai também verificar se a senha nova já não foi usada anteriormente. Esse arquivo de senhas antigas é atualmente gerado apenas pelo módulo pam_unix, embora exista uma discussão para se criar um módulo específico para esta tarefa (algo como pam_saveoldpass) e remover esta funcionalidade do módulo pam_unix.

Os parâmetros normalmente utilizados com o módulo cracklib são:

retry=N

"N" é o número de tentativas que o usuário poderá fazer para fornecer uma senha considerada boa.

difok=N

"N" é o número de letras diferentes que a senha nova deve ter em relação à senha antiga. Este parâmetro controla o comportamento da verificação do tipo similar, visto há pouco. O valor padrão é 10 (e este é o valor alterado por "N" ou metade do tamanho da senha atual), aquele que for o menor.

minlen=N

Tamanho mínimo da nova senha mais um. Além de contar a quantidade de caracteres da senha nova, créditos também podem ser fornecidos com base na quantidade de algarismos, caracteres maiúsculos/minúsculos e símbolos. Ou seja, se o valor de minlen for 10, o usuário pode usar uma senha com menos do que 10 caracteres, desde que, somando a quantidade de caracteres mais os créditos, o valor final ultrapasse 10. Por exemplo:

password required /lib/security/pam_cracklib.so retry=3 minlen=10

Especifica-se um tamanho mínimo de 9 para a senha nova. Portanto, uma senha igual a senharuim vai funcionar (possui nove caracteres). Mas uma senha igual a am0Bb$ também funcionará, apesar de possuir apenas 6 caracteres, isto por causa dos créditos.

am0Bb$=>6+1(B, maiúscula)+1(0, dígito)+1($, símbolo)= 9=>OK,
passará.

Por outro lado:

am0Bbd => 6 + 1(B, maiúscula) + 1(0, dígito) = 8 => 
não passará.

Por padrão, cada um dos tipos de variação da senha (minúsculo, maiúsculo, algarismo e símbolo) conta no máximo um crédito, ou seja:

am0b9$ => 6 + 1(0, dígito) + 1 ($, símbolo) = 8 => não passa

Note que o uso de dois algarismos não ajudou em termos de créditos. Mas isto pode ser mudado se for passado um outro parâmetro para o módulo:

password required /lib/security/pam_cracklib.so retry=3 \ 
minlen=10 dcredit=2

Através do parâmetro dcredit estipula-se que será tolerado no máximo dois créditos provenientes de algarismos na senha. Com esta alteração, a senha am0b9$ passará como válida pois usa dois algarismos e então atingirá o mínimo de 9 exigido por esta configuração do módulo. Estes parâmetros de créditos também existem para as outras variantes:

  • dcredit: número máximo de créditos fornecidos provenientes do uso de algarismos na senha. O valor padrão é 1.

  • ucredit: número máximo de créditos fornecidos provenientes do uso de letras maiúsculas na senha. O valor padrão é 1.

  • lcredit: número máximo de créditos fornecidos provenientes do uso de letras minúsculas na senha. O valor padrão é 1.

  • ocredit: número máximo de créditos fornecidos provenientes do uso de outros caracteres (símbolos) na senha. O valor padrão é 1.

pam_console

O objetivo do módulo pam_console é permitir ao usuário local (ou seja, no console, fisicamente na máquina) o acesso a diversos dispositivos normalmente restritos ao superusuário, como placa de som, dispositivo de disquete e também permitir ao usuário comum (local) executar certas tarefas, como desligar o computador, entrar no ambiente gráfico ou mesmo instalar pacotes RPM.

Essa capacidade adicional é fornecida ao usuário no seu primeiro login é removida após o último logout, e se dá através da modificação das permissões de alguns dispositivos e também através de autenticação.

Diz-se que o primeiro usuário que fizer login no console "ganha" o console e as permissões definidas no arquivo de configuração /etc/security/console.perms. Quando um usuário possui o console, um arquivo de lock é criado em /var/lock com o nome console.lock. O conteúdo do arquivo é o nome do usuário que possui o console. Se um outro usuário local fizer um login, ele não receberá o console, pois já existe um bloqueio indicando que o console pertence a outro usuário. Quando o usuário do console sair, o arquivo de lock será removido e o console novamente ficará à disposição do primeiro usuário (não root) que fizer o login.

Quando um usuário recebe o console, várias permissões são alteradas no sistema de arquivos, conforme indicado no arquivo de configuração deste módulo PAM. Note que este módulo está como optional, ou seja, não é usado para o sucesso ou não da autenticação do usuário. Isso é necessário, pois ele pode falhar (um outro usuário já possui o console, por exemplo).

A seguir, um arquivo de configuração típico:

# file classes -- these are regular expressions
<console>=tty[0-9][0-9]* vc/[0-9][0-9]* :[0-9]\.[0-9] :[0-9]
# file classes -- these are regular expressions
<xconsole>=:[0-9]\.[0-9] :[0-9]

# device classes -- these are shell-style globs
<floppy>=/dev/fd[0-1]* \
         /dev/floppy/* /mnt/floppy*
<sound>=/dev/dsp* /dev/audio* /dev/midi* \
        /dev/mixer* /dev/sequencer \
        /dev/sound/* /dev/beep /dev/snd/*
<cdrom>=/dev/cdrom* /dev/dvd* /dev/cdwriter* /dev/dvdwriter* \
        /dev/cdrecorder* /dev/dvdrecorder* /dev/cdroms/* \
        /mnt/cdrom* /mnt/dvd*
<serial>=/dev/ttyS* /dev/ircomm*
<pilot>=/dev/pilot
<jaz>=/mnt/jaz*
<zip>=/mnt/pocketzip* /mnt/zip*
<ls120>=/dev/ls120 /mnt/ls120*
<scanner>=/dev/scanner /dev/usb/scanner*
<rio500>=/dev/usb/rio500
<camera>=/mnt/camera* /dev/usb/dc2xx* /dev/usb/mdc800*
<memstick>=/mnt/memstick*
<flash>=/mnt/flash*
<diskonkey>=/mnt/diskonkey*
<rem_ide>=/mnt/microdrive*
<b>=/dev/fb /dev/fb[0-9]* \
     /dev/fb/*

# permission definitions
<console>  0660 <floppy>     0660 root.floppy

Em primeiro lugar, esta configuração define classes de arquivos e classes de dispositivos. Por fim, especifica como devem ser as permissões quando o usuário ganhou o console e quando faz logout. Por exemplo, os dispositivos do tipo floppy devem ter permissão 0660 com o dono sendo o usuário (o grupo não é alterado), e 0660 com donos root.floppy após o logout do usuário. Este tipo de esquema de permissões permite, por exemplo, que o usuário formate um disquete sem que seja necessário obter direitos de root na máquina.

Usando LDAP juntamente com PAM

Aqui será mostrado um exemplo rápido de como modificar o arquivo de configuração PAM para o programa login passar a suportar LDAP também. Note que isto não é suficiente para se ter um sistema completamente dependente do LDAP, para isso ainda é necessário o módulo nss_ldap, que nada tem a ver com PAM. O arquivo modificado fica da seguinte forma:

#%PAM-1.0
auth     required   /lib/security/pam_securetty.so
auth     required   /lib/security/pam_nologin.so
auth     sufficient /lib/security/pam_unix.so shadow nullok md5\ 
         use_authtok
auth     required   /lib/security/pam_ldap.so use_first_pass
account  sufficient /lib/security/pam_unix.so
account  required   /lib/security/pam_ldap.so
password required   /lib/security/pam_cracklib.so
password sufficient /lib/security/pam_unix.so nullok use_authtok\ 
         md5 shadow
password required   /lib/security/pam_ldap.so use_first_pass
session  optional   /lib/security/pam_console.so
session  sufficient /lib/security/pam_unix.so
session  required   /lib/security/pam_ldap.so
[Note]Nota

Este é um guia detalhado para usuários mais avançados, que preferem ver exatamente que alterações podem ser feitas nos arquivos de configuração. O programa authconfig é capaz de fazer todas estas alterações automaticamente.

O módulo pam_securetty fica inalterado, pois ainda deseja-se controlar os terminais por onde o usuário root pode fazer login. Na verdade, o usuário root nem estará no banco de dados LDAP (usuários de sistema devem sempre ser locais). O mesmo para o módulo pam_nologin: permanece inalterado.

Existem, portanto dois módulos responsáveis pela autenticação: pam_unix e o módulo pam_ldap; deseja-se que usuários locais e remotos possam se autenticar nesta máquina. Para usá-los simultaneamente, colocam-se flags de controle.

Primeiramente, coloca-se o módulo pam_unix, pois se o usuário for local, poupa-se uma consulta ao servidor LDAP. Deve-se marcar este módulo como sufficient, ou seja, se ele for bem-sucedido (se o usuário for local e a senha estiver correta) então nenhum outro módulo desta classe (auth) será executado. Se o resultado não for OK (o usuário só existe no LDAP, ou então ele errou a senha), então o próximo módulo será tentado.

O módulo seguinte é justamente o pam_ldap. Nesta configuração coloca-se o parâmetro required, ou seja, se ele falhar, a autenticação como um todo falha também. Para não pedir a senha novamente para o usuário, aproveita-se a senha já fornecida antes e utiliza-se o parâmetro use_first_pass. Este parâmetro diz para o módulo pam_ldap para pegar a senha fornecida anteriormente. Se ela estiver incorreta, o módulo falha. Se fosse usado, por exemplo, o parâmetro try_first_pass em seu lugar, no caso de existir falha, o módulo pam_ldap novamente pediria a senha para o usuário.

O mesmo truque do sufficient e required pode ser aplicado às outras classes: account, password e session. A classe session possui ainda uma pequena alteração no posicionamento do módulo pam_console. Como nada mais é executado após um módulo marcado como sufficient ter sido bem-sucedido, o pam_console não seria chamado se ficasse no fim do arquivo, como na configuração original para o programa login. Assim, ele é colocado no início.

Outros módulos interessantes

Existem diversos módulos PAM em uma distribuição Linux. Nem todos são usados, muitos são desconhecidos. Serão mostrados aqui alguns dos mais interessantes, do ponto de vista de segurança. Todos estes módulos estão bem descritos na documentação; mais detalhes sobre todos os módulos podem ser vistos em /usr/share/doc/pam-doc-[versão].

pam_deny, pam_warn

Estes dois módulos são úteis para se adotar o que é chamado de fail-safe. Como já foi visto, cada programa que suporta PAM deve ter seu respectivo arquivo de configuração no diretório /etc/pam.d. Se o arquivo não existir, o PAM vai abrir o arquivo other. É interessante que este arquivo esteja da seguinte forma:

# default configuration: /etc/pam.d/other
#
auth     required       /lib/security/pam_warn.so
auth     required       /lib/security/pam_deny.so
account  required       /lib/security/pam_deny.so
password required       /lib/security/pam_warn.so
password required       /lib/security/pam_deny.so
session  required       /lib/security/pam_deny.so

O módulo pam_deny simplesmente vai sempre retornar erro. O problema é que ele não faz registros, e é aí que entra o pam_warn, cujo único objetivo é colocar uma mensagem no log do sistema. Um exemplo típico de log é ilustrado abaixo:

mar 19 10:53:51 kepler PAM-warn[8365]: service: su \ 
  [on terminal: <unknown>]
mar 19 10:53:51 kepler PAM-warn[8365]: user: (uid=681) -> root \
 [remote: ?nobody@?nowhere]

Para gerar este log, foi removido o arquivo /etc/pam.d/su e, como usuário comum, deve-se tentar executar o comando su:

$ su
su: senha incorreta

Se o arquivo other não tivesse o pam_warn, nada seria registrado nos logs do sistema.

pam_access

O módulo pam_access pode ser usado para controlar quais usuários podem fazer login de qual local (terminal, remoto, domínio, etc.). Alguns servidores, como o openssh, já possuem um controle parecido embutido, mas também podem usufruir deste módulo. O arquivo de configuração do módulo pam_access é /etc/security/access.conf e contém alguns exemplos. A sintaxe é bastante simples. Por exemplo, a linha a seguir permite o login de usuario1 (ou de usuários do grupo grupo1) apenas a partir dos terminais tty3 e tty4. O resto (inclusive logins remotos) fica negado:

-:usuario1:ALL EXCEPT tty3 tty4

Note que somente alterar o arquivo /etc/security/access.conf não é o suficiente, isto é, o módulo pam_access precisa ser usado. Este módulo entra na categoria account e deve ser usado da seguinte forma:

account    required     /lib/security/pam_access.so

Mesmo que o serviço esteja explicitamente permitindo o login de um dado usuário, se pam_access estiver sendo usado e este mesmo usuário estiver bloqueado no access.conf, o login não será permitido.

pam_limits

Este módulo é muito importante quando se tem usuários com shell em um servidor. Basicamente, ele configura limites para os recursos do sistema disponíveis para o usuário: uso de CPU, memória e outros que serão vistos a seguir. Note que estes limites são aplicados por processo, e não por usuário[57]. Este módulo entra apenas na categoria session e seu arquivo de configuração, /etc/security/limits.conf, contém vários detalhes. As entradas do arquivo de configuração do módulo pam_limits são da seguinte forma:

<domínio>     <tipo>     <item>     <valor>
domínio:

Pode ser um nome de usuário, um nome de grupo (usando a sintaxe @grupo) ou um asterisco (*), indicando qualquer domínio.

tipo:

Pode ter somente dois valores: hard e soft. Limites do tipo hard são aqueles definidos pelo superusuário e impostos pelo kernel do Linux. O usuário não pode aumentar estes limites. Por outro lado, limites do tipo soft são aqueles que o usuário pode alterar, desde que não ultrapasse o que foi definido como um limite hard. Pode-se pensar neste último tipo de limites como sendo valores padrão para o usuário, ou seja, ele começa com estes valores.

item:

pode ser um dos seguintes:

  • core: tamanho máximo para arquivos core (KB).

  • data: tamanho máximo do segmento de dados de um processo na memória (KB).

  • fsize: tamanho máximo para arquivos que forem criados.

  • memlock: tamanho máximo de memória que um processo pode bloquear na memória física (KB).

  • nofile: quantidade máxima de arquivos abertos de cada vez.

  • rss: tamanho máximo de memória que um processo pode manter na memória física (KB).

  • stack: tamanho máximo da pilha (KB).

  • cpu: tempo máximo de uso de CPU (em minutos).

  • nproc: quantidade máxima de processos disponíveis para um único usuário.

  • as: limite para o espaço de endereçamento.

  • maxlogins: quantidade máxima de logins para este usuário.

  • priority: a prioridade com que os processos deste usuário serão executados.

valor:

Aqui deve ser colocado o valor para o item da coluna anterior.

É importante notar que se existirem limites para um usuário e para o seu grupo, os limites para o usuário terão preferência sobre os limites especificados para o seu grupo. E, mais uma vez, não basta alterar o arquivo de configuração se o módulo não for usado. Este é um módulo da categoria session, e deve ser utilizado da seguinte forma:

session     required     /lib/security/pam_limits.so

O módulo aceita dois parâmetros:

  1. debug: aumenta a quantidade de mensagens que vão para o log do sistema;

  2. conf=/caminho/para/arquivo.conf: indica um arquivo de configuração alternativo.

A seguir serão mostrados alguns exemplos. Número máximo de logins simultâneos para o grupo grupo1:

@grupo1 	-	maxlogins	1

Ultrapassando este limite, o usuário receberá uma mensagem na tela informando que excedeu o número máximo de logins e o log mostrará:

Mar 19 16:39:52 kepler pam_limits[14659]:Too many logins (max 1)\
   for usuario
Mar 19 16:39:54 kepler login[14659]: Permission denied

Se o PAM estiver sendo utilizado, isto vale também para logins remotos. Por exemplo, vale direto para o telnet, pois ele usa o programa login. Para fazer valer para SSH também, basta acrescentar o módulo pam_limits ao /etc/pam.d/sshd.

# telnet localhost
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Conectiva Linux 10
Kernel 2.6.5-55674cl

login: usuario 
Password: 

$ telnet localhost
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Conectiva Linux 10
Kernel 2.6.5-55674cl
login: usuario
Password: 

Too many logins for 'usuario'

Permission denied
Connection closed by foreign host.

Número máximo de processos para o grupo grupo2:

@grupo2 	-	nproc	3

Exemplo:

kepler login: usuario
Password:
$ bash
$ bash
$ bash
bash: fork: Recurso temporariamente indisponível
$ ls
bash: fork: Recurso temporariamente indisponível
$ exit
$ ls
Desktop  GNUstep

Este recurso de se limitar o número de processos é bastante interessante, pois evita um fork bomb se usado em conjunto com os outros parâmetros, como tempo máximo de uso de CPU por processo e com os parâmetros relacionados ao uso de memória, e também limitando o número de logins simultâneos.

Note que alguns processos possuem seu próprio controle do uso de recursos (como o Apache, por exemplo), e se recusam a criar mais sub-processos em conseqüência de certas condições de carga da máquina.

pam_time

O módulo pam_time pode ser usado para controlar o acesso a um serviço baseado no horário e dia da semana. A sintaxe para o uso do módulo é:

account     required     /lib/security/pam_time.so

O seu arquivo de configuração padrão é /etc/security/time.conf e as entradas são no formato:

serviço;terminal;usuários;horários
  • serviço: o nome do serviço, como, por exemplo, login ou sshd.

  • terminal: uma lista de terminais.

  • usuários: lista de usuários. Grupos não são suportados.

  • horários: lista de horários no formato DiaHorário. Para indicar os dias, deve-se usar a abreviação do dia da semana em inglês, além de outras abreviações úteis; veja a Tabela 15.2. Horários de Restrição de Login.

Tabela 15.2. Horários de Restrição de Login

Dia

Valor a ser usado na lista de horários

Segunda-feira

Mo

Terça-feira

Tu

Quarta-feira

We

Quinta-feira

Th

Sexta-feira

Fr

Sábado

Sa

Domingo

Su

Dias úteis

Wk

Fim-de-semana

Wd

Todos os dias

Al

Uma "lista", da forma como pode ser usada aqui, é uma seqüência de nomes e opcionalmente alguns caracteres especiais: ! (negação), * (curinga), & (AND) e | (OR).

Para especificar os horários, deve-se sempre utilizar o primeiro valor referente ao dia da semana e logo após a faixa de horários; por exemplo, Mo1800-0900 indica apenas a segunda-feira das 18h às 9 horas do dia seguinte, e Wk0900-1800 indica dias úteis (segunda a sexta) das 09 às 18 horas.

Para somente permitir o login no console nos dias úteis das 8 até às 18 horas, mas permitindo o login de root em qualquer horário, use:

login ; tty* ; !root ; Wk0800-1800

Uma observação importante: o processo de verificação do horário é feito apenas no início da sessão. Ou seja, não existe nenhum mecanismo que force a saída do usuário após o término do horário permitido de login. Por exemplo, aproveitando a regra acima, se um usuário se logar às 17h59 e não fizer logout, ele continuará na máquina mesmo após às 18 horas. Se ele sair, no entanto, não conseguirá entrar de novo pelo menos até às 8 horas do dia seguinte. Para contornar este problema, pode-se usar a variável de ambiente TMOUT[58] do bash. Esta variável especifica o tempo de inatividade máximo de uma sessão. Passando esse tempo, o logout é forçado.

Referências



[57] Seguindo a tradição, o usuário root e seus processos não possuem limites.

[58] Esta variável pode ser declarada como somente leitura pelo administrador do sistema, impedindo que os usuários possam alterar seu valor.