Howtos, cómos sobre seguridad y optimizaciones al PHP, trabajo con SSL, servidores apache
Generando cerficados SSL para apache:
La creación de certificados SSL es uno de los puntos más interesantes al trabajar con servidores web. Estos certificados nos permiten que la conexión entre el cliente (browser) y el servidor web viaje encriptada minimizando o mitigando la posiblidad de un ataque de hombre en el medio que tienda a descubrir nuestras claves.
Ahora, cómo hacerlo? Muchas personas piensan que es una tarea extremadamente difícil, pero básicamente se resume en 3 pasos (con uno adicional opcional), que son:
1- Creación de una clave privada (KEY)
2- Generación de una solicitud de certificado (CSR)
*- Creación de un certificado autogenerado
3- Instalación del certificado (CRT)
El primer paso es crear la clave RSA privada. Esta clave es del tipo RSA de 1024 bits y estará encriptada usando Triple DES y guardada en formato PEM de forma tal que sea visible como texto ASCII.
Usaremos varios archivos como fuente de numeros aleatorios lo que ayudará a hacer la clave más segura. Un buen formato son archivos texto comprimidos en formato gzip. La clave es generada usando el siguiente comando (file1 a file5 son los archivos a ser usados para mejorar los numeros aleatorios):
$ openssl genrsa -des3 -rand file1:file2:file3:file4:file5 -out server.key 1024
En nuestro caso de ejemplo, yo usaré dos archivos binarios. En la vida real les recomiendo poner algunos archivos más aquí mi ejemplo real:
openssl genrsa -rand /usr/bin/lsattr:/bin/cat -out server.key 1024
17084 semi-random bytes loaded
Generating RSA private key, 1024 bit long modulus
........++++++
..........................++++++
e is 65537 (0x10001)
rver.key:
Si se fijan no usé el switch -des3, si lo pusiera, siempre me pediría la passphrase al arrancar el servidor web. Y eso a mi no me conviene.
Aquí está generada la server.key, la clave privada:
ll server.key
-rw-r--r-- 1 root root 963 Apr 1 16:08 server.key
Es muy importante mantener una copia de ésta clave pues es la base para la encriptación usando un certificado. De ser posible mantener un respaldo en un disquete o cinta. El costo de un certificado,aunque varía, está entre los 100 y los 600usd aproximadamente y es sumamente doloroso tener que regenerar un certificado. Prefiero mantener un CD con la copia de server.key a no tener que pagar de nuevo.
El segundo paso es generar una petición de certificación (Certificate Signed Request). Con esta podremos realizar la petición de un certificado a la entidad certificadora de nuestra elección.
Este es el archivo que se les envía cuando las entidades certificadoras solicitan el CSR. Sin embargo, también podemos hacer que nuestro sistema genere un Certificado AutoGenerado el cual nos permitirá operar de forma segura, pero siempre le sacará a los clientes una advertencia de que el certificado no puede ser validado en una entidad certificadora.
En negrita está lo que nosotros debemos ir escribiendo. El ejemplo es para Quito, Pichincha, Ecuador, pero debe ponerse los datos de su organización propiamente dichos.
openssl req -new -key server.key -out server.csr
Enter pass phrase for server.key: (poner la frase con que generamos la clave privada)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [CA]:EC
State or Province Name (full name) [Some-State]:Pichincha
Locality Name (eg, city) [Some-Locality]:Quito
Organization Name (eg, company) [Some-Organization Ltd]:Ecualinux
Organizational Unit Name (eg, section) [Some-Organizational]:IT
Common Name (eg, YOUR name) [www.domain.com]:www.dominio.com
Email Address [admin@domain.com]:direccionvalida@hotmail.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Aquí se nos generará el CSR(server.csr):
ll server*
-rw-r--r-- 1 root root 765 Apr 1 16:22 server.csr
-rw-r--r-- 1 root root 963 Apr 1 16:08 server.key
Cuando vayamos a comprar un certificado, sólo enviaremos éste archivo server.crt a la entidad certificadora.
Ahora, como esto de comprar un certificado toma un tiempo y cuesta dinero, procedamos nosotros a generarnos un certificado autogenerado a partir de estos datos y seguir operando hasta que idealmente nos llegue el certificado válido.
Este certificado de ejemplo será válido por 60 días, podemos poner más (1400 o algo así) si es que nunca vamos a pedir un certificado válido a una entidad certificadora.
openssl x509 -req -days 60 -in server.csr -signkey server.key -out server.crt
openssl x509 -req -days 60 -in server.csr -signkey server.key -out server.crt
Signature ok
subject=/C=EC/ST=Pichincha/L=Quito/O=Ecualinux/OU=IT/CN=Ernesto Perez/emailAddress=direccionvalida@hotmail.com
Getting Private key
Listo.. ya tendremos nuestro certificado autogenerado.
ll server*
-rw-r--r-- 1 root root 969 Apr 1 16:27 server.crt
-rw-r--r-- 1 root root 765 Apr 1 16:22 server.csr
-rw-r--r-- 1 root root 963 Apr 1 16:08 server.key
En el caso de que hayamos solicitado un certificado de autenticidad a una entidad certificadora:
Es éste certificado el que nos enviaría una entidad certificadora para que usemos. Cuado lo envían, normalmente lo hacen en el cuerpo del mensaje, lo que tenemos que hacer realmente es crear un nuevo archivo llamado server.crt y pegarle todos los datos que nos indiquen.
Ahora procedamos a instalar el certificado en el apache:
primero verificar que apache esté instalado:
rpm -q httpd
si no está instalado, instalarlo conjuntamente con el php y el módulo para el manejo de ssl:
yum install php php-imap php-mysql httpd mod_ssl
probemos que el apache arranque
service httpd restart
Una vez instalado el apache, los certificados SSL estarán activos. Puesto que por defecto mod_ssl busca en /etc/httpd/conf.d/ssl.conf e intenta usar los certificados nombrados server.crt y server.key, debemos copiar nuestros recién generados hacia esos directorios:
[root@laptop ~]# cp server.crt /etc/httpd/conf/ssl.crt/
[root@laptop ~]# cp server.key /etc/httpd/conf/ssl.key/
[root@laptop ~]# service httpd restart
Stopping httpd: [FAILED]
Starting httpd: [ OK ]
Si quisiéramos agregar un servidor virtual con ssl, sugiero editar el archivo /etc/httpd/conf.d/ssl.conf ahi se definen los servidores virtuales en ssl. Tener en consideración que el archivo .crt y el .key deben ser diferentes para cada sitio virtual. También debemos tener en cuenta que apache permite sólo un certificado SSL por cada IP. Esto es, si quisiéramos más de un certificado SSL en el servidor, debemos obtener más de una dirección IP para el servidor.
y listo.. ya tenemos nuestro certificado instalado para esa IP del servidor.
Si desea adquirir un certificado SSL generado por una entidad certificadora revise en nuestro sitio www.ecualinux.com
Endureciendo PHP
PHP es al momento, uno de los lenguajes de programación (fundamentalmente para web) más populares al momento. Es un lenguaje de programación multiplataforma, es decir, puede ejecutarse tanto sobre linux, unix SCO, windows, macos, OSF o cualquier otro sistema operativo usado en el mercado.
¿Qué ventajas me da esto? Pues que una aplicación hecha en PHP puede sencillamente ser portada entre diferentes sistemas operativos con pocos o ningún cambio.
Debido a la amplia distribución del php en el mercado, php necesita ahora más que nunca de una fortaleza extraordinaria, una gran resistencia ante ataques de gusanos o usuarios malintencionados (fallas de seguridad).
En este texto, ayudaremos a los interesados a comprender un poco más las diferentes técnicas de protección contra fallas de seguridad que han ideado los autores del Hardened PHP.
Partes de este documento han sido extraídas del sitio de hardened php.
¿Qué es el hardened-php?
1. Proteger el php contra un número de scripts php pésimamente escritos
2. Potenciales fallas de seguridad desconocidas que puedan existir en el motor de php en sí.
Una de las características que vemos más prometedoras es precisamente este segundo punto, ya que no basta sólo con protegernos contra fallas de seguridad desconocidas, siempre es bueno tener algoritmos y programas endurecidos que sean capaz de soportar de una forma y otra ataques a sus fallas de seguridad desconocidas. Gracias a que el PHP es código abierto, los autores de hardened-php han podido aplicar estas ideas al php.
¿Qué provee el hardened php?
* Protección con canarios en el manejador de memoria del Zend
* Protección con canarios de las listas enlazadas del Zend
* Protección contra exploits (fallas) en el manejo de formato de cadenas
* Protección contra inclusión de código arbitrario
* Histórico de los atacantes vía syslog
¿Qué es un canario?
Los mineros usaban hace años, para detectar monóxido de carbono (CO) en las minas donde trabajaban unos canarios enjaulados. Los llevaban delante, los canarios eran más sensibles al CO que el ser humano, por tanto al incrementarse un poco la concentración de CO en la mina, el canario moría y los mineros podían determinar que debían salir inmediatamente del sector afectado.
En la programación se usa la misma técnica, un canario es un área con ciertos datos que se ponen inmediatamente después de una variable (en la memoria) cuando un atacante intenta, por ejemplo, sobreescribir el área de datos mediante un exploit de desbordamiento (de una variable), escribe en el área de la variable, pero aprovecha una determinada vulnerabilidad que escribe más allá del tamaño de la variable y sobre escribe otras áreas hasta potencialmente escribir en el área de código (el área de datos y código son contiguas). Ahora, con esta protección el sistema una vez se escriba los datos, verificará si el canario ha sido envenenado (al estar después de la variable, si lo sobreescriben lo que harán será cambiar la información que se suponía no variara) y el programa al ver datos diferentes a los puestos por él, determinará que el canario está envenenado y procederá a terminar la aplicación.
Instalación del php endurecido
Bajar el php de www.php.net
Abrirlo a un directorio, digamos: /usr/src:
cd /usr/src
tar -zxvf /root/php-x.y.z.tar.gz (x.y.z serán los numeros de la vesión de php que bajamos, sugiero sea la última).
cd php-x.y.z
Bajar el hardened-php de: http://www.hardened-php.net/download.php
gunzip hardened-php-x.y.z-a.b.c.patch.gz
patch -p 1 < hardened-php-x.y.z-a.b.c.patch
Compilar php como usualmente se hace.
Compatibilidad
hardened php ha sido diseñado para sistemas linux. Cualquier problema al usar hardened php para otro sistema operativo, por favor referirlo a los autores.
Impacto en el desempeño
Los autores piensan que unos pocos ciclos adicionales gastados a favor de la seguridad son negligibles respecto a la resistencia que añade al php.
Uso de la memoria
Al añadirse protecciones de canario y elementos de listas y listas, el hardened php incurre en un uso de memoria un poco mayor al normal.