Автоматизация сессии telnet с использованием скриптов bash
Я работаю над автоматизацией некоторых задач, связанных с telnet, используя скрипты Bash. После автоматизации пользователь не будет взаимодействовать с telnet. (то есть это будет полностью автоматизировано)
сценарии выглядят примерно так:
# execute some commands on the local system
# access a remote system with an IP address: 10.1.1.1 (for example)
telnet 10.1.1.1
# execute some commands on the remote system
# log all the activity (in a file) on the Local system
# exit telnet
# continue on with executing the rest of the script.
Здесь я сталкиваюсь с двумя проблемами:
Как выполнить команды на удаленной системе из сценария (без участия человека)?
Из моего опыта работы с некоторыми тестовыми кодами я смог сделать вывод, что при выполнении telnet 10.1.1.1 telnet переходит в интерактивный сеанс, а последующие строки кода в сценарии выполняются в локальной системе. Как я могу запустить строки кода на удаленной системе, а не на локальной?
Я не могу получить файл журнала для активности в сеансе telnet в локальной системе. Перенаправление stdout, которое я использовал, делает копию в удаленной системе (я не хочу выполнять операцию копирования, чтобы скопировать журнал в локальную систему). Как я могу достичь этой функциональности?
14 ответов
Написать expect
скрипт.
Вот пример:
#!/usr/bin/expect
#If it all goes pear shaped the script will timeout after 20 seconds.
set timeout 20
#First argument is assigned to the variable name
set name [lindex $argv 0]
#Second argument is assigned to the variable user
set user [lindex $argv 1]
#Third argument is assigned to the variable password
set password [lindex $argv 2]
#This spawns the telnet program and connects it to the variable name
spawn telnet $name
#The script expects login
expect "login:"
#The script sends the user variable
send "$user "
#The script expects Password
expect "Password:"
#The script sends the password variable
send "$password "
#This hands control of the keyboard over two you (Nice expect feature!)
interact
Хотя для неинтерактивного использования я бы также предложил использовать функцию Expect, обычные команды оболочки могут быть достаточными. Telnet принимает свою команду в stdin, поэтому вам просто нужно передать или записать команды в нее:
telnet 10.1.1.1 <<EOF
remotecommand 1
remotecommand 2
EOF
(Редактировать: Судя по комментариям, удаленной команде требуется некоторое время для обработки входных данных, или телнет не принимает изящный ранний сигнал SIGHUP. В этих случаях вы можете попробовать короткий сон на входе:)
{ echo "remotecommand 1"; echo "remotecommand 2"; sleep 1; } | telnet 10.1.1.1
В любом случае, если он становится интерактивным или что-то, используйте expect
,
Telnet часто используется, когда вы изучаете протокол HTTP. Я использовал этот скрипт как часть моего веб-скребка:
echo "open www.example.com 80"
sleep 2
echo "GET /index.html HTTP/1.1"
echo "Host: www.example.com"
echo
echo
sleep 2
допустим, имя сценария get-page.sh:
get-page.sh | telnet
даст вам HTML-документ.
Надеюсь, это будет кому-то полезно;)
Это сработало для меня..
Я пытался автоматизировать несколько входов в Telnet, которые требуют имя пользователя и пароль. Сеанс telnet должен бесконечно выполняться в фоновом режиме, так как я сохраняю журналы с разных серверов на моей машине.
telnet.sh автоматизирует вход в telnet с помощью команды "ожидается". Более подробную информацию можно найти здесь: http://osix.net/modules/article/?id=30
telnet.sh
#!/usr/bin/expect
set timeout 20
set hostName [lindex $argv 0]
set userName [lindex $argv 1]
set password [lindex $argv 2]
spawn telnet $hostName
expect "User Access Verification"
expect "Username:"
send "$userName\r"
expect "Password:"
send "$password\r";
interact
sample_script.sh используется для создания фонового процесса для каждого из сеансов telnet с помощью telnet.sh. Более подробную информацию можно найти в разделе комментариев кода.
sample_script.sh
#!/bin/bash
#start screen in detached mode with session-name 'default_session'
screen -dmS default_session -t screen_name
#save the generated logs in a log file 'abc.log'
screen -S default_session -p screen_name -X stuff "script -f /tmp/abc.log $(printf \\r)"
#start the telnet session and generate logs
screen -S default_session -p screen_name -X stuff "expect telnet.sh hostname username password $(printf \\r)"
- Убедитесь, что в фоновом режиме нет экрана, используя команду 'screen -ls'.
- Прочитайте http://www.gnu.org/software/screen/manual/screen.html чтобы узнать больше об экране и его параметрах.
- Параметр '-p' в файле sample_script.sh предварительно выбирает и повторно подключает к конкретному окну, чтобы отправить команду с помощью параметра '-X', в противном случае вы получите ошибку 'Не найден сеанс экрана'.
Ответ на @thiton был полезным , но я хотел бы избежать
sleep
команда. Также
telnet
не выходил из интерактивного режима, поэтому мой скрипт завис.
Я решил это, отправив команду telnet с помощью curl (которая, кажется, ждет ответа) и явно указав telnet выйти следующим образом:
curl telnet://10.1.1.1:23 <<EOF
remotecommand 1
remotecommand 2
quit
EOF
Вы можете использовать ожидаемые скрипты вместо bash. Ниже приведен пример, как подключиться к встроенной плате без пароля
#!/usr/bin/expect
set ip "<ip>"
spawn "/bin/bash"
send "telnet $ip\r"
expect "'^]'."
send "\r"
expect "#"
sleep 2
send "ls\r"
expect "#"
sleep 2
send -- "^]\r"
expect "telnet>"
send "quit\r"
expect eof
Следующее работает для меня... положить все ваши IP-адреса, которые вы хотите telnet в IP_sheet.txt
while true
read a
do
{
sleep 3
echo df -kh
sleep 3
echo exit
} | telnet $a
done<IP_sheet.txt
Используйте ssh для этой цели. Генерируйте ключи без использования пароля и поместите его в.authorized_keys на удаленном компьютере. Создайте сценарий для удаленного запуска, скопируйте его на другой компьютер, а затем просто запустите его удаленно, используя ssh.
Я использовал этот подход много раз с большим успехом. Также обратите внимание, что это намного более безопасно, чем telnet.
#!/bin/bash
ping_count="4"
avg_max_limit="1500"
router="sagemcom-fast-2804-v2"
adress="192.168.1.1"
user="admin"
pass="admin"
VAR=$(
expect -c "
set timeout 3
spawn telnet "$adress"
expect \"Login:\"
send \"$user\n\"
expect \"Password:\"
send \"$pass\n\"
expect \"commands.\"
send \"ping ya.ru -c $ping_count\n\"
set timeout 9
expect \"transmitted\"
send \"exit\"
")
count_ping=$(echo "$VAR" | grep packets | cut -c 1)
avg_ms=$(echo "$VAR" | grep round-trip | cut -d '/' -f 4 | cut -d '.' -f 1)
echo "1_____ping___$count_ping|||____$avg_ms"
echo "$VAR"
Используйте команды telnet и echo в конвейере со всеми шагами аутентификации telnet, как показано ниже.
echo {open host <ip> } | telnet > ${OUT_FILE}
См. Ссылку ниже: - https://www.inshellscripting.online/2020/07/how-telnet-on-remote-server-to-execute.html
Вот решение, которое будет работать со списком расширителей. Для этого требуется только bash - для некоторых из приведенных выше ответов требуется ожидать, и вы, возможно, не сможете рассчитывать на то, что ожидание будет установлено.
#!/bin/bash
declare -a Extenders=("192.168.1.48" "192.168.1.50" "192.168.1.51")
# "192.168.1.52" "192.168.1.56" "192.168.1.58" "192.168.1.59" "192.168.1.143")
sleep 5
# Iterate the string array using for loop
for val in ${Extenders[@]}; do
{ sleep 0.2; echo "root"; sleep 0.2; echo "ls"; sleep 0.2; } | telnet $val
done
Скрипт для получения версии CISCO-серверов:
#!/bin/sh
servers='
192.168.34.1
192.168.34.3
192.168.34.2
192.168.34.3
'
user='cisco_login'
pass='cisco_password'
show_version() {
host=$1
expect << EOF
set timeout 20
set host $host
set user $user
set pass $pass
spawn telnet $host
expect "Username:"
send "$user\r"
expect "Password:"
send "$pass\r"
expect -re ".*#"
send "show version\r"
expect -re ".*-More-.*"
send " "
expect -re ".*#"
send "exit\r"
EOF
}
for ip in $servers; do
echo '---------------------------------------------'
echo "$ip"
show_version $ip | grep -A3 'SW Version'
done
Вот как использовать telnet в оболочке bash
#!/usr/bin/expect
# just do a chmod 755 one the script
# ./YOUR_SCRIPT_NAME.sh $YOUHOST $PORT
# if you get "Escape character is '^]'" as the output it means got connected otherwise it has failed
set ip [lindex $argv 0]
set port [lindex $argv 1]
set timeout 5
spawn telnet $ip $port
expect "'^]'."
Играть с tcpdump
или же wireshark
и посмотреть, какие команды отправляются на сам сервер
Попробуй это
printf (printf "$username\r\n$password\r\nwhoami\r\nexit\r\n") | ncat $target 23
Некоторые серверы требуют задержки с паролем, поскольку он не содержит строк в стеке
printf (printf "$username\r\n";sleep 1;printf "$password\r\nwhoami\r\nexit\r\n") | ncat $target 23**