Crontab執行腳本中的ssh命令訪問被拒絕

咱們常常會經過crontab來執行定時任務,一般生產環境中在不一樣主機直接進行登陸是經過ssh來鏈接的。好比咱們經過在備份服務器上設定定時任務,按期經過scp(使用SSH的遠程拷貝命令)來拷貝遠程服務器的數據到備份服務器上,這也是我遇到的一個事情。shell


環境描述:bash


腳本與定時任務:服務器

定時任務設置以下:
ssh

不管是否執行成功,都把信息輸出到2222.txt中ide

wKioL1hVA8SA4TJ1AAAOa2l0LSc103.jpg-wh_50

腳本內容以下:
測試

我這裏僅用ssh命令來測試,實際上這個命令若是能夠正常執行的話,你執行scp命令也同樣ui

#!/bin/bash
ssh -v 192.168.50.135 'ls'


報錯信息:spa

下圖是crontab執行定時任務中的腳本的報錯信息blog

你發現TCP鏈接是成功創建的,而後也在備份服務器上的~/.ssh/目錄中的known_hosts文件中找到了host key。這個key是對方主機的公鑰。在/etc/ssh/ssh_config中的 StrictHostKeyChecking 的值決定了是否把對方的公鑰放在known_hosts文件中。若是是yes則表示不存放,若是是no則表示存放,若是是ask則表示詢問。crontab

下圖這個意思是說KEY找到了並且匹配,就是說備份服務器存的對方服務器的公鑰和對方如今使用的公鑰一致。

最後是嘗試發送本身使用的公鑰讓對方去驗證,這裏嘗試了幾回,而且更換了幾種驗證方式均宣告失敗,因此最後拒絕訪問。

wKioL1hVBHLh5tQxAAHGlcynAWM131.jpg-wh_50

下圖是單純運行腳本的輸出信息:也就是直接在終端中運行腳本

能夠看到驗證是經過的,不過你會發現它使用的是一個叫作id_dsa的公鑰文件發送給服務器,而後對方接受了。但是我這個備份服務器本地的~/.ssh/目錄中並無id_dsa的文件

wKiom1hVCR2g1Cm5AAGYbZ0ZsgY738.jpg-wh_50

我發現跳板機(Linux的跳板機,通常登陸IDC的機器都要登陸到跳板機,並且其餘服務器也只接受來自跳板機的IP信息,你就算撥入了×××,若是不先鏈接到跳板機,你也是沒法登陸服務器的,那可能有人問,我經過跳板機鏈接到了服務器,而後從這個服務器再SSH到另外的服務器是否能夠呢?能夠)的~/.ssh/目錄中有id_dsa文件,因而我就拷貝到個人備份服務器上,測試後依然失敗。


排查問題:


查看env

wKiom1hVDuiCFGgwAAAv7agSPjw962.jpg-wh_50


修改腳本:

修改~/.bashrc文件,也就是本地變量文件,在文件中增長以下內容,這些內容和也就是以前經過env查看到的

export SSH_CLIENT="192.168.90.58 14567 1314"
export SSH_TTY=/dev/pts/2
export SSH_AUTH_SOCK=/tmp/ssh-cvRpw15068/agent.15068
export SSH_CONNECTION="192.168.90.58 14567 192.168.90.91 1314"


修改腳本

#!/bin/bash
source $HOME/.bashrc
ssh -v 192.168.50.135 'ls'


驗證:

再次執行就成功了。


總結:

crontab執行腳本不成功一般都是環境變量致使的,由於crontab執行腳本屬於非登式shell,針對這種它是不加載/etc/profiel和~/.bash_profile。它的會先加載~/.bashrc,而後加載/etc/bashrc,最後加載/etc/profile.d/下的變量。因此我在家目錄中的bashrc中設置了和env中同樣的變量,這樣在腳本里面指定就能夠了。若是你只是在basrc中寫,而不在腳本中source初始化文件也不行。緣由我猜想多是跟crontab本身的環境變量有關,並且在/etc/rond的配置文件中設置環境變量不生效,不知道爲何。


因此在crontab執行腳本,一般的建議是命令寫全路徑,另外還應該設置好環境變量

#!/bin/bash
source /etc/profile
source $HOME/.bashrc

若是是ssh這種遠程執行,可使用-i參數指定公鑰。

相關文章
相關標籤/搜索