<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Aleph &#187; web</title>
	<atom:link href="http://aleph.llull.net/tag/web/feed/" rel="self" type="application/rss+xml" />
	<link>http://aleph.llull.net</link>
	<description></description>
	<lastBuildDate>Mon, 01 Aug 2011 08:48:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Optimizaciones en el blog</title>
		<link>http://aleph.llull.net/2009/05/24/optimizaciones-en-el-blog/</link>
		<comments>http://aleph.llull.net/2009/05/24/optimizaciones-en-el-blog/#comments</comments>
		<pubDate>Sun, 24 May 2009 20:58:28 +0000</pubDate>
		<dc:creator>Eduard</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[optimización]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[yslow]]></category>

		<guid isPermaLink="false">http://aleph.llull.net/?p=705</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>Desde que <a title="Blog personal d’en Xisco Lladó" href="http://zigazaga.net/">Xisco</a> me pidió consejo tras probar varias de sus páginas con <a title=" Yahoo! YSlow for Firefox" href="http://developer.yahoo.com/yslow/">YSlow</a> 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.</p>
<p>De <a href="http://developer.yahoo.com/performance/rules.html">todas las reglas</a>, las más sencillas de corregir son:</p>
<ul>
<li><a href="http://developer.yahoo.com/performance/rules.html#expires">Add Expires headers</a></li>
<li><a href="http://developer.yahoo.com/performance/rules.html#gzip">Compress components with gzip</a></li>
<li><a href="http://http://developer.yahoo.com/performance/rules.html#etags">Configure entity tags (ETags)</a></li>
</ul>
<p>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 <code>.htaccess</code> 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 <a href="http://httpd.apache.org/docs/2.0/en/mod/core.html#allowoverride">AllowOverride</a>)</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #adadad; font-style: italic;"># Add Expires Header</span>
&lt;<span style="color: #000000; font-weight:bold;">IfModule</span> mod_expires.c&gt;
<span style="color: #00007f;">ExpiresActive</span> <span style="color: #0000ff;">on</span>
<span style="color: #00007f;">ExpiresByType</span> image/gif <span style="color: #7f007f;">&quot;access plus 1 week&quot;</span>
<span style="color: #00007f;">ExpiresByType</span> image/jpeg <span style="color: #7f007f;">&quot;access plus 1 week&quot;</span>
<span style="color: #00007f;">ExpiresByType</span> image/png <span style="color: #7f007f;">&quot;access plus 1 week&quot;</span>
<span style="color: #00007f;">ExpiresByType</span> text/css <span style="color: #7f007f;">&quot;access plus 1 week&quot;</span>
<span style="color: #00007f;">ExpiresByType</span> application/javascript <span style="color: #7f007f;">&quot;access plus 1 week&quot;</span>
&lt;/<span style="color: #000000; font-weight:bold;">IfModule</span>&gt;
&nbsp;
<span style="color: #adadad; font-style: italic;"># Compress CSS files</span>
&lt;<span style="color: #000000; font-weight:bold;">IfModule</span> mod_deflate.c&gt;
<span style="color: #00007f;">AddOutputFilterByType</span> DEFLATE text/plain text/html text/xml application/rss+xml application/atom_xml
<span style="color: #00007f;">AddOutputFilterByType</span> DEFLATE text/css application/javascript
&lt;/<span style="color: #000000; font-weight:bold;">IfModule</span>&gt;
&nbsp;
<span style="color: #adadad; font-style: italic;"># ETag only use file time and size, but no inode</span>
<span style="color: #00007f;">FileETag</span> MTime Size</pre></td></tr></table></div>

<p>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.</p>
<p>Desde la 12 a la 15 configuramos la compresión de las páginas HTML, feeds (<code>text/xml</code>, <code>application/rss+xml</code> y <code>application/atom_xml</code>), 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.</p>
<p>Finalmente, en la última línea configuramos los ETags generados por el propio servidor Apache para los ficheros estáticos. Por defecto, <a href="http://httpd.apache.org/docs/2.0/en/mod/core.html#fileetag">Apache tiene en cuenta tres aspector para generar el ETag</a>: 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.</p>
<p>Con esta simple configuración yo conseguí pasar de una puntuación de <a href="http://aleph.llull.net/wp-content/uploads/aleph-yslow-grade-c.png">74</a> a <a href="http://aleph.llull.net/wp-content/uploads/aleph-yslow-grade-b.png">89</a>.</p>
<p>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.</p>
]]></content:encoded>
			<wfw:commentRss>http://aleph.llull.net/2009/05/24/optimizaciones-en-el-blog/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Como añadir un icono para el iPhone a tu web</title>
		<link>http://aleph.llull.net/2009/05/22/como-anadir-un-icono-para-el-iphone-a-tu-web/</link>
		<comments>http://aleph.llull.net/2009/05/22/como-anadir-un-icono-para-el-iphone-a-tu-web/#comments</comments>
		<pubDate>Fri, 22 May 2009 20:00:04 +0000</pubDate>
		<dc:creator>Eduard</dc:creator>
				<category><![CDATA[Informática]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[ipod]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://aleph.llull.net/?p=658</guid>
		<description><![CDATA[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. [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_664" class="wp-caption alignleft" style="width: 210px"><a href="http://aleph.llull.net/wp-content/uploads/icono-aleph-en-ipod.jpg"><img class="size-medium wp-image-664" title="Icono de Aleph en el iPod Touch" src="http://assets.llull.net/wp-content/uploads/icono-aleph-en-ipod-200x300.jpg" alt="Icono de Aleph en el iPod Touch" width="200" height="300" /></a><p class="wp-caption-text">Icono de Aleph en el iPod Touch</p></div>
<p>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.</p>
<p>Según podemos leer en la <a title="iPhone Human Interface Guidelines for Web Applications: Create an Icon for Your Web Application or Webpage" href="http://developer.apple.com/safari/library/documentation/InternetWeb/Conceptual/iPhoneWebAppHIG/MetricsLayout/chapter_5_section_2.html">documentación de Apple</a>, es tan simple como crear una imagen en formato PNG de 57&#215;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  <code>apple-touch-icon.png</code>. El dispositivo  se encargará de redondear las esquinas y darle ese efecto <em>glossy</em>. 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 <em>glossy</em> a la imagen manteniendo las esquinas redondeadas, basta con renombrarlo a <code>apple-touch-icon-precomposed.png</code>, como se indica en <a title="Safari Web Content Guide for iPhone OS: Specifying a Webpage Icon for Web Clip" href="http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariWebContent/ConfiguringWebApplications/chapter_8_section_2.html">otra parte de la documentación</a>.</p>
<p>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 <em>glossy</em> a la imagen:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;">  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;link</span> <span style="color: #000066;">rel</span>=<span style="color: #ff0000;">&quot;aple-touch-icon&quot;</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">&quot;/customIcon.png&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;link</span> <span style="color: #000066;">rel</span>=<span style="color: #ff0000;">&quot;apple-touch-icon-precomposed&quot;</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">&quot;/customIcon.png&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

<p>Lo que no acabo de entender muy bien son los motivos que puede tener Apple para no usar el <a title="Favicon @ Wikipedia [es]" href="http://es.wikipedia.org/wiki/Favicon">favicon</a> (<a title="Favicon @ Wikipedia [en]" href="http://en.wikipedia.org/wiki/Favicon">eng</a>) que los navegadores ya usan, entre otras cosas, para asignar un icono al enlace  cuando lo guardamos en nuestros <em>bookmarks</em>. Ya se que normalmente el favicon es de 16&#215;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.</p>
]]></content:encoded>
			<wfw:commentRss>http://aleph.llull.net/2009/05/22/como-anadir-un-icono-para-el-iphone-a-tu-web/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zenphoto: galería minimalista</title>
		<link>http://aleph.llull.net/2008/11/01/zenphoto-galeria-minimalista/</link>
		<comments>http://aleph.llull.net/2008/11/01/zenphoto-galeria-minimalista/#comments</comments>
		<pubDate>Sat, 01 Nov 2008 19:59:51 +0000</pubDate>
		<dc:creator>Eduard</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[fotos]]></category>
		<category><![CDATA[galería]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://aleph.llull.net/?p=151</guid>
		<description><![CDATA[Aquellos de vosotros que lleváis más tiempo visitando mi blog, os habréis dado cuenta de que he cambiado el software con el que gestiono mi galería de fotografías. Anteriormente usaba Gallery2 por su integración con WordPress mediante el plugin WPG2 (para el que desarrollé una mejora). Pero si bién era una solución válida, resultaba demasiado [...]]]></description>
			<content:encoded><![CDATA[<p>Aquellos de vosotros que lleváis más tiempo visitando mi blog, os habréis dado cuenta de que he cambiado el software con el que gestiono <a href="http://aleph.llull.net/zenphoto/">mi galería de fotografías</a>. Anteriormente usaba <a href="http://gallery.menalto.com/">Gallery2</a> por su integración con <a href="http://wordpress.org/">WordPress</a> mediante el plugin <a href="http://wordpress.org/extend/plugins/wpg2/">WPG2</a> (para el que desarrollé <a title="Mejorando WPG2: wpg2link" href="http://aleph.llull.net/2005/10/19/mejorando-wpg2-wpg2link">una mejora</a>). Pero si bién era una solución válida, resultaba demasiado compleja. Era como matar moscas a cañonazos. Sólo necesitaba una mínima parte de las características de Gallery2.</p>
<p>Por eso, un día empecé a evaluar alternativas que se ajustaran mejor a mis necesidades. Las únicas características que me interesaban eran que pudiera organizar las fotografías en álbumes, que se pudiera mostrar los datos EXIF de las fotografías, poder etiquetarlas, valorarlas y comentarlas, que se integrara con WordPress y que fuera una herramienta libre. <strong>Finalmente encontré <a href="http://www.zenphoto.org/">Zenphoto</a>, que cumple con todas esas necesidades excepto la integración con WordPress</strong>. En su web lo definen como:</p>
<blockquote><p>Zenphoto is an answer to lots of calls for an online gallery solution that just makes sense. After years of bloated software that does everything and your dishes, zenphoto just shows your photos, simply. It’s got all the functionality and “features” you need, and nothing you don’t. Where the old guys put in a bunch of modules and junk, we put a lot of thought. We hope you agree with our philosopy: simpler is better. Don’t get us wrong though –zenphoto really does have everything you need for your online gallery, and you’ll even stare in awe at some of the innovative innovations we innovated upon.</p></blockquote>
<p>Con el plugin <a href="http://simbul.bzaar.net/zenphotopress/">ZenphotoPress</a> para WordPress conseguí poder añadir fotos de la galería en los posts de forma simple. <strong>Pero integrar la apariencia me lo tuve que currar yo</strong>, usando como guía <a title="Integrating Zenphoto into WordPress" href="http://www.ruzee.com/blog/2006/06/integrating-zenphoto-into-wordpress/">este post de Steffen Rusitschka</a>. Pero con ese método Google no indexaba las páginas de la galería, aunque se visualizaban correctamente, porque todas devolvían un status 404. Además, compartían el título (tag &lt;title&gt; del <abbr title="HyperText Markup Language">HTML</abbr>) haciéndolo muy poco <em>Search Engine Friendly</em>. Para solucionarlo tuve que modificar un poco el código de Steffen. Este es el <code>index.php</code> de mi <em>theme</em> integrado con el WordPress:</p>

<div class="wp_syntax"><div class="code"><pre class="php-brief" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">defined</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'WEBPATH'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> normalizeColumns<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">6</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">require</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'DOCUMENT_ROOT'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'/wp-blog-header.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">// set the HTTP status</span>
status_header<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'200'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// add the zen headers to the wordpress header</span>
<span style="color: #000000; font-weight: bold;">function</span> zentitle<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #990000;">echo</span> <span style="color: #0000ff;">'&amp;raquo; '</span><span style="color: #339933;">.</span><span style="color: #990000;">strip_tags</span><span style="color: #009900;">&#40;</span>getGalleryTitle<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">function</span> addzen<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #990000;">global</span> <span style="color: #0000ff;">$_zp_themeroot</span><span style="color: #339933;">;</span>
  <span style="color: #990000;">echo</span> <span style="color: #0000ff;">'&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;screen, projection&quot; href=&quot;'</span><span style="color: #339933;">.</span><span style="color: #0000ff;">$_zp_themeroot</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'/css/master.css&quot; /&gt;'</span><span style="color: #339933;">;</span>
  zenJavascript<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  printRSSHeaderLink<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Gallery'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'Gallery RSS'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'wp_head'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'addzen'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'wp_title'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'zentitle'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> get_header<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
&lt;div class=&quot;index&quot;&gt;
  &lt;!-- Código original de Zenphoto --&gt;
&lt;/div&gt;
&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> get_footer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Lo más extraño es que yo tengo las bases de datos del blog y de la galería separadas pero no he necesitado hacer lo que comenta Steffen de conectarnos a una base de datos y luego a la otra. Por eso, si comparáis mi trozo de códico con el de Steffen veréis que falta esa parte. Lo siguiente será integrar el login de las dos aplicaciones, para lo que he visto que hay plugins, pero de momento no lo he mirado.</p>
<p>Como las URL de los álbumes han cambiado,<strong> también he añadido reglas de redirección en el <code>.htaccess</code> para no perder los enlaces que pudiera haber desde otras páginas</strong>.</p>
<p>Al final he conseguido dejarlo bastante bien integrado y estoy muy contento, tanto del resultado como de la aplicación en sí. Tiene justo lo que necesito. Ni más, ni menos. <img src='http://aleph.llull.net/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://aleph.llull.net/2008/11/01/zenphoto-galeria-minimalista/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>SSL en subdominios con una única dirección IP</title>
		<link>http://aleph.llull.net/2008/10/27/ssl-en-subdominios-con-una-unica-direccion-ip/</link>
		<comments>http://aleph.llull.net/2008/10/27/ssl-en-subdominios-con-una-unica-direccion-ip/#comments</comments>
		<pubDate>Mon, 27 Oct 2008 08:03:05 +0000</pubDate>
		<dc:creator>Eduard</dc:creator>
				<category><![CDATA[SysAdmin]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[https]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[ssl]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://aleph.llull.net/?p=309</guid>
		<description><![CDATA[La aparición a mediados de 1998 de los VirtualHosts basados en nombre en la versión 1.3 del servidor web de Apache significó un cambio importante en el mundo de los servidores web ya que permitía configurar webs en diferentes dominios, todos ellos compartiendo la misma dirección IP. Tampoco hay que olvidar que esa mejora fue [...]]]></description>
			<content:encoded><![CDATA[<p>La aparición a mediados de 1998 de los VirtualHosts basados en nombre en la <a href="http://httpd.apache.org/docs/1.3/">versión 1.3 del servidor web de Apache</a> significó un cambio importante en el mundo de los servidores web ya que permitía configurar webs en diferentes dominios, todos ellos compartiendo la misma dirección <abbr title="Internet Protocol">IP</abbr>. Tampoco hay que olvidar que esa mejora fue posible gracias a que los navegadores (por aquel entonces disponíamos de <a href="http://en.wikipedia.org/wiki/Netscape_Communicator">Netscape Communicator 4.5</a> e <a href="http://en.wikipedia.org/wiki/Internet_Explorer_4">Internet Explorer 4.0</a> [<a href="#nota-1">1</a>]) implementaron la versión 1.1 del protocolo <abbr title="HyperText Transfer Protocol">HTTP</abbr>, según la cual el navegador debe enviar el nombre del dominio al que se están conectando en la cabecera <em>Host</em>, usada por los servidores web para discriminar que a VirtualHost deben enviar la petición.</p>
<p>Desgraciadamente, las webs seguras nunca han podido beneficiarse de esta mejora por la forma en que funciona el protocolo HTTPS (HTTP sobre <abbr title="Secure Sockets Layer">SSL</abbr>). La cabecera Host que permite al servidor discernir el host virtual al que va dirigida la petición del usuario está a nivel HTTP, debajo del cual tenemos SSL y su negociación. En esa negociación es cuando el servidor envía al cliente su certificado X.509 y el navegador comprueba la validez del certificado comparando el campo <abbr title="Common Name">CN</abbr> del certificado con el nombre del dominio al que se está conectando. <strong>Por tanto, el servidor debe enviar el certificado correcto, y por tanto del host virtual correcto, al navegador antes que este le pueda indicar mediante la cabecera Host el dominio al que se quiere conectar</strong>. La única solución es usar VirtualHosts basados en dirección IP.</p>
<p>Sin embargo, si los diferentes dominios que tenemos en el servidor son subdominios que comparten el <a href="http://en.wikipedia.org/wiki/Second-level_domain">second-level domain</a>, o SLD, podemos conseguir que todos ellos dispongan de web segura usando una única dirección IP. Por ejemplo www.example.com y mail.example.com tienen el SLD example.com en común.</p>
<p>Para conseguirlo, también es imprescindible el uso de un <em>Wildcard SSL Certificate</em> (he decidido no traducirlo porque ninguna de las tradicciones que se me han ocurrido me acababa de gustar), que es un certificado SSL en el que el nombre del dominio contiene un comodín. Por ejemplo: *.example.com. De esta manera, indicamos al navegador que este certificado es válido para cualquier subdominio de example.com. No voy a explicar como se generan los certificados SSL ya que <a title="Busqueda 'SSL certificates Howto' en Google" href="http://www.google.com/search?q=ssl+certificates+howto">buscando un poco por google</a> se encuentran multitud de páginas al respecto. Si le vamos a dar un uso personal, podéis crear un <em>self signed certificate</em>. La única diferencia con los tutoriales que podáis encontrar es que como dominio introduciremos &#8220;*.&lt;dominio&gt;&#8221; (Por ejemplo: *.example.com).</p>
<h3>Configuración del servidor web de Apache</h3>
<p>Voy a suponer que en nuestro servidor tenemos configurado un servidor web Apache2 con varios host virtuales (www.example.com, mail.example.com y un servidor WebDAV para el Subversion en svn.example.com), y que el servidor sólo dispone de una dirección IP.</p>
<p>Lo primero que hay que hacer es poner el servidor web a escuchar en el puerto 443 (puerto estándar de HTTPS) y configurar un host virtual sobre ese puerto:</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">Listen</span> <span style="color: #ff0000;">443</span>
&lt;<span style="color: #000000; font-weight:bold;">VirtualHost</span> *:<span style="color: #ff0000;">443</span>&gt;
  <span style="color: #00007f;">ServerName</span> *.example.com
  <span style="color: #00007f;">ErrorLog</span> /var/log/apache2/https-error.log
&nbsp;
  <span style="color: #adadad; font-style: italic;"># Possible values include: debug, info, notice, warn, error, crit,</span>
  <span style="color: #adadad; font-style: italic;"># alert, emerg.</span>
  <span style="color: #00007f;">LogLevel</span> warn
&nbsp;
  <span style="color: #00007f;">CustomLog</span> /var/log/apache2/https-access.log combined
  <span style="color: #00007f;">ServerSignature</span> <span style="color: #0000ff;">Off</span>
&nbsp;
  <span style="color: #00007f;">SSLEngine</span> <span style="color: #0000ff;">On</span>
  <span style="color: #00007f;">SSLCertificateFile</span> /path/to/certs/example.com.pem
  <span style="color: #00007f;">SSLCertificateKeyFile</span> /path/to/private-keys/example.com.key
&lt;/<span style="color: #000000; font-weight:bold;">VirtualHost</span>&gt;</pre></div></div>

<p>Con esto ya tenemos la capa SSL configurada. El certificado indicado en el parámetro <code>SSLCertificateFile</code> es el <em>Widlcard SSL Certificate</em> que hemos creado anteriormente. A partir de aquí, <strong>el &#8220;truco&#8221; está en el uso creativo del mod_proxy</strong>, que conseguiremos añadiendo la siguiente configuración dentro del hosts virtual que acabamos de crear:</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;">  &lt;<span style="color: #000000; font-weight:bold;">Proxy</span> *&gt;
    <span style="color: #00007f;">Order</span> <span style="color: #00007f;">deny</span>,<span style="color: #00007f;">allow</span>
    <span style="color: #00007f;">Allow</span> from <span style="color: #0000ff;">all</span>
  &lt;/<span style="color: #000000; font-weight:bold;">Proxy</span>&gt;
&nbsp;
  <span style="color: #adadad; font-style: italic;"># Proxy requests to ourselves preserving the Host header</span>
  <span style="color: #00007f;">ProxyPass</span> / http://localhost/
  <span style="color: #00007f;">ProxyPassReverse</span> / http://localhost/
  <span style="color: #00007f;">ProxyPreserveHost</span> <span style="color: #0000ff;">on</span></pre></div></div>

<p>Con esta configuración estamos reenviando todas las peticiones que nos lleguen a este host virtual por HTTPS hacia el propio servidor, pero cambiando el protocolo de HTTPS a HTTP. <strong>Es importante destacar la última línea, que le indica al servidor web que debe mantener la cabecera Host al hacerse la petición a sí mismo</strong>, gracias a la cual no tendrá ningún problema a la hora de determinar que página quiere ver el usuario.</p>
<p>Para que las aplicaciones web puedan distinguir si la petición que les llega a entrado por HTTP o HTTPS, configuraremos el host virtual para que añada la cabecera <code>X_FORWARDED_PROTO</code> a las peticiones que se hace a sí mismo:</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;">  <span style="color: #adadad; font-style: italic;"># Add the X_FORWARDED_PROTO=https to allow applications to identify</span>
  <span style="color: #adadad; font-style: italic;"># proxyed https connections</span>
  <span style="color: #00007f;">RequestHeader</span> set X_FORWARDED_PROTO https</pre></div></div>

<p>Ya sólo queda un detalle, necesario únicamente si vamos a usar esta configuración para proteger un WebDAV. El problema de esta configuración con WebDAV viene a la hora de intentar hacer un &#8216;<code>svn mv</code>&#8216;, por ejemplo. Este comando indica el destino en la cabecera HTTP <code>Destination</code>. Como el cliente se esta conectando a https://svn.example.com/repo/etc, la cabecera tendrá ese valor. Pero el host virtual que tiene la configuración de WebDAV sólo está configurado para HTTP por lo que espera que la cabecera <code>Destination</code> empiece por http://svn&#8230; <strong>Para solucionar la inconsistencia entre la cabecera esperada y la recibida echaremos mano del mod_rewrite</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;">  <span style="color: #adadad; font-style: italic;"># Workarrounf for WebDAV Destination header</span>
  <span style="color: #00007f;">RewriteEngine</span> <span style="color: #0000ff;">on</span>
  <span style="color: #00007f;">RewriteCond</span> %{HTTP:Destination} ^https://(.*)$
  <span style="color: #00007f;">RewriteRule</span> . - [env=DESTINATION:http://%1,PT]
  <span style="color: #00007f;">RequestHeader</span> set Destination %{DESTINATION}e env=DESTINATION</pre></div></div>

<h3>Resumen de la configuración</h3>
<p>Una vez explicadas las diferentes partes de la configuración, os pongo toda la configuración tal cual se debe escribir en los ficheros de configuración del servidor web para que no haya problemas de &#8220;¿y esto donde va?, ¿dentro o fuera del virtualhost?&#8221; <img src='http://aleph.llull.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  :</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">Listen</span> <span style="color: #ff0000;">443</span>
&lt;<span style="color: #000000; font-weight:bold;">VirtualHost</span> *:<span style="color: #ff0000;">443</span>&gt;
  <span style="color: #00007f;">ServerName</span> *.example.com
  <span style="color: #00007f;">ErrorLog</span> /var/log/apache2/https-error.log
&nbsp;
  <span style="color: #adadad; font-style: italic;"># Possible values include: debug, info, notice, warn, error, crit,</span>
  <span style="color: #adadad; font-style: italic;"># alert, emerg.</span>
  <span style="color: #00007f;">LogLevel</span> warn
&nbsp;
  <span style="color: #00007f;">CustomLog</span> /var/log/apache2/https-access.log combined
  <span style="color: #00007f;">ServerSignature</span> <span style="color: #0000ff;">Off</span>
&nbsp;
  <span style="color: #00007f;">SSLEngine</span> <span style="color: #0000ff;">On</span>
  <span style="color: #00007f;">SSLCertificateFile</span> /path/to/certs/example.com.pem
  <span style="color: #00007f;">SSLCertificateKeyFile</span> /path/to/private-keys/example.com.key
&nbsp;
  &lt;<span style="color: #000000; font-weight:bold;">Proxy</span> *&gt;
    <span style="color: #00007f;">Order</span> <span style="color: #00007f;">deny</span>,<span style="color: #00007f;">allow</span>
    <span style="color: #00007f;">Allow</span> from <span style="color: #0000ff;">all</span>
  &lt;/<span style="color: #000000; font-weight:bold;">Proxy</span>&gt;
&nbsp;
  <span style="color: #adadad; font-style: italic;"># Workarrounf for WebDAV Destination header</span>
  <span style="color: #00007f;">RewriteEngine</span> <span style="color: #0000ff;">on</span>
  <span style="color: #00007f;">RewriteCond</span> %{HTTP:Destination} ^https://(.*)$
  <span style="color: #00007f;">RewriteRule</span> . - [env=DESTINATION:http://%1,PT]
  <span style="color: #00007f;">RequestHeader</span> set Destination %{DESTINATION}e env=DESTINATION
&nbsp;
  <span style="color: #adadad; font-style: italic;"># Add the X_FORWARDED_PROTO=https to allow applications to identify</span>
  <span style="color: #adadad; font-style: italic;"># proxyed https connections</span>
  <span style="color: #00007f;">RequestHeader</span> set X_FORWARDED_PROTO https
&nbsp;
  <span style="color: #adadad; font-style: italic;"># Proxy requests to ourselves preserving the Host header</span>
  <span style="color: #00007f;">ProxyPass</span> / http://localhost/
  <span style="color: #00007f;">ProxyPassReverse</span> / http://localhost/
  <span style="color: #00007f;">ProxyPreserveHost</span> <span style="color: #0000ff;">on</span>
&lt;/<span style="color: #000000; font-weight:bold;">VirtualHost</span>&gt;</pre></div></div>

<h3>Conclusiones</h3>
<p>Personalmente veo está configuración como una solución válida para servidores personales en los que se suelen usar <em>self signed certificates</em> o de <a href="http://www.cacert.org/">CAcert</a>. Para pequeñas empresas (con unos pocos dominios) puede ser una solución, pero los <em>Widlcard SSL Certificates</em> de <a title="Thawte Wildcard SSL Certificates" href="https://www.thawte.com/ssl-digital-certificates/wildcardssl/index.html">autoridades</a> <a title="Verisign Wildcard SSL Certificates" href="http://www.verisign.com/ssl-certificates/wildcard-ssl-certificates/">certificadoras</a> <a title="Go Daddy SSL Certificates" href="http://www.godaddy.com/gdshop/ssl/ssl.asp?ci=9039">comerciales</a> (cuyos certificados raíz vienen en los navegadores) no son baratos. Dependiendo del <em>hosting</em> creo que saldría más barato contratar IPs adicionales para el servidor y certificados individuales que no usar el <em>Widlcard SSL Certificate</em> en un servidor con una sóla IP.</p>
<p>En empresas medianas o grandes, puede justificarse el uso de <em>Widlcard SSL Certificates</em> si tienen un gran número de subdominios que quieren asegurar ya que puede suponer un ahorro, pero no veo el motivo de tenerlo todo sobre una sóla dirección IP. Por tanto, no veo que la configuración aquí explicada sea aplicable en este tipo de empresas.</p>
<p>A mi, esta solución me está funcionando muy bien y de momento no he encontrado ningún problema.</p>
<h3>Notas adicionales</h3>
<p>[<span id="nota-1">1</span>] Para los nostálgicos, ¿os acordáis de la <a href="http://es.wikipedia.org/wiki/Guerra_de_navegadores">guerra de navegadores</a>?</p>
]]></content:encoded>
			<wfw:commentRss>http://aleph.llull.net/2008/10/27/ssl-en-subdominios-con-una-unica-direccion-ip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

