Diretórios Privados com PAM_Namespace

Olá,

Lembro-me dos tempos em que ministrava os cursos da Red Hat pelo Brasil (bons tempos aqueles). Com certeza foi uma das  etapas da minha vida em que mais aprendi profissionalmente e pessoalmente. É incrível estar em lugar diferente a cada semana, com pessoas diferentes com culturas diferentes. Com certeza foi uma experiência fantástica.

Uma das perguntas frequentes que os alunos faziam, era se existia um modelo de particionamento que oferecesse uma boa relação custo vs benefício vs segurança. Acredito que a  melhor resposta para esse questionamento é obtida através de outros questionamentos: Quais serviços irão ser executados? Será utilizado quota? Como será o backup? Os usuários terão acesso remoto? Etc…

Independente do esquema de particionamento escolhido, sempre é observado a questão do diretório /tmp que além de ser compartilhado com os demais usuários, possui permissão de escrita, podendo assim gerar algum desconforto para o sysadmin ou instabilidade do sistema por conta de scripts ou usuários mal intencionados. Por exemplo, executar o comando yes, redirecionando a saída para um arquivo dentro do /tmp? Ou ainda ter acesso à informações  de outros usuários descuidados em salvar arquivos dentro do diretório /tmp.


[root@f15 ~]# yes DoS >> /tmp/disk-FULL
yes: standard output: No space left on device
yes: write error

Sendo um arquivo privado, o seu lugar não deveria ser tal diretório, porém “shit happens”!!! Geralmente cria-se então uma partição para acomodar o diretório /tmp, evitando assim  aborrecimentos causados por usuários ao executar comandos maliciosos no sistema.  Porém, como fica a privacidade dos arquivos armazenados dentro do diretório /tmp?

Com a utilização do módulo da PAM pam_namespace.so, podemos criar diretórios “poli-instanciados privados”, isto é, quando qualquer usuário acessar o diretório mapeado, será um diretório privado.

Nota: Iremos utilizar o diretório /tmp como exemplo, porém a técnica pode ser aplicada para outras situações.

A configuração do módulo pam_namespace.so se dá dentro no arquivo /etc/security/namespace.conf. Basicamente o formato de configuração do arquivo é:

diretório instância_dir_prefix tipo_de_autenticação lista_de_usuário

No primeiro campo, devemos colocar o caminho do diretório privado.

No segundo campo, iremos definir qual prefix do diretório que será utilizado para armazenar os arquivos criados pelo usuários. Esse diretório será automaticamente criado pelo módulo pam_namespace com permissão 000.

No terceiro campo, se define o método utilizado pela pam_namespace. São válidas as seguintes entradas:

  • user -> baseado no nome do usuário
  • level -> baseado no context SELinux MLS e nome do usuário. SELinux é obrigatório!
  • context -> baseado no contexto SELinux do processo e usuário. SELinux é obrigatório!
  • tmpfs -> utilização de diretório TMPFS
  • tmpdir -> para diretórios temporários que serão removidos após o logout do usuário

Por fim no quarto campo, temos a lista dos usuários (separados por vírgula) que serão excluídos dessa regra. Caso a lista inicie com o sinal “~“, a regra se aplicará somente os usuários contidos na lista. Se deixado em branco, a regra se aplicará para todos os usuários do sistema.

No intuito de exemplificar a configuração,  o /tmp será mapeado utilizando o método context para os usuários fulano e sicrano somente.

Primeiramente, iremos configurar o arquivo /etc/security/pam_namespace.conf :

Dica: abra um terminal como usuário root e deixe-o aberto durante o processo de configuração, assim em caso de problemas, você não perderá acesso de root no sistema


[root@f15 ~]# useradd  fulano
[root@f15 ~]# useradd  cicrano
[root@f15 ~]# echo senha | passwd --stdin fulano
Changing password for user fulano.
passwd: all authentication tokens updated successfully.
[root@f15 ~]# echo senha | passwd --stdin sicrano
Changing password for user sicrano.
passwd: all authentication tokens updated successfully.
[root@f15 ~]# ls -lad /tmp
drwxrwxrwt. 7 root root 4096 Jun  5 18:45 /tmp
[root@f15 ~]# cat /etc/security/namespace.conf  | grep -v ^#  | grep -v ^$
/tmp    /var/tmp/tmp-PAM_namespace    context    ~fulano,sicrano
[root@f15 ~]# setsebool -P allow_polyinstantiation 1
[root@f15 ~]# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   enforcing
Mode from config file:          enforcing
Policy version:                 24
Policy from config file:        targeted

Feito isso, nosso próximo passo será ativar o módulo pam_namespace.so dentro do arquivo /etc/pam.d/system-auth e /etc/pam.d/sshd

[root@f15 /]# cat /etc/pam.d/sshd
#%PAM-1.0
auth	   required	pam_sepermit.so
auth       include      password-auth
account    required     pam_nologin.so
account    include      password-auth

password   include      password-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context

session    required     pam_selinux.so open env_params
session	   required	pam_namespace.so debug
session    optional     pam_keyinit.so force revoke
session    include      password-auth

[root@f15 /]# cat /etc/pam.d/system-auth
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 500 quiet
auth        required      pam_deny.so

account     required      pam_unix.so
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 500 quiet
account     required      pam_permit.so

password    requisite     pam_cracklib.so try_first_pass retry=3 type=
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so
session     optional      pam_keyinit.so revoke

session     required      pam_limits.so
session	    required	  pam_namespace.so debug
-session     optional      pam_systemd.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so

Nota: é muito importante o posicionamento da linha pam_namespace.so dentro dos arquivos de configuração.

Abra uma nova sessão com o usuário root, e monitore os arquivos /var/log/messages e /var/log/secure. Acesse o sistema com os usuários fulano e sicrano e observe:

notebook $> ssh fulano@192.168.122.112
fulano@192.168.122.112's password:
Last login: Sun Jun  5 20:26:01 2011 from 192.168.122.1
[fulano@f15 ~]$ cd /tmp/
[fulano@f15 tmp]$ ls -la
total 8
drwxrwxrwt.  2 root root 4096 Jun  5 20:26 .
dr-xr-xr-x. 23 root root 4096 Jun  5 20:23 ..
[fulano@f15 tmp]$ touch private
[fulano@f15 tmp]$ exit
logout
Connection to 192.168.122.112 closed.

[root@f15 tmp]# tail -f /var/log/messages  /var/log/secure -n0

==> /var/log/messages <==

==> /var/log/secure <==

Jun  5 20:39:05 f15 sshd[1741]: Accepted password for fulano from 192.168.122.1 port 42627 ssh2
Jun  5 23:39:05 f15 sshd[1742]: fatal: mm_request_receive: read: Connection reset by peer
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): open_session - start
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): Parsing config file /etc/security/namespace.conf
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): Expanded polydir: '/tmp'
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): Expanded ruser polydir: '/tmp'
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): Expanded instance prefix: '/var/tmp/tmp-PAM_namespace/'
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): Configured poly dirs:
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): dir='/tmp' iprefix='/var/tmp/tmp-PAM_namespace/' meth=2
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): override user 500
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): override user 501
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): Set up namespace for pid 1741
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): Checking for ns override in dir /tmp for uid 500
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): Need poly ns for user 500 for dir /tmp
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): Checking for ns override in dir /tmp for uid 0
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): Checking for ns override in dir /tmp for uid 500
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): Setting poly ns for user 500 for dir /tmp
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): Set namespace for directory /tmp
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): member context returned by policy system_u:object_r:user_tmp_t:s0
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): poly_name system_u:object_r:user_tmp_t:s0_fulano
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): Inst ctxt system_u:object_r:user_tmp_t:s0 Orig ctxt system_u:object_r:tmp_t:s0
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): instance_dir /var/tmp/tmp-PAM_namespace/system_u:object_r:user_tmp_t:s0_fulano
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): Protect mount of /var/tmp/tmp-PAM_namespace over itself
Jun  5 20:39:06 f15 sshd[1741]: pam_namespace(sshd:session): namespace setup ok for pid 1741
Jun  5 20:39:06 f15 sshd[1741]: pam_systemd(sshd:session): Moving new user session for fulano into control group /user/fulano/19.
Jun  5 20:39:06 f15 sshd[1741]: pam_unix(sshd:session): session opened for user fulano by (uid=0)

Logando agora com o usuário sicrano:

notebook $> ssh sicrano@192.168.122.112
sicrano@192.168.122.112's password:
[sicrano@f15 ~]$ cd /tmp/
[sicrano@f15 tmp]$ ls
[sicrano@f15 tmp]$ touch test2
[sicrano@f15 tmp]$ ls -la
total 8
drwxrwxrwt.  2 root    root    4096 Jun  5 20:41 .
dr-xr-xr-x. 23 root    root    4096 Jun  5 20:23 ..
-rw-rw-r--.  1 sicrano sicrano    0 Jun  5 20:41 test2
[sicrano@f15 tmp]$ logout
Connection to 192.168.122.112 closed.

[root@f15 tmp]# tail -f /var/log/messages  /var/log/secure -n0

==> /var/log/messages <==

==> /var/log/secure <==

Jun  5 20:41:29 f15 sshd[1770]: Accepted password for sicrano from 192.168.122.1 port 43159 ssh2
Jun  5 23:41:29 f15 sshd[1771]: fatal: mm_request_receive: read: Connection reset by peer
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): open_session - start
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): Parsing config file /etc/security/namespace.conf
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): Expanded polydir: '/tmp'
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): Expanded ruser polydir: '/tmp'
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): Expanded instance prefix: '/var/tmp/tmp-PAM_namespace/'
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): Configured poly dirs:
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): dir='/tmp' iprefix='/var/tmp/tmp-PAM_namespace/' meth=2
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): override user 500
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): override user 501
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): Set up namespace for pid 1770
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): Checking for ns override in dir /tmp for uid 501
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): Need poly ns for user 501 for dir /tmp
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): Checking for ns override in dir /tmp for uid 0
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): Checking for ns override in dir /tmp for uid 501
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): Setting poly ns for user 501 for dir /tmp
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): Set namespace for directory /tmp
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): member context returned by policy system_u:object_r:user_tmp_t:s0
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): poly_name system_u:object_r:user_tmp_t:s0_sicrano
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): Inst ctxt system_u:object_r:user_tmp_t:s0 Orig ctxt system_u:object_r:tmp_t:s0
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): instance_dir /var/tmp/tmp-PAM_namespace/system_u:object_r:user_tmp_t:s0_sicrano
Jun  5 20:41:29 f15 sshd[1770]: pam_namespace(sshd:session): Protect mount of /var/tmp/tmp-PAM_namespace over itself
Jun  5 20:41:30 f15 sshd[1770]: pam_namespace(sshd:session): namespace setup ok for pid 1770
Jun  5 20:41:30 f15 sshd[1770]: pam_systemd(sshd:session): Moving new user session for sicrano into control group /user/sicrano/20.
Jun  5 20:41:30 f15 sshd[1770]: pam_unix(sshd:session): session opened for user sicrano by (uid=0)
Jun  5 20:41:46 f15 sshd[1780]: Received disconnect from 192.168.122.1: 11: disconnected by user
Jun  5 20:41:46 f15 sshd[1770]: pam_namespace(sshd:session): close_session - start
Jun  5 20:41:46 f15 sshd[1770]: pam_namespace(sshd:session): Resetting namespace for pid 1770
Jun  5 20:41:46 f15 sshd[1770]: pam_namespace(sshd:session): orig namespace for pid 1770
Jun  5 20:41:46 f15 sshd[1770]: pam_namespace(sshd:session): Checking for ns override in dir /tmp for uid 501
Jun  5 20:41:46 f15 sshd[1770]: pam_namespace(sshd:session): Unmounting instance dir for user 501 & dir /tmp
Jun  5 20:41:46 f15 sshd[1770]: pam_namespace(sshd:session): Unmount of /tmp succeeded
Jun  5 20:41:46 f15 sshd[1770]: pam_namespace(sshd:session): resetting namespace ok for pid 1770
Jun  5 20:41:46 f15 sshd[1770]: pam_systemd(sshd:session): Moving remaining processes of user session 20 of sicrano into control group /user/sicrano/master.
Jun  5 20:41:46 f15 sshd[1770]: pam_unix(sshd:session): session closed for user sicrano

Verificando os diretórios e arquivos criados, temos:

[root@f15 tmp]# ls -laRZ /var/tmp/
/var/tmp/:
drwxrwxrwt. root root system_u:object_r:tmp_t:s0       .
drwxr-xr-x. root root system_u:object_r:var_t:s0       ..
d---------. root root system_u:object_r:user_tmp_t:s0  tmp-PAM_namespace
/var/tmp/tmp-PAM_namespace:
d---------. root root system_u:object_r:user_tmp_t:s0  .
drwxrwxrwt. root root system_u:object_r:tmp_t:s0       ..
drwxrwxrwt. root root system_u:object_r:tmp_t:s0       system_u:object_r:user_tmp_t:s0_sicrano
drwxrwxrwt. root root system_u:object_r:tmp_t:s0       system_u:object_r:user_tmp_t:s0_fulano

/var/tmp/tmp-PAM_namespace/system_u:object_r:user_tmp_t:s0_sicrano:
drwxrwxrwt. root    root    system_u:object_r:tmp_t:s0       .
d---------. root    root    system_u:object_r:user_tmp_t:s0  ..
-rw-rw-r--. sicrano sicrano unconfined_u:object_r:user_tmp_t:s0 test2

/var/tmp/tmp-PAM_namespace/system_u:object_r:user_tmp_t:s0_fulano:
drwxrwxrwt. root   root   system_u:object_r:tmp_t:s0       .
d---------. root   root   system_u:object_r:user_tmp_t:s0  ..
-rw-rw-r--. fulano fulano unconfined_u:object_r:user_tmp_t:s0 private

A utilização do módulo pam_namespace.so não resolve todos os problemas, mas certamente é uma configuração interessante e uma carta na manga do sysadmin!

Um quebra costela, tchê!!