Windows一鍵執行SSH指令:AutoIT、Pietty搭配使用
Linux的命令列畫面讓很多人惟恐避之不及,這對有許多指令需要依賴SSH連線、並在命令列輸入才能執行的DSpace來說,無疑是一大門檻。在此我提出一種可以做到「一鍵指令」的方案:利用AutoIt自動執行機器人,透過PieTTY的命令列模式,用ini設定檔來設定連線參數,來執行捷徑所指定的指令的作法。
這種作法對資安來說非常不理想,僅是一個簡便利用的應急方案而已。
一鍵指令的背景與目的
我現在要做的事情是:
- 在Windows的環境下
- 透過SSH連線到Linux伺服器
- 進行登入動作(以及金鑰確認)
- 然後執行一個指令。
而這個方案的目的是將使用者的操作簡化到極限,我希望使用者能夠以滑鼠執行一個檔案,就自動做完上述的所有動作。
一鍵指令方案概述
簡單來說,這個方案的作法是:
- 利用PieTTY的命令列模式來輸入登入資訊與要執行的指令
- 以ini檔案儲存登入資訊
- 在Linux伺服器端配置參數與接收命令的sh腳本
- 利用AutoIt來處理連線的細節
- 利用Windows的捷徑與捷徑後輸入的參數,將參數輸入給AutoIt
Linux環境配置
要做到這些事情,需要Linux伺服器端與Windows使用者端的環境一起配置才行。這邊先敘述Linux的部份,大致上是要做以下三件事情:
- 建立帳號、密碼
- 開啟ssh連線
- 建立ssh-cmd.sh腳本
Linux伺服器建立帳號、密碼、開啟ssh連線等基本操作請參考鳥哥的Linux思房菜。在此最重要的是要配置接收來自客戶端指令的執行腳本「ssh-cmd.sh」。
在本篇的例子中,我以普通使用者「dspace」跟管理者「root」作為帳號、「password」作為該帳號的密碼來說明。
ssh-cmd.sh:執行指令腳本
因為帳號是使用「dspace」,所以我在「/home/dspace/ssh-cmd.sh」(SkyDrive備份)這個位置建立起腳本。腳本的內容如下:
#!/bin/bash # Program: # Excute command and pause at finish. ## History: ## 2009/11/12 Pudding First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export JAVA_HOME=/usr/java/jdk1.6.0_06 export PATH export LC_ALL=en_US export JAVA_OPTS="-Xmx128M -Xms64M -Dfile.encoding=UTF-8" ANT_HOME=/opt/apache-ant-1.7.0 JAVA_HOME=/usr/java/jdk1.6.0_06 CATALINA_HOME=/opt/apache-tomcat-6.0.16 PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$ANT_HOME/bin:$PATH:/opt/apache-maven-2.0.9/bin export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC JAVA_HOME ANT_HOME CATALINA_HOME if [ "$1" == "/home/dspace/tomcat_restart.sh" ]; then at now + 0 minutes < $1 echo "Tomcat will restart now." else $1 fi echo "" echo "=====================================" echo "" read -p "Please press ENTER to exit. " doExit
這個腳本中設置了相當多參數,請依照你伺服器的實際情況來決定要設置的參數內容。
此外,由於Tomcat的重新啟動無法直接透過這樣的指令來執行,所以我改成以「at」執行一次的方式來執行。必須說明的是,這並不是很理想的作法,有待以後改善。
tomcat_restart.sh:重新啟動Tomcat伺服器腳本
如果你沒有需要重新啟動Tomcat的話,這個步驟是可以省略的。「/home/dspace/tomcat_restart.sh」(SkyDrive備份)是用來重新啟動Tomcat伺服器的腳本,內容如下:
export JAVA_HOME=/usr/java/jdk1.6.0_06 export JAVA_OPTS="-Xmx128M -Xms64M -Dfile.encoding=UTF-8" /opt/apache-tomcat-6.0.16/bin/shutdown.sh sleep 1 /opt/apache-tomcat-6.0.16/bin/startup.sh
要記得將這些腳本的執行權限開啟,他們才能正常地執行。
Windows使用者端配置
你現在需要在Windows中建立一個資料夾,例如「c:\ssh-cmd\」,然後把以下的檔案放進去:
- pietty0327.exe(SkyDrive備份):SSH連線工具
- ssh.cmd.exe (AutoIt原始腳本檔案):執行連線的自動化程式
- config.ini:連線配置
- Windows捷徑:配置要執行的身分與指令,稍後敘述
PieTTY的命令列執行方式
雖然很多人都知道PieTTY是用來作SSH連線的,但是知道PieTTY可以透過命令列與指令檔案來進行連線並執行指令的人就不多了,其實這是基於PieTTY改編自PuTTY原始就有的功能喔。
具體來說,利用命令列來透過PieTTY連線的作法如下:
pietty0327.exe -l [ID] -P [PORT] -pw [PASSWORD] -m [COMMAND] -t [HOST]
裡面的參數中:
- [ID]是要登入的帳號
- [PORT]是連接埠
- [PASSWORD]是密碼
- [COMMAND]是「存放指令的檔案位置」,注意,不是指令,只是檔案位置喔
- [HOST]要連線的主機IP
config.ini:連線配置
連線的配置資訊,我將它存放在「config.ini」中。「config.ini」的內容如下:
[ssh-dspace] login=dspace pw=password [ssh-root] login=root pw=password [ssh] port=22 host=127.0.0.1
在此安排了兩種不同的身分,一種是以普通使用者「dspace」來執行,另一種是以管理者「root」來執行。除了重新啟動伺服器等重大指令之外,一般指令最好是以普通使用者「dspace」的身分來執行會比較安全。
ssh-cmd.exe:執行連線腳本
由於要執行指令必須要以存放在檔案中的形式來執行,所以建立這個檔案、並指引PieTTY來連線的工作,是交給AutoIt的自動腳本ssh-cmd.exe來執行。
ssh-cmd.exe是由ssh-cmd.au3編譯而來的,這是AutoIt的程式語言。內容如下:
Dim $user = "ssh-dspace" Dim $script = "" If $CmdLine[0] == 2 Then $user = "ssh-" & $CmdLine[1] $script = $CmdLine[2] ElseIf $CmdLine[0] == 1 Then $script = $CmdLine[1] EndIf Dim $login = IniRead("config.ini",$user, "login", "root") Dim $pw = IniRead("config.ini",$user, "pw", "password") Dim $port = IniRead("config.ini","ssh", "port", "22") Dim $host = IniRead("config.ini","ssh", "host", "127.0.0.1") If $script == "" Then MsgBox(0, "錯誤", "請指定要執行的指令") Exit EndIf Dim $doExcute = MsgBox(1, "提示","您確定要在伺服器中執行以下命令嗎: " & $script) If $doExcute == 2 Then Exit EndIf Dim $sh = "cmd.sh" Dim $scriptHeader = "~/ssh-cmd.sh " $file = FileOpen($sh, 2) ; Check if file opened for writing OK If $file = -1 Then MsgBox(0, "錯誤", "無法開啟檔案") Exit EndIf FileWrite($file, $scriptHeader & $script) FileClose($file) Dim $cmd = "pietty0327.exe -l " & $login & " -P " & $port & " -pw " & $pw & " -m " & $sh & " -t " & $host Run($cmd) Sleep(1000) If WinActivate("PieTTY Security Alert") Then WinActive("PieTTY Security Alert") Send("{ALTDOWN}Y{ALTUP}") EndIf
這個腳本做了幾件事情:
- 接收來自外部的「身分」與「指令」參數(稍後建立Windows捷徑的時候,我會再說明怎麼輸入這邊的參數)
- 讀取來自config.ini中的連線資訊,包括「帳號」、「密碼」、「伺服器位置」、「連接埠」
- 過濾指令、顯示提示
- 將指令寫入「cmd.sh」檔案中
- 以命令列執行PieTTY連線
建立Windows捷徑
接著要建立到「ssh-cmd.exe」的捷徑,並且在捷徑之後加上「參數」。建立好ssh-cmd.exe並改好名字之後,你可以打開捷徑的「內容」,在「目標」的欄位中設定參數。
舉例來說,我現在要在伺服器上以「dspace」身分執行「/home/dspace/tomcat_restart.sh」的指令,那麼目標裡面的設定如下:
"C:\ssh-cmd\ssh-cmd.exe" dspace /home/dspace/tomcat_restart.sh
目標的值除了指定要執行的程式位置之外,還指定了要執行的身分「dspace」跟要執行的指令「/home/dspace/tomcat_restart.sh」。如此配置之後,就能夠讓使用者直接點選此捷徑,讓他自動執行這些動作了。
你可以利用這個例子舉一反三,建立執行不同身分、不同指令的捷徑,並組成一個操作列表,讓使用者易於選擇。也可以將此捷徑放到「開始」程式集裡面,讓使用者更容易執行各種操作。這些動作我是用InnoSetup在安裝時自動配置而成,不過那又是另一番長篇大論了。
結語
儘管一鍵指令的方案我研究了很久,但是仍有很多不完美之處,希望高手能多多指教。
其實這個是DSpace-DLLL寫書的一部分技術內容。之前寫完書之後就匆忙地投入其他事情中,到最近在使用AutoIt時,又把之前寫的檔案挖出來看。
這時候就會覺得這個Blog對我來說也是很重要的,如果沒有這些記錄,我恐怕很快就會忘記自己之前做過的事情了吧。
網誌管理員已經移除這則留言。
回覆刪除您好!
回覆刪除感謝你分享這麼好的資訊。
不過小弟今天使用的時候發現了一些問題,我想使用MFC想要達到用這方法登入Linux 然後呼叫一個.sh去實行一個程式,不過我卡在[COMMAND]這邊,試了好多方法都會掛掉,沒有帶[COMMAND]參數就OK,可見我對cmd line file的認知不太對。我是直接在程式下面建立一個.sh檔,然後裡面就是一行呼叫Linux root下的一個程式,看您程式是有header+script去combine,不知這樣出來的檔案會是怎樣?
不知這樣您了解我的問題否,還望指點迷津 感恩 :)
您好,
回覆刪除請問您的[COMMAND]部分寫了些什麼?
路徑位置跟檔案位置有正確嗎?請盡量用完整路徑,不要用相對路徑
你看起來是想用MFC取代我原本用的AutoIT,應該是可行的
不過語法上你再確認一下比較好
剛剛跟of.hsiao信件討論,他說他的Windows上cmd.sh內容只有
回覆刪除~/ssh-cmd.sh
/root/test.sh
應該是不會有斷行才是吧?
cmd.sh的產生你是用AutoIT來做的嗎?還是用MFC來做的?
您好
回覆刪除之前[COMMAND]有點錯誤,我現在更正了
可以執行到Linux上的ssh-cmd.sh
不過我只是想單純的執行上面的某個程式
但是假設我在ssh-cmd.sh打上 /root/test 呼叫程式,Pietty就整個都掛了...
嗯……太複雜的執行方法我也不確定要如何處理。
回覆刪除總之這是一個在bash shell中執行的腳本就是了。
有找到解法的話,歡迎分享一下,感謝感謝
謝謝回答
回覆刪除其實我的目的只是想在MFC程式上,連接登入Linux,然後執行某個程式而已。
應該是比大大的還簡單,只是shell bash這東西我不太了解... Orz
不好意思請問版主大大 cmd.sh這個檔案裡面寫的是要寫連線後的操作指令?還是一個空白檔?還是有甚麼其他用途的嗎?
回覆刪除To 樓上,
刪除將指令寫入「cmd.sh」檔案中
cmd.sh是一個暫存用的指令檔,它就是被建立用來保存要執行的指令,然後再來執行這個cmd.sh
我知道了,我會再試試看,謝謝版主大大
刪除加油
刪除