[an error occurred while processing this directive]

Удалённая замена одного Linux-дистрибутива на другой по SSH
Для решения задачи полной переустановки Linux-дистрибутива на удалённом
сервере, к которому имеется только доступ по SSH, подготовлен скрипт
takeover.sh. Скрипт создаёт минималистичное рабочее окружение в памяти,
состоящее из инструментария busybox и простейшего init-процесса. Подключившись
по SSH к данному окружению можно провести переустановку с отмонтированием
корневого раздела. В том числе можно выполнить операции полной очистки всех
данных или переразбить дисковые разделы.

Скрипт обеспечивает только создание окружения, непосредственно операции по
переустановке выполняются вручную, после соединения к созданному окружению по
SSH. Скрипт перемонтирует корневой раздел, но не трогает данные, поэтому в
случае если что-то пошло не так и вручную не были произведены необратимые
изменения для возврата к исходному состоянию достаточно перезагрузить сервер.
После завершения установки новой ОС для выхода из созданного окружения и
загрузки новой системы достаточно инициировать перезагрузку. Перед выполнением
операции на реальном внешнем сервере рекомендуется провести тестовую
переустановку с использованием виртуальной машины.

Порядок операций:

Создадим директорию с окружением для запуска скрипта (/takeover) и примонтируем
к ней раздел tmpfs для хранения нового раздела в оперативной памяти:

   mount -t tmpfs none /takeover

Скопируем в директорию рабочее окружение одного из минималистичных
дистрибутивов для восстановления после сбоев, например,  SystemRescueCD.
После копирования убедимся, что окружение работоспособно при помощи команды:

   chroot /takeover /bin/sh

Скопируем в корень созданного окружения статически собранный вариант пакета 
busybox (/takeover/busybox) и проверим его работоспособность:

   /takeover/busybox sh

Скопируем в окружение скрипт takeover.sh и простейший init-процесс fakeinit,
предварительно скомпилировав его из файла  fakeinit.c:
   
   gcc -static ./fakeinit.c -o ./fakeinit 


Отключаем  по возможности все сервисы на переустанавливаемом сервере, убиваем
процесс cron и завершаем работу http-сервера (скрипт по умолчанию открывает
новый SSH-вход на 80 порту (на 22 порту пока висит старый SSH), поэтому важно,
чтобы на этом порту не было обработчиков).

Запускаем /takeover/takeover.sh и выполняем предложенные действия (задаём
пароль входа и соглашаемся с продолжением выполнения операции). Далее заходим в
новое окружение по SSH:

   ssh -p 80 root@my_host

После входа удаляем все оставшиеся фоновые процессы старой системы и
отмонтируем все разделы старой системы из директории /old_root, после чего
отмонтируем корень старой системы (/old_root). Предварительно копируем в
текущее окружение набор модулей ядра от старой системы /old_root/lib/modules,
на случае если они понадобятся в процессе замены старой системы.


Выполняем операции по замене системы, не забываем отмонтировать  дисковые
разделы. После завершения работы  перезагужаем систему

   reboot -f 
или
   echo b > /proc/sysrq-trigger


Скрипт takeover.sh:

   #!/bin/sh
   set -e

   TO=/takeover
   OLD_TELINIT=/sbin/telinit
   PORT=80

   cd "$TO"

   if [ ! -e fakeinit ]; then
       ./busybox echo "Please compile fakeinit.c first"
       exit 1
   fi

   ./busybox echo "Please set a root password for sshd"
 
   ./busybox chroot . /bin/passwd

   ./busybox echo "Setting up target filesystem..."
   ./busybox rm -f etc/mtab
   ./busybox ln -s /proc/mounts etc/mtab
   ./busybox mkdir -p old_root

   ./busybox echo "Mounting pseudo-filesystems..."
   ./busybox mount -t tmpfs tmp tmp
   ./busybox mount -t proc proc proc
   ./busybox mount -t sysfs sys sys
   if ! ./busybox mount -t devtmpfs dev dev; then
       ./busybox mount -t tmpfs dev dev
       ./busybox cp -a /dev/* dev/
       ./busybox rm -rf dev/pts
       ./busybox mkdir dev/pts
   fi
   ./busybox mount -t devpts devpts dev/pts

   TTY="$(./busybox tty)"

   ./busybox echo "Checking and switching TTY..."

   exec <"$TO/$TTY" >"$TO/$TTY" 2>"$TO/$TTY"

   ./busybox echo "Type 'OK' to continue"
   ./busybox echo -n "> "
   read a
   if [ "$a" != "OK" ] ; then
       exit 1
   fi

   ./busybox echo "Preparing init..."
   ./busybox cp $OLD_TELINIT tmp/telinit
   ./busybox cat >tmp/init <<EOF
   #!${TO}/busybox sh
   exec <"${TO}/${TTY}" >"${TO}/${TTY}" 2>"${TO}/${TTY}"
   cd "${TO}"
   ./busybox echo "Init takeover successful"
   ./busybox echo "Pivoting root..."
   ./busybox pivot_root . old_root
   ./busybox echo "Chrooting and running init..."
   exec ./busybox chroot . /fakeinit
   EOF
   ./busybox chmod +x tmp/init
   
   ./busybox echo "Starting secondary sshd"
   
   ./busybox chroot . /usr/bin/ssh-keygen -A
   ./busybox chroot . /usr/sbin/sshd -p $PORT

   ./busybox echo "You should SSH into the secondary sshd now."
   ./busybox echo "Type OK to continue"
   ./busybox echo -n "> "
   read a
   if [ "$a" != "OK" ] ; then
       exit 1
   fi

   ./busybox echo "About to take over init. This script will now pause for a few seconds."
   ./busybox echo "If the takeover was successful, you will see output from the new init."
   ./busybox echo "You may then kill the remnants of this session and any remaining"
   ./busybox echo "processes from your new SSH session, and umount the old root filesystem."

   ./busybox mount --bind tmp /sbin

   ./tmp/telinit u

   ./busybox sleep 10



init-процесс fakeinit.c


   #define _XOPEN_SOURCE 700
   #include <signal.h>
   #include <unistd.h>
   #include <sys/wait.h>

   int main()
   {
	sigset_t set;
	int status, i;

	for (i = 0; i < 64; i++)
		close(i);

	if (getpid() != 1) return 1;

	sigfillset(&set);
	sigprocmask(SIG_BLOCK, &set, 0);

	for (;;) wait(&status);
   }
 
Ключи: linux, remote, install, ssh, init, busybox, mount / Лицензия: CC-BY
Раздел:    Корень / Администратору / Система / Загрузка, однопользовательский режим

[an error occurred while processing this directive]

[an error occurred while processing this directive]