Report inadequate content

Linux in Harecoded

Convertir de ISO a UTF-8 por línea de comandos

 TAGS:Esta mañana he tenido que utilizar un .CSV generado desde Excel.

Al acceder a él desde la línea de comandos me he encontrado que se perdían todos los acentos. Un problema ya clásico este de "los carácteres especiales".

Gracias al comando 'file' he podido descubrir la codificación que Excel le da a nuestro fichero en el momento de hacer la exportación.

>file nombre_fichero.csv
nombre_fichero.csv: ISO-8859 text, with CRLF line terminators

Lo único que he tenido que hacer es convertirlo en la misma terminal a UTF-8. Conviene fijarse en que, iconv utiliza ISO-8859-15 en lugar del ISO-8859 que me ha devuelto file:

> iconv -f ISO-8859-15 -t UTF-8 fichero_origen.csv > fichero_convertido.csv

Con esto ya tengo en fichero_convertido.csv los datos con el formato esperado.
Suerte.

Textos grandes a partir de caracteres básicos en terminal

Estaba haciendo un script para automatizar el proceso de conexión a una base de datos, en producción.

Uno de esos scripts que conviene usar con cuidad así que pensé en poner un aviso que se mostrara al ejecutarlo:

[user~]$ cat prod_mysql.sh
echo "CUIDAOOOOOOOOO!!!!!" mysql -h localhost -u user_prod -plucksoytuhijo main_data

Pero al ejecutarlo pensé que ese aviso no era tan visible com me gustaría así que recordé una herramienta que usaba hace muchos años. Su nombre es figlet y, casualidades de la vida, todavía está disponible para correr en mi CentOS 6.3 http://www.figlet.org/

La instalación de figlet en CentOS es muy sencilla:

cd /tmp
wget http://pkgs.repoforge.org/figlet/figlet-2.2.2-1.el6.rf.x86_64.rpm
sudo rpm -U figlet-2.2.2-1.el6.rf.x86_64.rpm

Y ahora sólo me queda adaptar mi script:

[user~]$ cat prod_mysql.sh
figlet "CUIDAOOO!"
mysql -h localhost -u user_prod -plucksoytuhijo main_data

Mucho mejor:

[user~]$ ./prod_mysql.sh
  ____ _   _ ___ ____    _    ___   ___   ___  _
 / ___| | | |_ _|  _ \  / \  / _ \ / _ \ / _ \| |
| |   | | | || || | | |/ _ \| | | | | | | | | | |
| |___| |_| || || |_| / ___ \ |_| | |_| | |_| |_|
 \____|\___/|___|____/_/   \_\___/ \___/ \___/(_)

Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 18432
Server version: 5.1.61 Source distribution

Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Varnish VCL: Delete ALL cookies and other magic

This morning Javi Callón gave me a great introduction in few minutes to the Varnish in steroids world, I really appreciate it.  I'd like to share this snippet which might be very interesting for you if you are new to the Varnish magic too.

This has been my first contact with Varnish ever, and I have to say I am quite amazed on how the application is responding now in terms of performance. Do not take this snippet as a definitive solution to your problems.

I wrote an article yesterday on how to install Varnish. Truth is that if you install Varnish and you do not tune the VCL file chances are that Varnish is not caching anything because of the cookies. In a dynamic application there are a lot of factors that have to be taken (headers, user-agents, variations...)

This sample VCL tries to address the following problems:

  • Ignore a specific host (do not cache)
  • Remove ALL the cookies in the caching (the application does not need any of them)
  • Change the varnish cache of the images to 5 minutes
  • Special case when the URL contains a GET parameter ?rev=
  • Add in the response headers number of hits and if was a HIT or a MISS

Open the file/etc/varnish/default.vcl and add the following. It is recommended to leave the rest of the comments as they are for future reference of what Varnish does by default.

The code is commented so you properly understand what it does and you can remove any pieces you don't need.

# You already have a block like this one when you installed Varnish, keep it safe:
backend default {
  .host = "127.0.0.1";
  .port = "8080";
}

# ADD THE FOLLOWING
# -----------------

# 2 things are done here:
# First, ignore any request to a specific host. For instance, you don't want Varnish on a specific host.
# Second, remove cookies, because my application does not rely on cookies at all.
sub vcl_recv {

     # Varnish will Ignore any request to this host  (e.g: xx.mydomain.com)
     if ( req.http.host ~ "([a-z0-9]{2}\.mydomain\.com)$" )
     {
        return(pipe);
     }

     #Goodbye incoming cookies:
     unset req.http.Cookie;

}


sub vcl_fetch {
    # Remove cookies that destroy cache:    
     unset beresp.http.Set-Cookie;

     # 5 minutes (300s) cache for images
    if ( req.url ~ "\.(jpg|jpeg|png|gif)$" )
     {
        set beresp.ttl = 300 s;
     }

    # This is very specific of SIFO.me framework, but you can recycle it:
    # Any static URL containing ?rev= (this is JS and CSS) cache it almost forever.
    # The following regexp will find urls like http://.../file.js?rev=1747c3872495221156287e2000a0d110
    if ( req.url ~ "\?rev=[a-f0-9]{32}$" )
    {
       set beresp.ttl = 600000 s;
    }
}

# Add some debug info headers when delivering the content:
# X-Cache: if content was served from Varnish or not
# X-Cache-Hits: Number of times the cached page was served
sub vcl_deliver {

        # Was a HIT or a MISS?
        if ( obj.hits > 0 )
        {
                set resp.http.X-Cache = "HIT";
        }
        else
        {
                set resp.http.X-Cache = "MISS";
        }

        # And add the number of hits in the header:
        set resp.http.X-Cache-Hits = obj.hits;
}

Try if the configuration syntax is OK with:

/etc/init.d/varnish configtest

And then restart the service (also wipes the cache).

/etc/init.d/varnish restart

The new headers should appear and you will be able to see what Varnish is doing with a simple CURL or with any browser Inspector. Example:

[root@mnm1 mnm]# curl --head http://yourhost,com
HTTP/1.1 200 OK
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/5.3.3
Cache-Control: public, must-revalidate, max-age=30, s-maxage=43200
Vary: Accept-Encoding
Content-Type: text/html; charset=UTF-8
Date: Tue, 09 Oct 2012 13:38:41 GMT
X-Varnish: 1572155458 1572155457
Age: 12
Via: 1.1 varnish
Connection: keep-alive
X-Cache: HIT
X-Cache-Hits: 1

Have in mind that all these functions are appended to the default behaviour. So they are adding extra things, but not preventing the default Varnish workflow take action.

In the cases where the time to live of the cache (TTL) is not set ,Varnish will cache it for 2 minutes (look for "120 s" in the deafault.vcl code).

All in all, it seems to me that for the huge benefit that Varnish adds to a project, the investment of time and resources you have to put on are ridiculous (half morning if your dynamic app doesn't have excessive magic). Do not be scared and try to add Varnish at least in your static files, then move to the dynamics.

Simple Varnish Installation

The first thing to do is to make sure your application is passing the headers properly. At least you'll need this (in PHP):

// Let's say Varnish caches for 12 hours:
$cache_max_age = 60*60*12;
header( "Cache-Control: public, must-revalidate, max-age=0, s-maxage=$cache_max_age" ); 

Varnish installation (CentOS/Redhat):
RPM taken from https://www.varnish-cache.org/installation/redhat

rpm --nosignature -i http://repo.varnish-cache.org/redhat/varnish-3.0/el5/noarch/varnish-release-3.0-1.noarch.rpm

After adding the package:

yum install varnish

If you have another Linux see in the link, is more or less the same.

Now Varnish is installed. What we want to do next is to configure Apache to listen in another port and let the port 80 for Varnish. Varnish will be the one requesting to Apache the html and saving it in the memory for later accesses.

We will use as example the port 8080 for Apache. The first thing is to tell Varnish, where Apache will be listening to:

vi /etc/varnish/default.vcl

# Change the port to 8080, like this. Leave the rest of file as is:
backend default {
  .host = "127.0.0.1";
  .port = "8080";
}

Then we have to change Varnish to make it listen in port 80:

vi /etc/sysconfig/varnish

# Change VARNISH_LISTEN_PORT variable to 80, like this:
VARNISH_LISTEN_PORT=80

And now in the Apache settings make it listen to 8080:

vi /etc/httpd/conf/httpd.conf
# Change the Listen variable to 8080:

Listen 8080

If you use Named Virtualhosts using the port number (e.g: You declare them with NameVirtualHost *:80) you'll need to change them to 8080 too. I usually store my virtual configurations under this file, use yours:

vi /etc/httpd/conf.d/virtual.conf

# You can replace all the 80 by 8080 easily with vi with (take care there aren't other things changed):
:%s/80/8080/g

And now hold your breathe. Stop both services and start them again to make changes effective:

/etc/init.d/httpd stop
/etc/init.d/varnish stop
/etc/init.d/httpd start
/etc/init.d/varnish start

Your application should be served by Varnish now. Check in the "Network" tab of your Google Chrome or Firefox that the headers are properly passed:

 TAGS:

Putty keep-alive session (mantener activa la sesión)

Cuando utilizamos putty como cliente ssh muchas veces nos encontramos que, tras un tiempo de inactividad, la sesión se cierra.

Putty cuenta con una opción que nos permite envíar paquestes nulos, de forma automática, cada periodo definido de tiempo. De esa manera, putty, mantendrá la sesión activa.

Antes de activar esta opción hay que tener en cuenta que, el sistema de cancelación automática de una conexión no es más que una medida de seguridad por lo que, en caso de conectarnos a sistemas "sensibles", no conviene activar el keep-alive.

  TAGS:

 

 TAGS:

IP's que usa Facebook Open Graph

Queremos desarrollar una funcionalidad en nuestro proyecto web que intereactua con Facebook mediante el protocolo Open Graph.

Facebook nos ofrece una herramienta de Debug para validar que, las entradas OG de nuestro site son las esperadas. Con añadir nuestra url en esa herramiento podemos ver un interesante informe.

Cuando lanzamos cualquier tipo de acción desde nuestro site, desde el clásico "me gusta" a las más elaboradas "Custom Actions", Facebook envía su bot a la url que le enviamos y captura los datos de nuestros registros Open Graph. Dicen que, cada hora, lo revisan para mantenerse actualizados.

El problema surge cuando estamos desarrollando una nueva funcionalidad y, todavía, no está accesible en producción. En ese caso habrá que abrir el acceso a nuestro entorno de desarrollo para Facebook.

Estás son las ip's que, hasta la fecha, hemos podido identificar como las usadas por los crawlers de Facebook.

66.220.144.0/20
69.63.176.0/20
69.171.224.0/19
74.119.76.0/22
103.4.96.0/22
173.252.64.0/18
204.15.20.0/22
31.13.24.0/21
31.13.64.0/18

Contar veces que se pide una URL (y las que no es esa URL)

Hay veces que queremos saber cuántas veces se ha pedido una URL en nuestro servidor y Google Analytics o otro servicio de monitorización basado en Javascript no está disponible. Entonces siempre podemos recurrir a la fuente original de datos, los logs de acceso (esos gran incomprendidos y frecuentemente abandonados) de Apache, Nginx o donde sea.

Si por ejemplo queremos saber cuántas veces se ha pedido la página /abc.html en el mes de febrero (2012_02) y tenemos los logs segmentados por día, será tan sencillo como lanzar un:

grep -c  "GET /abc.html" /var/log/apache/access_2012_02_*

Similarmente, podemos obtener el número de peticiones que NO contienen esa petición añadiendo el parámetro -v:

grep -vc  "GET /abc.html" /var/log/apache/access_2012_02_*

La ubicación exacta de los blogs está declarada en vuestra configuración de Apache o Virtualhosts bajo la directiva AccessLog.

Instalar PHP 5.3 en CentOS

Me tienen contento!

Hace muchísimo que deberían haber incluído la versión de PHP 5.3 en los paquetes php por defecto de CentOS, pero parece que se van a quedar con la 5.2 hasta el fin de los tiempos. Ofrecen la versión 5.3 como un paquete separado (php53), lo que implica desinstalar PHP y librerías asociadas para reinstalar la 5.3 con este paquete distinto (incompatible con el anterior claro).

Así que, no pudiéndome aguantar más y con mono de namespaces, funciones lambda y toda la pesca, he migrado mi CentOS 5.5 a la 5.7 (esto no viene al caso ahora ni es necesario, via yum update.) y luego PHP a la 5.3 utilizando un repo externo. Para ello me he servido del repositorio REMI. Si no lo tienes para instalarlo sólo hay que hacer:

cd /etc/yum.repos.d/
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-5.rpm

Y para disfrutar de la 5.3:

yum --enablerepo=remi update php

Si no tienes aún PHP instalado entonces usa "install" en vez de "update".

Ale! Todo listo.

Conectar por SSH sin password (autenticación de clave pública)

 TAGS:

Esta es una de aquellas cosas que uno hace una y otra vez y al final pierde 10 minutos intentando recordar los comandos o buscando la información.

Para conectar a un servidor remoto por SSH sin usuario ni contraseña todo lo que hace falta es compartir una clave entre cliente y servidor. Los pasos son "mu" sencillos:

  1. Asegurarse que la carpeta .ssh existe en el servidor al que nos queremos conectar
  2. Crear una clave RSA pública en la máquina cliente (la que se conecta):
    ssh-keygen -t rsa
    Cuando se te pida por un password, dale al enter sin poner ninguno (este es el propósito del artículo, sin passwords)
  3. Copiar la clave pública en el servidor:
    scp ~/.ssh/id_rsa.pub usuario@servidor.com:.ssh/authorized_keys2

    Puedes omitir la parte usuario@ si te conectas con el mismo usuario.

Y esto es todo amigos. En la siguiente conexión por SSH ya no se pedirá de nuevo el password.

Importante:

A partir de este momento, si alguien robara la clave pública que has guardado en ~/.ssh/id_rsa tendría acceso completo a tu servidor. Más vale que la protejas bien :)

Si dejas un password en la autenticación RSA puede ser una buena idea desactivar en el servidor el acceso SSH vía login/password y dejar sólo autenticación por clave.