Ssh en Rescue mode

hmlinux90 Messages postés 8 Statut Membre -  
mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   -
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,

3 réponses

  1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
     
    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
  2. hmlinux90 Messages postés 8 Statut Membre
     
    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
  3. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
     
    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