Archive for the ‘Sistemas’ Category
Oferta de Administrador de Sistemas Junior en The Cocktail
The Cocktail es una consultora de internet, enfocada en la experiencia de usuario y diseño de producto, especialista en traducir objetivos de negocio en productos digitales innovadores, usables, atractivos y rentables.
Queremos incorporar a nuestro equipo de trabajo un Administrador de Sistemas Junior con experiencia en manejo de sistemas Linux, redes TCP/IP , y especialmente interés y compromiso por el open source. Realizará las siguientes tareas:
- Administración de servidores *nix – Particularmente Debian.
- Instalación y despliegue de nuevos servidores en producción y en desarrollo. Compilación de software.
- Monitorización y backups.
- Configuración de routers, switches, firewalls y balanceadores de carga.
- Mantenimiento de la red local, accesos remotos VPN y políticas de acceso a recursos.
Los requisitos mínimos son:
- Experiencia administrando sistemas Linux.
- Experiencia con Debian – GNU/Linux, MySQL, Apache.
- Conocimientos sobre redes TCP/IP.
- Interés y compromiso por el open source.
- Facilidad para trabajar en equipo. Auto-disciplina y atención a los detalles. Iniciativa y proactividad.
- Conocimiento e interés por Ruby On Rails y lenguajes de programación dinámicos.
- Experiencia con varias de las siguientes tecnologías: Apache, MySQL, Bash, Ruby, Samba, Postfix, Nagios, Xen, Iptables, Subversion, Git, Rsync, LDAP
Y por supuesto el mayor de los requisitos es que crea que es capaz de desempeñar este trabajo, teniendo en cuenta las responsabilidades arriba mencionadas.
El trabajo es de carácter presencial en las oficinas de Madrid en horario de jornada partida.
Si estás interesado, envía tu CV a: andrea.hidalgo ARROBA the-cocktail PUNTO com
Gráficas de uso de memoria de passenger con Munin
Estaba instalando algunos plugins adicionales en el munin para monitorizar el estado de las peticiones que entran por Apache.
He encontrado uno para monitorizar el uso de memoria pero se ha quedado anticuado con respecto a ciertos cambios que ha sufrido la salida del comando passenger-memory-stats. Por lo tanto ya no sirve.
Basándome en dicho plugin y en este otro, he hecho algunos cambios y el código resultante es el siguiente:
#!/usr/bin/env ruby
def output_config
puts <<-END
graph_category Passenger
graph_title passenger memory stats
graph_vlabel megabytes
apache_memory.label apache_memory
passenger_memory.label passenger_memory
END
exit 0
end
def output_values
memory_stats_command = '/usr/bin/passenger-memory-stats'
memory = {}
apache_header = "Apache processes"
passenger_header = "Passenger processes"
nginx_header = "Nginx processes"
section = nil
`#{memory_stats_command}`.each_line do |line|
if line.include?(apache_header)
section = "apache"
elsif line.include?(nginx_header)
section = "nginx"
elsif line.include?(passenger_header)
section = "passenger"
elsif /### Total private dirty RSS: (\d+\.\d+) MB/.match(line)
memory[section] = $1
else
next
end
end
puts "apache_memory.value #{memory['apache']}"
puts "passenger_memory.value #{memory['passenger']}"
#puts "nginx_memory.value #{memory['nginx']}"
end
if ARGV[0] == "config"
output_config
else
output_values
end
El plugin parsea los totales de memoria tanto de apache, como de nginx, como de apache passenger. En mi caso solo muestro los valores de apache y de passenger, pero si se quisiera mostrar los de nginx, bastaría con descomentar la linea:
puts "nginx_memory.value #{memory['nginx']}"
Diagrama de flujo de iptables
En varias ocasiones he necesitado tener un diagrama con el que de un vistazo pudiera ver claro el flujo de los paquetes a través de las diferentes cadenas de iptables.
El otro día me encontré con uno en un capítulo de linuxhomenetworking, que a pesar de no dar todos los detalles de cada paso, resulta totalmente claro y fácil de entender.

Oferta de becario para el área de sistemas de The Cocktail
En The Cocktail Experience, empresa dedicada a la consultoría web, estamos interesados en contratar becarios para el área de sistemas. Gente con muchas ganas de trabajar y aprender.
El perfil que estamos buscando es el siguiente:
- Experiencia con sistemas GNU/Linux.
- Conocimientos básicos de scripting
- Conocimientos básicos de servidores web y servidores de bases de datos (por ejemplo MySQL, Apache….)
- Posibilidad de realizar convenio de prácticas
Si estás interesado, envía tu CV a: andrea.hidalgo ARROBA the-cocktail PUNTO com
ServerName y ServerAlias en Apache
En el servidor web apache, dentro de un VirtualHost se puede incluir un ServerName para que Apache sepa que ha de aplicar la configuración contenida en ese VirtualHost a las peticiones dirigidas al DNS de dicho ServerName.
También se puede incluir uno o varios ServerAlias dentro del mismo VirtualHost por si el site definido en dicho VirtualHost puede ser accedido a través de más de un DNS diferente.
Ahora bien, la diferencia entre ServerName y ServerAlias es que el ServerAlias acepta wildcards y el ServerName no.
Yo puedo hacer lo siguiente:
<VirtualHost> ServerName example.com ServerAlias *.example.com ... </VirtualHost>
pero no puedo hacer esto:
<VirtualHost> ServerName *.example.com ... </VirtualHost>
Una historia de capistrano, crontabs y pipes
Al montar el deploy de una nueva máquina con capistrano he querido afinar un poco la carga de crontabs.
No me gusta poner las tareas de crontab en el /etc/crontab. Creo que es una muy mala práctica. En vez de eso prefiero que cada usuario tenga su propia tabla de crontabs y para ello hago uso del comando crontab.
En muchas ocasiones hace falta definir crontabs para más de un usuario. Para no andar añadiendo una linea en el script de deploy por cada fichero de crontab que se tenga doy por hecho que los nombres de todos los archivos con las tablas de crontab siguen el mismo formato, que es “crontab ..
El código pues para capistrano es:
task :app_deploy, :roles => [:app] do
Dir["./appserver/etc/crontab.*"].each { |crontab|
sudo "sh -c 'cat #{release_path}/#{crontab} | \
crontab -u #{File.extname(File.basename(crontab)).delete('.')} -"
}
end
En este código hay varias cosas que explicar.
Primero se presupone pues que si quiero, por ejemplo, añadir el crontab para el usuario www-data simplemente lo crearé y lo guardaré en appserver/etc/crontab.www-data
En cuanto al código, por un lado el bloque lo que hace es cargar en un array los ficheros con un nombre que coincida con el patrón comentado anteriormente. Hay que tener en cuenta que el código en ruby se ejecuta en la máquina desde la que se lanza el deploy y lo que se le pasa al comando run o sudo es un comando unix que se va a ejecutar en la máquina en la que se quiera hacer el deploy.
Por otro lado está el hecho de que cuando se ejecutan con sudo dos comandos unidos por una tubería, el sudo se va a aplicar únicamente al primero.
Si se hace:
$ sudo echo '* * * * * date > /tmp/date' | crontab -u root -
el sudo se va a aplicar únicamente al comando echo y no al comando crontab por lo que eso no funcionará ya que no tenemos privilegios suficientes.
Por lo tanto para no tener que repetir el comando sudo a los dos lados de la tubería y también para no complicar el comando en capistrano, lo que se puede hacer es englobar toda la sentencia en una subshell de la siguiente forma:
$ sudo sh -c 'echo "* * * * * date > /tmp/date" | crontab -u root -'
Error al instalar passenger (fcgi)
Al intentar instalar passenger a partir de la gema, me he encontrado con un error rarísimo. He estado un rato intentando ver que podía ser.
Al final me he cansado y he probado a cambiar la versión de rubygems de la 1.0.1 a la 1.3.1 y se ha instalado correctamente.
El error era el siguiente:
# gem install --no-ri --no-rdoc passenger
Bulk updating Gem source index for: http://gems.rubyforge.org
Building native extensions. This could take a while...
ERROR: Error installing passenger:
ERROR: Failed to build gem native extension.
/usr/bin/ruby1.8 extconf.rb install --no-ri --no-rdoc passenger
checking for fcgiapp.h... no
checking for fastcgi/fcgiapp.h... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers. Check the mkmf.log file for more
details. You may need configuration options.
Provided configuration options:
--with-opt-dir
--without-opt-dir
--with-opt-include
--without-opt-include=${opt-dir}/include
--with-opt-lib
--without-opt-lib=${opt-dir}/lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=/usr/bin/ruby1.8
--with-fcgi-dir
--without-fcgi-dir
--with-fcgi-include
--without-fcgi-include=${fcgi-dir}/include
--with-fcgi-lib
--without-fcgi-lib=${fcgi-dir}/lib
Gem files will remain installed in /usr/lib/ruby/gems/1.8/gems/fcgi-0.8.7 for inspection.
Results logged to /usr/lib/ruby/gems/1.8/gems/fcgi-0.8.7/ext/fcgi/gem_make.out
Oferta de becario para el área de sistemas de The Cocktail
En The Cocktail Experience, empresa dedicada a la consultoría web, estamos interesados en contratar becarios para el área de sistemas. Gente con muchas ganas de trabajar y aprender.
El perfil que estamos buscando es el siguiente:
- Experiencia con sistemas GNU/Linux, especialmente Debian
- Conocimientos básicos de scripting (en algún interprete tipo bash, ruby, perl, python, ….)
- Conocimientos básicos de servidores web y servidores de bases de datos (por ejemplo MySQL, Apache….)
- Interés y compromiso por el software libre
- Estudios relacionados (Informática, Telecomunicaciones….)
Si estás interesado, envía tu CV a: andrea.hidalgo ARROBA the-cocktail PUNTO com
ActiveLDAP, validaciones y callbacks
Mientras intentaba implementar el soporte de vacaciones con gnarwl y postfix en una aplicación Rails de gestión de usuarios en LDAP me he encontrado con una situación que no me esperaba.
Primero he de comentar por encima en que consiste gnarwl. Se trata de un script al que se le pasa por la entrada standard un correo en texto plano, con su remitente y destinatario. Después el script busca el destinatario del correo en el árbol LDAP donde está guardada toda su información y comprueba si el atributo vacationActive está activado. Si lo está, le envía al remitente del correo un mail con el texto indicado en el atributo vacationInfo.
Al grano. En el modelo del usuario, gracias a ActiveLDAP, tenía indicado que uno de los objectClass que definen a todo usuario en esta aplicación en concreto es el objectClass Vacation.
ldap_mapping :dn_attribute => 'uid', :prefix => 'ou=Usuarios',
:classes => ['top', 'person', 'qmailUser', 'inetOrgPerson', 'Vacation']
Como no quería sobrecargar el formulario de creación de usuario con un campo/checkbox “Vacaciones”, he metido un callback before_create en el modelo del usuario, de la siguiente forma:
before_create :set_vacation def set_vacation self.vacationActive = false end
De esta forma, la propia definición de objectClass Vacation del usuario se iba a encargar de asignarle ese objectClass y el before_create se iba a encargar de crear el atributo vacationActive y de ponerlo a false.
Cual ha sido mi sorpresa al ir a crear un usuario nuevo y recibir un mensaje típico de validación que no esperaba:
1 error prohibited this user from being saved
There were problems with the following fields:
* vacationActive is required attribute by objectClass 'Vacation'
Al principio me ha despistado un poco, pero al final he visto cual era el problema.
Obviamente sabía que cuando una entrada en LDAP tiene el objectClass Vacation, se exige que como mínimo tenga también el atributo vacationActive definido. Lo que no sabía era que ActiveLDAP genera las validaciones en tiempo real consultando primero los objectClass de esa entrada y generandose su lista con los atributos de los que dependen esos objectClass.
Por lo tanto el before_create añadido anteriormente no sirve, ya que es necesario crear ese atributo antes de la validación. Lo correcto sería:
before_validation_on_create :set_vacation
Además de este detalle se había juntado otro problema que hacía que me costase un poco con la solución. Este problema es que ActiveLDAP no acepta una definición de un booleano de la forma clásica:
vacationActive = false
ActiveLDAP acepta valores booleanos de la siguiente en forma de cadenas de la forma “TRUE” o “FALSE”.
Mirando un poco las tripas de ActiveLDAP he visto que tiene una función para normalizar los valores en el caso de que se le pase true o false. No obstante parece que no aplica esa función a nivel interno, por lo que resulta totalmente inutil en caso de desconocimiento del programador, como en este caso me ha pasado a mi.
Por lo tanto, el callback correcto en esta situación no sería el que he indicado anteriormente, sino que sería este:
before_validation_on_create :set_vacation def set_vacation self.vacationActive = "FALSE" end
Soporte de Syslog para Nginx
Estos días tenía la necesidad de hacer que nginx mandase sus logs al syslog local.
Nginx no tiene soporte nativo para usar syslog. Puede escribir los logs o en fichero o mandarlos a un pipe.
Estuve bsucando y encontré un parche de la versión 0.6.31 que resuelve el problema. Aquí habla también un poco del parche.
A pesar de que en ese último link explica por encima como hacerlo, lo voy a contar yo también.
- Bajamos la versión 0.6.31 de nginx en http://sysoev.ru/nginx/nginx-0.6.31.tar.gz. Según el comentario de Marlon (el creador del parche) debería funcionar también con las versiones 0.6.30 y 0.6.29, y mirando los changelogs pienso que tambíen debería funcionar en la última que es la 0.6.32. Si alguien lo prueba que me lo diga.
- Descomprimimos:
# cd /usr/src/ # tar xvzf nginx-0.6.31.tar.gz
- Bajamos el parche:
# wget http://bugs.gentoo.org/attachment.cgi?id=153345 -O nginx_syslog.patch
- Parcheamos:
# patch -p0 < nginx_syslog.patch
- Compilamos e instalamos nginx:
# cd nginx-0.6.31 # ./configure --with-syslog # make # make install
CFLAGS="$CFLAGS -Werror"
por:
CFLAGS="$CFLAGS"
Esto únicamente hace que no se rompa la compilación al encontrar algun warning. En mi caso los warning que lanza la compilación se pueden ignorar tranquilamente, por lo que resulta seguro continuar con ellos.
Si todo ha ido bien deberíamos de tener funcionando nginx. Faltaría unicamente configurarlo y ponerlo en marcha. En el fichero de configuración no hace falta indicar nada para que mande correctamente los logs al syslog. Por defecto los manda a la facility daemon.
Yo lo he probado ya en servidores en producción y por el momento funciona estupendamente.
Desde aquí agradezco el esfuerzo a Marlon de Boer, que no he conseguido encontrar un blog suyo donde hacerlo.