1. 程式人生 > >shell指令碼實現通過ssh跳板機(動態密碼)一鍵登陸伺服器(相關問題與解決方案)

shell指令碼實現通過ssh跳板機(動態密碼)一鍵登陸伺服器(相關問題與解決方案)

在我日常工作中,登陸伺服器一般分為兩個個步驟,通過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;去掉就可以了。