Proteja o servidor web e o banco de dados com mod_selinux e SEPostgreSQL
REDES
Um muro para a Web
O módulo mod_selinux do Apache ajuda a tapar os
buracos que vão além do controle do firewall.
por Thorsten Scherf
A
plicativos web são um vetor
de ataque popular na invasão de sistemas (figura 1).
Sistemas de firewall tradicionais não
conseguem proteger contra ataques
de injeção SQL e cross-site scripting,
o que significa que um erro em um
aplicativo web pode ter consequências fatais. Por um lado, os aplicativos
web são extremamente dinâmicos e
complexos; por outro lado, o desenvolvedor de um aplicativo web não
pode adivinhar o futuro para antecipar e eliminar perigos em potencial
antes que eles ocorram.
64
ModSecurity
O módulo ModSecurity do Apache
[1], que usa regras para filtrar conteúdo suspeito nos dados recebidos,
tornou-se uma ferramenta popular
para impedir a entrada de intrusos.
Pacotes de dados que não correspondem aos padrões permitidos são
descartados.
Essa abordagem consegue barrar
uma grande porcentagem de pacotes maliciosos antes que cheguem
ao aplicativo web, mas o que acontece com aqueles que conseguem
passar? Sistemas que dependem
de casamento de padrões detectam
apenas os padrões conhecidos e,
portanto, falham ao encontrar algo
desconhecido. Além disso, uma vez
que o intruso já tenha entrado, as
possibilidades de estender o ataque
são infinitas.
Com relação ao sistema operacional, os administradores conseguem
resolver esse problema com a introdução de um esquema MAC (Mandatory Access Control – Controle
Obrigatório de Acesso), que permite
o ajuste das permissões empregadas
a recursos específicos. Nos últimos
http://www.linuxmagazine.com.br
mod_selinux | SEGURANÇA
Site
Outros
7%
47%
33%
67%
53%
93%
2006
2007
2008
Figura 1A porcentagem de ataques de rede direcionados a servidores web aumenta a cada ano. (Fonte: Little Earth
Corporation)
anos, o SELinux estabeleceu-se como
uma importante ferramenta para
implantar MACs em ambientes de
alta segurança, mas o problema é
que o SE apenas restringe o acesso
aos recursos do sistema. Os novos
ataques concentram-se em servidores
de aplicativos web e bancos de dados.
O SEPostgreSQL (Security Enhanced PostgreSQL) [2] e o mod_selinux
[3] ampliam a proteção oferecida
pelo SELinux a objetos de bancos
de dados e aplicativos web.
Como funciona
O SEPostgreSQL é uma extensão do
popular sistema de banco de dados
PostgreSQL que suporta a atribuição de um contexto de segurança
SELinux a objetos individuais. Em
um banco de dados PostgreSQL
clássico, o usuário se conecta usando
um nome de usuário e uma senha.
Com isso, ele tem acesso a todos os
objetos disponíveis para sua conta.
Com o SEPostgreSQL, o socket do
cliente recebe um contexto de segurança que pode ser de um usuário
buscando acesso ou o contexto do
processo que o está acessando.
O administrador do SEPostgreSQL
pode atribuir rótulos de segurança a
tabelas individuais e a qualquer objeto que elas contenham e, por isso,
as regras centralizadas do SELinux
Linux Magazine #63 | Fevereiro de 2010
definem qual usuário ou processo
pode ou não acessar cada um dos
objetos do banco de dados.
Como no caso típico do SELinux,
dois controles de acesso devem ser
negociados antes que o usuário ou
o processo tenha acesso ao objeto
solicitado. Primeiro, as credenciais
são verificadas pelo sistema de autenticação do banco de dados; em um
segundo passo, o sistema verifica se
o rótulo de segurança do socket de
acesso possui privilégios suficientes
para o objeto requisitado.
Esses dois testes precisam ser efetuados com sucesso para que o banco
de dados sirva o objeto requisitado.
O administrador do banco de dados
também só pode acessar um objeto
específico caso o administrador de
segurança tenha dado autorização
explícita a esse acesso por meio de
uma regra do SELinux.
Diferentemente de objetos de sistema tradicionais, tais como arquivos
e diretórios, onde o contexto de segurança é armazenado em seus atributos, o SEPostgreSQL armazena o
contexto de segurança de um objeto
do banco de dados em um catálogo
de sistema especial. Catálogos de
sistema de bancos de dados relacio-
Listagem 1: Arquivo /etc/httpd/conf.d/mod_selinux.conf
01
02
03
04
05
06
07
<Directory “/var/www/html”>
# HTTP Basic Authentication
AuthType
Basic
AuthName
“Secret Zone”
AuthUserFile /var/www/htpasswd
Require
valid-user
</Directory>
Listagem 2: Arquivo /etc/httpd/conf.d/mod_selinux.conf
01
02
03
04
05
06
07
### O mod_selinux.conf pode acessar um
### arquivo local para mapear usuários
### a contextos de segurança
selinuxDomainMap /var/www/mod_selinux.map
selinuxDomainVal anon_webapp_t:s0
selinuxDomainEnv SELINUX_DOMAIN
65
SEGURANÇA | mod_selinux
Listagem 3: Arquivo /var/www/mod_selinux.map
01
02
03
04
foo
bar
_anonymous__
*
*:s0:c0
*:s0:c1
anon_webapp_t:s0
user_webapp_t:s0
Listagem 4: Comando chcat
01 # chcat -L
02 s0
03 s0-s0:c0.c255 SystemLow-SystemHigh
04 s0:c0.c255
SystemHigh
05 s0:c1
Marketing
06 s0:c2
Payroll
07 s0:c3
IT
08
09 chcat +IT /var/www/virtual/www1/index.html
10 ls -lZ /var/www/virtual/www1/index.html
11 -rw-rw-r-- root apache root:object_r:httpd_sys_content_t:IT /var
/www/virtual/www1/index.html
nais geralmente incluem dados de
esquema e outras metainformações.
O SEPostgreSQL introduz um
outro catálogo intitulado sg_security
e o usa para armazenar o mapeamento entre o contexto de segurança de
um objeto e o OID (Object Identifier
– Identificador do Objeto) correspondente. Quando um novo objeto
é criado no banco de dados, ele recebe um OID numérico. O próprio
banco de dados faz a resolução do
OID para uma string convencional
necessária ao contexto de segurança.
Módulo mod_selinux
O módulo mod_selinux do Apache
permite que o administrador inicie
diferentes instâncias do servidor web
com um contextos de segurança individuais em vez de usar o mesmo
contexto para vários processos. O
contexto de segurança designado a
uma instância de um servidor web
depende do usuário que a acessa.
O método é semelhante ao login
tradicional pelo shell. Após uma autenticação bem-sucedida pelo login
ou ssh, o usuário do shell recebe
um contexto de segurança. Com
isso, ele pode trabalhar no sistema
dentro das restrições de segurança
desse contexto. Caso o usuário tente fazer algo que não seja permitido
pelo contexto, o SELinux impedirá
que isso aconteça.
No caso do mod_selinux, é o Apache que age como agente ou proxy
de um usuário. Se um usuário se
conecta à sua conta, o processo do
servidor web aplicará o contexto
do usuário.
Para ver os direitos concedidos a
um processo, é possível consultar o
servidor de segurança embutido no
kernel para conferir os objetos que
o usuário pode e não pode acessar.
Quando o SEPostgreSQL é usado
como back-end de um aplicativo
web, os controles de acesso se estendem a objetos individuais dentro do
banco de dados.
Configuração do
mod_selinux
Antes de começar a configuração,
é necessário instalar o pacote do
mod_selinux, já presente nos repositórios da maioria das distribuições
GNU/Linux; se sua distribuição não
contém uma versão do módulo,
é possível baixá-lo do repositório
do Projeto Fedora [3]. Depois de
terminar a instalação em um sistema Fedora 11, o arquivo mod_selinux.conf estará no diretório /etc/
httpd/conf.d.
Contexto
Após a instalação do mod_selinux,
a próxima pergunta é: “como os
usuários receberão o contexto
de segurança para um aplicativo web?”. O mod_selinux pode
atribuir um contexto de várias
maneiras, todas descritas no seu
arquivo de configuração. Em primeiro lugar, é preciso informar ao
Apache qual o diretório ou local
onde a autenticação do usuário
é necessária. A listagem 1 mostra
um exemplo de autenticação que
utiliza um arquivo local com os
nomes de usuários e hashes MD5
de suas senhas.
Listagem 5: sesearch
01
02
03
04
05
06
07
08
66
# sesearch --allow -s user_webapp_t
Found 120 semantic av rules:
allow user_webapp_t public_content_t : file { ioctl read getattr lock open} ;
allow user_webapp_t public_content_t : dir { ioctl read getattr lock search open } ;
allow user_webapp_t public_content_t : lnk_file { read getattr } ;
allow user_webapp_t sysctl_kernel_t : file { ioctl read getattr lock open } ;
allow user_webapp_t sysctl_kernel_t : dir { ioctl read getattr lock search open } ;
...
http://www.linuxmagazine.com.br
mod_selinux | SEGURANÇA
O comando a seguir adiciona um
usuário ao arquivo de senhas:
# htpasswd -m /var/www/htpasswd foo
A listagem 2 contém mais configurações. A instrução selinuxDomainMap especifica um arquivo local que
atribui um contexto de segurança
para cada usuário; como alternativa,
pode-se usar selinuxDomainVal para
estabelecer um contexto padrão.
Um arquivo de mapeamento seria
semelhante à listagem 3.
Após a autenticação, os processos
do servidor web para as duas requisições do usuário encontram-se no
domínio do SELinux user_webapp_t
, com a MLS (Multi-Level Security
– Segurança Multi-Nível) do SELinux com sensibilidade de nível s0 e
categorias c0 (foo) e c1 (bar) na MCS
(Multi-Category Security – Segurança Multi-Categoria). O arquivo dá
acesso a objetos que pertencem a
essas categorias e que podem acessar
o domínio user_webapp_t. As categorias MCS dos objetos de arquivos
são determinadas pela ferramenta
chcat (listagem 4).
Se um usuário não estiver listado
no arquivo de mapeamento, só poderá ter acesso por meio do domínio
user_webapp_t, a menos que a categoria MCS esteja definida. A ferramenta sesearch informa se o acesso
a objetos no domínio user_webapp_t
é permitido (listagem 5). Essas regras
são adicionadas à política do SELinux através do pacote mod_selinux.
pp. Esse pacote é automaticamente
carregado após a instalação do mod_
selinux, como confirma a chamada
ao semodule:
# semodule -l |grep mod_selinux
mod_selinux 2.2
Logicamente, é possível adicionar
suas próprias regras à política, mas
elas precisam estar reunidas em um
pacote. Qualquer acesso não autenti-
Linux Magazine #63 | Fevereiro de 2010
Listagem 6: Tabela uaccount
01 # su sepgsql
02 # createdb web
03 # psql web
04 ...
05
06 web=# CREATE TABLE uaccount (
07 web(# uname TEXT PRIMARY KEY,
08 web(# upass TEXT,
09 web(# udomain TEXT
10 web(# );
11
12 web=# INSERT INTO uaccount VALUES (‘foo’, ‘pass’, ‘user_
webapp_t:s0:c0’);
13 web=# INSERT INTO uaccount VALUES (‘bar’, ‘pass’, ‘user_
webapp_t:s0:c1’);
cado ao servidor web é roteado para
o domínio anon_webapp_t do SELinux, como especificado no arquivo
de mapeamento.
Configurando o
SEPostgreSQL
Na autenticação de usuários em domínios maiores, é preferível armazenar
os usuários em um banco de dados,
principalmente se o sistema de banco
de dados for necessário para hospe-
dar seu aplicativo web. O exemplo
a seguir usa o SEPostgreSQL como
banco de dados.
A vantagem é que o administrador
pode mapear todos os objetos desse
banco de dados para um contexto
de segurança, o que não seria possível com outros sistemas de bancos
relacionais.
Na maioria das distribuições
GNU/Linux, é possível usar o repositório de software padrão para
a instalação; caso não seja possível,
Listagem 7: Arquivo /etc/httpd/conf.d/mod_selinux.conf
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
LoadModule dbd_module modules/mod_dbd.so
LoadModule authn_dbd_module modules/mod_authn_dbd.so
# Parâmetros para conexão ao banco de dados
DBDriver pgsql
DBDParams “dbname=web user=apache”
# Autenticação por digest
<Directory “/var/www/html”>
AuthType Digest
AuthName “Secret Zone”
AuthDigestProvider dbd
AuthDBDUserRealmQuery \
“SELECT md5(uname || ‘:’ || $2 || ‘:’ || upass), udomain, \
%s=%s as dummy FROM uaccount WHERE uname = $1”
# Mapeamento de contexto do SELinux
selinuxDomainEnv AUTHENTICATE_UDOMAIN
selinuxDomainVal anon_webapp_t:s0
</Directory>
67
SEGURANÇA | mod_selinux
o código-fonte está disponível no
Google Code [4].
Após a instalação, é necessário
inicializar o banco de dados com
os comandos abaixo:
# /etc/init.d/sepostgresql initdb
# /etc/init.d/sepostgresql start
O acesso administrativo ao banco
é feito por meio de uma conta padrão
(sepgsql) criada pelos comandos acima. Ela permite que o administrador
crie um banco de dados inicial para
armazenar os objetos do usuário
(listagem 6).
Com isso, é possível usar o arquivo
de configuração mod_selinux.conf para
acessar esses objetos na autenticação
de usuários pelo aplicativo web. O
contexto de segurança correspondente a cada objeto usuário já existe
no banco de dados, o que elimina a
necessidade de mapeamento. Os comandos necessários para configurar
o mod_selinux estão na listagem 7.
Em primeiro lugar, é preciso carregar os módulos do Apache neces-
Listagem 8: Contexto de Segurança para entradas de
bancos de dados
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# su sepgsql
# createdb footballdb
# psql footballdb
Welcome to psql 8.3.7, the PostgreSQL interactive terminal.
Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
footballdb=#
footballdb(#
footballdb(#
footballdb(#
footballdb(#
footballdb(#
CREATE TABLE clubs (
id
integer primary key,
nome
varchar(32),
ranking integer,
pontos integer
);
footballdb=# INSERT INTO clubs (id, nome, ranking, pontos)
footballdb-# VALUES (1, ‘Manchester United’, 1, 72);
footballdb=# SELECT security_context, * FROM clubs;
security_context | id | nome | ranking | pontos
––––––––––––----–+–---+––---–+––-------+––----unconfined_u:object_r:sepgsql_table_t:s0 | 1 | Manchester United
| 1 |
72
27 (1 row)
28
29 footballdb=# UPDATE clubs SET security_context =
‘system_u:object_r:public_content_t:s0’ WHERE nome=’Manchester
United’;
30
31 footballdb=# SELECT security_context, * FROM clubs;
32
33 security_context | id | nome | ranking | pontos
34 –––––––––––----––+–---+–---––+–------–-+––----35 system_u:object_r:public_content_t:s0 | 1 | Manchester United
| 1 | 72
36 (1 row)
68
sários para acessar o banco de dados.
Depois, os próximos dois parâmetros
especificam os nomes do driver e as
credenciais exigidas para acessar o
PostgreSQL. Esses parâmetros são
seguidos da autenticação do usuário,
onde a variável AUTHENTICATE_UDOMAIN
é usada para passar os dados de autenticação para o mod_selinux. O
usuário que não conseguir se conectar ainda pode usar o contexto
de segurança anon_webapp_t como
segunda opção.
SEPostgreSQL
com MAC
Como exemplo, as seções a seguir
descrevem a configuração do SELinux em um sistema gerenciador de
banco de dados relacional usando
SEPostgreSQL. A listagem 8 mostra
o fluxo esquematizado. Em primeiro
lugar, é necessário conectar-se ao
SGBD com privilégios de administrador e criar um novo banco de dados – footballdb, neste caso. Depois,
use o aplicativo cliente Psql para se
conectar ao banco de dados e criar
uma nova tabela – clubs neste exemplo. Em seguida, é adicionar uma
única entrada à tabela.
A primeira declaração SELECT gera
essa entrada. Como se pode ver, já
há um contexto de segurança. O tipo
deste contexto de segurança padrão
é sepgsql_table_t para o acesso a partir do domínio unconfined_t. Apenas
uma declaração de atualização é
necessária para mudar o contexto.
O último comando SELECT verifica
se a entrada possui agora um novo
contexto de segurança.
O contexto pode ser aplicado
individualmente a colunas, assim
como a registros no banco de dados
(listagem 9). A listagem 9 mostra uma
tabela com dados de funcionários; a
ideia é aplicar o contexto de segurança
sepgsql_secret_table_t a essa coluna.
Os usuários comuns no domínio de
usuários do SELinux não têm per-
http://www.linuxmagazine.com.br
mod_selinux | SEGURANÇA
missão para acessá-lo, como confirmam as duas declarações SELECT. O
comando SELECT sepgsql_getcon()
retorna o contexto de segurança do
socket de acesso; neste caso, o domínio de usuário user_t. O último
SELECT tenta acessar todas as colunas
da tabela de funcionários. Isso causa
um erro no SELinux, pois o acesso
ao tipo de objeto de banco de dados
sepgsql_secret_table_t não é permitido ao domínio user_t. As regras para
isso foram acrescentadas ao pacote
de políticas sepostgresql-devel.pp, que
contém a regra global do SELinux
para instalar o SEPostgreSQL. Assim
como no mod_selinux, é possível
acrescentar suas próprias regras. A
página de manual do sepostgresql
lista todos os tipos do SELinux suportados e suas respectivas permissões.
Para decidir sobre o acesso a objetos no banco de dados, o SEPostgreSQL sempre usa o contexto do socket
utilizado pelo cliente para acessá-lo.
Esse contexto pode ser o de segurança
do processo usado para o acesso (por
exemplo, httpd_t) ou o contexto do
shell do usuário (user_t, por exemplo).
O psql usa uma declaração SELECT sepgsql_getcon() para exibir o contexto
do socket que o está acessando. Se o
acesso for originado em um servidor
Apache ou em outra máquina, em
vez da máquina local, o SEPostgreSQL obviamente enxergará somente
o contexto do socket de rede usado
para acessá-lo. Porém, o uso de rótulos na rede é uma solução elegante,
pois suporta túneis IPSec arbitrários
entre vários sistemas para estender o
contexto de segurança de um processo
além das fronteiras da rede.
Conclusões
Graças ao mod_selinux, agora é possível iniciar processos individuais do
servidor web (ou threads individuais,
para ser mais exato) com um contexto
de segurança individual. Com isso,
o administrador pode usar as regras
do SELinux para definir os objetos
Linux Magazine #63 | Fevereiro de 2010
Listagem 9: Contexto de segurança para colunas
01 foo=# CREATE TABLE employee (
02 foo(# mid integer primary key,
03 foo(# mname varchar(32),
04 foo(# esalary varchar(32) CONTEXT = ‘system_u:object_r:sepgsql
_secret_table_t:s0’
05 foo(# );
06
07 foo=# GRANT ALL ON employee TO PUBLIC;
08
09 foo=# SELECT sepgsql_getcon();
10 sepgsql_getcon
11 ––––––––12 user_u:user_r:user_t:s0
13 (1 row)
14
15 foo=# SELECT * FROM employee;
16 ERROR: SELinux: denied { select } \
17
scontext=user_u:user_r:user_t:s0 \
18
tcontext=system_u:object_r:sepgsql_secret_table_t:s0 \
19 tclass=db_column name=employee.esalary
que têm permissão de acesso a essas
threads individuais. Examinando mais
atentamente a documentação, notase que há muitas outras aplicações
para isso. Por exemplo, é possível
usar o mod_selinux para iniciar hosts
virtuais individuais do Apache com
seus próprios contextos de segurança, ou definir um contexto com base
no endereço IP da máquina que está
acessando o servidor.
O mod_selinux oferece uma abordagem mais granular do que nunca
para acessar objetos do SELinux.
Apesar do AppArmor oferecer uma
solução similar, ele requer um servidor Apache especial, o que não
acontece com o mod_selinux. E,
caso o SEPostgreSQL seja usado
como banco de dados, o controle
obrigatório de acesso pode ser estendido aos objetos do banco de
dados. Uma combinação dos dois
sistemas promete grandes benefícios de segurança no uso de aplicativos web. n
Mais informações
[1]Módulo ModSecurity: http://www.modsecurity.org/
[2]SEPostgreSQL: http://wiki.postgresql.org/wiki/SEPostgreSQL
[3]Pacote do mod_selinux para Fedora:
https://admin.fedoraproject.org/pkgdb/packages/name/mod_selinux
[4]Download do SEPostgreSQL: http://code.google.com/p/sepgsql/
Gostou do artigo?
Queremos ouvir sua opinião. Fale conosco em
[email protected]
Este artigo no nosso site:
http://lnm.com.br/article/3278
69
Download

Um muro para a Web