У нас сервера загружаются по сети, загружается унифицированный минималистичный образ, без каких-либо настроек вообще, вот прям установили систему и загрузили только-только. И такой сервер должен пройти обязательную первичную настройку, например надо задать пароль root, запустить ssh сервер. Всё это надо сделать после загрузки ОС.
Можно конечно просто в /etc/rc.local скинуть все команды и забыть.
Но я решил пойти другим более интересным путём, я хочу чтобы всё выглядело так, как будто бы систему после загрузки каждый раз настраивал живой человек, а не просто запускался невидимый глазу скрипт, выполнялся, а чего выполнялся – не понятно.
Я решил сделать так, чтобы после загрузки происходил автоматический логин пользователя root, а далее выполняется запуск tmux, внутри которого делается настройка сервера. Не скриптом, а руками, типа руками живого человека.
Для чего это нужно?
Во-первых, чтобы видеть полную картину настройки и запуска всех команд, если что-то пошло не так, ты в любой момент сам уже зайти на сервер, сделать tmux attach и увидеть что там произошло.
Во-вторых, даже запуск скрипта внутри tmux не работает так, как мы того ожидаем: дело в том, что, запустив tmux new-window bash -c script, после выполнения скрипта мы не получим свою bash консоль обратно, а окно tmux просто закрывается, т.к. скрипт завершил работу. Можно сделать read, ожидать нажатия любой кнопки, но… Нет.
Приступим.
Для того, чтобы после загрузки init автоматически залогинился, нужно в inittab добавить параметр autologin.
Было:
c1:2:respawn:/sbin/agetty --noclear 38400 tty1 linux
Стало:
c1:2:respawn:/sbin/agetty --autologin root --noclear 38400 tty1 linux
Далее в ~/.bash_profile добавляем запуск скрипта:
$HOME/.local/bin/tmux.sh
В самом скрипте творим магию:
#!/bin/sh
tmux_exec="$(/usr/bin/env which tmux)"
bash_exec="$(/usr/bin/env which bash)"
# если сессия 0 уже запущена, не делаем ничего
if $tmux_exec has-session 1>/dev/null 2>/dev/null; then
:
# иначе
else
# запускаем tmux сервер
$tmux_exec start-server
# запускаем новую сессию, имя по-умолчанию "0"
$tmux_exec new-session -d "$bash_exec"
# запускаем ещё одно окно, просто пусть будет
$tmux_exec new-window -d "$bash_exec"
# используя send-keys посылаем наборы символов в tmux
# как если бы мы их сами печатали руками
# команда echo Hello World!
execute_command="echo Hello World!"
# преобразуем её в представление HEX
# 0x65 0x63 0x68 0x6F 0x20 0x48 0x65 0x6C 0x6C 0x6F 0x20 0x57 0x6F 0x72 0x6C 0x64 0x21 0x0A
execute_command_hex="$(xxd -p -u <<< "$execute_command" | sed "s/\(..\)/0x& /g; s/, $//;")"
# отправляем
tmux send-keys -H $execute_command_hex
fi
далее если мы посмотрим в tmux attach, то мы увидим, что команда выполнилась!
Таким вот образом мы можем целиком конфигурировать всю систему, посылая различные команды набранные «собственноручно» прямо в tmux через send-keys.
Таким же образом можно организовать ввод пароля по ssh, запустить ssh-подключение внутри tmux, а после чего отправить пароль.
# tmux start-server
# tmux new-session -d ssh root@localhost
# tmux send-keys "password" Enter
# tmux attach
И после tmux attach мы видим, что зашли на хост.