sábado, 29 de diciembre de 2007

Monitorización de procesos: pgrep, pkill y psg

Muchas veces os habréis encontrado con que queréis matar una aplicación que no responde y al hacer un ps veis que hay varios procesos que pertenecen a la misma aplicación, entonces no que más remedio que matar los procesos uno a uno. Bueno, eso era así antes de conocer pgrep y pkill. pgrep es una herramienta que dado un nombre de proceso muestra por pantalla los pid's de todos los procesos con ese nombre y pkill es su complemento que en lugar de mostrar los procesos los mata directamente.

Ejecutaremos unas cuantas veces yes redirigiendo su salida a /dev/null y poniendo el proceso en background para tener algo con lo que trabajar:

jgr@seiya ~ $ yes &> /dev/null & yes &> /dev/null & yes &> /dev/null &
[1] 3670
[2] 3671
[3] 3672


Si hacemos ahora un ps de los de toda la vida veremos esto (la última línea es el propio grep):

jgr@seiya ~ $ ps aux | grep yes
jgr 3670 42.8 0.0 4164 584 pts/2 R 20:12 0:19 yes
jgr 3671 41.4 0.0 4164 584 pts/2 R 20:12 0:19 yes
jgr 3672 42.8 0.0 4164 584 pts/2 R 20:12 0:19 yes
jgr 4244 0.0 0.0 6368 808 pts/2 S+ 20:13 0:00 grep --colour=auto yes


Ahora con pgrep veremos sólo los pid's de los procesos:

jgr@seiya ~ $ pgrep yes
3670
3671
3672


Y con pkill los matamos y con pgrep comprobaremos que estén realmente muertos:

jgr@seiya ~ $ pgrep yes
[1] Terminado yes >&/dev/null
[2]- Terminado yes >&/dev/null
[3]+ Terminado yes >&/dev/null


pgrep y pkill tienen algunas opciones interesantes como por ejemplo -l para mostrar el nombre de los procesos (sólo pgrep) o -u/-U para mostrar o matar sólo los procesos del usuario especificado y alguna más que podéis ver en el man de pgrep.

Bueno y ya que estamos con ps os enseñaré un alias que suelo usar en el .bashrc para hacer más cómodo el uso de ps:

export GREP_COLOR="1;32" #verde claro
alias grep='grep --colour=auto'
alias psg="ps aux | grep -v grep | grep"


Básicamente lo que hacen estos alias es colorear las concordancias del grep y eliminar la última línea de la salida del ps que corresponde al propio grep. Aquí podéis ver un ejemplo otra vez con el proceso yes del ejemplo anterior:

viernes, 14 de diciembre de 2007

Ver páginas de man con vim

Un sencillo truco para usar vim como paginador de man en dos pasos:

1.- Añadid a vuestro .bashrc

export MANPAGER="col -b | view -c 'set ft=man nomod nolist' -"


2.- Recargad las variables de entorno para poder usarlo en la shell actual:

source ~/.bashrc


Ya está ya podéis usar vi para ver páginas de man ;)

Ésta es la página de dónde he sacado el truco:
Tip #167: Using vim as a man-page viewer under Unix

jueves, 9 de agosto de 2007

logs de colores

Últimamente andaba buscando la forma de colorear la salida de tail para poder leer más fácilmente los logs de mis máquinas. Ayer encontré esta página de"trucos sucios y rápidos" la solución. Para usar el script, copiarlo a algún lugar del PATH de vuestra máquina (p.e. /usr/local/bin) dadle permiso de ejecución y ejecutrarlo de la siguiente manera:


tail -f /var/log/messages | colorlog.pl


Enseguida notaréis la diferencia ;)


#!/usr/bin/perl

$black = "\033[30m";
$red = "\033[31m";
$green = "\033[32m";
$yellow = "\033[33m";
$blue = "\033[34m";
$magenta = "\033[35m";
$purple = "\033[35m";
$cyan = "\033[36m";
$white = "\033[37m";
$darkgray = "\033[30m";
@word_good=("starting\n", "Freeing", "Detected", "starting.", "accepted.\n", "authenticated.\n", "Ready", "active", "reloading", "saved;", "restarting", "ONLINE\n");
@word_warn=("dangling", "closed.\n", "Assuming", "root", "root\n", "exiting\n", "missing", "Ignored", "adminalert:", "deleting", "OFFLINE\n");
@word_bad=("bad");
@word_note=("LOGIN", "DHCP_OFFER", "optimized", "reset:", "unloaded", "disconnected", "connect", "Successful", "registered\n");
@line_good=("up", "DHCP_ACK", "Cleaned", "Initializing", "Starting", "success", "successfully", "alive", "found", "ONLINE\n");
@line_warn=("warning:", "WARNING:", "invalid", "obsolete", "bad", "Password", "detected", "timeout", "timeout:", "attackalert:", "wrong", "Lame", "FAILED", "failing", "unknown", "obsolete", "stopped.\n", "terminating.", "disabled\n", "disabled", "Lost");
@line_bad=("DENY", "lost", "shutting", "dead", "DHCP_NAK", "failure;", "Unable", "inactive", "terminating", "refused", "rejected", "down", "OFFLINE\n", "error\n", "ERROR\n", "ERROR:", "error", "ERROR", "error:", "failed:");
@daemons=("named");
$col_good = $green;
$col_warn = $yellow;
$col_bad = $red;
$col_note = $purple;
$col_norm = "\033[00m";
$col_background = "\033[07m";
$col_brighten = "\033[01m";
$col_underline = "\033[04m";
$col_blink = "\033[05m";
$col_default = "$col_norm$white";
print "$col_norm$cyan";
$datespace=0;
mainloop: while (<>)
{
$thisline = $_;
$timestamp = substr($_,0,15);
s/................//;
@rec = split (/ /, $_);
$output="$col_brighten$cyan$timestamp";
$output.=" $col_brighten$blue$rec[0]";
if ($rec[1] eq "last")
{
$output.="$col_norm$green last message repeated ";
$output.="$col_brighten$rec[4]$col_norm$green times\n";
print "$output$col_default";
next mainloop;
}
if ($rec[1] =~ /\[(\d+)\]\:/)
{
my($pid) = $1;
$rec[1]=~s/\[$1\]\:// ;
$output .= "$col_norm$green $rec[1]" .
"$col_brighten$green\[";
$output .= "$col_brighten$white$pid" .
"$col_brighten$green\]: ";
}
else {
$output .= "$col_norm$green $rec[1] ";
}
$restcolor="$col_norm$cyan";
$restoftheline="";
for ($therest=(2); $therest<=$#rec; $therest++)
{ $highlight=0;
for ($i=0; $i<=$#word_good; $i++)
{ if ($word_good[$i] eq $rec[$therest])
{ $restoftheline.="$col_brighten$col_good"; $highlight=1; }
}
for ($i=0; $i<=$#word_warn; $i++)
{ if ($word_warn[$i] eq $rec[$therest])
{ $restoftheline.="$col_brighten$col_warn"; $highlight=1; }
}
for ($i=0; $i<=$#word_bad; $i++)
{ if ($word_bad[$i] eq $rec[$therest])
{ $restoftheline.="$col_brighten$col_bad"; $highlight=1; }
}
for ($i=0; $i<=$#word_note; $i++)
{ if ($word_note[$i] eq $rec[$therest])
{ $restoftheline.="$col_brighten$col_note"; $highlight=1; }
}
for ($i=0; $i<=$#line_good; $i++)
{ if ($line_good[$i] eq $rec[$therest])
{ $restcolor="$col_norm$col_good";
$restoftheline.="$col_brighten$col_good"; $highlight=1; }
}
for ($i=0; $i<=$#line_warn; $i++)
{ if ($line_warn[$i] eq $rec[$therest])
{ $restcolor="$col_norm$col_warn";
$restoftheline.="$col_brighten$col_warn"; $highlight=1; }
}
for ($i=0; $i<=$#line_bad; $i++)
{ if ($line_bad[$i] eq $rec[$therest])
{ $restcolor="$col_norm$col_bad";
$restoftheline.="$col_brighten$col_bad"; $highlight=1; }
}
$restoftheline.="$rec[$therest] ";
if ($highlight == 1)
{ $restoftheline.=$restcolor; }
}
$output.="$restcolor$restoftheline";
print "$output$col_default\033[1G";
}
exit(0);

sábado, 4 de agosto de 2007

Reasaltado de sintaxis en archivos sin extensión

Muchas veces os habréis encontrado archivos sin extensión pero que son archivos fuente de algún tipo (scripts de perl, archivos de configuración xml, etc) y que al editarlos con vim aparecen sin resaltado de sintaxis. Esto se soluciona fácilmente con la siguiente orden (en el modo de órdenes de vim):


set filetype=tipo_de_archivo


Por ejemplo para un archivo xml:

set filetype=xml

viernes, 20 de julio de 2007

Usando sysctl para optimizar la pila TCP/IP

sysctl es una herramienta que nos permite modificar el comportamiento del kernel en vivo. Esto significa que las modificaciones que hagamos se aplican instantaneamente sin tener que reiniciar la máquina. Además si añadimos los cambios que vayamos a hacer al archivo /etc/sysctl.conf estos cambios se aplicarán cada vez que se arranque la máquina. sysctl realiza estos cambios a través del sistema de archivos virtual /proc que permite la comunicación directa con el kernel.

El uso de sysctl es muy sencillo. Para listar las variables que podemos modificar basta con ejecutar:


# sysctl -a
sunrpc.max_resvport = 1023
sunrpc.min_resvport = 665
sunrpc.tcp_slot_table_entries = 16
sunrpc.udp_slot_table_entries = 16
sunrpc.nlm_debug = 0
sunrpc.nfsd_debug = 0
sunrpc.nfs_debug = 0
sunrpc.rpc_debug = 0
...
# He recortado la salida porque es bastante extensa


Como podéis el esquema es "nombre de la variable" = "valor". Muchas de estas variables son boleanas un 0 significa que están deshabilitadas y un 1 que están habilitadas. Si conocemos el nombre de la variable que queremos modificar bastará filtrar la salida de la orden anterior con grep para conocer su valor, p.e:


sysctl -a | grep 'ipv4.ip_forward'
net.ipv4.ip_forward = 1


Para que nuestros cambios sean permanentes y además queden documentados lo mejor es editar el archivo /etc/sysctl.conf. A continuación os pego un ejemplo:


# Hablitar reenvío de paquetes (modo router)
net.ipv4.ip_forward = 1

# Habilitar IP dinámica
net.ipv4.ip_dynaddr = 1

# Deshabilitar ECN (señalizador de congestión en la línea)
net.ipv4.tcp_ecn = 0

# Habilitar verificación del origen de la ruta (ayuda a
# a prevenir el IP Spoofing)
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1

# Habilitar SYN cookies (protege contra un ataque de desbordamiento
# de paquetes SYN http://cr.yp.to/syncookies.html
net.ipv4.tcp_syncookies = 1

# Deshabilitar enrutamiento de origen (el enrutamiento de origen
# se considera peligroso)
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0

# Deshabilitar paquetes de redireccionamiento icmp
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0

# Ignorar broadcasts icmp
net.ipv4.icmp_echo_ignore_broadcasts = 1

# No loguear paquetes icmp defectuosos
net.ipv4.icmp_ignore_bogus_error_responses = 1

# Desactivar marcas de tiempo. Con conexiones menores de 10mbps
# son innecesarias
net.ipv4.tcp_timestamps = 0

# Reducir el tiempo tcp_fin_timeout. Reduce el tiempo que
# permanece el socket abierto al cerrar una conexión.
net.ipv4.tcp_fin_timeout = 25

# Reducir tiempo entre keepalives. Cada cuanto tiempo se deben
# mandar paquetes para mantener abierta una conexión viva pero
# que no está siendo usada.
net.ipv4.tcp_keepalive_time = 1200

# Aumentar el búfer para los paquetes SYN
net.ipv4.tcp_max_syn_backlog = 1024

# Reducir los reintentos de conexión
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 3


Una vez editado el archivo aplicamos los cambios:


# sysctl -p /etc/sysctl.conf
net.ipv4.ip_forward = 1
net.ipv4.ip_dynaddr = 1
net.ipv4.tcp_ecn = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_fin_timeout = 25
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_max_syn_backlog = 1024
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 3


La salida nos muestra los cambios aplicados. Podéis encontrar el significado y lo valores que puede tomar cada variable en este tutorial.

miércoles, 18 de julio de 2007

Cómo listar los puertos abiertos de una máquina

VeRTiTo de A SYSAD BLOG - LINUX y yo hemos llegado a un acuerdo de colaboración por el cual yo traduciré algunos de los posts de su blog que me parezcan interesantes y él hará lo mismo con los míos. Así que empezaré con este pequeño howto del blog de VeRTiTo: list out opened host ports howto.

Los puertos abiertos son normalmente la manera no-física más directa de forzar la entrada remotamente.

Aquí encontraréis varias herramientas y formas para listar los puertos abiertos de vuestras máquinas Linux.

Veamos la primera forma de listar los puertos abiertos y usados:


# netstat -panut | grep LISTEN


Hemos usado la orden grep para filtrar los puertos que escuchan (LISTEN) de la salida de netstat. O también:


# netstat -ntl


Echad un vistazo al resultado de ejecutar la orden anterior:

tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 6536/sshd
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 1819/named
tcp 0 0 127.0.0.1:953 0.0.0.0:* LISTEN 1819/named


Tomando como referencia la primera línea esto es lo que significa cada cosa:


0.0.0.0:* = básicamente significa que el puerto está abierto para todas las IP's de la máquina
tcp = es el protocolo usado por el daemon para establecer la comunicación
22 = es el puerto en el que escucha el daemon
sshd = el daemon/servicio que escucha en este puerto


Podéis obtener mas o menos la misma información con la siguiente orden:


# ss -a | grep LISTEN

Cómo listar los puertos abiertos de una máquina

Ahora usaremos un escáner de puertos más potente sobre la IP de nuestro localhost:


# nmap -P0 localhost
Starting Nmap 4.20 ( http://insecure.org ) at 2007-07-17 22:29 WAT
Interesting ports on yourhost.domain.com (127.0.0.1):
Not shown: 1693 closed ports
PORT STATE SERVICE
22/tcp open ssh
53/tcp open domain
778/tcp open unknown
953/tcp open rndc

Nmap finished: 1 IP address (1 host up) scanned in 0.082 seconds


A menudo se dice que nmap es como una navaja suiza para probar posibles puertos abiertos, eso me recuerda también a netcat, pero no vamos a tratar ese tipo de hacking en este blog ;) Vamos a ver algunas opciones más de nmap:


# man nmap


Ejecutad:


# nmap -v localhost


¿Pero cómo podemos comprobar que un puerto está realmente abierto? Eso es fácil de comprobar con una de las más famosas herramientas usadas con Linux y routers:


# telnet localhost 22


Haced telnet al puerto 22 de vuestro localhost para ver si el puerto está realmente abierto.

Si el puerto está realmente abierto conectaréis con el daemon que escuche ese servicio que estará esperando vuestras ordenes. Apretad ctrl+J, intro y salid. ¡No os habéis conectado para hacer nada malo!

Ahora, ya podéis listar los puertos abiertos y desarrollar herramientas más fiables y conseguir más información sobre vuestras máquinas y sus puertos usando estas ordenes de Linux.

Recordad que las ordenes de Linux que hemos usado tienen más opciones que las que hemos visto aquí.

¡Qué tengáis un buen día!

Go To The English Version

martes, 17 de julio de 2007

check_mcpu (II)

Nueva versión de este plugin de Nagios para comprobar el uso de CPU en máquinas multiprocesador o de un sólo procesador. Le he añadido la opción -u para que en lugar de comprobar la CPU libre (modo predeterminado) compruebe la CPU usada. Esto será de ayuda para la gente como yo a la que le cueste restar ;)

En el modo predeterminado (modo CPU libre) si quieres saber cuanta CPU está usando la máquina tienes que restar de 100 la CPU usada, lo cual no me parece muy intuitivo, pero la mayoría de programas que he visto para monitorizar CPU's muestran la cantidad de CPU libre. Bueno, ahora al menos en este plugin ya podéis escoger como ver el uso de vuestras CPU's ;)


Este plugin comprueba la cantidad de CPU usada o libre (la opción predeterminada es libre) para múltiples procesadores. Todos los argumentos son opcionales

Uso: check_mcpu [-w | --warning] [-c | --critical] [-r | --reports] [-i | --interval]
check_mcpu -u | --used [-w | --warning] [-c | --critical] [-r | --reports] [-i | --interval]
check_mcpu -h | --help

-c | --critical
Termina con estado CRITICAL si la cantidad de CPU libre es inferior al valor en tanto por ciento.
En modo CPU usada termina con CRITICAL si la cantidad de CPU usada es superior al valor en tanto por ciento.
Valor predeterminado: 10
Valor predeterminado en modo CPU usada: 90

-w | --warning
Termina con estado WARNING si la cantidad de CPU libre es inferior al valor en tanto por ciento.
En modo CPU usada termina con WARNING si la cantidad de CPU usada es superior al valor en tanto por ciento.
Valor predeterminado: 10
Valor predeterminado en modo CPU usada: 90

-i | --interval
Tiempo en segundos entre pasadas de mpstat.
Valor predetermindado 1

-r | --reports
Número de pasadas por intervalo de segundos de mpstat.
Valor predetermindado 1

-u | --used
Comprueba la cantidad de CPU usada en vez de la CPU libre.


-h | --help
Muestra esta ayuda.

Este plugin depende del paquete sysstat:
http://perso.orange.fr/sebastien.godard/index.html


Como siempre os podéis bajar el plugin de Nagios Exchange: check_mcpu