# rm-rf.es | Administración de sistemas

Bitácora personal de un SysAdmin Gnu/Linux, Windows, BSD...

Volver a concatenar líneas de un LDIF con sed

Cuando necesitamos manipular a través de scripts un fichero LDIF, y este tiene líneas de atributos divididas con saltos de línea es necesario revertir esto y volver a concatenarlas para poder comenzar a trabajar. Como muchos sabéis, el estándar de LDIF especifica este punto:

Any line that begins with a single space MUST be treated as a continuation of the previous (non-empty) line. When joining folded lines, exactly one space character at the beginning of each continued line must be discarded. Implementations SHOULD NOT fold lines in the middle of a multi-byte UTF-8 character.

Vamos a ver entonces como a través de una línea de comandos usando sed podemos concatenar de nuevo las líneas que comiencen con un espacio con la línea anterior. El comando es el siguiente:

$ sed -e :a -e '$!N;s/\n //;ta' -e 'P;D' test.ldif

Este ejemplo únicamente volcará la salida por pantalla, recordar redirigir stdout a otro fichero o forzar con “-i” para sobreescribir el mismo fichero.

Cron o anacron, ¿qué elegir?

Cron LinuxPese a que aparentemente su función es la misma, es decir, la de realizar tareas de forma automática y desantendida en momentos concretos y/o periódicos, cada uno tiene sus peculiaridades y características que los hacen bastante distintos y su utilización depende de ámbitos distintos. De cron/crontab ya he hablado en varias ocasiones, no así de anacron, podéis usar el buscador o seguir el anterior enlace para encontrar más artículos.

Básicamente, las principales diferencias entre cron y anacron son las siguientes:

  1. Cron es estricto al 100% a la hora de ejecutar tareas configuradas, todo lo contrario que anacron. Si hay un cron que se tiene que ejecutar todos los días a las 03:00 y el sistema está apagado, cron no lo ejecutará. En cambio, anacron sí, lo ejecutará una vez que el sistema vuelva a encenderse si el trabajo tenía que haberse realizado cuando el equipo estaba apagado. Es decir, en servidores y sistemas con disponibilidad 24 x 7 x 365 es mejor usar cron, pero en equipos de escritorio o aquellos que puedan estar apagados es mejor anacron.
  2. Cron permite programar tareas con exactitud de minutos, mientras que en anacron el mínimo es la ejecución diaria de la tarea, pudiendo únicamente especificar un rango horario en el que se ejecutará.
  3. Cualquier usuario puede tener sus propios cron configurados, mientras que para usar anacron hay que ser superusuario. (cron es versatil y se puede restringir si fuera necesario).
  4. Cron corre como demonio todo el tiempo mientras que anacron se ejecuta a través de scripts en el arranque de sistema o con llamadas propias desde cron.

Normalmente en la mayoría de sistemas de producción, por no decir en todos encontraréis que se usa cron, anacron se suele dejar para equipos de escritorio, portátiles y demás equipos de uso personal.

Guía de comandos apt para Debian / Ubuntu (apt-get, apt-cache)

debianHoy vamos a dar un repaso al gestor de paquetes de Debian (y Ubuntu…) apt (Advanced Packaging Tool). Nos vamos a centrar en apt-get y apt-cache. apt-get permite descargar, actualizar e instalar paquetes entre otras cosas, apt-cache por otro lado permite lanzar consultas y buscar paquetes contra la base de datos de los repositorios.

APT-GET

Instalar un paquete:

# apt-get install <paquete>

Desinstalar un paquete:

# apt-get remove <paquete>

Eliminar un paquete incluidos sus ficheros de configuración:

# apt-get purge <paquete>

Eliminar de forma automática aquellos paquetes que no se estén utilizando:

# apt-get autoremove

Actualizar un paquete a la última versión disponible en el repositorio:

# apt-get update <paquete>

Actualizar el sistema. Actualizará todos los paquetes que dispongan de una versión superior dentro de la rama instalada de la distribución:

# apt-get upgrade

Actualizar la distribución completa. Actualizará nuestro sistema a la siguiente versión disponible de la distribución:

# apt-get dist-upgrade

Descargar únicamente las fuentes de un paquete para manipularlas de forma manual:

# apt-get source <paquete>

Limpiar cachés, paquetes descargados, etc:

# apt-get clean
# apt-get autoclean

Verificar que no tenemos ninguna dependencia incumplida:

# apt-get check

APT-CACHE

Buscar un paquete en los repositorios, se puede especificar un patrón, expresión regular, el nombre exacto del paquete, etc:

# apt-cache search <paquete>

Mostrar información sobre un paquete específico (nombre del paquete, versión, dependencias…):

# apt-cache showpkg <paquete>

Mostrar información del paquete incluyendo la descripción, información del paquete como su sitio web, página de bugs…

# apt-cache show <paquete>

Mostrar dependencias de un paquete:

# apt-cache depends <paquete>

Mostrar los nombres de todos los paquetes instalados en el sistema:

# apt-cache pkgnames

xargs: problemas con los argumentos {}

{} es el marcador por defecto para los argumentos que pasamos al comando xargs. Existe la opción de renombrar este marcador para hacer más comprensible el comando y/o evitar problemas como el que podemos ver a continuación:

# grep xx@xxxx.es /var/log/exim_mainlog | awk '{print $3}' | sort -u | xargs grep {} /var/log/exim_mainlog

grep: 1QmbRA-0003Ba-4E: No such file or directory
grep: 1QmdAR-0001To-DY: No such file or directory
grep: 1QmeHn-0002ZO-Ib: No such file or directory
grep: 1Qmfzd-0008TC-Lc: No such file or directory
grep: 1QmgoV-0002aV-Vo: No such file or directory
grep: 1QmhPk-0000Ou-UV: No such file or directory
grep: 1Qmi22-0007kj-B3: No such file or directory
grep: 1Qmifd-0006ur-3S: No such file or directory

Como podéis ver el argumento, que es el identificador del correo lo recibe correctamente pero genera problemas a la hora de ejecutar el xargs. En casos como estos, si no tenéis tiempo para revisar el problema podéis probar a renombrar {} por una cadena de texto con el parámetro -I y verificar si de ese modo funciona:

# grep xx@xxxx.es /var/log/exim_mainlog | awk '{print $3}' | sort -u | xargs -I marcador grep marcador /var/log/exim_mainlog

011-07-29 16:14:38 1Qmnpl-0000za-U7 H=([XX.XX.XX.230]) [XX.XX.XX.XX]Warning: "SpamAssassin as xx detected message as NOT spam (-0.2)"
2011-07-29 16:14:38 1Qmnpl-0000za-U7  xxx  R=virtual_user T=virtual_userdelivery
2011-07-29 16:14:39 1Qmnpl-0000za-U7 => xx@xx.es  R=lookuphost T=remote_smtp H=xx.xx.es [xx.xx.xx.xx] X=TLSv1:DHE-RSA-AE3256-SHA:256
2011-07-29 16:14:39 1Qmnpl-0000za-U7 Completed

Efectivamente así ha funcionado correctamente.

tee linux: mandar la salida de un comando a dos sitios

Tee Linux
Imágen: wikipedia

Tee es un comando Linux (bueno, realmente está disponible en Unix, 4DOS/4NT y Windows PowerShell) que permite copiar la entrada estándar de un comando a un archivo y así mismo seguir teniendo salida estándar por pantalla/terminal.
Copia la entrada estándar a cada ARCHIVO, y también a salida estándar.

Vamos a ver un ejemplo sencillo, ejecutamos el comando ps y a su vez volcamos su salida a un fichero:

$ ps | tee ps.txt
  PID TTY          TIME CMD
 2901 pts/6    00:00:00 bash
 3111 pts/6    00:00:00 ps
 3112 pts/6    00:00:00 tee
$ cat ps.txt
  PID TTY          TIME CMD
 2901 pts/6    00:00:00 bash
 3111 pts/6    00:00:00 ps
 3112 pts/6    00:00:00 tee

Hemos verificado que el contenido de la salida se ha almacenado en el fichero ps.txt y a su vez seguimos visualizandolo por pantalla, si no usaramos el comando tee y volcaramos la salida a un fichero no lo veríamos por pantalla (ver artículo redirigir stdin, stdout y stderr en Unix/Linux):

$ ps > ps.txt

El comando tee tiene muchas más posibilidades, recuerdo por ejemplo el artículo en el que explicabamos como guardar un fichero dentro de VIM cuando no tenemos permisos en vim:

:w !sudo tee %
[sudo] password for alex:

Crear y eliminar particiones con fdisk en Linux

disco duro

Crear particiones con fdisk

Para crear particiones usando la herramienta fdisk, primero debemos comprobar los discos del sistema disponibles y las particiones que ya haya creadas, para ello utilizamos el parámetro -l:

$ sudo fdisk -l

Disco /dev/sda: 160.0 GB, 160041885696 bytes
255 cabezas, 63 sectores/pista, 19457 cilindros
Unidades = cilindros de 16065 * 512 = 8225280 bytes
Identificador de disco: 0x000c3c51

Dispositivo Inicio    Comienzo   Fin     Bloques  Id  Sistema
/dev/sda2            3233        9855    53199247+  83  Linux
/dev/sda4            9856       19457    77128065   83  Linux

En la salida de fdisk hemos verificado que tenemos un único disco /dev/sda de 160 GB, sobre el cual ya hay dos particiones creadas con sistemas Linux, /dev/sda2 y /dev/sda4. Si nos fijamos bien, vemos que el disco tiene 19457 cilindros y que las particiones comienzan en el 3233, por lo que tenemos espacio libre para crear más si lo deseamos.

Vamos a crear entonces una partición de prueba que utilice el resto de espacio disponible en el disco, comenzamos ejecutando fdisk sobre el disco a utilizar:

$ sudo fdisk /dev/sda

Si pulsamos la m una vez dentro podremos visualizar las distintas opciones con su respectiva letra de ejecución:

Orden  Acción
   a   Conmuta el indicador de iniciable
   b   Modifica la etiqueta de disco bsd
   c   Conmuta el indicador de compatibilidad con DOS
   d   Suprime una partición
   l   Lista los tipos de particiones conocidos
   m   Imprime este menú
   n   Añade una nueva partición
   o   Crea una nueva tabla de particiones DOS vacía
   p   Imprime la tabla de particiones
   q   Sale sin guardar los cambios
   s   Crea una nueva etiqueta de disco Sun
   t   Cambia el identificador de sistema de una partición
   u   Cambia las unidades de visualización/entrada
   v   Verifica la tabla de particiones
   w   Escribe la tabla en el disco y sale
   x   Funciones adicionales (sólo para usuarios avanzados)

Vamos a crear una nueva partición, así que pulsamos “n”:

Orden (m para obtener ayuda): n
Acción de la orden
   e   Partición extendida
   p   Partición primaria (1-4)

Seleccionamos si queremos una partición extendida o primaria, en este caso podemos crearla como primaria, pulsamos “p” y dejamos que automáticamente se configure el número de la partición (se puede especificar, del 1 al 4). Después podemos seleccionar el primer y último cilindro a utilizar para la partición. Como yo voy a usar el resto de espacio disponible será del 1 al 19457 tal y como hemos visto antes, también podríamos indicar el tamaño de la partición en K, M o G. Lo dejamos por defecto en este caso:

p
Número de partición (1-4): 3
Primer cilindro (1-19457, valor predeterminado 1):
Último cilindro, +cilindros o +tamaño{K,M,G} (1-3232, valor predeterminado 3232):
Se está utilizando el valor predeterminado 3232

Ahora escribimos los cambios y salimos de fdisk:

Orden (m para obtener ayuda): w
¡Se ha modificado la tabla de particiones!

Llamando a ioctl() para volver a leer la tabla de particiones.

El núcleo todavía usa la tabla antigua.
La nueva tabla se usará en el próximo reinicio.
Se están sincronizando los discos.

Finalmente debemos ejecutar el comando partprobe para indicar al kernel que vuelva a leer la tabla de particiones:

$ sudo partprobe

Y ya tenemos nuestra nueva partición creada, ahora únicamente faltaría asignar el sistema de ficheros deseado (ext3, ext4, ntfs, etc):

$ sudo fdisk -l

Disco /dev/sda: 160.0 GB, 160041885696 bytes
255 cabezas, 63 sectores/pista, 19457 cilindros
Unidades = cilindros de 16065 * 512 = 8225280 bytes
Identificador de disco: 0x000c3c51

Dispositivo Inicio    Comienzo      Fin      Bloques  Id  Sistema
/dev/sda2            3233        9855    53199247+  83  Linux
/dev/sda3               1        3232    25961008+  83  Linux
/dev/sda4            9856       19457    77128065   83  Linux

Formateamos la partición como ext4:

$ mkfs.ext4  /dev/sda3
mke2fs 1.41.4 (27-Jan-2009)
mkfs.ext4: Permiso denegado mientras se intentaba determinar el tamaño del sistema de ficheros
alex@sistemas:~$ sudo mkfs.ext4  /dev/sda3
mke2fs 1.41.4 (27-Jan-2009)
Etiqueta del sistema de ficheros=
Tipo de SO: Linux
Tamaño del bloque=4096 (bitácora=2)
Tamaño del fragmento=4096 (bitácora=2)
1623840 nodos-i, 6490252 bloques
324512 bloques (5.00%) reservados para el superusuario
Primer bloque de datos=0
Número máximo de bloques del sistema de ficheros=0
199 bloque de grupos
32768 bloques por grupo, 32768 fragmentos por grupo
8160 nodos-i por grupo
Respaldo del superbloque guardado en los bloques:
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
	4096000

Escribiendo las tablas de nodos-i: hecho
Creating journal (32768 blocks): hecho
Escribiendo superbloques y la información contable del sistema de ficheros: hecho

Este sistema de ficheros se revisará automáticamente cada 27 montajes o
180 días, lo que suceda primero.  Utilice tune2fs -c o -i para cambiarlo.

Ahora podemos montar la partición y comenzar a usarla:

$ sudo mount //dev/sda3

Vemos que está disponible con el comando df:

$ df -h | grep /dev/sda3
/dev/sda3              25G  172M   23G   1% /test

Eliminar particiones con fdisk

Eliminar una partición usando fdisk es más sencillo que crearla, lo primero que haremos será desmontarla del sistema con el comando umount:

$ sudo umount /dev/sda3

Accedemos de nuevo a la gestión del disco con fdisk:

$ sudo fdisk /dev/sda

Una vez dentro, eliminamos la partición con la letra “d” y seguido el número de la partición, escribimos después los cambios con “w”:

Orden (m para obtener ayuda): d
Número de partición (1-4): 3

Orden (m para obtener ayuda): w
¡Se ha modificado la tabla de particiones!

Llamando a ioctl() para volver a leer la tabla de particiones.

Ejecutamos de nuevo partproble para hacer efectivos los cambios sin reiniciar:

$ sudo partprobe

Y la partición ha sido eliminada, un fdisk -l no devolverá la partición:

$ sudo fdisk -l | grep sda3

Cómo encontrar fallos e inconsistencias en los ficheros passwd y shadow

Linux passwordExiste un comando llamado pwck que mediante su ejecución verifica que la información contenida en los ficheros de autenticación /etc/passwd y /etc/shadow es correcta. Básicamente comprueba el número de campos en cada una de las entradas de los ficheros, verifica la existencia de los campos de login, UID y GID además de revisar que el directorio home de cada usuario existe y la shell que utiliza.

Su ejecución es simple, ejecutamos como root el comando y examinamos la salida, en este ejemplo vemos inconsistencia con los directorios home de varios usuarios (no existen:

# pwck
usuario «lp»: directorio «/var/spool/lpd» no existe
usuario «news»: directorio «/var/spool/news» no existe
usuario «uucp»: directorio «/var/spool/uucp» no existe
usuario «www-data»: directorio «/var/www» no existe
pwck: sin cambios

Si por ejemplo pusieramos una shell incorrecta al usuario www-data nos avisaría del fallo:

# pwck
usuario «www-data»: directorio «/var/www» no existe
usuario «www-data»: programa «/bin/shtest» no existe

Podemos probar (¡no lo hagáis con usuarios importantes o en servidores en producción!)a eliminar la columna del grupo en el usuario. pwck nos avisará y de forma activa nos indicará si queremos eliminar la línea incorrecta:

# pwck
entrada del archivo de contraseñas no válida
¿eliminar la línea «www-data:x:33::www-data:/var/www:/bin/sh»? no
ninguna entrada del fichero de contraseñas concuerda con /etc/passwd
¿eliminar la línea «www-data:*:14889:0:99999:7:::»? no

Si aceptamos las modificaciones nos indicará que se han realizado cambios en los archivos:

pwck: los archivos se han actualizado

Cómo utilizar la iLO de HP a través de SSH

HP Proliant iLOA la hora de automatizar gestiones y tareas que normalmente realizamos a través de la interfaz web de las iLO de HP disponer de acceso ssh a las mismas lo facilita enormemente (lógicamente…), así que en esta entrada vamos a ver los comandos y tareas básicas que podemos ejecutar desde la shell ssh que nos ofrece iLO.

El prompt que encontraremos al acceder por ssh es el siguiente:

</>hpiLO->

Ver el estado de “salud” del servidor

A través de ssh podemos ver el estado de los ventiladores, fuentes de alimentación y sensores de temperatura del sistema. Estos datos se encuentra en la ruta /system1/ y podemos visualizarlos con los siguientes comandos. Podemos tener una visión general de los parámetros que podemos revisar ejecutando:

</>hpiLO-> show /system1
status=0
status_tag=COMMAND COMPLETED

/system1
  Targets
    firmware1
    bootconfig1
    log1
    led1
    oemhp_vsp1
    cpu1
    cpu2
    memory1
    memory2
    memory3
    memory4
    memory5
    memory6
    memory7
    memory8
    slot1
    slot2
    slot3
    fan1
    sensor1
    sensor2
    sensor3
    sensor4
    sensor5
    sensor6
    sensor7
    sensor8
    sensor9
    sensor10
    sensor11
    drives
    network1
  Properties
    name=ProLiant BL460c G1
    number=XXXXXXX
    oemhp_server_name=XXXX
    enabledstate=enabled
    oemhp_powerreg=os
    processor_number=4
    pstate_number=1
    An iLO 2 License key is required.
  Verbs
    cd version exit show reset set start stop

Fuentes de alimentación

hpiLO-> show /system1/powersupply*
status=0
status_tag=COMMAND COMPLETED

/system1/powersupply*
Targets
Properties
Verbs
cd version exit show set

Nota: esta prueba ha sido realizada en un Proliant BL, motivo por el cual no se reciben datos.

Ventiladores

hpiLO-> show /system1/fan1
status=0
status_tag=COMMAND COMPLETED

/system1/fan1
  Targets
  Properties
    DeviceID=Virtual Fan
    ElementName=System
    OperationalStatus=Ok
    VariableSpeed=Yes
    DesiredSpeed=25
    HealthState=Ok

Sensores

hpiLO-> show /system1/sensor1

status=0
status_tag=COMMAND COMPLETED

/system1/sensor1
  Targets
  Properties
    DeviceID=VRM 1
    ElementName=CPU 1
    OperationalStatus=Ok
    RateUnits=Volts
    CurrentReading=N/A
    SensorType=Voltage
    HealthState=Ok
    oemhp_CautionValue=0
    oemhp_CriticalValue=0

Apagar, encender o reiniciar el servidor

Comprobar el estado del servidor:

</>hpiLO-> power

power: server power is currently: On

Encender el servidor:

</>hpiLO-> power on

ó

</>hpiLO-> start /system1

Apagar el servidor:

</>hpiLO-> power off

ó

</>hpiLO-> stop /system1

Power Cycle del servidor:

</>hpiLO-> power reset

ó

</>hpiLO-> reset /system1 hard

Reinicio suave del servidor:

</>hpiLO-> power warm

ó

</>hpiLO-> reset /system1 soft

Reinicio del servidor:

</>hpiLO-> reset /system1

Encender o apagar el LED (UID)

Comprobar el estado:

</>hpiLO-> show /system1/led1

Encender el UID:

</>hpiLO-> start /system1/led1

Apagar el UID:

</>hpiLO-> stop /system1/led1

Actualizar el firmware

Con el siguiente comando actualizaríamos el firmware del servidor a través de la imagen bin en la URL indicada:

</>hpiLO-> load -source http://repositorio.com/firmware/ilofirmware.bin

Visualizar el log de eventos y sistema

Visualizar el log de eventos de iLO:

</>hpiLO-> show /map1/log1

Este primer comando nos muestra el listado de eventos, luego podemos elegirlos de forma individual y visualizarlo:

</>hpiLO-> show /map1/log1/record212
status=0
status_tag=COMMAND COMPLETED

/map1/log1/record212
  Targets
  Properties
    number=212
    severity=Informational
    date=07/04/2009
    time=04:50
    description=Remote console session stopped by: XXX - 192.1.168.0.200(

Para visualizar eventos de sistema es lo mismo pero a través de /system1/log1:

</>hpiLO-> show /system1/log1
</>hpiLO-> show /system1/log1/record1
status=0
status_tag=COMMAND COMPLETED

/system1/log1/record1
  Targets
  Properties
    number=1
    severity=NonCritical
    date=08/04/2008
    time=00:01
    description=POST Error: 1785-Drive Array not Configured

Y esto es todo por hoy, una pequeña muestra de lo que podemos hacer en la iLO de HP vía SSH, por supuesto hay muchas más posibilidades, quizás las explique otro día ;)