iT邦幫忙

0

bash 的 while 迴圈遇到 closed 而意外中止

小弟在 CentOS 7 寫一個簡單的 while 迴圈
要查詢本機的 Web Server 支援哪些 Cipher Suite
迴圈卻因為遇到 closed 而意外中止了
不知該如何繼續,懇請各位大大協助。

迴圈內容如下
while read rec
do
printf "Checking "${rec}" ..."
if openssl s_client -connect localhost:443 -tls1_2 -cipher ${rec} > /dev/null 2>&1 ; then
echo OK
else
echo Failed
fi
done < ./CipherList

餵進去的 CipherList 檔案內容如下(擷取前五筆)
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-RSA-AES256-SHA384
ECDHE-ECDSA-AES256-SHA384
DH-DSS-AES256-GCM-SHA384

預期 while 應該跑完整個檔案,然後結束
但卻在遇到第一個 OK 就終止了。
如果把判斷條件隨意換成 Failed 條件(例如:把 port 換成 543)
就可以跑完整個檔案(當然全部的回應都是 Failed)。

直接以 openssl 指令執行檔案中的資料
會發現在執行成功時,最後會回一個『closed』
研判是因為這個 closed 造成了迴圈中斷(類似 broken 的效果)
請問各位大大
有什麼方法可以跳過這個 closed,讓迴圈正常跑下去?

PS:如果各位大大手邊沒有 Web Server,可以把 openssl 指令中的 localhost 換成 tw.yahoo.com、或是 google 的網站也可以,直接測試公眾網站,看看他們接受哪些加密方式。

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

5
Ray
iT邦大神 1 級 ‧ 2021-11-15 12:47:31
最佳解答

ㄟ....你應該手動先測一下 openssl 的 s_client 會怎麼互動...

如果他可以執行成功的話, openssl 會停下來等 stdin 輸入, 然後把 stdin 的資料傳送給對方; 這個時候, 由於你是在 Script 裡面餵給他 CipherList 這個檔案, 所以 openssl 就把這個檔案當成 stdin 的 streaming 全部給吃掉了....

然後, CipherList 就沒有東西可以給 while do 讀取了....
(因為他已經被 openssl 讀到 EOF 去)

失敗的話她會往下走, 是因為失敗的時候, openssl 不會停在 connect 狀態等你從 stdin 輸入字串, 所以不會把 CipherList 的內容吃光...

你可以用 echo 餵給 openssl 假的 stdin, 讓他咬一口再跳過去就好:

while read rec
do
printf "Checking "${rec}" ..."
if echo | openssl s_client -connect localhost:443 -tls1_2 -cipher ${rec} > /dev/null 2>&1 ; then
echo OK
else
echo Failed
fi
done < ./CipherList

執行結果:

sh test.sh
Checking ECDHE-RSA-AES256-GCM-SHA384 ...Good
Checking ECDHE-ECDSA-AES256-GCM-SHA384 ...Good
Checking ECDHE-RSA-AES256-SHA384 ...Good
Checking ECDHE-ECDSA-AES256-SHA384 ...Good
Checking DH-DSS-AES256-GCM-SHA384 ...Failed
kjfang iT邦新手 5 級 ‧ 2021-11-15 18:43:42 檢舉

raytracy大
實在太感謝您了,這問題困擾了我一天。
直接執行 openssl 時,我有注意到程式會稍微停頓一下子
通常都還沒等我反應過來要做啥就結束了
猜測是網路問題,就不去理他
沒想到就是這個小小的停頓
造成了程序中斷
也讓我誤認為是最後那個 closed 所造成的現象。

我要發表回答

立即登入回答