Criar um servidor IIS 7.0 personalizado

por Mike Volodarsky

Introdução

O IIS 6.0 e as versões anteriores implementaram a maior parte da funcionalidade de servidor amplamente usada dentro do próprio servidor. Por outro lado, o mecanismo de servidor Web do IIS 7.0 e superior fornece uma arquitetura modular sobre a qual praticamente todos os recursos do servidor são fornecidos como componentes conectáveis. Com isso, é possível realizar grandes aprimoramentos de maneira abrangente, incluindo:

  • Capacidade de controlar exatamente qual conjunto de recursos é carregado/usado no servidor, removendo os recursos desnecessários para reduzir a área da superfície de ataque/o volume do servidor
  • Capacidade de substituir cada recurso por implementações personalizadas ou de terceiros
  • Capacidade de especializar o servidor de acordo com a respectiva função na topologia do servidor
  • Controle avançado sobre o conjunto de recursos do servidor, tanto em um nível refinado quanto no nível de delegação do aplicativo

Esses componentes do servidor, conhecidos como módulos, são carregados durante a inicialização do processo de trabalho do pool de aplicativos e fornecem serviços de processamento de solicitação no servidor. Cada aplicativo do IIS 7.0 e superior é uma combinação de serviços disponibilizados por módulos habilitados para o aplicativo e do conteúdo associado usado por esses serviços. O servidor fornece duas funções principais executadas por módulos:

  • Oferecer serviços de solicitação, como autenticação ou cache de saída (semelhante aos filtros ISAPI no IIS 6.0)
  • Fornecer tratamento de solicitações, como tratamento de arquivos estáticos, CGI ou processamento de páginas ASP.NET (semelhante às extensões ISAPI no IIS 6.0)

Com a habilitação de diferentes módulos, o servidor pode ser configurado para fornecer os serviços exigidos pelos aplicativos no servidor.

As tarefas ilustradas neste artigo incluem:

  • Revisão da configuração do servidor, do padrão e do conjunto de módulos carregados no servidor por padrão
  • Remoção de todos os módulos para remover tudo do servidor, deixando só a configuração mínima, e examinar o efeito no volume
  • Como criar um servidor personalizado adicionando módulos de maneira incremental para dar suporte a um cenário específico

Revisão da configuração do módulo padrão

A configuração do servidor principal está contida no arquivo applicationHost.config, localizado no diretório %windir%\system32\inetsrv\config\ da configuração do IIS. Analisamos a seguinte configuração contida no grupo de seções <system.webServer>:

Seção <globalModules>. Esta seção de nível do servidor contém a lista de módulos carregados pelo processo de trabalho do servidor e as DLLs nativas associadas que implementam a funcionalidade deles.

Seção <modules>. Esta seção de nível do aplicativo contém a lista de módulos habilitados para um aplicativo específico. A seção serve para selecionar o subconjunto de módulos carregados que devem estar ativos em um aplicativo e para carregar módulos adicionais no nível do aplicativo.

Seção <handlers>. Esta seção de nível da URL contém os mapeamentos de manipulador que o servidor usa para mapear solicitações de entrada para um módulo específico que as processará. Isso é semelhante aos mapas de scripts do IIS 6.0 ou ao ASP.NET e fornece um mapeamento unificado das solicitações aos manipuladores de tipo de conteúdo nativo e gerenciado.

A descrição completa de todos os módulos do IIS está disponível na Visão geral dos módulos do IIS 7.0 e superior.

Criar um backup de configuração

Primeiro, faremos backup da configuração do servidor para que possamos restaurá-la, se necessário. Execute o seguinte comando em um prompt de comando em execução como Administrador:

%windir%\system32\inetsrv\appcmd add backup initial

Em seguida, podemos restaurar a configuração do servidor para o estado inicial executando:

%windir%\system32\inetsrv\appcmd restore backup initial

Examinar a lista padrão de módulos

Navegue até a seção <system.webServer>/<globalModules>. Esta seção, que só pode ser configurada no nível do servidor, contém os módulos carregados por processo de trabalho do servidor. Cada entrada configura um módulo com um nome específico e a DLL que implementa a funcionalidade desse módulo:

<globalModules>

    <!--several modules omitted -->

    <add name="BasicAuthenticationModule" image="…\authbas.dll" />

    <add name="WindowsAuthenticationModule" image="…\authsspi.dll" />

</globalModules>

Dê uma olhada nos nomes dos vários módulos na configuração de servidor padrão: vemos serviços que já conhecemos fornecidos como parte do servidor no IIS 6.0:

Módulo de Autenticação do Windows, autenticação de solicitação NTLM

<add name="WindowsAuthenticationModule" image="…\authsspi.dll" />

Módulo do manipulador de arquivos estáticos, entrega de arquivos estáticos

<add name="StaticFileModule" image="…\static.dll" />

Módulo de compactação dinâmica, compactação de respostas

<add name="DynamicCompressionModule" image="…\compdyn.dll" />

Navegue até a seção <system.webServer>/<modules>. Esta seção, que pode ser configurada no nível do servidor ou do aplicativo, especifica quais dos módulos carregados na seção <globalModules> estão habilitados para um aplicativo específico. Na maioria das vezes, vemos que essa seção lista os nomes dos módulos que vimos na seção, habilitando-os por padrão em todos os aplicativos.

Observação

Há alguns itens extras no final da lista: são módulos gerenciados desenvolvidos com o modelo de extensibilidade do ASP.NET. Saiba mais sobre como criar modos gerenciados no passo a passo Desenvolver um módulo usando o .NET.

Navegue até a seção <system.webServer>/<handlers>. Esta seção, que pode ser configurada no nível do servidor, do aplicativo ou da URL, especifica como as solicitações são tratadas. Os módulos normalmente participam de cada solicitação, enquanto os manipuladores só recebem solicitações para uma URL específica.

Um bom exemplo de um módulo é o módulo de compactação. O módulo de compactação analisa cada resposta e a compacta, se necessário. O manipulador de página ASP.NET é um bom exemplo de manipulador. Ele recebe apenas as solicitações mapeadas para ele, por exemplo, solicitações que têm a extensão .aspx. A lista <handlers> define os mapeamentos entre uma solicitação com base na URL e no verbo e um módulo de tratamento que será usado para processar essa solicitação. Há também algumas informações extras que são usadas para configurar cada mapeamento, que não é o foco deste tópico.

<handlers>
    <!-- certain details omitted -->
    <add name="CGI-exe" path="*.exe" verb="*" modules="CgiModule" ... />
    <add name="ISAPI-dll" path="*.dll" verb="*" modules="IsapiModule" ... />
    <add name="ASPClassic" path="*.asp" verb="GET,HEAD,POST"  modules="IsapiModule" ... />
</handlers>

Exame do volume do servidor

  1. Abra o Internet Explorer e faça uma solicitação ao servidor especificando a seguinte URL e pressionando ENTER:

    http://localhost/iisstart.htm
    

    Isso iniciará o pool de aplicativos do servidor e fornece o documento iisstart.htm.

  2. Inicie o Gerenciador de Tarefas e vá para a guia Processos. Como o processo de trabalho do IIS é executado em uma conta de usuário diferente, você precisa marcar a opção “Mostrar processos para todos os usuários”. Observe o tamanho do processo de trabalho do servidor w3wp.exe.
    Captura de ecrã que mostra o Gestor de Tarefas do Windows. A guia processos está selecionada.
    Figura 1: Gerenciador de Tarefas mostrando o processo de trabalho do IIS

  3. Agora execute a seguinte linha de comando:

    TASKLIST /fi "imagename eq w3wp.exe" /m
    

    Vemos que mais de 90 DLLs são carregadas pelo processo de trabalho. A maioria delas está localizada no diretório …\intersrv\. Muitas delas são DLLs de módulo que vimos na primeira tarefa ao analisarmos a seção <globalModules> e algumas outras que dão suporte à estrutura do .NET e ao próprio runtime do servidor.

Como remover tudo do servidor

Na tarefa anterior, examinamos a lista padrão de componentes carregados pelo servidor, que continha mais de 35 módulos que forneciam vários serviços, que iam da autenticação à entrega de arquivos estáticos. Cada um dos componentes carregados no servidor tem um impacto no volume dele, na área da superfície de ataque, no desempenho do runtime e, é claro, no conjunto de recursos habilitado.

Antes de criarmos nosso servidor personalizado com apenas a funcionalidade necessária na próxima tarefa, criaremos um servidor Web rápido, pequeno e seguro, removendo todos os módulos e executando o servidor vazio.

Se alterarmos o arquivo applicationHost.config durante a tarefa anterior, poderemos restaurá-lo para o estado original executando %windir%\system32\inetsrv\appcmd restore backup initial na linha de comando.

Agora, vamos remover tudo do servidor.

  1. Use um editor de texto para abrir %windir%\system32\inetsrv\config\applicationHost.config.

  2. Navegue até a seção <system.webServer>/<globalModules>.

  3. Remova todas as entradas da coleção, de modo que apenas uma definição de seção vazia permaneça:

    <globalModules> 
        <!—Remove Everything --> 
    </globalModules>
    
  4. Cole os itens em uma janela do Bloco de notas para uso posterior. Repita o mesmo com a seção <system.webServer>/<modules>. Remova todas as entradas dessa seção e cole-as em um rascunho do Bloco de notas de para uso posterior. Isso garante que não habilitemos nenhum módulo que deixamos de carregar. Cole esses itens recortados em uma janela de rascunho do Bloco de notas para uso posterior.

  5. Repita o mesmo com a seção <system.webServer>/<handlers>. Remova todas as entradas dessa seção para garantir que não especifiquemos nenhum mapeamento de manipulador com módulos que desabilitamos. Cole os itens em um rascunho do Bloco de notas para uso posterior. Salve o arquivo applicationHost.config para aplicar as alterações.

Examinar o volume do servidor vazio

Neste ponto, estamos prontos para carregar o servidor vazio: repetiremos as etapas anteriores para examinar o novo volume do servidor.

  1. Abra o Internet Explorer e faça uma solicitação ao servidor especificando a seguinte URL e pressionando ENTER:

    http://localhost/iisstart.htm
    

    Isso iniciará o pool de aplicativos do servidor e retornará um erro ao navegador, porque nenhum manipulador está registrado para fornecer o recurso solicitado.

  2. Execute o Gerenciador de Tarefas e vá para a guia Processos. Observe o tamanho do processo de trabalho do servidor w3wp.exe.

  3. Execute a seguinte linha de comando:

    TASKLIST /fi "imagename eq w3wp.exe" /m
    

    Observe que o volume do servidor foi reduzido para cerca de 8 MB. No período de tempo do servidor, o volume do servidor vazio será reduzido ainda mais.

    Apenas 50 DLLs são carregadas, em comparação com 90 ou mais. Isso indica que o servidor não carregou nenhuma das DLLs do módulo, que eram responsáveis direta e indiretamente pela diferença de contagem de DLLs. Não só os serviços estão desabilitados no servidor, mas também nenhum código para esses recursos é carregado no processo. Após a otimização, a contagem de DLLs do servidor vazio será significativamente menor.

Na próxima tarefa, criaremos o servidor personalizado apenas com os recursos desejados.

Como criar um servidor personalizado

Na tarefa anterior, removemos tudo do servidor, deixando-o apenas com o mecanismo de servidor principal em execução e nenhum módulo adicional carregado. Agora, criaremos o servidor personalizado a ser usado como servidor de arquivos Web em uma rede corporativa. Para fazer isso, habilitamos o servidor a fornecer apenas os seguintes serviços:

  • Fornecer arquivos estáticos
  • Fornecer listagens de diretório
  • Proteger o conteúdo com regras básicas de autenticação e autorização baseadas em URL

Habilitar o servidor para fornecer arquivos estáticos

Para realizar essa tarefa, considera-se que seguimos a tarefa anterior e deixamos o servidor vazio, removendo todos os módulos que estavam em execução. Nesse estado, o servidor sempre retorna respostas de erro 401 vazias para todas as solicitações, pois nenhum módulo é carregado para fornecer qualquer tipo de processamento de solicitação.

  1. Use um editor de texto para abrir %windir%\system32\inetsrv\config\applicationHost.config.

  2. Navegue até a seção <system.webServer>/<globalModules>. Adicione as duas linhas em negrito abaixo dentro da coleção: copie-a do resumo do Bloco de notas usado anteriormente para salvar os itens de coleção padrão. Isso carrega o módulo de manipulador de arquivos estáticos, responsável por atender às solicitações de arquivos estáticos, e o módulo de autenticação anônima, que produz um token de autenticação padrão para a solicitação:

    <globalModules>
        <add name="StaticFileModule" image="%windir%\System32\inetsrv\static.dll" />
        <add name="AnonymousAuthenticationModule" image="%windir%\System32\inetsrv\authanon.dll" />
    </globalModules>
    
  3. Navegue até a seção <system.webServer>/<modules>. Habilite o manipulador de arquivos estáticos e os modos de autenticação anônima adicionando a linha em negrito abaixo:

    <modules>
    
        <add name="AnonymousAuthenticationModule" />
    
        <add name="StaticFileModule" />
    
    </modules>
    
  4. Navegue até a seção <system.webServer>/<handlers>. Mapeie o manipulador de arquivos estáticos para todas as solicitações de arquivo adicionando a linha em negrito abaixo:

    <handlers>
        <add name="StaticFile" path="*" verb="GET,HEAD"  modules="StaticFileModule" resourceType="Either" requireAccess="Read"/>
    </handlers>
    
  5. Salve o arquivo applicationHost.config.

  6. Abra o Internet Explorer e faça uma solicitação à seguinte URL:

    http://localhost/iisstart.htm
    

    Isso fornecerá o documento solicitado. Habilitamos com êxito a funcionalidade de entrega de arquivo estático no servidor.

  7. Em seguida, solicite a listagem de diretórios fazendo uma solicitação à seguinte URL:

    http://localhost
    

    Obtemos uma resposta vazia porque nenhum manipulador está atualmente carregado, habilitado e mapeado para processar listagens de diretórios e, portanto, uma resposta vazia é enviada (200 OK). Na próxima tarefa, adicionaremos o manipulador.

Habilitar o servidor para fornecer listagens de diretórios

Para realizar essa tarefa, considera-se que realizamos as tarefas anteriores, removemos tudo do servidor e adicionamos a funcionalidade de entrega de arquivo.

  1. Use um editor de texto para abrir %windir%\system32\inetsrv\config\applicationHost.config.

  2. Como antes, adicione a configuração abaixo para habilitar o módulo de navegação de diretório e mapeie-o para atender às solicitações do diretório (a configuração cumulativa será exatamente como especificada abaixo após esta etapa, baseando-se na etapa anterior):

    <globalModules>
        <add name="AnonymousAuthenticationModule" image="%windir%\system32\inetsrv\authanon.dll" />
        <add name="StaticFileModule" image="%windir%\system32\inetsrv\static.dll" />
        <add name="DirectoryListingModule" image="%windir%\System32\inetsrv\dirlist.dll" />
    </globalModules>
    
    <modules>
        <add name="AnonymousAuthenticationModule" />
        <add name="StaticFileModule" />
        <add name="DirectoryListingModule" />
    </modules>
    
    <handlers>
        <add name="StaticFile" path="*" verb="GET,HEAD" modules="StaticFileModule,DirectoryListingModule"  resourceType="Either" requireAccess="Read" />
    </handlers>
    

    Neste ponto, habilitamos o recurso de listagem de diretórios no servidor. No entanto, o recurso expõe uma configuração adicional por motivos de segurança que controla se a listagem de diretórios é permitida ou não. Essa configuração é especificada na seção <system.webServer>/<directoryBrowse>.

  3. Altere a entrada para <directoryBrowse enabled="true" />

  4. Salve o arquivo applicationHost.config.

  5. Abra o Internet Explorer e repita a solicitação ao diretório solicitando a seguinte URL:

http://localhost

Isso fornecerá a listagem do diretório solicitado. Habilitamos com êxito a funcionalidade de listagem de diretórios no servidor.

Em seguida, adicionamos os serviços de autenticação e autorização para proteger o conteúdo no servidor contra o acesso não autorizado.

Como proteger recursos com a autorização de URL

Para realizar essa tarefa, considera-se que seguimos as tarefas anteriores, removemos tudo do servidor e adicionamos a funcionalidade de listagem de diretórios e entrega de arquivo.

  1. Use um editor de texto para abrir %windir%\system32\inetsrv\config\applicationHost.config.

  2. Desta vez, adicionamos dois módulos:

    • O módulo de autenticação básica, que dá suporte ao esquema de autenticação básica via HTTP1.1 com as credenciais do Windows do servidor
    • O módulo de autorização de URL, que dá suporte ao controle de acesso baseado em regra de função e usuário
  3. Para adicionar esses módulos, adicione as entradas de carregamento do módulo à seção <system.webServer>/<globalModules> e habilite os módulos na seção <system.webServer>/<modules>, como fizemos anteriormente para o manipulador de arquivos estáticos e o navegador de diretório.

    Observação

    Desta vez, não precisamos adicionar nada à seção <system.webServer>/<handlers>, pois esses módulos não fornecem tratamento de solicitação, apenas serviços de solicitação a todas as solicitações. A configuração final depois de você adicionar os itens abaixo em negrito terá esta aparência:

    <globalModules>
        <add name="AnonymousAuthenticationModule" image="%windir%\system32\inetsrv\authanon.dll" /> 
        <add name="StaticFileModule" image="%windir%\system32\inetsrv\static.dll" /> 
        <add name="DirectoryListingModule" image="%windir%\system32\inetsrv\dirlist.dll" /> 
        <add name="UrlAuthorizationModule" image="%windir%\System32\inetsrv\urlauthz.dll" />      
        <add name="BasicAuthenticationModule" image="%windir%\System32\inetsrv\authbas.dll" /> 
    </globalModules> 
    
    <modules> 
        <add name="AnonymousAuthenticationModule" /> 
        <add name="StaticFileModule" /> 
        <add name="DirectoryListingModule" /> 
        <add name="BasicAuthenticationModule" /> 
        <add name="UrlAuthorizationModule" /> 
    </modules>
    

    Para usarmos os recursos adicionados, precisamos configurá-los.

  4. Habilite o serviço de Autenticação Básica. Navegue até o elemento <basicAuthentication> e defina o atributo habilitado como true:

    <basicAuthentication enabled="true" />
    
  5. Desabilite a autenticação anônima. Navegue até o elemento <anonymousAuthentication> e defina o atributo habilitado como false:

    <anonymousAuthentication enabled="false" userName="IUSR" />
    

    Isso desabilitará a autenticação anônima e exigirá que o módulo de autenticação básica autentique o usuário com êxito antes que o acesso seja permitido.

  6. Salve o arquivo applicationHost.config.

  7. Abra o Internet Explorer e repita a solicitação ao diretório solicitando a seguinte URL:

    http://localhost
    

    Isso solicita uma listagem de diretórios. Como o navegador não nos autenticou, o módulo de autorização de URL rejeita a solicitação. O módulo de autenticação básica intercepta a rejeição e dispara um desafio de autenticação básica de volta para o navegador, fazendo com que o navegador exiba a caixa de diálogo de logon de autenticação básica.

  8. Faça logon com credenciais inválidas. A solicitação é rejeitada, com uma solicitação pedindo as credenciais novamente.

  9. Faça logon com a conta Administrador que você usou para fazer logon no computador. A listagem de diretórios é exibida, indicando que você adicionou com êxito as funcionalidades de autenticação e autorização ao servidor.

Resumo

Este artigo abordou a natureza com característica de componentes do servidor, examinou os recursos do IIS fornecidos e explicou como criar um servidor Web personalizado com apenas os serviços que um usuário pode precisar.

Antes de usar o servidor novamente, desfaça as alterações na configuração do servidor realizadas como parte deste passo a passo. Se você criou um backup anteriormente, restaure-o executando %windir%\system32\inetsrv\appcmd restore backup initial na linha de comando.

Confira os seguintes links para obter mais informações: