Autor: ACMhUnTeR Fecha: 22/04/2004
Tratare de explicar como configurar un servidor Apache con soporte para encriptacion de datos utilizando mod_ssl, como los servidores usados en las paginas que tienen un servicio de pago en linea, en donde la informacion sea manjeada con privacidad y seguridad. Tambien utilizaremos el mod_security que nos permitira aplicar reglas de seguridad en nuestro servidor como por ejemplo para los conocidos SQL Injection, arranque de nuestro servidor Apache en modo chroot sin necesidad de preparar un entorno chroot, y como ultimo la instalacion del mod_php4 para el soporte de nuestro servidor Apache con php.
Instalaremos para empezar nuestro servidor apache con soporte para el modulo SSL.
HellFire# cd /usr/ports/www/apache13-modssl && make install clean
Una vez finalizada la instalacion procederemos a verificar o modificar algunas lineas en la configuracion de nuestro archivo /usr/local/etc/apache/httpd.conf, explicare las lineas que manejara principalmente este modulo.
# Cargamos el modulo ssl <IfDefine SSL> LoadModule ssl_module libexec/apache/libssl.so </IfDefine> <IfDefine SSL> AddModule mod_ssl.c </IfDefine>
<IfDefine SSL> # Puerto que usaremos para conexiones normales Listen 80 # Puerto que usaremos para conexiones seguras Listen 443 </IfDefine> # Correo del Admin de Servidor Apache ServerAdmin acardenas@hellfire.no-ip.org <IfDefine SSL> # Mime/Types para la descarga de certificados AddType application/x-x509-ca-cert .crt # Mime/Types para la descarga de CRL's AddType application/x-pkcs7-crl .crl </IfDefine> <IfModule mod_ssl.c> # Hace la peticion del Passphare si lo tuviera cuando inicia el servidor SSLPassPhraseDialog builtin # Archivo cache de las sesiones SSL SSLSessionCache dbm:/var/run/ssl_scache # Tiempo de duracion cache de las sesiones SSL SSLSessionCacheTimeout 300 # Creara un archivo con el identificador de semaforo SSLMutex file:/var/run/ssl_mutex # Generara el Pseudo Random Number Generator utilizado por OpenSSL al iniciar SSLRandomSeed startup builtin # Generara el Pseudo Random Number Generator utilizado por OpenSSL al conectar SSLRandomSeed connect builtin # log del SSL SSLLog /var/log/ssl_engine_log # Nivel de log erro, warn , info ,trace ,debug SSLLogLevel info </IfModule> <IfDefine SSL> # Por defecto la navegacion segura utiliza el puerto 443 <VirtualHost _default_:443> # Ruta donde estaran nuestros archivos html, php etc DocumentRoot "/usr/local/www/data" # Dominio al cual respondera la peticion ServerName hellfire.no-ip.org # Correo del administrador ServerAdmin acardenas@hellfire.no-ip.org # Ruta donde se guardaran el log de errores ErrorLog /var/log/httpd-error.log # Ruta donde se guradara el log de accesos al servidor TransferLog /var/log/httpd-access.log # Indicamos el inicio de SSL en nuestor server SSLEngine on # Especifica el tipo de cifrado permitido para negociar con el cliente SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL # Ubicacion del Certificado del Servidor SSLCertificateFile /usr/local/etc/apache/ssl.crt/server.crt # Ubicacion clave privada SSLCertificateKeyFile /usr/local/etc/apache/ssl.key/server.key # Directorio Certificado de una Entidad SSLCACertificatePath /usr/local/etc/apache/ssl.crt # Certificado de una entidad SSLCACertificateFile /usr/local/etc/apache/ssl.crt/ca-bundle.crt # Aplica SSL para archivos cgi y shtml <Files ~ "\.(cgi|shtml?)$"> SSLOptions +StdEnvVars </Files> # Aplica SSL para el directorio de ejecucion de CGI <Directory "/usr/local/www/cgi-bin"> SSLOptions +StdEnvVars </Directory> # Para evitar los errores de bugs al trabajar con SSL para IE SetEnvIf User-Agent ".*MSIE.*" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 # Formato del log CustomLog /var/log/ssl_request_log \ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" </VirtualHost> </IfDefine>
Podemos trabajar con multiples dominios en nuestro servidor cada uno trabajando con sus propios certificados, como sus opciones del mod_ssl propios.
<IfDefine SSL> <VirtualHost 192.168.50.1:443> DocumentRoot... ServerName... . . . </VirtuaHost> <VirtualHost 192.168.50.2:443> DocumentRoot... ServerName... . . . </VirtuaHost> </IfDefine SSL>
Para la generacion del certificado CSR utilizaremos OpenSSL, crearemos una carpeta llamada /root/certificados/ donde crearemos el certificado CSR.
HellFire# openssl genrsa -des3 -out server.key 1024 Generating RSA private key, 1024 bit long modulus .............................................................++++++ ........++++++ e is 65537 (0x10001) Enter pass phrase for server.key:(Contraseña a usar como passphare server.key) Verifying - Enter pass phrase for server.key:(Reingresa contraseña passphrase server.key)
HellFire# cp server.key server.key.bak # Backup de nuestro Private key del CSR HellFire# openssl rsa -noout -text -in server.key # Solo para ver el contenido del server.key
HellFire# openssl req -new -key server.key -out server.csr Enter pass phrase for server.key:(Contraseña passphrase server.key) 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) [AU]:PE State or Province Name (full name) [Some-State]:Peru Locality Name (eg, city) []:Arequipa Organization Name (eg, company) [Internet Widgits Pty Ltd]:HellFire Organizational Unit Name (eg, section) []:FreeBSD Common Name (eg, YOUR name) []:hellfire.no-ip.org Email Address []:acardenas@hellfire.no-ip.org Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:
HellFire# openssl req -noout -text -in server.csr # Solo par ver el contenido del server.csr Creando certificado CA (Certificate Authority )
Cuando nuestro CSR (Certificate Signing Request) es firmado por una entidad certificadora nos emitira tambien un CA (Certificate Authority ), nosotros generaremos el nuestro para las pruebas que realizaremos, para esto utilizaremos la misma carpeta /root/certificados/
HellFire# openssl genrsa -des3 -out ca.key 1024 Generating RSA private key, 1024 bit long modulus .............++++++ ........................................................................................++++++ e is 65537 (0x10001) Enter pass phrase for ca.key:(Contraseña passphrase ca.key) Verifying - Enter pass phrase for ca.key:(Reingresa contraseña passphrase ca.key)
HellFire# cp ca.key ca.key.bak # Otro backup mas del Private key de nuestro CA HellFire# openssl rsa -noout -text -in ca.key # Solo para ver el contenido del ca.key
HellFire# openssl req -new -x509 -days 365 -key ca.key -out ca.crt Enter pass phrase for ca.key: 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) [AU]:PE State or Province Name (full name) [Some-State]:Peru Locality Name (eg, city) []:Arequipa Organization Name (eg, company) [Internet Widgits Pty Ltd]:Certificadora HellFire Organizational Unit Name (eg, section) []:Certificadora Common Name (eg, YOUR name) []:certificadora.hellfire.no-ip.org Email Address []:certificadora@certificadora.hellfire.no-ip.org
HellFire# openssl x509 -noout -text -in ca.crt # Solo par ver el contenido del ca.crt
Llegado a este punto ya tenemos nuestro archivo server.csr , solo hace falta enviarlo a una de las entidades certificadores como por ejemplo Verisign el cual firmara nuestro certificado (server.csr) emitido y lo convertira en un certificado real (server.crt), logico que para esto se realiza un pago. Como nosotros usaremos esta configuracion para realizar nuestras pruebas lo firmaremos nosotros mismos utilizando nuestro CA (Certificate Authority) ya generado, para esto usaremos un script distribuido con las fuentes de nuestro modulo, copiamos las fuentes desde la carpeta /usr/ports/distfiles/
HellFire# cp /usr/ports/distfiles/mod_ssl-x.x.x.tar.gz /root/ HellFire# cd /root/ && tar xvfz mod_ssl-x.x.x.tar.gz HellFire# cp mod_ssl-x.x.x/pkg.contrib/sign.sh /root/certificados/ HellFire# cd /root/certificados/ HellFire# chmod u+x sign.sh HellFire# sh sign.sh server.csr
Ahora ya tenemos listo nuestros archivos de certificacion server.key, server.crt y ca.crt los colocaremos en los directorios que hacen referencia en nuestra configuracion, utilizando este script nos mostro un error pero que al parecer no afecta con la creacion del certificado.
SSLCertificateFile /usr/local/etc/apache/ssl.crt/server.crt SSLCertificateKeyFile /usr/local/etc/apache/ssl.key/server.key SSLCACertificateFile /usr/local/etc/apache/ssl.crt/ca.crt
Con los pasos realizados anteriormente cada vez que iniciemos apache no pedira ingresar el passphare de nuestra certificado para evitarnos este problema removeremos la encriptacion del RSA private key, asi cada vez que reinicie el servidor iniciara limpiamente, y verificaremos los permisos para que solo root tenga acceso al archivo server.key.
HellFire# cp server.key server.key.org HellFire# openssl rsa -in server.key.org -out server.key HellFire# chmod 400 server.key
Antes de instalar el modulo de seguridad recomiendo hacer una copia de nuestro actual archivo de configuracion de apache /usr/local/etc/apache/httpd.conf con la configuracion realizada para el mod_ssl
HellFire# cd /usr/ports/www/mod_security && make install clean
Posiblemente ya esten añadidas las lineas que mencionare aqui, si no fuera asi por suerte tenemos nuestro anterior archivo de configuracion al cual hicimos un backup :)
# Cargamos el modulo security LoadModule security_module libexec/apache/mod_security.so AddModule mod_security.c <IfModule mod_security.c> # Indicamos el inicio de filtrado con la opcion DinamicOnly para evitar el uso de CPU en paginas estaticas SecFilterEngine DinamicOnly # Verifica que la codificacion de la url es valida SecFilterCheckURLEncoding On # Previene ataques de buffer overflow SecFilterForceByteRange 32 126 # Inicio del Audit log para peticiones dinamicas o relevantes generadas por los filtros SecAuditEngine DinamicOrRelevant # Ruta donde se guardara el Audit Log SecAuditLog /var/log/audit_log # Ruta donde se guardara el debug log SecFilterDebugLog /var/log/modsec_debug_log # Nivel del log 0 nada, 1 eventos significativos, 2 info de mensajes, 3 info de mensajes detallado SecFilterDebugLevel 0 # Permite mostrar informacion erronea de identificacion de nuestro servidor. SecServerSignature "Microsoft-IIS/6.0" # Scaneo de contenido POST de la paginas SecFilterScanPOST On # Accion por defecto que tomara al filtrar una regla sino se especificara SecFilterDefaultAction "deny,log,status:404" # Filtrar contenido de url con /etc/passwd SecFilter /etc/passwd # Filtrar contenido de url con /bin/sh para ciertos ataques SecFilter /bin/sh # Filtrar contenido de url contra sql injection y ejecutara un script para enviarnos un mensaje avisandonos del ataque SecFilter "select.+from" log,exec:/home/acardenas/ataque-sql.sh # Filtra la ejecucion de binarios en sistemas unix SecFilter "bin/" # Solo permite el acceso al site a navegadores mozilla y derivados SecFilterSelective HTTP_USER_AGENT "!(mod_security|mozilla)" # Permite que solo se use la variable user=ACMhUnTeR en el script admin.php y determina la ip con acceso. <Location admin/admin.php> SecFilterInheritance off SecFilterSelective ARG_user ACMhUnTeR chain SecFilterSelective REMOTE_ADDR "!^192.168.50.1$" </Location> </IfModule>
Esto es una pequeña muestra de algunas reglas que podemos utilizar con este interesante modulo de seguridad
Muchos se preguntaran que es el audit log bueno en la documentacion de mod_security comentan que el log generado por apache no es de mucha ayuda al no tenr informacion detallada del acceso al servidor, pues audit log trata de resolver este problema realizando un seguimiento muy detallado del acceso al servidor.
En el ejemplo podemos ver el uso del tag Location con el cual especificamos a que archivo en especial queremos utilizar ciertas reglas, utilizamos el SecFilterInheritance off para limpiar anteriores reglas y aplicar las que especificamos.
Se recomienda en paginas donde se utilice upload de archivo , desactivar especificamente en esas partes de la web el SecFilterScanPost off, porque seria pesado para nuestro servidor el scaneo de los archivos que subimos al servidor mediante nuestra web.
Podemos observar un ejemplo de filtrado SecFilter /bin/sh , peroun atacante puede utilizar variantes como /bin/./sh que saltarian el filtro, la actual version de mod_security realiza transformaciones automaticas de /./ a / por ejemplo, forzando a pasar por nuestro filtro. Para tener en cuenta
Los comandos de filtrado que mas usamos en mod_security son SecFilter y SecFilterSelective tener en cuenta la sintaxis que utiliza.
SecFilter [Cadena] [Accion] SecfilterSelective [Opcion] [Cadena] [Accion]
Otra interesante caracteristica de mod_security es la facilidad con la cual puede hacer ejecutarse a nuestro servidor apache e un entorno chroot sin necesidad de preparar un entorno chroot, para ello tendremos en consideracion algunas cosas.
En el archivo de configuracion de nuestro apache cambiaremos la ubicacion del cargado de nuestro modulo que ira despues del parametro ClearModuleList.
ClearModuleList AddModule mod_security.c
Realizado esto solo bastara con indicar la opcion en la configuracion de nuestro mod_security para el inicio como chroot.
SecChrootDir /chroot/apache
Algunas aplicaciones como la ejecucion de cgi tendran sus propios requerimientos y es mas probable que con esta manera de arrancar apache chroot fallara , asi que tendremos que elegir configurar la manera habitual de un entorno chroot ver el documento Chroot Apache en FreeBSD.
No entro mas en detalle de lo utilizado por mod_security ya que tiene una documentacion muy buena, y tambien por ser un modulo de facil manejo, donde la creacion de filtros esta a nuestra imaginacion :P, para mas datos descargarse la guia de referencia , asi tambien darle una leida a los articulos publicados y ejemplos rapidos de la misma pagina de mod_security, donde se encontrara informacion para evitar diferentes tipos de ataques como javascript y html injection, previniendo problemas con el register_globals de php entre otros, como algunas recomendaciones con algunos parametros de configuracion,los enlaces los pondre al final de el documento, tener cuidado en el armado de filtros que podemos esta denegando cosas que realmente no era nuestro objetivo.
Antes de instalar el modulo de php haremos una copia de nuestro anterior archivo de configuracion que contendra ya la configuracion de nuestro mod_ssl y mod_security HellFire# cd /usr/ports/www/mod_php4 && make install clean
Podemos instalar el mod_php4 con soporte para muchas aplicaciones como las bases de datos mysql. postgresql, openssl, entre otros y nuestro arbol de ports instalara las dependencias de estas opciones marcadas. Si queremos tener mas personalizadas nuestras aplicacion podemos instalarlas independientemente cada una con los parametros deseados.
# Cargamos el modulo php LoadModule php4_module libexec/apache/libphp4.so AddModule mod_php4.c # Definimos nuestro Directory index <IfModule mod_dir.c> <IfModule mod_php3.c> <IfModule mod_php4.c> DirectoryIndex index.php index.php3 index.html </IfModule> <IfModule !mod_php4.c> DirectoryIndex index.php3 index.html </IfModule> </IfModule> <IfModule !mod_php3.c> <IfModule mod_php4.c> DirectoryIndex index.php index.html </IfModule> <IfModule !mod_php4.c> DirectoryIndex index.html </IfModule> </IfModule> </IfModule> # Addtype para el soporte de php <IfModule mod_php3.c> AddType application/x-httpd-php3 .php3 AddType application/x-httpd-php3-source .php3s </IfModule> <IfModule mod_php4.c> AddType application/x-httpd-php .php AddType application/x-httpd-php-source .phps </IfModule>
Renombraremos o copiaremos el archivo php.ini-dist a php.ini que es el archivo de configuracion de php
Hellfire# cp /usr/local/etc/php.ini-dist /usr/local/etc/php.ini
Llegado a este punto tendremos un servidor apache con soporte para mod_ssl , mod_security, y mod_php4 y quizas trabajando con alguna base de datos adicional, el cual iniciaremos con el siguiente comando.
HellFire# apachectl startssl
Para que nuestro servidor se inicie automaticamente cada vez que iniciemos nuestra pc.
HellFire# cd /usr/local/etc/rc.d HellFire# cp apache.sh-dist apache.sh HellFire# chmod u+x apache.sh
Para probar nuestro servidor ingresamos en nuestro navegador web https://hellfire.no-ip.org, o el dominio o ip con el cual este configurado nuestro servidor.Vemos que en la url la referencia al protocolo http esta seguida de una s, esto indicara el uso del servidor seguro en el puerto 443.
Espero sirva de mucha utilidad este documento cualquier duda , comentario o sugerencia pueden hacerlo llegar a mi correo o publicandolo en los comentarios de la pagina de eldemonio.