Outils personnels

Reverse ssh : Accéder à un serveur derrière un NAT - Firewall : Différence entre versions

De wikiGite

(Service au démarrage de A)
(SYSTEMD)
 
(17 révisions intermédiaires par 3 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
== Fonctionnement ==
+
== Avec au moins un accès externe ==
 +
Un des serveurs du réseau local protégé par un firewall est accessible en SSH depuis l'extérieur. Lui-même a ensuite accès aux autres serveurs du réseau local.
 +
 
 +
On peut, en ligne de commande, passer par ce serveur pour en atteindre un autre ([[Tunnel_SSH_via_un_serveur_interm%C3%A9diaire]]).
 +
 
 +
On peut aussi se servir de du paramètre ProxyCommand, dans ce cas le plus simple est de préconfigurer la connexion par le fichier .ssh/config du poste local. On y déclare :
 +
Host serveur_intermediaire
 +
    Hostname serveur_intermediaire.domain.com
 +
    User root
 +
    ForwardAgent yes
 +
Host serveur_de_destination
 +
    Hostname 192.168.0.200
 +
    User admin
 +
    ProxyCommand ssh serveur_intermediaire -q -W %h:%p
 +
 
 +
"ForwardAgent" : transférer l'agent local (donc notre config) sur le reverse proxy
 +
"Hostname 192.168.0.200" : pour le serveur final on utilise l'adresse réseau interne, celle connue du serveur_intermediaire
 +
 
 +
On a plus qu'à se connecter par
 +
ssh serveur_de_destination
 +
et l'agent + proxyCommand font le reste.
 +
 
 +
== Sans aucun accès externe ==
 
[[Fichier:Reverse.png]]
 
[[Fichier:Reverse.png]]
 
  
 
Le serveur A se trouvant derriere le par-feu créé un tunnel vers le serveur B. Depuis B on se connecte au serveur A au travers du tunnel ssh.
 
Le serveur A se trouvant derriere le par-feu créé un tunnel vers le serveur B. Depuis B on se connecte au serveur A au travers du tunnel ssh.
 
== Prérequis ==
 
== Prérequis ==
Ajouter cette ligne dans /etc/ssh/sshd_config :
+
Ajouter cette ligne dans /etc/ssh/sshd_config sur B:
 
<source lang="bash">AllowTcpForwarding yes</source>
 
<source lang="bash">AllowTcpForwarding yes</source>
  
 
Par sécurité créer un utilisateur dédié au tunnel sur B :
 
Par sécurité créer un utilisateur dédié au tunnel sur B :
 
<source lang="bash">adduser userssh</source>
 
<source lang="bash">adduser userssh</source>
 
  
 
== Reverse ssh ==
 
== Reverse ssh ==
Le port 22222 de l'exemple suivant doit se trouver entre 1024 et 65535. Il faut evidement tenir une liste des ports accociés aux machines.
+
Le port 22222 de l'exemple suivant doit se trouver entre 1024 et 65535. Il faut evidement tenir une liste des ports associés aux machines.
  
 
Créez le tunnel sur le serveur A :
 
Créez le tunnel sur le serveur A :
Ligne 21 : Ligne 41 :
 
<source lang="bash">ssh -p 22222 rootA@127.0.0.1</source>
 
<source lang="bash">ssh -p 22222 rootA@127.0.0.1</source>
  
== Service au démarrage de A ==
+
 
 +
== Lancement automatique sur le serveur A avec autossh ==
  
 
<source lang="bash">aptitude install autossh</source>
 
<source lang="bash">aptitude install autossh</source>
Ligne 31 : Ligne 52 :
 
<source lang="bash">ssh-copy-id -i /root/.ssh/id_dsa.pub userssh@serveurB</source>
 
<source lang="bash">ssh-copy-id -i /root/.ssh/id_dsa.pub userssh@serveurB</source>
  
 +
 +
=== En l’exécutant au démarrage (rc.local) ===
 
ajouter dans /etc/rc.local :
 
ajouter dans /etc/rc.local :
 
<source lang="bash">autossh -i /root/.ssh/id_dsa -NR 22222:localhost:22 userssh@serveurB &</source>
 
<source lang="bash">autossh -i /root/.ssh/id_dsa -NR 22222:localhost:22 userssh@serveurB &</source>
  
  
 
+
=== En créant un script d'init ===
 +
==== SYSVINIT ====
 
Créer un script dans /etc/init.d/autosshd et remplacer les variables REMOTE_ADDR et LISTEN_PORT :
 
Créer un script dans /etc/init.d/autosshd et remplacer les variables REMOTE_ADDR et LISTEN_PORT :
  
Ligne 41 : Ligne 65 :
 
#!/bin/bash
 
#!/bin/bash
  
 +
### BEGIN INIT INFO
 +
# Provides:          autosshd
 +
# Required-Start:   
 +
# Required-Stop:   
 +
# Default-Start:    2 3 4 5
 +
# Default-Stop:      0 1 6
 +
# Short-Description: starts the autossh daemon
 +
# Description:      starts autossh
 +
### END INIT INFO
  
DAEMON="/usr/bin/autossh"
 
DESC="Autossh daemon"
 
 
REMOTE_USER="userssh"
 
REMOTE_USER="userssh"
 
REMOTE_ADDR="test.systea.fr"
 
REMOTE_ADDR="test.systea.fr"
 
LISTEN_PORT="22222"
 
LISTEN_PORT="22222"
 +
 +
DAEMON="/usr/bin/autossh"
 +
DESC="Autossh daemon"
 
LOGFILE="/var/log/autossh.log"
 
LOGFILE="/var/log/autossh.log"
 +
PIDFILE="/tmp/$REMOTE_USER-$REMOTE_ADDR.pid"
  
 
export AUTOSSH_PIDFILE=/tmp/$REMOTE_USER-$REMOTE_ADDR.pid
 
export AUTOSSH_PIDFILE=/tmp/$REMOTE_USER-$REMOTE_ADDR.pid
AUTOSSH_PIDFILE="/tmp/$REMOTE_USER-$REMOTE_ADDR.pid"
+
 
 
test -f $DAEMON || exit 0
 
test -f $DAEMON || exit 0
  
 
is_running() {
 
is_running() {
     if [ -f $AUTOSSH_PIDFILE ]; then
+
     if [ -f $PIDFILE ]; then
         PID=`cat $AUTOSSH_PIDFILE`
+
         PID=`cat $PIDFILE`
 
         if [ -n "$PID" ]; then
 
         if [ -n "$PID" ]; then
 
             return 0
 
             return 0
Ligne 77 : Ligne 112 :
 
         fi
 
         fi
 
     else
 
     else
         echo "Already running (pid $PID)"
+
         echo "[FAIL] Already running (pid $PID)"
 
     fi
 
     fi
 
}
 
}
Ligne 89 : Ligne 124 :
 
         echo "[FAIL] : Not running "
 
         echo "[FAIL] : Not running "
 
     fi
 
     fi
     [ -f $AUTOSSH_PIDFILE ] && rm -f $AUTOSSH_PIDFILE
+
     [ -f $APIDFILE ] && rm -f $PIDFILE
 
}
 
}
  
Ligne 109 : Ligne 144 :
 
         else
 
         else
 
             echo "$DESC: not running"
 
             echo "$DESC: not running"
             [ -f $AUTOSSH_PIDFILE ] && exit 1 || exit 3
+
             [ -f $PIDFILE ] && exit 1 || exit 3
 
         fi
 
         fi
 
     ;;
 
     ;;
Ligne 135 : Ligne 170 :
 
  update-rc.d autosshd defaults
 
  update-rc.d autosshd defaults
  
== Se connecter à d'autres port ==
+
==== SYSTEMD ====
 +
En créant un script /etc/systemd/system/foo-autossh.service
 +
<source lang="bash">
 +
[Unit]
 +
Description=AutoSSH service for a reverse tunnel from foo to bar
 +
After=network.target
 +
 
 +
[Service]
 +
User=autossh
 +
# -p [PORT]
 +
# -l [user]
 +
# -M 0 --> no monitoring
 +
# -N Just open the connection and do nothing (not interactive)
 +
# LOCALPORT:IP_ON_EXAMPLE_COM:PORT_ON_EXAMPLE_COM
 +
ExecStart=/usr/bin/autossh -M 0 -f -N -T -q -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -R 22222:localhost:22 userssh@serveurB
 +
ExecStop=killall -s KILL autossh
 +
Restart=always
 +
RestartSec=60
 +
 
 +
[Install]
 +
WantedBy=multi-user.target
 +
</source>
 +
 
 +
== Se connecter à d'autres ports ==
 
On souhaite par exemple se connecter à un serveur web se trouvant sur A.
 
On souhaite par exemple se connecter à un serveur web se trouvant sur A.
  
Ligne 143 : Ligne 201 :
 
Sur B :
 
Sur B :
 
<source lang="bash">firefox "http://127.0.0.1:22280"</source>
 
<source lang="bash">firefox "http://127.0.0.1:22280"</source>
 +
 +
== Se connecter à partir d'un poste client ==
 +
 +
Poste ---> INTERNET ---> serveurB ---> INTERNET ---> serveurA
 +
 +
Sur le poste on lance :
 +
<source lang="bash">ssh root@serveurB -t ssh -p 22222 root@127.0.0.1</source>

Version actuelle datée du 11 janvier 2018 à 11:14

Avec au moins un accès externe

Un des serveurs du réseau local protégé par un firewall est accessible en SSH depuis l'extérieur. Lui-même a ensuite accès aux autres serveurs du réseau local.

On peut, en ligne de commande, passer par ce serveur pour en atteindre un autre (Tunnel_SSH_via_un_serveur_intermédiaire).

On peut aussi se servir de du paramètre ProxyCommand, dans ce cas le plus simple est de préconfigurer la connexion par le fichier .ssh/config du poste local. On y déclare :

Host serveur_intermediaire
   Hostname serveur_intermediaire.domain.com
   User root
   ForwardAgent yes
Host serveur_de_destination
   Hostname 192.168.0.200
   User admin
   ProxyCommand ssh serveur_intermediaire -q -W %h:%p

"ForwardAgent" : transférer l'agent local (donc notre config) sur le reverse proxy "Hostname 192.168.0.200" : pour le serveur final on utilise l'adresse réseau interne, celle connue du serveur_intermediaire

On a plus qu'à se connecter par

ssh serveur_de_destination

et l'agent + proxyCommand font le reste.

Sans aucun accès externe

Reverse.png

Le serveur A se trouvant derriere le par-feu créé un tunnel vers le serveur B. Depuis B on se connecte au serveur A au travers du tunnel ssh.

Prérequis

Ajouter cette ligne dans /etc/ssh/sshd_config sur B:

AllowTcpForwarding yes

Par sécurité créer un utilisateur dédié au tunnel sur B :

adduser userssh

Reverse ssh

Le port 22222 de l'exemple suivant doit se trouver entre 1024 et 65535. Il faut evidement tenir une liste des ports associés aux machines.

Créez le tunnel sur le serveur A :

ssh -NR 22222:localhost:22 userssh@serveurB

Se connecter au tunnel depuis le serveur B

ssh -p 22222 rootA@127.0.0.1


Lancement automatique sur le serveur A avec autossh

aptitude install autossh

Générer une paire de clef avec root

ssh-keygen -t dsa

Faire un echange de clef avec le serveur B:

ssh-copy-id -i /root/.ssh/id_dsa.pub userssh@serveurB


En l’exécutant au démarrage (rc.local)

ajouter dans /etc/rc.local :

autossh -i /root/.ssh/id_dsa -NR 22222:localhost:22 userssh@serveurB &


En créant un script d'init

SYSVINIT

Créer un script dans /etc/init.d/autosshd et remplacer les variables REMOTE_ADDR et LISTEN_PORT :

#!/bin/bash

### BEGIN INIT INFO
# Provides:          autosshd
# Required-Start:    
# Required-Stop:     
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the autossh daemon
# Description:       starts autossh
### END INIT INFO

REMOTE_USER="userssh"
REMOTE_ADDR="test.systea.fr"
LISTEN_PORT="22222"

DAEMON="/usr/bin/autossh"
DESC="Autossh daemon"
LOGFILE="/var/log/autossh.log"
PIDFILE="/tmp/$REMOTE_USER-$REMOTE_ADDR.pid"

export AUTOSSH_PIDFILE=/tmp/$REMOTE_USER-$REMOTE_ADDR.pid

test -f $DAEMON || exit 0

is_running() {
    if [ -f $PIDFILE ]; then
        PID=`cat $PIDFILE`
        if [ -n "$PID" ]; then
            return 0
        else
            return 1
        fi
    else
        return 1
    fi
}

start_autossh() {
    if ! is_running; then
        echo -n "Starting $DESC"
        $DAEMON -i /root/.ssh/id_dsa -NR $LISTEN_PORT:localhost:22 $REMOTE_USER@$REMOTE_ADDR >> $LOGFILE 2>&1 &
        sleep 1;
        if is_running; then
            echo " [DONE] : Running @ pid $PID "
        else
            echo '[FAIL]';
        fi
    else
        echo "[FAIL] Already running (pid $PID)"
    fi
}

stop_autossh() {
    if is_running; then
        echo -n "Stopping $DESC: "
        kill -s SIGTERM $PID
        echo "[DONE]"
    else
        echo "[FAIL] : Not running "
    fi
    [ -f $APIDFILE ] && rm -f $PIDFILE
}

case "$1" in
    start)
        start_autossh
    ;;
    stop)
        stop_autossh
    ;;
    force-reload|restart)
        stop_autossh
        start_autossh
    ;;
    status)
        if is_running; then
            echo "$DESC: running (pid $PID)"
            exit 0
        else
            echo "$DESC: not running"
            [ -f $PIDFILE ] && exit 1 || exit 3
        fi
    ;;
    log)
        if [ -f $LOGFILE ]; then
            tail $LOGFILE
        else
            echo "[FAIL] : log file '$LOGFILE' does't exist"
        fi
    ;;
    *)
        echo "Usage: $0 {start|stop|restart|force-reload|status|log}"
        exit 3
    ;;
esac

exit 0

Autoriser l'execution du script :

chmod +x /etc/init.d/autosshd

Ajouter le script au démarage :

update-rc.d autosshd defaults

SYSTEMD

En créant un script /etc/systemd/system/foo-autossh.service

[Unit]
Description=AutoSSH service for a reverse tunnel from foo to bar
After=network.target

[Service]
User=autossh
# -p [PORT]
# -l [user]
# -M 0 --> no monitoring
# -N Just open the connection and do nothing (not interactive)
# LOCALPORT:IP_ON_EXAMPLE_COM:PORT_ON_EXAMPLE_COM
ExecStart=/usr/bin/autossh -M 0 -f -N -T -q -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -R 22222:localhost:22 userssh@serveurB
ExecStop=killall -s KILL autossh
Restart=always
RestartSec=60

[Install]
WantedBy=multi-user.target

Se connecter à d'autres ports

On souhaite par exemple se connecter à un serveur web se trouvant sur A.

Sur A :

ssh -NR 22280:localhost:80 userssh@serveurB

Sur B :

firefox "http://127.0.0.1:22280"

Se connecter à partir d'un poste client

Poste ---> INTERNET ---> serveurB ---> INTERNET ---> serveurA

Sur le poste on lance :

ssh root@serveurB -t ssh -p 22222 root@127.0.0.1