miércoles 14 de enero de 2009

Cómo configurar Apache+SSL en Win32

Versión 1.6.6

Un nuevo y esperemos que actualizado con más frecuencia ‘Cómo configurar’ el cual cubre Apache 2 está disponible en http://raibledesigns.com/tomcat/ssl-howto.html(en inglés). Checa además este tutorial que cubre Apache 2 en Windows 2003 Server(en inglés también) si es que usas ese.

Traducción al francés mantenida por Jean-Francois Moreau
Traducción al danés mantenida por Morten Fischer-Nielsen

Panorama general

Esta página describe la instalación de Apache para Windows con la extensión mod_ssl. La versión más reciente debería estar siempre disponible en http://tud.at/programm/apache-ssl-win32-howto.php3.

Este proceso le funcionó a varias personas en Windows NT, 98, ME, 2000 y XP. Puedes inclusive instalar Apache con SSL además del servidor Microsoft Internet Information Server si así lo necesitas.

Nota: algunas veces, hay cambios entre distribuciones precompiladas de Apache en las cuales este ‘Cómo configurar’ no aplica. En este caso, si la versión actual no te funciona, prueba con una versión anterior – una que sea anterior a la fecha de modificación de este ‘Cómo configurar’. O, si prefieres la aventura, trata de hacer que funcione.

Nótese que Apache 1.3.x en Win32 se considera calidad beta ya que no alcanza la estabilidad y rendimiento de las plataformas Un*x. Las versiones 2.x quizas sean mejores sin embargo este ‘Cómo configurar’ no lo cubre.

1.: Instalando Apache

Obtén la versión para Windows del servidor web Apache de alguna de las ubicaciones alternas. Se llama algo ásí como apache_x_y_z_win32-x86-no_src.msi. Se trata de un archivo auto-instalable que contiene el sistema base de Apache y archivos de configuración de ejemplo.

¡No mezcles versiones de Apache 1.3 y 2! No funcionan. Si encuentras 1.3.x en modssl.org, no puedes esperar que funcione con 2.0.x.

Instala Apache como se describe en http://www.apache.org/docs/windows.html.

Cambia al menos los siguientes parámetros en el archivo de configuración [APACHE_HOME]/conf/httpd.conf:
[No olvides reemplazar www.my-server.dom con el nombre de dominio real]
  • Port 80 a # Port 80 (Pónlo cómo comentario(#); no se necesita Port, Listen lo sobreescribe más adelante.)
  • (Si no está además del IIS) Listen 80
  • Listen 443 (Para que el servidor escuche por el puerto SSL estándar)
  • ServerName www.my-server.dom
  • (Si está además del IIS) DocumentRoot y el correspondiente <Directory algún-dir> a tu Inetpub\wwwroot

Instala el servicio de Apache(sólo NT/2000/XP) y levántalo. Verifica que todo funciona antes de proceder con la instalación de SSL para limitar los posibles errores.

Intenta http://www.my-server.dom:443/. No estará encriptado todavía pero si funciona quiere decir que la configuración del puerto 443 es correcta.

2.: Obteniendo OpenSSL y mod_ssl

Los archivos binarios(librerías/ejecutables) de donde usualmente se descargaban ya no están disponibles http://www.modssl.org/contrib/ o http://hunter.campbus.com/ y el sitio de OpenSSL sólo distribuye el código fuente pero ofrece la opción de un tercero para instalar los binarios en: http://www.openssl.org/related/binaries.html. Sólo tienes que seguir las instrucciones para instalarlo (Sólo OpenSSL).

Puesto que no encontré ningún paquete con los binarios de Apache, OpenSSL y mod_ssl listo para ejecutarse, me di a la tarea de bajar los fuentes y generar un paquete probado y funcionando. Este lo puedes descargar visitando:
Sobre binarios de Apache 1.3.x descomprimes en C:\, actualizas el archivo [APACHE_HOME]\conf\httpd.conf con tu configuración y listo.
Copia los archivos ssleay32.dll y libeay32.dll del directorio de distribución de OpenSSL [OPENSSL_HOME]\bin al directorio WINNT\System32 ó WINDOWS\System32 en XP. Esto es importante ya que en muchos casos olvidan hacerlo experimentando problemas posteriores.

Actualmente no es necesario un archivo de configuración(.cnf) para que openssl.exe pueda crear la petición de certificado(archivo .csr), si aún así crees que lo necesitas puedes descargarlo de aquí o de aquí. Este es un archivo de texto normal, sin embargo, algunas versiones de Windows insisten en ocultarte la extensión. Puedes editarlo con el Notepad de Windows o un buen editor, aunque no debería ser necesario.

3.: Creando un certificado de prueba

Puedes crear la petición de certificado (archivo .csr) de dos maneras, la primera es usando el archivo de configuración openssl.cnf mencionado en el punto anterior y la otra es sin usar este archivo.

Para crear el archivo de petición de certificado usando el archivo de configuración:

Las instrucciones siguientes son de http://www.apache-ssl.org/#FAQ.

openssl req -config openssl.cnf -new -out my-server.csr
Esto crea el acrhivo de petición y una llave privada. Para crearlo openssl necesita que ingreses la información solicitada, un ejemplo de esta información solicitada es el siguiente:

-----
Country Name (2 letter code) [AU]: GB
State or Province Name (full name) [Some-State]: Yorks
Locality Name (eg, city) []: York
Organization Name (eg, company) [Internet Widgits Pty Ltd]: MyCompany Ltd
Organizational Unit Name (eg, section) []: IT
Common Name (eg, YOUR name) []: www.my-server.dom
Email Address []:

Please enter the following 'extra' attributes to be sent with your certificate request

A challenge password []:
An optional company name []:
-----


Cuando llegas a “Common Name (eg, YOUR name) []: www.my-server.dom” da el nombre de dominio exacto de tu servidor web (p.e. www.my-server.dom) o si estás en una máquina de pruebas usa el nombre de red que tenga(p.e. testserver). Habrá un valor por default para algunos campos, si sólo pones un ‘.’(punto) en estos, serán manejados como campos vacíos. El certificado pertenece a este nombre de servidor y los navegadores muestran un mensaje o niegan mostrar el contenido si el nombre no coincide.

openssl rsa -in privkey.pem -out my-server.key
Esto quita password de la llave privada. DEBES entender lo que significa esto; my-server.key debería ser sólo visible por el servidor Apache y el administrador. Elimina el archivo .rnd ya que contiene información entrópica para crear la llave y podría ser usado para ataques criptográficos contra la llave privada.

Para crear el archivo de petición de certificado sin archivo de configuración:

openssl req -new -nodes -keyout my-server.key -out my-server.csr
Esto crea dos archivos. El archivo my-server.key que contiene la llave privada. En particular, asegúrate de respaldar la llave privada, ya que no hay manera de recuperarla si la pierdes. Ingresar la información solicitada por openssl.

Usa el nombre del servidor web como Nombre Común o Common Name (CN). Los campos email address, optional company name y challenge password pueden dejarse vacíos para un certificado de pruebas.

Una vez creado el archivo de petición de ceritificado continuas con lo siguiente.

openssl x509 -in my-server.csr -out my-server.cert -req -signkey my-server.key -days 365
Esto crea un certificado auto-firmado que puedes usar hasta que obtengas uno “real” de una autoridad certificada. (El cual es opcional, si sabes quienes son tus usuarios, puedes decirles que instalen el certificado en sus navegadores). Nótese que el certificado expira después de un año, puedes cambiar -days 365 al valor que tú especifiques.

Si tienes usuarios con MS Internet Explorer 4.x y quieres que sean capaces de instalar tu certificado (descargándolo y abriéndolo), necesitas crear una versión del certificado codificada en DER:

openssl x509 -in my-server.cert -out my-server.der.crt -outform DER
Crea el directorio [APACHE_HOME]\conf\ssl y mueve my-server.key y my-server.cert a esa ubicación.

4.: Configurando Apache y mod_ssl

Copia el archivo mod_ssl.so al directorio [APACHE_HOME]\modules.

Encuentra las directivas LoadModule en tu archivo httpd.conf y agrega lo siguiente a las que ya existen, de acuerdo al archivo proporcionado para tu distribución:

LoadModule ssl_module modules/ApacheModuleSSL.dll

o

LoadModule ssl_module modules/ApacheModuleSSL.so

o

LoadModule ssl_module modules/mod_ssl.so

en versiones recientes.

En versiones recientes de la distribución, podría también ser necesario agregar
AddModule mod_ssl.c
después de las líneas AddModule que ya existentes.

Añade lo siguiente al final del archivo httpd.conf:

# see http://www.modssl.org/docs/2.8/ssl_reference.html for more info
SSLMutex sem
SSLRandomSeed startup builtin
SSLSessionCache none

SSLLog logs/SSL.log
SSLLogLevel info
# You can later change "info" to "warn" if everything is OK

<VirtualHost www.my-server.dom:443>
SSLEngine On
SSLCertificateFile conf/ssl/my-server.cert
SSLCertificateKeyFile conf/ssl/my-server.key
</VirtualHost>


No olvides levantar Apache con -D SSL si la directiva IfDefine está activa en el archivo de configuración.

Puede que necesites usar regedit para cambiar la clave HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache\X.Y.Z con el número de versión correcto de Apache si el apache.exe de tu distribución no coincide con la clave. (Esto parece no ser necesario con versiones recientes)

También, si usas las directivas IfDefine y levantas Apache como servicio, necesitas editar la línea de comando de Apache en el registro (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Apache2)(Esto no lo he intentado).

Levanta el servidor, esta vez desde la línea de comandos (no como servicio) para ver los mensajes de error que impidan que Apache arranque. Si todo sale bien, (opcionalmente) presiona CTRL+C o desde otra sesión de línea de comando ejecuta: apache –k stop para detener el servidor e iniciarlo como servicio si así lo definiste.

Si no arranca, Apache debería mostrar mensajes descriptivos en la pantalla y/o en los archivos error.log y ssl.log del directorio [APACHE_HOME]\logs. Si algo no funciona, configura todos los LogLevels al máximo y échale un ojo a los archivos log. Son de mucha ayuda.

Depurando problemas de conexión

Los problemas de conexión al servidor desde un navegador pueden tener varias causas, varias de ellas en el lado del cliente (proxy, DNS, alguna tontería del IE).

Así que si encuentras problemas para conectarte con SSL, inténtalo desde otro navegador y/o revisa tu configuración. Si nada de eso funciona, puedes usar OpenSSL para depurar el problema.

bb@www$ openssl s_client -connect no-such-machine:443
gethostbyname failure # Error al resolver este nombre DNS. Conéctate con la dirección IP.
connect:errno=2

bb@www$ openssl s_client -connect www1.tud.at:443
connect: Connection refused
connect:errno=111
# No hay servidor SSL en este puerto. Revisa las directivas Listen y Port.

bb@www$ openssl s_client -connect apcenter.apcinteractive.net:443
# Todo está OK. OpenSSL muestra la información obtenida del servidor.
CONNECTED(00000003)
depth=0 /C=at/ST=Wien/L=Wien/O=APC interactive/OU=Lifecycle Management/CN=apcenter.apcinteractive.net/Email=bb@apcinteractive.net
verify error:num=18:self signed certificate
verify return:1
depth=0 /C=at/ST=Wien/L=Wien/O=APC interactive/OU=Lifecycle Management/CN=apcenter.apcinteractive.net/Email=bb@apcinteractive.net
verify return:1
---
Certificate chain
0 s:/C=at/ST=Wien/L=Wien/O=APC interactive/OU=Lifecycle Management/CN=apcenter.apcinteractive.net/Email=bb@apcinteractive.net
i:/C=at/ST=Wien/L=Wien/O=APC interactive/OU=Lifecycle Management/CN=apcenter.apcinteractive.net/Email=bb@apcinteractive.net
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIC0TCCAjoCAQAwDQYJKoZIhvcNAQEEBQAwgbAxCzAJBgNVBAYTAmF0MQ0wCwYDV
[...]
9ucXUnk=
-----END CERTIFICATE-----
subject=/C=at/ST=Wien/L=Wien/O=APC interactive/OU=Lifecycle Management/CN=apcenter.apcinteractive.net/Email=bb@apcinteractive.net
issuer=/C=at/ST=Wien/L=Wien/O=APC interactive/OU=Lifecycle Management/CN=apcenter.apcinteractive.net/Email=bb@apcinteractive.net
---
No client certificate CA names sent
---
SSL handshake has read 1281 bytes and written 320 bytes
---
New, TLSv1/SSLv3, Cipher is EDH-RSA-DES-CBC3-SHA
Server public key is 1024 bit
SSL-Session:
Protocol : TLSv1
Cipher : EDH-RSA-DES-CBC3-SHA
Session-ID: 49ACE1CF484A67D2C476B923D52110A6FCA1A7CE53D76DF7F233DEBF2333D4FB
Session-ID-ctx:
Master-Key: 00E9FA964253752294ECD69C18ADBA527B7170C112E2B3BCB25EA8F4FD847EC46E1FF0194EF8E16985B5E38BF6F12131
Key-Arg : None
Start Time: 980696025
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
[Escribe:
GET / HTTP/1.0
y presiona ENTER dos veces]

HTTP/1.1 200 OK
Date: Sun, 28 Jan 2001 15:34:58 GMT
Server: Apache/1.3.9 (Win32) mod_ssl/2.4.9 OpenSSL/0.9.4
Cache-Control: no-cache, no-store, must-revalidate, private
Expires: 0
Pragma: no-cache
X-Powered-By: PHP/4.0.4
Last-Modified: Sun, 28 Jan 2001 15:35:00 GMT
Connection: close
Content-Type: text/html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
# El servidor muestra su página principal


Problemas comunes

P: Veo lo siguiente cuando arranca Apache:

Syntax error on line [some number] of ...httpd.conf
Cannot load apache/modules/mod_ssl.so into server
(126) The module could not be found:


R: ¿Copiaste las DLLs de OpenSSL a WINNT\System32 (o WINDOWS\System32 en Win9x/ME/XP)?
Puedes verificar esto copiando openssl.exe a un directorio propio y ejecutarlo. Si marca error por no poder encontrar algunas DLLs, quiere decir que no las has copiado al directorio correcto.
Un usuario alguna vez comentó que tenía este problema aún cuando había hecho todo bien. Encontró que el problema eran las DLLs de OpenSSL que se corrompieron. Así que si tienes este error a pesar de haber hecho todo correctamente, intenta usar las DLLs de otra versión de OpenSSL.

P: Veo lo siguiente cuando arranca Apache:

Syntax error on line [some number] of apache/conf/httpd.conf:
Cannot load apache/modules/apachemodulessl.dll into server:
(127) The specified procedure could not be found:


o:

Syntax error on line [some number] of apache/conf/httpd.conf:
Invalid command 'SSLMutex', perhaps mis-spelled or defined by a module not
included in the server configuration


R: No añadiste la línea AddModule (o no donde debe ir, lo cual es debajo de las otras líneas AddModule).

P: SSL no funciona en el navegador y veo lo siguiente en algún archivo log:

[Fri Nov 16 15:46:30 2001] [error] OpenSSL: error:1407609C:SSL
routines:SSL23_GET_CLIENT_HELLO:http request [Hint: speaking HTTP to
HTTPS port!?]


R: ¿Qué más claro puede ser un mensaje de error? Tu configuración de VirtualHost o Listen no es la correcta.

Preguntas sobre la compilación de Apache, OpenSSL y mod_ssl
Sólo contestaré preguntas donde haya un trabajo de por medio, la documentación que estos proporcionan es bastante clara y sencilla de seguir aunque no apta para principiantes debo decir.

Como tip si es que tienes la curiosidad de hacerlo, utiliza los fuentes de todo, es decir, genera los binarios desde cero.

Enlaces

Servidor Web Apache: http://www.apache.org/
mod_ssl: http://www.modssl.org/
Configuración de mod_ssl: http://www.modssl.org/docs/2.8/ssl_reference.html
OpenSSL: http://www.openssl.org/
PHP preprocesador de hypertexto: http://www.php.net/

Autor de este documento: Balázs Bárány (http://tud.at)
(envíame tus preguntas, pero sólo después de haber echado un vistazo a los errores en los logs con LogLevel debug. Puedes escribirme en Inglés, Alemán y Húngaro. Si constantemente ignoro sus correos, lean todas las pistas de este ‘Cómo configurar’ acerca de cómo escribirme).

Colaborador: Horst Bräuner (Configuración de OpenSSL en NT)
Colaborador: Christoph Zich (Windows 98)
Colaborador: Torsten Stanienda (Prueba con 1.3.12, directiva IfDefine)
Colaborador: Peter Holm (Directivas Listen y Port)

Último cambio 14-ENE-2009

Traducido por Sergio Artigas.

Este documento puede ser redistribuído bajo la Licencia de Libre Documentation GNU. © Balázs Bárány 1999-2009