How to match this [admin#MikroTik] > in bash script (expect)? - bash

I am trying to write a script that will auto configure mikrotik router, but some weird character appears as soon as password is sent through the script and logins the router. Below is the script that i wrote,
#!/bin/bash
read -p "Enter IP Address: " Public_IP
read -p "Enter username: " Username
read -sp "Enter Password: " Password
echo
expect -c "
spawn ssh -o StrictHostKeyChecking=no $Username#$Public_IP
set timeout -1
expect "password:"
send "$Password\r"
expect "\[admin*"
sleep 4
expect "\[admin*"
"
While I run this script I see below the following in the image,
So what i want to accomplish is to see the second image and send some commands for example;
/ip arp print
send above commmand for instance.
image after running the script
the actual interface i want to get and send command like that

you need to add +tc after username in ssh command
spawn ssh -o StrictHostKeyChecking=no $Username+tc#$Public_IP
it´s works for me

Related

Establishing password less connection SunOS using expect

The host system from where I am trying to establish remote connection is running on SunOS. There isn't ssh-copy-id available on the system.
After searching, I found that the following command, when executed will mimic the ssh-copy-id function.
cat ~/.ssh/id_rsa.pub | ssh remotehost 'cat >>~/.ssh/authorized_keys && echo "Host Key Copied"'
I am trying to write a script using expect for doing this operation but it is failing with the following error.
Code:
#!/usr/bin/expect -f
#!/bin/bash
set username [lindex $argv 0]
set password [lindex $argv 1]
set host [lindex $argv 2]
cat ~/.ssh/id_rsa.pub | ssh remotehost 'cat >>~/.ssh/authorized_keys && echo \"Host Key Copied\"'
expect "Password:"
send "$password\n"
expect eof
Error:
invalid command name "cat"
while executing
"cat ~/.ssh/id_rsa.pub | ssh remotehost 'cat >>~/.ssh/authorized_keys && echo \"Host Key Copied\"'"
(file "./remote.sh" line 8)
From search, I understood that expect won't entertain shell commands by default. Could someone help in resolving my issue. Thanks in advance.
You're missing the spawn command: spawn launches the process that you're interacting with. You're also missing the ssh-copy-id command:
spawn ssh-copy-id $username#$host
expect ...
However, what you're doing is greatly reducing security. Passing the password in clear text on the command line, where it will likely be stored in your shell's history file.

expect script works while invoking individually but not as a salt state

I'm trying to do scp as well as ssh through expect. Below script works if I invoke it directly from terminal like /usr/bin/expect myexpect.sh but when I ran it using salt, the first scp command works where the second ssh fails.
myexpect.sh
#!/usr/bin/expect -f
set timeout 240
spawn scp apps.tar.gz /srv/salt/integration/serverclass_merged.conf foo#10.10.10.10:/home/foo
expect "password:"
send "password\n";
expect eof
spawn ssh -o StrictHostKeyChecking=no foo#10.10.10.10 "cd /home/foo;tar --strip-components=1 -xzvf apps.tar.gz -C /opt/apps/;cp serverclass_merged.conf /opt/local/serverclass.conf"
expect "assword:"
send "password\r"
interact
Relevant salt state looks like,
st.sls
copy_apps:
cmd.run:
- name: /usr/bin/expect /home/ocdn_adm/myexpect.sh
I know nothing about salt-stack but I suspect it's not running your Expect script from a pty. So replace interact with expect eof (or expect -timeout 12345 eof if necessary). interact works only when stdin is on a tty/pty.

ssh expect command with variables

I am planning to take password from file instead of passing parameter to the script
set cmd1 {`cat passwdfile.txt | grep -w pj | cut -d";" -f5`}
spawn ssh username#servername
expect "password: "
send "$cmd1\r"
expect "$ "
send "ps -ef |grep planning1\r"
expect "$ "
send "exit\r"
Error
username#servername's password:
Permission denied, please try again.
Why it is not taking password from the file ??
At the point where ssh is asking for a password, you don't have access to a shell, so the backticks and all the rest will be sent as plain characters as the password.
Assuming that file exists on your local machine, get the password before you spawn:
set pw [exec grep -w pj passwdfile.txt | cut -d\; -f5]
spawn ssh ...
expect "password: "
send "$pw\r"
Of course it's terribly insecure to store passwords in plain text. You should set up ssh keys to allow you to log in without having to type a password.

Script with condition

I am a beginner in the development of scripts.I want to do 4 tasks in one script:
1. Connect to machine 1 by ssh
2.Retrieve the data and put it in a CSV file
3.Send the CSV file to a directory
4.connect to machine 2 by ssh and do step 2 and 3
Fisrt test :
#!/bin/bash
#Settings
DATE=$(date +%Y_%m_%d)
DATE1=$(date +%d/%m/%Y)
HIER=$(date -d '1 day ago' "+%Y-%m-%d")
HEURE=$(date +"%T")
#Ip adress of the machine
machine1= IP1
machine2= IP2
#Connexion SSH OLT1
ssh root#IP1
#Command for geting data on machine
enable
config
display XXXX > IP1.csv
#exit connection
exit
I do not have any result so i think
Do i make a loop for executing the task for the 2 machines?
Thanks
I'm trying tu use expect because i find RSA key problem by using SSH and shell script
#spawn ssh $host -l $user
expect "login:"
send "root\r"
expect "passe:"
send "test\r"
expect -re $prompt
send "terminal length 0\r"
expect -re $prompt
send "enable\r"
expect -re $prompt
send "config\r"
expect -re $prompt
send "display .....\r"
expect -re "\r\nend\r\n"
send "exit\r"
I don't know how i can put the result on csv file to a directory?
Besides, can i put the IP on #spawn assume that task should be done on 2 machines
Thanks for your feedback
I try thisaccording to your sample but the ouput file is empty:
#!/usr/bin/expect
spawn ssh X.X.X.X -l root
expect "User password:"
send "admin\n"
expect -re "device>"
send "enable\r"
expect -re "device#"
send "config\r"
expect -re "device(config)#"
send "display .......\r"
expect -re "{ <cr>||<K> }:"
send "\r"
set date [timestamp -format %C%y%m%d]
log_file -noappend /home/device/CSTtest.csv
You can run your command and export to out file in same ssh call like this:
# ...
# first machine command
ssh root#IP1 "<COMMAND>" > /PATH_LOCAL_TO_SAVE_FILE/IP1.csv
# second machine command
ssh root#IP2 "<COMMAND>" > /PATH_LOCAL_TO_SAVE_FILE/IP2.csv

Issuing commands on remote linux

I'm looking for any way to do this task with expect:
Mac-mini:~ root# scp file peter#Mac-mini:file2
The authenticity of host 'mac-mini (192.168.1.105)' can't be established.
RSA key fingerprint is b6:12:3e:48:10:e6:d2:1f:8f:57:f4:01:2d:f3:23:89.
Are you sure you want to continue connecting (yes/no)? yes
Password: ********
and issue
crontab -l > crontab.src
#!/usr/bin/expect
set machine0 "Mac-minimini"
set machine1 "Mac-mini"
set machine2 "Mac-pro"
...
set machine19 "Mac-air"
for {set i 1} {$i < 20} {incr i 1} {
eval spawn scp file peter#${machine${i}}:file2
expect "connecting (yes/no)?"
send "yes\r"
#use correct prompt
set prompt ":|#|\\\$"
interact -o -nobuffer -re $prompt return
send "password\r"
interact -o -nobuffer -re $prompt return
send "crontab -l > crontab.src\r"
interact
}
Edit: You can use for loop and concatenate names for each machine using the variable of the loop.(e.g. Mac-mini0, Mac-mini1, ... Mac-mini19)
Edit2: I am not sure if ${machine${i}} works but worth to try..
Set up an ssh key like so:
ssh-keygen -t rsa
Place your public key on the remote machine (assuming you create a key in your home directory called id_rsa)
ssh-copy-id peter#Mac-mini
Then you will be able to scp without entering a password.
autoexpect -f scp file peter#Mac-mini:file2
For the crontab part, am assuming you mean on the remote machine.
autoexpect -f crontab ssh peter#Mac-mini "crontab -l > crontab.src"

Resources