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

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

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 ;)

Usar cURL a través de un proxy

Para quien no lo sepa, cURL permite hacer uso de un Proxy para recoger los datos de una URL, para ello tenemos que tener en cuenta los siguientes parámetros:

 -p/--proxytunnel   Operate through a HTTP proxy tunnel (using CONNECT)
    --proxy-anyauth Pick "any" proxy authentication method (H)
    --proxy-basic   Use Basic authentication on the proxy (H)
    --proxy-digest  Use Digest authentication on the proxy (H)
    --proxy-ntlm    Use NTLM authentication on the proxy (H)
    --socks4  Use SOCKS4 proxy on given host + port
    --socks5  Use SOCKS5 proxy on given host + port
 -U/--proxy-user  Set proxy user and password
 -x/--proxy  Use HTTP proxy on given port

Suponiendo que tenemos un proxy en la IP 192.168.0.111 y el puerto 3129 que podemos utilizar con usuario y password, si quisieramos hacer un cURL contra http://google.com a través del proxy sería así:

$ curl -x 192.168.0.111:3129 -U usuario:mipassword http://google.com

El resto de opciones ya depende de las necesidades de cada uno, como por ejemplo el tipo de autenticación, tunel Proxy http, etc.

sudo: audit_log_user_command(): Connection refused

La situación es que recibimos el siguiente error al ejecutar comandos con sudo:

$ sudo touch test
audit_log_user_command(): Connection refused 

Antes de revisar cualquier otro problema, revisad que la versión de sudo instalada en el sistema está libre de bugs, pues aunque se trata de un bug antiguo puede ser el origen del problema, aquí tenéis el Bug en Red Hat. En mi caso se trataba de una máquina virtual CentOS con la versión 1.6.9p17:

Installed Packages
Name       : sudo
Arch       : x86_64
Version    : 1.6.9p17
Release    : 6.el5_4
Size       : 474 k
Repo       : installed
Summary    : Allows restricted root access for specified users.
URL        : http://www.courtesan.com/sudo/
License    : BSD
Description: Sudo (superuser do) allows a system administrator to give certain
          : users (or groups of users) the ability to run some (or all) commands
          : as root while logging all commands and arguments. Sudo operates on a
          : per-command basis.  It is not a replacement for the shell.  Features
          : include: the ability to restrict what commands a user may run on a
          : per-host basis, copious logging of each command (providing a clear
          : audit trail of who did what), a configurable timeout of the sudo
          : command, and the ability to use the same configuration file (sudoers)
          : on many different machines.

La solución ha sido sencilla, actualizar a través de yum a la última versión disponible de sudo, en este caso la 1.7.2p1 y problema solucionado:

# yum update sudo

Servidor web en Python con un solo comando

Python es un lenguaje de programación extremadamente potente y sus módulos nos pueden hacer la vida muy fácil en determinadas situaciones. En este caso podemos levantar un servidor web sin ningún tipo de instalación ni configuración, únicamente tenemos que ejecutar el siguiente comando en la ruta que queramos compartir vía web:

# python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...

Automáticamente tendremos un servidor web levantado en el puerto 8000 de todas las IPs que escuchan en nuestro equipo (y en localhost por supuesto: http://localhost:8000) a través del cual se podrán procesar peticiones GET y HEAD estándar.

$ netstat -a | grep 8000
tcp        0      0 *:8000                  *:*                     LISTEN

Para un apaño rápido o para compartir cosas entre PCs puede ser muy útil en determinados momentos. El módulo utilizado es SimpleHTTPServer.

Comando DATE en bash: sumar y restar años, días o meses a la fecha actual

El comando date, a través del parámetro

-d, --date=STRING

permite mostrar y calcular la fecha distinta a la actual a partir de la suma o resta de X años, meses, días, minutos o segundos. Esto es útil cuando queremos por ejemplo añadir o restar 7 días a la fecha actual. Vamos a ver unos cuantos ejemplos:

Sumar 7 días a la fecha actual y mostrarlo en formato estándar:

$ date --date='+7 day'
vie may 13 17:40:47 CEST 2011

Restar 7 días a la fecha actual y mostrarlo en formato timestamp:

$ date +%s --date='-7 day'
1304091656

Sumar un año a la fecha actual con formato de fecha y hora:

$ date +%c --date='+1 year'
dom 06 may 2012 17:41:53 CEST

Restar dos meses a la fecha actual:

$ date --date='-2 month'
dom mar  6 16:42:48 CET 2011

Y así muchos más ejemplos. Seguro que os resulta muy útil dentro de scripts en bash por ejemplo.