<?xml version="1.0" encoding="UTF-8" standalone="no"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:gd="http://schemas.google.com/g/2005" xmlns:georss="http://www.georss.org/georss" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-6671913855625335983</atom:id><lastBuildDate>Sun, 06 Oct 2024 06:08:39 +0000</lastBuildDate><category>linux</category><category>out of topic</category><category>general</category><category>howto</category><category>seguridad</category><category>tips</category><category>programacion</category><category>reflexión</category><category>bash</category><category>debian</category><category>python</category><category>red</category><category>erlang</category><category>microsoft</category><category>sistemas</category><category>vim</category><category>atajos</category><category>cuda</category><category>ftp</category><category>lenovo review</category><category>c</category><category>openbox</category><category>unicode</category><title>inedit00</title><description>Recopilando pelusillas en mi ombligo con las que, algún día, dominaré el Mundo entero! Muahaahahaha!</description><link>http://inedit00.blogspot.com/</link><managingEditor>noreply@blogger.com (inedit00)</managingEditor><generator>Blogger</generator><openSearch:totalResults>119</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><language>en-us</language><itunes:explicit>no</itunes:explicit><itunes:subtitle>Recopilando pelusillas en mi ombligo con las que, algún día, dominaré el Mundo entero! Muahaahahaha!</itunes:subtitle><itunes:owner><itunes:email>noreply@blogger.com</itunes:email></itunes:owner><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-6384339994482268052</guid><pubDate>Thu, 31 May 2012 11:23:00 +0000</pubDate><atom:updated>2012-05-31T13:23:19.033+02:00</atom:updated><title>Fin de una era</title><description>Señores, gracias por haber estado aquí.&lt;br /&gt;
&lt;br /&gt;
Hace mas o menos 15 días que decidí abrir un nuevo blog: &lt;a href="http://www.krenel.org/"&gt;www.krenel.org&lt;/a&gt;. La idea es la misma que este mismo blog pero con dos diferencias:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;b&gt;El dominio es mío.&lt;/b&gt; No quiero usar más blogger como plataforma. Por motivos personales me intento alejar lo mas que puedo de los productos de Google.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Está en inglés&lt;/b&gt;. Mira, seamos sinceros: mi inglés apesta. ¿Qué mejor que escribir un blog ténico en inglés para practicar un poco? (&lt;span style="font-size: xx-small;"&gt;sisi, vale echarse una novia inglesa es mejor ¬¬'&lt;/span&gt; )&lt;/li&gt;
&lt;/ol&gt;
Pues estos dos puntos son el motivo de cambio y cese de este blog. No voy a cerrarlo porque hay artículos que creo son interesantes o alguien le puede sacar partido todavía, pero voy a dejar de escribir en él.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Éste es el post número 127&lt;/b&gt;. (2^7-1). Me parece un bonito número.&lt;br /&gt;
&lt;br /&gt;
El primer post lo escribí hace unos tres añitos y estoy muy satisfecho con lo que he ido publicando hasta ahora. Y voy a seguir haciéndolo, pero en otro blog y en otra lengua.&lt;br /&gt;
&lt;br /&gt;
De nuevo gracias y espero que algo de lo que he publicado os haya servido.&lt;br /&gt;
&lt;br /&gt;
Un saludo, Jan.</description><link>http://inedit00.blogspot.com/2012/05/fin-de-una-era.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-3727351512971825213</guid><pubDate>Fri, 27 Apr 2012 15:41:00 +0000</pubDate><atom:updated>2012-04-27T17:42:52.000+02:00</atom:updated><title>Erlang (V) HTTP reverse proxy</title><description>&lt;b&gt;[Repaso]&lt;/b&gt; &lt;br /&gt;
Repasemos la infraestrctura: Ahora mismo tenemos un servidor web hecho en Erlang, MochiWeb, que accepta mucha mucha carga.&lt;br /&gt;
&lt;br /&gt;
Este servidor en si mismo no hace el trabajo, sino que deja que un Actor de Erlang (llamado Usuario) se encargue de gestionar la petición. Así conseguimos una concurrencia brutal y soportamos un montonazo de carga[1]. El actor usuario, en caso de recibir un mensaje de otro usuario, devolverá este mensaje al servidor web, que a su vez se lo mandará al usuario final y este lo recibirá en su navegador. Bien. También tenemos en un almacén de datos en memória la gestión de las sesiones (en mnesia): allí se asocia un ID de sessión HTTP con el ID de usuario.&lt;br /&gt;
&lt;br /&gt;
Ahora mismo la arquitectura de la aplicación está pensada para ser ejecutada en una misma máquina, lo que supone algunos problemas: cuando toca reiniciar el equipo debido a actualizaciones de kernel y demás el chat debe permanecer "&lt;i&gt;cerrado&lt;/i&gt;". No solo esto, si no que el usuario no recibiría un bonito mensaje de error que diga "We are under maintenance", sinó mas bien un "&lt;i&gt;server not found&lt;/i&gt;" o algo así. Algo feo feo. Pero arreglarlo tampoco es algo fácil.&lt;br /&gt;
&lt;br /&gt;
También hay otros pequeños problemas como por ejemplo el logueo de las peticiones HTTP (típico fichero access.log) y ofrecer HTTPS (SSL/TLS).&lt;br /&gt;
&lt;br /&gt;
Veamos una imágen actual de la arquitectura de Gaab Web Chat:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjda4UF01QNZkOt9FicSko1r0Sjrgfu_daWzhSI6E0_ddCBt_9LYctwtWI8nIRFynvr3UkKlcG3I-3KZCYr1cp5AQZKBCeGHspYZhZYgfB8z_ooNcobHSZffzAITBRH7-AVjUViEo1582g/s1600/gaab_infrastructure.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="218" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjda4UF01QNZkOt9FicSko1r0Sjrgfu_daWzhSI6E0_ddCBt_9LYctwtWI8nIRFynvr3UkKlcG3I-3KZCYr1cp5AQZKBCeGHspYZhZYgfB8z_ooNcobHSZffzAITBRH7-AVjUViEo1582g/s640/gaab_infrastructure.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Bien. Tenemos un único punto de entrada directamente al servidor de chat de Erlang. En si mismo esto no está mal, ya que el servidor accepta una concurrencia "que te cagas", pero tenemos los problemas comentados anteriormente. Parece que la solución más simple es (como casi siempre) añadir una capa mas de complejidad y añadir un: &lt;b&gt;http reverse proxy&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;[Cherokee]&lt;/b&gt;&lt;br /&gt;
No explicaré lo que es un reverse proxy (consúltese en la wikipedia, o léase este[2] artículo), pero sí explicaré por qué he elegido Cherokee. Aparte de por que en todos los bencharks tiene unos muy buenos resultados, tiene unos ficheros de configuración con una gestión muy clara, es relativamente nuevo pero tiene un gran comunidad y está publicado bajo GPL es porque el creador del servidor web es español. Si señor. Me ha salido la vena patriótica y me apetece apoyar (ummm... vale, con "apoyar" quizás me he pasado, digamos "usar") un proyecto hecho en casa. Y punto.&lt;br /&gt;
&lt;br /&gt;
Y las primeras impresiones no pueden ser mejores: gestión vía web, creado un virtual host en menos de 1 minuto, creado el http proxy en 5 minutos. Amén. Así da gusto.&lt;br /&gt;
&lt;br /&gt;
La idea es usar Cherokee como balanceador de carga entre diferentes aplicaciones GaabWebChat(Erlang+Mnesia+Aplicacion) que se estarían ejecutando en máquinas distintas. La carga de tráfico sería balanceada entre todas las máquina que pudiese tener la aplicación. En caso de que se tuviese que actualizar la plataforma, sería tan simple como decirle a Cherokee que no mandara más tráfico en aquella máquina, actualizarla tranquilamente, y después volver a dirigir tráfico a la misma.&lt;br /&gt;
&lt;br /&gt;
La arquitectura quedaría algo así:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdPkLsAv2s_cVHuy-IRVgEFFki6amiomfHw0VyhqyZ_qVPIhOctHbdE9b3pIlQeeuYgC7MxNjEr12lqhnVFoyZ74Xvd3r5H31nhu5xK3PYFv2pZ4e1emaW0beFjmGYNfFnqssXHTNYX3o/s1600/gaab_new_infrastructure.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="268" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdPkLsAv2s_cVHuy-IRVgEFFki6amiomfHw0VyhqyZ_qVPIhOctHbdE9b3pIlQeeuYgC7MxNjEr12lqhnVFoyZ74Xvd3r5H31nhu5xK3PYFv2pZ4e1emaW0beFjmGYNfFnqssXHTNYX3o/s640/gaab_new_infrastructure.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Mucho mas chula que antes, no? Así Cherokee se puede encargar de gestionar las conexiones HTTP/HTTPS, loguear todos los requests en un fichero "access.log", balancear la carga entre varias aplicaciones y servir contenido estático.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;[Mejoras]&lt;/b&gt;&lt;br /&gt;
Esta plataforma todavía se puede mejorar ya que todavía hay un único punto de fallo, el servidor de Cherokee. Esto se podría remediar poniendo varios Cherokees en diferentes máquinas y balanceando la carga por DNS, por ejemplo. Pero esto ya queda (de momento) fuera del alacance de este post.&lt;br /&gt;
&lt;br /&gt;
Esta solución aquí propuesta es un algo que puede que en un futuro pueda necesitar, pero des de luego no lo incluiré en la primera versión que ponga online, ya que MochiWeb puede soportar muucha carga (estoy seguro que ahora mismo por cada 500MiB de RAM que pueda conseguir en un hosting puede soportar a 5K usuarios).&lt;br /&gt;
&lt;br /&gt;
Pues nada, señores. Un saludo.&lt;br /&gt;
&lt;br /&gt;
P.D: Mierda de Blogger. Las imágenes quedan como el culo, pero tienen que tener este tamaño para que se vean claras. So sorry. Prometo cambiar pronto el blog de sitio :/&lt;br /&gt;
&lt;br /&gt;
[1] Me faltan hacer un par de benchmarks para demostrar que esto es así, pero la pereza puede a uno.&lt;br /&gt;
[2] &lt;a href="http://www.cherokee-project.com/doc/modules_handlers_proxy.html"&gt;http://www.cherokee-project.com/doc/modules_handlers_proxy.html&lt;/a&gt;</description><link>http://inedit00.blogspot.com/2012/04/erlang-v-http-reverse-proxy.html</link><author>noreply@blogger.com (inedit00)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjda4UF01QNZkOt9FicSko1r0Sjrgfu_daWzhSI6E0_ddCBt_9LYctwtWI8nIRFynvr3UkKlcG3I-3KZCYr1cp5AQZKBCeGHspYZhZYgfB8z_ooNcobHSZffzAITBRH7-AVjUViEo1582g/s72-c/gaab_infrastructure.png" width="72"/><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-2538310251120264189</guid><pubDate>Thu, 26 Apr 2012 17:53:00 +0000</pubDate><atom:updated>2012-04-26T19:53:29.161+02:00</atom:updated><title>Peticiones Ajax en IE8 y cachés: crap, crap, crap</title><description>&lt;br /&gt;
&lt;div style="background-color: yellow; color: red; text-align: center;"&gt;
&lt;u&gt;&lt;b&gt;IE8 apesta. Y por extensión Microsoft también.&lt;/b&gt;&lt;/u&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;[Problema]&lt;/b&gt;&lt;br /&gt;
Las peticiones por Ajax que lanza IE8 son cacheadas. &lt;b&gt;Todas ellas.&lt;/b&gt; Si lanzas un requests por Ajax a la url "/check_mail_box" y el resultado de la petición dice que no tienes nuevos mails, tooodos los demás requests que hagas a esta URL estarán cacheados y realmente ni se volverá a lanzar una petición HTTP para comprobar nada. IE8 es inteligente (o almenos esto cree) y dice: ¿si ya tengo la información, para qué voy a volver a pedirla?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;¡PUES PORQUE PUEDE HABER CAMBIADO, CACHO RETRASADO! ¡POR ESTO LANZO OTRA PETICIÓN! ¡PARA COMPROBARLO DE NUEVO!&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Calémonos. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;[Repasando las bases]&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;El protocolo HTTP&lt;/u&gt;&lt;/b&gt; hace &lt;u&gt;AÑOS&lt;/u&gt; que se usa en el mundo Web. El cliente hace una petición de un recurso, el servidor busca el recurso y se lo devuelve al cliente. En caso de que se haga otra petición, el proceso se repite.&lt;br /&gt;
&lt;br /&gt;
Hace hace años también que dejó de servirse contenido estático y ahora se están sirviendo contenidos dinámicos, generados por PHP, .NET, CGI y un largísimo ETC... Esto significa que si tu pides un recurso, como por ejemplo "/last_users_connected", el resultado de la petición HTTP puede cambiar en el tiempo, ya que es una información CALCULADA en la parte servidor.&lt;br /&gt;
&lt;br /&gt;
Bien. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;Ajax.&lt;/u&gt;&lt;/b&gt; Ha aparecido hace relativamente poco. Es lo mismo que una petición HTTP pero de manera asíncrona. ¿Qué significa esto? Pues que el usuario puede estar navegando tranquilamente mientras, en segundo plano, se descarga otra información. Muy cómodo para no tener que ir recargando la página cada dos por tres. Pero esto de Ajax es solo un artificio creado por el navegador. En realidad se lanzan peticiones HTTP como las "normales". Exactamente iguales. No hay diferéncia entre ellas.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;[Acercándonos al problema]&lt;/b&gt;&lt;br /&gt;
Cada vez que el usuario entra en "www.facebook.com" el navegador lanza una petición HTTP pidiendo el recurso "/index.html". Bien. Si le damos a F5 (refrescar) o volvemos a abrir en otro Tab del navegador "www.facebook.com", vuelve a lanzar la petición y puede que los resultados del primer tab al segundo tab sean diferentes. Obvio.&lt;br /&gt;
&lt;br /&gt;
Imaginemos que el navegador cachea la primera petición a "/index.html" y que a partir de ahora cada vez que entramos en www.facebook.com nos sirve la versión cacheada. &lt;u&gt;Pues vaya inutilidad, verdad&lt;/u&gt;?&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;[Meollo]&lt;/b&gt;&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
Bien, pues esto es lo que hace IE8 con las llamadas de AJAX.&amp;nbsp;&amp;nbsp; &lt;b&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
Se le tiene que decir explícitamente a IE8 que NO haga uso de la caché en las peticiones por Ajax par que funcione de un modo normal. Otro modo de decir lo mismo es que se tiene que instruir a IE8 para que funcione CORRECTAMENTE y como un usuario corriente y moliente esperaría. Va contra la lógica más básica: le estás diciendo al navegador que descargue una información de un servidor (pero de modo asíncrono), y el navegador -por que le sale de los cojones- te devuelve una versión antigua de la misma sin lanzar peticiones ni ostias. Fuck.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;[Conclusión]&lt;/b&gt;&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
IE8 apesta.&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
Y por extensión Microsoft también.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
Un saludo, Jan.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;P.D: Me pregunto los miles de millones de euros que habrá costado esta decisión por parte del equipo de IE8. Pensadlo, la de librerías que se tienen que adaptar y la de programadores que tienen que aprender la gilipollez esta.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
P.D2: He de decir que W7, y IE9 ya parecen SO/navegador decentes, y que parece que las ñapas que había estado haciendo Microsoft hasta ahora (W98, W2000, WMe, WVista, IE{5,6,7,8}) quedan en el pasado. Ya iba siendo hora.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description><link>http://inedit00.blogspot.com/2012/04/peticiones-ajax-en-ie8-y-caches-crap.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-4057269595445418797</guid><pubDate>Mon, 09 Apr 2012 11:18:00 +0000</pubDate><atom:updated>2012-04-10T18:35:09.423+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">bash</category><title>Errores en el manual de bash</title><description>&lt;span&gt;&lt;span style="font-size: 100%;"&gt;Me aburro. No os creáis, me pasa amenudo. Y no lo veo como algo malo, ya que normalmente para quitarme el aburrimiento hago lo que yo llamo "cosas productivas". Como leer el manual de bash, por ejemplo.&lt;/span&gt;&lt;/span&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; font-weight: normal; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; "&gt;&lt;span&gt;&lt;b&gt;$ man bash&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; font-weight: normal; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;&lt;span style="font-weight: normal; font-style: normal; "&gt;Así de fácil. Y la verdad que está bastante interesante y uno se entera de cosas que no sabia, o entiende cosas en las que hasta ahora dudaba. Pero estoy yo tan tranquilo leyendo el manualillo en mi Kindle[0] en el avión, cuando me encuentro con una cosa que no me ha acaba de gustar. En el apartado &lt;/span&gt;&lt;i style="font-weight: bold; "&gt;REDIRECTION&lt;/i&gt;, pone lo siguiente:&lt;/div&gt;&lt;div&gt;&lt;span &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span  &gt;Bash handles several filenames specially when they are used in redirections, as described in the following table:&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div style="line-height: normal; font-variant: normal; font-size: 100%; font-family: Georgia, serif; "&gt;&lt;span &gt;&lt;span&gt;&lt;b&gt;/dev/tcp/&lt;/b&gt;&lt;/span&gt;&lt;i&gt;host&lt;/i&gt;&lt;span&gt;/&lt;/span&gt;&lt;i&gt;port&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span &gt;&lt;span style="font-family: Georgia, serif; "&gt;If &lt;/span&gt;&lt;i style="font-family: Georgia, serif; "&gt;host&lt;/i&gt;&lt;span style="font-family: Georgia, serif; "&gt; is a valid hostname or Internet address, and &lt;/span&gt;&lt;i style="font-family: Georgia, serif; "&gt;port&lt;/i&gt;&lt;span style="font-family: Georgia, serif; "&gt; is an integer port number or service name, &lt;/span&gt;&lt;b style="font-family: Georgia, serif; "&gt;bash&lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt; attempts &lt;/span&gt;&lt;span style="font-family: Georgia, serif; "&gt;to open a TCP connection to the corresponding socket.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;span&gt;&lt;div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family: Georgia, serif; font-size: 16px; "&gt;Bueno, hasta aquí no tengo ninguna queja. Estoy conforme con esto. Pero ya no me parece tan bien el siguiente bloque. ¡Ai señor! ¡Cuánto daño ha hecho el copy-paste!&lt;/span&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span &gt;&lt;br /&gt;/&lt;b&gt;dev&lt;/b&gt;/&lt;b&gt;udp&lt;/b&gt;/&lt;i&gt;host&lt;/i&gt;/&lt;i&gt;port&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span &gt;&lt;div&gt;If &lt;i&gt;host&lt;/i&gt; is a valid hostname or Internet address, and &lt;i&gt;port&lt;/i&gt; is an integer port number or service name, &lt;b&gt;bash&lt;/b&gt; &lt;b&gt;&lt;span &gt;&amp;gt;&amp;gt;&amp;gt;attempts to open a UDP **connection**&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;/b&gt; to the corresponding socket.&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;span &gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;O sea, exactamente igual que el bloque de anterior, pero cambiando &lt;b&gt;TCP&lt;/b&gt; por &lt;b&gt;UDP&lt;/b&gt;. Solo que estos dos protocolos no son lo mismo. Y dá la casualidad que en el protocolo UDP no se establecen conexiones. Y no es porque lo diga yo. Si hacemos un "&lt;i&gt;&lt;span &gt;man udp&lt;/span&gt;&lt;/i&gt;", podemos leer en la primera línea:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;This  is  an  implementation  of  the  User Datagram Protocol described in RFC 768.  It implements a &lt;span &gt;**&lt;/span&gt;&lt;b&gt;&lt;span &gt;connectionless**&lt;/span&gt;&lt;/b&gt;, unreliable datagram packet service. Packets may be reordered or duplicated before they arrive.&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;Connectionless&lt;/i&gt;, sin conexiones. Por lo que el término "&lt;i&gt;connection"&lt;/i&gt; al lado de UDP ya es incorrecto en si mismo, ya que las conexiones UDP no existen (si eso, se implementan en capas superiores en la pila TCP/IP, o sea, en la capa de Aplicación. Pero en el protocolo UDP no existen conexiones). Además, "&lt;i&gt;attemps to open&lt;/i&gt;&lt;i&gt;"&lt;/i&gt; también es incorrecto, ya que UDP no intenta "abrir"  nada, sinó mas bien intenta mandar el paquete a la red. ¿Que el paquete llega? Bues bien. ¿Que no llega? Pues a UDP se la suda. De hecho el protocolo UDP no sabe ni si ha llegado el paquete[1], ni le importa. &lt;b&gt;&lt;span &gt;Repito, no existe el concepto de conexión en el protocolo UDP.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;¿Qué todavía no me crees? Vaya, macho... a ver. RFC793, TCP[2]. Ocurrencias de la palabra &lt;i&gt;connection&lt;/i&gt;: 271. RFC768, UDP[3]. Ocurrencias de la palabra &lt;i&gt;connection&lt;/i&gt;: ninguna!!!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;¿Qué propongo? Pues cambiar la frase a algo así:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;If host is a valid hostname or Internet address, and port is an integer port number or service name, bash &lt;b&gt;attempts to send a UDP datagram&lt;/b&gt; to the corresponding socket.&lt;/blockquote&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ya he mandado un email al mantenedor del manual de bash, en mi perfecto inglés de mierda (gracias hermana por ayudarme a corregir mi inglesanalfabetismo). A ver que dice. Ya os diré cosas cuando conteste. A ver que le parece a él.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Un saludo, Jan.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[0] Noooo! Tranquilos!! No soy tan bruto como para inslarle Linux en un Kindle! Es simplemente que quería decir que me había comprado el juguetito ^_^&lt;/div&gt;&lt;div&gt;[1] no debería decir &lt;i&gt;paquete&lt;/i&gt; sinó &lt;i&gt;datagrama&lt;/i&gt;, para ser mas exacto, ya que lo que comunmente llamamos &lt;i&gt;paquetes&lt;/i&gt; se trata siempre del nombre del PDU de Capa de Red, o sea, protocolo IP, y ahora estamos hablando de la capa de tranmisión de datos, donte tenemos &lt;i&gt;datagramas&lt;/i&gt; en el caso de UDP y &lt;i&gt;segmentos&lt;/i&gt; en el caso de TCP, pero bueno..... sé que diciendo &lt;i&gt;paquete&lt;/i&gt; ya nos entendemos! Y recordemos que UDP es &lt;i&gt;unreliable&lt;/i&gt; y por esto se la suda si llegan o no los paquetes.&lt;/div&gt;&lt;div&gt;[2] &lt;a href="http://www.faqs.org/rfcs/rfc793.html"&gt;http://www.faqs.org/rfcs/rfc793.html&lt;/a&gt;&lt;/div&gt;&lt;div&gt;[3] &lt;a href="http://www.blogger.com/]%C2%A0http://www.faqs.org/rfcs/rfc768.html"&gt;http://www.faqs.org/rfcs/rfc768.html&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;</description><link>http://inedit00.blogspot.com/2012/04/errores-en-el-manual-de-bash.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-1439790341883411426</guid><pubDate>Sat, 07 Apr 2012 08:32:00 +0000</pubDate><atom:updated>2012-04-07T10:59:21.964+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">linux</category><title>Actualizando el microcódigo de la CPU (microcode.ctl)</title><description>&lt;div style="font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; "&gt;&lt;span &gt;&lt;b&gt;[Explicación]&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; font-weight: normal; "&gt;Los procesadores tienen un firmware, también llamado microcódigo. El firmware está situado entre el hardware y el lenguaje ensamblador. Mas o menos la cosa iría así:&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; font-weight: normal; text-align: center; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; text-align: center; "&gt;hardware -&amp;gt; &lt;b&gt;firmware&lt;/b&gt; (microcódigo) -&amp;gt; ensamblador -&amp;gt; kernel -&amp;gt; S.O. y aplicaciones&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; font-weight: normal; text-align: left; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; font-weight: normal; text-align: left; "&gt;Es un bloque de instrucciones máquina que establece la lógica a más bajo nivel y que está fuertemente ligado a la electrónica subyacente. Pero así mismo, es un cacho de código. O sea, software.&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; font-weight: normal; text-align: left; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; text-align: left; "&gt;&lt;span style="font-size: 100%; "&gt;Cuando compras una CPU en una tiena, o te compras un portátil estás adquiriendo un modelo concreto, que viene con una revisión (versión) de firmware concreta. Pero ¿&lt;b&gt;Qué passa si Intel saca una nueva versión de firmware con mejoras, optimizaciones, uso de algoritmos mas eficientes y con menor consumo de energía, corrección de bugs, etc&lt;/b&gt;? Pues que no los puedes disfrutar, a menos que instales el firmware nuevo. Y...¿Cómo se consigue actualizar el microcódigo? Pues normalmente no te queda otra que actualizar la BIOS de tu máquina actualizando así el microcódigo de tu procesador.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; text-align: left; "&gt;&lt;span style="font-size: 100%; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; text-align: left; "&gt;Pero ya sabes que actualizar la BIOS no siempre es buena idea. Si mientras la estás actualizando se vá la corriente, puedes tirar el procesador directamente, que es irrecuperable. Es algo peligroso. Se puede hacer, pero no es algo que quieras hacer muy amenudo. Enserio.&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; text-align: left; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; text-align: left; "&gt;Cagonlaputa. Entonces, ¿no hay alternativa posible? Si. Si la hay. Almenos en Linux si.&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; text-align: left; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; text-align: left; "&gt;&lt;b&gt;[Conociendo la herramienta]&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; text-align: left; "&gt;Hay un hermoso paquete llamado &lt;b style="font-style: normal; "&gt;microcode.ctl&lt;/b&gt; que hace éste trabajo por nosotros y que se encarga de cargar el microcódigo de &lt;b style="font-style: normal; "&gt;manera dinámica&lt;/b&gt; en nuestro procesador. Esto significa que no &lt;i&gt;flashea&lt;/i&gt; el procesador (no hace los cambios permanentes) sinó que actualiza el firmware del procesador &lt;b&gt;al vuelo&lt;/b&gt; y en tiempo de ejecución &lt;b&gt;cada vez&lt;/b&gt; que se inicia el S.O. Esto tiene varias ventajas:&lt;/div&gt;&lt;div style="text-align: left; "&gt;&lt;ol&gt;&lt;li&gt;&lt;span &gt;&lt;img src="http://www.blogger.com/img/blank.gif" alt="Lista numerada" border="0" class="gl_list_num" /&gt;Nada de actualizar la BIOS del modo tradicional, por lo que nos evitamos un procedimiento peligroso (y tedioso).&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span &gt;Se descarga automáticamente las nuevas versiones sacadas por Intel y las aplica en el próximo reinicio.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span &gt;En caso de que se descargue una versión que por lo que sea falla y nos dá problemas, solo debemos desactivar el &lt;i&gt;daemon&lt;/i&gt; que se encarga de actualizar el microcódigo del procesador cada vez que se inicia el sistema, y santas pascuas.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; text-align: left; "&gt;&lt;span style="font-size: 100%; "&gt;&lt;b&gt;[Instalación]&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left; "&gt;&lt;span style="font-family: Georgia, serif; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; font-size: 100%; "&gt;Pff.... ¿enserio que tengo que hacer esta sección? Si las secciones de "instalación" siempre son iguales en Linux :/&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left; "&gt;&lt;span  &gt;&lt;b&gt;$ sudo aptitude install microcode.ctl&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; font-weight: normal; text-align: left; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-weight: normal; text-align: left; "&gt;&lt;span style="font-style: normal; "&gt;...y a correr. En la instalación te pedirá si te quieres descargar también el paquete propietario &lt;/span&gt;&lt;i&gt;intel-microcode&lt;/i&gt; que contiene las últimas versiones de los microcódigos. Obviamente la resuesta es SI, QUIERO. Y punto. Si vas a ver el fichero /var/log/syslog puede que te encuentres con estas bonitas líneas (pero dependen de la versión de firmware que tengas, claro):&lt;/div&gt;&lt;div style="text-align: left; "&gt;&lt;div&gt;&lt;span &gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: left; "&gt;&lt;span &gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;microcode: CPU0 sig=0x20655, pf=0x10, revision=&lt;b&gt;0x2&lt;/b&gt;&lt;/div&gt;&lt;div&gt;microcode: CPU1 sig=0x20655, pf=0x10, revision=0x2&lt;/div&gt;&lt;div&gt;microcode: CPU2 sig=0x20655, pf=0x10, revision=0x2&lt;/div&gt;&lt;div&gt;microcode: CPU3 sig=0x20655, pf=0x10, revision=0x2&lt;/div&gt;&lt;div&gt;microcode: Microcode Update Driver: v2.00 &lt;tigran@aivazian.fsnet.co.uk&gt;, Peter Oruba&lt;/tigran@aivazian.fsnet.co.uk&gt;&lt;/div&gt;&lt;div&gt;microcode: CPU0 updated to revision &lt;b&gt;0x3&lt;/b&gt;, date = 2011-09-01&lt;/div&gt;&lt;div&gt;microcode: CPU1 updated to revision 0x3, date = 2011-09-01&lt;/div&gt;&lt;div&gt;microcode: CPU2 updated to revision 0x3, date = 2011-09-01&lt;/div&gt;&lt;div&gt;microcode: CPU3 updated to revision 0x3, date = 2011-09-01&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Un saludo!&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; font-weight: normal; text-align: left; "&gt;&lt;span style="font-size: 100%; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; font-weight: normal; text-align: left; "&gt;&lt;span style="font-size: 100%; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;</description><link>http://inedit00.blogspot.com/2012/04/actualizando-el-microcodigo-de-la-cpu.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-3085455213877936145</guid><pubDate>Fri, 06 Apr 2012 10:46:00 +0000</pubDate><atom:updated>2012-04-06T12:47:34.033+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">atajos</category><title>Gestor de portapapeles</title><description>&lt;span &gt;&lt;span style="font-size: 100%;"&gt;Entrada rápida. &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Georgia, serif; font-style: normal; font-variant: normal; line-height: normal; font-size: 100%; "&gt;&lt;b&gt;Parcellite&lt;/b&gt;[1] es un  &lt;b&gt;gestor de portapapeles&lt;/b&gt;. Simplemente pulsando Control+Alt+H te aparece un listado con las últimas cosas que has copiado mediante Control+C, seleccionándolas con el ratón o mediante el teclado. Elige un elemento de la lista y para pegar pulsa una de las siguientes combinaciones de teclas:&lt;/span&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: Georgia, serif; "&gt;Control+V&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Georgia, serif; "&gt;Shift+Insert&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Georgia, serif; "&gt;Control+Shift+V&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;span &gt;Para programar con Vim es una monada. Pruebalo. Ya. Te encantará.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span &gt;En mi configuración (a través de GTK) en la pestaña Behavior tengo marcadas solo las opciones:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span &gt;Use Copy (Control-C)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span &gt;Use Primary (Selection)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span &gt;Syncronize clipboards&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span &gt;Save history&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span &gt;Y todo lo demás desactivado.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span &gt;Un saludo.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Georgia, serif; font-size: 100%; "&gt;[1] &lt;/span&gt;&lt;a href="http://parcellite.sourceforge.net/" style="font-family: Georgia, serif; font-size: 100%; "&gt;http://parcellite.sourceforge.net/&lt;/a&gt;&lt;/div&gt;</description><link>http://inedit00.blogspot.com/2012/04/gestor-de-portapapeles.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-5312321584250832863</guid><pubDate>Thu, 05 Apr 2012 15:15:00 +0000</pubDate><atom:updated>2012-04-08T21:12:05.455+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">erlang</category><title>Erlang (IV) Semana 2</title><description>&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-align: left; "&gt;&lt;a href="http://inedit00.blogspot.com.es/2012/03/erlang-iii-semana-0.html"&gt;La Semana 1&lt;/a&gt; construímos un core de servidor de chat que hacía bastante bien su trabajo. Ahora el paso lógico es:&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family: Georgia, serif; "&gt;Integrar este core con un servidor HTTP&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Georgia, serif; "&gt;Crear una User Interface (UI) bonita y amigable&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span&gt;&lt;b&gt;[Servidor HTTP]&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;El primer punto, que al principio no acababa de ver claro, ha sido muy simple. Lo primero de todo era encontrar un servidor HTTP para Erlang. Mis requisitos eran:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: Georgia, serif; "&gt;Escrito 100% en Erlang. Para no liarnos con otras tecnologías&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Georgia, serif; "&gt;Que pueda soportar mucha concurrencia. Por motivos obvios en la aplicación que queremos crear.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Georgia, serif; "&gt;Con un sistema muy simple de hacer &lt;/span&gt;&lt;i style="font-family: Georgia, serif; "&gt;dispatch&lt;/i&gt;&lt;span style="font-family: Georgia, serif; "&gt; de llamadas, con controladoras y todo el tinglado. Quería algo que ya te lo diese un poco mascado, pero que fuera altamente personalizable.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span&gt;El servidor web &lt;b&gt;MochiWeb&lt;/b&gt; cumple con todos los requisitos anteriores. El trabajo principal ha sido crear un pequeño dispacher para cada una de las llamadas, para poder ofrecer una interfície &lt;i&gt;restful&lt;/i&gt; simple, limpia y clara pero que nos sirva para nuestros propósitos. Para saber exactamente cómo está implementado, que se mire el código (mas sobre esto al final), pero para dar una idea general os enseño la API REST que he creado:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;&lt;b&gt;Acción: &lt;/b&gt;/login&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;span style="font-family: Georgia, serif; "&gt;&lt;b&gt;Método&lt;/b&gt;: GET. &lt;/span&gt;&lt;span style="font-family: Georgia, serif; "&gt;&lt;b&gt;Parámetros&lt;/b&gt;: N/A. &lt;/span&gt;&lt;span style="font-family: Georgia, serif; "&gt;&lt;b&gt;Explicación&lt;/b&gt;: Renderiza la pantalla de login&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b style="font-family: Georgia, serif; "&gt;Acción: /&lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;login&lt;/span&gt;&lt;b style="font-family: Georgia, serif; "&gt; Método&lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;: POST. &lt;/span&gt;&lt;b style="font-family: Georgia, serif; "&gt;Parámetros&lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;: username, password. &lt;/span&gt;&lt;b style="font-family: Georgia, serif; "&gt;Explicación&lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;: Loguea el usuario, en caso de que los datos sean correctos, mediante el establecimiento de una cookie.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b style="font-family: Georgia, serif; "&gt;Acción: &lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;/logout&lt;/span&gt;&lt;b style="font-family: Georgia, serif; "&gt; Método&lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;: GET. &lt;/span&gt;&lt;b style="font-family: Georgia, serif; "&gt;Parámetros&lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;: N/A. &lt;/span&gt;&lt;b style="font-family: Georgia, serif; "&gt;Explicación&lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;: Lo obvio&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b style="font-family: Georgia, serif; "&gt;Acción&lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;: /msg &lt;/span&gt;&lt;b style="font-family: Georgia, serif; "&gt;Método&lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;: GET. &lt;/span&gt;&lt;b style="font-family: Georgia, serif; "&gt;Parámetros&lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;: N/A. Explicación: Éste es el mas importante de todos. Está pensado para ser llamado por AJAX y manetener la conexión abierta durante 20 segundos. Recibe como respuesta un JSON con los mensajes que puedan haber enviado enviado otros usuarios durante estos 20 segundos, la notificación de que otro usuario se ha logueado, etc... Más sobre esto, luego.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b style="font-family: Georgia, serif; "&gt;Acción: &lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;/msg&lt;/span&gt;&lt;b style="font-family: Georgia, serif; "&gt; Método&lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;: POST. &lt;/span&gt;&lt;b style="font-family: Georgia, serif; "&gt;Parámetros&lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;: msg, to &lt;/span&gt;&lt;b style="font-family: Georgia, serif; "&gt;Explicación&lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;: Envia el mensaje &lt;/span&gt;&lt;i style="font-family: Georgia, serif; "&gt;msg&lt;/i&gt;&lt;span style="font-family: Georgia, serif; "&gt; al usuario &lt;/span&gt;&lt;i style="font-family: Georgia, serif; "&gt;to&lt;/i&gt;&lt;span style="font-family: Georgia, serif; "&gt;. ¿Fácil, no?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b style="font-family: Georgia, serif; "&gt;Acción: &lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;/users_list&lt;/span&gt;&lt;b style="font-family: Georgia, serif; "&gt; Método&lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;: GET. &lt;/span&gt;&lt;b style="font-family: Georgia, serif; "&gt;Parámetros&lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;: N/A. &lt;/span&gt;&lt;b style="font-family: Georgia, serif; "&gt;Explicación&lt;/b&gt;&lt;span style="font-family: Georgia, serif; "&gt;: Devuelve un JSON con el listado de amigos conectados en este momento.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;¿Simple, verdad?&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;La acción mas interesante es /msg per método GET. Vamos a explicarla un poquito mas. Como comentaba mas arriba, esta llamada devuelve un &lt;i&gt;MIME-type application/json&lt;/i&gt;. Nada de XML ni líos, JSON nos va perfecto para este caso, ya que esto lo recibe la parte cliente y tiene que interpretarse en Javascript. Sabiendo que JSON significa JavaScript Object Notation, queda claro que para este caso ésta es la elección ideal. Esta acción está pensado para ser llamado por AJAX, pero también puede ser llamada por el método tradicional sin problemas. Cuando se cree la conexión, ésta permanecerá abierta durante 20 segunos. Durante este tiempo, si se produce algún evento en la parte servidor como por ejemplo recicibir un mensaje, se mandará el mensaje hacia el usuario a través de esta conexión. Si no hay nada que notificar en 20 segundos, se cierra la conexión y se espera que el cliente abra otra inmediatamente después, esperando así indefinidamente a recibir algún tipo de mensaje.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span style="font-size: 100%; "&gt;¿Qué tipo de información devuelve éste método? Pues información que tenga que ver con cambios de estado, mensajes de chat, notificaciones, etc... Veamos los JSON's de posibles resultados:&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: Georgia, serif; "&gt;{"action":"message", "user":"inedit00", "msg": "Hello world!"}&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Georgia, serif; "&gt;{"action": "friend_logged", "name": "foo"}&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;{"action": "friend_unlogged", "name": "bar"}&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;....&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span&gt;Como podeis ver la interfície es muy clara y legible. El &lt;i&gt;action&lt;/i&gt; determina qué tipo de mensaje es, y cada mensaje tiene los campos con la información necesaria. Procesar esto en JS es prácticamente un chiste. Mirad, así, en pseudo-javascript y para que os hagáis una idea:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;MessageHandler = {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;    message: function(request) {  alert(request.msg) },&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;    friend_logged: function(request) {alert("The user " + request.name + "logged in")},&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;    .....&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;var process_http_response = function(html) {&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span style="font-family: Georgia, serif; "&gt;    json = JSON.decode(html)&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span style="font-family: Georgia, serif; "&gt;    MessageHandler[json["action"]](json)&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;&lt;span style="font-size: medium; "&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;nada... un juego de niños. La ventaja de utilizar algo así es que para añadir una acción más, simplemente hay que mandar un mensaje distinto y crear su &lt;i&gt;handler&lt;/i&gt; en el código JS. Obviamente el código JS está pensado para ignorar todos los mensajes con un &lt;i&gt;action&lt;/i&gt; para los que no tiene &lt;i&gt;handler&lt;/i&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;Total, que con todo esto ya tenemos una manera de mandar mensajes a otros usuarios en el sistema des de la parte cliente (JavaScript) y que sean recibidos por otros usuarios mediante HTTP. Genial.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;&lt;b&gt;[User Interface]&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;Bueno, esto simplemente es HTML+CSS+JS. Aquí no hay mucho que contar. Si alguien se lo quiere mirar que vaya al repositorio y mire el código fuente de todo el percal (es poquito y simple). Os dejo con el número de líneas que he usado para cada una de las cosas, y un par de capturas de pantalla, y arreando....&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;ul&gt;&lt;li&gt;Página principal /index &lt;b&gt;37&lt;/b&gt; líneas de HTML&lt;/li&gt;&lt;li&gt;Página de login /login &lt;b&gt;31&lt;/b&gt; líneas de HTML&lt;/li&gt;&lt;li&gt;Fichero con todos el CSS's del proyecto: &lt;b&gt;98&lt;/b&gt; líneas&lt;/li&gt;&lt;li&gt;Fichero con todo el JS del proyecto &lt;b&gt;195&lt;/b&gt; líneas. Incluye la creación, cambio de tamaño/posición de las ventanas de chat, control de las conexiones por AJAX al servidor y los &lt;i&gt;handlers&lt;/i&gt; que procesan las respuestas (mensajes nuevos, usuarios conectados/desconectados, etc....)....&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;Nhá... ha quedado todo muy pequeñito y limpio. Por supuesto nada de estilos &lt;i&gt;inline&lt;/i&gt;, ni CSS en bloques &lt;i&gt;style&lt;/i&gt; dentro de los ficheros HTML, ni Javascript inline en atributos HTML (¡aberración!) ni demás guarradas varias en el código. &lt;b&gt;Sabéis que si hacéis estas cosas vais a ser sodomizados por Diox durante toda la eternidad, ¿verdad? &lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;En el HTML hay dos imports, uno al CSS y otro al fichero JS y palante toda. Y mas o menos el tema luce así (que siiiiiii, que sé que todo lo anterior que os he contado os la sudaaaa, que coméis por los ojos!! ):&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcSCQW6hhes6q9qKwvznJvixqUQw6LiK2LuFlLAz9sm79OrjSKtWMn0hKwGWr6KpIssx1oCFcsvZcXMnvG82Z4i40M_WEoFLtgOtplGjrN7N21aYlTjkdIpSZjmeOdmKXFmARwD4AzSDw/s1600/gaab_login.png"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcSCQW6hhes6q9qKwvznJvixqUQw6LiK2LuFlLAz9sm79OrjSKtWMn0hKwGWr6KpIssx1oCFcsvZcXMnvG82Z4i40M_WEoFLtgOtplGjrN7N21aYlTjkdIpSZjmeOdmKXFmARwD4AzSDw/s400/gaab_login.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5727952606063245554" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 400px; height: 209px; " /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifL2ZQFhsSIiQfg1ZpCn3Mez_bIHtOCYnCRyDiZ5bo411Nqyi60rK1cepzMeX89Fm4XVDQnFKnMUZXlKDO4JawX4qdQC7PUho-bWChFrQqN2GNQMlZlTLEKh5ZlTL321NuxSht9MnVhss/s1600/gaab_capture1.png"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifL2ZQFhsSIiQfg1ZpCn3Mez_bIHtOCYnCRyDiZ5bo411Nqyi60rK1cepzMeX89Fm4XVDQnFKnMUZXlKDO4JawX4qdQC7PUho-bWChFrQqN2GNQMlZlTLEKh5ZlTL321NuxSht9MnVhss/s400/gaab_capture1.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5727952524894012882" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 400px; height: 241px; " /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;Ahora mismo solo hay un usuario conectado con el que pueda hablar (yo mismo en otro navegador ¬¬'). En las ventana de chat soporta modificación de tamaño, ponerla donde quieras en la pantalla, cerrarla y puedes tener abiertas tantas conversaciones de chat como quieras (siempre que tengas mas amigos, obviamente). Para ser una primera versión sacada en una tarde (HTML+CSS), estoy muy contento con el resultado.&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;Y nada.... esto es básicamente todo lo que tiene que ver con UI. Los ficheros interesantes del repositorio que tienen que ver con UI son:&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;ul&gt;&lt;li&gt;/templates/index.dtl&lt;/li&gt;&lt;li&gt;/temlates/login.dtl&lt;/li&gt;&lt;li&gt;/priv/www/js/gaab.js&lt;/li&gt;&lt;li&gt;/priv/www/css/gaab.css&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;b&gt;[Repositorio]&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;b&gt;¿Repositorio? ¿Quién dijo repositorio?&lt;/b&gt; Pues claro que si, hombre! Si trabajas con código y no lo versionas es que te gusta vivir peligrosamente. Seguramente tus hobbies puedan ser hacer puenting sin cuerda, hacer la danza de pescado crudo en playas infestadas de tiburones en Madagascar o intentar ligar con la chica buenorra con el novio culturista.... a saber.&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;Todal, que tengo todo este código subido a un repositorio de bitbucket para uso y disfrute de todo quien quiera verlo:&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-align: center; "&gt;&lt;a href="http://code.krenel.org/gaab"&gt;http://code.krenel.org/gaab&lt;/a&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;y esto es todo... quien quiera preguntar alguna cosa, sugerir alguna otra, pedirme que explique algo un poco mas o tenga curiosidad en lo que sea: que me mande una caja de cerveza...... digooooooooo..... que deje un comentario!&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; "&gt;&lt;span&gt;Un saludo!&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;</description><link>http://inedit00.blogspot.com/2012/04/erlang-iii-semana-2.html</link><author>noreply@blogger.com (inedit00)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcSCQW6hhes6q9qKwvznJvixqUQw6LiK2LuFlLAz9sm79OrjSKtWMn0hKwGWr6KpIssx1oCFcsvZcXMnvG82Z4i40M_WEoFLtgOtplGjrN7N21aYlTjkdIpSZjmeOdmKXFmARwD4AzSDw/s72-c/gaab_login.png" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-4810244453614644604</guid><pubDate>Thu, 05 Apr 2012 09:06:00 +0000</pubDate><atom:updated>2012-04-05T12:22:07.261+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">vim</category><title>Vim y sus plugins</title><description>&lt;div style="text-align: left;"&gt;&lt;span style="font-family: Georgia, serif; font-size: 100%; "&gt;Menos pizzas, &lt;/span&gt;&lt;span style="font-family: Georgia, serif; font-size: 100%; font-weight: bold; "&gt;Vim&lt;/span&gt;&lt;span style="font-family: Georgia, serif; font-size: 100%; "&gt; puede hacerte todo lo demás. Si tienes complejo de pulpo (aka te gustaría tener un par de manos mas para poder usar Emacs como es debido), este post no es para ti.&lt;/span&gt;&lt;/div&gt;&lt;span&gt;&lt;div style="text-align: left;"&gt;&lt;span &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;span &gt;&lt;span style="font-size: 100%;"&gt;He empezado a programar con Erlang y hay un par de pluguins a instalar que son indispensables. Es importante recalcar la importancia que tiene tener un entorno de trabajo cómodo y eficiente, para que el trabajo salga mas rápido y mejor.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;b style="font-family: Georgia, serif; "&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;div&gt;&lt;span&gt;&lt;b style="font-family: Georgia, serif; "&gt;[Plugin para Erlang]&lt;/b&gt;&lt;br /&gt;&lt;span &gt;&lt;span style="font-size: 100%;"&gt;En el caso de erlang me he instalado &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;b style="font-family: Georgia, serif; font-size: 100%; font-style: normal; font-variant: normal; line-height: normal; "&gt;vimerl&lt;/b&gt;&lt;span &gt;&lt;span style="font-size: 100%;"&gt;[1] que entre sus muchas características como syntax highlight, code completion, auto-indent, etc... tiene una cosa que es una pasada que ellos llaman el QuickFix. Cada vez que guardas un fichero, comprueba si hay errores de sintaxis, variables no declaradas, variables no usadas, funciones no usadas, y demás... muy cómodo para no tener que hacer el proceso de: compilar, buscar errores en la consola, ver qué fichero y en qué línea han ocurrido, etc... E aquí un ejemplo. Fijaos que en la parte inferior de la pantalla nos pone una descripción del error en donde tenemos el cursor:&lt;/span&gt;&lt;/span&gt;&lt;div style="line-height: normal; font-variant: normal; font-style: normal; font-size: 100%; font-family: Georgia, serif; "&gt;&lt;br /&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBmTHLWkcht27-7AYDy65GPy79GjyK5mynTlQayKuucuhHUoQm3PNU46w_K4qRjMVI5eE6n-dack3coriXATrGZBvexZaStxJ9Y82kTBw0WM6Wo_XlUK-MQm2LIfqFQ0S3UOzev9uwG8c/s1600/erlang_example.png"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBmTHLWkcht27-7AYDy65GPy79GjyK5mynTlQayKuucuhHUoQm3PNU46w_K4qRjMVI5eE6n-dack3coriXATrGZBvexZaStxJ9Y82kTBw0WM6Wo_XlUK-MQm2LIfqFQ0S3UOzev9uwG8c/s400/erlang_example.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5727844354510963394" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 400px; height: 132px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: center;"&gt;&lt;span  &gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/span&gt;&lt;/div&gt;Los warnings los marca de color amarillento, mientras que los errores te los pone en rojo. Muy cómodo ya que cada vez que guardas el archivo puedes ver si tienes errores en el fichero o no. Muy chulo.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;[Plugins generales]&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Mas cosicas. Pues mira, uno que es básico, pero que hasta ahora no me gustaba mucho, es el &lt;b&gt;NerdTree&lt;/b&gt;[2](vaya puto nombre feo le han puesto a la criatura). Le he dado una oportunidad y de momento va de lujo. Es un explorador de ficheros, con el que se puede navegar por la estructura de directorios des de Vim:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQyup-hMwaExvSSvN9_Ekkyy9i1mbNw93yiPz_SvKegvsJZLcAHo7QZl6PXtN-TdlixYvWeLR1trPGCcMWXsl9FsLzMQQZHd22oxNzrgKwIMiYKFupPOuxYuYsQ1jH4hDaBPHHZHrdrtY/s1600/erlang_nerd.png"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQyup-hMwaExvSSvN9_Ekkyy9i1mbNw93yiPz_SvKegvsJZLcAHo7QZl6PXtN-TdlixYvWeLR1trPGCcMWXsl9FsLzMQQZHd22oxNzrgKwIMiYKFupPOuxYuYsQ1jH4hDaBPHHZHrdrtY/s400/erlang_nerd.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5727845930026648978" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 400px; height: 143px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: left;"&gt;&lt;span &gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/span&gt;&lt;/div&gt;Cómodo y fácil de usar. Hay dos configuraciones que te pueden hacer la vida mas fácil. La primera es para poder ignorar ficheros, y que no aparezcan en el listado. Añadiendo en el .vimrc la siguiente línea, se consiguen omitir los resultados que hagan match a las expresiones regulares de la lista (en mi caso ignorar loc ficheros *.pyc )&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span &gt;let NERDTreeIgnore=['.*pyc$']&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;La segunda es añadir un keybinding para mostrar/ocultar el NerdTree. Esto se consigue añadiendo ésta línea en el .vimrc:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;&lt;span &gt;map  &lt;f2&gt; :NERDTreeToggle &lt;cr&gt;&lt;/cr&gt;&lt;/f2&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;El pulsar F2, se abre/cierra el NerdTree. Muy cómodo también.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Y por último, un pluguin que complementa al NerdTree: &lt;b&gt;CommandT&lt;/b&gt;[3]. Básicamente es un listado de tooodos los ficheros del proyecto y escribiendo un par de letras puedes abrir el fichero que quieras. Ejemplo:&lt;/div&gt;&lt;div&gt;Digamos que tenemos un fichero en &lt;i&gt;www/back/back/controlers/dashboard.mako&lt;/i&gt;. Sería suficiente con escribir '&lt;i&gt;dash&lt;/i&gt;', como para que él ya te lo encuentre. Pero vamos a otro caso mas complicado en el que tenemos:&lt;/div&gt;&lt;div&gt;&lt;i&gt;/www/back/back/templates/foo&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;/www/back/back/templates/bar&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;/www/back/back/templates/lala&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;/www/back/back/widget/foo/template.mako&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;/www/back/back/widget/bar/template.mako&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;En este caso, si quremos encontrar el fichero "&lt;i&gt;/www/back/back/&lt;b&gt;wi&lt;/b&gt;dget/&lt;b&gt;f&lt;/b&gt;oo/&lt;b&gt;te&lt;/b&gt;mplate.mako&lt;/i&gt;" será suficiente con escribir: "wifte", que se corresponde a:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;"wi" de "widget"&lt;/li&gt;&lt;li&gt;"f" de "foo"&lt;/li&gt;&lt;li&gt;"te" de template&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Aparte de mi burda explicación que he hecho aquí, recomiendo que mireis el screencast[4] hecho por el mismo creador del &lt;i&gt;plugin&lt;/i&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;También crearemos un keybinding para este plugin, de modo que la pulsar F3 se abra automáticamente CommandT. El comportamiento por defecto para ejecutar CommandT es pulsar la combinación &lt;i&gt;&lt;leader&gt;t.&lt;/leader&gt;&lt;/i&gt; La tecla &lt;i&gt;&lt;leader&gt;&lt;/leader&gt;&lt;/i&gt; es la tecla "\", que en teclado inglés está en una posición muy cómoda, pero en el teclado castellano está a tomar por culo. Para esto la mayoría de gente se redefine la tecla &lt;i&gt;&lt;leader&gt;&lt;/leader&gt;&lt;/i&gt; a la coma ",".&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;&lt;span &gt;map  &lt;f3&gt; :CommandT &lt;cr&gt;&lt;/cr&gt;&lt;/f3&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;b&gt;&lt;span &gt;let mapleader = "," " Change the &lt;leader&gt; key from \ fo ,&lt;/leader&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Con estos pluguins tenemos una combinación ideal, ya que si no sabemos qué buscamos, tenemos el NerdTree para navegar por los directorios y encontrar el fichero buscado. Si sabemos el nombre exacto, podemos usar CommantT para localizar el fichero, y palante toda. Por falta de recursos, que no sea.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;He probado mas plugins (para buffers, tabs, cerrar paréntesis automáticamente, escribir html automáticament, etc..) pero ninguno de ellos me ha gustado. Pero la verdad que ha valido la pena encontrar estos tres plugins ya que mejoran mucho mi entorno de desarrollo.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Y nada mas por hoy. Un saludo, Jan.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[1] &lt;a href="http://www.vim.org/scripts/script.php?script_id=3743" style="font-weight: normal; "&gt;http://www.vim.org/scripts/script.php?script_id=3743&lt;/a&gt; pero mejor descargar la útima versión de &lt;a href="http://www.vim.org/scripts/script.php?script_id=3743" style="font-weight: normal; "&gt;https://github.com/oscarh/vimerl&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[2] &lt;a href="http://www.vim.org/scripts/script.php?script_id=1658"&gt;http://www.vim.org/scripts/script.php?script_id=1658&lt;/a&gt; pero otra vez recomiendo mejor bajar la última versión de &lt;a href="https://github.com/scrooloose/nerdtree"&gt;https://github.com/scrooloose/nerdtree&lt;/a&gt;&lt;/div&gt;&lt;div&gt;[3] &lt;a href="http://www.vim.org/scripts/script.php?script_id=3025"&gt;http://www.vim.org/scripts/script.php?script_id=3025&lt;/a&gt; y digo lo mismo que con los otros dos &lt;a href="https://github.com/wincent/Command-T"&gt;https://github.com/wincent/Command-T&lt;/a&gt;&lt;/div&gt;&lt;div&gt;[4]&lt;a href="https://wincent.com/products/command-t"&gt;https://wincent.com/products/command-t&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Post relacionado &lt;a href="http://inedit00.blogspot.com.es/2010/04/dandole-cana-vim.html"&gt;http://inedit00.blogspot.com.es/2010/04/dandole-cana-vim.html&lt;/a&gt; . Ahora que lo veo me parece super elemental, pero oye, que de esto hace 2 años y digamos que esto ya lo tengo bastante "mascado", jeje.&lt;/div&gt;&lt;/div&gt;</description><link>http://inedit00.blogspot.com/2012/04/vim-y-sus-plugins.html</link><author>noreply@blogger.com (inedit00)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBmTHLWkcht27-7AYDy65GPy79GjyK5mynTlQayKuucuhHUoQm3PNU46w_K4qRjMVI5eE6n-dack3coriXATrGZBvexZaStxJ9Y82kTBw0WM6Wo_XlUK-MQm2LIfqFQ0S3UOzev9uwG8c/s72-c/erlang_example.png" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-5956858704703149698</guid><pubDate>Mon, 26 Mar 2012 17:55:00 +0000</pubDate><atom:updated>2012-03-27T00:41:10.737+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">seguridad</category><title>Dig Your Own Hole</title><description>&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;&lt;b&gt;[Flame]&lt;/b&gt;&lt;/div&gt;&lt;span style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;Linux es genial, maravilloso, chulo, rápido.... &lt;span style="font-style: normal; color: rgb(255, 0, 0); font-weight: bold; "&gt;y asquerosamente inseguro&lt;/span&gt;. De hecho, cualquier SO de hoy en día lo es, pero cualquier distribución de Linux, por su naturaleza, es mas vulnerable.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;[Introducción]&lt;/b&gt;&lt;br /&gt;El mejor sysadmin que he conocido me enseñó algo: &lt;span style="font-style: normal; color: rgb(255, 0, 0); font-weight: bold; "&gt;la seguridad física no existe&lt;/span&gt;. És algo muy fácil de entender: si alguien tiene acceso físico a tu máquina, no hay nada que hacer. Des de DoS apagando la misma (ya sea desenchufando el cable o pulsando una &lt;a href="http://inedit00.blogspot.com.es/2009/10/reset-en-linux.html" style="font-weight: normal; font-style: normal; "&gt;divertida combinación de teclas&lt;/a&gt;[1]), pasando por ataques de &lt;a href="http://www.seginformatica.net/2012/03/ataque-de-david-hasselhoff-evolucion.html" style="font-weight: normal; font-style: normal; "&gt;David Hasselhoff&lt;/a&gt;[2], borrado de archivos, escalado de privilegios (des de una shell o haciendo truquillos en el grub), poner backdoors o, en caso de que nos pongamos mas serios el mismo robo del equipo y posterior análisis de los datos del disco duro, ataques de red MITM (ARP poisoning, ICMP redirect), hijacking de cookies que viajan por redes WiFi sin protección, y un laaargo etc. El tema está que el ataque se puede producir en cuestión de minutos y hay pocas formas de protegerse contra el.&lt;br /&gt;&lt;br /&gt;Una vez el sistema ha sido "&lt;i style="font-weight: normal; "&gt;tocado&lt;/i&gt;" físicamente por alguna otra persona que no seas tu mismo, la máquina deja de ser segura y no te puedes fiar nunca mas de ella. ¿Exagero? Esperad y veréis.&lt;br /&gt;&lt;br /&gt;Bueno, vale. Volviendo a la primera frase-flame del post quiero aclarar (o acotar) un poco la afirmación: Todas las distribuciones de Linux por lo general tienen implementaciones de red seguras. Los bugs de software (tanto en los programas en general como en el kernel) son arreglados en muy poco tiempo y uno tiene la opción de ver el código fuente de la mayoría de programas para asegurar que no incluyen sopresas, etc.... y todo esto está genial. Si la máquina se mantiene actualizada es difícil encontrar zero-days o exploit para ganar privilegios. Pero todo esto no es necesario ya que existe algo que se llama &lt;/span&gt;&lt;b style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; font-style: normal; "&gt;consola&lt;/b&gt;&lt;span &gt;&lt;span style="font-size: 100%;"&gt;. Que es muuy potente. Y que en manos de una persona agena (por no bloquear el portátil al ir a responder una llamada de móvil, o en un despiste tonto), y con muy pocos comandos, puede comprometer un sistema en un momentín. Y exactamente sobre esto va esta serie de posts.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span &gt;&lt;span style="font-size: 100%;"&gt;Aquí se pretenden recopilar una série de comandos con los que se podrá comprometer un sistema en caso de tener acceso a una consola.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;[Al lío]&lt;/b&gt;&lt;div&gt;&lt;span &gt;Ejecutar en una consola:&lt;br /&gt;&lt;/span&gt;&lt;span  &gt;&lt;b&gt;$ alias sudo="sudo touch /root/owned &amp;amp;&amp;amp; sudo"&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;Nótese que ya se ha  `&lt;i&gt;infectado`&lt;/i&gt;  la consola actual. En caso de que ahora el usuario legítimo ejecute cualquier comando usando "sudo", se le pedirá la contraseña, se ejecutará un comando arbitrario con privilegios de administrador (en nuestro comando de ejemplo 'touch /root/owned'), y después se ejecutará el comando que el había puesto, sin que el usuario se percate que ha ejecutado un comando adicional. Para hacer permanente el cambio se puede ejecutar:&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;&lt;span &gt;&lt;b&gt;$ echo 'alias sudo="sudo touch /root/owned &amp;amp;&amp;amp; sudo"' &amp;gt; ~/.bashrc&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;Y por ejecución de "comando adicional" podríamos entender: crear un usuario de sistema con privilegios de administrador, ejecutar un borrado de todo el disco, instalar un backdoor, programación de una tarea de descarga de un script remoto y ejecutarlo con privilegios de root o peor todavía: cambiar el fondo de pantalla[2].... Vamos, que tenemos privilegio de &lt;i&gt;root&lt;/i&gt; y podemos hacer lo que nos dé la gana.&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;Ahora simplemente tenemos que esperar que el usuario teclee algo así como:&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;&lt;span &gt;&lt;b&gt;$ sudo aptitude update #por ejemplo&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span  &gt;&lt;b&gt;[sudo] password for inedit:  &lt;el usuario="" pone="" su="" password=""&gt;&lt;/el&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;Y ya hemos comprometido el sistema. Bonito, ¿verdad?&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;&lt;span style="font-size: 100%; "&gt;&lt;span &gt;&lt;b&gt;$ ls -l /root/owned&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span  &gt;&lt;b&gt;-rw------- 1 root root 0 Mar 26 20:48 owned&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;&lt;span style="font-size: 100%; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;Seguro que si alguien hace algo así en tu máquina no te hace tanta gracia.&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;&lt;b&gt;[Prevención]&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;¿Modos de prevenir esto? Pues pocos, la verdad. El comando &lt;i&gt;alias&lt;/i&gt; es un funcionalidad del bash (man bash) que puede ser desactivada mediante el comando:&lt;/div&gt;&lt;div&gt;&lt;span  &gt;&lt;b&gt;$ shopt -u expand_aliases&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span &gt;Pero también puede ser activado &lt;/span&gt;&lt;span style="font-family: Georgia, serif; "&gt;por el mismo atacante&lt;/span&gt;&lt;span style="font-family: Georgia, serif; "&gt; &lt;/span&gt;&lt;span style="font-family: Georgia, serif; "&gt;con el comando ("&lt;/span&gt;&lt;span style="font-family: Georgia, serif; "&gt;&lt;span &gt;shopt | grep expand_aliases&lt;/span&gt;" para ver el estado actual):&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span  &gt;&lt;b&gt;$ shopt -s expand_aliases&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;Este método sólo aplicaría a bash. Si se usara una consola xterm o ksh se tendría que buscar el modo concreto de hacerlo en estas otras consolas, pero seguro que existen vías similares (si no iguales)&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;&lt;b&gt;[Moraleja]&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;Que nadie toque tu portátil/PC. &lt;b&gt;Nadie&lt;/b&gt;. Y muchos menos si es alguien que tiene conocimientos medios en sistemas Unix-like. Os pueden hacer un traje. Cuando el PC/portátil queda desatendido, debe ser bloqueado de algún modo (pidiendo contraseña, etc...).  Y aún así uno no puede estar seguro que salga un zero-day[3] (que en realidad era un &lt;i&gt;feature&lt;/i&gt;!!!) y te jodan el tinglado de mientras vas a echar un meo. Los sistemas Linux son muy versátiles, pero esta versatilidad puede jugar en tu contra algunas veces. Si alguien ha tocado tu sistema, aunque no sepa la contraseña de root te puede tangar sin problemas. Y si no la sabe pero la quiere existen otros muchos recursos que ya veremos mas adelante.&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;Un saludo. &lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;&lt;br /&gt;&lt;br /&gt;[1] http://inedit00.blogspot.com.es/2009/10/reset-en-linux.html&lt;br /&gt;[2] http://www.seginformatica.net/2012/03/ataque-de-david-hasselhoff-evolucion.html&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="font-family: Georgia, serif; font-size: 100%; font-variant: normal; line-height: normal; "&gt;[3] http://seclists.org/oss-sec/2012/q1/191&lt;/div&gt;</description><link>http://inedit00.blogspot.com/2012/03/dig-your-own-hole.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-6940330979091514657</guid><pubDate>Sat, 17 Mar 2012 12:15:00 +0000</pubDate><atom:updated>2012-04-08T21:12:33.758+02:00</atom:updated><title>Erlang (III) Semana 1</title><description>&lt;div style="text-align: center;"&gt;&lt;span style="font-size:130%;"&gt;Semana 1&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;Después de hacer una &lt;a href="http://inedit00.blogspot.com.es/2012/03/erlang-ii.html"&gt;&lt;span style="font-style: italic;"&gt;Semana Cero&lt;/span&gt;&lt;/a&gt;* de: aprender, aprender, aprender, aprender, aprender.... &lt;a href="http://inedit00.blogspot.com.es/2012/03/erlang-y-webchats-i.html"&gt;he empezado el proyectito&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;La primera semana simplemente es para jugar y hacer pruebas. Quería empezar creando una primera versión de mi chat. En realidad he rehecho el código 4 veces des de cero, mejorando cada vez la versión anterior. El objetivo primero era conseguir dar de alta usuarios (login), y que pudiesen mandarse mensajes entre ellos. Todo a través de la línea de comandos (intérprete de Erlang). Después también he pensado que estaría bien hacer un poquito de &lt;span style="font-style: italic;"&gt;benchmark&lt;/span&gt; para probar si la idea básica funciona, o todavía necesito aprender más cosas antes de empezar.&lt;br /&gt;&lt;br /&gt;Básicamente estas "iteraciones" de ir rehaciendo código y mejorándolo según los errores y problemas aprendidos ha sido algo así:&lt;br /&gt;&lt;/span&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Escrito código 100% &lt;span style="font-style: italic;"&gt;custom&lt;/span&gt; que se encarga de la gestión de mensajes, sin hacer uso de OTP. Básicamente se disponen de dos módulos: &lt;span style="font-style: italic;"&gt;gaab_server&lt;/span&gt; y &lt;span style="font-style: italic;"&gt;gaab_user&lt;/span&gt;. El primero sirve para saber qué usuarios que están registrados en el chat, el segundo módulo tiene todas las funcionalidades de un usuario, y dispone de funciones tales como &lt;span style="font-style: italic;"&gt;send_message, receive_message, talk_with&lt;/span&gt;, ....&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Reescrito el código ahora haciendo uso de records para manter el estado e implementando una interfície muy parecida a &lt;span style="font-style: italic;"&gt;gen_server&lt;/span&gt;, pero todavía hecho todo 100% &lt;span style="font-style: italic;"&gt;custom&lt;/span&gt;.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Usar &lt;span style="font-style: italic;"&gt;gen_server&lt;/span&gt; tanto para el &lt;span style="font-style: italic;"&gt;gaab_server&lt;/span&gt; como para &lt;span style="font-style: italic;"&gt;gaab_user&lt;/span&gt;, quitar toda la funcionalidad &lt;span style="font-style: italic;"&gt;custom&lt;/span&gt; que ya me dá &lt;span style="font-style: italic;"&gt;gen_server&lt;/span&gt;.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Creado un Makefile, organizado el proyecto en las carpetas correspondientes (src, ebin,...) y demás.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;"&gt;[Cómo funciona]&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:100%;"&gt;Explico un poquito más cómo funciona el tema... Tenemos un agente de &lt;span style="font-style: italic;"&gt;gaab_server&lt;/span&gt; que se encarga de almacenar los usuarios logeados. Básicamente el flujo normal será loguearnos en gaab_server y éste creará un agente de tipo &lt;span style="font-style: italic;"&gt;gaab_user&lt;/span&gt;, y nos devolverá su Pid. El servidor también tiene una función llamada pidof/1 que devuelve el Pid del usuario pasado como parámetro. Simplemente se encarga de saber qué usuarios están logueados en el sistema.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:100%;"&gt;El agente &lt;span style="font-style: italic;"&gt;gaab_user&lt;/span&gt; tiene funciones para hablar con otros usuarios, y siempre está a la espera de recibir mensajes dirigidos hacia el, que imprime por pantalla. Todo muy simple, por ser una primera versión.&lt;/span&gt;&lt;/p&gt;&lt;p style="font-weight: bold;"&gt;&lt;span style="font-size:100%;"&gt;[Benchmarcks]&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:100%;"&gt;Vamos a lanzar un par de tests para comprobar que, efectivamente, el servidor soporte algo de carga. Se van a medir básicamente dos cosas: coste de CPU y coste de memória. Los dos parámtros con los que jugamos son básicamente dos: número de usuarios conectados al mismo tiempo y número de mensajes por segundo enviados entre usuarios. La &lt;a href="http://inedit00.blogspot.com.es/2011/06/lenovo-x201-review.html"&gt;máquina con la que trabajamos&lt;/a&gt; es la siguiente:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:100%;"&gt;Memória RAM: 6GiB DDR (1066).&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:100%;"&gt;CPU: Intel i5 - M540  2.53GHz (2 cores + 2 de Hyperthreading)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:100%;"&gt;Empezemos.&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: center; color: rgb(0, 0, 102); font-weight: bold;"&gt;&lt;span style="font-size:100%;"&gt;Prueba 1. Aumentar número de usuarios&lt;/span&gt;&lt;/p&gt;&lt;span style="font-weight: bold;font-size:100%;"&gt;1.1 - Número de Usuarios: 10K. Mensajes por segundo: 500.&lt;/span&gt;&lt;p style="text-align: left;"&gt;&lt;span style="font-size:100%;"&gt;Carga de CPU ~50% de carga en un core (~13% de el procesador).&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: left;"&gt;&lt;span style="font-size:100%;"&gt;Memória total del proceso: &lt;span style="color: rgb(0, 0, 102); font-weight: bold;"&gt;46.336 Kbytes&lt;/span&gt;. Memória por usuario: 2,98 Kb.&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: left;"&gt;&lt;span style="font-weight: bold;font-size:100%;"&gt;1.2 - &lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;"&gt;Número de &lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;"&gt;Usuarios: 20K. Mensajes por segundo: 500.&lt;/span&gt; &lt;/p&gt;&lt;p style="text-align: left;"&gt;&lt;span style="font-size:100%;"&gt;Carga de CPU ~50% de carga en un core (~13% de el procesador).&lt;/span&gt;&lt;/p&gt; &lt;p style="text-align: left;"&gt;&lt;span style="font-size:100%;"&gt;Memória total del proceso: &lt;span style="color: rgb(0, 0, 102); font-weight: bold;"&gt;78.656 Kbytes&lt;/span&gt;. Memória por usuario: 3.11 Kb&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: left;"&gt;&lt;span style="font-weight: bold;font-size:100%;"&gt;1.3 - &lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;"&gt;Número de &lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;"&gt;Usuarios: 30K. Mensajes por segundo: 500.&lt;/span&gt;&lt;/p&gt;&lt;span style="font-size:100%;"&gt;Carga de CPU ~50% de carga en un core (~13% de el procesador).&lt;/span&gt;  &lt;p style="text-align: left;"&gt;&lt;span style="font-size:100%;"&gt;Memória total del proceso: &lt;span style="color: rgb(0, 0, 102); font-weight: bold;"&gt;87.692 Kbytes&lt;/span&gt;. Memória por usuario: 2.37Kb&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;span style="color: rgb(0, 0, 102); font-weight: bold;font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: center;"&gt;&lt;span style="color: rgb(0, 0, 102); font-weight: bold;"&gt;Prueba 2. Aumentar el número de mensajes/segundo&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-weight: bold;font-size:100%;"&gt;2.1 - Número de Usuarios: 10K. Mensajes por segundo: 500. (prueba 1.1 anterior)&lt;/span&gt; &lt;p style="text-align: left;"&gt;&lt;span style="font-size:100%;"&gt;Carga de CPU &lt;span style="color: rgb(0, 0, 102); font-weight: bold;"&gt;~50%&lt;/span&gt; de carga en un core (~13% del procesador).&lt;/span&gt;&lt;/p&gt; &lt;p style="text-align: left;"&gt;&lt;span style="font-size:100%;"&gt;Memória total del proceso:&lt;span style="font-weight: bold; color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;46.336 Kbytes. &lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="text-align: left;"&gt;&lt;span style="font-weight: bold;font-size:100%;"&gt;2.2 - &lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;"&gt;Número de &lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;"&gt;Usuarios: 10K. Mensajes por segundo: 750.&lt;/span&gt; &lt;/p&gt; &lt;p style="text-align: left;"&gt;&lt;span style="font-size:100%;"&gt;Carga de CPU &lt;span style="color: rgb(0, 0, 102); font-weight: bold;"&gt;~75%&lt;/span&gt; de carga en un core (~20% del procesador).&lt;/span&gt;&lt;/p&gt;  &lt;p style="text-align: left;"&gt;&lt;span style="font-size:100%;"&gt;Memória total del proceso: &lt;span style="color: rgb(0, 0, 0);"&gt;37.244 Kbytes. &lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="text-align: left;"&gt;&lt;span style="font-weight: bold;font-size:100%;"&gt;2.3 - &lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;"&gt;Número de &lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;"&gt;Usuarios: 10K. Mensajes por segundo: 1000.&lt;/span&gt;&lt;/p&gt; &lt;span style="font-size:100%;"&gt;Carga de CPU &lt;span style="color: rgb(0, 0, 102); font-weight: bold;"&gt;~85%&lt;/span&gt; de carga en un core (~23% del procesador).&lt;/span&gt;  &lt;p style="text-align: left;"&gt;&lt;span style="font-size:100%;"&gt;Memória total del proceso: &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);font-size:100%;"&gt;30.366&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Kbytes. &lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;span style="font-size:100%;"&gt;&lt;br /&gt;**Nota: El proceso de Erlang por si solo ocupa 16.508 KBytes.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[Conclusiones]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Pues todo exactamente como esperébamos&lt;/span&gt;. &lt;span style="color: rgb(0, 0, 102);"&gt;Crear muchos usuarios&lt;/span&gt; no tiene coste computacional, &lt;span style="color: rgb(0, 0, 102);"&gt;solo un coste de memória&lt;/span&gt;. Ahora mismo los actores son muy chiquititos y pesan unos 3Kbytes. Aún así esta cifra es muy subjetiva ya que dentro de poco la aplicación empezará a crecer, y los usuarios tendrán que guardar un poco más de información, pero no mucha mas. Esto significa que, a priori, con 1GB de RAM podemos tener unos 300K usuarios activos, en este momento ( ya veremos cuando pongamos conexiones TCP por enmedio, jeje... ). Si quisiéramos llegar a 1 millón de usuarios al mismo tiempo, con 4GB para los procesos de usuario, de momento debería ser suficiente (pero lo dicho, ya veremos).&lt;br /&gt;&lt;br /&gt;Si los usuarios se mandan muchos mensajes entre ellos aumenta el consumo de CPU. Normal. &lt;span style="color: rgb(0, 0, 102);"&gt;A más mensajes, más carga&lt;/span&gt;. Hombre, 1.000 mensajes por segundo son unos cuantos, no está nada mal, pero prácticamente ocupan un core de CPU, por lo que el consumo no es nada despreciable. Tampoco tengo muy claro en aplicaciones grandes cual es el ratio de número_de_usuarios/número_de_mensajes_por_segundo. Pero bueno, ya lo descubriremos.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;Pues nada. Este es el resumen de mi &lt;span style="font-weight: bold;"&gt;Semana 1&lt;/span&gt;. La próxima entrega incluye el servidor web MochiWeb, interfazes web, HTML+CSS+JS, AJAX y la integración de lo que hemos venido haciendo hasta ahora con todo lo anterior.&lt;br /&gt;&lt;br /&gt;Un saludo, Jan.&lt;br /&gt;&lt;br /&gt;* En realidad &lt;span style="font-style: italic;"&gt;Semana Cero&lt;/span&gt; es un modo de hablar. Aprendiendo las bases de Erlang me ha llevado entre 2-3 semanas de una o dos horitas al día (cuando todavía trabajaba).&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Post anterior: &lt;a href="http://inedit00.blogspot.com.es/2012/03/erlang-ii.html"&gt;Erlang (II) Aprendiendo lo básico&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Post siguiente: &lt;a href="http://inedit00.blogspot.com.es/2012/04/erlang-iii-semana-2.html"&gt;Erlang (IV) Semana 2&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;</description><link>http://inedit00.blogspot.com/2012/03/erlang-iii-semana-0.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>18</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-2397394097593266989</guid><pubDate>Tue, 13 Mar 2012 10:58:00 +0000</pubDate><atom:updated>2012-04-07T00:37:48.157+02:00</atom:updated><title>MOC ha muerto. Exaile sube al ring.</title><description>Pues esto, el reproductor de consola &lt;span style="font-style: italic;"&gt;moc&lt;/span&gt; ha muerto. Me parece que ha sido después de una actualización de algún paquete de audio o algo así, que hace que &lt;span style="font-style: italic;"&gt;moc&lt;/span&gt; no funcione bien; consume un 100% de CPU, no cierra el cliente de ncurses.... vaya, que me había quedado sin música.&lt;br /&gt;&lt;br /&gt;Y esto no puede ser.&lt;br /&gt;&lt;br /&gt;He intentado instalar el rhythmbox pero me ha dicho que tenía que descargar 60 paquetes, descargar 50,7MB y resolver chorrocientas dependencias. Já! Estás que instalo yo algo así. He buscado un poquitín y me he encontrado con el reproductor &lt;span style="font-weight: bold;"&gt;Exaile&lt;/span&gt;: liviano, muy simple de usar, controles muy simples y se puede pausar/pasar canción/etc des de el &lt;span style="font-style: italic;"&gt;try-icon&lt;/span&gt;. Está en los repositorios de debian, por lo que mola. Una pena que no sea una aplicación por consola, pero bueno... me acostumbraré.&lt;br /&gt;&lt;br /&gt;Aunque no sea un programa 100% por consola, no quita que no se le puedan pasar parámetros al programa por consola. Esto nos dá libertad total para crear shortcuts. Por ejemplo, hacer que Control-Alt-P ejecuten "&lt;span style="color: rgb(0, 0, 102);"&gt;exaile --play-pause&lt;/span&gt;" y así poder poner play/pause con una simple combinación de teclas (y evitamos tocar el ratón).&lt;br /&gt;&lt;br /&gt;Pues nada, que me ha gustado. Cuando hagan el fix en &lt;span style="font-style: italic;"&gt;moc&lt;/span&gt;, me vulevo a pasar a la aplicación de consola, pero de mientras iré tirando de &lt;span style="font-style: italic;"&gt;exaile&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Edit1&lt;/span&gt;: Anónimo1 me ha propuesto probar &lt;span style="font-weight: bold;"&gt;cmus&lt;/span&gt;, y la verdad es que me ha molado. Mas complejo, pero está chulo. Todavía no he descubierto si tiene la capacidad de reproducir emisoras de radio...&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Edit2&lt;/span&gt;: Parece ser que el bug de Moc que me llevó a escribir este post ya está arreglado. Puedo usar Moc de nuevo.... pero seguiré usando Cmus una temporada, &lt;span style="color: rgb(255, 0, 0);"&gt;que en la variedad está el gusto&lt;/span&gt; (es algo que mi &lt;span style="font-weight: bold;"&gt;ex&lt;/span&gt;novia no entendió)</description><link>http://inedit00.blogspot.com/2012/03/moc-ha-muerto-exaile-sube-al-ring.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>7</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-6908216082796542147</guid><pubDate>Thu, 08 Mar 2012 09:34:00 +0000</pubDate><atom:updated>2012-04-08T21:13:41.812+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">erlang</category><category domain="http://www.blogger.com/atom/ns#">general</category><category domain="http://www.blogger.com/atom/ns#">programacion</category><title>Erlang (II) Aprendiendo lo básico</title><description>Erlang. Erlang. Erlang. &lt;span style="font-weight: bold; "&gt;¿Por dónde empezar a aprender?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Pues por  muchos sitios. Hay un montón de documentación disponible, y un montón de tutoriales. Es suficiente con buscar un poquitín, para encontrarse con material de mucha calidad. Hoy recopilaré las fuentes que me han ido ayudando a aprender lo poco que sé de Erlang.&lt;br /&gt;&lt;br /&gt;He decicido no hacer otro manual de Erlang mas, ya que toda la informaicón que se puede encontrar en Internet es mas que suficiente, y lo único que estaría haciendo sería repetir contenido.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; "&gt;[¿Qué es erlang?]&lt;/span&gt;&lt;br /&gt;Lo explico con mis palabras (seguro que con inexactitudes e imprecisiones) y después pongo un par de enlaces ineresantes y un poco mas &lt;span style="font-weight: normal; font-style: italic; "&gt;serios&lt;/span&gt;. Erlang es un lenguaje de programación funcional, de propósito general y altamente enfocado a la concurrencia. Se creó por la compañía Ericsson para ser usado en temas relacionados con la telefonía (programación de PBX, etc). Una de las características de la telefonía es que necesita &lt;span style="font-weight: bold; "&gt;acceptar mucha concurrenicia&lt;/span&gt; (número de llamadas al mismo tiempo), &lt;span style="font-weight: bold; "&gt;tiene que ser tolerante a fallos&lt;/span&gt; (si una llamada ocasiona un problema, las demás llamadas deben continuar), &lt;span style="font-weight: bold; "&gt;tiene que tener un &lt;/span&gt;&lt;span style="font-style: italic; font-weight: bold; "&gt;downtime&lt;/span&gt;&lt;span style="font-weight: bold; "&gt; mínimo&lt;/span&gt; por lo que implementa un sistema de &lt;span style="font-weight: bold; "&gt;cámbio de código "en caliente"&lt;/span&gt; (ya que siempre hay llamadas establecidas, y una parada de sistema significa dejara sin servicio a los clientes),&lt;span style="font-weight: bold; "&gt; no&lt;/span&gt; &lt;span style="font-weight: bold; "&gt;existen datos comparitos&lt;/span&gt;, ( de este modo se eliminan muchos problemas de concurrencia y bloqueos ), &lt;span style="font-weight: bold; "&gt;los procesos&lt;/span&gt;, también llamados Agentes o Actores, &lt;span style="font-weight: bold; "&gt;son partes de código que se ejecutan de modo independiente&lt;/span&gt;, &lt;span style="font-weight: bold; "&gt;y que se comunica entre otros procesos mediante mensajes&lt;/span&gt; (no son procesos de Sistema, estos "procesos" son gestionados por la máquina virtual de Erlang ). Crear Actores (o procesos) de Erlang es &lt;span style="font-weight: bold; "&gt;*muy*&lt;/span&gt; barato computacionalmente, o sea 1µs. En C# o Java crear un proceso (de sistema) tarda unos 300µs. En erlang se pueden crear literalmente millones de procesos, mientras que en Java/C# no se puede crear mas que unos 2.000. Otra característica muy chula del lenguaje es que estos Procesos-Erlang (o también llamados Agentes o Actores) se pueden ejecutar en cualquier Core o CPU de tu ordenador. De hecho, se pueden ejecutar en otra máquina especificando un parámetro adicional. Esto nos dá la libertad de poder escalar horizontalmente de una manera increíble. Normalmente el mismo Erlang ya hará uso de toda la capacidad de procesamiento de un mismo ordenador (usando todos sus cores), de manera transparente para el usuario y sin tener que programar un línea de código adicional. Pero si se añade una máquina más, es tan simple como decirle a Erlang "'ei! Te he añadido mas recursos. ¡Úsalos!".... y punto :)&lt;br /&gt;&lt;br /&gt;Bueno, vayamos con las definiciones mas serias.&lt;br /&gt;&lt;br /&gt;Obviamente tenemos la web de &lt;a href="http://en.wikipedia.org/wiki/Erlang_%28programming_language%29" style="font-weight: normal; "&gt;wikipedia&lt;/a&gt;, pero la vamos a usar sólo para echarle un vistazo general a las definiciones de qué es Erlang y ver un poquito cómo se vé el código en este lenguaje. Erlang es un lenguaje funcional, lo que quiere decir que hace uso intensivo de recursividad y demás. Las variables solo pueden ser asignadas una vez (sisi, literalmente. Solo una vez. Divertido, ¿verdad?). Que estos conceptos no te asusten. Es simplemente cambiar el &lt;span style="font-weight: normal; font-style: italic; "&gt;chip&lt;/span&gt;. En uno de los manuales que enlazaré mas adelante se explica todo, y queda todo muy claro.&lt;br /&gt;&lt;br /&gt;Después lo mejor será que el mismo Joe Armstrong, uno de los creadores principales de Erlang, nos &lt;a href="http://www.infoq.com/presentations/joe-armstrong-erlang-qcon08" style="font-weight: normal; "&gt;cuente sus bondades&lt;/a&gt; (las de Erlang, no las suyas). Hay otra charla exactamente igual en contenido pero para un publico mas &lt;span style="font-weight: normal; font-style: italic; "&gt;senior&lt;/span&gt; (o mas &lt;span style="font-weight: normal; font-style: italic; "&gt;enterprise&lt;/span&gt;, no lo tengo muy claro) y por lo tanto menos divertida. Esta está muy chula.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; "&gt;[Empezando a jugar]&lt;/span&gt;&lt;br /&gt;Para ir metiéndonos en tarea, podemos echarle un vistazo al curso de la &lt;a href="http://www.erlang.org/course/course.html" style="font-weight: normal; "&gt;web oficial de Erlang&lt;/a&gt;, que dicen que está un poco desfasado, pero está muy bien explicado cómo usar las &lt;span style="font-weight: normal; font-style: italic; "&gt;features&lt;/span&gt; claves del lenguaje. Todo muy escueto, pero bastante útil para entender los conceptos básicos y saber qué nos vamos a encontrar. Hay cinco módulos: &lt;span style="font-weight: normal; font-style: italic; "&gt;History, Sequential Programming, Concurrent Programming,  Error handling&lt;/span&gt; y &lt;span style="font-weight: normal; font-style: italic; "&gt;Advanced Topics&lt;/span&gt;. Recomiendo que se lean con calma e intentando entender todo lo que se pueda. También hay un apartado de &lt;a href="http://www.erlang.org/course/exercises.html" style="font-weight: normal; "&gt;ejercicios&lt;/a&gt; para practicar lo aprendido. Muy útil.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; "&gt;Y aquí viene el punto fuerte&lt;/span&gt;. &lt;span style="font-weight: bold; color: rgb(255, 0, 0); "&gt;La guía definitiva&lt;/span&gt;. &lt;a href="http://learnyousomeerlang.com/" style="font-weight: normal; "&gt;Learn you some Erlang&lt;/a&gt;[1]. La polla en bicicleta. Cuando acabe de leerme la guía entera me voy a poner en contacto con el tío y le mandaré 50€ para que se vaya a tomar unas cervecitas al bar, porque la verdad que se lo ha currado. Son 30 capítulos. Cada uno explica una parte de Erlang. Empieza primero con la história, cómo instalar el intérprete de erlang, tipos de datos, los módulos, la sintaxis de las funciones y los pattern matching, recursividad, funciones de alto nivel, errores y excepciones, concurrencia, multiprocesos, y un laaaaaaargo etc. Una pasada, oye.&lt;br /&gt;&lt;br /&gt;Ya en la introducción el autor dice que es necesario unos conocimientos básicos de programación en lenguajes imperativos (Python, C/C++, Java, Ruby...) y que no hace falta tener conocimientos de lenguajes funcionales (Scala, Haskel, CLisp, Clojure....). Vamos, que empieza des de cero y es muy fácil de ir siguiendo. Todo está con ejemplos de código que podemos ir siguiendo nosotros mismos ( y debemos hacerlo ), y hasta te dá los códigos fuente de todos los programillas que se van creando durante el curso/libro.&lt;br /&gt;&lt;br /&gt;Otra cosa muy buena que tiene &lt;span style="font-weight: bold; "&gt;el autor es que te cuenta lo que es Erlang, y no te lo intenta vender&lt;/span&gt;. Te cuenta sus cosas buenas, y sus cosas malas. Para lo que sirve, y para lo que no sirve. Normalmente las guías siempre te dicen: "aprende a programar en el mejor leguaje de programación del mundo" ( yo almenos tengo dos libros en casa que en la portada aparece este lema, siendo lenguajes de programación distintos ). El autor siempre intenta explicarte las bondades del lenguaje, pero te dice cuáles son sus limitaciones. Muy chulo, la verdad.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; "&gt;[Otra información interesante]&lt;/span&gt;&lt;br /&gt;Hay una pregunta en Stack Overflow sobre &lt;a href="http://stackoverflow.com/questions/2708033/technically-why-is-processes-in-erlang-more-efficient-than-os-threads" style="font-weight: normal; "&gt;por qué los procesos de Erlang son mas eficientes que los Threads del SO&lt;/a&gt; que es muy interesante. También tenemos otra entrada (que sinceramente todavía no he probado[2]) sobre &lt;a href="http://stackoverflow.com/questions/1774315/vim-settings-for-erlang" style="font-weight: normal; "&gt;plugins de Erlang para el Vim&lt;/a&gt; (resaltado de sintaxis, introspección en los módulos, completion... lo típico, vamos).&lt;br /&gt;&lt;br /&gt;Hay otra página, de un tal Richard Jones co-fundador de Last.fm, en donde explica &lt;a href="http://www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-1" style="font-weight: normal; "&gt;cómo construir una aplicación de un millón&lt;/a&gt; de usuarios en Erlang. Son tres entradas muy muy interesantes. Yo me lo leí cuando empezaba con Erlang y me fascinó, aunque sinceramente me enteré de poco. Ahora cada vez lo entiendo mas, y lo utilizo como referéncia para ir cogiendo ideas y ver cómo ha solucionado algunos problemas.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://alexmarandon.com/articles/mochiweb_tutorial/" style="font-weight: normal; "&gt;Otro artículo interesante&lt;/a&gt;, aunque mucho mas específico, es un ejemplo práctico de cómo usar el framework web MochiWeb. Si quieres crear un servidor web, MochiWeb te puede solucionar la papeleta. Es muy ligero, y te dá todos los recursos necesarios para manejar los &lt;span style="font-weight: normal; font-style: italic; "&gt;request/responses&lt;/span&gt;. En éste artículo te explican cómo crear un pequeño &lt;span style="font-weight: normal; font-style: italic; "&gt;dispacher&lt;/span&gt; de los &lt;span style="font-weight: normal; font-style: italic; "&gt;requests&lt;/span&gt; que llegan,  y un modo de devolver las respuestas de manera simple.&lt;br /&gt;&lt;br /&gt;Y nada, de momento esto es todo. Te animo a que le des una oportunidad. No es difícil: Es diferente. Pero muy divertido, y con el que se pueden hacer cosas realmente chulas. Yo estoy difrutando un montón. Para cualquier cosa, dudas, preguntas o aclaraciones, no dudes en dejar tu comentario.&lt;br /&gt;&lt;br /&gt;Un saludo, Jan.&lt;br /&gt;&lt;br /&gt;&lt;b style="font-weight: normal; "&gt;Edit&lt;/b&gt;: Añado otro &lt;a href="http://www.infoq.com/interviews/Erlang-Joe-Armstrong" style="font-weight: normal; "&gt;vídeo muy chulo&lt;/a&gt; de Joe Armstrong.&lt;div style="font-weight: normal; "&gt;&lt;b&gt;Edit&lt;/b&gt;[2]: Vale, ya he probado el pluguin para el Vim y &lt;a href="http://inedit00.blogspot.com.es/2012/04/vim-y-sus-plugins.html" style="font-weight: normal; "&gt;aquí están mis impresiones&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;b&gt;Siguiente post&lt;/b&gt;&lt;/span&gt;&lt;span style="font-weight: normal; "&gt;: &lt;a href="http://inedit00.blogspot.com.es/2012/03/erlang-iii-semana-0.html"&gt;Erlang (III) Semana 1&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Post anterior&lt;/b&gt;: &lt;a href="http://inedit00.blogspot.com.es/2012/03/erlang-y-webchats-i.html"&gt;Erlang y WebChats (I)&lt;/a&gt;&lt;/div&gt;&lt;div style="font-weight: normal; "&gt;[1] Hay un &lt;a href="http://erlang.org.ar/AprendeAlgoDeErlang"&gt;grupo en argentina&lt;/a&gt; que está traduciendo este magnífico trabajo, para al que no le vaya demasiado bien esto del inglés.&lt;/div&gt;</description><link>http://inedit00.blogspot.com/2012/03/erlang-ii.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-4466633402619140729</guid><pubDate>Wed, 07 Mar 2012 23:04:00 +0000</pubDate><atom:updated>2012-03-08T12:27:15.386+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">sistemas</category><category domain="http://www.blogger.com/atom/ns#">tips</category><title>Generar una clave pública a partir de una clave privada (SSH)</title><description>&lt;pre&gt;&lt;code&gt;Típica tontería. Tenemos la llave privada SSH en nuestro PC pero por lo que sea hemos perdido la llave pública de esta clave.&lt;br /&gt;Solución? Pues generar la clave pública otra vez, que se puede recalcular a partir de la clave privada.&lt;br /&gt;El comando es muy simple:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102); font-weight: bold;"&gt;$ ssh-keygen -f ~/.ssh/key -y &amp;gt; ~/.ssh/key.pub&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Nos pedriá la contraseña de la clave privada ( &lt;span style="font-style: italic;"&gt;¿por que que tenemos cifrada la clave privada, verdad?&lt;/span&gt; )&lt;br /&gt;Y estamos listos.&lt;br /&gt;&lt;br /&gt;Si quisiéramos sacar el fingerprint de la clave[1], sería tan fácil como ejecutar&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;$ ssh-keygen -l -f ~/.ssh/key.pub&lt;br /&gt;2048 71:1a:34:94:1b:61:60:09:0c:00:54:e8:ad:17:97:ec key.pub (RSA)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;[1] &lt;a href="http://inedit00.blogspot.com/2009/11/comprobar-fingerprint-en-ssh.html"&gt;http://inedit00.blogspot.com/2009/11/comprobar-fingerprint-en-ssh.html&lt;/a&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;</description><link>http://inedit00.blogspot.com/2012/03/generar-una-clave-publica-partir-de-una.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-6224539805787348481</guid><pubDate>Tue, 06 Mar 2012 22:03:00 +0000</pubDate><atom:updated>2012-04-08T21:14:43.683+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">erlang</category><category domain="http://www.blogger.com/atom/ns#">general</category><title>Erlang y WebChats (I)</title><description>&lt;span style="font-weight: bold; "&gt;[INTRODUCCIÓN]&lt;/span&gt;&lt;br /&gt;¿Sabes esta sensación que te recorre el cuerpo cuando te miras a los ojos con otra persona y estás seguro de que es tu alma gemela, de que has encontrado el amor de tu vida, y que no quieres mas que pasar el resto de tu vida con ella?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; "&gt;Pues yo no.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Pero supongo que algo parecido me ha pasado con Erlang. Bromas aparte. Es un lenguaje de programación que me ha encantado y al que le pienso dedicar muchas horas en los próximos meses. No se si ha sido amor a primera vista, o que simplemente me pilla en un momento en el que me molan las cosas chungas, extrañas y muy diferentes.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; "&gt;[PROBLEMA]&lt;/span&gt;&lt;br /&gt;Os explico de donde viene todo esto.  Resulta a través de &lt;a href="http://highscalability.com/" style="font-weight: normal; "&gt;highscalability.com&lt;/a&gt; acabé en una página del blog de What'sApp[1] en donde pone algo tal que así:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-weight: normal; "&gt;[...] Over the past few months we have been making a lot of improvements to  our servers to increase the performance, uptime and scalability. Today  we have tuned some knobs, shifted some traffic around &lt;span style="font-weight: bold;"&gt;and achieved 1  million established tcp sessions on a single machine&lt;/span&gt; [...] For those curious how we did it, the technology on the backend is simple: FreeBSD + Erlang [...]&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold; "&gt;Un millón de conexiones TCP. En una sola máquina ¡Wow!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Justo cuando lo leí me entró muchísima de curiosidad por el tema. Las únicas pistas que daban eran FreeBSD (SO que Unix-like, que ya he probado en casa alguna vez) y.... Erlang. ¿Qué es Erlang? Pues de la wikipedia[2] sacamos (y marco las partes que me llamaron la atención):&lt;br /&gt;&lt;blockquote style="font-weight: normal; "&gt;&lt;br /&gt;&lt;b&gt;Erlang&lt;/b&gt; es un lenguaje de &lt;span class="mw-redirect"&gt;programación concurrente&lt;/span&gt;. El subconjunto de programación secuencial de Erlang es un &lt;span style="color: rgb(0, 0, 102); font-weight: bold;"&gt;lenguaje funcional&lt;/span&gt;, con evaluación estricta, asignación única, y tipado dinámico. Fue diseñado en la compañía Ericsson para realizar &lt;span style="color: rgb(0, 0, 102); font-weight: bold;"&gt;aplicaciones distribuidas, tolerantes a fallos&lt;/span&gt;, soft-real-time y de &lt;span style="color: rgb(0, 0, 102); font-weight: bold;"&gt;funcionamiento ininterrumpido&lt;/span&gt;. &lt;span style="color: rgb(0, 0, 102); font-weight: bold;"&gt;Proporciona el cambio en caliente de código de forma que éste se puede cambiar sin parar el sistema.&lt;/span&gt; Originalmente, Erlang era un lenguaje propietario de Ericsson, pero &lt;span style="color: rgb(0, 0, 102); font-weight: bold;"&gt;fue cedido como software de código abierto en 1998&lt;/span&gt;.&lt;/blockquote&gt;&lt;br /&gt;Bueno, suena genial. Pues solo con esta información, o sea, sabiendo que WhatsApp había conseguido tener 1M de conexiones TCP en una misma máquina, y viendo mas o menos las caraterísticas principales de Erlang me dije: &lt;span style="font-weight: bold; color: rgb(255, 0, 0); "&gt;Si ellos han podido, yo también puedo.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; "&gt;[NUDO]&lt;/span&gt;&lt;br /&gt;Umm.... si lo piensas así en frio puedes decir: cágate, lorito. Y entonces me comentarías:&lt;br /&gt;&lt;span style="font-weight: normal; color: rgb(0, 0, 102); "&gt;- A ver, Jan. No sabes  cuantos empleados tiene What'sApp. Ni la pasta que manejan. Ni los  cracks que puedan tener contratados. Ni muchas otras cosas que pueden influir en el éxito de un proyecto así.... ¿No crees que te estás pasando un poquitín?&lt;/span&gt;&lt;br /&gt;Y yo te voy a contestar:&lt;br /&gt;&lt;span style="font-weight: normal; color: rgb(0, 0, 102); "&gt;- Pues no. Ellos   han conseguido hacer un millón de conexiones TCP's a una sola máquina. Y si ellos pueden, yo también. Y punto.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; "&gt;[PRESENTACIÓN DEL PROBLEMA/EJECRCICIO]&lt;/span&gt;&lt;br /&gt;Bien. Entonces necesito pensar en un proyectito que sea chulo, y con el que aprender Erlang. A la vez tiene que ser algo lo suficientemente simple como para que el problema no me sobrepase al inicio, pero que lo pueda ir complicando bastante a medida que vaya aprendiendo. Y, ¿en qué he pensado? Pues en un &lt;span style="color: rgb(0, 0, 102); font-weight: bold; "&gt;Web Chat&lt;/span&gt;!&lt;br /&gt;&lt;br /&gt;¿Que qué es un web chat? Pues hombre,  algo como "&lt;span style="font-weight: normal; font-style: italic; "&gt;el chat de faceboo&lt;/span&gt;k" ( ¬¬' así seguro que todo el mundo lo entiendea).&lt;br /&gt;&lt;br /&gt;Pues nada, la gracia es hacer un WebChat que soporte &lt;span style="font-weight: normal; font-style: italic; "&gt;mucha carga&lt;/span&gt;. Se tendrá que desarollar tanto la parte cliente (HTML+CSS+JS), como el servidor web (en Erlang), así como proceso de chat en si mismo (en Erlang también) y el posible acceso a datos.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; "&gt;¿El objetivo cuál es?&lt;/span&gt; Pues conseguir un servidor de chat que soporte mucha carga. De momento me conformaré con tener 10.000 usuarios funcionando al mismo tiempo (problema C10K[3]). Después intentaremos mejorar lo posible para llegar a 100K usuarios, y si no veo muy negro el tema, el &lt;span style="font-weight: bold; "&gt;objetivo final será conseguir 1M de usuarios&lt;/span&gt; (conexiones TCP al mismo tiempo) contra una misma máquina y obviamente que puedan hablar de manera flúida entre ellos y demás.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; "&gt;[RETO]&lt;/span&gt;&lt;br /&gt;Cagonlaputa. Resulta que los de WhatsApp me están retando. Seguro que lo han hecho aposta. Han publicado un nuevo post en el blog[4] titulado "1 million is so 2011". El artículo dice:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-weight: normal; "&gt;Happy 2012 everyone!&lt;br /&gt;A few months ago we published a blog post that talked about our servers doing 1 million tcp connections on a single box[1].&lt;br /&gt;&lt;br /&gt;Today we have an update for those keeping score at home: &lt;span style="font-weight: bold; color: rgb(0, 0, 102);"&gt;we are now able  to easily push our systems to over 2 million tcp connections&lt;/span&gt;!&lt;/blockquote&gt;&lt;br /&gt;Vale. Ya está. Si ellos han conseguido 2M de conexiones TCP en una misma máquina, des de luego que yo puedo conseguir 1M. En el mismo artículo también comparten información sobre lo que ellos entienden por &lt;span style="font-weight: normal; font-style: italic; "&gt;una misma máquina&lt;/span&gt; y..... bueno.... ejem&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;blockquote style="font-weight: normal; "&gt;&lt;code&gt;hw.machine: amd64&lt;br /&gt;&lt;/code&gt;&lt;code&gt;hw.model: Intel(R) Xeon(R) CPU           X5675  @ 3.07GHz&lt;br /&gt;&lt;/code&gt;&lt;code&gt;hw.ncpu: &lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;24&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;code&gt;hw.physmem: &lt;span style="color: rgb(255, 0, 0); font-weight: bold;"&gt;103&lt;/span&gt;062118400&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;code style="font-weight: normal; "&gt;¡¡¡Alaaaaaa!!! ¡Vaya maquinón! &lt;span style="font-weight: bold;"&gt;24 cores a 3.07GHz cada uno, y 103GB de memória RAM&lt;/span&gt;. ¡Trabajar así da gusto! Ya veremos si yo puedo acercarme o no... esto no me desanima, sino que hace que el reto sea mejor =)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span style="font-weight: bold; "&gt;[DESENLACE]&lt;/span&gt;&lt;span style="font-weight: normal; font-style: italic; "&gt; &lt;span style="font-size:85%;"&gt;(Hay desenlace porque a mi me contaron en el cole que tenía que haber siempre una presentación-nudo-desenlace)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Pues nada, que próximamente vendrán toda una serie de entradas sobre el tema. Aprender Erlang, ver sus cosas buenas y sus cosas malas, enlazar un motón de documentación útil, ver algunos ejercicios propuestos, ver qué es OTP, ver el enfoque que le damos al tema del WebChat, los benchmarks que van saliendo, las mejoras que se hacen y demás. Lo más seguro que el proyecto acabe siendo publicado en un repositorio de github/bitbucket con una licencia OpenSource ( mi primer proyecto OpenSource!! =) )&lt;br /&gt;&lt;br /&gt;¿Que te mola el rollo? pues sigue el blog y las entradas que voy publicando. Te van a gustar. ¿Que no te mola?, no lo leas; me la suda[5].&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Muy señores míos, un saludo!!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: normal; font-size: 78%; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: normal; font-size: 78%; "&gt;(haré como los de What's App, que queda super molón)&lt;/span&gt;&lt;br /&gt;P.S. - Ahora mismo no busco trabajo pero las ofertas siempre son bienvenidas. Si estás interesado en contratarme, envia información de algún proyecto chulo a inedit00 [2] gmail [.] com. &lt;span style="font-weight: normal; font-size: 78%; "&gt;(Yo también busco becarias para hacer summer-interships ;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;[1]: &lt;a href="http://blog.whatsapp.com/index.php/2011/09/one-million/" style="font-weight: normal; "&gt;http://blog.whatsapp.com/index.php/2011/09/one-million/&lt;/a&gt;&lt;br /&gt;[2]: &lt;a href="http://es.wikipedia.org/wiki/Erlang" style="font-weight: normal; "&gt;http://es.wikipedia.org/wiki/Erlang&lt;/a&gt;&lt;br /&gt;[3]: &lt;a href="http://www.kegel.com/c10k.html" style="font-weight: normal; "&gt;http://www.kegel.com/c10k.html&lt;/a&gt;&lt;br /&gt;[4]: &lt;a href="http://blog.whatsapp.com/index.php/2012/01/1-million-is-so-2011/" style="font-weight: normal; "&gt;http://blog.whatsapp.com/index.php/2012/01/1-million-is-so-2011/&lt;/a&gt;&lt;br /&gt;[5]: &lt;a href="http://inedit00.blogspot.com/2009/09/mi-primera-vez.html" style="font-weight: normal; "&gt;http://inedit00.blogspot.com/2009/09/mi-primera-vez.html&lt;/a&gt;&lt;div style="font-weight: normal; "&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Post siguiente&lt;/b&gt;: &lt;a href="http://inedit00.blogspot.com.es/2012/03/erlang-ii.html"&gt;Erlang (II) Aprendiendo lo básico&lt;/a&gt;&lt;/div&gt;</description><link>http://inedit00.blogspot.com/2012/03/erlang-y-webchats-i.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-4156385090009082218</guid><pubDate>Sun, 04 Mar 2012 10:46:00 +0000</pubDate><atom:updated>2012-03-04T11:52:01.814+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">tips</category><title>Problemas con el ratón en ioquake3</title><description>Tengo un problema en mi Lenovo Think Pad X201 cuando intento jugar al ioquake3. Resulta que cuando abres el juego, el cursor aparece en la mitad de la pantalla.&lt;br /&gt;Cuando, cuando mueves el cursor, todo va OK. Pero a los 5 segundos o eso, el cursor se vuelve a situar en el centro de la pantalla otra vez. Y así cada 5 segundos. Obviamente es imposible jugar normalmente. No se a que es debido, pero si que se la solución: antes de ejecutar el binario de ioquake3 teneis que ejecutar:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;$ export SDL_VIDEO_X11_DGAMOUSE=0&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Un saludo!</description><link>http://inedit00.blogspot.com/2012/03/problemas-con-el-raton-en-ioquake3.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-222639620297699424</guid><pubDate>Thu, 01 Mar 2012 09:16:00 +0000</pubDate><atom:updated>2012-03-01T10:38:42.508+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">out of topic</category><title>[fun] Se finí</title><description>Muy señores míos, hoy es fiesta en algunos lugares de España. Para mi es el primer día libre que disfrutaré de unas "vacaciones" que durarán los próximos 6 meses. Ayer, después de 3 días muy intensos que han parecieron un parto de un rinoceronte (sisi, con cuerno y todo), acabé el trabajo dejando todas las cosas posibles listas. Los últimos días, haciendo horas extras (por amor al arte)  y jornadas de 11 horas, todavía me llamaba el jefe a última hora para decirme "si me podía mirar esto y lo otro" =)&lt;br /&gt;&lt;br /&gt;En fin.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ya está. He sobado 12 horas y ya estoy listo para &lt;s&gt;tocarme los cojones durante 6 meses&lt;/s&gt; disfrutar de estas vacaciones merecidas. Estoy viendo infinitas horas de programación, proyectitos frikis, fiestas con los amigos, salir de marcha, cenas, paseos por la ciudad Condal, algún que otro viaje por estos mundos de dios y en definitiva disfrutar de la vida y ser feliz. Lo normal, vamos.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Como nota divertida os quiero dejar con una imagen muy curiosa. Algo que cuando te lo encuentras no sabes si descojonarte o volarte la cabeza. Obviamente me descojoné, ya que las cosas nos las tenemos que tomar siempre por el lado positivo. El programa protagonista es Microsoft Bussines Solutions Navision versión  3.7. Creo que el nombre en clave del proyecto en Microsoft era Super-Mega-Truño-Brutal-Anal-Coprofagicalmente-Fatal. Bueno, pues de mientras estás metido en el código, buscando un error tope chungo que no llegas a resolver, vas y te encuentras una función con este nombre:&lt;br /&gt;&lt;br /&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4pk55gn5wCePK3vpkvQpO2_y6bR6fbE08zpygfL51p6lzdQRXiLd9-q06SBFt0h_5qBmh6KyzsEnzSvl-Ky8q5P998D4QPEJ_mnez8NZH4sAftCzmFxUXl81rGcUh4siVCCWu6QCUOSs/s1600/CorregirDesastre.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 250px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4pk55gn5wCePK3vpkvQpO2_y6bR6fbE08zpygfL51p6lzdQRXiLd9-q06SBFt0h_5qBmh6KyzsEnzSvl-Ky8q5P998D4QPEJ_mnez8NZH4sAftCzmFxUXl81rGcUh4siVCCWu6QCUOSs/s400/CorregirDesastre.png" alt="" id="BLOGGER_PHOTO_ID_5714859567481795826" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgS6gvqcpgcVnNG1FOZxbapaltxqU0BY-XNH2klgy-45dnhPP1623SzwqOAl_LNEdBfFtHoyelAhizjbXK1GuFAU91FWKTDZqhyphenhyphenFfCdqsRTueRRjAEX8JQv2rzna2dcgZDfVwiqlEK8vx4/s1600/Screenshot2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 224px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgS6gvqcpgcVnNG1FOZxbapaltxqU0BY-XNH2klgy-45dnhPP1623SzwqOAl_LNEdBfFtHoyelAhizjbXK1GuFAU91FWKTDZqhyphenhyphenFfCdqsRTueRRjAEX8JQv2rzna2dcgZDfVwiqlEK8vx4/s400/Screenshot2.png" alt="" id="BLOGGER_PHOTO_ID_5714859699271428914" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;jajajajajajajajajajajajajajajaja! No te echaré de menos, Navision. Hazme caso que no ;)</description><link>http://inedit00.blogspot.com/2012/03/fun-se-fini.html</link><author>noreply@blogger.com (inedit00)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4pk55gn5wCePK3vpkvQpO2_y6bR6fbE08zpygfL51p6lzdQRXiLd9-q06SBFt0h_5qBmh6KyzsEnzSvl-Ky8q5P998D4QPEJ_mnez8NZH4sAftCzmFxUXl81rGcUh4siVCCWu6QCUOSs/s72-c/CorregirDesastre.png" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-1488852216317284328</guid><pubDate>Sat, 18 Feb 2012 14:43:00 +0000</pubDate><atom:updated>2012-02-18T16:20:03.609+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">red</category><title>Puertos abiertos en el router: mala idea.</title><description>&lt;span style="font-weight: bold;"&gt;[Introducción chorra]&lt;/span&gt;&lt;br /&gt;Juer, vaya día. Estoy tan tranquilo hoy haciendo unas pruebicas con sockets TCP en mi red local, trabajando con el wireshark capturando los paquetes resultantes para ver si, haciendo un par de putadas a una conexión TCP, puedo llegar a romper algo. Nada, intentando explotar una idea que tuve hace dos días y viendo si dá para un post o no. Hasta aquí todo normal.&lt;br /&gt;&lt;br /&gt;Resulta que en una de estas he encendido el Transmission ( http://www.transmissionbt.com ), para el que no lo sepa es un cliente de BitTorrent. Si no sabes que es BitTorrent dale &lt;s&gt;&lt;a href="http://www.sesamestreet.org/"&gt;aquí&lt;/a&gt;&lt;/s&gt;  &lt;a href="http://es.wikipedia.org/wiki/BitTorrent"&gt;aqui&lt;/a&gt; . Para la gente con poca memória: P2P. Intercambio de ficheros. ¿Te suena ya?&lt;br /&gt;&lt;br /&gt;Bien. Voy a Edit&amp;gt;Preferences&amp;gt;Network&amp;gt;Test Port. "&lt;span style="font-weight: bold;"&gt;Port closed&lt;/span&gt;". Genial. Tendré que crear una regla en el router.&lt;br /&gt;&lt;br /&gt;Voy a la configuración del router, veo que ya hay una regla creada para exactamente esto, pero en una IP que no es la mia (es la de otro ordenador de casa, que ahora mismo está apagado). Pos fale. No problemo. Le digo que todo lo que venga por el puerto &lt;span style="color: rgb(51, 204, 0);"&gt;61415&lt;/span&gt; me lo mande a mi IP local: 192.168.1.35. Pongo una regla en la configuración del cortafuegos de mi portátil para que accepte conexiones entantes por el puerto &lt;span style="color: rgb(51, 204, 0);"&gt;61415&lt;/span&gt;. La regla es así:&lt;br /&gt;&lt;br /&gt;iptables -A INPUT -p TCP -m state --state NEW --dport &lt;span style="color: rgb(51, 204, 0);"&gt;61415&lt;/span&gt; -j ACCEPT&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Nótese que el puerto por "defecto" es el &lt;span style="color: rgb(255, 102, 0);"&gt;51413&lt;/span&gt;, pero como ya está configurado para que lo use otra máquina en mi red, yo estoy usando el &lt;span style="color: rgb(51, 204, 0);"&gt;61415&lt;/span&gt; (puerto que he elegido al tuntún). Pruebo otra vez: Edit&amp;gt;Preferences&amp;gt;Network. Cambio el puerto del &lt;span style="color: rgb(255, 102, 0);"&gt;51413&lt;/span&gt; al &lt;span style="color: rgb(51, 204, 0);"&gt;61415&lt;/span&gt;. Le doy a &lt;span style="font-style: italic;"&gt;Test Port:&lt;/span&gt; "&lt;span style="font-weight: bold;"&gt;Port open&lt;/span&gt;". Genial, ahora esto irá chuscado. Voy a por algo para picar (esto de abrir puertos hace que a uno le entre hambre). Cuando vuelvo la descarga ya está completada. Genial. Apago el Transmission, me pongo algo de música, pongo enmarcha el Wireshark para seguir haciendo pruebas y.... WTF!!!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[Paquetes, Paquetes Everywhere]&lt;/span&gt;&lt;br /&gt;Joder, macho. Aún habiendo cerrado el Transmission hay muchísimo tráfico que viene de Internet hacia mi máquina. Pero a saco. Unos 3-4 requests por segundo.&lt;br /&gt;&lt;br /&gt;Todas las peticiones son paquetes TCP tipo SYN. O sea, que des de Internet quieren establecer una conexión con mi máquina. Miro el puerto de destino de estas conexiones y es el &lt;span style="color: rgb(51, 204, 0);"&gt;61415&lt;/span&gt;. Mi ordenador responde a cada una de ellas con un paquete TCP tipo RST, que les dice "ummm.... pos va a ser que no", ya que no tengo ningún servicio escuchando en este puerto.&lt;br /&gt;&lt;br /&gt;Vale, tate. &lt;span style="font-weight: bold;"&gt;Esto es lógico&lt;/span&gt;. Hace un momento, cuando tenía el Transmission encendido la gente se conectaba a mi máquina para pillar archivos. He cerrado la aplicación de Transmission, pero esto es algo que la gente de Internet no sabe, por lo que intentan conectarse igualmente a mi PC para pillar ficheros (por esto mandan un TCP-SYN). Mi portátil como no tiene ningún programa escuchando en el 61414, contesta las peticiones con un TCP-RST diciendo... lo siento, no hay nada a lo que te puedas conectar (de esto se encarga el kernel). O sea, esto es normal, y no hay nada malo en que intenten conectarse a mi máquina sin conseguirlo. Esto te puede llegar a quitar bastante ancho de banda, pero bueno, supongo después de un rato el número de requests va disminuyendo hasta que finalmente pare.&lt;br /&gt;&lt;br /&gt;Claro, yo quiero seguir haciendo pruebas con el wireshark, pero con tanto "ruido" no hay quién trabaje. Total, que me voy al router y borro la regla de redirección de puerto &lt;span style="color: rgb(51, 204, 0);"&gt;61415&lt;/span&gt; hacia mi máquina. A ver si ahora puedo trabajar tranquilo.&lt;br /&gt;&lt;br /&gt;Recordemos que ya tenía otra regla en el router. La regla dice que redirija todo el tráfico al puerto &lt;span style="color: rgb(255, 102, 0);"&gt;51413&lt;/span&gt; a la IP 192.168.1.33 (otro host de mi red, ahora mismo apagado). No la he modificado porque quiero que la 192.168.1.33 siga pudiendo usar el Transmission sin cambiar la configuración.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[ARP-FLOOD]&lt;/span&gt;&lt;br /&gt;Pongo enmarcha el wireshark otra vez. Fuck. Ahora hay alguien que me está inundando la puta red de paquetes ARP. Que majos todos.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4z4RfitsPmUzaJcW6gCMS-sDGcy5RAJCyNU260leq-NPncPTcEnq7wZOneDh7O-JYdJ942riXNBXDZwzNn7PdHRR5XBM6fPmbTFJi8suRpCmlXZ3m83zw4lLCTG8KOE2l7bMCDXZauks/s1600/arp.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 580px; height: 269px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4z4RfitsPmUzaJcW6gCMS-sDGcy5RAJCyNU260leq-NPncPTcEnq7wZOneDh7O-JYdJ942riXNBXDZwzNn7PdHRR5XBM6fPmbTFJi8suRpCmlXZ3m83zw4lLCTG8KOE2l7bMCDXZauks/s400/arp.png" alt="" id="BLOGGER_PHOTO_ID_5710489335431805490" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Veamos, el router (192.168.1.1) pregunta quién tiene la IP 192.168.1.33, mediante paquetes ARP lanzados casi cada segundo. Pues vaya: &lt;span style="font-weight: bold;"&gt;NADIE TIENE ESA IP&lt;/span&gt;; es un host en mi red que ahora mismo está apagado, normal que nadie conteste. Pero ¿por qué el router intenta descubrir quién es 192.168.1.33? Quiero decir.. esta máquina ha estado parada durante días. &lt;span style="font-weight: bold;"&gt;¿Qué tráfico tiene que ir a una máquina apagada hace días? ¿Quién quiere ponerse en contacto con una máquia apagada?&lt;/span&gt; WTF!&lt;br /&gt;&lt;br /&gt;Pues alguien que esté usando BitTorrent y quiera un fichero que cree que yo tengo. Parece que algún hijo de delfín daltónico y chimpanzé fitofílico ha decidido hacer conexiones contra mi IP pública, al puerto &lt;span style="color: rgb(255, 102, 0);"&gt;51413&lt;/span&gt;. Pero, ¿Por quéeee y para qué? Vale que este sea el puerto por defecto de Transmission, pero &lt;span style="font-weight: bold;"&gt;yo hoy no lo he usado para nada&lt;/span&gt;. Yo siempre he estado usando el &lt;span style="color: rgb(51, 204, 0);"&gt;61415&lt;/span&gt;. ¿Con que derecho intenta acceder al puerto &lt;span style="color: rgb(255, 102, 0);"&gt;51413&lt;/span&gt;? o sea.... ¿qué espera encontrar? Esto parece una mala implementación de un cliente de BitTorrent, o alguna comprovación que harán algunos servidores de torrents para comprobar si, además del puerto &lt;span style="color: rgb(51, 204, 0);"&gt;61415&lt;/span&gt;, también tenemos abierto el &lt;span style="color: rgb(255, 102, 0);"&gt;51413&lt;/span&gt;, digo yo. No lo sé, pero la verdad que no me mola mucho el tema.&lt;br /&gt;&lt;br /&gt;Lo que está pasando, es que como tengo una regla en el router que dice "redirígeme todo el tráfico que venga al puerto &lt;span style="color: rgb(255, 102, 0);"&gt;51413&lt;/span&gt; a la IP 192.168.1.33", el router la palica siempre. Si o si. Y claro, para poder mandarle tráfico entrante al host 192.168.1.33 necesita saber primero quién es éste host (obtener la dirección MAC, para los menos entendidos en tema de ARP). Y es por esto que está mandando paquetes ARP a SACO en toda mi red. De echo, manda un paquete ARP por cada petición que le llega al puerto &lt;span style="color: rgb(255, 102, 0);"&gt;51413&lt;/span&gt;. Una de las características de ARP es que son paquetes que se mandan a &lt;span style="font-weight: bold;"&gt;broadcast&lt;/span&gt;. &lt;span style="font-weight: bold;"&gt;O sea que lo reciben TODOS los hosts de mi red&lt;/span&gt;. Fuck. Obviamente como ninguno de ellos es 192.168.1.33, todo el mundo descarta el paquete y andando. Pero bueno, es un desperdicio de ancho de banda y no me mola el rollo.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[Cómo ver el tráfico que recibiría 192.168.1.33 en caso de estar encendido]&lt;/span&gt;&lt;br /&gt;Pues como me da pereza infinita ir a encender el host 192.168.1.33, poner el wireshark y demás, vamos a ver el tráfico que recibiría este host ahora mismo des de mi portatil:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 0, 153);"&gt;$ sudo ifconfig eth0:2 192.168.1.33&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ala. Hecho. Ahora mi portátil tiene la IP 192.168.1.35 y la 192.168.1.33 en una subinterfície (conocíais lo de las subinterfícies, verdad? ;) ). Mi host se indentifica como 192.168.1.33 y responde las peticiones ARP. Miro el wireshark y ala! Estamos como al principio: Hosts de Internet intentan establecer una conexión con mi equipo, y mi equipo contestando que "no, no tengo ningún servicio escuchando en el puerto donde me estás haciendo la petición. RST! RST! RST!".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDDoXjgE7zRYdzvZyBFE_K-_v4sH6yUysJRYkdq6sfwCPbcpfQfsrwoi8KaHl0DTEPr8b_2EdGjLVC3qR6hk8QhroyqQYlqTUV6qBLY_XfFusPRE6A0RfUAvT7ycBdXFhZuzSqj71dMqk/s1600/rst.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 600px; height: 244px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDDoXjgE7zRYdzvZyBFE_K-_v4sH6yUysJRYkdq6sfwCPbcpfQfsrwoi8KaHl0DTEPr8b_2EdGjLVC3qR6hk8QhroyqQYlqTUV6qBLY_XfFusPRE6A0RfUAvT7ycBdXFhZuzSqj71dMqk/s400/rst.png" alt="" id="BLOGGER_PHOTO_ID_5710490547662390018" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[¿Cómo solucionar el problema?]&lt;/span&gt;&lt;br /&gt;Bueno, no parece muy difícil llegar a la conclusión de que &lt;span style="font-weight: bold;"&gt;los puertos&lt;/span&gt;, si están &lt;span style="font-weight: bold;"&gt;cerrados&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;mejor&lt;/span&gt;. En caso de usar protocolos P2P, en necesario abrir los puertos para que el tema vaya flúido. Yo a partir de ahora voy a abrir/cerrar los puertos de mi router cada vez que me quiera descargar algo. No me mola que si a alguien le apetece enviarme un paquete al puerto por defecto de BitTorrent, esto se traduzca en chorrocientos paquetes ARP en mi red. Vale, tampoco hacen daño, pero no los quiero ahí.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[Notas finales]&lt;/span&gt;&lt;br /&gt;En este post tampoco cuento nada extraño ni sofisticado. Todo funciona como es debido, y si se piensa bien, no hay problema de que las cosas funcionen así. Aún así para mi ha supuesto la primera prueba que tengo que respalde la afirmación que todo el mundo hace diciendo: "los puertos del router mejor cerrados!". Y tienen razón. Ahora veo que me estoy provocando ARP-Flooding en mi propia red, en el caso de que el host de destino esté apagado. O que en caso de que esté encendido, que el host tenga que responder a peticiones ( ni que sea para decir RST ) que provinenen de Internet. Mucho mejor que se encargue de hacer todo esto el router, y deje mis hosts de la LAN en paz.&lt;br /&gt;&lt;br /&gt;También he vuelto a ver claro esto de que Internet es la selva, y que muchas veces el router nos hace de separación entre nuestra tranquila/estable/fiable red local, y la locura de Internet.&lt;br /&gt;&lt;br /&gt;Un saludo, Jan.</description><link>http://inedit00.blogspot.com/2012/02/puertos-abiertos-en-el-router-mala-idea.html</link><author>noreply@blogger.com (inedit00)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4z4RfitsPmUzaJcW6gCMS-sDGcy5RAJCyNU260leq-NPncPTcEnq7wZOneDh7O-JYdJ942riXNBXDZwzNn7PdHRR5XBM6fPmbTFJi8suRpCmlXZ3m83zw4lLCTG8KOE2l7bMCDXZauks/s72-c/arp.png" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-5854437164585176687</guid><pubDate>Fri, 17 Feb 2012 18:05:00 +0000</pubDate><atom:updated>2012-02-18T01:59:05.231+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">linux</category><category domain="http://www.blogger.com/atom/ns#">red</category><title>TCP Sockets: TIME_WAIT y los puertos efímeros son poco amigos</title><description>Hoy vamos a explicar un poco qué es TIME_WAIT y cómo puede darte por culo un rato largo.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[INTRODUCCIÓN]&lt;/span&gt;&lt;br /&gt;Todos sabemos que las conexiones TCP ( capa 4 en modelo OSI, también llamada capa de transmisió de datos ) tienen estados. Umm... bueno, igual no todos lo sabemos. Refresquemos un poco qué son esto de los estados TCP antes de empezar.&lt;br /&gt;&lt;br /&gt;TCP establece la conexión a tres vías[1]. Cuando se intenta establecer la conexión del host A al host B, el host A manda un paquete tipo SYN al host B. La conexión pasa a estar en un estado SYN_SENT. Cuando el host B le contesta con un paquete ACK-SYN, la conexión para a un estado llamado SYN_RECV. Cuando la conexión por fin se establece pasa a estado ESTABLISHED. También hay el estado LISTEN, que es el estado que tienen servicios tales como apache, memcached o sshd, esperando nuevas conexiones. Total, con todo esto nos tenemos que quedar con la copla de que &lt;span style="font-style: italic;"&gt;una conexión TCP pasa por diferentes estados desde que se establece hasta que se cierra.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;La lista completa de estados se puede ver fácilmente haciendo un &lt;span style="font-style: italic;"&gt;man netstat&lt;/span&gt;, y buscando el apartado &lt;span style="font-style: italic;"&gt;State.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Bien, entonces tenemos que los dos estados mas comunes son: ESTABLISHED conexiones establecidas y LISTEN, en el caso de que estemos en un servidor con varios servicios activos. Para ver una lista de las conexiones abiertas en nuestra máquina podemos hacer un:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;$ sudo netstat -pan --tcp | less&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[SUPOSICIÓN]&lt;/span&gt;&lt;br /&gt;Si ejecuto un script muy simple que haga peticiones HTTP contra mi servidor web local SUPONGO que no habrá ningún problema (jeje, los cojones). Tengo un servidor Apache escuchando en el puero 80 en localhost. Problemos a ejecutar el siguiente comando en 5 consolas diferentes.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;$ while true; do curl localhost; done&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;El comando "curl" abre una conexión TCP, hace una petición HTTP, se le devuelve un resultado (que no nos importa lo mas mínimo, ahora mismo) y CIERRA LA CONEXIÓN TCP. O esto es lo que nosotros esperamos, vamos. Entiendo que tener 5 instancias del script haría que normalmente tuviese 5 conexiones en estado ESTABLISHED, pero esto, nunca debería ocasionar un problema a nivel de sistema.&lt;br /&gt;&lt;br /&gt;Hagamos la prueba. Ejecutamos cinco veces el script en consolas separadas, y en otra terminal ejecutamos:&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;&lt;br /&gt;$ sudo watch -n 0.5 'netstat -pan --tcp | grep ESTABLISHED | wc -l'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Pues efectivamente, nunca pasamos de 5 conexiones al mismo tiempo en estado ESTABLISHED pero... Umm.... pero al cabo de un minuto de estar ejecutando los scripts, el comando "curl" empieza a dar un error:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;curl: (7) Failed to connect to 127.0.0.1: Cannot assign requested address&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[PROBLEMA]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;WTF&lt;/span&gt;. A ver, tenemos tan solo 5 conexiones abiertas. El error del curl parece decirnos que no puede obtener un puerto de origen para establecer la conexión. Veamos porqué:&lt;br /&gt;Ejecutemos los scripts anteriores y pongamos un filtro diferente en el netstat:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;$ sudo netstat -pan --tcp | grep TIME_WAIT | wc -l&lt;/span&gt;&lt;br style="color: rgb(0, 0, 102);"&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;5329&lt;/span&gt;&lt;br style="color: rgb(0, 0, 102);"&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;$ sudo netstat -pan --tcp | grep TIME_WAIT | wc -l&lt;/span&gt;&lt;br style="color: rgb(0, 0, 102);"&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;13440&lt;/span&gt;&lt;br style="color: rgb(0, 0, 102);"&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;$ sudo netstat -pan --tcp | grep TIME_WAIT | wc -l&lt;/span&gt;&lt;br style="color: rgb(0, 0, 102);"&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;19348&lt;/span&gt;&lt;br style="color: rgb(0, 0, 102);"&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;$ sudo netstat -pan --tcp | grep TIME_WAIT | wc -l&lt;/span&gt;&lt;br style="color: rgb(0, 0, 102);"&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;21526&lt;/span&gt;&lt;br style="color: rgb(0, 0, 102);"&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;$ sudo netstat -pan --tcp | grep TIME_WAIT | wc -l&lt;/span&gt;&lt;br style="color: rgb(0, 0, 102);"&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;28214&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;COJONES! &lt;span style="font-weight: bold;"&gt;Por algún motivo estan quedando chorrocientos sockets abiertos en estado TIME_WAIT&lt;/span&gt;!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[QUÉ ES TIME WAIT]&lt;/span&gt;&lt;br /&gt;Ahora que nos hemos puesto un poco en matéria vamos a ver para que se usa el estado TIME_WAIT, y como puede llegar a ser un problema. De la definición del &lt;span style="font-style: italic;"&gt;man&lt;/span&gt; de nestat sacamos que:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;TIME_WAIT: The socket is waiting after close to handle packets still in the network.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Umm... según esto parece que la conexión no se cierra hasta que pase un tiempo para poder capturar los paquetes que se habían "perdido" por la red debido a posibles problemas de enrutamiento. Jummm... explicación algo escueta. Sobre todo porque no dice cuanto vamos a tener que esperar. Vamos a investigar un poquito más sobre el tema...&lt;br /&gt;&lt;br /&gt;El RFC 1122 en el apartado "Transport layer, TCP" [2] dice algo así como:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;When a connection is closed actively, it MUST linger in TIME-WAIT state for a time 2xMSL (Maximum Segment Lifetime).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Vaaaale. Ahora ya tenemos un poco mas de información. Resulta que tenemos que esperarnos 2xMSL antes de que una conexión pase de TIME_WAIT a CLOSED ( y se libere la conexión ). Genial. Y ahora... ¿Dónde coño puedo consultar el tamaño del Maximum Segment Lifetime? Pues ejecutando este comando:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;$ cat /proc/sys/net/ipv4/tcp_fin_timeout&lt;/span&gt;&lt;br style="color: rgb(0, 0, 102);"&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;30&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Que en mi máquina Debian me da un resultado de 30 segundos. En máquinas con Ubuntu el valor acostumbra a ser 60, en máquinas Solaris acostumbra a ser 120. Entonces parece ser que, en mi máquina, tardaré 2*MSL, o sea 2*30=60 segundos en liberar una conexión. El problema que hemos experimentado antes es que hay muchos sockets (conexiones) abiertas en estado TIME_WAIT. Cuando llegamos al límite de conexiones efímeras del sistema, el kernel nos dá un error diciendo "umm... me sabe mal, pero no me quedan puertos efímeros". Esto se traduce en el error que nos saca el "curl". O sea, no es problema del comando "curl" que vaya dejando conexiones abiertas, ya que si no tendríamos muchas conexiones en estado ESTABLISHED, y no es el caso. Tampoco es problema del kernel, ya que éste implementa el RFC 1122 como dios manda.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[PUERTOS EFÍMEROS]&lt;/span&gt;&lt;br /&gt;"Ei. Ei, espera. Cuando has empezado a hablar de puertos efímeros y toda esta mierda me he perdido. A ver si te explicas un poquito más, macho."&lt;br /&gt;Veamos. Cuando establecemos una conexión TCP con nuestro navegador a un servidor Web, necesitamos un puerto de origen [3]. Estos puertos, se conocen como puertos efímeros. El protocolo TCP necesita definir un puerto origen y un puerto destino. En nuestro ejemplo, el puerto destino será el 80 (servidor web), y el puerto origen será un puerto efímero. El Kernel nos asigna un puerto efímero automáticamente cuando establecemos una conexión nueva. Para ver el rango de puertos efímeros que tenemos definido podemos ejecutar:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;$ cat /proc/sys/net/ipv4/ip_local_port_range&lt;/span&gt;&lt;br style="color: rgb(0, 0, 102);"&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;32768   61000&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Si hacemos 61000-32768 nos dá 28232. Si os fijais, es un número muy parecido al número de sockets en estado TIME_WAIT que teníamos cuando ha empezado a petar todo. Esto es debido a que un &lt;span style="font-weight: bold;"&gt;socket en estado TIME_WAIT todavía es un socket activo&lt;/span&gt;. Es lo mismo como si estuviese en estado ESTABLISHED, por lo que está ocupando un puerto efímero. Si acumulamos muchos sockets en estado TIME_WAIT, vamos agotando los puertos efímeros. Cuando llegamos al límite y tenemos reservados *todos* los puertos efímeros, al kernel no le queda otra que devolver error cada vez que se quiere crear un socket nuevo. Bonito, verdad?&lt;br /&gt;&lt;br style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;[POSIBLES SOLUCIONES]&lt;/span&gt;&lt;br /&gt;Bueno, una de ellas pasa por aumentar el número de puertos efímeros del sistema. Esto se puede conseguir simplemente ejecutando:&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;$ sudo su - root&lt;/span&gt;&lt;br style="color: rgb(0, 0, 102);"&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;$ echo "1025 61000" &amp;gt; /proc/sys/net/ipv4/ip_local_port_range&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Hecho esto, ahora disponemos de 60K puertos efímeros y no solo 30K. En realidad esto no es una solución de nada. Simplemente tendremos que esperar 2 minutos y no 1 para que los procesos "curl" agoten el número de sockets. Estamos haciendo que el sistema aguante un poquito mas, pero ya está.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Otra solución parece que puede venir modificando el parámetro 2*MSL. Si disminuimos este valor del MSL, los sockets en estado TIME_WAIT deberían estar en este estado durante menos tiempo. El parámetro es ajustable mediante el comando comentado anteriormente:&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;$ sudo su -c 'echo 5 &amp;gt; /proc/sys/net/ipv4/tcp_fin_timeout'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Si probais de aplicar este cambio vereis que en realidad las conexiones en estado TIME_WAIT no se cierran a los 10 segundos como sería lo esperado (2*MSL; 2*5=10), sino que se siguien cerrando a los 60 segundos. Por qué ocurre esto? Simple. El valor "60 segundos" está hardcoded en el kernel de linux. Así de bonito. Si miramos el fichero /include/net/tcp.h línea 105 del kernel de línux veremos algo tal que así:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT state, about 60 seconds */&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A partir de línea 202 del fichero /net/ipv4/tcp_minisocks.c vereis que hace uso intensivo de la variable TCP_TIMEWAIT_LEN, justo en la sección donde define el estado TCP_TIME_WAIT al socket TCP. Por lo que &lt;span style="font-weight: bold;"&gt;modificar a través de las sysctls el parámetro "tcp_fin_timeout" no va a servir de un carajo&lt;/span&gt;. Ni 2*MSL ni pollas. Harcoded en el código. (Esto vulnera el RFC 1122 y la regla 2MSL? Si alguien lo sabe que por favor comente! Gracias )&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;La última solución, que dista mucho de ser algo perfecto pasa por activar el &lt;span style="font-style: italic;"&gt;tcp_tw_recycle&lt;/span&gt; y &lt;span style="font-style: italic;"&gt;tcp_tw_reuse.&lt;/span&gt; Ambas directivas son bastante peligrosas, y vulneran explícitamente el RFC 1122. No deberían usarse en entornos de producción o sin saber muy bien qué se está haciendo. La documentación que he encontrado al respecto es [4] y [5].&lt;br /&gt;&lt;br style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;TCP_TW_RECYCLE: It enables fast recycling of TIME_WAIT sockets. The default value is 0 (disabled). The sysctl documentation incorrectly states the default as enabled. It can be changed to 1 (enabled) in many cases. Known to cause some issues with hoststated (load balancing and fail over) if enabled, should be used with caution.&lt;/span&gt;&lt;br style="font-style: italic;"&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;$ echo 1 &amp;gt; /proc/sys/net/ipv4/tcp_tw_recycle&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;TCP_TW_REUSE: This allows reusing sockets in TIME_WAIT state for new connections when it is safe from protocol viewpoint. Default value is 0 (disabled). It is generally a safer alternative to tcp_tw_recycle&lt;/span&gt;&lt;br style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;Note: The tcp_tw_reuse setting is particularly useful in environments where numerous short connections are open and left in TIME_WAIT state, such as web servers. Reusing the sockets can be very effective in reducing server load.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;$ echo 1 &amp;gt; /proc/sys/net/ipv4/tcp_tw_reuse&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;O sea, usadlos, pero con mucho cuidado.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;La solución definitiva viene en forma de pregunta: &lt;span style="font-weight: bold;"&gt;¿Qué coño haceis creando 30K conexiones TCP en menos de un minuto, criaturas del Señor?&lt;/span&gt;&lt;br /&gt;Si habeis llegado aquí porque os habeis encontrado con el problema del TIME_WAIT en un servidor de producción cuando recibía bastante tráfico os tengo que decir algo que no os va gustar: &lt;span style="font-weight: bold;"&gt;algo estáis haciendo mal&lt;/span&gt;. En este caso no es suficiente con cerrar las conexiones a la BBDD, caches, o lo que sea cada, vez que se hace una consulta. La solución pasa por hacer pooling de conexiones y demás. &lt;span style="font-style: italic;"&gt;REAPROVECHA&lt;/span&gt;R conexiones. Pero bueno, esto es otra guerra que se sale del alcance de este post. Aún así para dudas, ruegos y preguntas teneis los comentarios. Intentaré ayudar hasta donde pueda/sepa.&lt;br /&gt;&lt;br /&gt;&lt;br style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;[ÚLTIMAS NOTAS]&lt;/span&gt;&lt;br /&gt;Nótese que este problema es provocado por la conjunción de crear muchas conexiones por parte de un CLIENTE (importante este punto) durante un periodo muy corto de tiempo. Esto hace que se acumulen muchos sockets abiertos (bueno, o no-cerrados, para ser mas exactos) en estado TIME_WAIT. Cuando se llega al punto que la suma de todos los sockets en dicho estado es igual al número de puertos efímeros de la máquina, el kernel no es capaz de crear sockets nuevos hasta que no se liberan recursos, devolviendo un error a cualquier proceso que intente crear una conexión nueva (nótese que las conexiones ya establecidas seguirán funcionando normalmente).&lt;br /&gt;&lt;br /&gt;Espero que les haya gustado el post. La zona de comentarios está disponible para hacer preguntas, o proponer soluciones alternativas al problema.&lt;br /&gt;&lt;br /&gt;Un saludo, Jan.&lt;br /&gt;&lt;br /&gt;[1] http://danred.wordpress.com/2009/09/28/establecimiento-de-conexion-tcp-de-3-vias/&lt;br /&gt;[2] http://www.rfc-editor.org/rfc/rfc1122.txt  página 87&lt;br /&gt;[3] Recordemos que un socket está formado por un IP Origen - Puerto Origen - IP Destino - Puerto Destino.&lt;br /&gt;[4] http://www.speedguide.net/articles/linux-tweaking-121&lt;br /&gt;[5] http://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt</description><link>http://inedit00.blogspot.com/2012/02/hoy-vamos-explicar-un-poco-que-es.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>30</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-4284906210669590159</guid><pubDate>Sun, 12 Feb 2012 18:25:00 +0000</pubDate><atom:updated>2012-02-17T19:10:29.686+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">seguridad</category><title>Wikipedia, querida. ¿Por qué no te preocupas por mi privacidad?</title><description>Lo veo y no me lo creo. Por Diox![1]...&lt;br /&gt;&lt;br /&gt;Página de login de la www.wikipedia.org. Se accede des del link que aparece en la parte superior derecha que reza algo así como &lt;span style="font-style: italic;"&gt;Log in / create account&lt;/span&gt;. Si nos fijamos en el tooltip de dicho botón pone: &lt;span style="font-style: italic;"&gt;You are encouraged to log in; however, it is not mandatory. [alt-shift-o]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Oh. Resulta que incluso tenemos un shortcut para ir a la página de login: alt-shit-o. Curioso.&lt;br /&gt;&lt;br /&gt;Pongo el nombre de usuario, pongo la contraseña y.... oh! Wait. Me fijo antes de darle al botón &lt;span style="font-style: italic;"&gt;Log in&lt;/span&gt; que no estoy en una página segura. &lt;span style="font-weight: bold;"&gt;O sea, que no estoy con HTTPS. ¿Será posible?&lt;/span&gt; Miro los opciones de la página dándole al logo de la wikipedia, justo a la izquierda de la URL en firefox y me dice: "&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;Your connection to this website is not encrypted&lt;/span&gt;". Mecagonlaputa.&lt;br /&gt;&lt;br /&gt;Le doy a "More information" y me encuentro con esto:&lt;br /&gt;&lt;br /&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhG7bAQjD6cx_8quphyO1X-0l1Z7NGIg2tyZiOL2R0oJ_vIQZWULNBQEBlJXfS7s1frAdgSUxuX2xjZ3RV85z-SYMsoaoUtAP1cwnNM04u-xendzLp4sI1T3FoBxEsggZXiKJp0Zv-gLRw/s1600/wikipedia.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 277px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhG7bAQjD6cx_8quphyO1X-0l1Z7NGIg2tyZiOL2R0oJ_vIQZWULNBQEBlJXfS7s1frAdgSUxuX2xjZ3RV85z-SYMsoaoUtAP1cwnNM04u-xendzLp4sI1T3FoBxEsggZXiKJp0Zv-gLRw/s320/wikipedia.png" alt="" id="BLOGGER_PHOTO_ID_5709755632600703506" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Jumm.... parece que está claro. La página no está cifrada. Bueno, como todavía tengo la esperanza de que la propiedad "action" del form vaya a una URL segura (esto es posible? tendré que probarlo[2]). Hago una prueba simple:&lt;br /&gt;&lt;br /&gt;Pongo enmarcha el "wireshark" capturando todo el tráfico. Le doy a "login" en la página de la Wikipedia y.... e voilá. Esto es lo que ha capturado el wireshark:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;POST /w/index.php?title=Special:UserLogin&amp;amp;&lt;span style="font-weight: bold;"&gt;action=submitlogin&lt;/span&gt;&amp;amp;type=login&amp;amp;returnto=Main+Page&amp;amp;campaign=ACP1 HTTP/1.1&lt;br /&gt;Host: en.wikipedia.org&lt;br /&gt;[...] # Borradas las demás cabezeras por no tener releváncia en este caso&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;wpName=jcarreras&amp;amp;wpPassword=ilovemiami&lt;/span&gt;&amp;amp;wpLoginAttempt=Log+in&amp;amp;wpLoginToken=c7b2dc6fc071c5fe3b6f96efb8ef6122&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Que bonito! Si señor! Un POST de toda la vida que contiene dos variables llamadas wpName y wpPassword. Todo viajando en claro a través de la red. Con dos cojones.&lt;br /&gt;&lt;br /&gt;Fijándome un poquito mas veo que justo debajo del login hay un apartado que pone: "&lt;span style="font-style: italic;"&gt;Secure you account&lt;/span&gt;". El primer punto pone: "&lt;span style="font-style: italic;"&gt;Consider logging in on the secure server.&lt;/span&gt;" y tiene un enlace que te lleva a la misma página pero usando HTTPS. Mi pregunta es: ¡¿por que carajo éste no es el modo de hacer login por defecto?! Un login que mande una contraseña en claro SIEMPRE debe ir a través de un canal cifrado/seguro. Siempre.&lt;br /&gt;&lt;br /&gt;Después continua tocando otros puntos sobre seguridad como:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;If your password only contains letters or only numbers [...] consider changing it.&lt;/span&gt; Para qué? Si el password viaja en cleartext?! No tiene importancia la longitud de la misma si la contraseña viaja en texto plano.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;To avoid becoming a victim of phishing, always verify that you are viewing Wikipedia's login page [...]&lt;/span&gt; Ummm... exactamente PARA ESTO sierve HTTPS y los certificados SSL. Aparte de cifrar todo el canal de información, verifican que el servidor és quién dice ser.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Do not give out your password to anyone&lt;/span&gt;. Jejeje, les falta decir: "nosotros lo haremos por tí, majo".&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Pues vaya, esto simplemente haciendo un MITM con arpspoof+tcpdump o con Ettercap directamente y, ale, regalando tu contraseña a toda la gente que se encuentra en tu red local! Yuhuuu! Felicidad!&lt;br /&gt;&lt;br /&gt;Un saludo, Jan.&lt;br /&gt;&lt;br /&gt;[1] http://www.frikipedia.es/friki/Diox&lt;br /&gt;[2] Me refiero poner en el &lt;span style="font-style: italic;"&gt;action&lt;/span&gt; de un &lt;span style="font-style: italic;"&gt;form&lt;/span&gt;, una url que sea algo así como &lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;http&lt;span style="color: rgb(255, 0, 0);"&gt;s&lt;/span&gt;&lt;/span&gt;://foo.bar/login&lt;/span&gt;</description><link>http://inedit00.blogspot.com/2012/02/wikipedia-querida-por-que-no-te.html</link><author>noreply@blogger.com (inedit00)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhG7bAQjD6cx_8quphyO1X-0l1Z7NGIg2tyZiOL2R0oJ_vIQZWULNBQEBlJXfS7s1frAdgSUxuX2xjZ3RV85z-SYMsoaoUtAP1cwnNM04u-xendzLp4sI1T3FoBxEsggZXiKJp0Zv-gLRw/s72-c/wikipedia.png" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-3622562792896414657</guid><pubDate>Sun, 05 Feb 2012 11:46:00 +0000</pubDate><atom:updated>2012-02-05T12:47:05.457+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">general</category><title>Fin de una época... AKA adiós trabajo, adiós</title><description>A finales de este mes también acabo en mi trabajo =).&lt;br /&gt;&lt;br /&gt;"Pobre Jan. ¿Te sacan? Puta crisis, afecta a todo el mundo..."&lt;br /&gt;Ummm... Pues no. No me sacan. Ni mucho menos. Os cuento.&lt;br /&gt;&lt;br /&gt;Resulta que a mi me encanta estudiar y aprender cosas nuevas. Acabé el Grado Superior de Administración de Sistemas Informáticos, hice las prácticas en eConcept y les molé. Me hicieron un contrato fijo, cobraba un suelo que no estaba mal y *aprendía un montón*. Esto para mí es lo más importante. Casi casi es lo que valoro más: aprender cosas nuevas. Esto es así porque: disfruto aprendiendo, me da un valor añadido, puedo ponerme nuevas metas, me mantengo al día y en definitiva todavía me considero un estudiante.&lt;br /&gt;&lt;br /&gt;En la empresa somos muy poquitos. 6 técnicos en total: 4 programadores y 2 de sistemas. Todos son unos cracks: tenemos a un ex-empleado de Microsoft, otro compañero a estado trabajando en el Centro de Supercomputación de Barcelona, un sysadmin que aparte de su trabajo habitual también da clases de CISCO CCNA, y más de uno en el equipo a recibido ofertas por parte de Google para que trabajen para ellos. Trabajar con gente así es una pasada, ya que aprendes muchísimo, se te contagia el interés por las cosas más complicadas o supuestamente difíciles y.... buffff, es genial. Y aunque sean unos técnicos increibles son todavía mejores personas. Ha sido una pasada estar con ellos. Esto es lo que voy a echar de menos.&lt;br /&gt;&lt;br /&gt;He estado en proyectos muy interesantes: telefonía de VozIP (con centralita propia y demás) haciendo todo el tema de tarificación y tarifas planas, así como prácticamente todo el backoffice para gestionar los clientes, extensiones, geográficos, etc... También me dieron un proyecto para mi solito sobre gestión de contratos de telefonía (VozIP, fija, móvil y ADSL) para que los comerciales puedan generar de manera electrónica los contratos en casa de los mismos clientes y mandarles el contrato rellenado y listo para firmar al email del cliente para que lo revisen cuando quieran. También he estado ayudando en el proyecto de www.nauticholidays.com haciendo un pequeño CMS, habilitar temas de SEO y me he estado encargando del mantenimiento del proyecto entero durante un par de meses. Todo muy chulo, la verdad.&lt;br /&gt;&lt;br /&gt;Bueno, en realidad no todo ha sido *tan* chulo. He tenido que hacer cosas menos agradables como encargarme de mantener una aplicación de facturación (Microsoft Navision, una versión del año de la Pepa) que fallaba (falla) mas que una escopeta de feria... pero bueno. Mejor nos quedamos con las cosas buenas. =)&lt;br /&gt;&lt;br /&gt;Básicamente me quedé en la empresa porque el tipo de trabajo era muy interesante, los compañeros eran geniales y sobretodo porque iba a aprender un montón. La otra opción era empezar la carrera de informática en la UPC de Barcelona. Lo planteé del siguiente modo: ahora trabajo, tendré experiència en el Mundo Real(tm), aprenderé un monton y ahorraré todo lo que cobre para poder ir a estudiar la carrera. Y esto he hecho.&lt;br /&gt;&lt;br /&gt;El caso es que en la empresa durante el primer año aprendía un montón de cosas cada semana. Era exagerado. Python, SQLAlchemy, CSS, JavaScript, el framework de desarollo (pylons), cosas de sistemas, el modelo MVC, bases de datos no relacionales (MongoDB), colas asíncronas (beanstalk), repositorios (primero bazar y después mercurial), desnormalización de datos, caches, procesos de deploy super-rápidos, Scrum.... La 'putada' de aprender tanto es que al final del primer año alcanzé lo que llamo la "zona de confort".&lt;br /&gt;&lt;br /&gt;Esta zona es peligrosa. Llegas a ella cuando empiezas a sentirte cómodo con todas las cosas nuevas que has ido aprendiendo. Llega un momento que ya sabes todo lo que necesitas para hacer tu trabajo de manera eficinente y solo de vez en cuando necesitas revisar la documentación o aprender algo nuevo. Esta zona no me gusta porque es aburrida. Aprender cosas nuevas mola. Aprendes cosas para poder trabajar. Cuando dejas de aprender lo único que haces es trabajar. Y yo todavía me considero un estudiante, no un trabajador. Tendré 40 años ( o mas ¬¬ ) para trabajar. Ahora que me gusta aprender: coño, tengo que aprovechar. O sea, esto es mi punto de vista. Para la empresa la "zona de confort" significa que tienen un trabajador que ya ha alcanzado el nivel de conocimientos que necesitan para que ocupe su puesto de trabajo sin necesidad de formarse o de ayuda externa, por lo que es ideal.&lt;br /&gt;&lt;br /&gt;Durante el segundo año he estado trabajando. Sin mas. Aprendiendo muy poquito, pero asentando los conocimientos adquiridos. Y ahorrando, ahorrando mucho. No ha sido tan divertido y emocionante como el primero, pero también ha estado bien. El caso es que ahora he conseguido tener un colchón de dinerito suficiente para estudiar mas o menos tres añitos en Barcelona, por lo que me he preguntado: ¿Por qué seguir trabajando?&lt;br /&gt;&lt;br /&gt;Y el tema ha estado claro. El simple hecho de tener esta duda hace que respuesta no pueda ser otra: me las piro. Entre esto y el hecho de que han habido un poco de lios familiares, un servidor se va a vivir a BCN dentro de un mesecito. Tendré 6 meses todos para mi, antes de que empiece la carrera de informática. Tengo ya un par de proyectitos personales pensados que me gustaría hacer y pienso estar con los amigos y familiares. Disfrutar la vida en general, así, por que si =)&lt;br /&gt;&lt;br /&gt;A quien ésto no le de envidia, es que no tiene alma, jeje ;)</description><link>http://inedit00.blogspot.com/2012/02/fin-de-una-epoca-aka-adios-trabajo.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-3621105502851735511</guid><pubDate>Sun, 05 Feb 2012 11:42:00 +0000</pubDate><atom:updated>2012-02-05T12:47:48.744+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">general</category><title>CISCO CCNA</title><description>El año pasado empecé el curso de CISCO CCNA, o sea Cisco Certified Networking Associate. Muy interesante, la verdad. Para el que no lo sepa la empresa CISCO es una multinacional norteamericana líder en el mercado de las redes (networking). Venden des de routers para hogares familiares ( los Lynksys, puede que tengas uno ), hasta el hardware que se utiliza para comunicar los diferentes continientes como Europa y América. O sea, el backbone de Internet funciona sobre hardware de CISCO. Tienen una gama de productos increíbles, y no sólo ofrecen productos, si no que también imparten formación. Hay lo que ellos llaman "la carrera de CISCO" que se basa en tres niveles con un curso principal en cada nivel, y otros 4 módulos de ampliación. Para verlo mas claramente tenemos el primer nivel que es el CCNA:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;CCNA&lt;/span&gt;: Curso principal, normalmente de unas 260 horas, es el que yo estoy haciendo. Incluye:&lt;ul&gt;&lt;li&gt;    Bloque 1- Aspectos básicos del networking: OSI, TCP/IP, direccionamiento, capa de enlace de datos/física, Ethernet, planificació de cableado, etc...&lt;/li&gt;&lt;li&gt;    Bloque 2 - Conceptos y protocolos de enrutamiento: Enrutamiento estático, protocolos de enrutamiento dinámico (RIP, VLSM, CIDR, RIPv2, EIGRP, OSPF)&lt;/li&gt;&lt;li&gt;    Bloque 3 - Conmutación y WLAN: Diseño de redes LAN, configuración de switches, VLAN, VTP, STP, enrutamiento entre VLAN, configuración de WLAN.&lt;/li&gt;&lt;li&gt;    Bloque 4 - Acceso a redes WAN: PPP, FrameRelay, Seguridad en la red, ACL, VPN's, DHCP, DNS y resolución de problemas en la red.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;CCNA Security&lt;/span&gt;. Unas 80 horas de curso. Es un módulo de ampliación.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;CCNA QoS&lt;/span&gt;: 80 horas, va sobre Quality of Service (Calidad de servicio). Para poder distinguir el tráfico prioritario (VozIP, HTTP) y hacer que siempre llegue con una calidad mínima.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;CCNA WiFi&lt;/span&gt;: 80 horas.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;CCNA Service Provider Operation&lt;/span&gt;: ni puta idea =). 80 horas seguramente por ser un módulo expansión.&lt;br /&gt;&lt;br /&gt;Todavía no he acabado el curso, me quedan dos o tres capítulos del bloque 4 para poderme presentar al último examen parcial, y después tendré que hacer acopio de toda mi voluntad y fuerzas y ponerme a estudiar muy fuerte para verme lo suficientemente preparado como para hacer el exámen final. Tienes que sacar más de un 80% de puntuación para poder aprovar, por lo que no es moco de pavo. Cada intento son unos 200€.&lt;br /&gt;&lt;br /&gt;Bueno, este es mi primer motivo por el cual no he estado escribiendo mucho por aquí. Otra cosa que ha influído ha sido el trabajo. Después de hacer 8 horas de curro al día, llegas a casa con pogas ganas de investigar cosas nuevas (aunque algo se hace), pero ya no te quedan fuerzas para escribir nada interesante.&lt;br /&gt;&lt;br /&gt;Pero bueno, no desesperemos! El curso de CCNA prácticamente ya lo he acabado y dentro de poco &lt;a href="http://inedit00.blogspot.com/2012/02/fin-de-una-epoca-aka-adios-trabajo.html"&gt;tendré mucho tiempo libre&lt;/a&gt;. Os puedo anticipar que he empezado a jugar con el lenguaje de programación de Erlang, que me está encantando. Es un lenguaje funcional donde tenemos "variables invariables", que son variables pero que sólo pueden ser asignadas una vez (o sea, nada de "i++"). No existen las estructuras "while" o "for", ya que se usa recursividad como estructura iterativa, y las listas son el tipo de dato más común en el lenguaje. Una pasada! Ya os contaré lo que vaya aprendiendo y dónde quiero llegar con todo esto. Tengo un proyectito chulo chulo. Si todo sale bien será mi primer proyecto publicado como OpenSource!!&lt;br /&gt;&lt;br /&gt;Dentro de un mesecito mas o menos tengo pensado volver a retomar el blog, y intentaré escribir 2 o 3 entradas semanales como en "mis tiempos mozos", por lo que estad preparados para lo que se avecina! =)&lt;br /&gt;&lt;br /&gt;Un saludo, Jan.</description><link>http://inedit00.blogspot.com/2012/02/cisco-ccna.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-6217860557534309123</guid><pubDate>Sat, 17 Dec 2011 12:55:00 +0000</pubDate><atom:updated>2011-12-17T14:15:06.399+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">general</category><title>Plugins Firefox II</title><description>Hace tiempo &lt;a href="http://inedit00.blogspot.com/2009/09/add-ons-firefox.html"&gt;escribí una entrada&lt;/a&gt; sobre los plugins que venía usando en Firefox. Bueno, parece ser que he tirado hacia el minimalismo últimamente y resulta que ya no uso ninguno de los plugins mencionados. Ahora uso tan solo dos:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Adblock Plus&lt;/span&gt;: Te quita toooooda la publicidad de Internet. Dejas de verla. Incluso la propaganda que pone youtube.com antes de visualizar un video? Esta también dejas de verla. Es genial. Recomiendo a todo el mundo que se lo instale ni que sea para probar. Además, se va actualizando solo cada tanto, para mantener la base de datos de contenidos publicitaros que tu navegador no tiene que cargar. Super chulo.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;ShareMeNot&lt;/span&gt;: Sirve para que todos aquellos botones "sociales" como por ejemplo el "Me gusta" de facebook, o el "+1" de Google, dejen de mandar información a Facebook/Google/Twitter sobre las páginas que visitas. Muy interesante para mantener la privacidad.&lt;br /&gt;&lt;br /&gt;El ShareMeNot puede que requiera de una explicación adicional. Imaginemos que www.marca.com decide poner el botón "Me gusta" en todas sus páginas. Pues si estás logueado en facebook en el navegador y al mismo momento entras en www.marca.com, Facebook sabe que has entrado en esta página. Esto es debido a que automáticamente asocia el "Me gusta" con tu perfil. El problema es que Facebook sabe las páginas que vas visitando y lo va registrando. Y esto no mola. Por ejemplo, si la página web www.MeGustanLasGordasPelirrojas.com tiene un botón de "Me gusta" y estás logueado en facebook al mismo tiempo, Facebook a partir de ahora ya sabe "un poquito más" acerca de tí. Puede que a partir de ahora te haga publicidad de ciertas chicas con cierto problema de obesidad. Por esto está bien tener un plugin de firefox que te prevenga que se vaya mandando información sobre qué visito a todos los sitios web 2.0 y mantener así la privacidad de nuestros datos.&lt;br /&gt;&lt;br /&gt;Y esto es todo por hoy. Un saludo!</description><link>http://inedit00.blogspot.com/2011/12/plugins-firefox-ii.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-9221172315879592644</guid><pubDate>Sun, 20 Nov 2011 11:18:00 +0000</pubDate><atom:updated>2012-03-08T17:36:21.972+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">linux</category><category domain="http://www.blogger.com/atom/ns#">programacion</category><category domain="http://www.blogger.com/atom/ns#">reflexión</category><title>Clase de buceo</title><description>En el &lt;a href="http://inedit00.blogspot.com/2011/09/sudo-su-sin-espera-nodelay.html"&gt;post anterior&lt;/a&gt;[1] comentaba cómo configurar las PAM para desactivar el tiempo de espera en caso de haberte equivocado escribiendo un password. Este post explica el proceso que seguí para saber que no es posible establecer un tiempo de espera personalizado. Siempre te tienes que esperar dos segundos en caso de haberte equivocado de password, o puedes desactivar el tiempo de espera. Lo que no puedes hacer es decir, "espérate 5 segundos en caso de que me haya equivocado de password antes de volver a preguntarme".. También se puede ver lo bonito que es el OpenSource, y la de que el código fuente sea público.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[Preámbulo]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Resulta que en el fichero /etc/pam.d/login hay una opción que pone: "auth  optional  pam_faildelay.so delay=3000000". Un comentario al lado explica claramente lo que hace esto:&lt;br /&gt;&lt;br /&gt;"Enforce a minimal delay in case of failure (in microseconds)". O lo que es lo mismo: Fuerza una pequeña espera en caso de fallo en la autenticación. 3 segundos, para ser mas exactos.&lt;br /&gt;&lt;br /&gt;Pues parece obvio pensar que si cambio 3000000 a 1000000, el tiempo de espera cuado haga login fallido se reducirá a 1 segundo.&lt;br /&gt;&lt;br /&gt;Probemos antes de hacer el cambio:&lt;br /&gt;$ sudo echo 1  # Comando chorra, pero lo importante es que nos pida el password&lt;br /&gt;[sudo] password for inedit: badpassword&lt;br /&gt;--- pasan unos dos segundos, aproximadamente ---&lt;br /&gt;&lt;br /&gt;Hacemos el cambio en el fichero, poniendo el parámetro "delay=1000000". Probamos de nuevo:&lt;br /&gt;$ sudo echo 1&lt;br /&gt;[sudo] password for inedit: badpassword&lt;br /&gt;--- pasan unos dos segundos, aproximadamente. Lo mismo que antes... ---&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;mmmm... mierda, no funciona. Probemos lo propuesto en el &lt;a href="http://inedit00.blogspot.com/2011/09/sudo-su-sin-espera-nodelay.html"&gt;post anterior&lt;/a&gt;, o sea, poner el parámetro nodelay en el fichero /etc/pam.d/common-auth:&lt;br /&gt;auth    [success=2 default=ignore]    pam_unix.so nullok_secure nodelay&lt;br /&gt;&lt;br /&gt;Probamos de nuevo:&lt;br /&gt;&lt;br /&gt;$ sudo echo 1&lt;br /&gt;[sudo] password for inedit: badpassword&lt;br /&gt;--- inmediatamente despues nos dice que la contraseña es incorrecta y que lo intentemos de nuevo. Tiempo de espera: cero segunos ---&lt;br /&gt;&lt;br /&gt;Genial. Parece que el parámetro "nodelay" funciona. Pero ¿Por qué no funciona el "delay=3000000"?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[Siguiendo pasos lógicos]&lt;/span&gt;&lt;br /&gt;Vale, resulta que el parámetro "nodelay" se lo ponemos como parámetro a un fichero llamado "pam_unix.so". Ni idea de qué coño hace este fichero, pero busquemos a ver si existe ene el sistema:&lt;br /&gt;&lt;br /&gt;$ locate pam_unix.so&lt;br /&gt;/lib/x86_64-linux-gnu/security/pam_unix.so&lt;br /&gt;&lt;br /&gt;Touché, existe. mmmm..... vale. ¿Ahora qué hacemos con el? Ni idea de que hace realmente el fichero. Lo he abierto y es un binario....mmmm.... Vale, ya lo tengo. &lt;a href="http://inedit00.blogspot.com/2011/09/sudo-su-sin-espera-nodelay.html"&gt;Descubramos qué paquete ha creado este fichero&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;$ dpkg-query -S /lib/x86_64-linux-gnu/security/pam_unix.so&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;libpam-modules&lt;/span&gt;: /lib/x86_64-linux-gnu/security/pam_unix.so&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Con que &lt;span style="font-weight: bold;"&gt;libpam-modules&lt;/span&gt;, eh? Vaaaale, pues mira, estamos siguiendo la pista y no nos va mal. Ahora ¿cuál puede ser el siguiente paso? Pues descargar el código fuente y que hace realmente el código:&lt;br /&gt;$ mkdir ~/killme&lt;br /&gt;$ cd ~/killme&lt;br /&gt;$ apt-get source libpam-modules&lt;br /&gt;&lt;br /&gt;Esto nos habrá creado un par de ficheros en el directorio "killme" [2].&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[Buceando en el código]&lt;/span&gt;&lt;br /&gt;Vale, ahora tenemos el código de la "libpam". ¿Qué hacemos? Lo obvio, aquí sería buscar alguna referéncia a "pam_unix.so". Pero como los ficheros ".so" son compilados y nosotros nos hemos descargado el código fuente, vamos a probar lo siguiente:&lt;br /&gt;$ find -name "pam_unix*"&lt;br /&gt;&lt;br /&gt;Oh! Genial, tenemos resultados! Parece que existe una carpeta interesante: "./pam-1.1.3/modules/pam_unix"&lt;br /&gt;&lt;br /&gt;Vale, ahora deberíamos buscar algo de utilidad dentro de esta carpeta. Juguemos con "grep", a ver si hay suerte:&lt;br /&gt;$ cd ./pam-1.1.3/modules/pam_unix2&lt;br /&gt;$ grep nodelay -i       # -i es para hace "ignore-case". O sea, que no distinga entre mayúsculas y minúsculas.&lt;br /&gt;&lt;blockquote&gt;pam_unix.8:\fBnodelay\fR&lt;br /&gt;pam_unix.8.xml:          &lt;option&gt;nodelay&lt;/option&gt;&lt;br /&gt;README:nodelay&lt;br /&gt;support.c:    if (off(UNIX_NODELAY, ctrl)) {&lt;br /&gt;support.h:#define UNIX_NODELAY             16    /* admin does not want a fail-delay */&lt;br /&gt;support.h:/* UNIX_NODELAY */         {"nodelay",         _ALL_ON_,             0100000},&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Tenemos resultados! Parecen interesantes los ficheros "support.c" y "support.h". Revisado el fichero "support.h" parece que solo hay la declaración del parámetro UNIX_NODELAY.&lt;br /&gt;Veamos el fichero "support.c", a ver que contiene:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;[...]&lt;br /&gt;#ifdef HAVE_PAM_FAIL_DELAY&lt;br /&gt;   if (off(UNIX_NODELAY, ctrl)) {&lt;br /&gt;       D(("setting delay"));&lt;br /&gt;       (void) pam_fail_delay(pamh, 2000000);    /* 2 sec delay for on failure */&lt;br /&gt;   }&lt;br /&gt;#endif&lt;br /&gt;[...]&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Eureka! Lo hemos encontrado! Vale, yo no tengo ni idea de C. Nunca he programado nada serio en C, ni mucho menos una librería de sistema para Linux. Pero si hemos llegado hasta este fichero buscando cosas lógicas, ahora no nos va a detener un poco de código en C. Parece que es el código fuente de "pam_unix.so".&lt;br /&gt;&lt;br /&gt;Vamos a intentar leer lo que pone este pedacito de código. La condición "if" parece que comprueba lo siguiente:&lt;br /&gt;   SI (el parámetretro UNIX_NODELAY és igual a falso) ENTONCES {&lt;br /&gt;       Espérate 2 segundos&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Pues ya lo tenemos, señores. Resulta que &lt;span style="font-weight: bold;"&gt;no se puede definir un tiempo de espera&lt;/span&gt;, ya que el tiempo de espera &lt;span style="font-weight: bold;"&gt;está puesto de modo estático en el código&lt;/span&gt;. En ningún momento el código va a leer la variable "delay=3000000", por lo que si ponemos "delay=5000000" es normal que lo ignore.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[conclusión]&lt;/span&gt;&lt;br /&gt;¿Cómo hemos podido sacar todo esto? Pues la respuesta es muy simple: porque es Software Libre y se puede conseguir el código fuente muy facilmente a través de Internet. Inspeccionando el código vemos claramente lo que hace ( y mejor todavía, lo que &lt;span style="font-weight: bold;"&gt;no hace&lt;/span&gt; ). En este punto, y si tuviese los conocimientos de C necesarios, podría reescribir el código fuente para que aceptara un parámetro "delay" y que pudiese ser definido des de la pam.d/login. Una vez hechos los cambios, podría mandarlos al mantenedor del paquete y en caso de gustarle dichos cambios, los incorporaría en el código de la libpam. Y el mundo sería un lugar mejor y lloverían gominolas del cielo :)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[1] Recomiendo que te lo leas, sinó este pot no tiene mucho sentido.&lt;br /&gt;[2] Me gusta bastante crear directorios con el nombre "kill" o "killme" para usos temporales, ya que es un modo de saber si puedo borrar el directorio sin ni tan solo preocuparme de ver que contiene. En cambio, un directorio que llamado "temp" o "temporal".... bueno, si, son datos temporales. Pero hasta cuando? Servirá lo que hay dentro? Es algo lioso. Usando "killme" el tema está claro, puedes borrar la carpeta cuando quieras sin ningun problema, ya que el contenido de la misma no es importante ;)</description><link>http://inedit00.blogspot.com/2011/11/clase-de-buceo.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-5226925811922573947</guid><pubDate>Thu, 08 Sep 2011 21:39:00 +0000</pubDate><atom:updated>2011-09-09T08:39:50.354+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">linux</category><category domain="http://www.blogger.com/atom/ns#">tips</category><title>Saber a qué paquete pertenece un fichero</title><description>Algunas veces hay ficheros con nombres curiosos, y uno se pregunta qué paquete debe haber instalado este fichero. Por ejemplo el fichero:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;/usr/bin/pico&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Yo me pregunto, ¿quién lo habrá puesto ahí?&lt;br /&gt;&lt;br /&gt;Pues fácil:&lt;br /&gt;$ sudo aptitude install dlocate -y&lt;br /&gt;$ dlocate /usr/bin/pico&lt;br /&gt;&amp;gt; &lt;span style="font-weight: bold;"&gt;perl&lt;/span&gt;: /usr/bin/piconv&lt;br /&gt;&lt;br /&gt;Pues mira, ha sido el paquete "perl".&lt;br /&gt;&lt;br /&gt;Esto también sirve para ficheros de configuración, así como carpetas del sistema. Todo lo que esté "trackeado" por &lt;span style="font-style: italic;"&gt;dpkg&lt;/span&gt;, es suceptible de ser encontrado por dlocate.&lt;br /&gt;&lt;br /&gt;Un saludo, Jan.&lt;br /&gt;&lt;br /&gt;UPDATE: El comando "dpkg-query -S /usr/bin/see" también hace lo mismo.</description><link>http://inedit00.blogspot.com/2011/09/saber-que-paquete-pertenece-un-fichero.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6671913855625335983.post-8281638913992352100</guid><pubDate>Thu, 08 Sep 2011 21:02:00 +0000</pubDate><atom:updated>2011-09-08T23:21:20.557+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">debian</category><category domain="http://www.blogger.com/atom/ns#">seguridad</category><category domain="http://www.blogger.com/atom/ns#">tips</category><title>"sudo su" sin espera ( nodelay )</title><description>Pues como hoy me he tirado 30 minutos buscando esta opción y considerando que hay poca información sobre ella ( y menos en castellano ), así va:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-weight: bold;"&gt;¡NODELAY&lt;/span&gt; en pam_unix.so!&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[¿De qué va el tema?]&lt;/span&gt;&lt;br /&gt;Pues se trata de optimización de tiempo y comodiad en la consola. Cuando ejecutamos un comando con "sudo", normalmente nos pide la contraseña ( a menos que lo hayamos desactivado ). Esto es la política de seguridad bastante recomendada, ya que si no cualquier persona te podria juankear el ordenador si lo dejas solo un momento sin bloquear.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[Total, dónde está el problema, entonces?]&lt;/span&gt;&lt;br /&gt;Pues que si al ejectuar cualquier comando con &lt;span style="font-style: italic;"&gt;sudo&lt;/span&gt;, te equivocas al picar tu password, te tienes que esperar 3 segundos para volverlo a picar. Y esto es un coñazo. Ejemplo:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;inedit@tpad:~$ sudo echo 1&lt;br /&gt;[sudo] password for inedit: &lt;span style="font-style: italic;"&gt;foo&lt;/span&gt;&lt;br /&gt;- espera de tres segundos -&lt;br /&gt;Invalid password, please try again:&lt;br /&gt;[sudo] password for inedit: &lt;span style="font-style: italic;"&gt;bar&lt;br /&gt;&lt;/span&gt;- espera otra vez de tres segundos -&lt;span style="font-style: italic;"&gt;&lt;br /&gt;....etc...&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;[HOWTO]&lt;/span&gt;&lt;br /&gt;Total, que esta opción se puede desactivar a través de las PAM de linux del siguiente modo:&lt;br /&gt;&lt;br /&gt;sudo vim &lt;span style="font-weight: bold;"&gt;/etc/pam.d/common-auth&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Y modificar la lína donde pone:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;auth    [success=2 default=ignore]    pam_unix.so nullok_secure&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Y cambiarla por:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;auth    [success=2 default=ignore]    pam_unix.so nullok_secure nodelay&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;De este modo se desactiva totalmente el tiempo de espera entre logins. Cuando te equivoques al escribir tu password, automáticamente te volverá a preguntar la clave.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[Precaución]&lt;/span&gt;&lt;br /&gt;Y uno se preguntará, ¿por qué puñetas no estaba desactivado esto ya? Pues por motivos de seguridad: previene que se lanzen ataques de fuerza bruta contra el PC, ya que el hecho de que te tengas que esperar 3 segundos tras cada intento fallido, limita mucho los ataques ( los hace inviables por la cantidad de tiempo que se necesita probar un número acceptable de claves ). Aplicando la regla anterior estamos quiando esta restricción. O sea que cuidadín en ejecutar algo así en una máquina de producción donde tenga SSH expuesto en Internet y demás. Quien avisa no es traidor.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[Nota final]&lt;/span&gt;&lt;br /&gt;Como siempre, en un extremo tenemos seguridad, y en el otro tenemos comodidad. No podemos elegir ambos. Por lo que lo mejor es quedarse siempre en un punto medio.&lt;br /&gt;&lt;br /&gt;Un saludo, Jan.&lt;br /&gt;&lt;br /&gt;Posdata: Si alguien consigue sacar algo en claro sobre el fichero /etc/pam.d/login  y su parámetro "pam_faildelayso delay=3000000", que por favor deje un comentario y así completamos la información. Yo no he sido capaz de ajustarlo a un segundo. Gracias de antemano.</description><link>http://inedit00.blogspot.com/2011/09/sudo-su-sin-espera-nodelay.html</link><author>noreply@blogger.com (inedit00)</author><thr:total>1</thr:total></item></channel></rss>