Архив метки: telnet

Автоматизация Telnet/SSH

Одна из часто встречающихся задач администрирования — автоматизация терминальной рутины; иными словами, действий, выполняемых через Telnet или SSH.

Tmagic

На сайте IBM есть такая вещь, как Terminal Automation Tool (Tmagic). Вот пример скрипта, который она может выполнить:

* Variables declared below.
V host=host1
V port=23
V user=user1
V password=user1
V prompt="$ «* Variable with special meaning
V ThinkTime=2
V TimeOut=2
V NumThreads=2
V LogSeed=»TMagic"
V LogPath="/tmp"

* Connect and logon
C «${host} ${port}»R «login»
S «${user}\r»
R «Password»
S «${password}\r»
R «${prompt}»
L «Logged in.\n»

* A simple «date» command
FOR 5 TIMES DO
S «date\r»
R «${prompt}»
D 1
DONE
L «All Done\n»

Q

Как видим, здесь происходит подключение к хосту и выполнение на нем неких команд. Результаты работы записываются в лог. Если этого достаточно, можно идти и скачивать. Небольшая инструкция входит в комплект.

Expect

Expect, расширение языка Tcl — куда более мощный инструмент.

Я скачивал в исходниках expect-5.43.0-5.1.src.rpm и компилировал. Потребуется установить собственно expect, tcl и tcl.src. Поскольку все это может оказаться в довольно неожиданных каталогах, могут потребоваться дополнительные параметры для configure. Здесь tclconfig — это местонахождение tclConfig.sh, tclinclude — понятно, исходников tcl.

./configure --with-tclconfig=/usr/lib --with-tclinclude=/usr/src/redhat/SOURCES/tcl8.4.13

Потом как обычно, make и make install.

Вот скрипт, близкий к тому, что я реально использую для автоматизации одной из задач:

#!/usr/local/bin/expect -f
# --------------------------------------
# Usage: expect-script [host] [username]
# --------------------------------------
# Variables
set host [lrange $argv 0 0]
set user [lrange $argv 1 1]
set timeout -1# Connect to remote host
spawn ssh $user@$host
match_max 100000

# Wait for password prompt
expect «*?assword:*»

# Grab the password without showing it
stty -echo
expect_user -re «(.*)\n»
send_user «\n»
stty echo
set password $expect_out(1,string)

# ...and then send it
send — «$password\r»
send_user «\n»

# Wait for command prompt
expect -re «(%|#|\\$) $»

# Send actual commands
send «command1\r»
send «command2\r»
send «A»
send «B»
send «C»

# Leave control to the user
interact

Здесь тоже все вполне понятно: из командной строки берутся два аргумента — имя хоста и имя пользователя, затем мы подключаемся к хосту по SSH, запрашиваем пароль у пользователя (на экране он не будет отображаться), посылаем пароль, ждем появления командной строки и посылаем некоторые команды и нажатия клавиш. В конце мы отдаем управление терминалом пользователю.

Разумеется, фазу ввода пароля можно исключить:

set password MyPaSsWoRd
expect «*?assword:*»
send — «$password\r»
send_user «\n»
expect -re «(%|#|\\$) $»

Тогда пароль будет фигурировать в скрипте в открытом виде. Можно пойти правильным путем, отказаться от паролей в пользу ключей и применить ssh-agent/ssh-add, и это отдельная тема.

Приведенный скрипт я использую совместно с другим, который сначала запускает GNOME Terminal с нужной кодировкой:

export LANG=ru_RU.IBM866; gnome-terminal --disable-factory --execute /scripts/expect-script hostname username

Более подробно о настройке GNOME Terminal речь шла в предыдущей заметке: GNOME Terminal: кодировка по умолчанию.

Способ скрытия пароля при вводе взят отсюда: http://stackoverflow.com/questions/681928/how-can-i-make-an-expect-script-prompt-for-a-password