Creación de un servidor de IIS 7.0 personalizado

por Mike Volodarsky

Introducción

IIS 6.0 y versiones anteriores implementaron la mayor parte de la funcionalidad de servidor ampliamente usada dentro del propio servidor. En cambio, IIS 7.0 y versiones posteriores del motor de servidor web proporciona una arquitectura modular sobre la que prácticamente todas las características del servidor se proporcionan como componentes conectables. Esto permite enormes mejoras en todo el panel, entre las que se incluyen:

  • Capacidad de controlar exactamente qué conjunto de características se carga o usa en el servidor, quitando características innecesarias para reducir el área expuesta a ataques o la superficie de memoria del servidor
  • Capacidad de reemplazar cada característica por implementaciones personalizadas o de terceros
  • Capacidad de especializar el servidor en función de su rol en la topología de servidor
  • Control avanzado sobre el conjunto de características del servidor, tanto en un nivel específico como en el de delegación de la aplicación

Estos componentes de servidor, conocidos como módulos, se cargan durante la inicialización del proceso de trabajo del grupo de aplicaciones y proporcionan servicios de procesamiento de solicitudes en el servidor. Cada aplicación IIS 7.0 y versiones posteriores es una combinación de servicios proporcionados por módulos habilitados para la aplicación y contenido asociado utilizado por estos servicios. El servidor proporciona dos roles principales que desempeñan los módulos:

  • Proporcionar servicios de solicitud, como la autenticación o el almacenamiento en caché de salida (similar a los filtros ISAPI en IIS 6.0)
  • Proporcionar control de solicitudes, como el control de archivos estáticos, CGI o el procesamiento de páginas de ASP.NET (similar a las extensiones ISAPI en IIS 6.0)

Al habilitar módulos diferentes, el servidor se puede configurar para proporcionar los servicios que requieren las aplicaciones en el servidor.

Las tareas que se muestran en este artículo incluyen:

  • Revisión de la configuración del servidor, el valor predeterminado y el conjunto de módulos cargados en el servidor de forma predeterminada
  • Quitar todos los módulos para quitar el servidor hasta su configuración mínima y examinar el efecto en la superficie
  • Creación de un servidor personalizado mediante la adición incremental de módulos para admitir un escenario específico

Revisión de la configuración predeterminada del módulo

La configuración del servidor principal se encuentra en el archivo applicationHost.config, que se encuentra en el directorio de configuración de IIS %windir%\system32\inetsrv\config\. Observamos la siguiente configuración contenida en el grupo de secciones <system.webServer>:

Sección <globalModules>. Esta sección de nivel de servidor contiene la lista de módulos cargados por el proceso de trabajo del servidor y los archivos DLL nativos asociados que implementan su funcionalidad.

Sección <modules>. Esta sección de nivel de aplicación contiene la lista de módulos habilitados para una aplicación determinada. Esta sección sirve para seleccionar el subconjunto de módulos cargados que deben estar activos en una aplicación y también para cargar módulos de nivel de aplicación adicionales.

Sección <handlers>. Esta sección de nivel de dirección URL contiene las asignaciones de controladores que el servidor usa para asignar solicitudes entrantes a un módulo determinado que lo procesará. Esto es similar a los scriptmaps de IIS 6.0 o ASP.NET, y proporciona una asignación unificada de solicitudes a controladores de tipos de contenido nativos y administrados.

La descripción completa de todos los módulos de IIS está disponible en la Información general sobre los módulos de IIS 7.0 y versiones posteriores.

Crear una copia de seguridad de configuración

En primer lugar, realizamos una copia de seguridad de la configuración del servidor para poder restaurarla si es necesario. Ejecute el siguiente comando desde un símbolo del sistema que se ejecute como administrador:

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

A continuación, podemos restaurar la configuración del servidor al estado inicial ejecutando:

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

Examinar la lista predeterminada de módulos

Vaya a la sección <system.webServer>/<globalModules>. Esta sección, que solo se puede configurar en el nivel de servidor, contiene los módulos cargados por cada proceso de trabajo del servidor. Cada entrada configura un módulo con un nombre específico y el archivo DLL que implementa la funcionalidad de ese módulo:

<globalModules>

    <!--several modules omitted -->

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

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

</globalModules>

Examine los nombres de los distintos módulos en la configuración predeterminada del servidor: vemos los servicios conocidos proporcionados como parte del servidor en IIS 6.0:

Módulo de autenticación de Windows, autenticación de solicitudes NTLM

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

Módulo de controlador de archivos estáticos, servicio de archivos estáticos

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

Módulo de compresión dinámica, compresión de respuestas

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

Vaya a la sección <system.webServer>/<modules>. Esta sección, que se puede configurar en el nivel de servidor o aplicación, se especifica cuáles de los módulos cargados en la sección <globalModules> están habilitados para una aplicación determinada. En la mayor parte, vemos que en esta sección se enumeran los nombres de los módulos que vimos en ella, lo que los habilita de forma predeterminada para todas las aplicaciones.

Nota:

Hay algunos elementos adicionales al final de la lista: estos son módulos administrados desarrollados mediante el modelo de extensibilidad de ASP.NET. Obtenga más información sobre la creación de modos administrados en el tutorial Desarrollo de un módulo mediante .NET.

Vaya a la sección <system.webServer>/<handlers>. En esta sección, que se puede configurar en el nivel de servidor, aplicación o dirección URL, se especifica cómo se controlan las solicitudes. Los módulos suelen participar en todas y cada una de las solicitudes, mientras que los controladores solo obtienen solicitudes para una dirección URL determinada.

Un buen ejemplo de un módulo es el módulo de compresión. El módulo de compresión examina cada respuesta y la comprime si es necesario. El controlador de páginas ASP.NET es un buen ejemplo de un controlador. Solo recibe solicitudes asignadas a ella, por ejemplo, solicitudes que tienen la extensión .aspx. La lista <handlers> define las asignaciones entre una solicitud basada en la dirección URL y el verbo, y un módulo de control que se usará para procesar esta solicitud. También hay información adicional que se usa para configurar cada asignación, que no es el foco en este tema.

<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>

Examen de la superficie del servidor

  1. Abra Internet Explorer y realice una solicitud al servidor especificando la siguiente dirección URL y presionando Entrar:

    http://localhost/iisstart.htm
    

    Esto inicia el grupo de aplicaciones de servidor y sirve el documento iisstart.htm.

  2. Inicie el Administrador de tareas y vaya a la pestaña Procesos. Dado que el proceso de trabajo de IIS se ejecuta en una cuenta de usuario diferente, debe comprobar "Mostrar procesos para todos los usuarios". Tenga en cuenta el tamaño del proceso de trabajo del servidor de w3wp.exe.
    Captura de pantalla que muestra el Administrador de tareas de Windows. La pestaña Procesos está seleccionada.
    Figura 1: Administrador de tareas que muestra el proceso de trabajo de IIS

  3. Ahora ejecute la siguiente línea de comandos:

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

    Vemos que el proceso de trabajo carga más de 90 DLL. La mayoría de ellos se encuentran en el directorio ...\intersrv\: muchos de ellos son archivos DLL de módulo que vimos en la primera tarea al examinar la sección <globalModules> y algunos otros que admiten .NET Framework y el propio entorno de ejecución del servidor.

Eliminación del servidor

En la tarea anterior, hemos examinado la lista predeterminada de componentes cargados por el servidor, que contenía más de 35 módulos que proporcionaron varios servicios que van desde la autenticación hasta el servicio de archivos estáticos. Cada uno de los componentes cargados en el servidor tiene un impacto en la superficie del servidor, su área expuesta a ataques, el rendimiento en tiempo de ejecución y, por supuesto, el conjunto de características habilitado.

Antes de crear nuestro propio servidor personalizado con solo la funcionalidad necesaria en la siguiente tarea, creamos un servidor web rápido, pequeño y seguro quitando todos los módulos y ejecutando el servidor vacío.

Si cambiamos el archivo applicationHost.config durante la tarea anterior, podemos restaurarlo al estado original ejecutando %windir%\system32\inetsrv\appcmd restore backup initial desde la línea de comandos.

Ahora para quitar el servidor.

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

  2. Vaya a la sección <system.webServer>/<globalModules>.

  3. Quite todas las entradas de la colección para que solo permanezca una definición de sección vacía:

    <globalModules> 
        <!—Remove Everything --> 
    </globalModules>
    
  4. Pegue los elementos en una ventana del Bloc de notas temporal para usarla más adelante. Repita lo mismo con la sección <system.webServer>/<modules>. Quite todas las entradas de esta sección y péguelas en un Bloc de notas temporal para su uso posterior. Esto garantiza que no se habilite ningún módulo que ya no se cargue. Pegue estos elementos cortados en una ventana del Bloc de notas temporal para usarla más adelante.

  5. Repita lo mismo con la sección <system.webServer>/<handlers>. Quite todas las entradas de esta sección para asegurarse de que no se especifican asignaciones de controladores con módulos deshabilitados. Pegue los elementos en un bloc de notas temporal para su uso posterior. Guarde el archivo applicationHost.config para que se apliquen los cambios.

Examen de la superficie de servidor eliminada

En este momento, estamos listos para cargar el servidor eliminado: repetiremos los pasos anteriores para examinar la nueva superficie del servidor.

  1. Abra Internet Explorer y realice una solicitud al servidor especificando la siguiente dirección URL y presionando Entrar:

    http://localhost/iisstart.htm
    

    Esto debe iniciar el grupo de aplicaciones de servidor y devolver un error al explorador porque no hay ningún controlador registrado para atender el recurso solicitado.

  2. Ejecute el Administrador de tareas y vaya a la pestaña Procesos. Tenga en cuenta el tamaño del proceso de trabajo del servidor de w3wp.exe.

  3. Ejecute la siguiente línea de comandos:

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

    Observe que la superficie del servidor se ha reducido a aproximadamente 8 Mb. En el período de tiempo del servidor, se reducirá aún más la superficie del servidor vacío.

    Solo se cargan 50 DLL, en comparación con 90 o más, lo que indica que el servidor no cargó ninguno de los archivos DLL del módulo, que se contabilizaron directa e indirectamente para la diferencia de recuento de DLL. No solo se deshabilitan los servicios en el servidor, sino que tampoco se carga ningún código para estas características en el proceso. Después de la optimización, el número de DLL del servidor vacío será significativamente menor.

En la siguiente tarea, compilaremos el servidor personalizado solo con las características que queremos.

Creación de un servidor personalizado

En la tarea anterior, quitamos el servidor a la configuración mínima, con solo el motor de servidor principal en ejecución y sin módulos adicionales cargados. Ahora, creamos el servidor personalizado que se usará como servidor de archivos web en una red corporativa. Para ello, habilitamos el servidor para que proporcione solo los siguientes servicios:

  • Proporcionar archivos estáticos
  • Listas de directorios de servicio
  • Protección del contenido con reglas básicas de autenticación y autorización basadas en direcciones URL

Habilitar el servidor para atender archivos estáticos

Para realizar esta tarea, se supone que hemos seguido la tarea anterior y quitado el servidor eliminando todos los módulos que estaba ejecutando. En este estado, el servidor siempre devuelve respuestas de error 401 vacías a todas las solicitudes, ya que no se carga ningún módulo para proporcionar ningún tipo de procesamiento de solicitudes en absoluto.

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

  2. Vaya a la sección <system.webServer>/<globalModules>. Agregue las 2 líneas en negrita debajo dentro de la colección: cópielas desde el panel temporal que se usó anteriormente para guardar los elementos de colección predeterminados. Esto carga el módulo de controlador de archivos estáticos, que es responsable de atender solicitudes de archivos estáticos y el módulo de autenticación anónima, que genera un token de autenticación predeterminado para la solicitud:

    <globalModules>
        <add name="StaticFileModule" image="%windir%\System32\inetsrv\static.dll" />
        <add name="AnonymousAuthenticationModule" image="%windir%\System32\inetsrv\authanon.dll" />
    </globalModules>
    
  3. Vaya a la sección <system.webServer>/<modules>. Habilite el controlador de archivos estáticos y los modos de autenticación anónima agregando la línea en negrita siguiente:

    <modules>
    
        <add name="AnonymousAuthenticationModule" />
    
        <add name="StaticFileModule" />
    
    </modules>
    
  4. Vaya a la sección <system.webServer>/<handlers>. Asigne el controlador de archivos estático a todas las solicitudes de archivo agregando la línea en negrita siguiente:

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

  6. Abra Internet Explorer y realice una solicitud a la siguiente dirección URL:

    http://localhost/iisstart.htm
    

    Esto sirve el documento solicitado. Hemos habilitado correctamente la funcionalidad de servicio de archivos estáticos en el servidor.

  7. A continuación, solicite la lista de directorios realizando una solicitud a la siguiente dirección URL:

    http://localhost
    

    Obtenemos una respuesta vacía porque no hay ningún controlador cargado, habilitado y asignado para procesar los listados de directorios: se envía una respuesta vacía (200 OK). En la siguiente tarea, agregaremos el controlador.

Habilitar el servidor para proporcionar listas de directorios

Para realizar esta tarea, se supone que hemos realizado las tareas anteriores, reducimos el servidor a nada y agregamos la funcionalidad de servicio de archivos.

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

  2. Como antes, agregue la configuración siguiente para habilitar el módulo de examen de directorios y asígnela para atender solicitudes de directorio (la configuración acumulativa tendrá un aspecto exacto como se especifica a continuación después de este paso, basándose en el paso 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>
    

    En este momento, hemos habilitado la característica de lista de directorios en el servidor. Sin embargo, la característica expone una configuración adicional por motivos de seguridad que controlan si se permite o no la lista de directorios. Esta configuración se especifica en la sección <system.webServer>/<directoryBrowse>.

  3. Cambie la entrada a <directoryBrowse enabled="true" />

  4. Guarde el archivo applicationHost.config.

  5. Abra Internet Explorer y repita la solicitud en el directorio solicitando la siguiente dirección URL:

http://localhost

Esto sirve para la lista del directorio solicitado. Hemos habilitado correctamente la funcionalidad de lista de directorios en el servidor.

A continuación, agregamos los servicios de autenticación y autorización para proteger el contenido del servidor frente al acceso no autorizado.

Protección de recursos con autorización de direcciones URL

Para realizar esta tarea, se supone que hemos seguido las tareas anteriores, reducimos el servidor a nada y agregamos la funcionalidad de servicio de archivos y lista de directorios.

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

  2. Esta vez, agregamos dos módulos:

    • El módulo de autenticación básica, que admite el esquema de autenticación básico a través de http1.1 en las credenciales de Windows del servidor
    • El módulo de autorización de direcciones URL, que admite el control de acceso basado en reglas de usuario y rol
  3. Para agregar estos módulos, agregue las entradas de carga del módulo a la sección <system.webServer>/<globalModules> y, a continuación, habilite los módulos en la sección <system.webServer>/<modules>, como hicimos anteriormente para el controlador de archivos estáticos y el explorador de directorios.

    Nota:

    Esta vez no es necesario agregar nada a la sección <system.webServer>/<handlers>, ya que estos módulos no proporcionan control de solicitudes, solo proporcionan servicios de solicitud a todas las solicitudes. La configuración final después de agregar los siguientes elementos en negrita tendrá este aspecto:

    <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 poder usar las características agregadas, es necesario configurarlas.

  4. Habilite el servicio de autenticación básica. Vaya al elemento <basicAuthentication> y establezca el atributo habilitado en true:

    <basicAuthentication enabled="true" />
    
  5. Deshabilite la autenticación anónima. Vaya al elemento <anonymousAuthentication> y establezca el atributo habilitado en false:

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

    Esto deshabilita la autenticación anónima y requiere que el módulo de autenticación básica autentique correctamente al usuario antes de conceder acceso.

  6. Guarde el archivo applicationHost.config.

  7. Abra Internet Explorer y repita la solicitud en el directorio solicitando la siguiente dirección URL:

    http://localhost
    

    Esto solicita una lista de directorios. Dado que el explorador no nos ha autenticado, el módulo de autorización de dirección URL rechaza la solicitud. El módulo de autenticación básica intercepta el rechazo y desencadena un desafío de autenticación básico al explorador, lo que hace que el explorador muestre el cuadro de diálogo de inicio de sesión de autenticación básico.

  8. Inicie sesión con credenciales no válidas. La solicitud se rechaza, con una solicitud que solicita credenciales de nuevo.

  9. Inicie sesión con la cuenta de administrador que usó para iniciar sesión en la máquina. Se muestra la lista de directorios, que indica que ha agregado correctamente funcionalidades de autenticación y autorización al servidor.

Resumen

En este artículo se trata la naturaleza componente del servidor, se examinan las características de IIS que se proporcionan y se explica cómo crear un servidor web personalizado con solo los servicios que puede requerir un usuario.

Antes de volver a usar el servidor, deshaga los cambios realizados en la configuración del servidor como parte de este tutorial. Si creó una copia de seguridad anteriormente, restáurela mediante la ejecución de %windir%\system32\inetsrv\appcmd restore backup initial desde la línea de comandos.

Consulte los vínculos siguientes para obtener más información: