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

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

Bucle de password expirado en ldap nativo RHEL contra Sun LDAP


Me ha resultado difícil concretar el problema en tan poco espacio en el título. La situación es la siguiente:

  • Sun LDAP Server
  • Cliente Red Hat Enterprise Linux con LDAP nativo configurado contra el servidor de Sun

La configuración del LDAP Nativo en Red Hat es relativamente sencilla, únicamente lanzamos el authconfig-tui o pasamos los parámetros correspondientes al comando authconfig. Una vez configurado, ya deberíamos poder autenticarnos con los usuarios del LDAP.

En este caso concreto, todo funcionaba correctamente a excepción de la autenticación. Si hacíamos su desde root a cualquier usuario del LDAP funcionaba, la salida del comando getent passwd o getent shadow mostraba todos los usuarios, podíamos hacer ldapsearch, etc.

Con la autenticación, nos pedía continuamente cambiar la password porque había expirado:

$ ssh test@10.0.0.15
You are required to change your LDAP password immediately.
Warning: Your password has expired, please change it now
...
...

Por lo que sea, los servidores Solaris en nuestro caso hacían caso omiso a los atributos de expiración, llevabamos años sin problemas, pero RHEL sí que los revisaba. Todo debería haber funcionado una vez cambiada la clave, pero los servidores RHEL seguían pidiendo continuamente que se cambiara (en Solaris sí que se accedía con la nueva clave).

Para poder acceder correctamente desde Red Hat (y creo que desde cualquier máquina Linux) hay que prestar especialmente atención a estos atributos de LDAP para cada usuario:

shadowMax:
shadowMin:
shadowWarning:

Si están presentes, es necesario que su valor este vacío (no 0) para solucionar el problema. O eso, o especificar una expiración de 99999 en shadowMax… una vez cambiado accederéis sin problemas vía ssh  y con el resto de autenticación.

ssh, authorized_keys y umask


OpenSSHHoy vamos con una entrada de las tontas, de esas que por no mirar un log tardamos más de lo debido en resolver el problema. En este caso algo tan simple como configurar el acceso sin password y con llaves públicas de ssh me ha tenido unos minutos intrigado.

Básicamente, el problema ha sido por una configuración de umask un poco puñetera para el usuario:

$ umask
0002

Para los que no tengáis claro como funciona umask, revisad este artículo: El comando umask. En este caso al crear el fichero authorized_keys para almacenar las llaves públicas, este umask ha provocado que se creara con permisos muy poco seguros…

-rw-rw-r--. 1 foo foo    0 ene 27 22:12 authorized_keys

Y claro, ssh decía que de esta no era la forma correcta en el /var/log/secure:

Jan 27 21:55:52 nodo2 sshd[3282]: Authentication refused: bad ownership or modes
for file /home/foo/.ssh/authorized_keys
Jan 27 21:55:53 nodo2 sshd[3284]: Connection closed by 192.168.1.128

Securizamos con un 400 o 600 y solucionado:

$ chmod 600 /home/foo/.ssh/authorized_keys

Yo estaba empeñado en que era problema de SElinux, pero al ver que el modo permisivo no hacía que se solucionara el próximo paso tenía que ser mirar messages o secure.

Instalar y configurar TigerVNC server y utilizarlo con un túnel SSH


Instalar y configurar el servidor VNC TigerVNC es realmente sencillo. Lo que muchas veces no nos paramos a pensar es que el protocolo en sí no es seguro por lo que el tráfico no está cifrado al conectar al escritorio remoto. Vamos a ver como solucionarlo.

Lo primero es instalar TigerVNC con yum (RHEL, CentOS, Scifi linux, etc). En este caso instalo también el cliente para hacer las pruebas en local:

# yum install tigervnc-server tigervnc

Una vez instalado debemos saber que la configuración se realiza en el fichero /etc/sysconfig/vncservers. Los comentarios del fichero nos indican claramente como configurarlo, también hice un artículo hace un tiempo, echadle un vistazo: Instalar y configurar vnc-server en CentOS/RHEL/Fedora

He creado un usuario “alex” al que únicamente se le permite el acceso local por seguridad:

# The VNCSERVERS variable is a list of display:user pairs.
#
# Uncomment the lines below to start a VNC server on display :2
# as my 'myusername' (adjust this to your own).  You will also
# need to set a VNC password; run 'man vncpasswd' to see how
# to do that.
#
# DO NOT RUN THIS SERVICE if your local area network is
# untrusted!  For a secure way of using VNC, see this URL:
# http://kbase.redhat.com/faq/docs/DOC-7028

# Use "-nolisten tcp" to prevent X connections to your VNC server via TCP.

# Use "-localhost" to prevent remote VNC clients connecting except when
# doing so through a secure tunnel.  See the "-via" option in the
# `man vncviewer' manual page.

# VNCSERVERS="2:myusername"
# VNCSERVERARGS[2]="-geometry 800x600 -nolisten tcp -localhost"
VNCSERVERS="2:ale
VNCSERVERARGS[2]="-geometry 800x600 -nolisten tcp -localhost"

Creamos el password VNC para el usuario del siguiente modo:

# su alex -c "vncpasswd"
Password: XXXX
Verify: XXXX

Arrancamos el servidor VNC para el usuario alex:

[alex@localhost /]$ vncserver
xauth:  creating new authority file /home/alex/.Xauthority

New 'rhcsa:1 (alex)' desktop is rhcsa:1

Starting applications specified in /home/alex/.vnc/xstartup
Log file is /home/alex/.vnc/rhcsa:1.log

Llegados a este punto podemos acceder sin problemas en local al escritorio remoto con el comando vncviewer:

$ vncviewer localhost:1

Desde fuera no, por motivos de seguridad. Para ello vamos a crear un tunel SSH de modo que las conexiones VNC con el exterior sí que estén cifradas. Vamos a usar por ejemplo el puerto 6922 para el tunel. El servidor VNC se encuentra en la IP 10.0.0.100, desde el equipo remoto con el que queremos conectar al servidor creamos el tunel:

$ ssh alex@10.0.0.100 -L 6922:10.0.0.100:5901 -N

Y ya está, podemos acceder remotamente al servidor VNC de forma segura con el nuevo puerto:

$ vncviewer localhost:6922

Si queréis usar el estandar podéis mantener los puertos de VNC:

$ ssh alex@10.0.0.100 -L 5901:10.0.0.100:5901 -N
$ vncviewer localhost:1

Usar autenticación LDAP (OpenLDAP) con OpenSSHD (sshd)


OpenSSHEl otro día hice un artículo en el que veíamos cómo instalar y configurar LDAP (OpenLDAP). Resumiendo un poco, lo que vimos es la instalación propia de OpenLDAP, su configuración básica y la importación de usuarios y grupos de sistema a nuestro directorio. El segundo paso tras esas tareas es la de configurar sshd (OpenSSH) para que pueda autenticarse contra LDAP.

Lo primero que hay que hacer es seguir los pasos del anterior artículo para configurar LDAP correctamente, y sobre todo la sección “Configurar el sistema para autenticar contra LDAP”. Como recordatorio, modificabamos el fichero /etc/nsswitch.conf y le indicabamos que la autenticación a través de passwd/shadow/group también se puede hacer vía LDAP:

passwd:  files ldap
group:  files ldap
shadow:   files ldap

Una vez realizados los pasos indicados en el otro artículo, únicamente nos falta configurar la parte del lado de OpenSSH. Es bastante sencillo, pues todo el trabajo pesado se hace en LDAP. Únicamente tenemos que activar la directiva PAMAuthenticationViaKbdInt en el fichero de configuración /etc/ssh/sshd_config y reiniciar el servicio:

# vim /etc/ssh/sshd_config

Y añadimos la línea:

PAMAuthenticationViaKbdInt yes

Reiniciamos el servicio:

# /etc/init.d/sshd restart

E inmediantamente si hacemos login vía SSH con un usuario creado en el directorio LDAP veremos que funciona correctamente y también que queda registrado en el log correspondiente:

# tail -f /var/log/ldap.log
...
...
Sep 3 12:53:01 cluster01 slapd[2382]: => access_allowed: backend default read access granted to "(anonymous)"
Sep 3 12:53:01 cluster01 slapd[2382]: => access_allowed: read access to "uid=alex,ou=People,dc=ldap-db,dc=com" "uidNumber" requested
Sep 3 12:53:01 cluster01 slapd[2382]: => access_allowed: backend default read access granted to "(anonymous)"
Sep 3 12:53:01 cluster01 slapd[2382]: => access_allowed: read access to "uid=alex,ou=People,dc=ldap-db,dc=com" "gidNumber" requested
Sep 3 12:53:01 cluster01 slapd[2382]: => access_allowed: backend default read access granted to "(anonymous)"
Sep 3 12:53:01 cluster01 slapd[2382]: => access_allowed: read access to "uid=alex,ou=People,dc=ldap-db,dc=com" "homeDirectory" requested
Sep 3 12:53:01 cluster01 slapd[2382]: => access_allowed: backend default read access granted to "(anonymous)"
Sep 3 12:53:01 cluster01 slapd[2382]: => access_allowed: read access to "uid=alex,ou=People,dc=ldap-db,dc=com" "gecos" requested
Sep 3 12:53:01 cluster01 slapd[2382]: => access_allowed: backend default read access granted to "(anonymous)"
...
...

Encapsular tráfico a través de un tunel cifrado con SSH


Hoy vamos a ver como conseguir establecer conexiones cifradas mediante SSH (Openssh) a protocolos/servicios que no están sirviendo su tráfico encriptado. La mayoría de vosotros sabréis que es sencillo “esnifar” el tráfico dentro de una misma red, gracias a este encapsulamiento de tráfico (que es muy sencillo) podemos cifrar el tráfico entre dos equipos independientemente de que el servicio lo ofrezca sin ningún tipo de cifrado. Eso sí, hay que tener conexión vía ssh al servidor destino.

Vamos a verlo con ejemplos ya que resulta más sencilla la explicación de este modo. Pongamos el caso de que queremos conectar de forma segura al sitio web http://test.com. Este sitio web no sirve el contenido por protocolo seguro así que todo el tráfico se podrá visualizar sin problemas desde cualquier equipo de esta red local, por ejemplo con el programa Wireshark (analizador de protocolos de red) lo podemos verificar.

Primero accedemos directamente desde el navegador desde http://test.com, el analizador de tráfico muestra todos los paquetes de información sin cifrar:

whireshark

Ahora, lo que vamos a hacer es crear un tunel de cifrado entre las dos máquinas. Utilizaremos el puerto local 9999 para servir el contenido que previamente encapsulamos por conexión segura desde el servidor que sirve todos los datos (test.com). Para ello creamos una conexión SSH al servidor destino y creamos un tunel entre nuestro puerto 9999 local y el puerto remoto 80 (http):

# ssh alex@test.com -L 9999:pruebas.com:80 -N

Nota: si queréis que el proceso quede en segundo plano y no aparezca la shell ssh en la consola debéis usar el parámetro

-f

.

-N

hace que no se puedan ejecutar comandos SSH en el servidor remoto.

Ahora, podemos acceder al mismo sitio web (http://test.com) desde nuestro equipo, de forma local a través del puerto 9999. Simplemente ponemos en el navegador:

http://localhost:9999

Vemos que efectivamente, al acceder de este modo estamos sirviendo el mismo contenido pero esta vez completamente cifrado:

whireshark cifrado

Una vez conocida la sintaxis del tunneling (

man ssh

) podemos aplicar este mismo recurso a cualquier otro servicio (http, ftp, smtp, pop).

Como información extra os dejo una excelente explicación de Tunel SSH poor parte de la Wikipedia:

El protocolo SSH (secure shell) se utiliza con frecuencia para tunelizar tráfico confidencial sobre Internet de una manera segura. Por ejemplo, un servidor de ficheros puede compartir archivos usando el protocolo SMB (Server Message Block), cuyos datos no viajan cifrados. Esto permitiría que una tercera parte, que tuviera acceso a la conexión (algo posible si las comunicaciones se realizan en Internet) pudiera examinar a conciencia el contenido de cada fichero trasmitido.
Para poder montar el sistema de archivo de forma segura, se establece una conexión mediante un túnel SSH que encamina todo el tráfico SMB al servidor de archivos dentro de una conexión cifrada SSH. Aunque el protocolo SMB sigue siendo inseguro, al viajar dentro de una conexión cifrada se impide el acceso al mismo.
Por ejemplo, para conectar con un servidor web de forma segura, utilizando SSH, haríamos que el cliente web, en vez de conectarse al servidor directamente, se conecte a un cliente SSH. El cliente SSH se conectaría con el servidor tunelizado, el cual a su vez se conectaría con el servidor web final. Lo atractivo de este sistema es que hemos añadido una capa de cifrado sin necesidad de alterar ni el cliente ni el servidor web.

Ejecutar comandos en equipos remotos vía SSH


Hoy vamos a ver como ejecutar a través de ssh comandos en equipos remotos. Esta práctica es de utilidad en el momento que gestionas muchos equipos y dispones de una máquina central para gestionar todos.
A partir de aquí tened en cuenta que es posible automatizar tareas en servidores remotos mediantes scripts, creación de llaves públicas ssh, etc.

El modo de ejecutar los comandos en un servidor remoto sería el siguiente:

$ ssh servidor_remoto comando

Ejemplo (ejecutamos el comando date en el servidor remoto 192.168.0.188 vía ssh a través del puerto 9999):

$ ssh root@192.168.0.188 -P9999 date
stdin: is not a tty
Sun Oct  4 20:15:14 CEST 2009

Si el comando que váis a ejecutar incorpora comillas, tendréis que entrecomillar todo el comando para evitar errores. Si el comando incluye comillas simples, entrecomilladlo con dobles, y si incluye comillas dobles, con simples:

$ ssh root@192.168.0.188 -P9999 'echo "Esto es una prueba"'
$ ssh root@192.168.0.188 -P9999 "echo 'Esto es una prueba'"

Os recomiendo revisar estos dos artículos sobre ssh, hablo sobre la securización del servicio y el acceso sin necesidad de clave:

Login SSH sin password de forma rápida y sencilla

Cómo securizar un servidor SSH

El comando rsync


El comando rsync sustituye al obsoleto rcp (remote-copy). Se trata de un comando de gran flexibilidad, permite encriptar las trasferencias de datos a través de ssh, permite realizar copias desde una máquina local a una remota (y viceversa), de local a local, y entre servidores rsync.

Lo que diferencia a rsync de otros comandos o utilidades es que usa un algoritmo mediante el cual, cuando se copian datos, solamente se copian aquellos que han sido modificados o que han cambiado desde la última vez que se copiaron. Si un fichero a cambiado solamente copiará aquellos datos diferentes entre el fichero antiguo y el nuevo. Esto supone un ahorro considerable de ancho de banda, tiempo y carga del sistema.

Como siempre, toda la información y opciones de rsync en su página man:

man rsync

Os dejo algunos ejemplos para que os vayáis familiarizando con la herramienta, esto y mucho más en la web oficial de rsync.

backup a un servidor de backups central cada 7 días de forma incremental

#!/bin/sh

# This script does personal backups to a rsync backup server. You will end up
# with a 7 day rotating incremental backup. The incrementals will go
# into subdirectories named after the day of the week, and the current
# full backup goes into a directory called "current"
# tridge@linuxcare.com

# directory to backup
BDIR=/home/$USER

# excludes file - this contains a wildcard pattern per line of files to exclude
EXCLUDES=$HOME/cron/excludes

# the name of the backup machine
BSERVER=owl

# your password on the backup server
export RSYNC_PASSWORD=XXXXXX

########################################################################

BACKUPDIR=`date +%A`
OPTS="--force --ignore-errors --delete-excluded --exclude-from=$EXCLUDES
      --delete --backup --backup-dir=/$BACKUPDIR -a"

export PATH=$PATH:/bin:/usr/bin:/usr/local/bin

# the following line clears the last weeks incremental directory
[ -d $HOME/emptydir ] || mkdir $HOME/emptydir
rsync --delete -a $HOME/emptydir/ $BSERVER::$USER/$BACKUPDIR/
rmdir $HOME/emptydir

# now the actual transfer
rsync $OPTS $BDIR $BSERVER::$USER/current

Backup a un disco spare

I do local backups on several of my machines using rsync. I have an
extra disk installed that can hold all the contents of the main
disk. I then have a nightly cron job that backs up the main disk to
the backup. This is the script I use on one of those machines.

    #!/bin/sh

    export PATH=/usr/local/bin:/usr/bin:/bin

    LIST="rootfs usr data data2"

    for d in $LIST; do
	mount /backup/$d
	rsync -ax --exclude fstab --delete /$d/ /backup/$d/
	umount /backup/$d
    done

    DAY=`date "+%A"`

    rsync -a --delete /usr/local/apache /data2/backups/$DAY
    rsync -a --delete /data/solid /data2/backups/$DAY

The first part does the backup on the spare disk. The second part
backs up the critical parts to daily directories.  I also backup the
critical parts using a rsync over ssh to a remote machine.

mirroring vger CVS tree

The vger.rutgers.edu cvs tree is mirrored onto cvs.samba.org via
anonymous rsync using the following script.

    #!/bin/bash

    cd /var/www/cvs/vger/
    PATH=/usr/local/bin:/usr/freeware/bin:/usr/bin:/bin

    RUN=`lps x | grep rsync | grep -v grep | wc -l`
    if [ "$RUN" -gt 0 ]; then
	    echo already running
	    exit 1
    fi

    rsync -az vger.rutgers.edu::cvs/CVSROOT/ChangeLog $HOME/ChangeLog

    sum1=`sum $HOME/ChangeLog`
    sum2=`sum /var/www/cvs/vger/CVSROOT/ChangeLog`

    if [ "$sum1" = "$sum2" ]; then
	    echo nothing to do
	    exit 0
    fi

    rsync -az --delete --force vger.rutgers.edu::cvs/ /var/www/cvs/vger/
    exit 0

Note in particular the initial rsync of the ChangeLog to determine if
anything has changed. This could be omitted but it would mean that the
rsyncd on vger would have to build a complete listing of the cvs area
at each run. As most of the time nothing will have changed I wanted to
save the time on vger by only doing a full rsync if the ChangeLog has
changed. This helped quite a lot because vger is low on memory and
generally quite heavily loaded, so doing a listing on such a large
tree every hour would have been excessive.

Backup automatizado de home

I use rsync to backup my wifes home directory across a modem link each
night. The cron job looks like this

    #!/bin/sh
    cd ~susan
    {
    echo
    date
    dest=~/backup/`date +%A`
    mkdir $dest.new
    find . -xdev -type f \( -mtime 0 -or -mtime 1 \) -exec cp -aPv "{}"
    $dest.new \;
    cnt=`find $dest.new -type f | wc -l`
    if [ $cnt -gt 0 ]; then
      rm -rf $dest
      mv $dest.new $dest
    fi
    rm -rf $dest.new
    rsync -Cavze ssh . samba:backup
    } >> ~/backup/backup.log 2>&1

note that most of this script isn't anything to do with rsync, it just
creates a daily backup of Susans work in a ~susan/backup/ directory so
she can retrieve any version from the last week. The last line does
the rsync of her directory across the modem link to the host
samba. Note that I am using the -C option which allows me to add
entries to .cvsignore for stuff that doesn't need to be backed up.

Plugins para el cliente SSH PuTTY


Leo en The Geek Stuff una excelente lista de plugins para el conocido cliente SSH de Windows PuTTY. Paso a traducir lo esencial de dicha lista.

1. PuTTY Connection Manager

Sin duda algo imprescindible en un cliente SSH es la disponibilidad de pestañas y organización de las terminales, con este plugin podrás añadir pestañas a PuTTY. Necesita tener instalado .NET 2.0. Si al instalar el plugin las ventanas siguieran abriendose normal haced lo siguiente:

Tools -> Options -> Selecciona la check-box “Enable additional timing for PuTTY capture (ms)” -> cambia el valor a 300 ms

PuTTY Connection Manager main interface

2. PuTTYcyg

PuTTYcyg te permitirá usar PuTTY como una terminal local cygwi.

3. PuTTYtray

PuTTYtray, permite minimizar PuTTY en el system tray de Windows, además este plugin permite guardar las sesiones en un fichero para poder exportarlas a cualquier otro equipo, mientras que PuTTY originalmente las guarda en el registro de Windows.

4. PuttyTabs

PuttyTabs muestra en un icono flotante un listado desplegable con las sesiones activas en PuTTY, útil si usamos gran cantidad de terminales a la vez.

5. Modified PuTTY

El plugin modified PuTTY guarda las sesiones en una carpeta en lugar de en el registro, y será capaz de mostrar todas las disponibles en el programa, tanto las del registro como las de carpeta.

6. PocketPuTTY

PocketPuTTY funciona en Windows Mobile 2003/5., lo que te permitirá utilizarlo en moviles, blackberrys, pda’s, etc.

Pocket PuTTY

7. PuTTY Portable

PuTTY Portable es parte de la suite de aplicaciones PortableApp, y te permitirá lanzar PuTTY desde una unidad USBy guardar en ella las sesiones.

8. PuTTY Session Manager

PuTTY Session Manager permite organizar las sesiones de PuTTY en carpetas y además asignarles hotkeys. Requiere Microsoft .NET 2.0.

9. PuTTY Command Sender

PuTTYCS es una utilidad que permite realizar tareas repetitivas en servidores de forma sencilla. Uando PuTTYCS,  puedes mandar un comando unix a múltiples sesiones de PuTTY a la vez.