Prestashop es uno de los CMS de comercio electrónico que más auge está teniendo últimamente. La documentación es bastante buena pero hay algunas cosas que sólo tratan de pasada y creo que son muy importantes para mejorar el funcionamiento de Prestashop.

Concretamente os quería enseñar la forma de mejorar el rendimiento de prestashop utilizando Amazon CloudFront para servir contenidos estáticos.

Amazon CloudFront es el servicio de Amazon AWS que permite distribuir contenidos más rápido y con menor latencia que si lo hicieras desde tu propio servidor. Amazon CloudFront tiene distribuidos a través del mundo varios puntos de salida de forma que entrega los archivos al usuario desde el punto más cercano a su ubicación. Otra ventaja de Amazon CloudFront es que liberas a tu servidor de la entrega de esos ficheros con lo que consigues liberar recursos que podrás utilizar para otras cosas.

Para crear tu distribución lo único que tienes que hacer es ir a tu consola de Amazon y en la pestaña de CloudFront pulsar en «Create Distribution».

Debes de seleccionar la opción de Custom Origin y en Origin DNS Name poner la página de tu tienda

En la siguiente pantalla debes de indicar un subdominio del dominio de tu tienda, aunque no es obligatorio. En mi caso lo suelo poner siempre por estética ya que si no cuando carga la página los clientes podrían ver que se cargan contenidos de otros sitios con nombres tan extraños como dlskfhxxxis3dhflk23shf.cloudfront.net. En el ejemplo he utilizado ccc1.mitiendac.com

En el último paso podréis ver como queda la distribución que acabáis de crear.

Una vez creada la distribución  podréis ver en el panel de control que hay una nueva distribución y que su estado es «InProgress». En mi caso permaneció en ese estado unos 10 minutos hasta que pasó al estado «Deployed»  que es cuando ya se puedo empezar a utilizar.

En esta imagen tenéis un ejemplo de como quedaría.


Si habéis decidido utilizar un subdominio de vuestra tienda, mientras que finaliza la creación, podeís ir al servidor dns de vuestro dominio y añadir el subdominio a los dns. Para ello hay que crear una entrada cname con el nombre ccc1.mitienda.com. que apunte al nombre de la distribución que acabamos de crear, por ejemplo xxxxxxxx.cloudfront.net

El último paso es ir al administrador de prestashop y configurar el apartado de CCC (). Para eso hay que ir a Preferencias -> Rendimiento. y activar CCC. añadiendo la distribución. Si habéis utilizado el subdominio hay que poner ccc1.mitienda.com y si no, introducir directamente la distribución, p.e. xxxxxxxx.cloudfront.net en el apartado Servidores de media.

Como veis en la imagen se pueden añadir hasta 3 servidores de media. Para poner otros dos sólo hay que repetir lo anterior otras dos veces.

Por último os quería comentar algo sobre el coste de este servicio pero es difícil ya que es muy variable por que se factura en función del uso así que lo mejor es que vosotros mismos echéis mano de la calculadora y revisando los precios de la página de amazon lo calculéis o que utilicéis la calculadora de Amazon.

Si no os aclaráis con los precios lo que os recomiendo es que lo hagáis y que diariamente reviséis lo que lleváis gastado. Probablemente con el gasto de un par de días «normales» os será mas que suficiente para poder calcular el coste mensual.

Pandora FMS es un software de monitorización muy completo que estoy utilizando en sustitución de los icinga/nagios que venía utilizando hasta ahora. Una característica común a pandora fms y nagios es la capacidad de poder añadir tus propios plugins al sistema de monitorización lo que da una enorme libertad para poder hacer prácticamente cualquier cosa.

Uno de los plugins que he preparado sirve para poder medir con comodidad la velocidad de respuesta de un sitio web. Los parámetros que mide son:

  • Time to First Byte
  • Tiempo total de descarga
  • Tiempo de pretransferencia
  • Código http de respuesta
  • Tamaño total de la página

Algunos de estos parámetros son muy útiles para poder ver desviaciones o comportamientos extraños que asociados a su alarma correspondiente nos pueden avisar con tiempo para evitar caídas o incluso ataques.

Hay algunos parámetros que pueden extrañar como el código http de respuesta o el tamaño de la página, los he añadido para poder tener avisos de casos como errores 504 o 500 que de otra forma son difíciles de detectar y el tamaño de la página para monitorizar actualizaciones en ciertas páginas que no cuentan con herramientas como rss o similares para avisarnos de los cambios.

La instalación es muy sencilla y sólo se ha de copiar al directorio de los plugins del servidor donde tengamos pandora fms funcionando, asignarle permisos de ejecución y asegurarnos de que tenemos curl instalado (apt-get install curl).

En pandora debemos de ir a Gestionar servidores -> gestionar complementos y pulsar en Añadir y rellenar todos lo datos del plugin.


Ahora tenemos que añadir a un agente nuevo o a uno ya creado un nuevo módulo que utilice este plugin. El tipo de módulo debe de ser de Servidor de complementos.

Introducimos todos los datos necesarios, en este caso para medir el valor «Time to first byte».

O por ejemplo para comprobar si se produce algún error 500 en una página

Este plugin está desarrollado en bash por lo que puede usarse desde la línea de comandos directamente.
Aquí os dejo el código fuente:

#!/bin/bash
# Page Speed Plugin Pandora FMS Server plugin
# (c) Manuel Angel Fernandez 2012
 
function help {
        echo -e "Page Speed Plugin for Pandora FMS Plugin server. http://pandorafms.com"
        echo " "
        echo "This plugin is used to check page speed and Time to First Time"
        echo " "
        echo -e "Syntax:" 
        echo -e "\t\t-f Time to First Byte"
        echo -e "\t\t-t Total time"
        echo -e "\t\t-p Pretransfer time"
        echo -e "\t\t-c Http status code"
        echo -e "\t\t-s Size download(Kb)"
        echo -e "\t\t-a All parameters csv format"
        echo -e "\t\t-h This help"
        echo -e "Samples:"
        echo "   ./page_speed -f www.yahoo.com"
        echo " "
	echo "by Manuel Angel Fernandez - manuel at rastreador.com.es" 
	echo " "
        exit
}
 
if [ $# -eq 0 ]
then
        help
fi
 
 
# Main parsing code
while getopts ":h:f:t:p:c::s:a:" optname
  do
    case "$optname" in
      "h")
                help
        ;;
      "f")
                curl -so /dev/null -H "Pragma: no-cache" -H "Cache-Control: no-cache" -w "%{time_starttransfer}\n" "$OPTARG?`date +%s`"
                exit 0
        ;;
      "t")
                curl -so /dev/null -H "Pragma: no-cache" -H "Cache-Control: no-cache" -w "%{time_total}\n" "$OPTARG?`date +%s`"
                exit 0
        ;;
      "p")
                curl -so /dev/null -H "Pragma: no-cache" -H "Cache-Control: no-cache" -w "%{time_pretransfer}\n" "$OPTARG?`date +%s`"
                exit 0
        ;;
      "c")
                curl -so /dev/null -H "Pragma: no-cache" -H "Cache-Control: no-cache" -w "%{http_code}\n" "$OPTARG?`date +%s`"
                exit 0
        ;;
      "s")
                curl -so /dev/null -H "Pragma: no-cache" -H "Cache-Control: no-cache" -w "%{size_download}\n" "$OPTARG?`date +%s`"
                exit 0
        ;;
      "a")
                curl -so /dev/null -H "Pragma: no-cache" -H "Cache-Control: no-cache" -w "Timetofirstbyte\tTotal-Time\tPretransfer-time\tHttp-code\tdownload-size\n%{time_starttransfer}\t%{time_total}\t%{time_pretransfer}\t%{http_code}\t%{size_download}\n" "$OPTARG?`date +%s`"
                exit 0
        ;;
 
 
       ?)
                help
        ;;
      default)
                help
        ;;
 
    esac
done

Espero que os sea de utilidad.

s3cmd es una pequeña aplicación que sirve para interactuar con el servicio de almacenamiento de Amazon, S3. Hace un tiempo ya os había contado cómo realizar backups con s3cmd.

Si utilizas ubuntu o debian, s3cmd está en los repositorios oficiales, pero una versión bastante antigua con muchos fallos. En mi caso el fallo que más me estaba afectando es cuando se se producía timeout hacía que la aplicación se cerrara sin finalizar las tareas, cosa que últimamente se estaba convirtiendo un algo demasiado habitual.

Por suerte el desarrollador de la aplicación ha creado un repositorio donde mantiene actualizadas las versiones estables para debian 5 y 6 y ubuntu 10.04 LTS y superiores. Para actualizar sólo hay que ejecutar los siguientes comandos.

wget -O- -q http://s3tools.org/repo/deb-all/stable/s3tools.key | sudo apt-key add -
sudo wget -O/etc/apt/sources.list.d/s3tools.list http://s3tools.org/repo/deb-all/stable/s3tools.list
sudo apt-get update && sudo apt-get install s3cmd

Fuente: s3tools.org

Si por cualquier razón necesitáis bloquear el tráfico de un servidor desde algún país en concreto en http://www.countryipblocks.net/ mantienen una lista actualizada de los rangos de ips de cada país.

Puedes descargar varios formatos, incluso uno preparado para insertar directamente en un fichero .htaccess, aunque a mi no me parece el mejor formato ya que obligas a que el servidor web revise una lista de ips que puede llegar a ser muy grande antes de que muestre la página y eso podría hacer que la navegación se enlenteciera demasiado, además un servidor web no es el más adecuado para realizar esa función.

Os pongo varios ejemplo de como realizar el bloqueo desde la línea de comandos. Para los ejemplos he utilizado korea, no se os ocurra utilizar rangos de ips de el país en el que estáis por que os podéis bloquear el acceso. Como diría un amiguete, «no seáis gañanes»

Con iptables:

.
/usr/bin/wget -O /tmp/pais.txt https://www.countryipblocks.net/e_country_data/KR_cidr.txt; for i in $(/bin/cat /tmp/pais.txt | /bin/grep -v '#'); do sbin/iptables -A INPUT -s $i -j DROP; done; /bin/rm /tmp/pais.txt

Con apf:

.
/usr/bin/wget -O /tmp/pais.txt https://www.countryipblocks.net/e_country_data/KR_cidr.txt; for i in $(/bin/cat /tmp/pais.txt | /bin/grep -v '#'); do /etc/apf/apf -d $i; done; /bin/rm /tmp/pais.txt

ACTUALIZACIÓN
countryipblocks.net ya no permite descargar esos ficheros así que ahora utilizo el listado de maxmind.com

Como lo dan en otro formato he tenido que cambiar la rutina que lo proceso, ahora en una sola línea, aunque tiene el inconveniente de que necesitas tener instalada la aplicación ipcalc (sudo apt-get install ipcalc) para calcular el cidr.
Tened en cuenta que sólo permite descargar la base de datos unas pocas veces al día.

En esta rutina bloquea todo el tráfico que viene de china (CN)

curl http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip | funzip | grep CN | tr -d '"' | awk '{split($0,a,","); print "ipcalc -r "a[1]" "a[2]" | head -2 | tail -1"}' | sh | awk '{print "iptables -A INPUT -s "$0" -j DROP"}' | sh

Amazon Web Services

Antes de empezar 2 conceptos sobre Amazon Web Sevices (aws):
Instancia: es el equivalente a un servidor
Grupo de seguridad: reglas predeterminadas de un firewall

Durante el proceso de creación de una instancia en Amazon EC2 uno de los pasos es asignarle un grupo de seguridad.
Lo normal es dejar abiertos sólo aquellos puertos que realmente necesitas para minimizar los riesgos de accesos y ataques no deseados.

Yo tengo predefinidos tres grupos, uno super básico con sólo el puerto 80, 443 (los usados por las páginas web) y el 22 (ssh), otro más abierto con mas puertos para otro tipo de servidor y el «vivalavirgen» con todo abierto, que en principio no debería de utilizarse para nada excepto algunas pruebas.

En mi caso el problema surgió al crear una nueva instancia para un servidor que tiene servicios en puertos que hasta ahora no había utilizado y sin darme cuenta le asigné un grupo de seguridad que no tenía esos puertos contemplados.

Evidentemente al intentar acceder a esos servicios no podía,así que intenté cambiar el grupo de seguridad de esa instancia pero me llevé una buena sorpresa al comprobar que no era posible por el tipo de servidor que había seleccionado.

La única solución que encontré fue ir al menú de la instancia y seleccionar la opción «Launch more like this» y en el proceso de creación de la nueva instancia asignarle el grupo correcto. Es una forma de hacer esto un poco «de andar por casa» pero funciona y soluciona la papeleta al que lo necesite.

El spam en los blogs es un problema que acaba afectando de alguna forma a todos los que administramos servidores. En WordPress hay estupendos plugins para evitar el spam como Akismet y que funcionan muy bien, pero siempre funcionan después de que el spam ya ha entrado en el blog con el consiguiente consumo de ancho de banda, cpu, memoria y espacio en disco. Evidentemente para un sólo blog no es un problema pero cuando tienes muchos con mucho tráfico y está entrando continuamente spam en todos ellos puede acabar siendo un problema.

En Stop Forum Spam han creado una lista de spammers a nivel mundial que puedes consultar descargando un fichero con las ips, emails o nombres de usuario utilizados o a través de una api que puedes consultar libremente desde cualquier aplicación que desarrolles.

En mi caso para ahorrar tiempo y ancho de banda he creado una entrada en el cron que diariamente descarga las ips bloqueadas durante las ultimas 24 horas y las bloquea directamente.

Ejemplo con iptables

.
/usr/bin/wget -O /tmp/listed_ip_1.zip http://www.stopforumspam.com/downloads/listed_ip_1.zip; /usr/bin/unzip /tmp/listed_ip_1.zip -d /tmp/; for i in $(/bin/cat /tmp/listed_ip_1.txt); do /sbin/iptables -A INPUT -s $i -j DROP; done; /bin/rm /tmp/listed_ip_1.*

y si utilizas el firewall apf

.
/usr/bin/wget -O /tmp/listed_ip_1.zip http://www.stopforumspam.com/downloads/listed_ip_1.zip; /usr/bin/unzip /tmp/listed_ip_1.zip -d /tmp/; for i in $(/bin/cat /tmp/listed_ip_1.txt); do /usr/local/sbin/apf -d $i; done; /bin/rm /tmp/listed_ip_1.*

Espero que os sea útil.

[Actualización]
Acabo de encontrar un plugin para wordpress que utiliza esta lista junto con otras dos:
http://wordpress.org/extend/plugins/stop-spammer-registrations-plugin/

Ayer detecté un error poco frecuente en un servidor web con apache.
Después de una caida del servidor, cuando intentaba iniciar el apache este no arrancaba y en el log aparecía el error.
(28)No space left on device: Couldn’t create accept lock (/var/lock/apache2/accept.lock.xxxxx) (5)

Espacio en disco duro no falta, así que el problema era otro por lo que revolviendo por internet vi que, por suerte, no era el primero que le pasaba algo así y que ese error se achacaba a un problema con el array de semáforos.

Al hacer un

ipcs -s

se veía que tenía un montón de semáforos abiertos por el usuario del apache cuando este no está funcionando.
La solución pasa por eliminar todos los semáforos abiertos por el usuario del apache y ya se puede reiniciar sin problemas.

Si los liberas a mano puedes utilizar:

ipcrm -s proceso

O si lo prefieres automatizar un poco:

for i in `/usr/bin/ipcs -s | /bin/grep www-data | /usr/bin/awk '{print $2}'` ; do /usr/bin/ipcrm -s $i; done

Ahora sólo me queda averiguar por que se llena el array de semáforos y no se libera.

Enviar correos desde WordPress es muy sencillo utilizando la función wp_mail.

Lo mejor es que veáis un ejemplo.

$email="usuario@dominio.com";
$titulo="Subject del Email de prueba";
$mensaje="Email de prueba. bla bla bla";
$headers = 'From: Remitente ' . "\r\n";
wp_mail($email, $titulo, $mensaje, $headers);

En este ejemplo podemos ver los cuatro campos principales. Lo que hace es enviar un email en modo texto, si queremos enviarlo en html debemos añadir un filtro para indicar que el contenido se enviará en html.

add_filter('wp_mail_content_type',create_function('', 'return "text/html"; '));

En el ejemplo:

$email="usuario@dominio.com";
$titulo="Subject del Email de prueba";
$mensaje="Email de prueba. bla bla bla";
$headers = 'From: Remitente ' . "\r\n";
add_filter('wp_mail_content_type',create_function('', 'return "text/html"; '));
wp_mail($email, $titulo, $mensaje, $headers);

Si además queremos enviar un fichero adjunto al mensaje sólo tenemos que añadir un parámetro más a la función wp_mail.

$email="usuario@dominio.com";
$titulo="Subject del Email de prueba";
$mensaje="Email de prueba. bla bla bla";
$headers = 'From: Remitente ' . "\r\n";
$fichero="/home/rastreador/mi_fichero";
$atach= array($fichero);
add_filter('wp_mail_content_type',create_function('', 'return "text/html"; '));
wp_mail($email, $titulo, $mensaje, $headers,$atach);

WordPress muestra en las cabeceras de todos los blogs la versión que estás ejecutando. Si quieres añadir una pequeña capa más de seguridad a tu instalación de WordPress lo mejor es eliminar esa información.
Una forma sencilla y rápida de hacer esto es añadir al final de tu fichero functions.php del tema este código:

remove_action('wp_head', 'wp_generator');