tunnel-autossh.md 5.3 KB

% Tunnel SSH avec reverse

Introduction

L'idée est d'ouvrir un tunnel SSH qui passe par un serveur relai.

Le poste de travail (poste) se connecte à la cible via le relai.

        ____________           ____________
poste -------------->[ relai ]-------------> cible
 p_tun >> Tunnel(L) >> p_relai << Tunnel(R) <<port_ssh
        ____________           _____________

Définition d'un tunnel local to server :

port client SSH >> Tunnel(L) >> port serveur SSH

Définition d'un tunnel reverse from server :

port client SSH << Tunnel(R) << port serveur SSH

Exemple

        __________           _________
poste ------------>[ relai ]-----------> cible
  6122>> Tunnel(L) >>6022<< Tunnel(R) <<22
        __________           _________
  • 6122 port d'entrée (1 = in)
  • 6022 port de sortie du tunnel poste > relai (0 = out)
  • 22 port SSH de la cible

Mise en application

IPI

  • <poste>: mon poste de travail (port 6122 sera relié au port 22 de la cible)
  • <relai>: luke
    • (port 6022 reliera la sortie du tunnel entrant (poste > relai) à l'entrée du tunnel reverse (relai > cible))
  • <cible>: proxmox-patrick

Exemple serveur IPI: adresse publique: 185.64.149.17

Création d'une paire de clé sur la cible

En tant qu'utilisateur standard (nom = u_ssh_cible)

Générer une paire de clé privé/publique sur la <cible> SANS passphrase.

Copier la clé publique (elle sera copiée dans le fichier authorized_keys de l'utilisateur tunnel@<relai>)

Mise en place du relai

Création d'un utilisateur tunnel sur <relai>

Fichier authorized_keys pour l'utilisateur tunnel

Préfixe:

from="185.64.149.17",no-agent-forwarding,no-pty,no-X11-forwarding,permitopen="localhost:6022",command="/home/tunnel/bin/tunnelcheck"

Copie de la clé publique de la <cible>:

from="185.64.149.17",no-agent-forwarding,no-pty,no-X11-forwarding,permitopen="localhost:6022",command="/home/tunnel/bin/tunnelcheck" ssh-ed25519 AAAACccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc u_ssh_cible@cible

Création du script de vérification du tunnel

mkdir bin
touch bin/tunnelcheck
chmod +x bin/tunnelcheck

Copier le code suivant dans bin/tunnelcheck :

#!/bin/bash
set -Eeuo pipefail

parameters=(${SSH_ORIGINAL_COMMAND-})

if [[ ${#parameters[@]} -gt 1 ]]
then
	server_response=$(ssh -o PasswordAuthentication=no -p ${parameters[1]} -n -f localhost exit 2>&1 | cut -c1-17 || echo "")
	if [[ ${server_response:-} = "Permission denied" ]]
	then
		echo TUNNEL_OK
		exit 0
	else
		echo TUNNEL_KO
		exit 1
	fi
fi

Mise en place du reverse tunnel sur <cible>

Lancement initial

ssh -f -T -N -R 6022:localhost:22 tunnel@relai.aezi.fr

Vérification depuis le <relai>

Depuis le <relai> en tant qu'utilisateur tunnel, lancer:

SSH_ORIGINAL_COMMAND="tunnel_check 6022" /home/tunnel/bin/tunnelcheck

Vérifier les fingerprint si nécessaire

Mise en place du crontab

Sur la machine <cible> (en tant qu'u_ssh_cible ):

crontab -e

Coller la ligne suivante:

*/30 * * * * /usr/bin/ssh tunnel@relai.aezi.fr /home/tunnel/bin/tunnelcheck 6022 && echo OK || /usr/bin/ssh -f -T -N -R 6022:localhost:22 tunnel@relai.aezi.fr

Depuis le <poste> de travail

Ouverture du tunnel vers le <relai>

ssh -f -T -N -L 6122:localhost:6022 tunnel@relai.aezi.fr

Connection

ssh -p 6122 u_ssh_cible@localhost
# Sur ma machine
ssh -f -T -N -L 6122:localhost:6022 tunnel@relai.aezi.fr
ssh -L 55522:localhost:55555 tunnel@relai.aezi.fr

# Pour se connecter
ssh -p 55522 laurent@127.0.0.1

IMPORTANT: à la première connection

Vérifier les fingerprint

Finalisation de la sécurisation

Désactiver l'utilisateur tunnel

Sur le serveur cible

#!/bin/bash

#autossh -f -M 0 -N -o "ServerAliveInterval 10" -o "ServerAliveCountMax 3" -T -N -R 22:localhost:55555 tunnel@relai.aezi.fr
#autossh -v -M 0 -o "ServerAliveInterval 10" -o "ServerAliveCountMax 3" -T -N -f -R 55555:localhost:22 tunnel@relai.aezi.fr
autossh -v -M 55556 -T -N -f -R 55555:localhost:22 tunnel@relai.aezi.fr
#ssh -v -f -N -T -R 55555:localhost:22 tunnel@relai.aezi.fr

Solution Maison

Côté serveur

ssh tunnel@relai.aezi.fr /home/tunnel/bin/tunnelcheck 55555 && echo OK || ssh -f -T -N -R 55555:localhost:22 tunnel@relai.aezi.fr

Côté relai

$ cat bin/tunnelcheck
#!/bin/bash
set -Eeuo pipefail

parameters=(${SSH_ORIGINAL_COMMAND-})

if [[ ${#parameters[@]} -gt 1 ]]
then
	server_response=$(ssh -o PasswordAuthentication=no -p ${parameters[1]} -n -f localhost exit 2>&1 | cut -c1-17 || echo "")
	if [[ ${server_response:-} = "Permission denied" ]]
	then
		echo TUNNEL_OK
		exit 0
	else
		echo TUNNEL_KO
		exit 1
	fi
fi

Pour tester côté relai:

$ SSH_ORIGINAL_COMMAND="tunnel_check 55555" bin/tunnelcheck

Sources

Gestion des sessions et du contrôle