Expect: How can I open a telnet session from an ssh session? - session

I want to write a script that automatically connects me via SSH to a given IP, and after that opens a telnet session from where it just connected.
My expect code till now:
# $1 = ssh root#111.111.111.111
# $2 = password
# $3 = telnet 123.123.123.123 10023
(expect -c "
set timeout 20
spawn $1
expect {
\"Password:\" { send \"$2\r\" }
timeout { send_error \"\nTimeout!\n\"; exit 1; }
}
spawn $3
interact
" )
My problem is that I cannot spawn the telnet in the ssh session, the script is just "telnetting" from my home directory. Maybe there is a way with session ids, but I could not find helpful information.
Would be nice if someone of you could suggest some solution or workaround,
thanks in advance and please excuse my bad English skills :)
Edit:
What helped with my problem, was:
(expect -c "
set timeout 20
spawn ssh root#server telnet server2
expect {
\"Password:\" { send \"$2\r\" }
timeout { send_error \"\nTimeout!\n\"; exit 1; }
}
interact
" )

I'd have a bit of a different approach for you, easier maybe.
As I understand it:
You want to SSH into a server of yours and from there telnet to another place
Did you consider using key based authentication with SSH ?
For this approach you would add your identity key to .ssh/authorized_keys on the remote server.
Here is an example which uses expect from command line, connects to a SSH server using a key file and from there connects to a mailserver and sends "HELO test"
Tested it on my servers, works
expect -c 'expect "\n" {eval spawn ssh -i identity_file my.sshserver.com telnet mail.anotherserver.com 25; expect "SMTP" {send "HELO test\r\n"};interact}'
you can also add a timeout option to ssh (-oConnectTimeout)
It will connect to the server and call the telnet command, so you would have an open SSH session which has telnet already connected.
The script waits for an initial ENTER from you to start.

As you also asked for a Workaround, here is one: You can use ssh port forwarding
ssh -f -N -n root#111.111.111.111 -L 10024:123.123.123.123:10023
[wait for connecting]
telnet localhost 10024
Here, ssh will open a connection and go into background. the local ssh client will listen on port 10024 and redirect all traffic to 123.123.123.123 port 10023. As long as this ssh instance is running, you can open and use telnet sessions (From the initial location).

Related

How to connect to a ssh remote server after a sudo vpnc connection, all automatically ? (bash)

I'm actually working on vi and I want to make a script which connects me to a vpnc (and automatically enters the password), and then, connects me to a ssh distant server.
I made this, but it's not working:
#! /usr/bin/
set force_conservative 1;
set timeout 2
spawn sudo vpnc
expect "password: $"
send "xxx"
spawn ssh marpic#192.xxx.xxx.xxx
expect "password: $"
send "xxx"
interact
I want to implement this so I can later add my copyfiles.sh script which copies the files on the ssh server to my PC.
check your first line.
make sure you invoke the shell correctly.
#!/usr/bin/bash is the path correct?

Non-interactive SSH GPG Agent forwarding with pre-existing connection

I have got a bit of a chicken/ egg problem here.
The Problem
I would like to SSH to a remote machine and forward my local gpg-agent. The problem is that the gpg-agent on the remote machine only starts once the SSH connection is established. While the gpg-agent is NOT running on the remote machine, I cannot connect to the remote machine via SSH while specifying the forwarding.
In the light of this, this command does not work, since the remote gpg-agent is not running and therefore the /run/user/1000/gnupg/S.gpg-agent does not exist yet.
ssh -R /run/user/1000/gnupg/S.gpg-agent:/run/user/1000/gnupg/S.gpg-agent user#remotemachine
The Workaround
The alternative is to do it interactively/ manually as shown below.
ssh user#remotemachine
I am now connected via SSH and as a side effect, the gpg-agent got automatically started too.
When I now update the existing SSH connection, by opening the SSH PTY:
[enter]
~C
ssh> -R /run/user/1000/gnupg/S.gpg-agent:/run/user/1000/gnupg/S.gpg-agent
Forwarding port.
[enter]
I can now run my GPG commands on the remote machine by the use of my local gpg-agent.
The Aim
I would like to have the above workaround automated. Basically I want to SSH to the remote machine with ssh user#remotemachine and the remote machine will then automatically add the SSH forwarding to the existing SSH connection.
The Question
How can I make the remote machine automatically update the newly established SSH connection and add the gpg-agent forwarding?
Since you used the expect tag, here is a simple expect script that should suffice.
#!/usr/bin/expect -f
spawn ssh user#remotemachine
expect {$ }
send "date\r"
expect {$ }
send "~C"
expect "ssh> "
send -- "-R /run/user/1000/gnupg/S.gpg-agent:/run/user/1000/gnupg/S.gpg-agent\r"
expect -timeout 5 timeout exit "\r\n"
send "echo ok\r"
expect "\nok\r"
expect {$ }
interact
Put this in a file and do chmod +x on it. For some reason, I found I didn't get the Forwarding port message from the -R command unless I enabled ssh -v, so I just check for \r\n, but you can change this. Also, I assumed the shell prompt from the remote was $, so you might need to change that too, but if your prompt is [enter] then you need to say
expect -ex {[enter]}
to avoid the string being interpreted as a regular expression.

How to add carriage return to bash when prompted for ssh password to localhost?

I'm new to bash and was tasked with scripting a check for a compliance process.
From bash (or if python is better), I need to script an ssh connection from within the host running the script.
For example:
ssh -l testaccount localhost
But I need to run this 52 times so that it is trapped by an IPS.
When running this string I am prompted for a password and I have to hit enter in order to make the script complete.
Is there a way to include a password or carriage return to act as manual intervention so that I do not have to hit enter each time?
Here's a sample of what I was able to get working, but it only sequenced 30 attempts:
#!/bin/bash
i=0
while [$i -lt 52]
do
echo | ssh -l testaccount localhost&
i=$[$i+1]
done
Fail2ban configuration and good practice :
//count how password as root failed
cat /var/log/secure.1 | grep "Failed password for root" --count
//check the list for analyst
cat /var/log/secure.1 | grep "Failed password for root"
//setting fail2ban copy for local configuration
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
//open the configuration file and edit some secu
sudo nano /etc/fail2ban/jail.local
maxfailures = 5 //here you have to set to 56 as you said
bantime = 600 //here time during second try login
ignoreip = 192.168.0.0/16 //add the lan and ip online static
[mail]
enabled = false //true if you want to alert you IP blacklisted banned ...
//log traffic
cat /var/log/fail2ban.log
[ssh]
//network protocole protection & supervision
enabled = true
port = ssh,sftp
filter = sshd
logpath = /var/log/auth.log
maxretry = 6
//enable fail2ban
systemctl enable fail2ban
//start fail2ban
systemctl start fail2ban
NOTE: While expect comes in its own package, expect was already in my SLES base installs ... don't know if this would be true for RHEL, too ... ?
Take a look at this answer on how to automate SSH with a password.
I'm thinking you could probably re-use the expect script from that post to simulate a single failed login, eg:
either set pass to a bogus value or don't set at all
if you don't set pass then remove the send -- "$pass\r" clause
if the remote system re-prompts X times for a password then provide multiple copies of the expect/send commands (a few extras will generate some expect related errors but still cause a failed ssh login)
For one of my remote hosts I'm prompted 3 times to enter a password before I'm returned to the command prompt.
I whipped up the following test:
$ cat sshtest
#!/usr/bin/expect -f
set pass xyz
set server myremotehost
set name bob
spawn ssh $name#$server
match_max 100000
expect "*?assword:*"
send -- "\r"
expect "*?assword:*"
send -- "\r"
expect "*?assword:*"
send -- "\r"
expect "*?assword:*"
send -- "\r"
expect "*?assword:*"
send -- "\r"
interact
And the results of running the script:
$ sshtest
spawn ssh bob#myremotehost
Password:
Password:
Password:
Permission denied (publickey,keyboard-interactive).
send: spawn id exp4 not open
while executing
"send -- "\r""
(file "sshtest" line 16)
If you don't have enough expect/send pairs then you'll be left stranded with a Password: prompt, so I added a few extra expect/send pairs, which in turn generated those last 4 lines of the output. [I don't use expect so there may be a more graceful way to do this ... ymmv.]
Obviously your main script could call this script and place said call in the background, and do whatever you want with the output (>/dev/null 2>&1 ??)
I also verified on the remote host that the failed logins were logged in /var/log/warn and /var/log/messages.

Secure Socket Shell login

In Putty is there any bash script to log in different password protected server(ssh) and retrieve data to a specific server? Without ftp is there any bash script for this operation?
I mean, if I want to get data from 3 different ssh named server1, server2 and server3 and save the data in server1 then how should I write my bash for this purpose. I don't want to use ftp concept for this operation.
I think he's asking on how to download data from another machine via SSH instead of reconnecting via FTP/SFTP. It is possible however you need to specifiy the locations of the external machine by its IP address:
scp username#sshserver:path/to/file.txt /Users/localuser/Desktop/
This command is to be executed from the local machine. If a password is required, it will be prompted. Write a for loop and input the server variables into the scp command for your script:
myArray = ("server_1" "server_2" "server_3")
for i in "${myArray[#]}"
do:
echo $i
done
EDIT
This is the script for connecting to an SSH server:
#!/usr/bin/expect -f
spawn ssh user#host
match_max 100000
expect "*?assword:*"
send -- "password\r"
send -- "\r"
interact

How to stop authentication of host message from coming up.

I am writing a script to log into multiple Cisco routers. I am running into and issue. This message pops up every time. "The authenticity of host 'x.x.x.x (x.x.x.x)' cant be established RSA key fingerprint is X. Are you sure you want to continue connecting (yes/no)?
From everything I have read about this says this is normal for the first time sshing into it, but it should store the RSA key and no longer display this message. Is there anyway to stop this message from popping up?
Here is my code so far.
#!/usr/bin/expect -f
spawn ssh -l user x.x.x.x
sleep 3
expect "*word"
send "mypassword"
send \r
Add the following to your ssh options:
-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no
Alternatively, to avoid host key verification and not use known_hosts file for a particular remote machine, you can also add the following to /etc/ssh/ssh_config:
Host remote_machine_ip
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
/etc/ssh/ssh_config - Golbal configuration
$HOME/.ssh/config - User-specific configuration
You can expect that prompt to occur, and actually answer it:
spawn ssh -l user x.x.x.x
expect {
"connecting (yes/no)" {send "yes\r"; exp_continue}
"password:" {send "mypassword\r"}
}
exp_continue basically acts as a loop so that you can keep waiting for the password prompt.
If the "connecting" prompt does not occur, no problem: expect will see the password prompt and carry on.

Resources