bash 스크립트를 사용하여 텔넷 세션 자동화


80

Bash 스크립트를 사용하여 일부 텔넷 관련 작업을 자동화하는 중입니다. 자동화되면 사용자와 텔넷의 상호 작용이 없습니다. (즉, 완전히 자동화됩니다)

스크립트는 다음과 같습니다.

# 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.

여기에 두 가지 문제가 있습니다.

  1. 스크립트에서 원격 시스템에서 명령을 실행하는 방법 (인간 상호 작용없이)?

    일부 테스트 코드에 대한 경험을 통해 텔넷 10.1.1.1 이 실행될 때 텔넷이 대화 형 세션으로 들어가고 스크립트의 후속 코드 줄이 로컬 시스템에서 실행 된다는 것을 추론 할 수있었습니다 . 로컬 시스템이 아닌 원격 시스템에서 코드 줄을 어떻게 실행할 수 있습니까?

  2. 로컬 시스템의 텔넷 세션에서 활동에 대한 로그 파일을 가져올 수 없습니다. 내가 사용한 stdout 리디렉션은 원격 시스템에 복사본을 만듭니다 (로그를 로컬 시스템에 복사하기 위해 복사 작업을 수행하고 싶지 않음). 이 기능을 어떻게 얻을 수 있습니까?

답변:


77

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 to you (Nice expect feature!)
interact

실행하려면 :

./myscript.expect name user password

2
'기대'는 대부분 대화 형 세션입니다. 내가 원하는 것은 자동화 된 비대화 형 세션입니다. 내가 직면 한 문제는 telnet 10.1.1.1 다음의 모든 행 이 내가 액세스하는 시스템이 아닌 로컬 시스템에서 실행되기 때문에 원격 시스템 (telnet을 통해)에서 스크립트를 실행할 수 없다는 것입니다.

3
Thomas Telensky가 지적했듯이 필요에 따라 ssh가 궁극적으로 더 쉽습니다. 그러나 기대는 완전히 비대화 형일 수 있습니다. 텔넷 다음의 모든 줄은 원격 컴퓨터에서 실행하려는 줄이라는 것을 의미한다고 가정합니다.이 경우 명령을 보내기로 예상 스크립트에 추가하고 상호 작용 명령을 삭제하십시오. 그러나 ssh는 더 쉽고 안전합니다.
joemooney

2
그럴 수 있지. 이 작업에는 expect을 사용하겠습니다.

1
또 다른 좋은 추가 사항은 이것을 읽는 것입니다 -elenako.com/2013/04/04/… , 스크립트가 \r명령 끝에 시퀀스 가없는 경우, 내가 직접 입력을 클릭했을 때 어떤 이유로 작동하지 않았습니다
llamerr

88

예상을 사용하는 것이 좋지만 비 대화 형 사용의 경우 일반 셸 명령으로 충분할 수 있습니다. 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.


2
+1 sleep나는 또한 추가 한 꿈 ;-) 같은 작품 | tee /dev/tty |사이에 화면 ;-)에 전체 세션이합니다
paluh

1
제 경우에는 가장 도움이되는 답변이지만 추가해야했습니다echo -e "command\r";
mf_

1
비대화 형으로 텔넷에 암호를 제공하려면 어떻게합니까?
Geremia

{ echo "remotecommand 1"; echo "remotecommand 2"; sleep 1; } | telnet 10.1.1.1 :이 예는 내 요구 사항을 충족합니다. 텔넷이 실패하고 쉘 스크립트가해야하는 경우 오류 검사를 추가하는 방법을 알고 싶습니다 exit 1.
Yash

44

텔넷은 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 문서를 줄 것입니다.

누군가에게 도움이되기를 바랍니다.)


1
가장 유용한 댓글! 이것은 실제로 명령을 루프에 넣어서 보내는 명령을 자동화 할 수있게합니다
RomanM

또 다른 도움이 포스트 blog.tonycode.com/tech-stuff/http-notes/...
leomeurer

한 줄에 해당하는 항목 : { echo "GET / HTTP/1.1"; echo "Host: www.example.com"; echo; sleep 1; } | telnet www.example.com 80. 처음에는 sleep이 필요하지 않으며 (open 명령을 사용하지 않는 한) 마지막에 2가 아닌 하나의 빈 에코와 sleep 1 만 필요합니다.
baptx

그러나 HTTPS 요청을 수행해야하는 경우 ncat 또는 nc라고도하는 netcat을 사용해야합니다.{ echo "GET / HTTP/1.1"; echo "Host: example.com"; echo; sleep 1; } | ncat --ssl example.com 443
baptx

12

이거 저 한테 ..

사용자 이름과 암호가 필요한 여러 텔넷 로그인을 자동화하려고했습니다. 다른 서버의 로그를 내 컴퓨터에 저장하기 때문에 텔넷 세션은 백그라운드에서 무기한 실행되어야합니다.

telnet.sh는 'expect'명령을 사용하여 텔넷 로그인을 자동화합니다. 더 많은 정보는 여기에서 찾을 수 있습니다 : 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.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)"
  1. 'screen -ls'명령을 사용하여 배경에서 실행중인 화면이 없는지 확인하십시오.
  2. 읽기 http://www.gnu.org/software/screen/manual/screen.html#Stuff를 화면과 그 옵션에 대한 자세한 내용을보실 수 있습니다.
  3. sample_script.sh의 '-p'옵션은 '-X'옵션을 통해 명령을 보내기 위해 특정 창을 미리 선택하고 다시 연결합니다. 그렇지 않으면 'No screen session found'오류가 발생합니다.

2

bash가 삽입 된 expect 스크립트를 사용할 수 있습니다. 아래 예는 비밀번호가없는 임베디드 보드에 telnex를 연결하는 방법을 보여줍니다.

#!/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

2

다음은 나를 위해 일하고 있습니다 ... IP_sheet.txt에 텔넷하려는 모든 IP를 넣으십시오.

while true
read a
do
{
    sleep 3
    echo df -kh
    sleep 3
    echo exit
} | telnet $a
done<IP_sheet.txt

1
#!/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"

0

그 목적을 위해 ssh를 사용하십시오. 암호를 사용하지 않고 키를 생성하고 원격 시스템의 .authorized_keys에 배치합니다. 원격으로 실행할 스크립트를 만들고 다른 컴퓨터에 복사 한 다음 ssh를 사용하여 원격으로 실행하면됩니다.

이 접근 방식을 여러 번 사용하여 큰 성공을 거두었습니다. 또한 텔넷보다 훨씬 안전합니다.


1
ssh확실히보다 안전 telnet하지만 일부 IP 장치는 ssh서비스를 제공하지 않고 telnet장치 사용을위한 프로토콜에 의존 합니다.
fduff 2013

2
텔넷 (프로그램)은 모든 텍스트 기반 클라이언트 / 서버 연결을위한 클라이언트로 사용할 수 있습니다. 예를 들어 HTTP 및 IMAP과 같은 쉬운 테스트에 사용할 수 있습니다. @Tomas의 제안은 Telnet (원격 로그인 서비스) 사용을 SSH로 바꾸는 것입니다. 그의 의견은 사실이지만 아마도 OP가 요구 한 것이 아닐 것입니다.
Rob Shepherd

Rob, 텔넷은 실제로 모든 포트에 연결하는 데 사용할 수 있지만 OP 질문을 참조하십시오. 컨텍스트에서 그는 로그인을 위해서만 텔넷을 사용하기를 원합니다 ( "원격 시스템에서 일부 명령 실행" ). 이 목적으로 텔넷을 사용하는 것은 매우 위험합니다.
TMS

이것은 그의 기존 스크립트를 사용하여 '일부 텔넷 관련 작업 자동화'라는 질문에 대한 대답이 아닙니다.
FractalSpace

0

bash shell / expect에서 텔넷을 사용하는 방법은 다음과 같습니다.

#!/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 "'^]'."

0

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

-4

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**

9
새로움은 무례함에 대한 변명이 아닙니다. FAQ stackoverflow.com/faq를 참조하십시오 .
Verbeia

1
모욕적 인 게 아니에요 .. 미안 해요. 나는 사람들이 expect 명령을 해결책으로 사용하는 것을 계속 봅니다. 나는 사람들이 당신이 성취하려는 것을 이해하는 데 더 나은 해결책이 있다는 것을 깨닫기를 바랍니다. expect 명령은 작동 방식을 보여주지 않고 알지 못하는 경우에 대한 해결 방법 일뿐입니다. 그것은 더 혼란 스럽습니다. 의심스러운 경우 출처로 이동하십시오. 소스를 사용할 수없고 네트워크 프로토콜 인 경우 tcpdump, wireshark, 패킷을 스누핑하고 명령 흐름을 따르고 작업 지식과 함께 무언가를 결합 할 수 있어야합니다.
str8

7
당신이 그렇게 말한다면-저는 Mathematica 프로그래머이므로 당신의 대답과 코멘트의 본질은 저에게 미스터리입니다. 그러나 "멍청이"라는 단어를 의도적으로 모욕적으로 해석하는 것은 나 혼자가 아닙니다. 나는 당신이 사이트에서 조금 더 많은 시간을 보내고 사람들이 여기에서 어떻게 행동하는지 볼 필요가 있다고 생각합니다.
Verbeia
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.