How do I run a command remotely as root ? - linux

I`m trying to login to a server as userA then switch to the root account and run some command. The steps should be like:
ssh userA#10.0.0.1
su - root
whoami
I implemented step 1 with the code below but don't know how to implement steps 2 and 3.
#!/usr/bin/expect -f
set timeout 12
set password_root 12345678
set password_A 12345678
spawn ssh -t sflow#10.0.0.1
expect -re ".*password:"
send "$password_sflow\r"
expect eof

#!/usr/bin/expect
set timeout 12
set password_root 12345678
set password_A 12345678
set prompt "#|>|\\\$ $"
spawn ssh -t user1#xxx.xxx.x.xx
expect {
timeout {puts TIMEOUT}
"yes/no" {send "yes\r";exp_continue}
"password:" {send "user1password\r";exp_continue}
-re $prompt
}
send "su - root\r"
expect "Password:"
send "rootpassword\r"
expect -re $prompt
send "whoami\r"
expect -re $prompt
# and to exit
send "exit\r" ;# exit su
expect -re $prompt
send "exit\r" ;# exit ssh
expect eof

Related

why this interact not exec? (expect)

expect -c "
log_user 0
set timeout 60
spawn ssh ${user}#${ip} -p ${port} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
log_user 1
expect {
\"password:\" {send \"${password}\r\";exp_continue}
default {}
eof {exit 1}
}
set timeout -1
interact
"
when password not ok, eof effect.
when password is ok, interact not effect, i can't put command by keyboard, it is blocking, i just don't want use "#" or "$" to check login status, because my shell use zsh and prefix is "🚀 ~ ❯", please help me, thinks.

I cant get my expect script to run remote bash script as "expected"

I am trying to run an expect script, which should run a bash script on a remote linux server. The bash script is meant to restart a strongswan IPSec tunnel based on the argument sent via the expect script.
Here's my expect script:
#log_user 0
set prompt {\$ >}
expect -re $prompt
set ip 192.168.0.1
set user user
set password 4p4ssw0rd
set target [lindex argv 0]
spawn ssh -p 2228 "$user\#$ip"
expect "password:"
send "$password\r";
expect ">"
send "su -\r"
expect "Password:"
send "$password\r"
expect "#"
send "sh /usr/local/bin/ipsec_fixer.sh $target; exit\r"
expect "#"
Here's the remote script:
target=$1
if [[ -n "$target" ]]; then
value=`grep -i $target /etc/ipsec.conf -A1 |awk '{print $2}'| tail -n 2 | sed 's/0$//'`
declare -a args
args=( $(grep "$value"* /etc/ipsec.conf | awk '{print $2}') )
for each in ${args[#]}; do ipsec down $each; sleep 3; ipsec up $each ; done
else
exit 2
fi
The expect script runs, but I get the following output:
/usr/local/bin/fix_ipsec avpnconnection
spawn ssh -p 2228 user#192.168.0.1
user#192.168.0.1's password:
Last login: Sun Dec 11 05:40:55 2016 from 192.168.0.232
sh /usr/local/bin/ipsec_fixer.sh argv; exit
021 no connection named "-c"
021 no connection named "-c"
021 no connection named "-c"
021 no connection named "-c"
logout
user#remote:/home/login >
I have no idea what is going on. Please what am I doing wrong?
I think I've figured it out: the odd looking
021 no connection named "-c"
021 no connection named "-c"
021 no connection named "-c"
021 no connection named "-c"
lines are from the remote system's shell.
My expect script now looks like this:
set script /usr/local/bin/ipsecfixer.sh
spawn ssh -p 2228 $user#$ip
expect "password:"
send "$password\r";
expect ">"
send "su -\r"
expect "Password:"
send "$password\r"
expect "#"
send "/bin/bash $script $argv\r"
expect "#"
And it does the job, so far..
You could just use
ssh -t -p 2228 user#192.168.0.1 "sudo /bin/sh /usr/local/bin/ipsec_fixer.sh $target"
and use SSH Key-Based Authentication.
As for the messages you get, is it possible that the script you're launching has an influence on the current SSH connections?

Expect script doesn't work from cron ,works from command line

Here the script and message observed:
[root#server01 ~]# cat /usr/local/scripts/rsync.exp
#!/usr/bin/expect
eval spawn rsync -av --delete /backup/ root#server02:/backup
;#use correct prompt
set prompt ":|#|\\\$"
interact -o -nobuffer -re $prompt return
send "welcome123\r"
interact -o -nobuffer -re $prompt return
send "pwd"
interact -o -nobuffer -re $prompt return
expect "#"
expect eof
[root#server01 ~]#
expect: spawn id exp4 not open
while executing
"expect "#""
(file "/usr/local/scripts/rsync.exp" line 13)
[root#server01 ~]#
I see above error when I kill with ctrl+d at the command line.

Transmit commands via ssh with password using expect

I need to iterate on a sequence of servers(many type of servers, each type of servers stored in separate files), run on them some commands(stored in different files accordingly to server type) and log the output on the local machine, using ssh with password. Since sshpass, ssh key authentication is not a solution for my case please don't recommend them.
Here is my code:
#!/usr/local/bin/expect -f
#Set path to nodes files
NODES=nodes/*
#Set path to commands files
CMD=commands/*
for fn in $NODES
do
echo "Working in $fn"
for fc in $CMD
do
echo "Working in $fc"
if [ ${fn:6:3} = ${fc:9:3} ]
then
# read Nodes from file
while read fn_line; do
#extracting substrings of user, host, password separated by comma
IFS=', ' read -a uhp <<< $fn_line
#establish ssh session to the node
eval spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no ${uhp[0]}#${uhp[1]}
echo ${uhp[0]} ${uhp[1]} ${uhp[2]}
#use correct prompt
set prompt "assword:*"
interact -o -nobuffer -re $prompt return
send "${uhp[2]}\r"
set prompt ":|#|\\\$"
interact -o -nobuffer -re $prompt return
#execute and logging HC commands on the node
while read fc_line; do
#set prompt ":|#|\\\$"
#interact -o -nobuffer -re $prompt return
echo "$fc_line\r" >> logs/${fn:6:3}.log
$fc_line\r >> logs/${fn:6:3}.log
#interact -o -nobuffer -re $prompt return
done < $fc
done < $fn
fi
#cat $f
done
done
I know in my code the problem is combination of bash and expect interpreter. Please help me to do it only in expect style or show me how can i combine bash with expect. Other problem is the while after establishing of ssh connection, but i think it can be solved by storing it previously in an array and looping through it after establishing of ssh connection.
How about writing a small utility in expect which spawns ssh command:
#!/usr/bin/expect
set HOST [lindex $argv 0]
set PORT [lindex $argv 1]
set USER [lindex $argv 2]
set PASSWORD [lindex $argv 3]
set COMMAND [join [lrange $argv 4 end] " "]
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no -p $PORT $USER#$HOST $COMMAND
expect "assword:"
send "$PASSWORD\r"
expect eof
exit
and using it in a Bash script like this:
ssh-util <host> <port> <user> <pass> <command>
e.g.
ssh-util 10.0.0.10 22 root s3cr3t ls -la

How to one-line this "expect" command?

I would like to one-line this
#!/usr/bin/expect
spawn ssh-copy-id -i .ssh/id_dsa.pub root#testip
expect "Are you sure you want to continue connecting (yes/no)?"
send -- "yes\r"
expect eof
which I would assume should be
/usr/bin/expect -c 'expect "\n" { eval spawn ssh-copy-id -i .ssh/id_dsa.pub root#testip; expect "Are you sure you want to continue connecting (yes/no)?"; send -- "yes\r" }'
but it is not.
Can anyone see how it should be?
Maybe you will not need it anymore, but it should be like this:
/usr/bin/expect -c 'spawn ssh-copy-id -i .ssh/id_dsa.pub root#testip ; expect "Are you sure you want to continue connecting (yes/no)?" ; send -- "yes\r" ; expect eof'

Resources