shell指令碼實現通過ssh跳板機(動態密碼)一鍵登陸伺服器(相關問題與解決方案)
阿新 • • 發佈:2019-02-19
在我日常工作中,登陸伺服器一般分為兩個個步驟,通過ssh命令登陸跳板機,然後再通過跳板機登陸伺服器。登陸跳板機又分為三個步驟,輸入一長串使用者名稱,再通過手機令牌檢視動態密碼,輸入密碼+動態碼。這樣每次登陸伺服器都需要這麼繁瑣的步驟,在需要解決一個問題的時候,在登入上花的時間已經好幾分鐘,在同時登入多個伺服器時更是讓人頭皮發麻,所以想寫一個指令碼,簡化操作流程實現一鍵登入。
下面是第一個思路,通過bash指令碼巢狀expect的方法,實現與命令列自動化互動,實現登入伺服器,該辦法在試驗後發現有問題,造成該方法不能實施。後面會介紹具體問題
#!/bin/bash salt="你的跳板機動態密碼" username="your username" password="your password" server="伺服器名" serverpass="伺服器密碼" /usr/bin/expect <<-EOF spawn ssh "$username" expect { "*yes/no*" { send "yes\n"; exp_continue; } "*Password:" { send "$password$salt\n"; exp_continue; } "*adadadw*" { send "ssh $server\r"; exp_continue; } "*password:" { send "$serverpass\r"; exp_continue; } } interact EOF
第二個辦法:
上面的方法會導致登上伺服器後無法進行其他操作,最終會退出,所以採取下面的辦法直接用expect指令碼執行,然後通過另一個bash指令碼呼叫該expect指令碼
login.sh
#!/usr/bin/expect set salt [lindex $argv 0] set username yourusername set password yourpassword set server 伺服器名 set serverpass 伺服器密碼 spawn ssh "$username" expect { "*yes/no*" { send "yes\n"; exp_continue; } "*Password:" { send "$password$salt\n"; exp_continue; } "*adadadw*" { send "ssh $server\r"; exp_continue; } "*password:" { send "$serverpass\r"; exp_continue; } } interact
test.sh
#!/bin/bash
salt=`python otp.py` #自己寫的獲取動態密碼的python指令碼,其他方法也可實現該指令碼,這裡就不公佈了
./login.sh $salt
通過tesh.sh呼叫login.sh即可實現一鍵登入,不會出現第一個方法出現的問題
./test.sh
遇到的問題及總結
bash和expect巢狀寫的注意事項
1.變數都要在bash裡面定義
2.bash與expect巢狀用set定義變數就不管用了
3.bash 指令碼巢狀expect指令碼實現ssh自動登入會導致崩潰(第一個方法導致的問題,暫未找到具體原因)
更新一下:
有個小問題,登入上伺服器後會有小卡頓:
原因是最後的 exp_continue;
把最後一個 exp_continue;去掉就可以了。