jueves, 19 de noviembre de 2009

Inventariando

Ante la tarea de inventariar los equipos que tenemos así como sus características principales (fabricante, modelo, ram, cpu,...), se hace imprescindible contar con un script que capture todos estos valores y nos los presente de manera resumida.

Aquí van algunos comandos para capturar información valiosa:

1. Memoria RAM instalada:

# echo "Memoria RAM (MB): "`free -m | grep Mem | tr -s "  " " " | cut -d " " -f 2`

2. Unidades de almacenamiento (discos duros, memorias USB, etc):

# echo "Discos duros:" && fdisk -l | grep "Disco /dev/" | cut -d " " -f 3,4 | tr -d ","

3. Fabricante, modelo y número de serie:

# lshw | grep -e product -e vendor -e serial | head -n 3

4. Procesador/es:

# cat /proc/cpuinfo | grep "model name" | sed "s/model name\t/Procesador/"

5. Número total de cores:

# grep 'model name' /proc/cpuinfo | wc -l

6. Para los sistemas Ubuntu, la versión:

# cat /etc/lsb-release | grep "DESCRIPTION" | cut -d "=" -f 2 | tr -d "\""

En Linux existen como véis multitud de comandos para conocer cualquier información. Es cuestión de investigar un poco por nuestro sistema (y googlear) para saber cómo hacer algo.

viernes, 13 de noviembre de 2009

Problema con cron

Cuando se tienen máquinas viejas actuando como servidores, es probable que no mantengan adecuadamente la hora del sistema. Y aunque cambiar la pila de botón de la placa base suele solucionar el problema, en ocasiones no es así (evidencia deterioro de hardware).

Lo normal es configurar cron para que ejecute el comando ntpdate -u servidor_hora cada cierto tiempo (por ejemplo una vez el día) para mantener la hora del sistema:

# crontab -e

[...]
0 0 * * * ntpdate -u ip_o_nombre_servidor_hora
[...]

Pero... transcurridos unos días accedemos al servidor y vemos que la hora va mal. Para asegurarnos que el comando se ha ejecutado, chequeamos el fichero syslog:

$ grep ntpdate /var/log/syslog
[...]
Nov 11 00:00:01 mipc /USR/SBIN/CRON[360]: (root) CMD (ntpdate -u 192.168.1.1)
Nov 12 00:00:01 mipc /USR/SBIN/CRON[1066]: (root) CMD (ntpdate -u 192.168.1.1)
Nov 13 00:00:01 mipc /USR/SBIN/CRON[1697]: (root) CMD (ntpdate -u 192.168.1.1)
[...]

Entonces, ¿qué ocurre?

Ocurre que cron no ejecuta los comandos programados (en nuestro caso ntpdate) dentro de un bash, por lo que los directorios en los que busca cron el comando ntpdate para ejecutarlo puede que no lo contengan. Cron intentó ejecutar el comando a las 00:00 todos los días (syslog da fe) pero el comando no se encontró. Claro, nosotros hacemos pruebas y lo ejecutamos en nuestro shell bash, con un valor apropiado en nuestra variable $PATH, vemos que funciona y asumimos que tiene que funcionar con cron.

Una solución sencilla es indicar la ruta completa del comando ntpdate en el crontab:

# crontab -e

[...]
0 0 * * * /usr/sbin/ntpdate -u ip_o_nombre_servidor_hora
[...]

Así funcionará sin problemas.

miércoles, 11 de noviembre de 2009

Ejecución de sentencias SQL desde scripts

En alguna ocasión nos puede interesar que algún script realice una consulta o inserción contra una base de datos. Os voy a indicar una sencilla forma de hacerlo, siempre y cuando uséis PostgreSQL como SGBD.

Lo primero de todo, será tener instalado el cliente de Postgresql, que para la versión 9.10 de Ubuntu es el siguiente paquete:

# aptitude install postgresql-client-8.3 (ó 8.4)

Tras instalarlo, deberemos tener disponible el comando psql.

Desde un script, basta con ejecutar:

$ echo "INSERT INTO inventario_macs VALUES ('192.168.1.1', '00:60:08:63:f5:4f');" | psql -h 192.1681.100 -d bd_pruebas -U upruebas

Indicar varias cosas:
  • La opción -h especifica la IP o nombre del servidor que aloja la base de datos.
  • La opción -d especifica la base de datos a la que queremos conectarnos (el servidor puede alojar varias bases de datos).
  • La opción -U especifica el usuario con que nos vamos a conectar.
Hay que tener en cuenta que la base de datos puede estar configurada para que solicite contraseña ante un acceso (autenticación activada) o no. Si no está activa esta opción, el comando anterior funcionará sin problemas. Si estuviese activa, al ejecutar el comando psql se nos preguntará por la contraseña, por lo que no es viable para usarlo en scripts de ejecución automatizada.

Para establecer entre una máquina cliente y otra servidor un vínculo de confianza con el objetivo de que no nos pidan la contraseña por cada acceso que queramos hacer (como ocurre con ssh), realizar los siguientes pasos en la máquina cliente:

1. Crear un fichero con nombre .pgpass en el directorio home del usuario que accederá a la base de datos. Este fichero contendrá lineas con el siguiente formato: hostname:puerto:base_datos:nombre_usuario:password. En nuestro caso:

192.168.1.100:5432:bd_pruebas:upruebas:micarromelorobaron

2. Asignar los permisos adecuados al fichero:

$ chmod 0600 .pgpass

Tras ello, podremos lanzar el comando anterior pues no se volverá a preguntar el password de acceso a la base de datos.

Como añadido, indicar que es muy cómodo a la hora de crear tablas redactar en nuestro propio equipo un archivo de texto con las sentencias SQL correspondientes, y luego ejecutarlas en el servidor de la forma:

$ cat fichero.sql | psql -h 192.1681.100 -d bd_pruebas -U upruebas

martes, 10 de noviembre de 2009

Seguimiento de IPs para obtener su MAC

Hasta ahora hemos visto la forma de obtener la MAC de una IP, pero claro, la IP tiene que estar en uso para poder conocer su MAC. ¿Cómo podríamos hacer para conocer la MAC de varias IPs que aunque no están en uso actualmente sí lo pueden estar en las próximas horas o días?

Se hará lo siguiente: tendremos una lista de IPs a chequear (de las cuales no conocemos sus direcciones MAC). Cada cierto tiempo (pongamos cada hora) se chequearán todas las IPs y las que respondan a ping (y por tanto obtengamos su MAC) las iremos anotando en otra lista.

La lista de IPs a chequear la tendremos en el fichero ips:

192.168.1.2
192.168.1.5
192.168.1.100
192.168.1.200
192.168.1.240

Realizaremos el script que chequeará cada vez que sea llamado:

#!/bin/sh

IFS="
"

for IP in $(cat ips)
do
  MAC=`ping -c 1 $IP >/dev/null 2>&1 && arp -n | grep "$IP " | awk '{print $3}'`
  if [ $? -eq "0" ]; then
    echo $IP $MAC >> macs
  else
    echo $IP >> tmp
  fi
done

mv tmp ips

Y por último, configuraremos cron para que llame al script cada hora:

$ crontab -e
0 * * * * sh /home/juan/chequear.sh

Indicar que, según muestra el script, en el fichero ips nos irán quedando las IPs que no han respondido a ping y en el fichero macs las IPs junto a sus MAC.

lunes, 9 de noviembre de 2009

Ejecución de comandos tras el arranque del S.O.

Si deseamos ejecutar algún comando o script tras el arranque del sistema operativo, deberemos especificarlo en el fichero /etc/rc.local:

ntpdate -u 192.168.1.1

Añadiendo esta linea bastaría para que tras el arranque de Linux, un equipo sincronice su hora con un servidor de hora (supuesto que el equipo 192.168.1.1 tenga corriendo el servicio ntpd). Esto es muy interesante para equipos con bastantes años que no llevan correctamente la hora del sistema.

Ahora bien, prefiero hacerlo bonito y que quede totalmente integrado con la "estética" del arranque en modo consola de Ubuntu (como en Ubuntu server):

echo -n " * Actualizando la hora del sistema... "
ntpdate -u 192.168.1.1
echo "OK"

viernes, 6 de noviembre de 2009

Simular comando watch

El comando watch es bastante útil si queremos monitorizar algún valor. Ejecuta el comando que le indiquemos por parámetro cada x segundos indicados también por parámetro, mostrando la salida del comando:

$ watch -n 1 date

En el ejemplo anterior, se ejecutará el comando date cada segundo (si no se indica periodicidad, por defecto son 2 segundos).

Ahora bien, ¿como podemos simular este comando en equipos que no disponen de él? Ejemplos de ello son instalaciones estándar de algunos sistemas Unix-like. Lo haremos de la siguiente forma:

#!/bin/sh

funcion(){
clear
date
}

while [ 1 ];
do
  funcion
  sleep 1
done

Este script tiene dos puntos clave: el comando a ejecutar (date en nuestro caso) y la cantidad de segundos a esperar por cada ejecución (1 en nuestro caso). Adaptando estas lineas simularéis el comando watch para la ejecución de lo que queráis.

miércoles, 4 de noviembre de 2009

Averiguando versión de Ubuntu

Basta con leer el contenido del siguiente fichero:

$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=9.10
DISTRIB_CODENAME=karmic
DISTRIB_DESCRIPTION="Ubuntu 9.10"

martes, 3 de noviembre de 2009

Transferir ficheros con netcat

Imaginemos que necesitamos transferir un fichero por red entre dos máquinas y que, por el motivo que sea, no lo podemos hacer por ftp, scp,... bien por desconocimiento de passwords o por falta de esos servicios. En este caso, netcat es nuestra aplicación.

En la máquina receptora del fichero estableceremos netcat como servidor en un determinado puerto:

$ nc -l -p 5000 > fichero.odt

Lo que hará será escuchar por ese puerto y todo lo que reciba escribirlo al fichero fichero.odt (si no hubiésemos redirigido la salida estándar aparecería por pantalla).

En la máquina origen (la que tiene el fichero deseado), ejecutar el comando:

$ cat fichero.odt | nc 192.168.1.1 5000 -q 0

Supuesto que el servidor destino tiene dicha IP. Lo que hacemos en este caso es pasarle como entrada a netcat el contenido del fichero, y este lo enviará a la IP y puerto indicados. La opción -q 0 cerrará la conexión con el otro extremo cuando finalice la transmisión del fichero.

Si desconfiáis de que el contenido del fichero transmitido sea correcto, ejecutad en ambos servidor el comando:

$ md5sum fichero.odt
22cd94e9c8db682d2f3cb432649eb6b8  fichero.odt

para comparar el hash del fichero.

Se permiten muchas variaciones, como por ejemplo comprimir el fichero antes de mandarlo para generar menos tráfico de red y/o tardar menos en transmitirlo:

$ gzip -c fichero.odt | nc 192.168.1.1 5000 -q 0

lunes, 2 de noviembre de 2009

Averiguando MAC desde IP

En ocasiones nos puede interesar conocer la MAC de una determinada IP de nuestra red, bien para temas de inventario o para saber si alguien se ha cambiado indebidamente su IP.

Este sencillo script nos ayudará a obtener la MAC de la IP indicada como parámetro:

#!/bin/sh
ping -c 1 $1 >/dev/null 2>&1 && arp -n | grep $1 | awk '{print $3}'

Su llamada sería:

$ ./obtener_mac 192.168.1.1
00:13:f7:e9:96:cf

Si quisiéramos realizar un listado completo de IPS-MACS de nuestra red, podríamos adaptar el script de esta forma:

#!/bin/sh

for IP in $(seq 254)
do
  MAC=$(ping -c 1 $1$IP >/dev/null 2>&1 && arp -n | grep "$1$IP " | awk '{print $3}')
  echo $1$IP - $MAC
done

Suponiendo una red de clase C y pasando como parámetro la parte fija de la dirección IP:

$ ./listado_macs 192.168.2.
192.168.2.1 - 00:13:f7:e9:96:cf
192.168.2.2 -
192.168.2.3 -
[.......]

sábado, 31 de octubre de 2009

For each line en bash

En ocasiones podemos necesitar desde un script en bash analizar cada una de las lineas de un fichero. Un bucle for es una buena opción para ello.

Supongamos que tenemos un fichero llamado fichero con el siguiente contenido:

uno dos tres
cuatro cinco
seis

Y un script analizar.sh con el siguiente código:

#!/bin/bash

LINEAS=$(cat fichero)

for LINEA in $LINEAS
do
  echo $LINEA
done

Si lo ejecutamos, veremos que la salida no es la esperada:

$ ./analizar.sh
uno
dos
tres
cuatro
cinco
seis

Esto ocurre porque un bucle en bash usa para separar los campos espacios en blanco, saltos de linea, etc. Tendremos que decir a bash que el separador sea exclusivamente el salto de linea:

#!/bin/bash

IFS="
"
LINEAS=$(cat fichero)

for LINEA in $LINEAS
do
  echo $LINEA
done

La variable IFS (Internal Field Separator) es una variable interna de bash que especificará el caracter separador. Con este simple cambio, podremos procesar cada linea de un fichero según nuestras necesidades.

jueves, 29 de octubre de 2009

Ocultación de contraseñas en fstab al montar comparticiones samba

Si accedemos frecuentemente a comparticiones samba desde nuestra máquina Linux, es interesante que estas comparticiones se monten automáticamente al inicio del sistema. Para ello, en el fichero /etc/fstab tendremos algo parecido a esto:

//192.168.1.1/compartido  /mnt/compartido   smbfs  defaults,username=perico,password=delospalotes,uid=juan,gid=juan,iocharset=utf8    0 0

Pero claro, cualquier usuario de nuestra máquina puede hacer un cat /etc/fstab y enterarse del usuario y contraseña que usamos para hacer esta conexión.

Existe una forma de ocultar el usuario y contraseña usados:

//192.168.1.1/compartido  /mnt/compartido   smbfs  defaults,credentials=/root/.smbcredentials/servidor,uid=juan,gid=juan,iocharset=utf8    0 0

Ahora, la entrada del fstab indica que la identificación sobre el servidor se hará usando los datos del fichero /root/.smbcredentials/servidor, fichero que por supuesto solo lo puede leer root.

El contenido del fichero /root/.smbcredentials/servidor tendrá el siguiente contenido:

username=perico
password=delospalotes

miércoles, 28 de octubre de 2009

Deshabilitar ssh para root

Una manera de securizar un poco más un equipo de cara a posibles atacantes es no permitir que un usuario se pueda logar como root mediante ssh en la máquina en cuestión. Esta medida de seguridad nos permitirá el que, si un atacante se consigue logar en nuestra máquina por un ataque de fuerza bruta (o cualquier otro método), al menos le sea imposible hacerlo (en una primera fase) como usuario root. Siempre podrá intentar logarse con su, pero este será un segundo reto que le llevará tiempo.

Para deshabilitar el acceso de logado como root en ssh, establecer el parámetro a No en el fichero /etc/ssh/sshd_config:

PermitRootLogin no

Y a continuación, reiniciar el demonio sshd:

# /etc/init.d/ssh restart

martes, 27 de octubre de 2009

Películas con telnet

A los aficionados a Star Wars y que además son amantes de la consola de Linux, seguid estos sencillos pasos:
  1. Haced palomitas
  2. Repanchingaros bien en vuestra silla
  3. Ejecutad $ telnet towel.blinkenlights.nl

lunes, 26 de octubre de 2009

Fork bomb en Ubuntu

La mayoría de distribuciones Linux y Unix vienen con un límite de procesos por usuario bastante relajado o incluso inexistente. Haciendo uso de esta configuración por defecto, se puede realizar una denegación de servicio a un equipo/servidor.

El fork bomb consiste en ejecutar el siguiente comando (con cualquier usuario):

$ :(){ :|:& };:

Esto hará que nuestro bash comience a generar procesos hasta ocupar toda la CPU y bloquear, literalmente, nuestra máquina. Así pues, no hagáis pruebas sobre equipos en producción!! Es curioso ver cómo un usuario sin privilegios de root puede tumbar un equipo.

Si ejecutamos el comando

$ ulimit -u

Observaremos el número de procesos máximos que el usuario actual puede generar. Si queremos limitar este número basta con ejecutar el comando:

$ ulimit -u 1000

Para limitar a 1000 el número de procesos. Este valor se puede definir en el fichero /etc/security/limits.conf. Añadir la siguiente entrada para limitar el número máximo de procesos para cualquier usuario a 1000:

* hard nproc 1000

sábado, 24 de octubre de 2009

Mandar emails desde Python

Os voy a mostrar una sencilla función que os permitirá enviar correos electrónicos desde Python:

# -*- coding: latin-1 -*-
import smtplib
CUENTA_CORREO='usuario@dominio'
PASSWORD_CUENTA_CORREO='pass'
IP_SERVIDOR_SMTP='X.X.X.X'

 
def mail(destinatarios, cc, asunto, mensaje):
    # Destinatarios: lista de emails
    # cc: lista de emails
    # asunto: string
    # mensaje: string
    headers = "From: %s\r\nTo: %s\r\nCc: %s\r\nContent-Type: text/plain; charset=\"utf-8\"\r\nSubject: %s\r\n\r\n" % (CUENTA_CORREO, ','.join(destinatarios), ','.join(cc), asunto)
    message = headers + mensaje

    mailServer = smtplib.SMTP(IP_SERVIDOR_SMTP)
    mailServer.login(CUENTA_CORREO, PASSWORD_CUENTA_CORREO)
    mailServer.sendmail(CUENTA_CORREO, destinatarios + cc, message)
    mailServer.quit()


mail(['a@hotmail.com','b@hotmail.com'], ['c@hotmail.com'], 'prueba', 'esto es una prueba')

viernes, 23 de octubre de 2009

Conocer nuestra IP pública

En la mayoría de ocasiones, nuestro equipo está en una subred privada y salimos a Internet mediante un router que es el único que posee una IP pública. Y aunque existen muchas páginas web que te indican la IP pública con la que sales a Internet, como esta, os voy a indicar cómo saber este dato desde la consola (porque lo mismo estoy en un servidor sin entorno gráfico ni navegador):

$ curl icanhazip.com

jueves, 22 de octubre de 2009

Buscar palabras dentro de ficheros

Un comando muy útil en Linux es grep, y como admite muchos parámetros se pueden hacer gran cantidad de cosas con él.

En esta ocasión lo vamos a usar para que nos diga qué ficheros contienen una palabra (o una expresión regular) y en qué lineas, dado el directorio actual y suponiendo la búsqueda en los ficheros de éste y sus subdirectorios:

root@pc:/etc# grep -nr eth0 *
dhcp3/dhclient.conf:36:#  interface "eth0";
dhcp3/dhclient.conf:42:#  interface "eth0";
initramfs-tools/initramfs.conf:62:# Specify the network interface, like eth0
initramfs-tools/initramfs.conf:65:DEVICE=eth0
laptop-mode/conf.d/ethernet.conf:36:ETHERNET_DEVICES="eth0 eth1"
network/interfaces.232:4:auto eth0
network/interfaces.232:5:iface eth0 inet static
network/interfaces.137:4:auto eth0
network/interfaces.137:5:iface eth0 inet static
network/interfaces:4:auto eth0
network/interfaces:5:iface eth0 inet static

miércoles, 21 de octubre de 2009

Ping sonoro

¿Cuántas veces habremos reiniciado un servidor remotamente y usamos el comando ping para chequear cuándo está disponible? Podemos pasar entre unos pocos segundos hasta algunos minutos, y durante ese tiempo estamos mirando cada dos por tres la ventanita de terminal.

El comando ping dispone de un parámetro por el que puede emitir un pitido por cada ping satisfactorio:

$ ping -a 192.168.1.1

De esta forma, podréis minimizar el terminal y hacer otras tareas pues siempre seréis avisados cuando el servidor quede disponible.

martes, 20 de octubre de 2009

Descargar web completas

Cualquier distribución Linux dispone de una utilidad que permite descargar webs completas (entre otros muchos propósitos posibles). Se trata de wget.

La sintaxis es la siguiente:

$ wget -rkcp --wait=2 --limit-rate=100K -U Mozilla http://administracion-linux.blogspot.com

Cada uno de los parámetros significan lo siguiente:
  • -r: descarga recursiva
  • -k: una vez descargado un fichero, transforma los links para referirlos a archivos locales (para poder ver una web correctamente en local con todos sus elementos).
  • -c: termina de bajar ficheros que se hayan quedado a medio.
  • -p: se descarga todos los ficheros necesarios para poder ver bien la página web.
  • --wait: segundos de espera entre la descarga de un fichero y el siguiente. Este parámetro es interesante para que el servidor web no detecte que se trata de un programa de descarga masiva y nos corte la descarga.
  • --limit-rate: marca el máximo de descarga por archivo. Persigue el mismo propósito que el parámetro anterior.
  • -U: wget se hace pasar por un navegador. Tiene el mismo prósito que los dos parámetros anteriores.

lunes, 19 de octubre de 2009

Despertando equipos

En ocasiones podemos necesitar acceder por ssh a un equipo para realizar alguna tarea o consultar algún dato pero... ¡el equipo lo tenemos apagado! Es muy interesante disponer de un método de arranque remoto para estos casos.

En primer lugar, activaremos desde la BIOS del PC en cuestión el arranque "wakeonlan" y anotaremos la dirección MAC de la tarjeta de red que usaremos para despertarlo. En sistemas Linux, esta dirección se puede obtener con el comando ifconfig, o ifconfig eth0 por ejemplo, si se conoce la tarjeta de red que nos interesa.

Después, instalaremos el paquete wakeonlan en el PC que usaremos para despertar al anterior (suponiendo una distribución Ubuntu).

Por último, bastará con ejecutar el siguiente comando para levantar el equipo:

$ wakeonlan 00:19:99:32:a5:e8

domingo, 18 de octubre de 2009

Actualizar a Ubuntu 9.10

Aunque Ubuntu 9.10 no sale oficialmente hasta dentro de 11 días, desde hace un tiempo podrás actualizar tu versión de Ubuntu a la 9.10 Beta. Para ello, seguir estos sencillos pasos:
  1. Desde el entorno gráfico, presionar Alt + F2.
  2. Ejecutar el comando update-manager -d.
Aparecerá un asistente que se bajará todos los paquetes necesarios y los instalará.

¿A qué esperas?

lunes, 12 de octubre de 2009

Actualizar la hora del sistema

Si disponemos de un viejo equipo, es posible que este retrase la hora. En ocasiones, aun cambiándole la pila de botón de la placa base este problema no se soluciona. En esta situación, necesitaremos sincronizar la hora del equipo con algún servidor de hora.

En este enlace de rediris disponéis de bastantes servidores de hora accesibles desde Internet. Es recomendable que acudáis al servidor de hora de vuestra zona geográfica pues los servidores de hora están montados de manera jerárquica (varios servidores de zona sincronizados entre sí por servidores de un nivel superior); el acesso siempre será más rápido y se balanceará mejor la carga de trabajo.

Podéis consultar cómo de desfasada la fecha/hora de vuestro sistema con el comando:

$ ntpdate -q SERVIDOR

donde SERVIDOR será la IP o nombre del servidor de hora a consultar.

Si obtenemos una salida de este tipo:

server 130.206.208.254, stratum 0, offset 0.000000, delay 0.00000
12 Oct 17:14:25 ntpdate[17952]: no server suitable for synchronization found

Significa que el servidor consultado no tiene operativo el demonio servidor de hora, ntpd. Tendréis que probar con otro.

El mismo comando, pero con el parámetro -u (en puesto de -q) sincronizará la hora del sistema con la del servidor de hora. Se tendrá que ejecutar como root para que el cambio de hora de nuestro sistema se pueda efectuar.

viernes, 9 de octubre de 2009

Cifrar contraseñas con Python

Python es un estupendo lenguaje con el que construir desde pequeños scripts a grandes aplicaciones en un abrir y cerrar de ojos. Yo hago mis pinitos con él.

Si alguna vez habéis realizado un programa en el que los usuarios han de logarse, es fundamental que el servidor guarde las contraseñas con un cifrado seguro. Y es interesante que si dos usuarios escogen la misma contraseña, el administrador de sistemas que gestione dicha información encriptada no sepa de este hecho, es decir, que no vea la misma cadena cifrada para dos usuarios.

La estrategia que seguiremos será la siguiente: la cadena de texto a cifrar no será sólo el password del usuario, sino la concatenación de su login y su password. Así, dos usuarios con la misma password no tendrán la misma cadena cifrada (pues el login se supone que es único). Usaremos el cifrado SHA-1 por ser un método (hasta ahora) seguro.

Este script en Python nos dará la clave cifrada que tendremos que guardar:

# -*- coding: latin-1 -*-

import hashlib, sys

if len(sys.argv) < 3:
    print "Uso: python encriptador.py USUARIO PASSWORD"
else:
    print "Password generado: " + hashlib.sha1( sys.argv[1] + sys.argv[2] ).hexdigest()

Para los no iniciados en Python, para ejecutarlo basta con:

$ python encriptador.py pepico delospalotes

Si deseáis usar el cifrado SHA-256, bastará con sustituir en el script anterior "sha1" por "sha256". La cadena resultado veréis que es más larga.

jueves, 8 de octubre de 2009

Acceso remoto automatizado por telnet

Aunque el método común de logarse en una máquina de manera remota (y en modo texto) es ssh, en alguna ocasión puede que nos toque administrar sistemas antiguos que usan telnet para las labores de administración remota.

En este caso, permitir que un script se pueda logar por telnet en una máquina remota y ejecutar algunos comandos puede resultar tarea dificil (telnet no permite especificar por linea de comandos usuario y contraseña). A simple vista nos parecería que el logado por telnet requiere hacerse por una persona. No obstante, este proceso se puede automatizar (y por tanto, usarlo en nuestros scripts).

La idea es la siguiente: "teclear" los comandos o textos necesarios cuando las aplicaciones nos las van pidiendo. Cuando ejecutamos el comando telnet $IP_SERVIDOR, en un segundo o menos nos aparece el típico "Login: "; en este momento nuestro script tecleará el login correspondiente. Tras dos segundos (o algo menos) se nos pide "Password: "; a lo que nuestro script responderá. Y así con el resto de comandos o textos que una persona que se logase fuese introduciendo (con las temporizaciones correctas).

Os pongo un ejemplo:

#!/bin/sh

SERVIDOR=192.168.1.100
USUARIO=admin
PASSWORD=istrador
(sleep 1;echo $USUARIO; sleep 2; echo $PASSWORD; sleep 3; echo "xterm"; sleep 3;echo "bdf"; sleep 2; echo "exit" ) | telnet $SERVIDOR >salida 2> /dev/null

Si omitimos la redirección de la salida estándar a fichero, podremos ver cómo se va ejecutando todo y se van escribiendo los comandos en los tiempos establecidos. Si no dejásemos una pausa de 2 segundos entre la introducción del login y del password, el password se escribiría en pantalla antes de que el demonio telnet imprima el texto "Password: ", y muchos demonios telnet (si no todos) olvidan lo tecleado antes de solicitar el password. Lo mismo para el resto de comandos; necesitamos esperar a que "bdf" (df de HP-UX) termine de ejecutarse y nos aparezca el prompth del shell para poder meter el siguiente comando: exit.

miércoles, 7 de octubre de 2009

Matar procesos

Ante la necesidad de matar un proceso desde consola, lo usual es realizar los siguientes pasos:

1. Buscar el PID (identificador de proceso) del proceso a matar. Por ejemplo, firefox:

$ ps -ef | grep firefox
juan     11414     1  4 11:02 ?        00:11:42 /usr/lib/firefox-3.0.14/firefox
juan     21829 21542  0 15:51 pts/0    00:00:00 grep firefox

2. Matar el proceso:

$ kill 11414

No obstante, existe un comando que nos permite matar los procesos que encajan con una palabra:

$ pkill firefox

Ojo: Este comando matará todos los procesos que contengan dicha palabra. Por tanto, si ejecutamos algo como:

$ pkill a

nos cargaremos un montón de procesos (todos en los que el nombre del ejecutable o parámetros contengan una a).

martes, 6 de octubre de 2009

Acceso por ssh sin contraseña

En ocasiones es muy útil permitir el acceso por ssh desde un equipo a otro sin que pida la contraseña. Por ejemplo, un script que se ejecuta en una máquina cliente y que necesita ejecutar un comando en una máquina servidor. Este proceso automático no podría introducir la contraseña cuando ésta sea pedida.

La forma de configurar una máquina servidor para que no pida contraseña cuando se acceda desde una máquina cliente específica es la siguiente:

1. En la máquina cliente, logarnos con el usuario que accederá a la máquina servidor. Comprobar si existe el fichero ~/.ssh/id_rsa.pub.

2. Si el fichero anterior no existe, ejecutar el comando:

$ ssh-keygen -t rsa

y pulsar enter a todas las preguntas que se nos hagan. Con esto, habremos creado la clave pública y privada (los ficheros ~/.ssh/id_rsa.pub y ~/.ssh/id_rsa respectivamente).

3. Copiar la llave pública al directorio home del usuario@maquina servidor (la que será accedida sin contraseña):

$ scp ~/.ssh/id_rsa.pub usuario@maquina:/home/usuario/

4. En la máquina servidor, y logados con el usuario al que accederemos sin contraseña, ejecutaremos:

$ cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
$ rm ~/id_rsa.pub

En este momento ya podremos logarnos por ssh sin contraseña desde la máquina cliente con el usuario con que generamos la clave pública/privada a la máquina servidor con el usuario que configuramos para ello.

lunes, 5 de octubre de 2009

Gráficas con gnuplot

Supongamos que disponemos de un fichero de log con valores de ocupación de una partición que hemos ido recolectando. Vamos a hacer uso de la aplicación gnuplot para realizar gráficas usando dichos datos.

Lo primero de todo será instalar gnuplot. Así pues, como usuario root ejecutar:

# aptitude install gnuplot

Vamos a suponer que el fichero de log tiene el siguiente formato:

2009-10-05:08:00 50

siendo la primera columna la fecha y hora y la segunda columna el porcentaje de ocupación.

Gnuplot usa como entrada un fichero de texto donde se especifica el formato y configuración del gráfico a crear. Nuestro fichero de entrada será el siguiente:

set encoding iso_8859_1
set term png
set xdata time
set ylabel "Uso"
set ytics nomirror
set yrange [0:100]
set grid ytics
set xtics nomirror rotate 2592000
set style fill solid 1.0
set timefmt "%Y-%m-%d:%H:M"
set format x "%m"
set xlabel "Meses"

set out "uso_home.png"
set xrange ["2009-01-01:00:00":"2009-10-03:23:59"]
set title "Ocupacion /home en 2009"
plot "ocupacion.log" using 1:2 with boxes


y lo llamaremos gnuplot.in, por ejemplo. Este fichero de entrada supone que los datos a dibujar están en el fichero ocupacion.log.

Si ejecutamos gnuplot:

$ gnuplot gnuplot.in

obtendremos el fichero con la gráfica. Os pongo un ejemplo de cómo quedaría:



Si nos fijamos en el fichero de entrada a gnuplot, se pueden cambiar bastantes parámetros para conseguir: estilos de linea diferentes, rangos de fecha diferentes, distinto valor de máximo de la gráfica del eje y, etc.

domingo, 4 de octubre de 2009

Creación de logs

Si queremos monitorizar un valor en un pc o servidor, lo mejor será automatizar el proceso de obtención del valor y almacenarlos en un log. Para ello haremos uso de cron. Supongamos que el valor a capturar es la recurrente ocupación de la partición /home.

Paso 1

Vamos a crear el script que se ejecutará periódicamente:

#!/bin/sh
FECHA=`date +%Y-%m-%d:%H:%M`
VALOR=`df | grep /home | tr -s "  " " " | cut -d " " -f 5 | tr -d "%"`

echo $FECHA $VALOR >> /var/log/ocupacion_home.log

Al fichero del script lo vamos a llamar ocupacion_home.sh y lo vamos a guardar en /usr/local/bin/ (estando como usuario root).

Se pueden escoger otros formatos de fecha, aunque este lo veo bastante útil.

Paso 2

Le daremos al fichero del script permisos de ejecución:

# chmod +x /usr/local/bin/ocupacion_home.sh

Paso 3

A continuación vamos a programar cron para que ejecute este comando una vez cada hora. Ejecutar el comando:

crontab -e

Se abrirá un editor (el que tengamos por defecto*) en el que tendremos que escribir lo siguiente:

0 * * * * /usr/local/bin/ocupacion_home.sh

Guardaremos y saldremos del editor. En este momento, de manera automática se registrará cada hora en punto la ocupación de nuestra partición /home.

Si se desea programar otra periodicidad, recomiendo leer el manual de cron o este otro enlace.

* Si queremos usar un editor determinado, por ejemplo vi, ejecutaremos lo siguiente:
 export EDITOR=vi

Tras esto podremos ejecutar crontab -e pues se abrirá con vi. Si queremos hacer que este editor sea siempre nuestro editor predeterminado, habrá que incluir al final del fichero ~/.bashrc la linea anterior.

sábado, 3 de octubre de 2009

Monitorizar valor

Supongamos que queremos tener un terminal abierto y controlar en él la ocupación de /home (o cualquier otra cosa). Tenemos dos opciones:

1. Ejecutar manualmente cada vez que queramos obtener el valor el comando:

df | grep /home | tr -s "  " " " | cut -d " " -f 5 | tr -d "%"

2. Decirle a un programita muy cachondo que lo ejecute cada x tiempo:

watch -n 1 'df | grep /home | tr -s "  " " " | cut -d " " -f 5 | tr -d "%"'

El parámetro -n 1 especifica que el comando que denotamos entre las comillas simples se ejecute cada segundo. Por supuesto, este comando tiene otros muchos parámetros con los que jugar y afinarlo a nuestros propósitos.

viernes, 2 de octubre de 2009

Obtener ocupación de partición

Todos los sistemas Unix-like tienen una serie de comandos comunes que, aunque por separado hacen pequeñas cosas, combinándolos consiguen preciados objetivos.

Voy a indicar la forma de obtener el porcentaje de uso de una partición, por ejemplo /home de nuestra máquina. Esto nos será de mucha utilidad cuando nos propongamos monitorizar las particiones un servidor:

df | grep /home | tr -s "  " " " | cut -d " " -f 5 | tr -d "%"

Aunque este tocho pueda parecer largo y poco comprensible, en realidad es muy sencillo y algunos de estos comandos los usaréis muchísimo en cientos de scripts.

Vayamos por partes:

1. df: muestra el uso de nuestras particiones. Su salida sería:
S.ficheros         Bloques de 1K   Usado    Dispon Uso% Montado en
/dev/sda1              7692876   3376756   3925344  47% /
tmpfs                   509272         0    509272   0% /lib/init/rw
varrun                  509272       116    509156   1% /var/run
varlock                 509272         0    509272   0% /var/lock
udev                    509272       144    509128   1% /dev
tmpfs                   509272       144    509128   1% /dev/shm
/dev/sda3            144173428  21509424 115340376  16% /home


Pero a nosotros solo nos interesa el valor de /home.

2. grep /home: Se queda con las líneas que contengan esa palabra. En nuestro caso es únicamente la que nos interesa.

3. tr -s "  " " ": Si os fijáis, df nos devuelve varias columnas separadas entre sí por espacios. Podríamos pensar que el porcentaje de uso de /home siempre aparecerá en el caracter 54 y/o 55, pero si nos vamos a otro PC o servidor esto puede cambiar. Así, nos interesará que la separación entre columna y columna sea tan solo de un espacio, para tenerlo todo controlado. Este comando sustituye toda pareja de espacios consecutivos que vea por uno solo. Por tanto, termina de ejecutarse cuando entre columna y columna nos queda solo un espacio.

En este punto, tras ejecutar df | grep /home | tr -s "  " " " tendríamos:

/dev/sda3 144173428 21509432 115340368 16% /home

4. cut -d " " -f 5: Ahora lo que hacemos con este comando es decir: queremos el campo (field) 5 (que es donde está el valor de ocupación) suponiendo el delimitador entre campo y campo " ". Con todos estos comandos enlazados, nos queda:

16%

5. tr -d "%": Por último, si no nos apetece que aparezca el símbolo de porcentaje, podemos eliminarlo con este comando (-d de delete):

16

Como nota decir que cada uno de estos comandos permite realizar muchas otras acciones, pudiéndose modificar con los parámetros que aceptan. Se recomienda leer las páginas del manual (man) para conocerlas en profundidad.

Recordad: esta sencilla técnica de obtener el valor de una columna la usaréis a menudo para muchos otros fines.

Bienvenida

Hola a todos,

En primer lugar gracias por visitar este humilde blog. Pretendo convertirlo en un cuaderno de anotaciones sobre scripts, comandos, trucos, utilidades o resolución de problemas que voy creando o encontrando en el día a día de mi trabajo como administrador de sistemas Linux.

Ante todo decir que no soy un experto en nada, pero espero que en este blog encontréis un punto de vista distinto a la hora de hacer algo en particular, o la resolución a un problema que podáis tener.

Actualmente trabajo con una Ubuntu y me gusta bastante (como buen administrador) el uso de la consola, la creación de scripts sh o python para automatizar tareas y seguir aprendiendo en el uso de estas herramientas.

Nada más, espero que les guste el blog.