Auto-Update WordPress With SFTP

[wordpress-auto-update][1]

每次進到 WordPress 的後台管理系統,看到有一堆 plugins 和系統安全更新,暈!!很多人 – 包含懶人如我 – 看到需要更新那們多套件,每樣套件都需要 ssh 登入主機設定或者用 ftp 上傳,覆蓋過舊的版本,那大概會選擇不要更新,放給它爛吧!等被黑了再說..XD 所以 WordPress 官方當然想要盡量減少懶人如我這樣不愛更新系統的情況。而若要讓懶人常常更新系統,充分非必要條件乃是可以直接在網頁上點選更新選項,接下來後台直接幫你設定安裝完畢!多麼完美阿!就像作業系統一樣,不~甚至更屌,只需要可以上網的地方就可以做到系統跟新。研究了一下他的更新機制,總體來說,它會先下載更新套件到一個 apache2 可以寫入的暫存區,接下來再用 FTP 或者 FTPS (SSL) 上傳到 WordPress 系統存放網頁的目錄,把舊版的程式碼覆蓋掉。

或許大家會好奇,為甚們不要直接從那個暫存區透過 PHP command 直接解壓縮覆蓋掉舊版程式碼?主要是因為 Apache2 或者 web server 的權限問題。Web server 並非對所有的檔案或目錄有寫入的權限,因此唯一的變通方式是透過 PHP 的 FTP (FTPS) 的 function 來從 server 對 server 建立 FTP 連線(此連線由 PHP 所建立,也就是其實 client 端就是 server 上跑的 PHP)。故由以上分析得知,要用 WordPress 的自動更新功能,其必要條件為下:

  1. 主機端必須裝有 FTP (FTPS) Server, 並且接受本地端連線(從 server 本身連 server )。
  2. 給予自動更新系統建立 FTP (FTPS) 的帳號必須要可以完全控制放置網頁的那個目錄與檔案 – 也就是該目錄與檔案的擁有者需為此帳號。
  3. FTP (FTPS) Server 不能開啟 chroot 模式,因為 PHP FTP Client 判別上傳到哪個目錄是直接用 pwd 來得知。若開啟 chroot, PHP FTP Client 將不知道把新版程式碼放到哪個目錄。

上面這些條件中,最難解決的應該是安裝 FTP (FTPS) 伺服器!基本上我的機器已經不裝 FTP Server 了,取而代之的採用 SFTP (SSH) 來上下傳檔案。我一直以為 PHP 不支援 SFTP Client, 也因此不支援 SFTP 更新。因蠻多人會搞混,這裡稍微解釋一下 FTPS 和 SFTP 有甚們不同。FTP 不安全是眾所皆知的事情。FTP 在傳輸帳號密碼或資料的時候,皆採用明碼,也就是說有心人士只要傾聽封包,即可知道你的帳號密碼以及傳輸的內容。而 FTPS 基本上是透過 SSL 加密的 FTP, 概念上和 HTTP 與 HTTPS 的關係類似。透過 FTPS 登入系統時,帳號和密碼都會被加密,但是傳輸的資料未必會被加密,需要由 Client 端指定。看似 FTPS 很安全,而且保有 FTP 的便利性,那它有甚缺點呢?答案是 FTPS 需要額外的 data 傳輸通道,這對於防火牆設定會造成一些困擾。其次是 FTPS 就是加密的 FTP, 所以你還是得要裝好 FTP 伺服器(如 vsftp ),這會增加資安風險。或許你會說可以裝好 FTP 伺服器,然後透過防火牆只讓 localhost 也就是本機可以連入,那我們就可以用 WordPress 的自動更新功能,且沒甚資安風險啦!好吧,如果為了那 WordPress 自動更新功能你要這樣大費周章,那我不反對。

SFTP 是建立於 SSH 通訊協定。稍微對於 Unix 系統有些認識的人,都應該聽過 SSH 才是。SSH 可以讓你安全加密的遠端連線到其他 Unix 主機,並建立遠端終端機介面。所有透過 SSH 傳輸的資訊皆為加密過的,因此中間就算有人竊聽到你的網路封包,還是無法解密得知內容。SSH 在設計的時候當然不是指針對遠端終端機加密操作,它包含了大量的擴展能力。舉例來說,我常常用 SSH 來建立 port 對 port 的加密通道,並在此通道上跑 VNC protocol. 偶爾我也會用 SSH 來建立加密通道,偷偷在一些封鎖及時通訊軟體的地方上線聊天。目前甚至有透過 SSH 加密通道的遠端網路磁碟通訊協定 – SSH Filesystem based on Fuse. 故,SSH 當然會應用在檔案傳輸的角色 – SFTP, 更好的消息是,SFTP 幾乎是不用安裝的,這是 SSH 送的功能。大部分的 Unix 系統皆已經內建了 SSH 伺服器。(ps, 在此推薦一下跨平台且自由軟體,在 Linux, Mac, and Windows 都可以使用的 FTP, FTPS, and SFTP Client – FileZilla. )

接下來的問題是,Wordpress 到底接不接受透過 SFTP 更新?好吧~應該是說 PHP 有沒有辦法建立 SSH 連線?答案是可以的!不然也不會有這篇文章出現。預設是 PHP 沒有支援 SSH 的模組,你得要自己編譯,然後掛到 PHP 系統上面。這些事情在 Debian 或 Ubuntu 裡面可以很容易透過套件管理系統做到。以下我們假設使用的作業系統為 Debian 或 Ubuntu. 其它的發行板可能需要參閱相對應的資訊,但概念上是一樣的。

(ps, 你的 SSH 帳號仍然需要滿足上面使用 FTP 方案的條件二,也就是該帳號需要可以完全擁有你網頁檔案與目錄的權限。而條件三因為 SFTP 沒有 chroot, 所以一定可以定位到你網頁的目錄,不需多慮。)

首先裝編譯器以及需要的函式庫標頭檔和 suphp module:

sudo apt-get install build-essential zlib1g-dev php5-dev \
php5-cli php-pear libssh2-1-dev libapache2-mod-suphp

接下來開始編譯 SSH for PHP 的函式庫吧:

sudo pecl install -f ssh2

在 /urs/lib/php5 的某個目錄應該會有剛編譯好的 ssh2.so library. 檢查一下看有沒有成功。

ls /usr/lib/php5/*/ssh2.so
/usr/lib/php5/20060613/ssh2.so

接下來編輯 /etc/php5/conf.d/ssh2.ini

extension=ssh2.so

重新啟動 Apache2, 使剛剛新加入的模組生效。

sudo  /etc/init.d/apache2 restart

若以上步驟都成功的操作,你的 PHP 應該是可以有操縱 SSH 連線的能力,重新進入 WordPress 的後台,按下自動更新的選項後,應該是有 SFTP 可以選擇。你甚至可以用 SFTP 安裝新的 plugins, 完全不需要下載後再上傳,很方便吧!

若你的 SFTP 選項還是沒有出現,請先建立一個 PHP 網頁 phpinfo.php:

執行該網頁後,你應該可以看到以下資訊,若沒有的話,就是 SSH 模組安裝有問題。如果模組安裝成功,Wordpress 卻沒有這個選項,可能是你使用的 WordPress 版本不支援 SFTP, 請更新到最新版。

ishot-1

[1]: /assets/blog/2009/05/wordpress-auto-update.png

Dialogue & Discussion