How to stop tcpdump remotely using expect from a new telnet session - tcl

I am trying to stop the tcpdump command from running on a remote terminal. If I telnet to the terminal, start tcpdump, and then send a ^c, tcpdump stops with no issues. However if I telnet to the same terminal, start tcpdump, and then exit the telnet session, when I reconnect to the same telnet session I am unable to stop tcpdump via a ^c. When I do this instead of stopping tcpdump it seems that it just quits the telnet session and tcpdump continues to run on the remote terminal. I provided my script below. Any help is greatly appreciated.
#!/usr/local/bin/expect -f
exp_internal 1
set timeout 30
spawn /bin/bash
expect "] "
send "telnet 192.168.62.133 10006\r"
expect "Escape character is '^]'."
send "\r"
expect "# "
set now [clock format [clock seconds] -format {%d_%b_%Y_%H%M%S}]
set command "tcpdump -vv -i trf400 ip proto 89 -s 65535 -w /tmp/test_term420_${now}.pcp "
send "$command\r"
expect "tcpdump: listening on"
# This works correctly. tcpdump quits and I am returned to the expected prompt
send "\x03"
expect "# "
send "$command\r"
expect "tcpdump: listening on"
# Exit telnet session
send -- "\x1d"
expect "telnet> "
send -- "q\r"
expect "] "
# Reconnect to telnet session
send "telnet 192.168.62.133 10006\r"
expect "Escape character is '^]'."
send "\r"
# This does not work as intended. The ^c quits the telnet session instead of stopping tcpdump
send "\x03"
expect "] "
send "ls\r"
expect "] "

To send a Ctrl+C to a subordinate process with Expect, do this:
send "\x03"
(Ctrl+#=0, Ctrl+A=1, Ctrl+B=2, Ctrl+C=3, etc.)
The correct handling of the Ctrl+C depends on the virtual terminal engine intercepting it and converting a character into a request to send a signal. This only happens when the terminal is in cooked mode. You've probably got the terminal cooked — it's the default after all — but if this doesn't work, that's the first thing to check.

It sounds to me that the tcpdump process has fallen to the background after the first telnet session disconnected.
Maybe what you need to do when you connect over your second telnet session is find the process id using ps and then signal it via the kill command?
Or better yet, launch it in the background in the first place ("&" at the end):
tcpdump -vv -i trf400 ip proto 89 -s 65535 -w /tmp/test_term420_${now}.pcp &
and the shell will give you the pid of the tcpdump process before it returns the prompt... you can read it via expect -re and later on when you re-connect, issue a kill -HUP <pid> (or -INT or whatever).
You should get something like the following (using sleep 5 as command, just as an example):
$ sleep 5 &
[1] 29344
$
Just my 2c.

Related

Expect script should not end

I need some help with my script. I have written a piece of code where the script uses ssh to remote host and executes a tail command and need to stay there. It should not come out of the script.
#!/usr/bin/tclsh
package require Expect
set IP [lindex $argv 0]
set spawnID [spawn ssh root#$IP]
expect {
password: {
send "XXXXXXX\r"
exp_continue
}
"# "
}
send "kubectl -it exec server-0 bash\r"
expect "# "
send "tail -f Server.log\r"
expect "$"
The tail -f command should stay but its coming out of the script in few seconds.
Its printing the logs as expected but comes out of the session in 10 seconds.
Requirement is to stay there unless the user hits "ctrl c"

Exit #!/usr/bin/expect when Status was VPN tunnel closed

i am using an expect script
#!/usr/bin/expect -f
set force_conservative 0 ;
if {$force_conservative} {
set send_slow {1 .1}
proc send {ignore arg} {
sleep .1
exp_send -s -- $arg
}
}
set timeout -1
spawn $env(SHELL)
match_max 100000
send -- "cd /home/forticlientsslvpn/64bit/\r"
send -- "./forticlientsslvpn --server ip:port --vpnuser UN"
expect -exact "./forticlientsslvpn --server ip:PORT --vpnuser UN"
send -- "\r"
expect -exact "\r
Password for VPN:"
send -- "PW\r"
expect -exact "\r
STATUS::Setting up the tunnel\r
STATUS::Connecting...\r"
send -- "Y\r"
expect eof
file which will connect VPN,
when VPN connection is successful it will display STATUS::Tunnel running,
But when connection closed, STATUS will be Tunnel closed and still the script will keep on running
STATUS::Stopping tunnel
STATUS::Tunnel closed...```
How to exit the script when we get ```STATUS::Tunnel closed```
The problem is that you spawn a shell, and when the vpn client closes, the shell is still running.
Spawn the vpn client directly:
#!/usr/bin/expect -f
set timeout -1
cd /home/forticlientsslvpn/64bit
spawn ./forticlientsslvpn --server ip:port --vpnuser UN
match_max 100000
expect "Password for VPN:"
send -- "PW\r"
expect "STATUS::Connecting..."
send -- "Y\r"
expect eof
By adding expect Stopping and expect closed in the last lines of the script will exit the script.
expect Stopping
expect closed
exit

userparameters and ZBX_NOTSUPPORTED

I want to ping an external ip from all of my servers that run zabbix agent.
I searched and find some articles about zabbix user parameters.
In /etc/zabbix/zabbix_agentd.conf.d/ I created a file named userparameter_ping.conf with following content:
UserParameter=checkip[*],ping -c4 8.8.8.8 && echo 0 || echo 1
I created an item named checkip in zabbix server with a graph but got no data. After some another digging I found zabbix_get and tested my userparameter but I got the error : ZBX_NOTSUPPORTED
# zabbix_get -s 172.20.4.43 -p 10050 -k checkip
my zabbix version :
Zabbix Agent (daemon) v2.4.5 (revision 53282) (21 April 2015)
Does anybody know what I can do to address this?
After some change and talks with folks in mailing list finally it worked but how :
first i created a file in :
/etc/zabbix/zabbix_agentd.conf.d/
and add this line :
UserParameter=checkip[*],ping -W1 -c2 $1 >/dev/null 2>&1 && echo 0 || echo 1
and run this command :
./sbin/zabbix_agentd -t checkip["8.8.8.8"]
checkip[8.8.8.8] [t|0]
so everything done but Timeout option is very important for us :
add time out in /etc/zabbix/zabbix_agentd.conf
Timeout=30
Timeout default is 3s so if we run
time ping -W1 -c2 8.8.8.8
see maybe it takes more than 3s so you got error :
ZBX_NOTSUPPORTED
It can be anything. For example timeout - default timeout is 3 sec and ping -c4 requires at least 3 seconds, permission/path to ping, not restarted agent, ...
Increase debug level, restart agent and check zabbix logs. Also you can test zabbix_agentd directly:
zabbix_agentd -t checkip[]
[m|ZBX_NOTSUPPORTED] [Timeout while executing a shell script.] => Timeout problem. Edit zabbix_agentd.conf and increase Timeout settings. Default 3 seconds are not the best for your ping, which needs 3+ seconds.
If you need more than 30s for the execution, you can use the nohup (command..) & combo to curb the timeout restriction.
That way, if you generate some file with the results, in the next pass, you can read the file and get back the results without any need to wait at all.
For those who may be experiencing other issues with the same error message.
It is important to run zabbix_agentd with the -c parameter:
./sbin/zabbix_agentd -c zabbix_agentd.conf --test checkip["8.8.8.8"]
Otherwise zabbix might not pick up on the command and will thus yield ZBX_NOTSUPPORTED.
It also helps to isolate the command into a script file, as Zabbix will butcher in-line commands in UserParameter= much more than you'd expect.
I defined two user parameters like this for sync checking between to samba DCs.
/etc/zabbix/zabbix_agentd.d/userparameter_samba.conf:
UserParameter=syncma, sudo samba-tool drs replicate smb1 smb2 cn=schema,cn=configuration,dc=domain,dc=com
UserParameter=syncam, sudo samba-tool drs replicate smb2 smb1 cn=schema,cn=configuration,dc=domain,dc=com
and also provided sudoer access for Zabbix user to execute the command. /etc/sudoers.d/zabbix:
Defaults:zabbix !syslog
Defaults:zabbix !requiretty
zabbix ALL=(ALL) NOPASSWD: /usr/bin/samba-tool
zabbix ALL=(ALL) NOPASSWD: /usr/bin/systemctl
And "EnableRemoteCommands" is enabled on my zabbix_aganetd.conf, sometimes when I run
zabbix_get -s CLIENT_IP -p10050 -k syncma or
zabbix_get -s CLIENT_IP -p10050 -k syncam
I get the error ZBX_NOTSUPPORTED: Timeout while executing a shell script.
but after executing /sbin/zabbix_agentd -t syncam on the client, Zabbix server just responses normally.
Replicate from smb2 to smb1 was successful.
and when it has a problem I get below error on my zabbix.log
failed to kill [ sudo samba-tool drs replicate smb1 smb2 cn=schema,cn=configuration,dc=domain,dc=com]: [1] Operation not permitted
It seems like it is a permission error! but It just resolved after executing /sbin/zabbix_agentd -t syncam but I am not sure the error is gone permanently or will happen at the next Zabbix item check interval.

how to copy a file from remotehost to localhost by using tcl-expect

Here i am making a connection b/w two machines using telnet and in the remote host i am creating a file named "file.txt" and storing the result of the "ls" command execution in the file.txt. now i need to send the file to the local host. i dont know how to do it. anybody who knows it kindly help me out here.
#!/usr/local/bin/expect
spawn telnet <machine ip>
expect "login:"
send "<username>\n"
expect "Password:"
send "<password>\n"
expect "bash"
send " ls > file.txt\r "
expect "bash"
send " cat file.txt \r "
expect "bash"
send " command for copying file to the localhost computer\r"
expect "bash"
send "exit\r"
You're strongly recommended to use ssh and scp for this task.
#!/usr/local/bin/expect
### Factor these out
set user <username>
set pass <password>
set host <machineIP>
### Get the file list into a file remotely
spawn ssh $user#$host sh -c {ls -1 >file.txt}
expect {
"Password:" {
send "$pass\r"
exp_continue
}
eof {
close
}
}
### Copy the file to the local machine
spawn scp $user#${host}:file.txt .
expect {
"Password:" {
send "$pass\r"
exp_continue
}
eof {
close
}
}

Expect Tcl script - Error passing quoted argument using spawn

I just wrote a very simple Expect script for wrapping around rsync, but it seems to be giving me trouble. Basically, I am automating the SSH login prompt called from rsync. I also have to pass arguments through rsync to SSH so it doesn't do the host key checking. I am well aware of SSH authentication keys and ssh-keygen, but I have good reasons for doing things this way so no lectures on passing passwords on the command-line.
Script
#!/usr/local/bin/expect -f
if {$argc != 5} {
puts "usage: remoteCopy {remotehost, username, password, localfile, remoteloc}"
exit 1
}
set remotehost [lindex $argv 0]
set username [lindex $argv 1]
set password [lindex $argv 2]
set localfile [lindex $argv 3]
set remoteloc [lindex $argv 4]
set timeout -1
spawn rsync -e \"ssh -q -o StrictHostKeyChecking=no\" $localfile $username#$remotehost:$remoteloc
expect "Password"; send "$password\r"
Here is the complete output from the script:
Output
avoelker#localhost $ ./remoteFileCopy.tcl remotehost remoteuser remotepass ~/localfile /tmp/
spawn rsync -e "ssh -q -o StrictHostKeyChecking=no" /localhost/home/avoelker/localfile remoteuser#remotehost:/tmp/
rsync: Failed to exec "ssh: No such file or directory (2)
rsync error: error in IPC code (code 14) at pipe.c(83)
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(434)
send: spawn id exp6 not open
while executing
"send "$password\r""
(file "./remoteFileCopy.tcl" line 17)
avoelker#localhost $
It appears to me that rsync is trying to execute "ssh instead of just ssh, however, copying and pasting the first line of output from Expect's stdout (rsync -e "ssh -q -o StrictHostKeyChecking=no" /localhost/home/avoelker/localfile remoteuser#remotehost:/tmp/) directly into the shell works perfectly fine, so I know it isn't a problem with rsync.
When I remove the -e argument entirely from the spawn rsync line, the Expect script executes without errors, but I would have to add in host key checking to the script, which I do not want to do.
Does someone more experienced with Expect/Tcl know what I am doing wrong?
Drop your backslashes. The spawn line should just say:
spawn rsync -e "ssh -q -o StrictHostKeyChecking=no" $localfile $username#$remotehost:$remoteloc
After all, you don't want rsync to see a command with a quote in it, do you?