Liliana Esther Velásquez Alegre Solha <nina@cais.rnp.br>
Rede Nacional de Ensino e Pesquisa (RNP)
Introdução
Escolhendo o USERID / GROUPID
Entendendo a estrututa dos diretórios
Trabalhando com os arquivos de configuração
Escrevendo programas e scripts CGI seguros
Recomendações gerais
Problemas conhecidos de alguns servidores WWW
Conclusão
Referências bibliográficas
Sites relacionados
través deste artigo pretende-se, inicialmente, mostrar quais as principais implicações, em relação a segurança, associadas ao fato de se oferecer um dos serviços mais difundidos hoje na Internet, o Web. Por outro lado, serão apresentadas algumas técnicas das quais um administrador de redes pode se servir para tornar este serviço mais seguro, evitando, deste modo, que usuários inescrupulosos acessem documentos considerados sigilosos, executem comandos que permitam modificar a configuração do sistema ou, simplesmente, disparem ataques que degradem o desempenho do seu servidor.
Introdução
Sem dúvida alguma, o Web é o serviço Internet mais utilizado hoje em dia. Isto, principalmente, graças a sua versatilidade: usuários podem, por exemplo, enviar e-mails, conversar virtualmente através de chats, disponibilizar informações, pegar programas de repositórios de software e, o melhor de tudo, utilizando uma única interface.
Não é de admirar, portanto, que toda empresa, provedor de acesso, universidade, organismo governamental, etc. considerem este serviço como básico e desejem implantá-lo na sua rede local. Mas, será que existe algum risco nisto? Será que eles sabem destes riscos? Mais importante ainda, será que sabem como evitá-los?
Pensemos no seguinte: por um lado, o serviço Web foi projetado basicamente para atender a pedidos anônimos, de usuários não autenticados a fim de disponibilizar as informações requisitadas de uma maneira eficiente. Por outro lado, servidores Web, por natureza, são programas bastante complexos e, em muitos casos, o código fonte destes programas são amplamente divulgados. Conseqüentemente, tornam-se susceptíveis de serem analisados em busca de vulnerabilidades que possam ser exploradas. Se a isto acrescentamos o fato de que algumas funcionalidades do serviço Web, como as oferecidas pelo CGI, podem ser facilmente exploradas e, como se sabe, não são poucos os usuários inexperientes em programação CGI, pergunta-se: resta alguma dúvida que seu servidor Web se torna um fácil alvo de ataque?
O que fazer diante deste cenário? Existem duas alternativas, pagar por um servidor "seguro", o que na verdade é uma utopia pois não existe aplicação reconhecidamente 100% segura, ou, simplesmente, tentar contornar o problema através da aplicação de técnicas que permitam tornar seu servidor Web mais seguro. É desta segunda opção que este artigo trata, e é ao longo dele que estas técnicas serão abordadas.
Escolhendo o USERID / GROUPID
Na maioria dos servidores Web, o daemon httpd (processo "pai") é executado com permissão de root de modo que eles possam "ouvir" na porta privilegiada 80 (porta padrão para o serviço http) e também possam escrever nos arquivos de log. Assim, toda vez que é recebido um pedido de conexão na porta 80, é inicializado um processo "filho" para atender esta nova conexão, o dono e grupo destes processos são determinados pelas diretivas UserID e GroupID, respectivamente, presentes no arquivo de configuração httpd.conf.
Recomenda-se, categoricamente, que estes processos filhos não sejam rodados como root. A razão é simples: caso isto aconteça, todo script que seu servidor chamar será também executado pelo usuário root, o que obviamente poderá criar potenciais problemas de segurança. Comumente, estes processos devem ser executados como nobody, assim:
UserID nobody GroupID 1
Alguns administradores acham até mais seguro não inicializar nem o daemon (processo "pai") como root, e sim como o usuário nobody. Isto é possível. No entanto, neste caso, devem ser consideradas mudanças das permissões nos arquivos de log e mudança na porta destinada a "ouvir" as conexões no servidor.
Uma outra alternativa, pouco recomendada pelo fato de degradar o desempenho do servidor, se este for muito requisitado, é inicializar o servidor via o daemon inetd e não como um daemon mesmo. Se o administrador está ciente disto e a segurança do seu servidor fala mais alto do que o desempenho do mesmo, esta pode ser uma boa alternativa. Basta para tal:
- Acrescentar a seguinte linha no arquivo /etc/inetd.conf:
www stream tcp nowait nobody /usr/local/etc/httpd/httpd
httpd -f /usr/local/etc/httpd/conf/httpd.conf - Configurar apropriadamente, no arquivo httpd.conf, a diretiva ServerType:
ServerType inetd
- Incluir a seguinte linha no arquivo /etc/services:
www 80/tcp http #HyperText Transfer Protocol
A vantagem deste mecanismo é que todos os processos serão executados como usuário nobody e as conexões serão ouvidas na porta 80 (porta padrão).
O exemplo acima assume que o daemon encontra-se no diretório /usr/local/etc/httpd e que seu arquivo de configuração, o httpd.conf, encontra-se no diretório /usr/local/etc/httpd/conf. O administrador deve atentar para o fato de que a entrada no arquivo /etc/inetd.conf corresponde a uma única linha.
Entendendo a estrututa dos diretórios
Para rodar um servidor de maneira segura é preciso primeiro entender o propósito de cada diretório contido nele e as proteções necessárias para cada um deles.
É preciso ter um cuidado especial no que diz respeito às permissões dos subdiretórios e arquivos contidos tanto no diretório raiz do servidor (Server Root Directory), onde os scripts CGI, os arquivos de log e de configuração são armazenados, bem como no diretório onde os documentos HTML são armazenados (Document Root Directory).
Considerando a estrutura de diretórios de um típico servidor Web UNIX (o Apache 1.2.5 foi escolhido para o caso deste artigo), podemos apontar os seguintes dois esquemas como os mais seguros, ou melhor, os menos inseguros:
drwxr-x--x 3 www www 512 Jan 26 14:44 cgi-bin/ drwxr-x--- 2 www www 512 Jan 19 10:00 conf/ rwx------ 1 www www 271452 Jan 26 19:28 httpd drwxrwxr-x 8 www www 512 Jan 26 19:28 htdocs/ drwxrwxr-x 2 www www 1024 Jan 16 17:27 icons/ drwxr-x--- 2 www www 512 Jan 26 11:03 logs/
Neste caso, a estratégia consiste em criar um usuário www encarregado da administração do servidor Web (webmaster) e um grupo www para todos aqueles usuários que precisem modificar algum documento HTML. Como as atividades deste usuário são bastante definidas, é recomendável considerar como diretório home deste usuário, o próprio diretório raiz do servidor.
A desvantagem deste esquema é que, permitindo que usuários diferentes do root modifiquem qualquer arquivo que o root execute (scripts CGI, por exemplo) ou sobre os quais o root escreva (arquivos de log, por exemplo), pode estar-se comprometendo a segurança do sistema.
No esquema abaixo, onde o próprio root é o dono do diretório raiz do servidor, este problema não acontece.
Esquema 2:
drwx--x--x 3 root www 512 Jan 26 14:44 cgi-bin/ drwx------ 2 root www 512 Jan 19 10:00 conf/ rwx------ 1 root www 271452 Jan 26 19:28 httpd drwxrwxr-x 8 root www 512 Jan 26 19:28 htdocs/ drwxrwxr-x 2 root www 1024 Jan 16 17:27 icons/ drwx------ 2 root www 512 Jan 26 11:03 logs/
Repare que o modo de acesso do diretório cgi-bin foi configurado como 711, isto permite executar programas/scripts contidos nele mas não listá-los, nem mesmo para os usuários locais. Os scripts propriamente ditos, contidos neste diretório, deverão ter, necessariamente, permissão 755 para que posssam ser executados corretamente.
No que diz respeito às permissões dos arquivos de configuração, todos eles deverão ter permissão de escrita e leitura para root, como mostrado a seguir:
-rw------- 1 root other 2189 Jan 26 10:59 access.conf -rw------- 1 root other 6735 Nov 26 16:51 httpd.conf -rw------- 1 root other 6909 Oct 2 16:30 srm.conf
Trabalhando com os arquivos de configuração
Nesta seção, não se pretende analisar detalhadamente cada um dos arquivos de configuração mencionados anteriormente, mesmo por que isto não seria possível num único artigo, mas a idéia é mostrar como diminuir os riscos de segurança através da configuração correta destes arquivos.
-
Desabilitando a listagem automática de diretórios
Se na maioria dos casos esta opção é vantajosa, esta facilidade também possibilita a estranhos ter acesso a informações sigilosas. As diretivas IndexIgnore e IndexOptions , presentes no arquivo srm.conf podem ser configuradas de modo a contornar este problema.
-
Links simbólicos
Alguns servidores permitem seguir links simbólicos fora da árvore de diretório de documentos fazendo com que arquivos sigilosos possam ser acessados via Web. Para evitar este problema, sugere-se incluir alguma das seguintes linhas no arquivo access.conf:
Options Indexes FollowSymLinks Options SymLinksIfOwnerMatch
-
Desabilitando os famosos Server Side Includes (SSI)
Os SSI podem ser configurados de modo que usuários remotos possam executar comandos arbitrários no servidor. Se esta facilidade não for realmente necessária, recomenda-se desabilitá-la no arquivo access.conf através da diretiva Options:
Options IncludesNoExec
-
Protegendo os arquivos do servidor
Considere o seguinte exemplo:
1. # cd /; ln -s / public_html 2. Acessando http://localhost/~root
Isto permitirá a usuários remotos, navegar tranquilamente pelo sistema de arquivos inteiro. Mas, fique calmo, pois isto pode ser contornado incluindo as seguintes linhas no arquivo access.conf:Order deny,allow Deny from all
Por outro lado, se você quiser permitir o acesso a diretórios específicos, basta acrescentar linhas do tipo:Order deny,allow Allow from all
-
Evitando que configurações dos usuários prevaleçam sobre as configurações do sistema
Basta incluir, no arquivo de configuração do servidor (access.conf), as seguintes linhas:
AllowOverride None Options None allow from all
-
Protegendo documentos confidenciais
Existem, tipicamente, dois tipos de restrição de acesso:
- Restrição por endereço IP, subrede ou domínio
- Restrição por nome e senha de usuário.
Nenhum destes dois tipos de restrições é completamente seguro. Ambos têm as suas deficiencias.
O primeiro caso , por exemplo, é vulnerável a ataques do tipo DNS spoofing, IP spoofing. Você também não tem a certeza que o usuário que está por trás da máquina "confiável" seja quem você espera. Ou, ainda pior, esta máquina pode ter sofrido uma invasão e simplesmente está sendo usada para acessar os documentos sigilosos.
No segundo caso, vêem-se dois problemas principais: o uso de senhas facilmente quebráveis (seja via método de tentativa e erro ou via força bruta) e o fato deste tipo de restrição ser susceptível a ataques do tipo sniffing.
A combinação de ambos os métodos tem se mostrado como uma boa alternativa. Detalhes de como implementá-los vão depender do servidor escolhido. Como mencionado anteriormente, o artigo considerou o servidor Apache 1.2.5. Assim, a diretiva Satisfy pode ser utilizada quando for considerado o uso simultâneo dos dois métodos.
Para restringir o acesso a documentos contidos num determinado diretório, utilizando o mecanismo de IPs e domínios, basta acrescentar no arquivo access.conf linhas do tipo:
order mutual-failure deny from all allow from 200.144.121 .cais.rnp.br allow from 200.136.100.17 halley.na-cp.rnp.br
Isto nega o acesso a diretorio_protegido a partir de qualquer máquina, exceto às pertencentes à rede de domínio cais.rnp.br (200.144.121) e à máquina halley.na-cp.rnp.br (200.136.100.17).Para restringir o acesso a documentos contidos num determinado diretório, utilizando o mecanismo de usuários/senhas, existem duas alternativas:
- Acrescentar, no arquivo access.conf, para cada diretório, linhas do tipo:
AuthName Titulo_da_caixa_de_dialogo AuthType Basic AuthUserFile /usr/local/etc/httpd/conf/passwd require valid-user
- Criar, individualmente, arquivos .htaccess (default) e colocá-los, respectivamente, dentro dos diretórios a serem protegidos. Cada um destes arquivos deverá conter linhas do tipo:
AuthName Titulo_da_caixa_de_dialogo AuthType Basic AuthUserFile /usr/local/etc/httpd/conf/passwd require valid-user
Escrevendo programas e scripts CGI seguros
Intencionais, ou não, os maiores furos de segurança são encontrados nos scripts CGI. O maior problema destes scripts é que os erros de codificação são bastante sutis, permitindo, em alguns casos, o vazamento de informações do servidor (ou do sistema) ou até mesmo a execução de comandos arbitrários no servidor.
Recomenda-se, portanto, tomar os seguintes cuidados ao escrever um script CGI:
- Analisar sempre os dados de entrada do usuário (por exemplo, verificar se tem algum ";" no meio da URL solicitada);
- Invocar programas usando caminhos absolutos;
- Evitar incluir neles maiores informações que possam ser aproveitadas por hackers;
- Para ter um melhor controle, recomenda-se colocar todos os scripts num único diretório (comumente o /cgi-bin) e configurar isto no arquivo srm.conf;
- Caso decida-se implementar uma política de permissões como mostrado no Esquema 1, deve-se lembrar que é assumida uma total confiança na conduta dos usuários que escrevem os scripts CGI;
- Os scripts deverão ser criados com permissão 755.
Detalhes mais completos relacionados a problemas de segurança com scripts CGI serão abordados numa próxima edição do NewsGeneration.
Recomendações gerais
Além das técnicas anteriormente abordadas, é importante tomar algumas precauções gerais visando tornar o seu servidor WWW mais seguro. Por exemplo:
- Isolar, se possível, o seu servidor Web de outros servidores públicos (mail, DNS, etc). Num esquema de firewalls é recomendável colocar seu servidor Web público conectado à rede externa;
- Verificar, com freqüência, os arquivos de log em busca de atividades suspeitas (ex.: pedidos de URL muito longas);
- Monitorar, periodicamente, mudanças não autorizadas nos arquivos de configuração, nos scripts CGI, etc. A ferramenta Tripwire pode-se tornar uma grande aliada nesta tarefa;
- Desativar os scripts não usados, scripts que normalmente acompanham a distribuição do servidor, mas que não são usados.
- Estar ciente dos possíveis problemas de integrar os serviços Web e FTP Anônimo, principalmente, se, por alguma razão irremediável, seus usuários precisam depositar (fazer "upload") arquivos no seu servidor FTP;
- Acompanhar os alertas de segurança via listas de discussão, repositórios de órgãos especializados em segurança, etc.
Problemas conhecidos de alguns servidores WWW
A título de ilustração, foram levantadas as vulnerabilidades de servidores WWW nos sistemas UNIX e NT, que são os mais usados hoje em dia.
Se existe um destes servidores rodando em sua instituição, então é recomendável que ele seja atualizado para a versão mais recente do pacote, ou que sejam aplicados os patches respectivos que corrijam os bugs abaixo mencionados.
SERVIDORES NT
-
Bug: Permite que usuários remotos, não autorizados, acessem documentos supostamente protegidos por senha e por IP. Estes documentos têm como característica principal o nome longo (i.e. não atendem à nomenclatura DOS 8.3).
-
Bug: Scripts .bat (executados em batch) podem permitir executar o comando dir no servidor.
-
Bug: Permite a qualquer usuário remoto, ao invocar o executável perl.exe com alguns parâmetros, executar no próprio servidor, um conjunto arbitrário de comandos em Perl.
-
Bug: Devido a um ataque do tipo DOS (no caso, envio de uma URL de tamanho grande) por parte de usuários remotos, é possível que o servidor pare de funcionar.
-
Bug: Permite a qualquer usuário remoto invocar um conjunto arbitrário de comandos DOS no servidor.
SERVIDORES UNIX
-
Bug: Permite a usuários remotos acessar um servidor ao solicitar uma URL extremamente longa.
-
Bug: Os scripts CGI cgi_src/util.c e src/util.c, que acompanham, respectivamente, as distribuições (anteriores a 1.4 e anteriores a 1.5) do servidor NCSA, incluem um bug que permite a qualquer usuário remoto executar comandos UNIX arbitrários no servidor. O famigerado ataque via "phf" se enquadra nesta categoria, pois este programa faz chamada a uma função de biblioteca presente no arquivo cgi-src/util.c.
-
Bug: Usuários locais podem executar comandos UNIX com permissão igual à do servidor Web. Isto não é nada seguro quando estes usuários locais tornam-se "pouco confiáveis", como no caso de usuários conectados a um provedor de acesso.
-
Bug: Permite a usuários remotos enviar cookies extremamente grandes ao servidor Web, ocasionando o estoro da pilha. Conseqüentemente, comandos UNIX arbitrários poderão ser executados.
-
Bug: Permite a usuários remotos visualizar o conteúdo de qualquer diretório de documentos Web, mesmo ele contendo uma página do tipo index.html.
Conclusão
Não existe servidor Web totalmente seguro. O que é possível é tornar o seu servidor mais seguro utilizando técnicas de configuração adequadas. Os administradores de redes devem tomar conhecimento destas técnicas e fazer uso das mesmas.
Referências bibliográficas
Practical UNIX & Internet Security
by Simson Garfinkel and Gene Spafford, 2nd Edition, 1996,O'Reilly & Associates, Inc.
Sites relacionados
The World Wide Web Security FAQ
Security Tips for Server Configuration
Apache HTTP Server Project: Documentation
NewsGeneration, um serviço oferecido pela RNP – Rede Nacional de Ensino e Pesquisa
Copyright © RNP, 1997 – 2004