ssh串連遠程主機時候會詢問密碼,跟su、sudo命令的預設行為一樣,是不從stdin讀入資料的,傳說是為安全考慮,但是有時候在指令碼當中確實需要無人守值的登陸。
搜尋一下不難找到類似的例子,使用expect來完成密碼應答:
代碼如下 |
複製代碼 |
#!/bin/bash auto_login_ssh () { expect -c "set timeout -1; spawn -noecho ssh -o StrictHostKeyChecking=no $2 ${@:3}; expect *assword:*; send -- $1r; interact;"; } auto_login_ssh password user@host StrictHostKeyChecking=no |
參數讓ssh預設添加新主機的公開金鑰指紋,也就不會出現出現是否繼續yes/no的提示了。
上述expect代碼基本可以達到要求了,可實現自動登入
自動ssh/scp指令碼
如果需要從A,到B,然後才能夠到C,那麼需要ssh和scp兩次,是比較麻煩的。
ssh自動登入:
代碼如下 |
複製代碼 |
#!/usr/bin/expect -f set timeout 30 spawn ssh weiqiong@B expect "password:" send "ppppppr" expect "]*" send "ssh weiqiong@Cr" expect "password:" send "ppppppr" interact scp從A拷貝檔案到C: #!/usr/bin/expect -f set timeout 300 set file [lindex $argv 0] spawn scp $file weiqiong@B:/home/weiqiong expect "password:" send "ppppppr" expect "]*" spawn ssh weiqiong@B expect "password:" send "ppppppr" expect "]*" send "scp $file weiqiong@C:/home/weiqiongr" expect "password:" send "ppppppr" expect "]*" exit interact scp從C拷貝檔案到A: #!/usr/bin/expect -f set timeout 300 set file [lindex $argv 0] spawn ssh weiqiong@B expect "password:" send "ppppppr" expect "]*" send "scp weiqiong@C:/home/weiqiong/$file .r" expect "password:" send "ppppppr" expect "]*" send "exitr" expect "]*" spawn scp weiqiong@B:/home/weiqiong/$file . expect "password:" send "ppppppr" interact |
4. 建立ssh/scp通道
比如說我的機器是A,中間伺服器為B,目標伺服器是C
從A可以ssh到B,從B可以ssh到C,但是A不能直接ssh到C
現在展示利用ssh通道技術從A直接傳輸檔案到C
代碼如下 |
複製代碼 |
1. ssh -L1234:C:22 userid@B input B's password
|
(1234是本機A的空閑連接埠,該指令需要A機器上的root使用者權限,實際上是在本機1234連接埠建立了一個通道)
2. 開啟一個新的console,鍵入:
代碼如下 |
複製代碼 |
scp -P1234 filename userid@localhost: input C's password |
如果僅僅是日常使用,為了避免經常輸入主機密碼的麻煩,最理想的方法是生產原生公/私金鑰組,把指紋直接複製到遠程主機上,較新的openssh提供了ssh-copy-id工具:
代碼如下 |
複製代碼 |
ssh-keygen ssh-copy-id user@host1 ssh-copy-id user@host2 ssh-copy-id user@host3 |
運行ssh-keygen時會問幾個問題,全部斷行符號預設就是我們要的效果了,分別把密鑰分發到遠程主機後,以後執行ssh user@host,還是scp,都是直接完成了。
如果需要刪除遠程機器上對應本機本賬戶的密鑰,登陸到該賬戶,開啟~/.ssh/authorized_keys檔案,搜尋你的使用者名稱,刪除那行,儲存,即可。
當然也可以自動化:
代碼如下 |
複製代碼 |
auto_ssh_copy_id () { expect -c "set timeout -1; spawn ssh-copy-id $2; expect { *(yes/no)* {send -- yesr;exp_continue;} *assword:* {send -- $1r;exp_continue;} eof {exit 0;} }"; } |