Gå til innhold

[Expect/TCL] Telnet til router - hente iper fra database


Anbefalte innlegg

Hei har et script som telneter til en router og utfører en komando. Scriptet er skrevet i expect. Skulle hatt et script slik at jeg kan hente mange iper fra en database og utføre spøringen mot alle routerne.

 

 

#!/usr/bin/expect

 

proc fail args {

puts "[lindex $args 0]"

exit

}

 

proc trypass pass {

global lpass

send "$pass\r"

set lpass $pass

}

 

set ip 10.0.0.0

# Kan sette ip med komandoen under, da maa du scriptet kjores med

# ./filnavn ip-til-modem

# [lindex $argv 0]

 

set passfile [open "passfile" "r"]

set password [read $passfile]

set password [lindex [split $password "\n"] end-1]

close $passfile

 

set newpass mitthemmeligepassord

# komandoen paa linjen under setter random tall som passord

# [expr rand()]

# Kan ogsaa sette set newpass 1234, da blir passordet fast 1234

puts "$password > $newpass"

 

set timeout 10

spawn telnet $ip

 

set i 0

while (true) {

expect {

"Password: " {

incr i;

if {$i==1} {trypass $password}

if {$i==2} {trypass 1234}

if {$i==3} {trypass etannetpassord}

if {$i==4} {trypass ennda flere passord}

if {$i>=5} {fail "Bad Password"}

}

"Number:" {break}

"Password!!!" {fail "Bad Password"}

timeout {fail "Timed out"}

eof {fail "Got a eof"}

}

}

if {"$newpass"=="$lpass"} {send "99\r";expect eof; fail "Password is the same. Quited"}

 

send "23\r"

 

expect {

"CANCEL:" {send "$lpass\r"; send "$newpass\r"; send "$newpass\r\r"; set passfile [open "passfile" "a"];puts $passfile $newpass;close $passfile}

timeout {fail "Timed out"}

eof {fail "Got a eof"}

}

expect {

"Number:" {send "99\r"}

timeout {fail "Timed out"}

eof {fail "Got a eof"}

}

#expect eof

 

 

Passordene blir lagret i en annen fil, der scriptet legger det nye nederst.

Jeg har fått til alt untatt at scriptet skal gå mot flere routere og være automatikk slik jeg slipper å skrive inn alle ip manuelt. Her snakker vi om over 50 routere/modem.

Jeg har testet scriptet mot den faste ipen som står i scriptet. Dette funker!

Endret av Datasmurfen.
Lenke til kommentar
Videoannonse
Annonse
  • 3 uker senere...

Du kan feks gjøre det i python, som mest sannsynlig allerede er installert hvis du bruker linux.

 

Eksempel hvis du bruker mysql:

#!/usr/bin/python

import MySQLdb
import os

db = MySQLdb.connect(host="localhost", user="BRUKERNAVN", passwd="PASSORD",
db="DATABASE")

cursor = db.cursor()

cursor.execute("SELECT * FROM tabellnavn")

result = cursor.fetchall()

for ip in result:
os.system('./expectfil ' + ip[1])

 

Den burde fungere, hvis du får feil på MySQLdb modulen må du bare installere den, "apt-get install python-mysqldb" hvis du bruker ubuntu.

Lenke til kommentar
Du kan feks gjøre det i python, som mest sannsynlig allerede er installert hvis du bruker linux.

 

Eksempel hvis du bruker mysql:

#!/usr/bin/python

import MySQLdb
import os

db = MySQLdb.connect(host="localhost", user="BRUKERNAVN", passwd="PASSORD",
db="DATABASE")

cursor = db.cursor()

cursor.execute("SELECT * FROM tabellnavn")

result = cursor.fetchall()

for ip in result:
os.system('./expectfil ' + ip[1])

 

Den burde fungere, hvis du får feil på MySQLdb modulen må du bare installere den, "apt-get install python-mysqldb" hvis du bruker ubuntu.

 

Ved å kjøre denne vil scriptet kjøres i loop med de gitte ip adresser? Må vel foreta noen justeringer i mitt ?

Lenke til kommentar
Hei har et script som telneter til en router og utfører en komando. Scriptet er skrevet i expect. Skulle hatt et script slik at jeg kan hente mange iper fra en database og utføre spøringen mot alle routerne.

 

Du behøver ikke dra inn Python osv. her, hvis du ikke vil lære litt Python da.

 

Du kunne gjøre databasekallet ditt inne i fra expect scriptet ditt, men da må du ha en expect som har sql interface, evt. at du linker inn dette.

 

Det som er enklest er nok at du bare gir alle IP'ene på kommandolinja når du starter scriptet så har du en løkke som går over alle IP'ene, som dette eksemplet her:

 

#!/usr/bin/expect


foreach ip "$argv" {
	puts "doing telnet to IP $ip"
	puts "bla bla bla, rest of the stuff here"
}

 

 

Dette vil gi følgende output:

 

$ ./expect-ip.ex 192.168.1.2 192.168.1.3 192.168.1.3
doing telnet to IP 192.168.1.2
bla bla bla, rest of the stuff here
doing telnet to IP 192.168.1.3
bla bla bla, rest of the stuff here
doing telnet to IP 192.168.1.3
bla bla bla, rest of the stuff here

 

Du gjør telnet osv. der hvor "bla bla bla" er.

 

Neste problem er å skrive en bash kommando for å hente ut data fra databasen og dytte det ut på argumentlinja til scriptet. Du kunne gjøre noe som:

 

echo "select ip from mytable where regtime>'2008-01-01'" | psql ipdatabase | xargs ./expect-ip.ex

 

Jeg vet ikke hvilken database du bruker, men du må sørge for at alt som er av headere osv. strippes av før du kjører det inn i xargs. De fleste databaseprogrammer har opsjoner for å gjøre output minst mulig verbose. Hvis du ikke får vekk alle headere osv. kan du pipe det inn head og tail for å skrelle det vekk før du bruker xargs til å kjøre scriptet ditt.

Lenke til kommentar

Blir vel slik scriptet da ?

Tror jeg holder meg til Expect siden det er det jeg kan..

 

 

#!/usr/bin/expect

 

echo "select ip from mytable where regtime>'2008-01-01'" | psql ipdatabase | xargs ./expect-ip.ex

foreach ip "$argv" {

puts "doing telnet to IP $ip"

proc fail args {

puts "[lindex $args 0]"

exit

}

 

proc trypass pass {

global lpass

send "$pass\r"

set lpass $pass

}

 

set ip 10.0.0.0

# Kan sette ip med komandoen under, da maa du scriptet kjores med

# ./filnavn ip-til-modem

# [lindex $argv 0]

 

set passfile [open "passfile" "r"]

set password [read $passfile]

set password [lindex [split $password "\n"] end-1]

close $passfile

 

set newpass mitthemmeligepassord

# komandoen paa linjen under setter random tall som passord

# [expr rand()]

# Kan ogsaa sette set newpass 1234, da blir passordet fast 1234

puts "$password > $newpass"

 

set timeout 10

spawn telnet $ip

 

set i 0

while (true) {

expect {

"Password: " {

incr i;

if {$i==1} {trypass $password}

if {$i==2} {trypass 1234}

if {$i==3} {trypass etannetpassord}

if {$i==4} {trypass ennda flere passord}

if {$i>=5} {fail "Bad Password"}

}

"Number:" {break}

"Password!!!" {fail "Bad Password"}

timeout {fail "Timed out"}

eof {fail "Got a eof"}

}

}

if {"$newpass"=="$lpass"} {send "99\r";expect eof; fail "Password is the same. Quited"}

 

send "23\r"

 

expect {

"CANCEL:" {send "$lpass\r"; send "$newpass\r"; send "$newpass\r\r"; set passfile [open "passfile" "a"];puts $passfile $newpass;close $passfile}

timeout {fail "Timed out"}

eof {fail "Got a eof"}

}

expect {

"Number:" {send "99\r"}

timeout {fail "Timed out"}

eof {fail "Got a eof"}

}

#expect eof

}

 

 

 

 

Endret av Datasmurfen.
Lenke til kommentar
Blir vel slik scriptet da ?

 

 

Nei, det var ikke det jeg mente. Du lager først et shell script, f.eks. expect-ip.sh

 

#!/bin/sh

echo "select ip from mytable where regtime>'2008-01-01'" | psql ipdatabase | xargs ./expect-ip.ex

 

Du må fikse SQL select query (jeg vet ikke hva tabellene og feltene dine heter). Du må endre navnet på database programmet (psql har jeg brukt), du må endre navnet på databasen (jeg vet ikke hva din database heter) og du må endre navnet på scriptet ditt (det heter expect-ip.ex i mitt eksempel ovenfor).

 

Du bør også teste kommandoen ovenfor fram til "... ipdatabase" og se at dette gir deg alle IP adressene (og ikke noe annet), en på hver linje før du forsøker å gi de videre til scriptet ditt (vha xargs).

 

Deretter må du lage en løkke i expect scriptet ditt, det skulle bli noe som:

 

#!/usr/bin/expect

proc ..
proc .. # her har du proc'ene dine


foreach ip "$argv" {
	puts "doing telnet to IP $ip"

	set passfile [open "passfile" "r"]
	set password [read $passfile]
	set password [lindex [split $password "\n"] end-1]
	close $passfile

	#.. resten av kroppen her

	expect {
	"Number:" {send "99\r"}
	timeout {fail "Timed out"}
	eof {fail "Got a eof"}
}

 

Du skal da kunne teste scriptet ditt med "./expect-ip.ex 192.168.1.1 192.168.1.2 192.168.1.3" (bytt ut med IP til ruterene du skal teste).

 

Er ikke helt sikker på hva du gjør med passordene, hvis det er slik at du leser inn passord fra fil bare en gang så kan du legge det foran løkka siden det ikke er nødvendig å åpne passord filen din hver gang

Endret av asicman
Lenke til kommentar
Løkker, er ikke helt stødige på løkker.. Kunne du vist hva du tenker ?

 

foreach ip "$argv" {
	puts "doing telnet to IP $ip"
	puts "bla bla bla, rest of the stuff here"
}

 

Er en løkke. Hvis du ikke er stødig på løkker bør du nok lære litt mer om løkker og programmering før du fortsetter. Siden du bruker expect som egentlig er bygget på Tcl så burde du lese litt om Tcl.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...