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

<channel>
	<title>tail -f &#124; sysadmin &#187; Apache</title>
	<atom:link href="http://www.tail-f.com.ar/category/servicios/httpd/apache-httpd-servicios/feed" rel="self" type="application/rss+xml" />
	<link>http://www.tail-f.com.ar</link>
	<description>Noticias y recursos para sysadmins Unix</description>
	<lastBuildDate>Mon, 28 Nov 2011 21:44:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Sencillo parser para Apache mod_status en Python</title>
		<link>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/sencillo-parser-para-apache-mod_status-en-python.html</link>
		<comments>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/sencillo-parser-para-apache-mod_status-en-python.html#comments</comments>
		<pubDate>Sun, 31 Jul 2011 01:01:46 +0000</pubDate>
		<dc:creator>elbarto</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[mod_status]]></category>
		<category><![CDATA[parser]]></category>

		<guid isPermaLink="false">http://www.tail-f.com.ar/?p=455</guid>
		<description><![CDATA[Cuánto hace que no actualizo este blog!! Hoy estuve jugando un poco con Python y me puse a hacer un pequeño script que supongo que a otros les podrá servir como base para hacer algo más interesante. Precisamente, tengo planes para hacer algo más interesante, pero como recién están en veremos, les voy pasando esta [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.tail-f.com.ar/wp-content/uploads/apache1.gif"><img class="size-full wp-image-37 alignright" title="apache1" src="http://www.tail-f.com.ar/wp-content/uploads/apache1.gif" alt="" width="210" height="210" /></a></p>
<p>Cuánto hace que no actualizo este blog!! Hoy estuve jugando un poco con Python y me puse a hacer un pequeño script que supongo que a otros les podrá servir como base para hacer algo más interesante. Precisamente, tengo planes para hacer algo más interesante, pero como recién están en veremos, les voy pasando esta pequeña base a ver si alguien me gana de mano <img src='http://www.tail-f.com.ar/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Como muchos sabrán, Apache (y otros web servers) tiene un módulo llamado <a href="http://httpd.apache.org/docs/2.2/mod/mod_status.html">mod_status</a> que nos permite ver en tiempo real el estado del servidor (los requests que se están procesando, el uso del CPU, el estado de las conexiones, etc.). Esta información puede ser muy útil para hacer diagnósticos cuando está habiendo algún tipo de problema, para hacer monitoreo, etc. El módulo nos muestra una página web con la información y tiene dos interfaces: una está pensada para ser vista por seres humanos y otra para ser consultada por scripts (para ver esta segunda sólo hace falta pasarle el parámetro &#8220;?auto&#8221; en la URL). El problema es que esta segunda interfaz no nos muestra a qué dominios (virtual hosts) están dirigidos los requests que se están procesando (o si hay forma de que lo muestre yo no la encontré). Entonces me puse a hacer un sencillo script en Python para parsear la página &#8220;para seres humanos&#8221;.</p>
<p>Por suerte Python nos ofrece muchas herramientas muy útiles para este tipo de cosas, así que no me tuve que esforzar demasiado. En este caso utilicé <a href="http://docs.python.org/library/urllib2.html">urllib2</a> para acceder a la página de mod_status y <a href="http://www.crummy.com/software/BeautifulSoup/">BeautifulSoup</a> para parsear el HTML. Por si no lo conocen, BeautifulSoup es un muy poderoso parser para XML/HTML hecho en Python. No viene con el código fuente sino que hay que instalarlo, pero hacerlo es muy fácil:</p>
<p>En Debian/Ubuntu:</p>
<pre>apt-get install python-beautifulsoup</pre>
<p>En CentOS/RedHat:</p>
<pre>yum install python-BeautifulSoup</pre>
<p>Con easy_install:</p>
<pre>easy_install BeautifulSoup</pre>
<p>El código tiene una clase Status que es la que hace la magia y una función main() que utiliza la clase para parsear una URL e imprimir algunos datos a modo de ejemplo.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">import</span> <span class="kw3">sys</span><br />
<span class="kw1">import</span> <span class="kw3">urllib2</span><br />
<span class="kw1">from</span> <span class="kw3">operator</span> <span class="kw1">import</span> itemgetter<br />
<span class="kw1">from</span> BeautifulSoup <span class="kw1">import</span> BeautifulSoup</p>
<p><span class="kw1">class</span> Status <span class="br0">&#40;</span><span class="kw2">object</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; _url = <span class="kw2">None</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span> <span class="br0">&#40;</span><span class="kw2">self</span>, url<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._url = url</p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> fetch <span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw3">urllib2</span>.<span class="me1">urlopen</span><span class="br0">&#40;</span><span class="kw2">self</span>._url<span class="br0">&#41;</span>.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">def</span> parse <span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; html = <span class="kw2">self</span>.<span class="me1">fetch</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; soup = BeautifulSoup<span class="br0">&#40;</span>html<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; status = <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; status<span class="br0">&#91;</span><span class="st0">&#8216;server_info&#8217;</span><span class="br0">&#93;</span> = <span class="br0">&#91;</span>i.<span class="kw3">string</span>.<span class="me1">strip</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">for</span> i <span class="kw1">in</span> soup.<span class="me1">findAll</span><span class="br0">&#40;</span><span class="st0">&#8216;dt&#8217;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; status<span class="br0">&#91;</span><span class="st0">&#8216;requests&#8217;</span><span class="br0">&#93;</span> = <span class="br0">&#91;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; requests = soup.<span class="me1">find</span><span class="br0">&#40;</span><span class="st0">&#8216;table&#8217;</span><span class="br0">&#41;</span>.<span class="me1">findAll</span><span class="br0">&#40;</span><span class="st0">&#8216;tr&#8217;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; keys = <span class="br0">&#91;</span>i.<span class="kw3">string</span> <span class="kw1">for</span> i <span class="kw1">in</span> requests.<span class="me1">pop</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> tr <span class="kw1">in</span> requests:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; req = <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> n, td <span class="kw1">in</span> <span class="kw2">enumerate</span><span class="br0">&#40;</span>tr<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; req<span class="br0">&#91;</span>keys<span class="br0">&#91;</span>n<span class="br0">&#93;</span><span class="br0">&#93;</span> = td.<span class="kw3">string</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; status<span class="br0">&#91;</span><span class="st0">&#8216;requests&#8217;</span><span class="br0">&#93;</span>.<span class="me1">append</span><span class="br0">&#40;</span>req<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> status</p>
<p><span class="kw1">def</span> main <span class="br0">&#40;</span>argv<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">len</span><span class="br0">&#40;</span>argv<span class="br0">&#41;</span> &lt; <span class="nu0">2</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;Usage %s &quot;</span>%argv<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">1</span></p>
<p>&nbsp; &nbsp; status = Status<span class="br0">&#40;</span>argv<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; data = status.<span class="me1">parse</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;SERVER INFORMATION&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;==================&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">for</span> v <span class="kw1">in</span> data<span class="br0">&#91;</span><span class="st0">&#8216;server_info&#8217;</span><span class="br0">&#93;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> v</p>
<p>&nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;REQUESTS BY VHOST&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;=================&quot;</span><br />
&nbsp; &nbsp; entries = <span class="br0">&#91;</span>i<span class="br0">&#91;</span><span class="st0">&#8216;VHost&#8217;</span><span class="br0">&#93;</span> <span class="kw1">for</span> i <span class="kw1">in</span> data<span class="br0">&#91;</span><span class="st0">&#8216;requests&#8217;</span><span class="br0">&#93;</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; requests = <span class="kw2">sorted</span><span class="br0">&#40;</span><span class="br0">&#91;</span><span class="br0">&#40;</span>entries.<span class="me1">count</span><span class="br0">&#40;</span>i<span class="br0">&#41;</span>, i<span class="br0">&#41;</span> <span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">list</span><span class="br0">&#40;</span><span class="kw2">set</span><span class="br0">&#40;</span>entries<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#93;</span>, reverse=<span class="kw2">True</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;<span class="es0">\n</span>&quot;</span>.<span class="me1">join</span><span class="br0">&#40;</span><span class="br0">&#91;</span><span class="st0">&quot;%d: %s&quot;</span>%<span class="br0">&#40;</span>a,b<span class="br0">&#41;</span> <span class="kw1">for</span> a,b <span class="kw1">in</span> requests<span class="br0">&#93;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">if</span> __name__ == <span class="st0">&quot;__main__&quot;</span>:<br />
&nbsp; &nbsp; <span class="kw3">sys</span>.<span class="me1">exit</span><span class="br0">&#40;</span>main<span class="br0">&#40;</span><span class="kw3">sys</span>.<span class="me1">argv</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
<p>La forma de uso es:</p>
<pre>python status.py "http://localhost/server-status"</pre>
<p>Y en este caso la salida del script es algo así:</p>
<pre>SERVER INFORMATION
==================
Server Version: Apache/2.2.19 (Unix) mod_ssl/2.2.19 OpenSSL/0.9.8e-fips-rhel5 DAV/2
Server Built: May 26 2011 15:14:47
Current Time: Sunday, 31-Jul-2011 00:53:59 ART
Restart Time: Saturday, 30-Jul-2011 12:07:12 ART
Parent Server Generation: 0
Server uptime:  12 hours 46 minutes 47 seconds
Total accesses: 407813 - Total Traffic: 3.7 GB
CPU Usage: u2.05 s3.23 cu52 cs0 - .125% CPU load
8.86 requests/sec - 85.0 kB/second - 9.6 kB/request
10 requests currently being processed, 8 idle workers
REQUESTS BY VHOST
=================
9: www.tail-f.com.ar
5: www.otro-dominio.com.ar
4: www.not-a-domain.com.ar
3: www.algunlado.com.ar
2: subdominio.dominio.com.ar
1: www.pepe.com.ar
1: www.no-votes-a-macri.com.ar
1: www.asd.com.ar
1: localhost</pre>
<p>Obviamente esto no es una aplicación funcional, sino un ejemplo que espero que les sirva para hacer algo más copado. Yo seguiré jugando y si hago algo un poco más interesante, ya se los mostraré.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/sencillo-parser-para-apache-mod_status-en-python.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Python: Ver dominios de Apache que más transferencia consumen</title>
		<link>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/python-ver-dominios-de-apache-que-mas-transferencia-consumen.html</link>
		<comments>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/python-ver-dominios-de-apache-que-mas-transferencia-consumen.html#comments</comments>
		<pubDate>Thu, 11 Mar 2010 01:47:12 +0000</pubDate>
		<dc:creator>elbarto</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[access_log]]></category>
		<category><![CDATA[log]]></category>

		<guid isPermaLink="false">http://www.tail-f.com.ar/?p=361</guid>
		<description><![CDATA[Hace un rato publiqué un post con un script para ver qué dominios de Apache consumen mayor transferencia. El script en BASH toma unos 7 segundos en procesar 750 archivos de uno de mis servidores. Ahora hice una versión en Python, para la que me dieron algunos consejos los chicos de PyAr, y toma aproximadamente [...]]]></description>
			<content:encoded><![CDATA[<p>Hace un rato publiqué un post con un script para ver <a href="http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/ver-dominios-de-apache-que-mas-transferencia-consumen.html">qué dominios de Apache consumen mayor transferencia</a>. El script en <a href="http://www.tail-f.com.ar/tag/bash">BASH</a> toma unos 7 segundos en procesar 750 archivos de uno de mis servidores. Ahora hice una versión en <a href="http://www.tail-f.com.ar/tag/python">Python</a>, para la que me dieron algunos consejos los chicos de <a href="http://python.org.ar/pyar/">PyAr</a>, y toma aproximadamente 4 segundos en procesar los mismos archivos. Aquí les dejo el código:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="co1">#!/usr/bin/env python</span><br />
<span class="st0">&quot;&quot;</span><span class="st0">&quot; Access Log Parser</p>
<p>Parses all the files in a directory<br />
treating them as access_log files<br />
and outputs the list of files sorted<br />
by transfered megabytes. Useful for<br />
identifying heavy users.</p>
<p>Usage:<br />
./access_log_parser.py &lt;base_dir&gt;<br />
base_dir = directory where the access_log files are<br />
&quot;</span><span class="st0">&quot;&quot;</span><br />
<span class="kw1">import</span> <span class="kw3">sys</span><br />
<span class="kw1">import</span> <span class="kw3">os</span><br />
<span class="kw1">import</span> <span class="kw3">time</span><br />
<span class="kw1">from</span> <span class="kw3">operator</span> <span class="kw1">import</span> itemgetter</p>
<p><span class="kw1">def</span> main <span class="br0">&#40;</span>args<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Main</p>
<p>&nbsp; &nbsp; Main function of the script.<br />
&nbsp; &nbsp; This is where the magic happens.<br />
&nbsp; &nbsp; It takes the script arguments<br />
&nbsp; &nbsp; and returns an exit code.<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="co1"># Parameter checking</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">len</span><span class="br0">&#40;</span>args<span class="br0">&#41;</span> &lt; <span class="nu0">2</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;Usage: %s &lt;base_dir&gt;&quot;</span> % args<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">1</span></p>
<p>&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw3">os</span>.<span class="me1">path</span>.<span class="me1">isdir</span><span class="br0">&#40;</span>args<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; base_dir = args<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">print</span> <span class="st0">&quot;%s is not a directory&quot;</span> % args<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">return</span> <span class="nu0">2</span></p>
<p>&nbsp; &nbsp; <span class="co1"># Init vars</span><br />
&nbsp; &nbsp; t1 = <span class="kw3">time</span>.<span class="kw3">time</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; mbyte = <span class="nu0">1048576.0</span><br />
&nbsp; &nbsp; domains = <span class="br0">&#91;</span><span class="br0">&#93;</span></p>
<p>&nbsp; &nbsp; <span class="co1"># Start processing files</span><br />
&nbsp; &nbsp; <span class="kw1">for</span> item <span class="kw1">in</span> <span class="kw3">os</span>.<span class="me1">listdir</span><span class="br0">&#40;</span>args<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; path = <span class="kw3">os</span>.<span class="me1">path</span>.<span class="me1">join</span><span class="br0">&#40;</span>base_dir, item<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw3">os</span>.<span class="me1">path</span>.<span class="me1">isfile</span><span class="br0">&#40;</span>path<span class="br0">&#41;</span> <span class="kw1">and</span> \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw3">os</span>.<span class="me1">path</span>.<span class="me1">getsize</span><span class="br0">&#40;</span>path<span class="br0">&#41;</span> &gt; <span class="nu0">0</span>:</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bytes = <span class="nu0">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; init_date = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data = <span class="kw2">None</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># Process file lines</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> line <span class="kw1">in</span> <span class="kw2">open</span><span class="br0">&#40;</span>path, <span class="st0">&#8216;r&#8217;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data = line.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">&quot; &quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> init_date <span class="kw1">is</span> <span class="kw2">None</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; init_date = data<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="nu0">1</span>:<span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bytes += <span class="kw2">long</span><span class="br0">&#40;</span>data<span class="br0">&#91;</span><span class="nu0">9</span><span class="br0">&#93;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">except</span> <span class="kw2">ValueError</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">pass</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; domains.<span class="me1">append</span><span class="br0">&#40;</span><span class="br0">&#123;</span><span class="st0">&#8216;domain&#8217;</span>: item, \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;mbytes&#8217;</span>: bytes / mbyte, \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;init_date&#8217;</span>: init_date, \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;end_date&#8217;</span>: data<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="nu0">1</span>:<span class="br0">&#93;</span> <span class="br0">&#125;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="co1"># Print out sorted information</span><br />
&nbsp; &nbsp; <span class="kw1">for</span> domain <span class="kw1">in</span> <span class="kw2">sorted</span><span class="br0">&#40;</span>domains, key=itemgetter<span class="br0">&#40;</span><span class="st0">&#8216;mbytes&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;%.2f MB | From: %s | To: %s | %s&quot;</span> % \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>domain<span class="br0">&#91;</span><span class="st0">&#8216;mbytes&#8217;</span><span class="br0">&#93;</span>, \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;domain<span class="br0">&#91;</span><span class="st0">&#8216;init_date&#8217;</span><span class="br0">&#93;</span>, \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;domain<span class="br0">&#91;</span><span class="st0">&#8216;end_date&#8217;</span><span class="br0">&#93;</span>, \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;domain<span class="br0">&#91;</span><span class="st0">&#8216;domain&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;Generated in %d seconds&quot;</span> % <span class="br0">&#40;</span><span class="kw3">time</span>.<span class="kw3">time</span><span class="br0">&#40;</span><span class="br0">&#41;</span> &#8211; t1<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">0</span></p>
<p><span class="kw1">if</span> __name__ == <span class="st0">&quot;__main__&quot;</span>:<br />
&nbsp; &nbsp; <span class="kw3">sys</span>.<span class="me1">exit</span><span class="br0">&#40;</span>main<span class="br0">&#40;</span><span class="kw3">sys</span>.<span class="me1">argv</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
<p>Para ejecutarlo:</p>
<pre>./access_log_parser.py /tmp/domain_logs
...
544.30 MB | From: 10/Mar/2010:02:48:33 | To: 10/Mar/2010:18:13:25 | dominio1.com.ar.log
602.34 MB | From: 10/Mar/2010:00:23:09 | To: 10/Mar/2010:23:39:45 | dominio2.com.ar.log
944.03 MB | From: 10/Mar/2010:00:49:35 | To: 10/Mar/2010:23:39:57 | dominio3.com.ar.log
Generated in 3 seconds
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/python-ver-dominios-de-apache-que-mas-transferencia-consumen.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ver dominios de Apache que más transferencia consumen</title>
		<link>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/ver-dominios-de-apache-que-mas-transferencia-consumen.html</link>
		<comments>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/ver-dominios-de-apache-que-mas-transferencia-consumen.html#comments</comments>
		<pubDate>Wed, 10 Mar 2010 19:07:44 +0000</pubDate>
		<dc:creator>elbarto</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[BASH]]></category>
		<category><![CDATA[access_log]]></category>
		<category><![CDATA[logs]]></category>

		<guid isPermaLink="false">http://www.tail-f.com.ar/?p=350</guid>
		<description><![CDATA[Frecuentemente me encuentro ante la necesidad de saber qué dominios de los que tengo alojados en mis servidores consumen más tráfico HTTP. Como éste es el tipo de tráfico más importante y que más incide en el desempeño general de mis servidores, saber qué dominios transfieren más datos por HTTP me orienta en la búsqueda [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.tail-f.com.ar/wp-content/uploads/nerd.jpg"><img class="alignright size-medium wp-image-354" title="nerd" src="http://www.tail-f.com.ar/wp-content/uploads/nerd-300x227.jpg" alt="" width="300" height="227" /></a>Frecuentemente me encuentro ante la necesidad de saber qué dominios de los que tengo alojados en mis servidores consumen más tráfico HTTP. Como éste es el tipo de tráfico más importante y que más incide en el desempeño general de mis servidores, saber qué dominios transfieren más datos por HTTP me orienta en la búsqueda de heavy users. Para ello hice un script hace algún tiempo, y ahora lo estuve revisando, retocando y simplificando, y decidí compartirlo.</p>
<p>En el entorno de <a href="http://www.tail-f.com.ar/tag/directadmin">Directadmin</a>, los logs de <a href="http://www.tail-f.com.ar/tag/apache">Apache</a> se encuentran en /var/log/httpd. Allí hay una carpeta &#8220;domains&#8221; que guarda los logs de cada dominio. Por cada dominio hay tres logs: dominio.com.log, dominio.com.error.log y dominio.com.bytes. El primero es el access_log, el segundo el error_log y el tercero solamente guarda la cantidad de bytes de cada request. La opción más sencilla es trabajar con este último tipo de logs, pero el problema que tienen es que no indican la fecha. Si bien se supone que los logs de Directadmin rotan una vez por día, alguna vez me ha pasado que por razones que nunca pude descubrir, algunos logs no rotaban y generaban ciertas confusiones. Por lo tanto, el script que dejo usa los access_logs. Además esta opción es reutilizable en otras implementaciones de Apache que no tengan archivos de bytes.</p>
<p>El código:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="re3"># Access Log Parser</span><br />
<span class="re3">#</span><br />
<span class="re3"># Parses all the files <span class="kw1">in</span> a directory</span><br />
<span class="re3"># treating them <span class="kw2">as</span> access_log files</span><br />
<span class="re3"># and outputs the list of files sorted</span><br />
<span class="re3"># by transfered megabytes. Useful for</span><br />
<span class="re3"># identifying heavy <span class="kw2">users</span>.</span><br />
<span class="re3">#</span><br />
<span class="re3"># Usage:</span><br />
<span class="re3"># ./access_log_parser.<span class="kw2">sh</span> &lt;base_dir&gt;</span><br />
<span class="re3"># base_dir = directory where the access_log files are</span></p>
<p><span class="kw1">if</span> <span class="br0">&#91;</span> -z $<span class="nu0">1</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;Usage: $0 &quot;</span><br />
&nbsp; &nbsp; <span class="kw3">exit</span> <span class="nu0">1</span><br />
<span class="kw1">fi</span></p>
<p><span class="re2">BASE_DIR=</span>$<span class="nu0">1</span><br />
<span class="re2">T1=</span>`<span class="kw2">date</span> +%s`<br />
<span class="kw1">for</span> <span class="kw2">file</span> <span class="kw1">in</span> <span class="re1">$BASE_DIR</span>/*;<br />
<span class="kw1">do</span><br />
&nbsp; &nbsp; <span class="re2">size=</span>`<span class="kw2">stat</span> -c %s <span class="re1">$file</span>`<br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re1">$size</span> -gt <span class="nu0">0</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">from=</span>`<span class="kw2">head</span> <span class="nu0">-1</span> <span class="re1">$file</span> | <span class="kw2">awk</span> <span class="st0">&#8216;{print($4)}&#8217;</span> |sed <span class="st0">&#8216;s/^<span class="es0">\[</span>//&#8217;</span>`<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">to=</span>`<span class="kw2">tail</span> <span class="nu0">-1</span> <span class="re1">$file</span> | <span class="kw2">awk</span> <span class="st0">&#8216;{print($4)}&#8217;</span> |sed <span class="st0">&#8216;s/^<span class="es0">\[</span>//&#8217;</span>`<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">bytes=</span>`<span class="kw2">cat</span> <span class="re1">$file</span> | <span class="kw2">awk</span> <span class="st0">&#8216;{a+=$10}END{print a}&#8217;</span>`<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">mbytes=</span>`<span class="kw3">echo</span> <span class="re1">$bytes</span> | <span class="kw2">awk</span> <span class="st0">&#8216;{print $1 / 1048576}&#8217;</span>`<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> &nbsp;<span class="st0">&quot;$mbytes MB ($bytes bytes) | From: $from | To: $to | ${file:${#BASE_DIR}+1}&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">fi</span><br />
<span class="kw1">done</span> \<br />
| <span class="kw2">sort</span> -nb<br />
<span class="re2">T=</span>`<span class="kw2">date</span> +%s`</div>
<p>Un detalle importante: el script levanta todos los archivos de un directorio que se especifica por parámetro. Esto es así porque yo lo invoco desde otro script:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="re3">#!/bin/bash</span><br />
<span class="re2">LOG_DIR=</span>/var/log/httpd/domains/<br />
<span class="re2">TMP=</span>/tmp/domain_logs<br />
<span class="kw1">if</span> <span class="br0">&#91;</span> ! -d <span class="re1">$TMP</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw2">mkdir</span> -p <span class="re1">$TMP</span><br />
<span class="kw1">fi</span></p>
<p><span class="kw2">rm</span> -f <span class="re1">$TMP</span>/*</p>
<p><span class="kw3">cd</span> <span class="re1">$LOG_DIR</span><br />
<span class="kw1">for</span> i <span class="kw1">in</span> `<span class="kw2">ls</span> *.log |grep -v error`; <span class="kw1">do</span><br />
&nbsp; &nbsp; <span class="kw2">ln</span> <span class="re1">$i</span> <span class="re1">$TMP</span>/<span class="re1">$i</span><br />
<span class="kw1">done</span><br />
/root/access_log_parser.<span class="kw2">sh</span> <span class="re1">$TMP</span></div>
<p>Este último script lo que hace es crear un directorio temporal (si no existe). Vaciar su contenido. Y luego generar hardlinks a todos los access_logs de /var/log/httpd/domains. De esta forma, no me tengo que preocupar por si los logs son modificados mientras yo estoy ejecutando el script. Por último, ejecuta mi primer script (access_log_parser.sh) y le pasa como parámetro el directorio temporal donde están los access_logs.</p>
<p>Por último, la salida del script sería algo así:</p>
<pre>...
186.995 MB (196078184 bytes) | From: 10/Mar/2010:00:27:47 | To: 10/Mar/2010:16:51:09 | dominio1.com.ar.log
187.096 MB (196184596 bytes) | From: 10/Mar/2010:03:24:55 | To: 10/Mar/2010:16:51:24 | dominio2.com.ar.log
245.692 MB (257626221 bytes) | From: 10/Mar/2010:02:53:50 | To: 10/Mar/2010:16:39:54 | dominio3.com.log
273.46 MB (286743390 bytes) | From: 10/Mar/2010:02:48:33 | To: 10/Mar/2010:14:59:29 | dominio4.com.ar.log
306.344 MB (321224473 bytes) | From: 10/Mar/2010:00:23:09 | To: 10/Mar/2010:16:51:20 | dominio5.com.ar.log
444.097 MB (465669066 bytes) | From: 10/Mar/2010:00:49:35 | To: 10/Mar/2010:16:51:20 | dominio6.com.ar.log
Generated in 6 seconds</pre>
<p>Les dejo, de yapa, la opción del script utilizando los logs de bytes. Como dije, esta opción es un poco más sencilla y veloz, pero no nos dice las fechas de los logs.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="re3">#!/bin/bash</span></p>
<p><span class="kw1">if</span> <span class="br0">&#91;</span> -z $<span class="nu0">1</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;Usage: $0 &quot;</span><br />
&nbsp; &nbsp; <span class="kw3">exit</span> <span class="nu0">1</span><br />
<span class="kw1">fi</span></p>
<p><span class="re2">BASE_DIR=</span>$<span class="nu0">1</span><br />
<span class="re2">T1=</span>`<span class="kw2">date</span> +%s`<br />
<span class="kw1">for</span> <span class="kw2">file</span> <span class="kw1">in</span> <span class="re1">$BASE_DIR</span>/*.bytes;<br />
<span class="kw1">do</span><br />
&nbsp; &nbsp; <span class="re2">size=</span>`<span class="kw2">stat</span> -c %s <span class="re1">$file</span>`<br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re1">$size</span> -gt <span class="nu0">0</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">bytes=</span>`<span class="kw2">cat</span> <span class="re1">$file</span> | <span class="kw2">awk</span> <span class="st0">&#8216;{a+=$1}END{print a}&#8217;</span>`<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">mbytes=</span>`<span class="kw3">echo</span> <span class="re1">$bytes</span> | <span class="kw2">awk</span> <span class="st0">&#8216;{print $1 / 1048576}&#8217;</span>`<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> &nbsp;<span class="st0">&quot;$mbytes MB ($bytes bytes) ${file:${#BASE_DIR}+1}&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">fi</span><br />
<span class="kw1">done</span> \<br />
| <span class="kw2">sort</span> -nb<br />
<span class="re2">T=</span>`<span class="kw2">date</span> +%s`<br />
<span class="kw3">echo</span> <span class="st0">&quot;Generated in $(($T-$T1)) seconds&quot;</span></div>
<p>Y la salida sería así:</p>
<pre># ./parser.sh /var/log/httpd/domains
...
181.716 MB (190543470 bytes) dominio1.com.bytes
187.115 MB (196203973 bytes) dominio2.com.ar.bytes
189.093 MB (198278283 bytes) dominio3.com.ar.bytes
245.692 MB (257626221 bytes) dominio4.com.bytes
273.472 MB (286756234 bytes) dominio5.com.ar.bytes
314.32 MB (329588717 bytes) dominio6.com.ar.bytes
444.516 MB (466108759 bytes) dominio7.com.ar.bytes
Generated in 2 seconds</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/ver-dominios-de-apache-que-mas-transferencia-consumen.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grave exploit para Apache descubierto</title>
		<link>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/grave-exploit-para-apache-descubierto.html</link>
		<comments>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/grave-exploit-para-apache-descubierto.html#comments</comments>
		<pubDate>Mon, 08 Mar 2010 21:31:30 +0000</pubDate>
		<dc:creator>elbarto</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[bugs]]></category>
		<category><![CDATA[custombuild]]></category>

		<guid isPermaLink="false">http://www.tail-f.com.ar/?p=348</guid>
		<description><![CDATA[Leo en Slashdot que se descubrió un grave exploit para Apache. De acuerdo con la nota de ZDNet, la compañía de seguridad &#8220;Sense of Security&#8221; descubrió un serio bug en el servidor web Apache que podría permitir a un atacante remoto obtener control sobre una base de datos. Una vulnerabilidad existente en el módulo &#8220;mod_isapi&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.tail-f.com.ar/wp-content/uploads/apache1.gif"><img class="size-medium wp-image-37 alignright" title="apache1" src="http://www.tail-f.com.ar/wp-content/uploads/apache1-300x300.gif" alt="" /></a></p>
<p>Leo en <a href="http://tech.slashdot.org/story/10/03/08/1258200/Serious-Apache-Exploit-Discovered">Slashdot</a> que se descubrió un grave exploit para Apache. De acuerdo con la <a href="http://www.zdnet.com.au/news/security/soa/Apache-bug-prompts-update-advice/0,130061744,339301617,00.htm">nota de ZDNet</a>, la compañía de seguridad &#8220;Sense of Security&#8221; descubrió un serio bug en el servidor web Apache que podría permitir a un atacante remoto obtener control sobre una base de datos. Una vulnerabilidad existente en el módulo &#8220;mod_isapi&#8221; del core de Apache podría permitirle a un atacante obtener privilegios de administrador, comprometiendo seriamente la seguridad de la información.</p>
<p>La nota de ZDNet no da muchos detalles del bug, pero indica que comprometería especialmente a los servidores Windows. Por otra parte, el <a href="http://www.senseofsecurity.com.au/advisories/SOS-10-002">reporte de Sense of Security</a> es más detallado e incluye una &#8220;prueba de concepto&#8221; acerca de cómo explotar el bug.</p>
<p>Se recomienda actualizar a la <a href="http://httpd.apache.org/download.cgi#apache22">versión 2.2.15 de Apache</a> que corrige el bug.</p>
<p><a href="http://www.tail-f.com.ar/tag/directadmin">Directadmin</a> ya ha hecho los cambios correspondientes, así que con <a href="http://www.tail-f.com.ar/2008/11/22/paneles-de-control/directadmin/custombuild-en-directadmin.html">Custombuild</a> podemos actualizar rápida y fácilmente a la nueva versión siguiendo el <a href="http://www.tail-f.com.ar/paneles-de-control/directadmin/actualizar-software-con-custombuild-para-directadmin.html">procedimiento</a> que explique recientemente.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/grave-exploit-para-apache-descubierto.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tips Apache: ver configuración desde la línea de comandos</title>
		<link>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/tips-apache-ver-configuracion.html</link>
		<comments>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/tips-apache-ver-configuracion.html#comments</comments>
		<pubDate>Mon, 01 Mar 2010 16:19:28 +0000</pubDate>
		<dc:creator>elbarto</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://www.tail-f.com.ar/?p=327</guid>
		<description><![CDATA[A veces queremos saber algunas cosas de la configuración de Apache, pero no queremos revisar el httpd.conf ni seguir sus includes. El binario httpd acepta algunos parámetros que nos pueden servir, proveyéndonos esa información. Dejo un par de ejemplos. Verificar sintaxis de los archivos de configuración Muy facilmente podemos pedirle al Apache que verifique la [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_37" class="wp-caption alignright" style="width: 220px"><a href="http://www.tail-f.com.ar/wp-content/uploads/apache1.gif"><img class="size-medium wp-image-37 " title="apache1" src="http://www.tail-f.com.ar/wp-content/uploads/apache1-300x300.gif" alt="" width="210" height="210" /></a><p class="wp-caption-text">Apache Web Server</p></div>
<p>A veces queremos saber algunas cosas de la configuración de Apache, pero no queremos revisar el httpd.conf ni seguir sus includes. El binario httpd acepta algunos parámetros que nos pueden servir, proveyéndonos esa información. Dejo un par de ejemplos.</p>
<p><strong>Verificar sintaxis de los archivos de configuración</strong></p>
<p>Muy facilmente podemos pedirle al Apache que verifique la sintaxis de los archivos de configuración. Esto es útil por si hicimos una modificación de la que no estamos seguros y queremos verificarla antes de reiniciar el servicio (y dejar a los clientes sin servicio hasta que lo resolvamos).</p>
<p>Comando:</p>
<pre>httpd -t</pre>
<p>Salida:</p>
<pre>Syntax OK</pre>
<p><strong>Obtener versión de Apache</strong></p>
<p>La más sencilla y obvia, para ver la versión de Apache sólo basta con:</p>
<pre>httpd -v</pre>
<p>Y la salida es algo así:</p>
<pre>Server version: Apache/2.2.14 (Unix)
Server built:   Jan 28 2010 12:43:06</pre>
<p><strong>Ver información de compilación</strong></p>
<p>Eventualmente podemos querer tener algunos datos sobre cómo fue compilado Apache.<br />
Esta es una versión más completa de lo que ofrece httpd -v.<br />
Entre otros datos, nos sirve para saber qué módulo de MPM está usando Apache.</p>
<p>Comando:</p>
<pre>httpd -V</pre>
<p>Salida:</p>
<pre>Server version: Apache/2.2.14 (Unix)
Server built:   Jan 28 2010 12:43:06
Server's Module Magic Number: 20051115:23
Server loaded:  APR 1.3.9, APR-Util 1.3.9
Compiled using: APR 1.3.9, APR-Util 1.3.9
Architecture:   32-bit
Server MPM:     Prefork
  threaded:     no
    forked:     yes (variable process count)
Server compiled with....
 -D APACHE_MPM_DIR="server/mpm/prefork"
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_SYSVSEM_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=128
 -D HTTPD_ROOT="/etc/httpd"
 -D SUEXEC_BIN="/usr/sbin/suexec"
 -D DEFAULT_PIDLOG="/var/logs/httpd.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_LOCKFILE="/var/logs/accept.lock"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="conf/mime.types"
 -D SERVER_CONFIG_FILE="conf/httpd.conf"</pre>
<p><strong>Ver módulos</strong></p>
<p>Hay dos alternativas diferentes para ver los módulos. Por un lado podemos ver todos los módulos que están compilados con Apache. Por otro lado, podemos ver todos los módulos que carga Apache (esto incluye módulos compilados aparte).</p>
<p>Módulos compilados</p>
<pre>httpd -l</pre>
<p>Esto no muestra el listado de módulos compilados en el binario de Apache:</p>
<pre>Compiled in modules:
  core.c
  mod_authn_file.c
  mod_authn_default.c
  mod_authz_host.c
  mod_authz_groupfile.c
  mod_authz_user.c
  mod_authz_default.c
  mod_auth_basic.c
  mod_include.c
  mod_filter.c
  mod_deflate.c
  mod_log_config.c
  mod_logio.c
  mod_env.c
  mod_headers.c
  mod_unique_id.c
  mod_setenvif.c
  mod_version.c
  mod_proxy.c
  mod_proxy_connect.c
  mod_proxy_ftp.c
  mod_proxy_http.c
  mod_proxy_scgi.c
  mod_proxy_ajp.c
  mod_proxy_balancer.c
  mod_ssl.c
  prefork.c
  http_core.c
  mod_mime.c
  mod_dav.c
  mod_status.c
  mod_autoindex.c
  mod_asis.c
  mod_suexec.c
  mod_cgi.c
  mod_dav_fs.c
  mod_dav_lock.c
  mod_negotiation.c
  mod_dir.c
  mod_actions.c
  mod_userdir.c
  mod_alias.c
  mod_rewrite.c
  mod_so.c</pre>
<p>Módulos cargados:</p>
<pre>httpd -M</pre>
<p>Así veremos todos los módulos que carga Apache:</p>
<pre>Loaded Modules:
 core_module (static)
 authn_file_module (static)
 authn_default_module (static)
 authz_host_module (static)
 authz_groupfile_module (static)
 authz_user_module (static)
 authz_default_module (static)
 auth_basic_module (static)
 include_module (static)
 filter_module (static)
 deflate_module (static)
 log_config_module (static)
 logio_module (static)
 env_module (static)
 headers_module (static)
 unique_id_module (static)
 setenvif_module (static)
 version_module (static)
 proxy_module (static)
 proxy_connect_module (static)
 proxy_ftp_module (static)
 proxy_http_module (static)
 proxy_scgi_module (static)
 proxy_ajp_module (static)
 proxy_balancer_module (static)
 ssl_module (static)
 mpm_prefork_module (static)
 http_module (static)
 mime_module (static)
 dav_module (static)
 status_module (static)
 autoindex_module (static)
 asis_module (static)
 suexec_module (static)
 cgi_module (static)
 dav_fs_module (static)
 dav_lock_module (static)
 negotiation_module (static)
 dir_module (static)
 actions_module (static)
 userdir_module (static)
 alias_module (static)
 rewrite_module (static)
 so_module (static)
 python_module (shared)
 evasive20_module (shared)
 qos_module (shared)
 php5_module (shared)
Syntax OK</pre>
<p>Aquí se puede notar la diferencia entre los módulos compilados con el Apache (linkeados como &#8216;static&#8217;) y los compilados como objetos compartidos que se cargan en tiempo de ejecución (&#8216;shared&#8217;).</p>
<p><strong>Ver virtual hosts</strong></p>
<p>También podemos ver todos los virtual hosts que están configurados en el Apache.</p>
<pre>httpd -S</pre>
<p>Esto nos va a mostrar una lista como esta:</p>
<pre>VirtualHost configuration:
1.1.1.1:80       is a NameVirtualHost
         default server localhost (/etc/httpd/conf/extra/httpd-vhosts.conf:29)
         port 80 namevhost localhost (/etc/httpd/conf/extra/httpd-vhosts.conf:29)
         port 80 namevhost www.midominio.com (/usr/local/directadmin/data/users/usuario/httpd.conf:11)
1.1.1.1:443      is a NameVirtualHost
         default server localhost (/etc/httpd/conf/extra/httpd-vhosts.conf:38)
         port 443 namevhost localhost (/etc/httpd/conf/extra/httpd-vhosts.conf:38)
         port 443 namevhost www.midominio.com (/usr/local/directadmin/data/users/usuario/httpd.conf:48)</pre>
<p>En el ejemplo vemos un hipotético servidor (usando Directadmin) con IP 1.1.1.1, y los virtual hosts para el puerto 80 y el 443, tanto los default como los que corresponden al dominio &#8220;www.midominio.com&#8221; del usuario llamado &#8220;usuario&#8221;.</p>
<p><strong>Nota sobre diferentes distribuciones</strong></p>
<p>El artículo lo escribí pensando en CentOS y otras distros donde el binario de Apache se llama httpd. En Debian y sus derivados, el binario es apache o apache2. Todos los comandos que comenté acá se pueden correr invocando esos binarios o apachectl (que en algunos casos puede ser apache2ctl).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/tips-apache-ver-configuracion.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Apache: 15 años</title>
		<link>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/apache-15-anos.html</link>
		<comments>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/apache-15-anos.html#comments</comments>
		<pubDate>Tue, 23 Feb 2010 18:19:48 +0000</pubDate>
		<dc:creator>elbarto</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Noticias]]></category>
		<category><![CDATA[aniversario]]></category>
		<category><![CDATA[historia]]></category>

		<guid isPermaLink="false">http://www.tail-f.com.ar/?p=322</guid>
		<description><![CDATA[Un 23 de Febrero, pero del año 1995, nacía Apache, el servidor HTTP multiplataforma y de código abierto más usado en el mundo. En sus inicios, Apache consistía solamente en un conjunto de parches a aplicar al servidor de NCSA, pero luego su código fue reescrito por completo. Dicen que su nombre se debe a que [...]]]></description>
			<content:encoded><![CDATA[<p>Un 23 de Febrero, pero del año 1995, nacía <a href="http://www.apache.org/" target="_blank"><strong>Apache</strong></a>, el servidor HTTP multiplataforma y de código abierto más usado en el mundo.</p>
<p><a href="http://www.tail-f.com.ar/wp-content/uploads/apache1.gif"><img class="size-medium wp-image-37 alignright" title="apache1" src="http://www.tail-f.com.ar/wp-content/uploads/apache1-300x300.gif" alt="" width="180" height="180" /></a></p>
<p>En sus inicios, Apache consistía solamente en un conjunto de parches a aplicar al servidor de NCSA, pero luego su código fue reescrito por completo.</p>
<p>Dicen que su nombre se debe a que querían que tuviese la connotación de algo que es firme y enérgico pero no agresivo, y la tribu Apache fue la última en rendirse al que pronto se convertiría en gobierno de EEUU, y en esos momentos la preocupación de su grupo era que llegasen las empresas y “civilizasen” el paisaje que habían creado los primeros ingenieros de internet.</p>
<p>En el <a href="http://blogs.apache.org/foundation/entry/the_apache_software_foundation_announces2"><strong>blog de la Fundación Apache</strong></a>, comentan hoy el aniversario y relatan un poco su historia.</p>
<p>Tomado de <a href="http://www.ubuntips.com.ar/2010/02/23/15-anos-de-apache/">Ubuntips</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/apache-15-anos.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mod_wsgi + Python 2.6 en CentOS</title>
		<link>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/mod_wsgi-python-2-6-en-centos.html</link>
		<comments>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/mod_wsgi-python-2-6-en-centos.html#comments</comments>
		<pubDate>Sun, 14 Feb 2010 22:08:19 +0000</pubDate>
		<dc:creator>elbarto</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[mod_wsgi]]></category>

		<guid isPermaLink="false">http://www.tail-f.com.ar/?p=313</guid>
		<description><![CDATA[Guía de instalación de mod_wsgi con Apache y Python 2.6 en CentOS.]]></description>
			<content:encoded><![CDATA[<div id="attachment_100" class="wp-caption alignright" style="width: 221px"><a href="http://www.tail-f.com.ar/wp-content/uploads/python-logo.gif"><img class="size-full wp-image-100" title="Python" src="http://www.tail-f.com.ar/wp-content/uploads/python-logo.gif" alt="" width="211" height="71" /></a><p class="wp-caption-text">Python</p></div>
<p>Hace algún tiempo publiqué un artículo donde explicaba cómo instalar <a href="http://www.tail-f.com.ar/2009/03/14/servicios/httpd/apache-httpd-servicios/mod_python-python-26-en-centos.html">mod_python con Python 2.6 en CentOS</a>, por el problemita que tiene yum que no funciona con la última versión de Python. Pues bien, últimamente por lo que he venido leyendo, una alternativa mejor a mod_python es <a href="http://code.google.com/p/modwsgi">mod_wsgi</a>, pues aparentemente funciona bastante mejor, más rápido y es la opción recomendada para usar con Apache y <a href="http://www.djangoproject.com/">Django</a>.</p>
<p>Por lo tanto, dejo esta guía muy sencilla de cómo instalar mod_wsgi con Python 2.6 en CentOS.</p>
<p>Descargar mod_wsgi, descomprimir y configurar</p>
<pre># cd /usr/src
# wget http://modwsgi.googlecode.com/files/mod_wsgi-3.1.tar.gz
# tar zxvf mod_wsgi-3.1.tar.gz
# cd mod_wsgi-3.1
# ./configure --with-python=/usr/bin/python2.6</pre>
<p>Esa última línea es la clave para que utilice la instalación correcta de Python (ver el <a href="http://www.tail-f.com.ar/2009/03/14/servicios/httpd/apache-httpd-servicios/mod_python-python-26-en-centos.html">artículo anterior</a> para saber cómo instalar Python 2.6 sin pisar la versión actual).</p>
<p>Luego compilamos e instalamos</p>
<pre># make &amp;&amp; make install</pre>
<p>Agregamos la línea para cargar el módulo en el httpd.conf</p>
<pre>LoadModule wsgi_module        lib/apache/mod_wsgi.so</pre>
<p>Y reiniciamos el Apache</p>
<pre>service httpd restart</pre>
<p>Luego para configurar un virtual host para que utilice mod_wsgi no es tan sencillo, pero tampoco es demasiado complicado. Básicamente hay que generar un archivo .wsgi, que no es más que un archivo Python que va a ser el que se integre con mod_wsgi y luego configurarlo en el httpd.conf. Lo que hay que tener en cuenta es que mod_wsgi no sirve contenido estático, por lo cual uno debe configurar por un lado el handling del código python y por otro los archivos estáticos. Si bien es algo distinto a lo que solemos hacer con mod_php, es algo bastante lógico y es una buena práctica pensar en servir por separado el contenido dinámico y el estático.</p>
<p>Como es un poco complejo, lo mejor es leer la guía correspondiente. En el <a href="http://code.google.com/p/modwsgi/">sitio de mod_wsgi</a> van a ver que hay mucha documentación. Particularmente, la guía de <a href="http://code.google.com/p/modwsgi/wiki/IntegrationWithDjango">integración con Django</a> es muy útil.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/mod_wsgi-python-2-6-en-centos.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>mod_python + Python 2.6 en CentOS</title>
		<link>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/mod_python-python-26-en-centos.html</link>
		<comments>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/mod_python-python-26-en-centos.html#comments</comments>
		<pubDate>Sat, 14 Mar 2009 21:03:06 +0000</pubDate>
		<dc:creator>elbarto</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[mod_python]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Python 2.6]]></category>

		<guid isPermaLink="false">http://www.tail-f.com.ar/?p=258</guid>
		<description><![CDATA[Hace algún tiempo escribí un pequeño artículo sobre cómo instalar mod_python en Apache 2.2. El tema es que, lógicamente, cada tanto uno quiere actualizar Python para tener las últimas correcciones de bugs y los últimos features. En mi caso quería instalar Python 2.6.1 en un CentOS. El tema es que con yum no veía ninguna [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_166" class="wp-caption alignright" style="width: 278px"><img class="size-full wp-image-166" title="mod_python" src="http://www.tail-f.com.ar/wp-content/uploads/mod_python.gif" alt="mod_python" width="268" height="164" /><p class="wp-caption-text">mod_python</p></div>
<p>Hace algún tiempo escribí un pequeño artículo sobre <a href="http://www.tail-f.com.ar/2009/01/01/servicios/httpd/apache-httpd-servicios/instalar-mod_python-para-apache-22.html">cómo instalar mod_python en Apache 2.2</a>. El tema es que, lógicamente, cada tanto uno quiere actualizar Python para tener las últimas correcciones de bugs y los últimos features. En mi caso quería instalar Python 2.6.1 en un CentOS. El tema es que con yum no veía ninguna actualización, pero tenía Python 2.4.x instalado y yo quería lo último. Me bajé el código, lo compilé, lo instalé y al rato me di cuenta que al hacer eso había roto el yum (que está escrito en Python). Así fue que llegué a darme cuenta de cómo instalar Python 2.6.1 por separado, y recompilar mod_python para que trabaje con esa versión, y esto es lo que quería compartir con ustedes.</p>
<p><strong>Primero: Instalar Python 2.6 en una ubicación alternativa</strong></p>
<p>Lo primero que vamos a hacer es descargar, compilar e instalar Python 2.6 en una ruta alternativa, es decir, sin pisar la instalación actual de Python 2.4 que viene con CentOS.</p>
<pre># cd /usr/src
# wget http://www.python.org/ftp/python/2.6.1/Python-2.6.1.tgz
# tar zxvf Python-2.6.1.tgz
# cd Python-2.6.1/
# ./configure --prefix=/usr
# make
# make altinstall</pre>
<p>La clave está justamente en el último paso. En vez de hacer &#8220;make install&#8221;, hacemos &#8220;make altinstall&#8221; para que se instale sin sobreescribir la versión actual de Python. Básicamente lo que hace es instalar todas las libs en /usr/lib/python2.6 (esto lo hace de todas formas), y luego crear el binario /usr/bin/python2.6 pero sin sobreescribir /usr/bin/python.</p>
<p>Editado el 10/03/2010: En algunos casos puede ser necesario agregar al configure de Python la opción &#8211;enable-shared. Gracias Orcen!</p>
<p><strong>Segundo: Recompilar mod_python</strong></p>
<p>Ahora queda recompilar mod_python contra la nueva versión de python.</p>
<pre># cd /usr/src
# wget http://www.apache.org/dist/httpd/modpython/mod_python-3.3.1.tgz
# tar -zxvf mod_python-3.3.1.tgz
# cd mod_python-3.3.1
# ./configure --with-python=/usr/bin/python2.6
# make
# make install</pre>
<p>La clave aquí está en el configure al que le pasamos el parámetro de qué binario de Python debe usar.</p>
<p><strong>Tercero: Reiniciar Apache y probar</strong></p>
<p>Por último queda reiniciar Apache y repetir <a href="http://www.tail-f.com.ar/2009/01/01/servicios/httpd/apache-httpd-servicios/instalar-mod_python-para-apache-22.html">la prueba explicada en el artículo anterior</a>.</p>
<pre># service httpd restart</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/mod_python-python-26-en-centos.html/feed</wfw:commentRss>
		<slash:comments>36</slash:comments>
		</item>
		<item>
		<title>Instalar mod_evasive en Apache para dificultar ataques DoS</title>
		<link>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/instalar-mod_evasive-en-apache-para-dificultar-ataques-dos.html</link>
		<comments>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/instalar-mod_evasive-en-apache-para-dificultar-ataques-dos.html#comments</comments>
		<pubDate>Sat, 07 Feb 2009 17:46:09 +0000</pubDate>
		<dc:creator>elbarto</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[DDoS]]></category>
		<category><![CDATA[DoS]]></category>
		<category><![CDATA[mod_evasive]]></category>
		<category><![CDATA[seguridad]]></category>

		<guid isPermaLink="false">http://www.tail-f.com.ar/?p=219</guid>
		<description><![CDATA[Describiremos a continuación los pasos para la instalación y configuración de mod_evasive, un módulo para Apache desarrollado por Nuclear Elephant para prevenir ataques DoS. Antes que nada es preciso advertir que no se trata de una solución definitiva y que, incluso, bajo ataques importantes, no sirve de mucho. Pero es una buena forma de evitar [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_37" class="wp-caption alignright" style="width: 310px"><a href="http://www.tail-f.com.ar/wp-content/uploads/apache1.gif"><img class="size-medium wp-image-37" title="apache1" src="http://www.tail-f.com.ar/wp-content/uploads/apache1-300x300.gif" alt="Apache Web Server" width="300" height="300" /></a><p class="wp-caption-text">Apache Web Server</p></div>
<p>Describiremos a continuación los pasos para la instalación y configuración de <a href="http://www.zdziarski.com/projects/mod_evasive/">mod_evasive</a>, un módulo para Apache desarrollado por <a href="http://www.zdziarski.com/projects.html">Nuclear Elephant</a> para prevenir ataques <a href="http://en.wikipedia.org/wiki/Denial-of-service_attack">DoS</a>. Antes que nada es preciso advertir que no se trata de una solución definitiva y que, incluso, bajo ataques importantes, no sirve de mucho. Pero es una buena forma de evitar ataques pequeños y mantener la salud de nuestro servidor.</p>
<p><strong>¿Cómo funciona?</strong></p>
<p>Básicamente lo que hace es mantener una tabla dinámica con las URIs accedidas por las distintas IPs de los clientes del Apache, y permite ejecutar algunas acciones cuando una misma IP solicita un mismo recurso (una misma URI o elementos de un mismo sitio) más de n veces en m segundos. La acción por default que ejecuta el mod_evasive es, una vez superado el máximo de requests por segundo permitidos, bloquear durante una cantidad de segundos al cliente (la IP) devolviendo un error 403 (Forbidden) a la petición HTTP. Pero lo interesante es que también permite ejecutar un comando de sistema al registrarse un intento de ataque, con lo cual se puede agregar una regla al iptables para bloquear la IP del cliente.</p>
<p><strong>Instalación</strong></p>
<p>La instalación es muy sencilla. Basta con descargar el tar, descomprimirlo, compilarlo con <a href="http://httpd.apache.org/docs/2.2/programs/apxs.html">apxs</a> y habilitarlo en el httpd.conf.</p>
<pre># cd /usr/src
# wget http://www.zdziarski.com/projects/mod_evasive/mod_evasive_1.10.1.tar.gz
# tar zxvf mod_evasive_1.10.1.tar.gz
# cd mod_evasive
# apxs -cia mod_evasive20.c # para Apache 1.3 el comando sería apxs -cia mod_evasive.c
# vi /etc/httpd/conf/httpd.conf # editamos la configuracion
# service httpd restart # reiniciamos el Apache</pre>
<p>En el httpd.conf habría que agregar las siguientes líneas.</p>
<pre>
&lt;IfModule mod_evasive20.c&gt;
DOSHashTableSize 3097
DOSPageCount 2
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 300
&lt;/IfModule&gt;
</pre>
<p><strong>Opciones de configuración</strong></p>
<p>A continuación transcribo la descripción de las distintas opciones de configuración tomada de <a href="http://www.xombra.com/go_articulo.php?nota=89">esta excelente guía de Xombra Team</a>.</p>
<ul>
<li><strong> DOSHashTableSize</strong> &lt;valor&gt; &#8211; Establece el número de nodos a almacenar para cada proceso de peticiones de la tabla hash (contenedor asociativo de recuperación de peticiones por medio de claves que agiliza las respuestas del servidor). Si aplicamos un número alto a este parámetro obtendremos un rendimiento mayor, ya que las iteraciones necesarias para obtener un registro de la tabla son menores. Por contra, y de forma evidente, aumenta el consumo de memoria necesario para el almacenamiento de una tabla mayor. Se hace necesario incrementar este parámetro si el servidor atiende un número abultado de peticiones, aunque puede no servir de nada si la memoria de la máquina es escasa.</li>
<li><strong>DOSPageCount</strong> &lt;valor&gt; &#8211; Indica el valor del umbral para el número de peticiones de una misma página (o URI) dentro del intervalo definido en DOSPageInterval. Cuando el valor del parámetro es excedido, la IP del cliente se añade a la lista de bloqueos.</li>
<li> <strong>DOSSiteCount</strong> &lt;valor&gt; &#8211; Cuenta cuántas peticiones de cualquier tipo puede hacer un cliente dentro del intervalo definido en DOSSiteInterval. Si se excede dicho valor, el cliente queda añadido a la lista de bloqueos.</li>
<li><strong>DOSPageInterval</strong> &lt;valor&gt; &#8211; El intervalo, en segundos, para el umbral de petición de páginas.</li>
<li><strong>DOSSiteInterval</strong> &lt;valor&gt; &#8211; El intervalo, en segundos, para el umbral de petición de objetos de cualquier tipo.</li>
<li><strong>DOSBlockingPeriod</strong> &lt;valor&gt; &#8211; Establece el tiempo, en segundos, que un cliente queda bloqueado una vez que ha sido añadido a la lista de bloqueos. Como ya se indicó unas líneas atrás, todo cliente bloqueado recibirá una respuesta del tipo 403 (Forbidden) a cualquier petición que realice durante este periodo.</li>
<li><strong>DOSEmailNotify</strong> &lt;e-mail&gt; &#8211; Un e-mail será enviado a la dirección especificada cuando una dirección IP quede bloqueada. La configuración del proceso de envío se establece en el fichero mod_evasive.c de la forma /bin/mail -t %s, siendo %s el parámetro que queda configurado en este parámetro. Será necesario cambiar el proceso si usamos un método diferente de envío de e-mails y volver a compilar el módulo con apxs (por ejemplo, la opción t ha quedado obsoleta en las últimas versiones del comando).</li>
<li><strong>DOSSystemCommand</strong> &lt;comando&gt; &#8211; El comando reflejado se ejecutará cuando una dirección IP quede bloqueada. Se hace muy útil en llamadas a herramientas de filtrado o firewalls. Usaremos %s para especificar la dirección IP implicada. Por ejemplo, podemos establecer su uso con iptables de la forma siguiente:
<pre>DOSSystemCommand “/sbin/iptables –I INPUT –p tcp –dport 80 –s %s –j DROP”</pre>
</li>
<li><strong>DOSLogDir</strong> &lt;ruta&gt; &#8211; Establece una ruta para el directorio temporal. Por defecto, dicha ruta queda establecida en /tmp, lo cual puede originar algunos agujeros de seguridad si el sistema resulta violado.</li>
<li><strong>DOSWhitelist</strong> &lt;IP&gt; &#8211; La dirección IP indicada como valor del parámetro no será tenida en cuenta por el módulo en ningún caso. Para cada dirección IP a excluir ha de añadirse una nueva línea con el parámetro. Por ejemplo, dejaremos fuera del chequeo del módulo a un posible bot que use los siguientes rangos de direcciones:
<pre>DOSWhitelist 66.249.65.*
DOSWhitelist 66.249.66.*</pre>
</li>
</ul>
<p><strong>Probarlo</strong></p>
<p>¿Y cómo sé si está funcionando? mod_evasive viene con un pequeño script en perl para probar el funcionamiento del módulo. Para eso vamos al directorio de mod_evasive y ejecutamos el script test.pl:</p>
<pre># cd /usr/src/mod_evasive
# perl test.pl
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden</pre>
<p>Y si pusimos la directiva para bloquear la IP por iptables podemos verlo con:</p>
<pre># iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP tcp --  anywhere tcp dpt:http</pre>
<p><strong>Referencias</strong></p>
<ul>
<li><a href="http://www.zdziarski.com/projects/mod_evasive/">Sitio oficial</a></li>
<li><a href="http://www.zdziarski.com/projects/mod_evasive/mod_evasive_1.10.1.tar.gz">Descargar versión 1.10.1</a></li>
<li><a href="http://www.xombra.com/go_articulo.php?nota=89">Guía de Xombra Team</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/instalar-mod_evasive-en-apache-para-dificultar-ataques-dos.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Apache: solucionar &#8220;(28) No space left on device&#8221;</title>
		<link>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/apache-solucionar-28-no-space-left-on-device.html</link>
		<comments>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/apache-solucionar-28-no-space-left-on-device.html#comments</comments>
		<pubDate>Tue, 13 Jan 2009 17:09:20 +0000</pubDate>
		<dc:creator>elbarto</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[errores]]></category>
		<category><![CDATA[no space left on device]]></category>

		<guid isPermaLink="false">http://www.tail-f.com.ar/?p=197</guid>
		<description><![CDATA[Recién me topé con un error medio raro, que jamás me había sucedido y afortunadamente encontré rápido la solución en internet. Por eso me pareció bueno compartirlo, para que si se encuentran con este error sepan cómo corregirlo y para que quede la solución online por si a otra persona le sucede. De repente me [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_37" class="wp-caption alignright" style="width: 160px"><a href="http://www.tail-f.com.ar/wp-content/uploads/apache1.gif"><img class="size-thumbnail wp-image-37" title="apache1" src="http://www.tail-f.com.ar/wp-content/uploads/apache1-150x150.gif" alt="Apache Web Server" width="150" height="150" /></a><p class="wp-caption-text">Apache Web Server</p></div>
<p>Recién me topé con un error medio raro, que jamás me había sucedido y afortunadamente encontré rápido la solución en internet. Por eso me pareció bueno compartirlo, para que si se encuentran con este error sepan cómo corregirlo y para que quede la solución online por si a otra persona le sucede.</p>
<p>De repente me avisan que está caído el Apache de uno de los servers y que al reiniciarlo no levanta. Entro al servidor y veo que efectivamente falla al iniciar. Reviso el error log y veo lo siguiente:</p>
<pre>[Tue Jan 13 14:34:03 2009] [notice] mod_python: Creating 8 session mutexes based on 450 max processes and 0 max threads.
[Tue Jan 13 14:34:03 2009] [notice] mod_python: using mutex_directory /tmp
[Tue Jan 13 14:34:03 2009] [error] (28)No space left on device: mod_python: Failed to create global mutex 0 of 8 (/tmp/mpmtx297990).
Configuration Failed</pre>
<p>No me parecía que pudiera haber un error con mod_python porque siempre funcionó. De todas formas, lo deshabilité, probé de nuevo y me daba el mismo error en otra parte:</p>
<pre>[Tue Jan 13 14:31:05 2009] [emerg] (28)No space left on device: Couldn't create accept lock (/var/logs/accept.lock.29427) (5)</pre>
<p>Evidentemente el problema iba por otro lado, y lo primero que pensé era que me estaba quedando sin espacio en el disco. Revisé eso y tampoco. El consumo del disco era muy bajo (25%). Entonces recurrí a Google y encontré la solución en <a href="http://www.ehow.com/how_4397601_error-no-space-left-device.html">eHow</a>.</p>
<p>Al parecer es un problema común, que se solucione revisando los arrays de semáforos que está usando el Apache y removiéndolos.</p>
<pre># Revisar los semáforos de Apache
ipcs -s | grep apache
# Remover todos los semáforos
for i in `ipcs -s | grep apache | awk '{print $2}'` ; do ipcrm -s $i; done
# Iniciar Apache
service httpd start</pre>
<p>Fuente: <a href="http://www.ehow.com/how_4397601_error-no-space-left-device.html">http://www.ehow.com/how_4397601_error-no-space-left-device.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/apache-solucionar-28-no-space-left-on-device.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

