Ir al contenido principal

HTTPS con Apache sobre Windows

Actualmente el estándar en Internet es que todo, absolutamente todo, deba consultarse usando el protocolo HTTPS, lo que “garantiza” que la información que se transmite desde el navegador hasta el servidor web viaja encriptada y solamente el servidor “entiende” lo que el cliente envió. Para quienes no están convencidos y para evitarles el trabajo de ir a buscarlo, esta es la definición de HTTPS tomado de Wikipedia:

El Protocolo seguro de transferencia de hipertexto (en inglés, Hypertext Transfer Protocol Secure o HTTPS) es un protocolo de aplicación basado en el protocolo HTTP, destinado a la transferencia segura de datos de hipertexto, es decir, es la versión segura de HTTP.
https://es.wikipedia.org/wiki/Protocolo_seguro_de_transferencia_de_hipertexto

Como desarrolladores, hay que anotar que en lo que a consultas locales se refiere, se “asume” que uno mismo no requiere tanto protocolo y por tanto todo el desarrollo a realizar podría hacerse sobre HTTP convencional. Sin embargo, hay que tener presente que si la aplicación/página web a desarrollar va a correr finalmente sobre HTTPS, sería prudente probarla sobre dicho protocolo y evitar que, por ejemplo, se invoquen consultas (Ajax, WebServices, imágenes, etc.) usando HTTP al interior de una aplicación/página web abierta con HTTPS, ya que estas consultas serán automáticamente bloqueadas en los navegadores modernos, ocasionando efectos no deseados en la presentación de dicha aplicación/página web.

Y créanme, cuando les digo que esas cosas pasan.

Importante: Por defecto, un navegador que abre una página con HTTPS solamente permite consultas usando HTTPS desde dicha página.

Partiendo del hecho que ya tenemos un servidor web Apache instalado correctamente (como se describe en la entrada Apache sobre Windows de este blog), para validar si nuestro servidor web soporta HTTPS bastará con consultar la URL https://localhost. Las versiones más recientes de Apache para Windows puede que ya lo traigan habilitado por defecto o al menos la distribución ApacheHaus lo hace. Sin embargo, es posible que el certificado usado esté vencido o próximo a vencer o que requiera “afinarse” la configuración del servidor para que funcione como esperamos (especialmente si el DocumentRoot configurado no es el deseado).

Configurando el servidor 

Si el protocolo no es soportado o no está habilitado en el servidor Apache, se presentará una página de error como la mostrada a continuación.

Asumiendo que la versión instalada es del tipo 2.4.xx (para versiones antiguas este proceso puede no funcionar), procedemos a revisar el archivo configuración en conf/httpd.conf y buscamos las siguientes líneas ya las habilitamos ya que pueden estar comentadas por defecto (recuerda que para habilitarlas basta con retirar el caráter “#” al inicio de la línea):

  • LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
  • LoadModule ssl_module modules/mod_ssl.so
  • Include conf/extra/httpd-ssl.conf

Si alguna de estas líneas no se encuentra, este procedimiento no servirá para habilitar HTTPS en tu servidor, lo siento.

Respecto a la última línea, verifica que exista el archivo “conf/extra/httpd-ssl.conf”, que contiene la configuración para la conexión HTTPS (Nota curiosa: SSL es el nombre oficial de esta forma de conexión, pero HTTPS se quedó como una referencia estándar al protocolo).

Aviso: En la distribución ApacheHaus, en lugar del archivo “httpd-ssl.conf” se encuentra habilitado “conf/extra/httpd-ahssl.conf”, que corresponde a la versión de ejemplo de esa distribución, por lo que comentaremos esa línea y habilitaremos la estándar.

A continuación editamos las siguientes líneas en el archivo “conf/extra/httpd-ssl.conf”:

DocumentRoot "xxxxx" 
Configura esta línea para que apunte al directorio base para HTTPS. Si es el mismo directorio configurado en “http.conf” puedes comentarlo o retirarlo.
ServerName localhost:443
Nombre del servidor local, por defecto puede usarse “localhost”.
ErrorLog "xxxx/logs/ssl_error.log"
TransferLog "xxxx/logs/ssl_access.log"
Nombres alternativos a los archivos donde se registran los mensajes de errores y eventos de transferencia (los nombres y path aquí indicados son de referencia, puedes indicar los que consideres convenientes).
SSLCertificateFile "${SRVROOT}/conf/server.crt"
Este es el archivo de certificado de seguridad. Usaremos el nombre “conf/ssl/server.crt” como ejemplo pero puedes cambiarlo por uno diferente. Si no existe el directorio “conf/ssl” , créalo manualmente para evitar errores más adelante.
SSLCertificateKeyFile "${SRVROOT}/conf/ssl/server.key"
Este es el archivo con la llave privada (Server Private Key). Aplican las mismas condiciones del archivo de certificado antes descritas.

Adicionalmente, tal como en la configuración de httpd.conf, buscamos cualquier referencia a “cgi-bin” y la comentamos (a menos claro que usemos ese directorio con algún fin).

Guardamos las modificaciones y ejecutamos nuestro servidor ejecutando “bin\httpd.exe” o corriendo el archivo BAT que seguramente tendrás a mano si seguiste las recomendaciones de la entrada referida anteriormente.

Certificados de seguridad

¿Qué es un archivo de certificado de seguridad o un certificado SSL? En palabras de Cloudfare:

Un certificado SSL es un archivo de datos alojado en el servidor de origen de un sitio web. Los certificados SSL hacen posible la encriptación SSL/TLS, y contienen la clave pública del sitio web, y la identidad del sitio web, junto con información relacionada. Los dispositivos que intenten comunicarse con el servidor de origen harán referencia a este archivo para obtener la clave pública y verificar la identidad del servidor. La clave privada se mantiene secreta y segura.
https://www.cloudflare.com/es-es/learning/ssl/what-is-an-ssl-certificate/

Si los archivos de certificados no existen, se presentará un error del tipo:

AH00526: Syntax error on line 145 of C:/xxxx/conf/extra/httpd-ahssl.conf:
SSLCertificateFile: file 'C:/xxxx/conf/ssl/server.crt' does not exist or is empty

En este caso, podemos crear manualmente los respectivos archivos, lo que se conoce como un Certificado digital auto-firmado. El proceso descrito a continuación también aplica en caso que necesitemos actualizar certificados ya vencidos. 

Desde una ventana de consola de Windows, ejecutar los siguientes comandos desde el directorio “conf” (recuerda crear el directorio “conf\ssl” que es donde residirán los archivos de interés):

..\bin\openssl req -config openssl.cnf -new -out ssl\temp.csr -keyout ssl\temp.pem

En respuesta se tendrá algo como lo siguiente:

Generating a RSA private key
....................................................
....................................+++++
writing new private key to 'ssl\temp.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
...

A excepción de las siguientes, todas las preguntas pueden ser dejadas con los valores por defecto (es decir, presionar simplemente ENTER):

Enter PEM pass phrase
Contraseña usada para generar luego el certificado definitivo.
Common Name (e.g. server FQDN or YOUR name) []
Nombre del servidor (por ejemplo “localhost” o “www.miservidor.com” o algún nombre que te resulte procedente).

El paso anterior crea archivos temporales a partir de los cuales serán creados los archivos definitivos a usar. A continuación procedemos a crear el archivo de llave privada (se solicitará el valor dado a “PEM pass phrase” en el paso anterior), con nombre ssl\server.key:

..\bin\openssl rsa -in ssl\temp.pem -out ssl\server.key

Y finalmente, generamos el archivo certificado con nombre ssl\server.crt:

..\bin\openssl x509 -in ssl\temp.csr -out ssl\server.cert -req -signkey ssl\server.key -days 365

El parámetro “-days” refiere al número de días que estará habilitado el certificado, lo que significa que en un futuro tendremos que repetir este proceso y generar nuevos archivos. Si al ejecutar obtenemos el mensaje “Getting Private key” entonces todo habrá salido bien y ahora tendremos los archivos necesarios para que funcione nuestro servidor con HTTPS.

Aviso: Si no encuentras el archivo ejecutable “openssl.exe” sugeriría que revises el paquete de distribución de Apache que instalaste en tu servidor Windows y si es posible, cambies por otro. Si tienes instalado GIT en tu computador, es probable que en su directorio puedas encontrar una copiar de openssl.exe que puedas usar (por ejemplo en C:\Program Files\Git\usr\bin\openssl.exe). Finalmente, no quedaría otra que buscar en Internet cómo descargar e instalar openssl en Windows.

Reiniciamos el servidor web y procedemos de nuevo a validar desde el URL https://localhost.

A tener en cuenta...

Es posible al consultar localhost usando HTTPS se encuentre una respuesta del navegador similar a la mostrada en la siguiente imagen:

Esto se debe a que los navegadores no aceptan automáticamente certificados generados por una Entidad Certificadora que no esté autorizada. Un ejemplo de entidad certificadora valida es DigiCert Inc o Symantec, empresas que por supuesto requieren de pago para generarte un certificado valido por algunos meses, luego de lo cual deberás pagar para renovarlo.

Ahora bien, si un mensaje de este tipo aparece cuando visitas una página cualquiera en Internet, es mejor que huyas de allí como si de la viruela o una epidemia Zombie se tratara. Pero como sabemos que estamos consultando nuestro servidor local y que somos "de confianza", basta con hacer click en el botón “Avanzado” y luego al desafiante botón de “Aceptar el riesgo y continuar” (los nombres de los botones pueden variar dependiendo del navegador usado). Luego de eso, el mensaje no se volverá a presentar en tu navegador.

Existen algunos métodos para prevenir este mensaje de error, pero podrían representar un riesgo de seguridad al usar software de dudosa procedencia para lograrlo. Si el paso por esta ventana de seguridad en el navegador (que como mencioné antes probablemente pase solamente una vez) no es un inconveniente grave para tu trabajo como desarrollador, pues mejor no arriesgarse, ¿verdad?

Ya para terminar...

En caso que esta información haya sido insuficiente y todavía no hayas podido habilitar HTTPS en tu servidor, te invito a consultar la página https://stackoverflow.com/questions/4221874/..., que contiene un paso a paso bastante detallado y varios comentarios con soluciones al respecto (este artículo es la base de mucha de la información contenida en esta entrada). 

Ahora si, ya con esto terminamos. Espero ya puedas tener habilitado HTTPS en tu servidor web Apache y comiences a desarrollar sin reparos de protocolo.

La primer imagen que acompaña esta entrada fue tomada de https://www.pexels.com

Comentarios

Entradas populares de este blog

Manejo de recursos HTML para tus páginas web con PHP

Déjame saber si te resulta familiar esta situación: páginas web que descargan el mismo recurso (sean estilos CSS o código Javascript) más de una vez o incluyen recursos remotos que tardan una eternidad en cada descarga. Yo lo he visto en más de una ocasión y no es difícil imaginar el porqué ocurre. Un desarrollador incluye el recurso de estilos que necesita su segmento de código y otro hace lo mismo, sin reparar (o sin que siquiera importe) que comparten el mismo recurso. En otro escenario muy común, acostumbran incluir muchos recursos remotos, con lo que el rendimiento de la página depende de lo rápido que responda dicho recurso. ¿Puede hacerse algo al respecto? Claro que si. Vamos a crear una clase en PHP que se encargue de administrar estos recursos y que nos facilite su despliegue en la página sin repeticiones . ¿Y respecto a la demora en la carga de recursos remotos? Atendamos una cosa por vez, porque como dicen por ahí: «Vísteme despacio, que tengo prisa». Administrando ...

Manejo de clases globales únicas en PHP

¿Cómo acceder desde cualquier script en tu proyecto a Clases y/o funciones de uso común? Este puede ser una de las primeras directrices a establecer para cualquier proyecto porque siempre, siempre , sea en  PHP  u otro lenguaje, será necesario usar recursos comunes. En PHP existen diferentes alternativas para su manejo, ya sea por medio de variables globales o de clases/objetos estáticos. A continuación consideraremos una propuesta para este manejo. Creación de recursos globales Para ilustrar esta solución, partimos de la necesidad de implementar una librería para manejo de servicios relacionados con el servidor Web, que de forma amigable nos permita disponer de información como: Valores almacenados de la variable superglobal $_SERVER de PHP. Valores asociados a la consulta realizada por el usuario, por Ej. la dirección IP del usuario o la URL ingresada. Valores asociados al servidor web usado, por Ej. la dirección IP del servidor o la ubicación del script que ej...

¿Qué tan bueno es realmente el “foreach” en PHP?

Como toda buena historia, esta comienza hace algún tiempo. El que fuera mi jefe por allá en la primera década del 2000, realmente odiaba (y mucho) el uso del foreach en el código PHP . Prefería que usáramos alguna alternativa diferente, alguna combinación del  for o del while . ¿Por qué? Ve tú a saber, nunca fue abierto respecto a las razones de su aprensión hacia ese constructor propio del lenguaje. Pero antes de continuar, veamos qué es y para qué nos puede servir. Arreglos, tenían que ser arreglos ¿Qué es foreach ? De acuerdo al manual de PHP , su definición es la siguiente: El constructor foreach proporciona un modo sencillo de iterar sobre arrays . foreach funciona sólo sobre arrays y objetos , y emitirá un error al intentar usarlo con una variable de un tipo diferente de datos o una variable no inicializada. Para su uso correcto existen dos sintaxis validas, a saber: foreach (expresión_array as $value) { ... } foreach (expresión_array as $key => $value) { ....