Ssh en Rescue mode

Fermé
hmlinux90 Messages postés 6 Date d'inscription mercredi 16 janvier 2008 Statut Membre Dernière intervention 1 octobre 2010 - Modifié par hmlinux90 le 1/10/2010 à 14:52
mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024 - 1 oct. 2010 à 19:01
Bonjour,

Je rencontre un soucis sur un serveur SLES9 distant pour lequel je souhaite accéder en ssh via le mode rescue. En effet, l'OS ayant quelque peu crashé, je n'ai plus la possibilité de le faire booter.

Existe t'il donc une solution pour accéder en ssh sur le serveur qui est en rescue mode?

Merci d'avance,

A voir également:

3 réponses

mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024 7 748
Modifié par mamiemando le 1/10/2010 à 16:11
En fait tout dépend de ce que le rescue mode te permet de faire. Si tu peux accéder à la machine en local, déjà on part bien, car tu vas pouvoir lancer le service ssh et par la suite y accéder depuis le réseau.

Version courte

A priori le démon sshd (le serveur ssh) est instancié via le script /etc/init.d/ssh ou nom proche. On peut instancier ce script directement par la commande suivante (en root) :

/etc/init.d/ssh start


... ou mieux (mais pas toujours possible si la distribution est vieille par exemple) :

service ssh start


(ce qui est équivalent soit dit en passant). Après quoi le serveur ssh devrait être accessible.

Version longue

En fait il faut bien voir que démarrer en rescue mode ou en normal mode ne consiste (une fois le kernel chargé) qu'à démarrer sur un runlevel différent. Un runlevel correspond à un état de la machine (arrêt, rescue, normal, ...., reboot) numéroté de 0 à 6. L'un d'eux (le 2 sous debian) est le runlevel par défaut. Certains sont standardisés (0 pour l'arrêt (halt), 1 pour le mode simple utilisateur (recovery), et 6 pour le reboot).

En fonction du runlevel sur lequel on démarre, certaines lignes de /etc/inittab sont évaluées ou non. Pour les distributions plus récente, note que ce fichier n'existe plus mais le principe reste le même. Bref, ce fichier instancie le script shell /etc/init.d/rc et lui passe le runlevel en paramètre.

Extrait de /etc/inittab

...
# /etc/init.d executes the S and K scripts upon change
# of runlevel.
#
# Runlevel 0 is halt.
# Runlevel 1 is single-user.
# Runlevels 2-5 are multi-user.
# Runlevel 6 is reboot.

l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
...


Celui-ci instancie en cascade (soit start, soit stop) un ou plusieurs services. Rappelons que les scripts associés aux services sont tous dans /etc/init.d (et c'est pour ca que ssh se lance par /etc/init.d/ssh).

Pour savoir ce qu'il doit lancer ou éteindre, le script /etc/init.d/rc examine les liens symboliques établis dans /etc/rcX.d ou X est à remplacer par le numéro du runlevel dans lequel on bascule. C'est lien commence par K (kill) ou S (start) selon les services qui doivent être coupés ou démarrés dans tel ou tel runlevel.

Ainsi /etc/rc0.d (arrêt) et /etc/rc6.d (reboot) contiennent uniquement des liens K (on éteint tout), tandis que /etc/rc1.d contient quelques S et /etc/rc2.d plus de liens S (on démarre plus de service en mode normal qu'en recovery).

Bref tu l'auras compris, démarrer en recovery mode ne revient qu'à lancer moins de service, mais on peut tout à fait les instancier a posteriori. C'est le rôle de la commande :

/etc/init.d/ssh start
service ssh start


(qui est un script shell et que tu peux regarder avec ton éditeur texte favori). Note que tous les scripts de /etc/init.d supporte le passage des mêmes options (start, stop, restart, ...).

On peut même basculer la machine dans un autre runlevel (voir commandes init, halt et reboot) qui, tu l'auras compris consistent notamment à invoquer les scripts associés aux différents services.

Bonne chance
0
hmlinux90 Messages postés 6 Date d'inscription mercredi 16 janvier 2008 Statut Membre Dernière intervention 1 octobre 2010
1 oct. 2010 à 17:21
Merci mamiemando pour ta réponse précise.

Le soucis est que lorsque je boot sur le mode rescue (via le CD de la SLES9), dans /etc/init.d, je n'ai pas le service ssh ou sshd de disponible. Je peut mettre en place une IP sur le serveur avec "ifconfig eth0 XX.XX.XX.XX", ce dernier devient donc visible sur le réseau (ping OK) mais le ssh ne fonctionne pas.

Cordialement
0
mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024 7 748
1 oct. 2010 à 19:01
Forcément... si tu ne lances pas de démon ssh, pas de ssh :) Il devrait apparaître (s'il est lancé) avec un ps :

(mando@aldur) (~) $ ps aux | grep sshd
root      1781  0.0  0.0   5492   944 ?        Ss   18:47   0:00 /usr/sbin/sshd
mando     2349  0.0  0.0   3320   812 pts/1    S+   18:56   0:00 grep sshd


Rien ne t'empêche d'instancier directement sshd par cette commande (en root) :

/usr/sbin/sshd


... mais a priori on fait plutôt ça via un service (donc le fameux /etc/init.d/ssh start).

Au pire si tu veux vraiment passer par un script, voici les fichiers utilisés sous debian (à préparer sur clé usb par exemple)

/lib/lsb/init-functions

# /lib/lsb/init-functions for Debian -*- shell-script -*-
#
#Copyright (c) 2002-08 Chris Lawrence
#All rights reserved.
#
#Redistribution and use in source and binary forms, with or without
#modification, are permitted provided that the following conditions
#are met:
#1. Redistributions of source code must retain the above copyright
#   notice, this list of conditions and the following disclaimer.
#2. Redistributions in binary form must reproduce the above copyright
#   notice, this list of conditions and the following disclaimer in the
#   documentation and/or other materials provided with the distribution.
#3. Neither the name of the author nor the names of other contributors
#   may be used to endorse or promote products derived from this software
#   without specific prior written permission.
#
#THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
#IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
#LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
#CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
#SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
#BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
#OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
#EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

start_daemon () {
    local force nice pidfile exec i args
    force=0
    nice=0
    pidfile=/dev/null

    OPTIND=1
    while getopts fn:p: opt ; do
        case "$opt" in
            f)  force=1;;
            n)  nice="$OPTARG";;
            p)  pidfile="$OPTARG";;
        esac
    done
    
    shift $(($OPTIND - 1))
    if [ "$1" = '--' ]; then
        shift
    fi

    exec="$1"; shift

    args="--start --nicelevel $nice --quiet --oknodo"
    if [ $force = 1 ]; then
        /sbin/start-stop-daemon $args --chdir "$PWD" --startas $exec --pidfile /dev/null -- "$@"
    elif [ $pidfile ]; then
        /sbin/start-stop-daemon $args --chdir "$PWD" --exec $exec --oknodo --pidfile "$pidfile" -- "$@"
    else
        /sbin/start-stop-daemon $args --chdir "$PWD" --exec $exec -- "$@"
    fi
}

pidofproc () {
    local pidfile line i pids= status specified pid
    pidfile=
    specified=
    
    OPTIND=1
    while getopts p: opt ; do
        case "$opt" in
            p)  pidfile="$OPTARG"; specified=1;;
        esac
    done
    shift $(($OPTIND - 1))

    base=${1##*/}
    if [ ! "$specified" ]; then
        pidfile="/var/run/$base.pid"
    fi

    if [ -n "${pidfile:-}" -a -r "$pidfile" ]; then
        read pid < "$pidfile"
        if [ -n "${pid:-}" ]; then
            if $(kill -0 "${pid:-}" 2> /dev/null); then
                echo "$pid"
                return 0
            elif ps "${pid:-}" >/dev/null 2>&1; then
                echo "$pid"
                return 0 # program is running, but not owned by this user
            else
                return 1 # program is dead and /var/run pid file exists
            fi
        fi
    fi
    if [ -x /bin/pidof -a ! "$specified" ]; then
        status="0"
        /bin/pidof -o %PPID -x $1 || status="$?"
        if [ "$status" = 1 ]; then
            return 3 # program is not running
        fi
        return 0
    fi
    return 4 # Unable to determine status
}

# start-stop-daemon uses the same algorithm as "pidofproc" above.
killproc () {
    local pidfile sig status base i name_param is_term_sig
    pidfile=
    name_param=
    is_term_sig=no

    OPTIND=1
    while getopts p: opt ; do
        case "$opt" in
            p)  pidfile="$OPTARG";;
        esac
    done
    shift $(($OPTIND - 1))

    base=${1##*/}
    if [ ! $pidfile ]; then
        name_param="--name $base --pidfile /var/run/$base.pid"
    else
        name_param="--pidfile $pidfile"
    fi

    sig=$(echo ${2:-} | sed -e 's/^-\(.*\)/\1/')
    sig=$(echo $sig | sed -e 's/^SIG\(.*\)/\1/')
    if [ -z "$sig" -o "$sig" = 15 -o "$sig" = TERM ]; then
        is_term_sig=yes
    fi
    status=0
    if [ ! "$is_term_sig" = yes ]; then
        if [ -n "$sig" ]; then
            /sbin/start-stop-daemon --stop --signal "$sig" --quiet $name_param || status="$?"
        else
            /sbin/start-stop-daemon --stop --quiet $name_param || status="$?"
        fi
    else
        /sbin/start-stop-daemon --stop --quiet --oknodo $name_param || status="$?"
    fi
    if [ "$status" = 1 ]; then
        if [ -n "$sig" ]; then
            return 0
        fi
        return 3 # program is not running
    fi

    if [ "$status" = 0 -a "$is_term_sig" = yes -a "$pidfile" ]; then
        pidofproc -p "$pidfile" "$1" >/dev/null || rm -f "$pidfile"
    fi
    return 0
}

# Return LSB status
status_of_proc () {
    local pidfile daemon name status

    pidfile=
    OPTIND=1
    while getopts p: opt ; do
        case "$opt" in
            p)  pidfile="$OPTARG";;
        esac
    done
    shift $(($OPTIND - 1))

    if [ -n "$pidfile" ]; then
        pidfile="-p $pidfile"
    fi
    daemon="$1"
    name="$2"

    status="0"
    pidofproc $pidfile $daemon >/dev/null || status="$?"
    if [ "$status" = 0 ]; then
        log_success_msg "$name is running"
        return 0
    elif [ "$status" = 4 ]; then
        log_failure_msg "could not access PID file for $name"
        return $status
    else
        log_failure_msg "$name is not running"
        return $status
    fi
}

log_use_fancy_output () {
    TPUT=/usr/bin/tput
    EXPR=/usr/bin/expr
    if [ -t 1 ] && [ "x${TERM:-}" != "x" ] && [ "x${TERM:-}" != "xdumb" ] && [ -x $TPUT ] && [ -x $EXPR ] && $TPUT hpa 60 >/dev/null 2>&1 && $TPUT setaf 1 >/dev/null 2>&1; then
        [ -z $FANCYTTY ] && FANCYTTY=1 || true
    else
        FANCYTTY=0
    fi
    case "$FANCYTTY" in
        1|Y|yes|true)   true;;
        *)              false;;
    esac
}

log_success_msg () {
    if [ -n "${1:-}" ]; then
        log_begin_msg $@
    fi
    log_end_msg 0
}

log_failure_msg () {
    if [ -n "${1:-}" ]; then
        log_begin_msg $@ "..."
    fi
    log_end_msg 1 || true
}

log_warning_msg () {
    if [ -n "${1:-}" ]; then
        log_begin_msg $@ "..."
    fi
    log_end_msg 255 || true
}

#
# NON-LSB HELPER FUNCTIONS
#
# int get_lsb_header_val (char *scriptpathname, char *key)
get_lsb_header_val () {
        if [ ! -f "$1" ] || [ -z "${2:-}" ]; then
                return 1
        fi
        LSB_S="### BEGIN INIT INFO"
        LSB_E="### END INIT INFO"
        sed -n "/$LSB_S/,/$LSB_E/ s/# $2: \(.*\)/\1/p" $1
}

# int log_begin_message (char *message)
log_begin_msg () {
    if [ -z "${1:-}" ]; then
        return 1
    fi
    echo -n "$@"
}

# Sample usage:
# log_daemon_msg "Starting GNOME Login Manager" "gdm"
#
# On Debian, would output "Starting GNOME Login Manager: gdm"
# On Ubuntu, would output " * Starting GNOME Login Manager..."
#
# If the second argument is omitted, logging suitable for use with
# log_progress_msg() is used:
#
# log_daemon_msg "Starting remote filesystem services"
#
# On Debian, would output "Starting remote filesystem services:"
# On Ubuntu, would output " * Starting remote filesystem services..."

log_daemon_msg () {
    if [ -z "${1:-}" ]; then
        return 1
    fi
    log_daemon_msg_pre "$@"

    if [ -z "${2:-}" ]; then
        echo -n "$1:"
        return
    fi
    
    echo -n "$1: $2"
    log_daemon_msg_post "$@"
}

# #319739
#
# Per policy docs:
#
#     log_daemon_msg "Starting remote file system services"
#     log_progress_msg "nfsd"; start-stop-daemon --start --quiet nfsd
#     log_progress_msg "mountd"; start-stop-daemon --start --quiet mountd
#     log_progress_msg "ugidd"; start-stop-daemon --start --quiet ugidd
#     log_end_msg 0
#
# You could also do something fancy with log_end_msg here based on the
# return values of start-stop-daemon; this is left as an exercise for
# the reader...
#
# On Ubuntu, one would expect log_progress_msg to be a no-op.
log_progress_msg () {
    if [ -z "${1:-}" ]; then
        return 1
    fi
    echo -n " $@"
}


# int log_end_message (int exitstatus)
log_end_msg () {
    # If no arguments were passed, return
    if [ -z "${1:-}" ]; then
        return 1
    fi

    retval=$1

    log_end_msg_pre "$@"

    # Only do the fancy stuff if we have an appropriate terminal
    # and if /usr is already mounted
    if log_use_fancy_output; then
        RED='$TPUT setaf 1'
        YELLOW='$TPUT setaf 3'
        NORMAL='$TPUT op'
    else
        RED=''
        YELLOW=''
        NORMAL=''
    fi

    if [ $1 -eq 0 ]; then
        echo "."
    elif [ $1 -eq 255 ]; then
        /bin/echo -e " ${YELLOW}(warning).${NORMAL}"
    else
        /bin/echo -e " ${RED}failed!${NORMAL}"
    fi
    log_end_msg_post "$@"
    return $retval
}

log_action_msg () {
    echo "$@."
}

log_action_begin_msg () {
    echo -n "$@..."
}

log_action_cont_msg () {
    echo -n "$@..."
}

log_action_end_msg () {
    log_action_end_msg_pre "$@"
    if [ -z "${2:-}" ]; then
        end="."
    else
        end=" ($2)."
    fi

    if [ $1 -eq 0 ]; then
        echo "done${end}"
    else
        if log_use_fancy_output; then
            RED='$TPUT setaf 1'
            NORMAL='$TPUT op'
            /bin/echo -e "${RED}failed${end}${NORMAL}"
        else
            echo "failed${end}"
        fi
    fi
    log_action_end_msg_post "$@"
}

# Hooks for /etc/lsb-base-logging.sh
log_daemon_msg_pre () { :; }
log_daemon_msg_post () { :; }
log_end_msg_pre () { :; }
log_end_msg_post () { :; }
log_action_end_msg_pre () { :; }
log_action_end_msg_post () { :; }

FANCYTTY=
[ -e /etc/lsb-base-logging.sh ] && . /etc/lsb-base-logging.sh || true


/etc/default/ssh

# Default settings for openssh-server. This file is sourced by /bin/sh from
# /etc/init.d/ssh.

# Options to pass to sshd
SSHD_OPTS=


/etc/init.d/ssh

#! /bin/sh

### BEGIN INIT INFO
# Provides:             sshd
# Required-Start:       $remote_fs $syslog
# Required-Stop:        $remote_fs $syslog
# Default-Start:        2 3 4 5
# Default-Stop:
# Short-Description:    OpenBSD Secure Shell server
### END INIT INFO

set -e

# /etc/init.d/ssh: start and stop the OpenBSD "secure shell(tm)" daemon

test -x /usr/sbin/sshd || exit 0
( /usr/sbin/sshd -\? 2>&1 | grep -q OpenSSH ) 2>/dev/null || exit 0

umask 022

if test -f /etc/default/ssh; then
    . /etc/default/ssh
fi

. /lib/lsb/init-functions

if [ -n "$2" ]; then
    SSHD_OPTS="$SSHD_OPTS $2"
fi

# Are we running from init?
run_by_init() {
    ([ "$previous" ] && [ "$runlevel" ]) || [ "$runlevel" = S ]
}

check_for_no_start() {
    # forget it if we're trying to start, and /etc/ssh/sshd_not_to_be_run exists
    if [ -e /etc/ssh/sshd_not_to_be_run ]; then 
        if [ "$1" = log_end_msg ]; then
            log_end_msg 0
        fi
        if ! run_by_init; then
            log_action_msg "OpenBSD Secure Shell server not in use (/etc/ssh/sshd_not_to_be_run)"
        fi
        exit 0
    fi
}

check_dev_null() {
    if [ ! -c /dev/null ]; then
        if [ "$1" = log_end_msg ]; then
            log_end_msg 1 || true
        fi
        if ! run_by_init; then
            log_action_msg "/dev/null is not a character device!"
        fi
        exit 1
    fi
}

check_privsep_dir() {
    # Create the PrivSep empty dir if necessary
    if [ ! -d /var/run/sshd ]; then
        mkdir /var/run/sshd
        chmod 0755 /var/run/sshd
    fi
}

check_config() {
    if [ ! -e /etc/ssh/sshd_not_to_be_run ]; then
        /usr/sbin/sshd $SSHD_OPTS -t || exit 1
    fi
}

export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"

case "$1" in
  start)
        check_privsep_dir
        check_for_no_start
        check_dev_null
        log_daemon_msg "Starting OpenBSD Secure Shell server" "sshd"
        if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd.pid --exec /usr/sbin/sshd -- $SSHD_OPTS; then
            log_end_msg 0
        else
            log_end_msg 1
        fi
        ;;
  stop)
        log_daemon_msg "Stopping OpenBSD Secure Shell server" "sshd"
        if start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/sshd.pid; then
            log_end_msg 0
        else
            log_end_msg 1
        fi
        ;;

  reload|force-reload)
        check_for_no_start
        check_config
        log_daemon_msg "Reloading OpenBSD Secure Shell server's configuration" "sshd"
        if start-stop-daemon --stop --signal 1 --quiet --oknodo --pidfile /var/run/sshd.pid --exec /usr/sbin/sshd; then
            log_end_msg 0
        else
            log_end_msg 1
        fi
        ;;

  restart)
        check_privsep_dir
        check_config
        log_daemon_msg "Restarting OpenBSD Secure Shell server" "sshd"
        start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile /var/run/sshd.pid
        check_for_no_start log_end_msg
        check_dev_null log_end_msg
        if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd.pid --exec /usr/sbin/sshd -- $SSHD_OPTS; then
            log_end_msg 0
        else
            log_end_msg 1
        fi
        ;;

  try-restart)
        check_privsep_dir
        check_config
        log_daemon_msg "Restarting OpenBSD Secure Shell server" "sshd"
        set +e
        start-stop-daemon --stop --quiet --retry 30 --pidfile /var/run/sshd.pid
        RET="$?"
        set -e
        case $RET in
            0)
                # old daemon stopped
                check_for_no_start log_end_msg
                check_dev_null log_end_msg
                if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd.pid --exec /usr/sbin/sshd -- $SSHD_OPTS; then
                    log_end_msg 0
                else
                    log_end_msg 1
                fi
                ;;
            1)
                # daemon not running
                log_progress_msg "(not running)"
                log_end_msg 0
                ;;
            *)
                # failed to stop
                log_progress_msg "(failed to stop)"
                log_end_msg 1
                ;;
        esac
        ;;

  status)
        status_of_proc -p /var/run/sshd.pid /usr/sbin/sshd sshd && exit 0 || exit $?
        ;;

  *)
        log_action_msg "Usage: /etc/init.d/ssh {start|stop|reload|force-reload|restart|try-restart|status}"
        exit 1
esac

exit 0


... mais je ne sais pas dans quelle mesure il marchera chez toi. Le plus simple est peut-être d'instancier directement sshd à la main.

Bonne chance
0