Jan 24, 2010

Creación y aplicación de parches con diff y patch

Patch es una herramienta Linux que permite aplicar un parche a un determinado fichero o directorio.

Un claro ejemplo de la necesidad de emplear esta herramienta puede ser el siguiente: imaginemos que anualmente actualizamos la versión de una determinada aplicación a través del código fuente. El fichero de configuración puede cambiar ligeramente de una versión a otra, pero puede haber ciertos parámetros de configuración que siempre sean los mismos para nosotros y no nos interese modificarlos.

Lo que podemos hacer ante esta situación es generar un parche el cual posteriormente podremos utilizar para parchear las futuras actualizaciones de dicho fichero de configuración.

Vamos a ver todo esto con un sencillo ejemplo. Tenemos dos ficheros, file1 (archivo original) y file2 (archivo modificado) con el siguiente contenido:

[root@centos ~]# cat file1
Hoy es Lunes

[root@centos ~]# cat file2
Hoy es Martes

Para generar el parche ejecutaríamos el comando diff con la opción -u:

[root@centos ~]# diff -u file1 file2 > file.patch

[root@centos ~]# cat file.patch
--- file1 2010-01-21 15:14:08.000000000 +0100
+++ file2 2010-01-21 15:14:42.000000000 +0100
@@ -1 +1 @@
-Hoy es Lunes
+Hoy es Martes

Ahora vamos a suponer que tenemos un tercer fichero con el siguiente contenido:

[root@centos ~]# cat file3
Hoy es Lunes

No me gustan los Lunes

Y queremos parchearlo con el archivo que hemos creado previamente. El resultado sería el siguiente:

[root@centos ~]# patch file3 < file.patch
patching file file3

[root@centos ~]# cat file3
Hoy es Martes

No me gustan los Lunes

Por último, decir que si queremos anular un parche previamente aplicado emplearemos la opción -R.

[root@centos ~]# patch -R file3 < file.patch
patching file file3

[root@centos ~]# cat file3
Hoy es Lunes

No me gustan los Lunes

Utilizando el man pueden verse las múltiples opciones de los comandos diff y patch.

Jan 18, 2010

Subsistemas de seguridad en Linux

Muchas veces cuando a un administrador de sistemas le dicen que debe securizar una determinada máquina Linux, se limita a habilitar el control por aplicación (Application control), o como mucho, a levantar el firewall a través de iptables.

Los sistemas operativos pertenecientes a la familia GNU/Linux permiten configurar distintos subsistemas de protección a parte de los dos que se acaban de mencionar.


En la figura anterior se reflejan todas las capas de protección (a nivel de arquitectura operativa) que pueden llegar a atravesar los datos una vez que llegan a la máquina.
  • Netfilter: framework de desarrollo disponible en el kernel de Linux el cual permite interceptar y manipular paquetes a nivel de red. Iptables emplea las funciones de Netfilter para realizar las tareas de firewall.

  • SELinux context: arquitectura de seguridad integrada en el propio núcleo de Linux que controla los contextos, entornos o directorios sobre los que se ejecutan las aplicaciones.

  • TCP wrappers: filtra el acceso a determinados servicios en base a distintas reglas.

  • Application control: medidas de seguridad integradas y tomadas desde las propias aplicaciones que operan a nivel de usuario.

  • SELinux boolean: arquitectura de seguridad integrada en el propio núcleo de Linux que controla la mayoría de las funciones permitidas en el sistema y que conllevan ciertos riesgos de seguridad.

Jan 10, 2010

Backups en VMware ESXi

VMware ESXi 4.0 sólo nos permite hacer un backup de la configuración del servidor (usuarios, servidores NTP, parámetros del sistema, etc.) y no de las máquinas virtuales. Esta tarea se puede realizar a través del VMware vSphere CLI:

VMware vSphere CLI> vicfg-cfgbackup --server 192.168.1.11 --username root --password xxxxxx -s ESXi20091211.backup

Únicamente tendremos que indicar la dirección IP del ESXi, la password para el usuario root y un nombre para el fichero de backup.

Para restaurar el backup de configuración, ejecutaremos la siguiente orden:

VMware vSphere CLI> vicfg-cfgbackup --server 192.168.1.11 --username root --password xxxxxx -l ESXi20091211.backup

Para hacer un backup de una máquina virtual, tenemos la opción de exportarla a través de la herramienta VMware vSphere Client. Para ello tendremos que apagarla en primer lugar y a continuación pulsar sobre File, Export, Export OVF Template. Esta opción nos permitirá guardar en nuestro disco duro local una imagen en formato OVF de la máquina virtual.

El formato OVF (Open Virtualization Format) es un estándar abierto para empaquetar y distribuir máquinas virtuales. Su principal ventaja es que el tamaño de las exportaciones suele ser bastante más pequeño que el original, ya que no empaqueta las secciones del disco duro virtual que están sin utilizar. Por contra, este proceso tiene la principal desventaja de que hay que hacerlo con la máquina virtual apagada y de forma manual.

Si tenemos acceso a la service console del ESXi, vamos a tener la posibilidad de poder realizar backups de las máquinas virtuales de manera automática y en caliente, es decir, sin apagar el sistema operativo de la máquina virtual.

La idea es la siguiente: en primer lugar habría que hacer una copia del fichero VMK de la máquina virtual. A continuación habría que hacer un snapshot, de esta forma y a partir de este momento, cualquier cambio no se escribiría en el disco virtual, sino en el snapshot. Después ya podríamos copiar el disco virtual VMDK, y por último, eliminaríamos el snapshot.

Para hacer todo esto existe un script llamado ghettoVCB.sh, el cual sigue una metodología similar a la herramienta de pago de VMware para tal fin: VCB (VMware Consolidated Backup). Este script lo depositaremos en el datastore local del ESXi y le asignaremos permisos de ejecución.

~ # chmod +x /vmfs/volumes/datastore1/ghettoVCB.sh

La razón por la que se guarda en el datastore local es debido a que cualquier fichero o directorio que creemos fuera de este espacio, será automáticamente eliminado al volver a arrancar el ESXi.

El backup que creemos a partir de la máquina virtual lo podremos almacenar en el propio datastore local o montar una unidad de almacenamiento por NFS o iSCSI. Para el presente caso de estudio vamos a emplear un datastore remoto accedido por NFS y ubicado en la máquina con dirección IP 192.168.1.100.

Para dicho datastore se tiene la opción de dejarlo montado de forma permanente a través del cliente vSphere, o bien configurar las variables del script para que monte y desmonte la unidad remota cuando la vaya a emplear. Utilizaremos la segunda opción.

A continuación vamos a editar el script y modificar el valor de alguna de sus variables.

~ # cat /vmfs/volumes/datastore1/ghettoVCB.sh
...
# Formato del backup de la VM
DISK_BACKUP_FORMAT=zeroedthick

# Número de backups que serán rotados
VM_BACKUP_ROTATION_COUNT=1

# Habilitar el backup a través de NFS
ENABLE_NON_PERSISTENT_NFS=1

# Desmontar la unidad remota cuando el backup se haya completado
UNMOUNT_NFS=1

# Dirección IP del servidor NFS
NFS_SERVER=192.168.1.100

# Directorio que exportará el servidor NFS
NFS_MOUNT=/export

# Nombre con el que se mostrará el datastore importado
NFS_LOCAL_NAME=nfs_storage_backup

# Nombre del directorio donde se almacenarán los backups
NFS_VM_BACKUP_DIR=backups
...

Si en lugar de almacenar el backup en la máquina remota a través de NFS hubiéramos empleado el propio datastore local del ESXi, tendríamos que haber definido a través de la variable VM_BACKUP_VOLUME el path donde depositar el backup.

Los distintos formatos que soporta el backup (variable DISK_BACKUP_FORMAT) son los siguientes:

  • zeroedthick: éste es el tipo de disco utilizado por defecto al crear una VM en un ESXi y todo el espacio de almacenamiento es reservado previamente. Además, sus bloques son borrados (puestos a cero) la primera vez que se escribe sobre ellos.

  • eagerzeroedthick: durante el momento de su creación, todo el espacio es reservado y puesto a cero. Este tipo de discos son los más seguros, ya que los bloques han sido previamente borrados de cualquier dato previo, ofreciendo además un rendimiento ligeramente superior durante la primera operación de escritura.

  • thin: este tipo de disco tiene la peculiaridad de que crece bajo demanda, es decir, se puede definir un disco thin con un tamaño máximo de 100 GB, y nada más instalar el sistema operativo ocupar sólo 4 GB. Esos 4 GB serán el tamaño real del disco y podrá crecer hasta los 100 GB. El rendimiento ofrecido por este tipo de formato es muy pobre y no se recomienda para entornos de producción.

  • 2gbsparse: divide un disco en varios discos de un tamaño máximo de 2 GB. Este tipo de formato no se puede utilizar directamente en un ESX/ESXi, por lo que hay que transformarlo previamente a un formato thin o thick.

Decir también que el formato seleccionado (zeroedthick) crea una imagen idéntica (bit a bit) a la de la máquina virtual. Después ya por último, crearemos un fichero con la lista de las máquinas virtuales sobre las que queramos aplicar el backup (por ejemplo y para el presente caso de estudio, dos máquinas virtuales denominadas centos01.local y centos02.local).

~ # cat /vmfs/volumes/datastore1/vms_to_backup
centos01.local
centos02.local

Para ejecutar el script lanzaremos la siguiente orden:

/vmfs/volumes/4a65032c-09446b90-9d40-00237d337b62 # ./ghettoVCB.sh -f vms_to_backup -l log_backup

Para automatizar este proceso de backups podemos añadir una tarea al cron del sistema operativo. En el siguiente ejemplo se va a configurar un backup automático que se ejecute todos los Sábados por la noche a las 02:30h.

En primer lugar vamos a definir esta tarea en el cron del usuario root:

~ # cat /var/spool/cron/crontabs/root
...
30 02 * * 6 /vmfs/volumes/datastore1/ghettoVCB.sh -f /vmfs/volumes/datastore1/vms_to_backup -l /vmfs/volumes/datastore1/log_backup

Para que los cambios tomen efecto, vamos a reiniciar el proceso crond. Para ello primero lo mataremos y luego lo volveremos a arrancar a través de busybox (binario que contiene pequeñas versiones de los comandos más básicos de Linux).

~ # kill $(cat /var/run/crond.pid)

~ # busybox crond

El problema de este método es que si en un momento dado hay que reiniciar el ESXi, el sistema operativo restaurará el cron de root por su original. Por lo tanto lo que habrá que hacer será editar el fichero /etc/rc.local y definir este proceso dentro de dicho archivo.

~ # cat /etc/rc.local
...
/bin/kill $(cat /var/run/crond.pid)
/bin/echo "30 02 * * 6 /vmfs/volumes/datastore1/ghettoVCB.sh -f /vmfs/volumes/datastore1/vms_to_backup -l /vmfs/volumes/datastore1/log_backup" >> /var/spool/cron/crontabs/root
/bin/busybox crond

Y por último, para asegurarnos que los cambios en el fichero /etc/rc.local serán guardados para futuros reinicios, ejecutaremos el siguiente comando:

~ # /sbin/auto-backup.sh

Para restaurar un backup de una VM, primero copiaremos el directorio que contiene el backup al datastore local de la máquina, bien a través de una conexión iSCSI o NFS hacia la máquina que contiene los backups, o por ejemplo subiendo dicho directorio al datastore desde el ordenador con el que nos conectemos al ESXi a través del cliente vSphere.

A continuación, ejecutaremos un Browse sobre el datastore, accederemos al directorio que contiene todos los ficheros de la VM y pincharemos con el botón derecho del ratón sobre el archivo con extensión VMK. Para restaurar la máquina ejecutaremos la orden Add to Inventory.

Jan 4, 2010

VMware ESXi: Acceso a la shell de root por SSH

Una de las limitaciones que trae la versión gratuita de VMware ESX (vSphere), más conocido como ESXi, es que no tiene la Service Console (acceso SSH a la shell del sistema).

Para activar este servicio hay que acceder físicamente a la máquina donde se encuentre instalado el ESXi (conectada previamente a un teclado y un monitor) y abrir un terminal pulsando la combinación de reclas Alt+F1.

Una vez tengamos abierto el terminal, escribiremos la palabra unsupported. A continuación nos saldrá la palabra "Password :", con lo que tendremos que teclear la contraseña del usuario root del ESXi. A partir de este momento tendremos una shell con la que podremos ejecutar bastantes comandos Linux (otros muchos han sido quitados), con lo que sólo nos quedará que activar el servicio SSH.

Para ello editaremos con vi el fichero /etc/inetd.conf y descomentaremos la línea "#ssh stream tcp...". Reiniciaremos a continuación el administrador de servicios, eliminaremos todos los procesos inetd y por último, volveremos a lanzar el demonio inetd.

~ # /sbin/services.sh restart

~ # kill `ps | grep inetd | cut -f2 -d" "‘

~ # inetd