最近更新: 2014-10-02

因應 bash shellshock ,直接移除 bash 也是建議事項

關於 bash shellshock 的漏洞風波愈演愈烈,一波未平一波又起。好像有補不完的完全漏洞。關於這件事,我任職公司也有討論過因應之道。因為我任職公司屬於系統整合商,按照公司的產品性質,我給出的建議處置方式是「直接移除 bash」。

事實上, bash 只是一般使用者登入後使用的命令列介面。但大部份 shell script (指令稿) 的預設解譯器不是 bash ,而是 /bin/sh 。包括 PHP/Python/Perl 以 system() 呼叫外部指令時,也是如此。 /bin/sh 是 ash/dash 的符號連結,這個輕量型命令列介面並不受此 shellshock 影嚮。

在準系統或嵌入式系統中,為了追求輕量化且沒有讓使用者登入之必要性,實務上大多僅安裝 dash 或更輕量的 busybox

純種的 sh (也就是 Bourne shell) 只 Unix 系統才有,這種系統現在大概只有在電腦歷史博物館才看得到。在 Unix-like 系統中,跑得全都是替代品,例如 ash, ksh, zsh, dash, bash 等等,族繁不及備載,參考 Unix shell - Wikipedia。現在說到 /bin/sh 指的是各種可相容於 POSIX 規範的 shell 產品。有些 Unix-like 系統可能預設就將 /bin/sh 連結到 bash 。使用者需要自己確認。

bash 和 dash 相比,一個顯而易見的差異在於 bash 提供更完善的命令列線上編輯能力。因為 bash 要讓使用者在終端機環境操作時,享受有更多的便利性。舉凡方向鍵上下翻找命令歷史, Ctrl+A, Ctrl+E 等游標操作編輯行為,都是針對使用者手動操作鍵盤時的需求而設。但對於執行 shell 指令稿來說,這些編輯功能毫無必要。因此像 dash 這些輕量化 shell 都不提供線上編輯能力。

dash (/bin/sh) 雖然是輕量化 shell ,但它可是為執行 shell 指令稿而設計,仍然提供完整的 POSIX 規範的 shell 語法與指令。在 Linux 系統中,由系統自行安裝的 shell 指令稿九成以上僅以此類輕量化 shell 便可執行。而一但碰到 dash 語法不能滿足的操作時,我個人更偏好改用 PHP 或 Python 來寫指令稿 (是的,我也用 PHP 寫指令稿)。因為 bash 的進階語法閱讀性不佳,而我個人更重視閱讀性,所以就不喜歡用 bash 寫指令稿。

附帶一提,不管你的 /bin/sh 實際上連結到哪種 shell 。當你在寫 shell 指令稿時,如果你的 shebang 寫 #!/bin/sh ,那你的指令稿內容就應該只用 POSIX 規範的語法和指令。這樣才能保證 shell 指令稿執行時的相容性。這算是 Linux 散佈套件製作時的基本共識。

從一個系統整合商的角度來看,我們出貨的 Linux 系統根本就不讓使用者登入,我們公司自行撰寫的 shell 指令稿也不限定要用 bash 才跑得動。嗯,確實公司有些人在寫 shell 指令稿時會在開頭標上 #!/bin/bash 。但只是習慣,實際上沒用到 bash 專屬語法。很多人根本不知道 bash 專屬語法。至於一些開放出來的 Web 管理端介面,則是用 PHP (apache + mod_php) 撰寫。故我給出的建議就是「直接移除 bash 」。還有,那些登入後使用 /bin/bash 介面的帳號也要記得改成 /bin/sh 。

如果你是 Linux 桌面的使用者,經常在視窗上開終端機模擬程式 (xterm, gnome-terminal, konsole) 操作指令,沒有 bash 會打字打到手指斷掉的話,也有不正式解法。首先,將 bash 檔改個名字 (例如 /bin/my-bash) ,並將使用帳號的預設 shell 改成 /bin/sh 。最後修改終端機模擬程式的設定,告訴它啟動時執行 /bin/my-bash 。這樣就不會有系統程式「不小心」用到 bash 。只有你在桌面上執行終端機模擬程式時,終端機模擬程式才會用 bash 。當你用 ssh 登入時,則要記得自己執行 my-bash 切到 bash 命令操作環境。

如果還有駭客可以在這種啟動途徑下,植入惡意的 bash 指令稿,那他肯定是用系統中其他的安全漏洞駭入,或者根本就坐在你的電腦前操作。

從一般的、正式的使用目的來說,我覺得一般使用者更新 Linux 供應者提供的 bash 更新套件,應該就足以應付 shellshock 風波了。如果你疑神疑鬼,認為 bash 還有補不完的漏洞,那就換掉它吧。 Unix 世界多得是各種 shell 。

關於 bash shellshock 的漏洞事件:

樂多舊網址: http://blog.roodo.com/rocksaying/archives/31862477.html

樂多舊回應
未留名 (#comment-25150401)
Fri, 03 Oct 2014 13:44:41 +0800
請問您在第二段說明的
"事實上, bash 只是一般使用者登入後使用的命令列介面。但大部份 shell script (指令稿) 的預設解譯器不是 bash ,而是 /bin/sh 。包括 PHP/Python/Perl 以 system() 呼叫外部指令時,也是如此。 /bin/sh 是 ash/dash 的符號連結,這個輕量型命令列介面並不受此 shellshock 影嚮。"

我於centos 中/bin/sh下看見情況為 lrwxrwxrwx. 1 root root 4 Jun 19 09:52 sh -> bash
似乎是以bash為基本。
請問這個差別是因為os的問題還是我誤解了什麼?
未留名 (#comment-25150417)
Fri, 03 Oct 2014 14:24:26 +0800
這個差別是 Linux 散佈套件製作者的選擇。
Linux 世界有幾十種散佈套件版本,每一個製作者的設計理念都不相同。
也許 CentOS 的製作者覺得一個系統中不需要兩種 shell 。

就我本人用過,以及 wiki (http://en.wikipedia.org/wiki/Almquist_shell) 的資訊,下列系統是預設會安裝並將 /bin/sh 連結到 ash 或 dash : FreeBSD, NetBSD, Debian 及其衍生種, Ubuntu, Android 。

有些散佈套件會提供安裝選擇,當使用者沒有安裝 bash 以外的 shell 時,就自動將 /bin/sh 連接到 bash 。
如果有安裝第二種 shell 時,則會詢問或提示讓使用者將 /bin/sh 連接到其他 shell 。
未留名 (#comment-25150419)
Fri, 03 Oct 2014 14:34:48 +0800
附帶一提,不管你的 /bin/sh 實際上連結到哪種 shell 。當你在寫 shell script 時,如果你的 shebang 寫 #!/bin/sh ,那你的 shell script 內容就應該只用 POSIX 規範的語法和指令。這樣才能保證 shell script 執行時的相容性。這是 Linux 散佈套件製作時的基本共識。
hoamon@hoamon.com(何岳峰) (#comment-25150509)
Fri, 03 Oct 2014 17:21:17 +0800
好方法。