Redireccione temporalmente * todas * las solicitudes HTTP / HTTPS en IIS a una página de "mantenimiento del servidor"

10

Tenemos un servidor IIS que aloja cientos de aplicaciones web separadas, y el servidor de la base de datos física que aloja estas aplicaciones se desconectará por mantenimiento durante un breve período (esperamos que tarde menos de 15 minutos).

Durante ese período, queremos redirigir TODO el tráfico que ingresa, para cualquier sitio web, a una página "actualmente estamos en mantenimiento".

Me doy cuenta de que podría hacer esto yendo a todas las aplicaciones web y configurando una regla de reescritura de IIS que envíe al usuario a otra página para todas las solicitudes en esa aplicación. ¡Pero nos llevaría más tiempo hacer eso que hacer el mantenimiento de la base de datos!

He intentado tres cosas, ninguna de las cuales ha funcionado:

Regla global de reescritura de IIS

He estado buscando una manera simple de aplicar una regla a todos los sitios, de una sola vez, y luego poder "deshacer" esa regla en un paso igualmente indoloro. Hasta ahora, ninguno de mis intentos ha funcionado. Intenté poner esta regla de reescritura en mi web.config global en W: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ Config \ web.config:

<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="redirect all requests" stopProcessing="true">
                    <match url="^(.*)$" ignoreCase="false" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" pattern="" ignoreCase="false" />
                    </conditions>
                    <action type="Redirect" url="http://www.somedomain.com/maintenance" appendQueryString="true" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

Esto no funcionó. Estamos ejecutando .NET 4.0 de 64 bits en IIS, pero "por si acaso" puse lo mismo en los archivos web.config globales de 32 bits y 2.0, y aún no hay cambio.

App_Offline.htm "archivo especial"

Otra sugerencia que he visto es el archivo "especial" app_offline.htm , pero volvemos al mismo problema de que lleva más tiempo implementar este archivo en la raíz de la aplicación de todas nuestras aplicaciones de lo que realmente haría el mantenimiento.

Sitio "Estamos fuera de línea" en IIS

Todos nuestros sitios están configurados en IIS con una sola IP. Esto funciona para nosotros incluso sin SNA porque todas nuestras aplicaciones comparten un solo certificado SSL (es un UCC). Una cosa que se me ocurrió fue que tal vez podría configurar un sitio en IIS que coincidiera con todo el tráfico a la IP que estamos usando, y no especificara un valor de encabezado de host. La esperanza era que pudiera darle una "prioridad" más alta y que, cuando comenzara, hiciera coincidir todo el tráfico con esa IP, antes de que cualquiera de los otros sitios tuviera la oportunidad de hacerlo. Podría configurar ese sitio para que sirva la misma página para todas las solicitudes, independientemente de la URL de la solicitud.

Inicie ese sitio cuando esté en mantenimiento y deténgalo cuando haya terminado.

Pero tampoco pude hacer que esto funcionara, ya que IIS parece hacer coincidir una solicitud HTTP con un sitio más específico antes que menos específico. Por lo tanto, al omitir un valor de encabezado de host para este sitio "avisar a los usuarios que estamos fuera de línea", no coincidió a menos que la solicitud no tuviera un valor de encabezado de host que coincidiera con otro sitio. Lo que nos pone de nuevo en el mismo problema de tener que ir manualmente a cada aplicación web y realizar una acción para desconectarla y luego volver a ponerla en línea cuando hayamos terminado con el mantenimiento

¿Hay una manera simple de lograr esto? Parece que seguramente no somos los primeros en encontrarnos con este problema.

-Josh

Josh
fuente
Una opción sería instalar una instancia de apache u otro servidor web y configurar su sitio lamentable en él. Luego, cuando llegue el momento, detenga IIS e inicie Apache y haga que maneje todas las solicitudes.
phoebus
La forma en que comúnmente hacemos esto por cierto es tener una página lamentable en un dispositivo frente al servidor, por ejemplo, un equilibrador de carga.
phoebus

Respuestas:

6

"We're offline" Site in IISDiría que con su tercer enfoque , digamos que lo nombró Offline, si no tiene un encabezado de host especificado, atenderá todas las solicitudes no recogidas por ninguno de los otros sitios que tienen un encabezado de host coincidente. Para evitar esto, simplemente detenga todos los demás sitios.

Suponiendo que tiene instalado el Scripting de IIS, abra un PowerShell elevado:

import-module webadministration

ahora puede detener todos los sitios excepto el Desconectado:

Get-ChildItem IIS:\Sites | Where {$_.Name -ne "Offline"} | Stop-WebSite

cuando el SQL-Server esté respaldado, inícielo nuevamente:

Get-ChildItem IIS:\Sites | Where {$_.Name -ne "Offline"} | Start-WebSite

Si también tiene sitios FTP, los comandos mostrarán un error porque no puede canalizar un sitio FTP a un cmdlet Stop-WebSite, pero aún funciona para todos los sitios web.

Si tiene sitios que normalmente no se ejecutan, debe excluirlos en el segundo comando, como:

Where {$_.Name -ne "Offline" -and $_.Name -ne "foobar.com"}

Si no tiene instalados los cmdlets de PowerShell para IIS, puede usar appcmd.exe para hacer lo mismo, aunque no lo he usado en años.

Peter Hahndorf
fuente
2

Todos nuestros sitios están configurados en IIS con una sola IP.

1) tome un escritorio antiguo, ejecute live linux distro, dele la misma ip que el cuadro IIS, no lo conecte a la red

2) inicie nginx en live linux box y haga la página de tiempo de inactividad que desee, pruébela utilizando un conmutador / hub fuera de línea conectado a su computadora portátil

3) desconecte el cable de ethernet de la caja IIS y conéctelo a la caja de linux en vivo.

4) borre la memoria caché de mac addr en el interruptor (o roll power). su sitio de inactividad ya está en vivo.

nandoP
fuente
0

Instale Apache y cree un host virtual como el siguiente en path\to\apache\conf\extra\httpd-vhosts.conf:

<VirtualHost *:80>
    DocumentRoot C:/Apache/htdocs
    ServerName anyname.net

    # Other directives here
</VirtualHost>

Luego, en la raíz del documento especificada en la configuración anterior, cree un archivo index.html con un mensaje fuera de línea.

El siguiente paso es muy importante, debe detener todos los servicios que pueden usar el puerto 80 antes de ejecutar Apache. Puede encontrar una lista de la mayoría de ellos en este enlace

SaidbakR
fuente
0

Sé que esto es viejo, pero solo tenía que hacer esto en un viejo cuadro de Windows 2008 r2. Esta es una respuesta más para el título de la pregunta; con respecto al detalle de la pregunta, es simplemente un enfoque para configurar un " Estamos fuera de línea en IIS".

Esto no se basa en nada más que IIS y HTML estático. La funcionalidad de "redirección HTTP" de IIS no maneja lo que desea, pero hay otra forma de simularlo. Simplemente cambie todas las "Páginas de error" para que el sitio apunte a la página de mantenimiento. Sí, esto funciona solo si puede usar un "sitio" completo en IIS.

En mi caso, el sitio tiene un solo archivo "default.htm" en su carpeta raíz (por ejemplo, c: \ InetPub \ wwwroot). Por lo tanto, todas las "Páginas de error" están configuradas para "Ejecutar una URL en este sitio" y utilizan la ruta "/default.htm". Como uso URL absolutas (es decir, comenzando con "/") en el archivo, su contenido se ejecuta correctamente en el navegador, sin importar cuál sea la URL pública.

El resultado neto de esta configuración es cualquiera / todas las solicitudes al sitio que sirven el contenido de mi página de mantenimiento. No importa cuál sea la solicitud.

Además, tenga en cuenta que IIS afectará este cambio al generar un archivo web.config en la carpeta raíz. Esto es lo que creó para mí:

 <?xml version="1.0" encoding="UTF-8"?>
 <configuration>
     <system.webServer>
         <httpErrors>
             <remove statusCode="502" subStatusCode="-1" />
             <remove statusCode="501" subStatusCode="-1" />
             <remove statusCode="500" subStatusCode="-1" />
             <remove statusCode="412" subStatusCode="-1" />
             <remove statusCode="406" subStatusCode="-1" />
             <remove statusCode="405" subStatusCode="-1" />
             <remove statusCode="404" subStatusCode="-1" />
             <remove statusCode="403" subStatusCode="-1" />
             <remove statusCode="401" subStatusCode="-1" />
             <error statusCode="401" prefixLanguageFilePath="" path="/default.htm" responseMode="ExecuteURL" />
             <error statusCode="403" prefixLanguageFilePath="" path="/default.htm" responseMode="ExecuteURL" />
             <error statusCode="404" prefixLanguageFilePath="" path="/default.htm" responseMode="ExecuteURL" />
             <error statusCode="405" prefixLanguageFilePath="" path="/default.htm" responseMode="ExecuteURL" />
             <error statusCode="406" prefixLanguageFilePath="" path="/default.htm" responseMode="ExecuteURL" />
             <error statusCode="412" prefixLanguageFilePath="" path="/default.htm" responseMode="ExecuteURL" />
             <error statusCode="500" prefixLanguageFilePath="" path="/default.htm" responseMode="ExecuteURL" />
             <error statusCode="501" prefixLanguageFilePath="" path="/default.htm" responseMode="ExecuteURL" />
             <error statusCode="502" prefixLanguageFilePath="" path="/default.htm" responseMode="ExecuteURL" />
         </httpErrors>
     </system.webServer>
 </configuration>
Granjero
fuente