cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
2050
Views
0
Helpful
3
Replies

Help with Expect script to configure Cisco IPS sensor

genewolfe
Level 1
Level 1

This Expect script provides expect with a list of IP addresses to Cisco IPS sensors and commands to configure Cisco IPS sensors.

I'm having 2 problems:

1. Sometimes the script appears to send the next command before the next prompt appears in which case the correct command is skipped and the one afterwards sent and accepted. The commands usually need to be entered in order so this usually produces an error. Is using a sleep timer the only or best solution to this problem?

2. From what I can tell if I don't quote the command "configure terminal" it's received as 2 separate commands so I have to quote it. I don't know if this is causing the problem but for some reason when I use this script the regex string 10\.1\.1\.100 ends up being sent without the backslashes 10.1.1.100 but I don't want the regular expression dot . evaluated I just want an IP address with periods. Something about my expect script is causing this problem because when I log in using ssh and copy and paste the commands into the IPS sensors manually the regex string is saved with the backslashes. I've tried removing the quotes and I've also tried double quoting and neither work. Does anyone know what I'm doing wrong here or what I could try?

#!/usr/bin/expect

log_user 1

set timeout 10

set user "user"

set password "password"

set ip_list {

10.1.1.10

10.1.2.10

10.1.3.10

10.1.4.10

}

set cmd_list {

"configure terminal"

"service signature-definition sig0"

"signatures 60000 0"

"alert-severity high"

"sig-fidelity-rating 100"

"sig-description"

"sig-name Foo"

"sig-string-info Foo"

"no sig-comment"

"exit"

"engine string-tcp"

"regex-string 10\.1\.1\.100"

"service-ports 0-65535"

"direction from-service"

"exit"

"exit"

"exit"

}

foreach ip $ip_list {

if {$ip != ""} {

# Connect

spawn ssh $user@$ip

expect "?assword*"

send "$password\r"

set prompt "(Foo#)"

foreach command $cmd_list {

if {$command != ""} {

expect -re $prompt {

send "$command\r"

sleep 5

}

}

}

expect -re "Apply Changes" {

send -- "yes\r"

}

expect -re $prompt {

send -- "exit\r"

}

close

}

}

send_user "\nDone.\n"

3 Replies 3

mkodali
Cisco Employee
Cisco Employee

You have an issue with the prompt as you are hard coding the prompt to (Foo)# for every sensor ip address. I would think the expect would timeout and exit before sending next command. I suggest changing the prompt to .*#. With this fix you should not be using sleep.

If you don't double quote the config terminal, foreach loop will consider config and terminal as separate entries in the cmd_list and hence send separately.

For regex-string 10\.1\.1\.100 did you try sending as 10.1.1.100 without backslash (as the string is already enclosed in double quotes)

@mkodali

Thanks for your reply. I scrubbed the script of all real user names, passwords, IP addresses, regex, sensor names at prompts, etc.

I changed the regex I use to match the naming scheme for the IPS sensors to Foo# because I don't want anyone to see it.

This script works as far as the prompt goes. This script will successfully log into every sensor and send commands to every sensor.

On a few problematic sensors for some reason after sending "service signature-definition sig0", that seems to be the most common command causing this problem, the sensor takes a very long time such as 5-10 seconds before it provides another prompt. This long delay is why I'm using a sleep timer. The problem with that is my sleep timer is inside the loop which means if I set it to 10 seconds the script waits 10 seconds between every command on every sensor. What I don't understand is I thought expect was supposed to wait for a prompt before sending the command so I don't understand why I'm having to use a sleep timer at all but then that's why I'm on here. I'm missing something :)

I want the backslash

If I understand regex correctly the regex string 10.1.1.100 would match 10n1n1n100

I just tested it and it does

With the backslash the regex string 10\.1\.1\.100 matches only 10.1.1.100 and that's what I want.

Now I understand your problem better.

By default I think expect gives up after 10 seconds waiting for the prompt. For the first issue try changing the timeout to some value like 240 seconds by using the command "set timeout 240" before the foreach loop. Remove the sleep command in the loop before you run the script.

set timeout 240

foreach command $cmd_list {

if {$command != ""} {

expect -re $prompt {

send "$command\r"

}

}

You can set it back to 10 seconds after the loop.

For the second issue escape the backslash character itself :

"engine string-tcp"

"regex-string 10\\.1\\.1\\.100"

Hope this will solve your problems.

Review Cisco Networking products for a $25 gift card