Limitação de recursos usando PAM

Plugglable Autentication Modules (Módulos de autenticação plugáveis) são um conjunto de bibliotecas usadas para fazer autenticação, gerenciamento de contas, controle de recursos dos usuários no sistema, em adição ao tradicional sistema de acesso baseado em usuários/grupos. Este recurso permite modificar a forma que um aplicativo autentica e define recursos para o usuário sem necessidade de recompilar o aplicativo principal. Os recursos que desejamos controlar restrições via PAM são especificados individualmente por serviços nos arquivos correspondentes em /etc/pam.d e então os arquivos correspondentes em /etc/security são usados para controlar tais restrições.

Nesta seção assumirei explicações dirigidas aos recursos controlados pelos arquivos em /etc/security A maioria das explicações são baseadas em testes e nos próprios exemplos dos arquivos de configuração do PAM.

Descobrindo se um determinado programa tem suporte a PAM

Um método simples de se determinar se um programa binário possui suporte a PAM é executando o comando:

ldd [programa]

Por exemplo:

ldd /bin/login

libcrypt.so.1 => /lib/libcrypt.so.1 (0x4001c000)
libpam.so.0 => /lib/libpam.so.0 (0x40049000)
libpam_misc.so.0 => /lib/libpam_misc.so.0 (0x40051000)
libdl.so.2 => /lib/libdl.so.2 (0x40054000)
libc.so.6 => /lib/libc.so.6 (0x40058000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

Caso a biblioteca libpam for listada, o programa tem suporte a PAM compilado. Programas que não possuem suporte a PAM deverão ter o código fonte modificado inserindo as funções para tratamento dos módulos de autenticação.

Definindo uma política padrão restritiva

A política padrão do PAM é especificado em /etc/pam.d/other e define o que acontecerá caso nenhum dos arquivos de controle de serviço em /etc/pam.d confiram com o serviço em questão. Normalmente o módulo pam_unix.so é usado para fazer a política padrão, para deixar o sistema mais seguro, utilize a seguinte configuração no arquivo /etc/pam.d/other:

auth     required       /usr/lib/security/pam_warn.so
auth     required       /usr/lib/security/pam_deny.so
account  required       /usr/lib/security/pam_deny.so
password required       /usr/lib/security/pam_warn.so
password required       /usr/lib/security/pam_deny.so
session  required       /usr/lib/security/pam_deny.so

O módulo pam_deny.so é responsável por fazer o bloqueio, e o pam_warn envia avisos ao syslog (facilidade auth nível notice) caso serviços módulos PAM que necessitem do serviço de autenticação sejam bloqueados (isto não é feito automaticamente pelo pam_deny.so).

OBS: Esta configuração poderá causar bloqueio em muitas coisas caso possua módulos de autenticação mau configurados. Esteja certo de utilizar o módulo pam_warn.so (antes do pam_deny.so) nas diretivas restritivas para entender qual é o problema através da análise dos arquivos de logs.

Mais detalhes sobre a configuração de módulos de autenticação poderão ser encontrados no endereço ftp://ftp.us.kernel.org/pub/linux/libs/pam/Linux-PAM-html/pam.html e http://www.kernel.org/pub/linux/libs/pam/pre/doc/rfc86.0.txt.gz.

Restringindo/Bloqueando o login

Isto é controlado pelo arquivo /etc/security/access.conf. O formato deste arquivo consistem em três campos separados por ":":

  • Primeiro campo - Garante ("+") ou bloqueia ("-") o acesso caso as condições nos outros campos confiram.

  • Segundo campo - Contém o login, grupo. O formato usuário@computador pode ser usado para conferir com usuários que acessam de determinadas máquinas. Caso existam mais de um parâmetro, estes devem ser separados usando espaços. As palavras chave ALL (todos) e EXCEPT (exceção) e console também podem ser usadas.

  • Terceiro campo - Lista de terminais (tty - na forma listada pelo ttyname), nomes de máquinas, nomes de domínios (começando com "."), endereços IP ou FQDN, porção de rede (finalizando com um "."). As palavras chave ALL (todos) e LOCAL (máquinas na mesma rede) também podem ser usadas.

OBS1: - A configuração padrão do access.conf é garantir o acesso a todos os usuários, através de qualquer lugar (permissiva).

OBS2:: Mesmo se existir uma regra autorizando o acesso ao usuário, as restantes serão verificadas em busca de uma que bloqueie o acesso do usuário. Se nenhuma regra conferir, o usuário terá acesso garantido.

OBS3: - O nome de grupo somente é checado quando nenhum nome de usuário confere com nenhum usuário logado no sistema.

OBS4: - Grupos/usuários NIS podem ser especificados precedendo o nome do usuário ou grupo por uma "@".

Abaixo uma configuração restrita de /etc/security/access.conf:

#
# Desabilita o login de todos os usuários EXCETO o root no terminal tty1
-:ALL EXCEPT root:tty1

# Permite o login no console de todos os usuários especificados.
+:gleydson root:console

# Conexões vindas da rede *.debian.org e *.debian.org.br de usuários pertencendo 
# ao grupo operadores são consideradas seguras (exceto para o usuário root).
+:operadores EXCEPT root: .debian.org .debian.org.br

# Qualquer outra tentativa de acesso não definida acima é bloqueada imediatamente.
-: ALL: ALL

Restringindo o acesso a root no su

A restrição de acesso a usuário root pelo PAM funciona permitindo que somente alguns usuários que pertençam a um grupo criado pelo administrador possam se tornar o superusuário usando o comando su. Esta restrição funciona até mesmo para os usuários que possuem a senha correta de root, retornando uma mensagem de login ou senha incorretos. Isto é extremamente útil para restrições de acesso.

Um outro ponto positivo é caso ocorra um possível acesso não autorizado em seu sistema ou um daemon seja corrompido e o atacante cair em um shell, ele não poderá obter root na máquina pois o UID do daemon provavelmente não terá autorização. A distribuição Debian, em especial, possui grupos e nomes de usuários organizados de forma a permitir segurança e separação total caso utilize este mecanismo.

Este recurso se mostra bem eficiente para proteger a integridade da máquina até mesmo no comprometimento de máquinas que possui a senha semelhante, somente se usado em conjunto com as restrições de acesso de outros serviços remotos (como o ssh, ftp, etc). O guia Foca documenta as formas de restrição e seu impacto na segurança da máquina nos capítulos do nível Avançado (veja o índice para buscar o capítulo correspondente ao que deseja proteger).

Para configurar esta restrição, siga os seguintes passos:

  • Crie um grupo onde os usuários cadastrados terão acesso root. Por exemplo, usuarios-su (ou algo mais discreto).

  • Edite o arquivo /etc/pam.d/su. Insira a seguinte linha (caso não existir) no arquivo de configuração:

    auth       required   pam_wheel.so group=usuarios-su
    

    O que ela faz é usar o módulo pam_wheel.so requerendo que os usuários pertençam ao grupo usuarios-su. Salve e saia do editor.

  • Ainda como usuário root, adicione os usuários que terão acesso a root no grupo usuarios-su. Recomendo que adicione seu usuário primeiro, principalmente se estiver fazendo acesso remoto, pois se acontecer uma queda no link não ficará sem acesso root por cair na restrição :-)

  • Tente pegar o root com outros usuários que não pertençam ao grupo usuarios-su estes simplesmente terão o acesso negado.

Restrições de serviços PAM baseados em dia/hora

Estas restrições são controladas pelo arquivo /etc/security/time.conf, a sintaxe deste arquivo é quatro campos separados por ";":

  • Primeiro campo - Nome do serviço PAM que será controlado (um dos serviços contidos em /etc/pam.d).

  • Segundo campo - Lista de nomes de terminais que a regra que aplicará. O sinal "&" tem a função and, "|" tem a função or e "!" especifica uma exceção.

  • Terceiro campo - Nome de usuários afetados pela regra. O sinal "&" tem a função and, "|" tem a função or e "!" especifica uma exceção.

    OBS: O "*" poderá ser usado somente no primeiro, segundo ou terceiro campo em uma mesma regra.

  • Quarto campo - DiaSemana/faixa-de-horas que a restrição se aplicará. O dia da semana é especificado em duas letras:

    • Mo - Segunda-feira

    • Tu - Terça-feira

    • We - Quarta-feira

    • Th - Quinta-feira

    • Fr - Sexta-feira

    • Sa - Sábado

    • Su - Domingo

    • Wk - Todos os dias da semana

    • Wd - Somente sábado e domingo (fim de semana)

    • Al - Todos os dias

    O sinal "!" especifica uma exceção. A faixa de horas é especificada após o dia no formato HHMM-HHMM. Por exemplo:

    MoTuWe0000-2400 - Segundas, terças e quartas 
    MoFrSu0800-1900- - Segundas, sextas e domingo das 08:00 da manha as 19:00 da noite.
    FrFr0500-0600 - Não será realizada na sexta (especificações repetidas são anuladas) 
                    de 05:00 as 06:00.
    WkWe0731-1456 - Todos os dias da semana a partir de Quarta de 07:31 da manhã as 
                    14:56 da tarde.
    AlMo0000-2400 - Todos os dias da semana, exceto segunda-feira.
    

Por padrão o acesso é garantido a todos os usuários. Abaixo um exemplo de restrições usando o /etc/security/time.conf:

# Bloqueia o login do usuário user1 ou user2 em qualquer tty, a restrição 
# durante todos os dias de 00:00 as 06:30
login;tty*;user1|user2;!Al0000-0630

# Bloqueia o acesso do usuário root ao serviço login nos terminais tty* 
# (e não nos terminais ttyp*) nos finais de semana.
login;tty* & !ttyp*;root;!Wd0000-2400

# O usuário 1 não poderá efetuar o login as terças feiras de 00:00 as 06:00
login;!tty*;user1;Tu0000-0600

OBS1: Mesmo se existir uma regra autorizando o acesso ao usuário, as restantes serão verificadas em busca de uma que bloqueie o acesso do usuário. Se nenhuma regra conferir, o usuário terá acesso garantido.

OBS2: Quando as restrições de tempo são ativadas no /etc/security/time.conf, o daemon logoutd poderá ser ativado manualmente (através de /etc/init.d/logoutd) para monitora as restrições neste arquivo, forçando o logout de usuário de acordo com as configurações do /etc/security/time.conf. Isto ocorrerá automaticamente na próxima vez que iniciar o sistema (a distribuição detecta a presença de restrições de tempo no arquivo /etc/security/time.conf para decidir se deve ou não carregar este daemon).

Quando não está em execução, os limites de tempo são verificados somente no login do usuário, ele poderá ultrapassar este tempo sem ser desconectado do sistema.

Permitindo acesso a grupos extras

Este recurso é controlado pelo arquivo /etc/security/group.conf. Este arquivo é composto por 5 campos separados por ";" (os 4 primeiros são os mesmos explicados em “Restrições de serviços PAM baseados em dia/hora”. O 5o campo contém um ou mais grupos (separados por espaços ou vírgulas) que serão adicionados aos grupos do usuário quando as condições dos campos anteriores conferirem.

OBS: Se o usuário escrever um programa que chama um interpretador de comandos e der a permissão SGID (chmod g+s programa), ele terá acesso àquele grupo na hora que quiser. Restrinja o uso de grupos somente a usuários de confiança ou crie grupos específicos para evitar problemas.

Exemplo de configuração do arquivo /etc/security/group.conf:

# Permite que o usuário gleydson tenha acesso ao grupo floppy efetuando o login
# entre 08:00 da manha e 19:00 da noite
login;tty*;gleydson;Al0800-1900;floppy

# Todos os usuários podem ter acesso ao grupo games e sound aos sábados e domingos
login;tty*;*;SaSu0000-2400;sound games

# Todos os usuários podem ter acesso ao grupo games e sound todos os dias 
# de 18:00 as 05:00 da manhã (fora do horário de expediente ;-)
login;tty*;*;Al1800-0500;sound,games

# Backups são permitidos fora do horário de expediente (para não sobrecarregar 
# a CPU e evitar o uso excessivo de disco). 
login;tty*;gleydson;Al1830-2400;backup

OBS1: Mesmo que uma regra confira com o usuário, as outras também serão verificadas para garantir acesso grupos extras.

OBS2: O padrão na maioria das distribuições é limitar o número máximo de grupos do usuário para 32. Caso precise aumentar este limite, será necessário recompilar o kernel (e também a glibc, se necessário) para aceitar um número maior modificando a variável ngroup.

Limitação de recursos do shell

Estas restrições são especificadas no arquivo /etc/security/limits.conf. Seu formato consiste em 4 campos separados por ou ou mais espaços:

  • Primeiro campo - Especifica o nome de usuário, um nome de grupo (@grupo) ou um "*" especificando que as restrições nos outros campos se aplicam a todos os grupos e todos os usuários.

  • Segundo campo - Tipo de restrição:

    • soft - Limite suave de bloqueio.

    • hard - Limite rígido de bloqueio.

    • - - Quando o tipo de restrição não se aplica ao Ítem que deseja restringir o acesso.

    Quando somente o limite "hard" (rígido) é especificado, o limite suave assume o mesmo valor.

  • Terceiro campo - Ítem que deseja restringir o acesso:

    • core - Limita o tamanho do arquivo core (KB)

    • data - Tamanho máximo de arquivo de dados (KB)

    • fsize - Tamanho máximo de arquivo (KB)

    • memlock - Tamanho máximo do espaço de endereços bloqueado na memória (KB)

    • nofile - Número máximo de arquivos abertos

    • rss - Tamanho máximo residente (KB)

    • stack - Tamanho máximo da pilha (KB)

    • cpu - Tempo máximo de uso da CPU (MIN)

    • nproc - Número máximo de processos

    • as - Limite de espaço de endereços

    • maxlogins - Número máximo de logins

    • priority - Prioridade de execução de processos de usuários

  • Quarto campo - Especifica o valor do campo anterior

Os limites aplicados ao usuário podem ser visualizados através do comando ulimit -S -a (para listar limites suaves - soft) e ulimit -H -a (para listar limites rígidos - hard). Caso o parâmetro -S ou -H sejam omitidos, os limites listados serão os suaves (soft). Um exemplo de /etc/security/limits.conf (retirado da distribuição Debian GNU/Linux:

*               soft    core            0
*               hard    rss             10000
@student        hard    nproc           20
@faculty        soft    nproc           20
@faculty        hard    nproc           50
ftp             hard    nproc           0
@student        -       maxlogins       4
gleydson        -       maxlogins       2

OBS: Estas permissões passam a ter efeito no momento que o usuário se conecta ao sistema, e não quando elas são modificadas no arquivo /etc/security/limits.conf.