J'ai une dizaine de serveurs auxquels je me connecte régulièrement avec SSH. Chacun a une entrée dans le fichier ~/.ssh/config
de mon ordinateur local.
Pour ne pas perdre le contrôle de mon processus en cours lorsque ma connexion Internet est interrompue, je travaille toujours dans une session tmux
. Je voudrais un moyen de connecter automatiquement tmux à chaque fois qu'une connexion SSH est démarrée. Je n'ai donc pas besoin de toujours taper tmux attach || tmux new
après I SSH.
Malheureusement, cela n’est pas aussi simple que je l’espérais au départ.
~/.bashrc
sur les serveurs car je ne le souhaite que pour les sessions SSH, pas pour les sessions locales.tmux attach || tmux new
au ~/.ssh/rc
sur les serveurs entraîne simplement le déclenchement de l'erreur not a terminal
après la connexion, même lorsque l'option RequestTTY force
est ajoutée à la ligne de ce serveur dans mon fichier de configuration SSH local.D'accord, j'ai trouvé une solution généralement satisfaisante. Dans mon ~/.bashrc
local, j'ai écrit une fonction:
function ssh () {/usr/bin/ssh -t $@ "tmux attach || tmux new";}
qui écrase la fonction de terminal ssh pour appeler le programme ssh intégré avec les arguments donnés, suivis de "tmux attach || tmux new"
.
(Le $@
dénote tous les arguments fournis sur la ligne de commande, donc ssh -p 123 user@hostname
sera étendu à ssh -t -p 123 user@hostname "tmux attach || tmux new"
)
(L'argument -t
est équivalent à RequestTTY Force
et est nécessaire pour la commande tmux.)
Pour démarrer automatiquement tmux sur votre serveur distant lorsque vous vous connectez normalement via SSH (et uniquement SSH), modifiez le ~/.bashrc
de votre utilisateur ou de la racine (ou des deux) sur le serveur distant en conséquence:
if [[ -z "$TMUX" ]] && [ "$SSH_CONNECTION" != "" ]; then
tmux attach-session -t ssh_tmux || tmux new-session -s ssh_tmux
fi
Cette commande crée une session tmux appelée ssh_tmux
s'il n'en existe aucune, ou se rattache à une session existante portant ce nom. Si votre connexion est interrompue ou si vous avez oublié une session il y a plusieurs semaines, chaque connexion SSH vous ramène automatiquement à la session tmux-ssh que vous avez laissée.
Rien de spécial, juste ssh user@hostname
.
J'ai utilisé les lignes de @kingmeffisto (je ne suis pas autorisé à commenter cette réponse) et j'ai ajouté une sortie afin que terminer tmux mette également fin à la connexion ssh. Cependant, cela cassait les sessions SFTP, je devais donc vérifier $SSH_TTY
au lieu de $SSH_CONNECTION
.
EDIT 4/2018: Ajout du test du terminal interactif via [[ $- =~ i ]]
pour permettre à des outils tels que Ansible de fonctionner.
if [ -z "$TMUX" ] && [ -n "$SSH_TTY" ] && [[ $- =~ i ]]; then
tmux attach-session -t ssh || tmux new-session -s ssh
exit
fi
Comme décrit dans cet article de blog vous pouvez ssh, puis vous attacher à une session tmux existante avec une seule commande:
ssh hostname -t tmux attach -t 0
Connecter:
ssh user@Host -t "tmux new-session -s user || tmux attach-session -t user"
Pendant la session:
Utilisez Ctrl+d
pour terminer la session (la fenêtre tmux se ferme) ou Ctrl+b d
pour supprimer temporairement de la session et vous y reconnecter ultérieurement.
Souviens-toi! Si votre serveur a redémarré la session perdue!
Lorsque vous êtes dans tmux à tout moment, vous pouvez utiliser Ctrl+b s
pour voir la liste de sessions et changer de courant.
Corrige ton .bashrc:
Je vous recommande de définir la fonction universelle dans votre .bashrc
:
function tmux-connect {
TERM=xterm-256color ssh -p ${3:-22} $1@$2 -t "tmux new-session -s $1 || tmux attach-session -t $1"
}
Il utilise le port 22
par défaut. Définissez également vos alias de connexion rapide:
alias office-server='tmux-connect $USER 192.168.1.123'
alias cloud-server='tmux-connect root my.remote.vps.server.com 49281'
Connexion sans mot de passe:
Et si vous ne voulez pas taper le mot de passe à chaque fois, générez des clés .ssh
pour vous connecter automatiquement:
ssh-keygen -t rsa
eval "$(ssh-agent -s)" && ssh-add ~/.ssh/id_rsa
Placez votre clé publique sur l'hôte distant:
ssh-copy-id -p <port> user@hostname
Conseils supplémentaires:
Si vous voulez utiliser id_session temporaire qui correspond à une session locale bash, utilisez tmux id:
SID=$USER-$BASHPID
ssh user@Host -t "tmux new-session -s $SID || tmux attach-session -t $SID"
byobu est un wrapper très utile pour tmux/screen. Se connecte à une session existante si présente ou en crée une nouvelle.
Je l'utilise avec autossh qui permet de reconnecter gracieusement la session ssh. Fortement recommandé en cas de problèmes de connectivité intermittents.
function ssh-tmux(){
if ! command -v autossh &> /dev/null; then echo "Install autossh"; fi
autossh -M 0 $* -t 'byobu || {echo "Install byobu-tmux on server..."} && bash'
}
Cela pourrait vous être utile - utilisez ssh dans une boucle et reconnectez-vous ou connectez-vous à une session tmux existante afin de disposer d'un moyen simple, fiable et agréable de faire la reconnexion après une panne de réseau
#!/bin/bash
#
# reconnect to or spawn a new tmux session on the remote Host via ssh.
# If the network connection is lost, ssh will reconnect after a small
# delay.
#
SSH_HOSTNAME=$1
TMUX_NAME=$2
PORT=$3
if [[ "$PORT" != "" ]]
then
PORT="-p $PORT"
fi
if [ "$TMUX_NAME" = "" ]
then
SSH_UNIQUE_ID_FILE="/tmp/.ssh-UNIQUE_ID.$LOGNAME"
if [ -f $SSH_UNIQUE_ID_FILE ]
then
TMUX_NAME=`cat $SSH_UNIQUE_ID_FILE`
TMUX_NAME=`expr $TMUX_NAME + $RANDOM % 100`
else
TMUX_NAME=`expr $RANDOM % 1024`
fi
echo $TMUX_NAME > $SSH_UNIQUE_ID_FILE
TMUX_NAME="id$TMUX_NAME"
fi
echo Connecting to tmux $TMUX_NAME on hostname $SSH_HOSTNAME
SLEEP=0
while true; do
ssh $PORT -o TCPKeepAlive=no -o ServerAliveInterval=15 -Y -X -C -t -o BatchMode=yes $SSH_HOSTNAME "tmux attach-session -t $TMUX_NAME || tmux -2 -u new-session -s $TMUX_NAME"
SLEEP=10
if [ $SLEEP -gt 0 ]
then
echo Reconnecting to session $TMUX_NAME on hostname $SSH_HOSTNAME in $SLEEP seconds
sleep $SLEEP
fi
done
IMHO il y a deux solutions possibles qui manquent dans la liste des réponses:
~/.ssh/authorized_keys
de l'hôte:command="tmux attach-session -t mysession || tmux new-session -s mysession" ssh-ed25519 AAAAfoo23bar45foo23bar45foo23bar45foo23bar45foo23bar45foo23bar45foo23bar45 user@client
Cela fonctionnera évidemment avec tous les clients disposant de la clé privée correspondante, ce qui peut être un inconvénient, selon le cas. Il y a un risque qu'en cas de problème, il ne soit plus possible d'entrer dans le serveur.
~/.ssh/config file
du client, que @op utilise déjà de toute façon:Host myhost
Hostname Host
User user
RequestTTY yes # tmux needs a tty and won't work without one!
# sometimes requires "force" instead of "yes".
RemoteCommand tmux attach-session -t mysession || tmux new-session -s mysession
Considérant le risque avec l'option (1), cela pourrait être la meilleure solution. En cas de problème, il suffit de commenter les deux lignes.
Je sais que je ressuscite un vieux fil, mais j’ai travaillé sur la solution bashrc et je pense qu’elle a une utilité:
#attach to the next available tmux session that's not currently occupied
if [[ -z "$TMUX" ]] && [ "SSH_CONNECTION" != "" ];
then
for i in `seq 0 10`; do #max of 10 sessions - don't want an infinite loop until we know this works
SESH=`tmux list-clients -t "$USER-$i-tmux" 2>/dev/null` #send errors to /dev/null - if the session doesn't exist it will throw an error, but we don't care
if [ -z "$SESH" ] #if there's no clients currently connected to this session
then
tmux attach-session -t "$USER-$i-tmux" || tmux new-session -s "$USER-$i-tmux" #attach to it
break #found one and using it, don't keep looping (this will actually run after tmux exits AFAICT)
fi #otherwise, increment session counter and keep going
done
fi
Il y a un plafond à 10 (11) sessions pour le moment - je ne voulais pas tuer mon serveur avec une boucle infinie dans bashrc. Cela semble fonctionner de manière assez fiable, à part l'erreur de tmux qui échoue sur list-clients si la session n'existe pas.