Handling end of SSH session by remote server in Expect script - expect

I made 2 Expect scripts to SSH to a list of servers and change passwords. One for AIX and one for RedHat Linux.
The AIX script is working fine, but the Linux script is giving me a problem. The reason is that on the Linux servers, when you are forced to change an expired password, after the password is changed the remote side kills the SSH session.
passwd: all authentication tokens updated successfully.
Connection to drm23rdv closed.
send: spawn id exp20 not open
while executing...
At this point the script stops completely and there are still lots of servers to log in to. (and the current password is just a temporary one, although I could modify the script to use my permanent password choice but I like to do that as root)
What I would like to do after the initial, forced password change is log back into the server and change the password again as root. I am pretty sure I can handle that, but first I need to figure out a way to have expect handle the closed SSH session with more dignity than just giving up.

use expect eof {do something}, or the connection might close at any time, use expect_before {eof {do something}}

Related

Connecting to remote server with SSH keys

I have been trying to figure out where I am going wrong for a few days now.
I am trying to set up a pair of SSH keys, so my computer can remotely connect to my web server and run a script without a password.
I have generated the SSH keys on my Mac and placed the public key on the server in the '.ssh' folder, then added this to the 'authorized_keys' file.
When I run my command through terminal, I get the following, asking for both a passphrase and the password still.
Christophers-MacBook-Pro:~ christopherdavies$ bash /Users/christopherdavies/Desktop/rsync/chrisdavies/chrisdavies.sh
Enter passphrase for key '/Users/christopherdavies/.ssh/id_rsa':
chrisdavies#shell.host.co.uk's password:
Am I right to have placed the public key from my SSH keys pair on my Mac onto the server?
I am a bit lost here, so would really appreciate some advice. I am slowly learning, but feel I may be doing something blatantly obviously wrong...
It seems you are off to a good start. Some things to check:
make sure you stored the public key under .ssh/authorized_keys on the same user to which you intend to connect. In your case, it seems that your remote user is "chrisdavies", so it should be under ~chrisdavies/.ssh/autorized_keys.
make sure your script connects to the remote server as "chrisdavies". You might want to check that because you are under a different user on your MacBook "christopherdavies".
To troubleshoot, try to SSH to the remote server instead of running the script directly. If you run "ssh chrisdavies# and it works without the password, you do not have connectivity issues, and you'll need to look into your script.
I hope that helps!

pscp works for one account but does not work for another

I have two accounts A, B both registered on the windows server 2008 R2.
There is a script in which I use pscp module of putty to transfer files from the server.
Problem being that the command runs successfully using user account A but gets stuck using account B. The command does not complete using user account B
I have to manually terminate it.
Both accounts have the below privilege in group policy and computer management.
Administrator
Logon as a batch
Replace process level token
Please help
I figured out the problem. When we use pscp alone on command prompt , this is the prompt we get
The server's host key is not cached in the registry. You have no
guarantee that the server is the computer you think it is. The
server's rsa2 key fingerprint is: ssh-rsa 1024
cc:78:13:a3:68:a6:59:7e:b8:23:2d:13:3e:66:9b:b9 If you trust this
host, enter "y" to add the key to PuTTY's cache and carry on
connecting. If you want to carry on connecting just once, without
adding the key to the cache, enter "n". If you do not trust this host,
press Return to abandon the connection. Store key in cache? (y/n)
Connection abandoned.
We need to press y/n and the command shall thereafter proceed.
While this command was running in the script , the prompt was not getting any input from the user and was therefore never ending.
To mitigate this
one can do something like this
How to pass value to psftp prompt

ssh with putty from session 0 gives 'servers host key does not match ...' alert

I have some test code running from TeamCity. Part of my test code requires ssh with putty. This code works fine in in a command prompt (session 1) but when I run it from TeamCity (which is a process and therefore runs in session 0) I get the following alert in my test log
The servers host key does not match the one PuTTY has cached in the registry
[snip]
If you trust this host, enter "y" to add the key to PuTTY's cache and carry on connecting. If you want to carry on connecting just once, without adding the key to the cache, enter "n". If you do not trust this host, press Return to abandon the connection. Store key in cache? (y/n)
Since this is in session 0 I can't interact and hit 'y'. I can't work out why the key stored in the registry when I hit 'y' when running this the first time from session 1 doesn't stop the alert appearing in session 0.
Can anyone help me? Thanks.
Very likely there is no solution with PuTTY.
In OpenSSH you have a set of options to completely avoid the host key verification, with the drawback of lowering the security levels.
On Unix derivatives that would be:
-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
I think in Windows the second option would read "-o UserKnownHostsFile=NULL".
One possible "workaround" would be to manually start putty on the very first connection in order to get the host key in the stored cache. Subsequent calls would not require the interaction unless the host key changes (usually due to either a system re-installation or just the SSH server reinstallation).

Speeding up ssh in batch files

This is my situation:
I have a linux server/media center with a windows client.
My goal is to remote control rhythmbox amongst other things.
I've done this using plink (windows based cli ssh toy).
The problem is that starting up an ssh session logging in and sending a command is understandably slow as hell. When I had a windows server I used a tool called psexec which was almost instantaneous.
Is there any way to speed this process up? Either somehow sending the commands with the login request which should show some improvement. Or by maintaining a persistent ssh connection which I can use. (plink dcs at the end of the command).
More info: On my windows machine I'm using a bat like:
plink -ssh -l username -pw pass myipaddress "/home/username/bin/skip"
On my linux machine the skip bash file is something like:
//needed to get around a x11 error caused by controlling rhythmbox over sshif its an ssh connection copy the dbusaddressfirhythmbox-client --next //the cli wrapper for rhythmbox
Further Research:
The only way to go seems to keep an ssh connection open/maintained as a service. This seems doable as there is a demand due to setting up ssh tunnels (to bypass firewalls). From there I'd need a way to send the command line commands to this existing connection or reuse that connection.
The other option is of course to NOT use ssh. Hell I already have a connection through samba file shares and there is no lag there. I bet I could put a service linux side that checks for a modified file. Then have an ap client side that modifies said file. Amazingly hacky but so far it seems like the best option. And by best I mean the only one that cuts control lag. There has got to be a better way than this, I can't be the only nerd using linux as a media-center that wants remote controls. This kind of moves the topic from stackoverflow to superuser but that's ok.
You could user an SSL certificate to get rid of the login part. Alternatively, build yourself a small HTTP server which uses an "exotic" port for controlling your media player (amarok, btw, has one build-in)
Switching to something like mpd will bypass the ssh issue, although I give no guarantee that changing tracks will be any faster.
If anyone is curious, I ended up implementing an http based server with php to execute commands server side. And client side I used curl.exe to allow me to have nice click-able buttons without the overhead of a web-browser.
Also nice since it allowed me to implement an in browser UI which is great to use from any machine with internet, ones that don't have ssh installed. And works wonderfully from my phone as a remote control (which I can use from a country away if I so chose...)

How to capture your username on Box A after you have SSHed onto Box B?

Maybe not the best worded question, but hopefully it's a straightforward problem.
The scenario is SSHing from a personal account on box A to a generic account on box B. The script running on box B needs to capture the personal account name for logging purposes. Is there any way of capturing this, either via SSH itself or some information captured by the shell? We are using ssh2 (Reflections), and KornShell (ksh) on Solaris.
If you have full control of the client machine, you can deploy identd to get the username.
Full procedure to get name from script:
Walk up process tree, find sshd
Walk netstat -p to find the remote IP and port.
Connect to client on port 113 and ask.
You may have to disable privilege separation for this to work as-is; however it should be trivial to modify to work w/o it.
You can't log the remote username reliably
You can log the IP of the connection (see the SSH_CONNECTION variable)
You could have a standard where they use an alias for ssh that logs the remote username as part of the login process, or where they store their username in a .ssh/environment file (but allowing environments to be set may require ssh/sshd config changes).
alias sshblah='ssh blah "REMOTEUSER=$USER; bash'
(Except that doesn't work, and I haven't tried to figure out why - and it would be different if you use tcsh, etc).
You can use environment passing in this manner, and select which variables you allow to be set. You'd have to get the users to set some alternate to $USER, like $REMOTE_USER=$USER, and then allow $REMOTE_USER to pass through. And you're trusting they don't set it incorrectly, or forget to set it (you can handle that case with a little annoyance by modifying this mechanism).
Note that you almost have to trust the client connecting to tell you who the user is - you can make it hard/annoying to spoof the username, but unless you use per-user certificates instead of a generic login/password they all know, you can't verify who connected.

Resources