12

Below is the script which i am trying to run, which runs without any issue

for i in `seq 200 2100`
do
  usr=(`ssh -t -t -o ConnectTimeout=60 machine$1 finger | tail -1 | awk '{print$1}'`) 
  echo $usr
done

But once I add it to crontab, it doesn't give me the user.

22  12  *  *  *  sh /home/subrahmanyam/Scripts/who.sh

Please give your thoughts.....

may be cron demon is running, so we need to include some binaries...?

2
  • 1
    Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password). Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password). Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
    – user5529
    Mar 9, 2011 at 7:36
  • What are your intenesions with this? What are you trying to achieve. Just so you know we cant assist on any malicious activity if that is your intension Feb 23, 2017 at 8:30

5 Answers 5

16

You can make ssh connections within a cron session. What you need is to setup a public key authentication to have passwordless access. For this to work, you need to have PubkeyAuthentication yes in each remote server's sshd_config.

You can create a private/public key pair with or without a passphrase. If you use a passphrase (recommented) you need to also start ssh-agent. Without a passphrase, you only need to add the parameter -i your_identity_file to ssh command line. ssh will use $HOME/.ssh/id_rsa as default.

I replicated your example by using a key pair with a passphrase. Here's how I did it.

1) Created the key pair with passphrase. Saved the private key as ~/.ssh/id_rsa_test, which should have the correct permissions by default. We can enter an empty passphrase for not using one.

john@coffee:~$ ssh-keygen -N "somephrase" -f .ssh/id_rsa_test
Generating public/private rsa key pair.
Your identification has been saved in .ssh/id_rsa_test.
Your public key has been saved in .ssh/id_rsa_test.pub.
[snip]

2) Sent the public key to the servers, did the same for all of them. Remember they need to have PubkeyAuthentication enabled.

john@coffee:~$ ssh-copy-id -i .ssh/id_rsa_test server1
The authenticity of host 'server1 (11.22.33.1)' can't be established.
RSA key fingerprint is 79:e8:0d:f5:a3:33:1c:ae:f5:24:55:86:82:31:b2:76.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'server1,11.22.33.1' (RSA) to the list of known hosts.
john@server1's password: 
Now try logging into the machine, with "ssh 'server1'", and check in:

  .ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

3) Run ssh-agent as service with -s. This will not kill it if you logout. Its output is a valid shell script, setting the environment so ssh client will know how to connect to it. We save that to a file (only the first line is really needed).

john@coffee:~$ ssh-agent -s | head -n 1 > ssh-agent.cf 
john@coffee:~$ cat ssh-agent.cf 
SSH_AUTH_SOCK=/tmp/ssh-VhyKL22691/agent.22691; export SSH_AUTH_SOCK;

4) Loaded the above to our current environment so we can use ssh-add to add our private key to ssh-agent. the passphrase from above.

john@coffee:~$ source ssh-agent.cf 
john@coffee:~$ ssh-add  .ssh/id_rsa_test
Enter passphrase for .ssh/id_rsa_test: 
Identity added: .ssh/id_rsa_test (.ssh/id_rsa_test)

5) Verified it is added.

john@coffee:~$ ssh-add -l
2048 96:58:94:67:da:67:c0:5f:b9:0c:40:9b:52:62:55:6a .ssh/id_rsa_test (RSA)

6) The script I used, slightly modified than yours. Notice that I did not enclose the ssh command in parentheses and not using backticks rather $(), which is a better alternative for command substitution (this is bash compatible, you didn't mention which shell you're using). I used the exact same ssh command as yours.

john@coffee:~$ cat foo.sh 
#!/bin/bash

source /home/john/ssh-agent.cf
for server in server1 server2; do
    usr=$(ssh -t -t -o ConnectTimeout=60 $server finger | tail -1 | awk '{print $1}')
    date=$(ssh -o ConnectTimeout=60 $server date)
    echo "$server - $date - $usr" >> /home/john/foo.log
done

7) My crontab (note that my sh is actually bash)

john@coffee:~$ crontab -l
# m h  dom mon dow   command
*/1  *  *  *  *  sh /home/john/foo.sh

8) The output

john@coffee:~$ tail -n 4 foo.log
server1 - Wed Mar 23 14:12:03 EET 2011 - john
server2 - Wed Mar 23 14:12:04 EET 2011 - john
server1 - Wed Mar 23 14:13:03 EET 2011 - john
server2 - Wed Mar 23 14:13:04 EET 2011 - john

The only problem with using a passphrase is that you need to enter it manually at least one time. So, the above will not automatically work after a reboot.

2
  • Wonderful - thanks. I can live with the no automatic restart after reboot for now, at least. Dec 5, 2012 at 12:04
  • Use ssh-cron to set up scheduled SSH connections to secure servers without exposing your SSH keys, but using SSH agent. unix.stackexchange.com/questions/8903/…
    – Luchostein
    Aug 3, 2016 at 17:12
4

Who types the password? The cron job can't get at your ssh-agent, so public key won't work.

You need to supply ssh with a key file explicitly (see the -i option), since it can't query an agent; and that key must have an empty passphrase.

8
  • Tried by passing the username and password too -- ssh -t -t -o ConnectTimeout=60 user@machine$1 finger | tail -1 | awk '{print$1}' < /home/user/passwd ---- i mean home directory is on NFS, so it mounts to everymachine
    – user5529
    Mar 9, 2011 at 7:53
  • If ssh has any sense, it's using /dev/tty to read the password instead of stdin; that won't work from cron.
    – geekosaur
    Mar 9, 2011 at 7:57
  • Tried giving -i option but no luck! ---- ssh -o ConnectTimeout=60 -i /home/subrahmanyam/.ssh/known_hosts machine$1 finger | tail -1 | awk '{print$1}'------WARNING: UNPROTECTED PRIVATE KEY FILE! Permissions 0640 for '/home/user/.ssh/known_hosts' are too open. It is recommended that your private key files are NOT accessible by others. This private key will be ignored. bad permissions: ignore key:
    – user5529
    Mar 9, 2011 at 8:09
  • Why is it complaining about known_hosts? But yes, you need to watch out for permissions — the private key file should be mode 0600 or even 0400, owned by you. If you need some other user to be able to use it as well, you'll have look into POSIX ACLs or similar.
    – geekosaur
    Mar 9, 2011 at 8:12
  • Come to think of it, I saw GSSAPI being offered in there so another possibility is to get a keytab and use it to kinit inside the cron job. That said, keytabs also require the same care in permissions; but ssh at least won't complain about them.
    – geekosaur
    Mar 9, 2011 at 8:16
1

Rather than store a temporary file like forcefsck did, I prefer to use find to search for on active agent.

At the topic of a script that needs the ssh-agent, I use:

export SSH_AUTH_SOCK=$(find /run/user/$(id -u)/ -mindepth 2 -maxdepth 2 -path '*keyring-*' -name 'ssh' -print -quit 2>/dev/null)

It searches for the ssh-agent socket and returns the first one. It is restricted to only the current user, therefore you won't accidentally try to use another users and get a permission denied error. You would also need to already be logged in with an active ssh-agent. (Ubuntu starts an agent when the GUI starts up).

If you put this in another script, you'll need to call it with source or . because it needs to set the SSH_AUTH_SOCK variable.

0

Use ssh-cron to set up scheduled SSH connections to secure servers without exposing your SSH keys, but using SSH agent.

0

You can run your script or command in crontab like:

0 * * * * bash -c -l "/home/user/sshscript.sh"

or

0 * * * * bash -c -l "ssh root@yourhost 'echo $HOSTNAME'"

You must log in to answer this question.