使用MySQL時,只要撰寫程式的內容符合UDF架構的規範,即可撰寫自定義的函數來提升MySQL的功能。本文將介紹如何安裝此類UDF程式庫來擴充MySQL資料庫的功能。
接著執行指令「cp lib_mysqludf_log.so /usr/local/mysql5/lib/plugin/」,將lib_mysqludf_log.so複製到MySQL的plugin目錄位置。
再進入MySQL命令模式,執行「mysql>drop function lib_mysqludf_log_info;」,如此一來,倘若原先已有相關lib_mysqludf_log_info的函數,即先移除該函數。如果原先已有相關log_error的函數,即先移除該函數,因此接著輸入「mysql>drop function log_error;」。
執行「mysql>create function lib_mysqludf_log_info returns string soname 'lib_mysqludf_log.so';」,新建lib_mysqludf_log_info函數。此函數功能在於傳回lib_mysqludf_log_info的版本資訊。
再執行「mysql>create function log_error returns string soname 'lib_mysqludf_log.so';」新建log_error函數,這是lib_mysqludf_log唯一提供的函數,主要功能在於提供直接由MySQL資料庫存進Log資訊至系統檔案中的功能。
最後需留意的是log_error()函數。寫入相關的Log資訊至系統檔案中,例如「select log_error('hello world!!!');」即是寫入”hello world!!!”至系統檔案內。
安裝lib_mysqludf_sys程式庫
lib_mysqludf_sys程式庫可以讓使用者直接從MySQL資料庫執行系統指令,在某些商業化的資料庫軟體,如微軟的MSSQL也有提供相關的功能。其實,若從資訊安全的角度來看,提供MySQL可執行系統指令有些不明智。因為,一旦資料庫程式有安全性上的漏洞時,危害不小,例如類似SQL Injection的安全漏洞,在未提供資料庫可執行系統指令的功能前,受到危害的範圍可能僅限於資料庫系統,但若有提供執行系統指令的管道,則當資料庫被攻陷時,攻擊者即可利用此特性直接從資料庫控制整個系統。
不過,從使用者的便利性來看,提供可直接從MySQL執行系統指令的功能,在某些情況下是相當便利的。例如監控資料庫的內容,若有符合某些樣式的資料,即以系統指令寄發一封電子郵件至管理者的信箱的工作。
利用資料庫可直接呼叫系統指令的特性,或許不必撰寫任何程式,即可達到此類目標。但要特別說明的是,在lib_mysqludf_sys說明文件中,有特別說明此程式庫尚在實驗的階段,亦即尚未完全穩定,在使用上可能會有不可預期的結果出現。
依照筆者的測試,簡單的系統指令如ls、cat等可以正常運作,但若執行自定義的程式,譬如自行撰寫的程式,有時候會造成資料庫重新啟動的現象。接下來,繼續來說明如何安裝lib_mysqludf_sys程式庫,安裝步驟如下所示。
一開始,先下載lib_mysqludf_sys相關原始碼。連結至網址「https://github.com/mysqludf/lib_mysqludf_sys/archive/master.zip」取得相關原始碼。需下載壓縮成zip格式的壓縮檔,下載回來的檔案名稱為master.zip。然後執行指令「unzip master」解壓縮lib_mysqludf_sys壓縮檔。
隨後,利用指令「cd lib_mysqludf_sys-master/」切換至「lib_mysqludf_sys」原始碼目錄內,並執行指令「gcc -Wall -I/usr/local/mysql5/include -I. -shared lib_mysqludf_sys.c -o lib_mysqludf_sys.so」編譯lib_mysqludf_sys.so程式庫。編譯成功後,會產生lib_mysqludf_sys.so檔案。
接著輸入「cp lib_mysqludf_sys.so /usr/local/mysql5/lib/plugin/」將lib_mysqludf_sys.so複製至MySQL的plugin目錄,在此為「/usr/local/mysql5/lib/plugin/」。
然後利用相關指令「mysql -u root -p [資料庫密碼]」,登入至MySQL資料庫的管理介面中。接下來有mysql>字樣的指令,即表示在MySQL的管理介面中所執行的SQL指令。
假如lib_mysqludf_sys_info函數存在,執行「mysql>DROP FUNCTION IF EXISTS lib_mysqludf_sys_info;」即可刪除該函數。如果還有sys_get、sys_set、sys_exec、sys_eval等函數存在,可依序執行指令「DROP FUNCTION IF EXISTS sys_get;」、「DROP FUNCTION IF EXISTS sys_set;」、「DROP FUNCTION IF EXISTS sys_exec;」、「DROP FUNCTION IF EXISTS sys_eval;」加以刪除,操作過程如圖3所示。
|
▲圖3 刪除已存在的函數。 |
然後,執行「CREATE FUNCTION lib_mysqludf_sys_info RETURNS string SONAME 'lib_mysqludf_sys.so';」建立lib_mysqludf_sys_info函數,該函數功能為取得版本資訊。例如指令「select lib_mysqludf_sys_info()」可以取得lib_mysqludf_sys_info的版本資訊。
再輸入指令「CREATE FUNCTION sys_get RETURNS string SONAME 'lib_mysqludf_sys.so';」建立sys_get函數,該函數功能在於取得系統變數的值。例如指令「Select sys_get('PATH')」可取得路徑變數PATH的內容值。
然後透過指令「CREATE FUNCTION sys_set RETURNS int SONAME 'lib_mysqludf_sys.so';」來建立sys_set函數,該函數功能在於設定系統變數值。譬如指令「sys_set("MYPATH","123")」可設定一系統變數MYPATH內容值為「123」。
而指令「CREATE FUNCTION sys_exec RETURNS int SONAME 'lib_mysqludf_sys.so';」可建立sys_exec函數,該函數功能在於呼叫並執行系統上的執行檔,但僅回傳執行是否成功的回傳值(零與非零值)。假如此指令執行成功,會回傳一個零值;若執行失敗,即回傳非零值。舉例來說,「select sys_exec('ls /etc/');」指令則可執行「/etc/」下的檔案列表。
執行「CREATE FUNCTION sys_eval RETURNS string SONAME 'lib_mysqludf_sys.so';」指令後,則可建立sys_eval函數,該函數功能在於呼叫並執行系統上的執行檔,並回傳該指令的結果。例如「select sys_exec('ls /etc/');」指令將執行「/etc/」目錄下的檔案列表,假如此指令執行成功,即會回傳在「/etc」目錄下的檔案列表,指令執行過程如圖4所示。
|
▲圖4 新建相關的函數。 |