Default server in nginx
By default nginx accepts requests from any domain that points to the nginx server. If you want that only requests from domains that are configured in nginx be processed you cand add a default rule in nginx:
server {
listen 80 default;
server_name _;
deny all;
}
So, if you try to do a request from a domain not configured in nginx, it will return a 403 status (forbidden)
LDAP: Introduction
This is the first post of a LDAP posts collection where I’ll try to explain all what I learned about this technology for the last years.
What is LDAP?
LDAP stands for Lightweight Directory Access Protocol.
LDAP is not a database
LDAP is A protocol to handle information from a Database
One of the most common applications of LDAP is as an authentication backend for an email server. Next, we can see an example:
In this picture a happy user tries to check his email from his personal computer. So he sends his login information to the email server. The email server fetches this data and starts talking with the LDAP server. The LDAP server contains all the users information, so if the login information that it is receiving from the mail server matches the information of any user in its database, it is going to return a positive answer to the email server. At this point, the email server knows that the user sent a valid login information, so it will send him his new emails.
In the picture we can see that the email server doesn’t know the physical database where the users information is stored. It only speaks with the LDAP server, and later the LDAP server try to compare the information with the database backend.
LDAP is extremely fast reading and searching information in the database. This is because the elements in a LDAP directory are arranged in a hierarchical tree, so searches are made always downwards. Because of that, LDAP is widely used as an authentication backend for all kind of services, specially the ones with a big amount of users. Write operations are not so fast, but in this kind of applications, users are used to read their personal information from the database, but not to change it.
Data types
In spite of being a hierarchical tree, all elements in the tree are equal. An element has one or more objeClasses that define the element purpose. Every objectclass has one or more required attributes and one or more optional attributes. So, in the end, an element belongs to one or more objectClasses and has one or more attributes depending on the objectClasses it belongs to.
For example, en element representing a person has the person objectClass. So, this element is required to define the attributes sn (surname) and cn (commonName). But at the same time it could have, if it wants it to, the telephoneNumber attribute.
There are a lot of schemas that let the chance to load any kind of data in the tree. You can also create your own schema if there’s not any schema that satisfies your needs.
Structure
Like I said before, a LDAP directory is built with different kinds of elements arranged in a hierarchical tree structure. All the elements have a DN (Distinguished Name) that is an their identity inside the directory. An element DN is built with their own RDN (Relative Distinguished Name) and the RDN of the parent elements to the top element of the tree. This seems a bit confused, so let’s explain it better. Let’s see a small picture:
This is our directory tree. Let’s suppose that I want this directory to authenticate all of the example.com domain users.
Usually when the top element of a tree is a domain, all the parts of the domain name are stored in separated elements. So, com and example are stored in different elements but following the same order.
The com element has the RDN “dc=com“. His RDN is made up with an element attribute. This elements belongs to the dcObject objectclass. This objectClass defines that all element belonging to it has to set the dc (domainComponent) attribute. This element has more attributes but, the main one is dc so it is part of the RDN.
That is the same case with the element example. It belongs to dcObject objectclass. So its dc attribute is part of its RDN. There is another element above, so this elemend DN would be the sum of its RDN and the parent RDN, “dc=example,dc=com“.
Next we have a simple container. We want to store people information, but we could also want to store, for example, groups information. A group and a person are two different kinds of elements. So in that case we would create two different containers in the tree. One for storing people, and another to store groups.
In this case, we only have the People container. This element belongs to organizationalUnit objectClass. This objectClass force the element to set the ou (organizationalUnitName) attribute. So this element RDN is “ou=People”. And its DN is “ou=People,dc=example,dc=com”.
Finally we have the “cn=Luis” element. This is a person and it belongs to the person objectClass. Like I said before, the person objectClass force the element to set the cn and sn attributes. The cn value is “Luis” and the sn value is “Bosque”. We can choose any element attribute to make the RDN. We choosed the cn attribute, but could be also the sn attribute.
So, this element RDN is “cn=Luis” and its DN is “cn=Luis,ou=People,dc=example,dc=com”.
Important: We can’t have two elements in the tree with the same DN. So, in this specific case, we couldn’t have two people with the name “Luis”. It would be possible to have two people with the same attributes but their DN must be different. For example, we can call one of them Luis and the other Luisico.
We can see a bigger example of a LDAP directory tree. This is onle an example. I mean that you can use a LDAP directory to store any kind of information, not only people information. With the right schemas, you can use a directory to create any kind of data structure.
LDAP Implementations
There are a lot of servers implementing the LDAP protocol. OpenLDAP, Active Directory, Sun ONE Directory Server, Novell Directory Server, Red Hat Directory Server, etc…
I already worked with some of them but I’m used to work with OpenLDAP, so, in the next posts I will focus on OpenLDAP.
When you install OpenLDAP, in a Linux machine for example, it creates a simple BDB database with a few example data. S
Database Backends
There are also several available database backends to use with OpenLDAP like BDB, HDB, LDIF, etc..
When installing OpenLDAP, the server uses a BDB Database. It happens transparently to the user. So, the people that have just met LDAP don’t need to care about the difference between protocol and database.
Just install openldap and start working on it.
Curso de Sistemas Linux en The Cocktail
Voy a dar un curso de sistemas el viernes 16 por la tarde de 16 a 20 horas y el sábado 17 por la mañana de 10 a 14 horas. Va a ser en el aula de las oficinas de The Cocktail en la C/ Salamanca, 17, Madrid.
El curso va a cubrir todo el proceso de puesta en marcha de una máquina con entorno Ruby on Rails en producción. Esto implica los siguientes puntos:
* Instalación y configuración de Debian
* Instalación del stack de Rails
* Estrategias de Deploy
* DNS
* Securización del servidor
* Backups
* Monitorización
* Configuración del servicio de mailing
Estos puntos implican tecnologías como Debian, SSH, DNS, Ruby, Rails, rubygems, rsync, Munin, Postfix, Apache, Passenger, MySQL, Iptables, Bash scripting, IDS, …
La idea es tratar todos estos puntos en cierta profundidad aunque intentando tocar lo justo de ficheros de configuración para no hacer aburrido el curso.
Voy a intentar que el curso sea para todos los niveles. Se tocarán diversos aspectos desde truquillos del día a día y conceptos básicos de todas las tecnologías hasta configuraciones complejas, de una forma más o menos gradual.
A ver si lo conseguimos.
Si tenéis alguna sugerencia es el momento de decírmelo. Estoy totalmente abierto.
Los que os queráis apuntar decídmelo mandándome un email a “luis.bosque ARROBA the-cocktail PUNTO com”. Solo
pido que los que os apuntéis sea porque tenéis claro que queréis asistir a este curso y no por apuntaros por que sí.
Por desgracia hay límite de plazas, por lo que no puedo garantizar que haya sitio para todos.
wordpress.com, wordpress.org, redirections and LinkedIn
I wanted to change my wordpress.com blog to a self-hosted wordpress blog.
This is the scenario:
- My old blog is lbosque.wordpress.com.
- My new blog is blog.luisbosque.com.
- I would like to keep the indexed information in google, so people that open a old indexed post could actually access the information and not receive a 404 status.
- Wordpress.com doesn’t offer the posibility of add a 301 redirection in their system to put your blog outside of it, which is totally understandable.
So, what I did, is this:
- I added an extra domain (blog.luisbosque.com) in my wordpress.com blog. This costs about 10$/year, which is not much money. What I can do with this, is to set the new domain as a primary domain, so when I try to open http://lbosque.wordpress.com, wordpress redirects the request to http://blog.luisbosque.com. Unfortunatelly this is a 302 Redirection which is not a good thing to Google indexing, but there is no choice.
- Next, I installed the last wordpress.org version in my server and imported all the current blog information. Configured the webserver to use the blog.luisbosque.com domain.
- The next step was to change the blog.luisbosque.com DNS zone to point to my new server instead of doing a CNAME to lbosque.wordpress.com. So now when someone try to open http://lbosque.wordpress.com, wordpress.org redirects it to http://blog.luisbosque.com that is actually hosted on my server. My old blog is still hosted in wordpress.com, but because the redirections is no more visible.
So, now, I have to try to change all of my old blog references and wait to Google have indexed the most part of the new blog. Later, I’ll remove the lbosque.wordpress.com blog.
I found a problem when I changed the URL on the LinkedIn Wordpress plugin. Within this plugin, you have to enter your wordpress blog URL, and the plugin updates the LinkedIn application with the latest blog posts. This is great, but it has a problem when the domain you enter is in a external hosting, but it is also registered as a wordpress.com domain. The plugin tries to search this blog in the wordpress.com database, so if it finds it (in my case, it does it) it stops looking for it in their real server.
The solution I figured out is to use an auxiliar domain, this way:
- I configure in my web server an auxiliar domain, for example blog.luisbosque.es. I configure it so when someone try to open http://blog.luisbosque.es the webserver do a 301 redirection to http://blog.luisbosque.com
- I change the LinkedIn wordpress plugin blog URL to blog.luisbosque.es. This domain is not registered in the wordpress.com database so the plugin tries to fetch the feeds within my server, which actually redirects the request to the final domain blog.luisbosque.com
The result is that the posts title that appears in the wordpress application within LinkedIn belong to the blog.luisbosque.com domain and not to the blog.luisbosque.es auxiliar domain.
This is not the cleanest solution. It’s a bit tricky, but it works, which it’s enough for me.
Thanks to the fast and useful wordpress support answer, that helped me to figure out how to override this behaviour.
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
Tagline en el tema journalist de wordpress
He hecho un pequeñito cambio en el tema journalist de Lucian Marin, que es el que uso en este blog.
El cambio lo he aplicado a la última versión en la que, en la cabecera del tema, aparece un diálogo de fondo negro con el tagline del blog. Lo que he hecho es simplemente meterle un if para que no muestre el diálogo si el blog no tiene definido el tagline.
Este cambio hay que aplicárselo al header.php de dicho tema. A continuación pongo el diff del fichero:
19c19,21
< <div id="bubble"><p><?php bloginfo('description'); ?></p></div> <!-- erase this line if you want to turn the bubble off -->
---
> <?php if (strlen(get_bloginfo('description')) > 0) { ?>
> <div id="bubble"><p><?php bloginfo('description'); ?></p></div>
> <?php } ?>
Cambio de dominio del blog
He decidido alojar mi blog en slicehost para poderle meter mano a algunas cosas que estando en wordpress.com no puedo tocar.
El primer paso es redirigir lbosque.wordpress.com a blog.luisbosque.com.
Luego importaré todos los datos de wordpress.com a el wordpress que tengo preparado en mi máquina.
Por último cambiaré la redirección para que apunte directamente a mi máquina.
Así que a partir de ahora si alguien quiere consultar este blog tendrá que hacerlo a través de http://blog.luisbosque.com
Lo malo es que la redirección que hace wordpress.com es una 302 por lo que probablemente me encontraré con algunos problemas de indexación en google.
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


