Archive for the ‘Informática’ Category

Devolviendo un servidor de forma segura

Saturday, December 11th, 2010

Esta última semana he estado cambiando de servidor. Se acercaba la hora de renovar el servidor dedicado donde, por ejemplo, se encuentra alojado este blog y en la web del proveedor (OVH en este caso) ofrecían un servidor dedicado con mayores prestaciones y un 25% más barato. Así que contraté el nuevo servidor y moví los servicios.

Entonces me planteé la pregunta de como podía asegurarme de que el próximo “inquilino” del servidor viejo no pudiera recuperar ninguno de mis ficheros. Ya conocía las utilidades wipe o shred pero me faltaba encontrar una forma de poder ejecutarlas borrando todo el disco duro. Por suerte, los servidores dedicados de OVH disponen del “modo rescate” que arranca una mini-distribución por red en nuestro servidor a la que nos podremos conectar por SSH tras recibir el correo con la contraseña de root y que, afortunadamente, dispone de shred.

Así que, los pasos para devolver el servidor de forma segura serían:

  1. En el manager de OVH vamos a la sección ‘Servicios’ y vamos a ‘Netboot’
  2. De los netboot disponibles seleccionaremos ‘rescue-pro
  3. Ahora reiniciaremos el servidor para que arranque la distribución de rescate. Una vez haya arrancado, recibiremos un mail con la contraseña del usuario root.
  4. Ya sólo nos queda conectarnos por SSH al servidor usando la contraseña recibida y ejecutar 
    root@rescue:~# nohup shred -fvz /dev/sda&

Ese comando sobrescribirá todo el disco duro 25 veces (valor por defecto) con varios patrones y finalmente lo sobrescribirá con ceros para, según la página de man, ocultar el hecho de que se ha ejecutado. Dependiendo del tamaño del disco, el borrado seguro puede tardar bastantes horas, incluso días. Por eso aconsejo ejecutarlo con nohup y ponerlo en background. Así podremos desconectarnos y el proceso seguirá ejecutándose. Siempre podremos verificar el progreso leyendo el fichero nohup.out.

Una vez haya terminado, reiniciamos el servidor y ya estará listo para regresar a manos del proveedor sin que debamos temer por nuestros datos.

Como probar SMTP AUTH mediante CRAM-MD5

Thursday, December 9th, 2010

En artículos anteriores ya he hecho referencia al excelente artículo de Jaume Sabater sobre la instalación y configuración de un servidor de correo con Postfix. En su artículo hace el razonamiento de que como la autenticación se va a realizar sobre un canal cifrado no hace falta habilitar los métodos de autenticación CRAM-MD5 o DIGEST-MD5, que permiten hacer login sin transmitir la contraseña en plano (como pasa con los métodos PLAIN o LOGIN). Y no le falta razon, pero yo he tomado un camino intermedio: en el servidor SMTP por el puerto 587 (submission) están permitidos todos los métodos de autenticación ya que se fuerza el cifrado de la conexión; pero por el 25 no permito los métodos de autenticación PLAIN o LOGIN para evitar la tentación de hacer login con uno de esos métodos mediante un canal inseguro, pero sí permito CRAM-MD5 o DIGEST-MD5.

Para conseguir este efecto, nos aseguraremos que el siguiente parametro este definido en el fichero /etc/postfix/main.cf
smtpd_sasl_security_options = noplaintext, noanonymous

Con esto conseguiremos que por defecto no se permita ni PLAIN ni LOGIN. Para habilitarlos por el puerto de submission, modificaremos la definición del servicio submission en el fichero /etc/postfix/master.cf añadiendo la línea:
-o smtpd_sasl_security_options=noanonymous

El problema viene a la hora de comprobar que podemos hacer login mediante, por ejemplo, CRAM-MD5 ya que el cliente debe calcular el HMAC-MD5 de un string generado por el servidor, siendo la clave del algoritmo la contraseña del usuario, para realizar la autenticación sin que el usuario deba revelar su contraseña. Pero no es nada que unas cuantas lineas de Perl no puedan resolver:

#!/usr/bin/perl
use MIME::Base64
use Digest::HMAC_MD5 qw(hmac_md5_hex);
print encode_base64($ARGV[1] . " " . hmac_md5_hex(decode_base64($ARGV[0]), $ARGV[2]));

Los argumentos a pasarle son:

  1. el challenge generado por el servidor
  2. el nombre de usuario
  3. la contraseña

Pero nada mejor que un ejemplo para ver como funciona.

S: 220 mail.example.com ESMTP Postfix (Debian/GNU)
C: ehlo client.example.com
S: 250-mail.example.com
S: 250-PIPELINING
S: 250-SIZE 10240000
S: 250-ETRN
S: 250-STARTTLS
S: 250-AUTH DIGEST-MD5 NTLM CRAM-MD5
S: 250-AUTH=DIGEST-MD5 NTLM CRAM-MD5
S: 250-ENHANCEDSTATUSCODES
S: 250-8BITMIME
S: 250 DSN
C: AUTH CRAM-MD5
S: 334 PDQwMTc3NTY4MTAuODMzNzFAb3ZoMjAxMC5sbHVsbC5uZXQ+

Al indicarle que queremos autenticarnos mediante CRAM-MD5 el servidor nos proporciona el challenge que pasaremos al script en Perl junto con el nombre de usuario y la contraseña en otra consola.

$ ./cram-md5.pl PDQwMTc3NTY4MTAuODMzNzFAb3ZoMjAxMC5sbHVsbC5uZXQ+ user password
dXNlciA3MTUxODVjYTRkMzMxOGRkMzYxZTg2NDg4M2ZkNmE3NA==

Para autenticarnos, le enviaremos el string obtenido al servidor.

C: dXNlciA3MTUxODVjYTRkMzMxOGRkMzYxZTg2NDg4M2ZkNmE3NA==
S: 235 2.7.0 Authentication successful
C: quit
S: 221 2.0.0 Bye

(‘$’ denota el promt de la shell, ‘S’ una línea recibida del servidor y ‘C’ una línea enviada por el cliente)

Cambiar la contraseña de Google en Android

Sunday, November 7th, 2010

Hoy me ha dado por cambiar la contraseña de mi cuenta en Google y, como era de esperar, mi Nexus One ha dejado de sincronizar los contactos y emails, pero no me esperaba que fuera tan complicado cambiarle la contraseña. Aunque debo reconocer que seguramente la culpa sea mía :-P

Cuando la sincronización ha fallado, en la barra de notificaciones de Android (la barra arriba del todo) ha aparecido el correspondiente aviso. Al hacerle click me ha abierto un dialogo preguntándome por un captcha, que por su tamaño resulta muy complicado leer y con el teclado en la pantalla resulta muy sencillo equivocarse al teclear. Después de contestar el captcha debía introducir la nueva contraseña, pero no conseguía pasar del captcha.

Tras buscar un poco por la ayuda de GMail, he encontrado que si te equivocabas en repetidas ocasiones al introducir el captcha, este se bloquearía. Por el tamaño que tiene, estoy convencido que en mis primeros intentos debo haberlo bloqueado. Por suerte los captchas se pueden desbloquear desde https://www.google.com/accounts/UnlockCaptcha, y tras hacerlo he podido poner la nueva contraseña en el móvil sin ningún problema.

Así que, ya sabéis que hacer si os encontráis en la misma situación.

El porqué de las instancias “spot” de Amazon EC2

Tuesday, August 10th, 2010

Amazon Web Services

Desde que las conocí, las instancias spot de Amazon EC2 siempre me habían llamado la atención desde la perspectiva económica. Aunque me parecía una forma interesante de sacar provecho económico a un exceso de capacidad de la plataforma EC2 en horas valle, que de otra forma sería desperdiciada, no acababa de entender sus ventajas frente a consolidar los servidores virtuales en un menor número de hosts y apagar los ociosos para ahorrar en consumo eléctrico. Siempre había supuesto, como gran parte de la industria, que el consumo eléctrico era el principal gasto en un datacenter.

No lo entendía hasta que hace unos días tuve la oportunidad de ver la presentación “Datacenter Infrastructure Innovation” (trasparencias) que James Hamilton dió durante el Velocity 2010. En su presentación realiza un estudio de los costes mensuales de un datacenter, mensualizando el coste de los servidores y de las infraestructuras de distribución y refrigeración a lo largo de sus periodos de amortización (3 y 10 años, respectivamente). De esta manera, puede comparar esos gastos con el consumo eléctrico. Y resulta que el que yo suponía era el principal gasto realmente es el tercero, siendo los dos primeros el hardware de los servidores y las infraestructuras, en ese orden.

Como bien explica James, consolidando y apagando hosts se ahorraría en consumo eléctrico pero, al no estar sacando ningún provecho económico al servidor físico ni a la parte proporcional de las infraestructuras de distribución y refrigeración, realmente se está perdiendo dinero. Al contrario de lo que ocurre con el consumo eléctrico, la amortización de las infraestructuras no es algo que puedas ahorrarte.

Pero si tienes exceso de capacidad y apagar los servidores supone realmente un gasto, ¿qué se puede hacer? Ahí es donde encajan las instancias spot. Permiten sacarle provecho al exceso de capacidad que se produce en las horas valle, a un precio que resulta atractivo a los clientes. Mientras escribo este artículo, el precio de las instancias spot es un ~60% más barato que las on-demand. Eso sí, las aplicaciones que corran en este tipo de instancias deben estar preparadas para los apagados abruptos que se producen en cuanto la demanda de instancias “normales” aumenta.

Instancias spot, ahorro económico para los clientes y una forma de aprovechar la capacidad sobrante para Amazon.

Como afecta el algoritmo al rendimiento (o resolviendo una pregunta de Google)

Sunday, April 11th, 2010

Tras nueve meses de sequía bloguera, vuelvo con un post bastante parecido al de “Exponenciación modular” (uno de los que más visitas tiene) que toca uno de los temas que me apasionan: el rendimiento de los algoritmos. Hace bastantes meses leí, via meneame, un post con 140 preguntas que (supuestamente) Google puede hacerte en una entrevista de trabajo. Una de esas preguntas me llamó la atención, tanto que unos cuantos compañeros del trabajo la estuvimos comentando. Te pedían que escribieras un algoritmo muy simple:

Dado un array A[N] de N números. Tienes que generar un array Ouput[N] de manera que Output[i] sea la multiplicación de todos los elementos de A[N] excepto A[i]. Por ejemplo Output[0] será la multiplicación desde A[1] hasta A[N-1] y Output[1] sera la multiplicación de A[0] y desde A[2] hasta A[N-1]…

En ruby es tan sencillo como:

n = A.length
Ouput = Array.new(n) do |i|
  result = 1
  n.times { |j| result *= A[j] unless j == i }
  result
end

El problema es que la pregunta continuaba con:

… hazlo en O(n) …

Ups, hay que repensarlo ya que el algoritmo anterior tiene dos bucles sobre N anidados por lo que es O(n2). Se me ocurrió hacerlo precalculando el producto de todos los elementos de A[N] y hacer que Output[i] = Total / A[i]. Así queda O(n).

product = A.inject(1) { |total, n| total * n }
Output = A.collect { |n| product / n }

Pero faltaba un último detalle de la pregunta:

… sin el operador de división.

Uff, ahora se pone interesante. Tras pensarlo un poco y escribir Ouput como una matriz de los elementos a multiplicar, ví un patrón que me podía servir. La matriz está formada por dos “triángulos” (perdón si el termino no es correcto. Hay algún matemático entre la audiencia?) que llamaremos L, resaltado en azul, y R, en rojo.

Output[0]   = [   1, A[1], A[2], ..., A[N-1]]
Output[1]   = [A[0],    1, A[2], ..., A[N-1]]
Output[2]   = [A[0], A[1],    1, ..., A[N-1]]
...
Output[N-1] = [A[0], A[1], A[2], ...,      1]

Se me ocurrió que esos dos “triángulos” o productos parciales se podían calcular a la vez en un único bucle para usarlos posteriormente para calcular Ouput[i] = L[i] * R[i] ya que:

  • L[i] = L[i-1] * A[i-1] para i > 0 (L[0] = 1)
  • R[i] = R[i+1] * A[i+1] para i < N-1 (R[N-1] = 1)
n = A.length
left,right = Array.new(n, 1), Array.new(n, 1)
1.upto(n-1) do |i|
  left[i]        =  left[i-1] * A[i-1]
  right[n-(i+1)] = right[n-i] * A[n-i]
end
Output = Array.new(n) { |i| left[i] * right[i] }

Bien, creo que al final lo hemos conseguido. Un algoritmo O(n) que no usa la división y que calcula los resultados según la formula indicada. Además, el algoritmo que usa la división tiene un problema: necesita que los elementos de A[N] sean números naturales (es decir, que no puedan ser 0) mientras que los otros dos algoritmos no tienen esta restricción.

Si os estáis preguntando si realmente hay diferencia de rendimiento entre los tres algoritmos (principalmente el primero versus los otros dos), aquí tenéis un gráfico que lo demuestra.

Como se puede ver, a medida que el tamaño del array A[N] crece los tiempos del primer algoritmo (double loop) crecen exponencialmente mientras que los otros dos (division y triangles) tienen un comportamiento lineal. Por tanto, si que hay diferencia, y mucha.

Los datos de benchmarking para generar el gráfico con el OpenOffice.org Calc los he obtenido he usado el siguiente script que genera CSV.

#! /usr/bin/env ruby
require 'benchmark'
 
def double_loop(input)
  n = input.length
  Array.new(n) do |i|
    result = 1
    n.times { |j| result *= input[j] unless j == i }
    result
  end
end
 
def division(input)
  product = input.inject(1) { |total, n| total * n }
  input.collect { |n| product / n }
end
 
def triangles(input)
  n = input.length
  left,right = Array.new(n, 1), Array.new(n, 1)
  1.upto(n-1) do |i|
     left[i]       =  left[i-1] * input[i-1]
    right[n-(i+1)] = right[n-i] * input[n-i]
  end
  Array.new(n) { |i| left[i] * right[i] }
end
 
t = 1_000
max_size  = 250
step_size = 10
 
step_size.step(max_size, step_size) do |n|
  input = Array.new(n) { rand(100) + 1 }
  t1 = Benchmark.realtime { t.times { double_loop(input) } }
  t2 = Benchmark.realtime { t.times { division(input) } }
  t3 = Benchmark.realtime { t.times { triangles(input) } }
  puts "#{input.length};#{t1};#{t2};#{t3}"
end

Por cierto, si a alguién se le ocurre otro algoritmo que lo ponga en los comentarios.

Actualización automática de los plugins de WordPress por SSH

Saturday, July 11th, 2009

Las versiones recientes de WordPress te permiten actualizar los plugins instalados con un simple click. Aunque interesante, nunca había usado esa funcionalidad porque requería tener instalado y configurado un servidor FTP o FTPS. Y, la verdad, me daba mucha pereza tener que mantener un servicio sólo para esto.

Pero hoy, tras actualizar a la versión 2.8.1, por casualidad he lanzado un grep en un directorio que no tocaba y he descubierto el fichero wp-admin/includes/class-wp-filesystem-ssh2.php. Resulta que WordPress también puede usar SSH para realizar esas actualizaciones. Normalmente esa opción no aparece por que no disponemos de todo el software necesario para que funcione, pero es bastante sencillo conseguirlo. Veamos como hacerlo en una Debian:

$ sudo aptitude install libssh2-1 libssh2-1-dev php5-dev
$ sudo pecl install -f ssh2
$ sudo vi /etc/php5/conf.d/ssh2.ini
    extension=ssh2.so
$ sudo /etc/init.d/apache2 restart

Una vez tenemos instalada la extensión ssh2.so de PHP, podemos desinstalar los paquetes de desarrollo que instalamos en el primer paso.

$ sudo aptitude remove libssh2-1 libssh2-1-dev php5-dev

Listo, ya podemos actualizar los plugins desde la comodidad de nuestro navegador sin necesidad de tener un servidor FTP o FTPS. Seguramente también se puede usar para actualizar el propio WordPress, aunque no lo puedo confirmar ya que yo lo actualizo usando subversión.

Como se puede ver es bastante sencillo. De todas formas, os dejo un screencast que he hecho sobre la instalación (inaugurando mi cuenta de YouTube).

Firmas DKIM con Postfix y Amavis

Saturday, June 6th, 2009

Hace bastantes meses escribí un artículo sobre como configurar el SpamAssassin para que verifique las firmas DKIM para luchar contra el Spam y me quedó pendiente explicar como firmar nuestros própios correos. Por aquel entonces era más o menos complicado pero desde la release de Debian Lenny, que incluye el paquete amavisd-new 2.6.1, la tarea se ha simplificado.

Voy a dar por sentado que tenemos un Postfix instalado y configurado para que use el Amavis para las funciones de anti-virus y anti-spam. Si no es así, te recomiendo que leas el excelente artículo de Jaume Sabater.

El primer problema lo tenemos si el mismo servidor está actuando como MX y como servidor SMTP para nuestros usuarios: Amavis firmaría tanto los correos de nuestros usuarios como los que le llegan en su función de MX, y no es lo que queremos. Por tanto, lo primero es separar esas dos funciones (MX y submission) en el Postfix añadiendo las siguientes líneas en /etc/postfix/master.cf (seguramente ya haya algo parecido pero comentado)

1
2
3
4
5
submission inet n       -       n       -       -       smtpd
-o smtpd_enforce_tls=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o content_filter=smtp-amavis:[127.0.0.1]:10026

Con estas líneas estamos indicándole al Postfix que también escuche por el puerto de submission (587/tcp), que por ese puerto sólo acepte correo de conexiones autentificadas y cifradas por TLS, y que debe enviar los correos recibidos al Amavis usando el puerto 10026 (mientras que el resto se seguirá enviando por el puerto 10024). Con esto conseguiremos que Amavis distinga y trate de forma diferente los correos de los usuarios.

Lo siguiente es hacer que Amavis también escuche por el puerto 10026 y hacer que firme los correos que le lleguen por ese puerto. Lo haremos añadiendo al fichero /etc/amavis/conf.d/50-user:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$inet_socket_port = [10024, 10026];
 
$interface_policy{'10026'} = 'AUTH';
 
$policy_bank{'AUTH'}   = {           # Authenticated clients
os_fingerprint_method   => undef, # don't fingerprint authenticated clients
bypass_spam_checks_maps => [1],   # don't spam check authenticated clients
originating => 1,
#
# force MTA to convert mail to 7-bit before DKIM signing
# to avoid later conversions which could destroy signature:
smtpd_discard_ehlo_keywords => ['8BITMIME'],
};
 
$enable_dkim_signing = 1;
dkim_key('llull.net', 'personal', '/etc/dkim/llull.net.key.pem');

En la última línea le indicamos que para el dominio ‘llull.net‘ y el selector ‘personal‘ debe firmar los correos con la clave privada contenida en el fichero /etc/dkim/llull.net.key.pem. Para generar ese fichero ejecutaremos como root el comando

server:~# amavisd-new genrsa /etc/dkim/llull.net.key.pem
Private RSA key successfully written to file "/etc/dkim/llull.net.key.pem" (1024 bits, PEM format)

Ya sólo falta obtener y configurar en nuestro servidor DNS la clave pública y para ello disponemos de otro comando:

server:~# amavisd-new showkeys
personal._domainkey.llull.net.  3600 TXT (
"v=DKIM1; p="
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDoTaWXxsXpNi100Flp7fIKJSlZ"
"ptMP4aCCZjUFgT7TsWokWQJhnGUNnxexEqqPtCDbCUAvEg3iieMRrKwZoHAUDqCf"
"fvW9dcYR7+NdnaxAXCBpOh8Wg5GFJeIid9Gsx3ByBObBQnRGSMOxdBRBO4VXwGb2"
"hKAIOiBMPxaFghdDZQIDAQAB")

Y ya sólo falta añadir la salida del anterior comando a la zona de nuestro dominio en el servidor DNS. La salida está en formato Bind por lo que si usamos ese servidor DNS no tendremos más que añadir  ese texto en el fichero correspondiente.

Acordaos de reiniciar el Postfix, Amavis y Bind para que apliquen las nuevas configuraciones. Para comprobar que todo está funcionando correctamente, podemos enviar un correo a uno de los reflectores existentes.

Ahora ya no tenéis escusa para que vuestro servidor de correo no firme los correos salientes. Si os surge alguna duda, usad los comentarios. Aunque creo que me he acordado de todo, han pasado algunos meses desde que lo configuré y es posible que haya pasado algo por alto.

Artículo basado en la documentación oficial de Amavis.

Optimizaciones en el blog

Sunday, May 24th, 2009

Desde que Xisco me pidió consejo tras probar varias de sus páginas con YSlow tenía pendiente escribir este post. YSlow es un plugin para Firefox que analiza distintos aspectos que pueden afectar al rendimiento de páginas webs y realiza recomendaciones. Todos los aspectos que se tienen en cuenta giran alrededor del tiempo de carga de la web. No entran en temas como optimización de base de datos y otros aspectos internos del servidor.

De todas las reglas, las más sencillas de corregir son:

Otras reglas pueden suponer reescribir parte de la aplicación pero para solventar estas tres basta con añadir algunas líneas al final del .htaccess del directorio raíz de nuestra web. Hay que tener en cuenta que los modulos necesarios deben estar instalados y la configuración del servidor nos debe permitir establecer esta configuración (directiva AllowOverride)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Add Expires Header
<IfModule mod_expires.c>
ExpiresActive on
ExpiresByType image/gif "access plus 1 week"
ExpiresByType image/jpeg "access plus 1 week"
ExpiresByType image/png "access plus 1 week"
ExpiresByType text/css "access plus 1 week"
ExpiresByType application/javascript "access plus 1 week"
</IfModule>
 
# Compress CSS files
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain text/html text/xml application/rss+xml application/atom_xml
AddOutputFilterByType DEFLATE text/css application/javascript
</IfModule>
 
# ETag only use file time and size, but no inode
FileETag MTime Size

En las líneas 2 a 9 configuramos que las imágenes, hojas de estilo y javascripts tengan una fecha de expiración de una semana a partir del momento en que se ha visitado la página web. Esto significa que el navegador del usuario usará la copia local (fichero cacheado) durante una semana. Este comportamiento puede suponer un problema si tenemos ficheros de estos tipos que vamos modificando sin cambiarle el nombre (p.e. un banner) ya que los navegadores de algunos de los usuarios mantendran las versiones antiguas.

Desde la 12 a la 15 configuramos la compresión de las páginas HTML, feeds (text/xml, application/rss+xml y application/atom_xml), hojas de estilo y javascripts. De esta forma conseguimos ahorrar tráfico (importante si estamos en un hosting con limitaciones de tráfico)  y que el tiempo de transmisión sea menor.

Finalmente, en la última línea configuramos los ETags generados por el propio servidor Apache para los ficheros estáticos. Por defecto, Apache tiene en cuenta tres aspector para generar el ETag: el inodo, fecha de modificación y tamaño. Pero se recomienda no usar el inodo para generarlo ya que si nuestra web empieza a ser conocida y tenemos que distribuir la carga entre varios servidores, es muy poco probable que un fichero tenga el mismo inodo en todos los servidores de la granja. Entonces, el ETag variaría en funcion del servidor que lo generara por lo que no se sacaría provecho a esta cabecera. Para resolverlo, configuramos el Apache para que genere el ETag sólo considerando la fecha de modificación y el tamaño del fichero.

Con esta simple configuración yo conseguí pasar de una puntuación de 74 a 89.

A medida que pueda escribiré algún post más sobre optimización web y como resolverlo en el caso concreto de un blog que usa WordPress.

Como añadir un icono para el iPhone a tu web

Friday, May 22nd, 2009
Icono de Aleph en el iPod Touch

Icono de Aleph en el iPod Touch

Desde la versión 1.1.3 del sistema operativo del iPhone, puedes añadir enlaces a tus webs favoritas a la pantalla de inicio. Por defecto, el dispositivo crea una miniatura de esa web, pero es tan pequeña que no sirve para identificarla. Por suerte, ese icono se puede personalizar como podéis ver en la captura de pantalla.

Según podemos leer en la documentación de Apple, es tan simple como crear una imagen en formato PNG de 57×57 pixeles (sí, a mi también me parece un tamaño un poco extraño) y colocarlo en la raíz de nuestra web con el nombre  apple-touch-icon.png. El dispositivo  se encargará de redondear las esquinas y darle ese efecto glossy. Pero si nuestra imagen ya tiene algún tipo de efecto de brillo (como me ocurre a mi) queda demasiado sobrecargado: demasiado brillo. Para que el iPhone no añada ese efecto glossy a la imagen manteniendo las esquinas redondeadas, basta con renombrarlo a apple-touch-icon-precomposed.png, como se indica en otra parte de la documentación.

En lugar de usar los nombres por defecto, también podemos dar una referencia a la imagen que queremos que se use como icono añadiendo en la cabecera del documento HTML uno de los siguientes tags dependiendo de si quieremos o no que se aplique el efecto glossy a la imagen:

  <link rel="aple-touch-icon" href="/customIcon.png"/>
  <link rel="apple-touch-icon-precomposed" href="/customIcon.png"/>

Lo que no acabo de entender muy bien son los motivos que puede tener Apple para no usar el favicon (eng) que los navegadores ya usan, entre otras cosas, para asignar un icono al enlace  cuando lo guardamos en nuestros bookmarks. Ya se que normalmente el favicon es de 16×16 píxeles por lo que resulta algo pequeña para la interfaz del iPhone y escalándola quedarían horribles. Pero el formato ICO soporta que en el mismo fichero puedas tener varios tamaños de la imagen. Bastaría con que el iPhone usara la más grande disponible y si ninguna tiene el tamaño mínimo requerido que hiciera lo de la miniatura de la web. Ahora mismo no se me ocurre ningún motivo técnico para tener que usar otra imagen diferente para un fin similar.

Posteando desde el iPod Touch

Saturday, April 11th, 2009

Como ya es bien conocido, Apple inició una revolución en el campo de los dispositivos móviles cuando presentó la última generación de los iPod (incluyendo su teléfono móvil, el iPhone) y dió el siguiente paso al publicar la versión 2.x del software de esos dispositivos al añadir el App Store. Gracias a lo cual la funcionalidad de estas plataformas móviles ha aumentado enormemente al permitir que terceras partes publiquen aplicaciones.

Una de estas aplicaciones, WordPress for iPhone, es la que me ha permitido publicar este post desde mi iPod Touch. Todavía le faltan algunas funcionalidades como, por ejemplo, la de un editor enriquecido que permita añadir enlaces o algo de estilo (listas, negrita, etc.) a los post, pero seguro que sólo es questión de tiempo.