Operar en varios servidores remotos vía SSH
Con el ssh podemos gestionar un servidor remoto de forma segura y con SCP podemos copiar ficheros de forma segura, pero siempre de un servidor en un servidor, pero a veces podemos necesitar operar en varios servidores a la vez, para lo cual deberíamos ir uno por uno, pero con este truco podemos operar en todos a la vez.
Para que quede más claro pondré un ejemplo y así se verá mejor la utilidad y de paso el ejemplo en si puede ser otro buen truco.
Supongamos que queremos meter una nueva SSL key en varios servidores pero de una sola vez en vez de tener que ir servidor por servidor, para ello podemos usar este truco:
cat ~/.ssh/id_dsa.pub | tee >(ssh usuario1@ip1 'cat - >> ~/.ssh/authorized_keys') | ssh isuario2@ip2 'cat - >> ~/.ssh/authorized_keys'
Podemos repetir el bloque del tee tantas veces como servidores necesitemos operar, en este caso se opera sobre 2 servidores pero si fueran 3 haríamos:
cat ~/.ssh/id_dsa.pub | tee >(ssh usuario1@ip1 'cat - >> ~/.ssh/authorized_keys') | tee >(ssh usuario2@ip2 'cat - >> ~/.ssh/authorized_keys') | ssh usuario3@ip3 'cat - >> ~/.ssh/authorized_keys'
Otro ejemplo sería replicar una estructura de directorios en varios servidores:
tar cvjf fichero.tar.bz2 directorio_a_copiar | tee >(ssh usuario1@ip1 'tar xjvf -') | tee >(ssh usuario2@ip2 'tar xjvf -') | ssh usuario3@ip3 'tar xjvf -'
Evidentemente debemos sustituir usuariox por el nombre de usuario e ipx por la IP correspondiente.
Otra forma de operar en varios ordenadores de forma simultanea e interactiva (lo que se teclea se ejecuta en TODOS los servidores) es hacerlo con tmux
Primero debemos crear un script (yo lo he llamado cluster.sh) donde indicamos que servidores conectamos simultaneamente y el que hace las conexiones vía ssh:
#!/bin/bash HOSTS= # comprobar que el primer parámetro existe if [ "$1" == "" ]; then echo "falta usuario" exit else usuario=$1 fi # el segundo parámetro indica el grupo de servidores if [ "$2" == "grupo1" ]; then HOSTS="server7 server 8" elif [ "$2" == "grupo2" ]; then HOSTS="server1 server2 server3" elif [ "$2" == "grupo3" ]; then HOSTS="server4 server6" elif [ "$2" == "grupo4" ]; then HOSTS="ip1 ip2" else echo "falta indicar el grupo a conectar." exit fi for host in $HOSTS do tmux splitw -dv "ssh $usuario@$host" tmux select-layout tiled done tmux set-window-option synchronize-panes on
Y por último como lanzar la conexión:
tmux new 'exec sh cluster.sh root grupo1'
Lo mejor es poner un alias (y como alias no acepta parámetros usaremos una función):
fcluster() { tmux new 'exec sh cluster.sh $1 $2' } alias acluster=fcluster