標籤:
MySQL資料庫一貫以高效能、高可性和易用性著稱,它已經成為世界上最流行的開來源資料庫。大量的個人、WEB開發人員、大型公司等都在其網站、關鍵系統、軟體包中廣泛使用MySQL資料庫。 通常,許多企業在部署一種產品時,安全性常常得不到應有的重視。企業最關心的是使其可以儘快地運行,企業由此也可以儘快贏利。有的企業在安裝MySQL時用的是預設選項,由此造成其資料不安全,且伺服器也臨被入侵的風險,並有可能在短時間內就出現效能問題。下面將提供保障MySQL安全的最佳方法。
1、避免從互連網訪問MySQL資料庫,確保特定主機才擁有存取權限 直接通過本網之外的電腦改變生產環境中的資料庫是異常危險的。有時,管理員會開啟主機對資料庫的訪問: > GRANT ALL ON *.* TO ‘root‘@‘%‘; 這其實是完全放開了對root的訪問。所以,把重要的操作限制給特定主機非常重要: > GRANT ALL ON *.* TO ‘root‘@‘localhost‘; > GRANT ALL ON *.* TO ‘root‘@‘myip.athome‘ > FLUSH PRIVILEGES 此時,你仍有完全的訪問,但只有指定的IP(不管其是否靜態)可以訪問。
2、定期備份資料庫 任何系統都有可能發生災難。伺服器、MySQL也會崩潰,也有可能遭受入侵,資料有可能被刪除。只有為最糟糕的情況做好了充分的準備,才能夠在事後快速地從災難中恢複。企業最好把備份過程作為伺服器的一項日常工作。
3、禁用或限制遠端存取 前面說過,如果使用了遠端存取,要確保只有定義的主機才可以訪問伺服器。這一般是通過TCP wrappers、iptables或任何其它的防火牆軟體或硬體實現的。 為限制開啟網路socket,管理員應當在my.cnf或my.ini的[mysqld]部分增加下面的參數: skip-networking 這些檔案位於windows的C:\Program Files\MySQL\MySQL Server 5.1檔案夾中,或在Linux中,my.cnf位於/etc/,或位於/etc/mysql/。這行命令在MySQL啟動期間,禁用了網路連接的初始化。請注意,在這裡仍可以建立與MySQL伺服器的本地串連。 另一個可行的方案是,強迫MySQL僅監聽本機,方法是在my.cnf的[mysqld]部分增加下面一行: bind-address=127.0.0.1 如果企業的使用者從自己的機器串連到伺服器或安裝到另一台機器上的web伺服器,你可能不太願意禁用網路訪問。此時,不妨考慮下面的有限許可訪問: mysql> GRANT SELECT, INSERT ON mydb.* TO ‘someuser‘@‘somehost‘; 這裡,你要把someuser換成使用者名稱,把somehost換成相應的主機。
4、設定root使用者的口令並改變其登入名稱 在linux中,root使用者擁有對所有資料庫的完全訪問權。因而,在Linux的安裝過程中,一定要設定root口令。當然,要改變預設的空口令,其方法如下: Access MySQL控制台:$ mysql -u root -p 在MySQL控制台中執行: > SET PASSWORD FOR ‘root‘@‘localhost‘ = PASSWORD(‘new_password‘); 在實際操作中,只需將上面一行的new_password換成實際的口令即可。 在Linux控制台中更改root口令的另一種方法是使用mysqladmin工具: $ mysqladmin -u root password new_password 此時,也是將上面一行的new_password換成實際的口令即可。 當然,這是需要使用強口令來避免強力攻擊。 為了更有效地改進root使用者的安全性,另一種好方法是為其改名。為此,你必須更新表使用者中的mySQL資料庫。在MySQL控制台中進行操作: > USE mysql; > UPDATE user SET user="another_username" WHERE user="root"; > FLUSH PRIVILEGES; 然後,通過Linux訪問MySQL控制台就要使用新使用者名稱了: $ mysql -u another_username -p
5、移除測試(test)資料庫 在預設安裝的MySQL中,匿名使用者可以訪問test資料庫。我們可以移除任何無用的資料庫,以避免在不可預料的情況下訪問了資料庫。因而,在MySQL控制台中,執行: > DROP DATABASE test;
6、禁用LOCAL INFILE 另一項改變是禁用”LOAD DATA LOCAL INFILE”命令,這有助於防止非授權使用者訪問本地檔案。在PHP應用程式中發現有新的SQL注入漏洞時,這樣做尤其重要。 此外,在某些情況下,LOCAL INFILE命令可被用於訪問作業系統上的其它檔案(如/etc/passwd),應使用下現的命令: mysql> LOAD DATA LOCAL INFILE ‘/etc/passwd‘ INTO TABLE table1 更簡單的方法是: mysql> SELECT load_file("/etc/passwd") 為禁用LOCAL INFILE命令,應當在MySQL設定檔的[mysqld]部分增加下面的參數: set-variable=local-infile=0
7、移除匿名賬戶和廢棄的賬戶 有些MySQL資料庫的匿名使用者的口令為空白。因而,任何人都可以串連到這些資料庫。可以用下面的命令進行檢查: mysql> select * from mysql.user where user=""; 在安全的系統中,不會返回什麼資訊。另一種方法是: mysql> SHOW GRANTS FOR ‘‘@‘localhost‘; mysql> SHOW GRANTS FOR ‘‘@‘myhost‘; 如果grants存在,那麼任何人都可以訪問資料庫,至少可以使用預設的資料庫“test”。其檢查方法如下: shell> mysql -u blablabla 如果要移除賬戶,則執行命令: mysql> DROP USER ""; 從MySQL的5.0版開始支援DROP USER命令。如果你使用的老版本的MySQL,你可以像下面這樣移除賬戶: mysql> use mysql; mysql> DELETE FROM user WHERE user=""; mysql> flush privileges;
8、降低系統特權 常見的資料庫安全建議都有“降低給各方的特權”這一說法。對於MySQL也是如此。一般情況下,開發人員會使用最大的許可,不像安全管理一樣考慮許可原則,而這樣做會將資料庫暴露在巨大的風險中。 為保護資料庫,務必保證真正儲存MySQL資料庫的檔案目錄是由”mysql” 使用者和” mysql”組所擁有的。 shell>ls -l /var/lib/mysql 此外,還要確保僅有使用者”mysql”和root使用者可以訪問/var/lib/mysql目錄。 Mysql的二進位檔案存在於/usr/bin/目錄中,它應當由root使用者或特定的”mysql”使用者所擁有。對這些檔案,其它使用者不應當擁有“寫”的訪問權: shell>ls -l /usr/bin/my*
9、降低使用者的資料庫特權 有些應用程式是通過一個特定資料庫表的使用者名稱和口令串連到MySQL的,安全人員不應當給予這個使用者完全的訪問權。 如果攻擊者獲得了這個擁有完全訪問權的使用者,他也就擁有了所有的資料庫。查看一個使用者許可的方法是在MySQL控制台中使用命令SHOW GRANT >SHOW GRANTS FOR ‘user‘@‘localhost‘; 為定義使用者的訪問權,使用GRANT命令。在下面的例子中,user1僅能從dianshang資料庫的billing表中選擇: > GRANT SELECT ON billing.dianshang TO ‘user1‘@‘localhost‘; > FLUSH PRIVILEGES; 如此一來,user1使用者就無法改變資料庫中這個表和其它表的任何資料。 另一方面,如果你要從一個使用者移除訪問權,就應使用一個與GRANT命令類似的REVOKE命令: > REVOKE SELECT ON billing.ecommerce FROM ‘user1‘@‘localhost‘; > FLUSH PRIVILEGES;
10、移除和禁用.mysql_history檔案 在使用者訪問MySQL控制台時,所有的命令曆史都被記錄在~/.mysql_history中。如果攻擊者訪問這個檔案,他就可以知道資料庫的結構。 $ cat ~/.mysql_history 為了移除和禁用這個檔案,應將日誌發送到/dev/null。 $export MYSQL_HISTFILE=/dev/null 上述命令使所有的記錄檔都定向到/dev/null,你應當從home檔案夾移除.mysql_history:$ rm ~/.mysql_history,並建立一個到/dev/null的符號連結。
11、安全補丁 務必保持資料庫為最新版本。因為攻擊者可以利用上一個版本的已知漏洞來訪問企業的資料庫。
12、啟用日誌 如果你的資料庫伺服器並不執行任何查詢,建議你啟用追蹤記錄,你可以通過在/etc/my.cnf檔案的[Mysql]部分添加:log =/var/log/mylogfile。 對於生產環境中任務繁重的MySQL資料庫,因為這會引起伺服器的高昂成本。 此外,還要保證只有root和mysql可以訪問這些記錄檔。 錯誤記錄檔 務必確保只有root和mysql可以訪問hostname.err記錄檔。該檔案存放在mysql資料曆史中。該檔案包含著非常敏感的資訊,如口令、地址、表名、預存程序名、代碼等,它可被用於資訊收集,並且在某些情況下,還可以向攻擊者提供利用資料庫漏洞的資訊。攻擊者還可以知道安裝資料庫的機器或內部的資料。 MySQL日誌 確保只有root和mysql可以訪問logfileXY記錄檔,此檔案存放在mysql的曆史目錄中。
13、改變root目錄 Unix作業系統中的chroot可以改變當前正在啟動並執行進程及其子進程的root目錄。重新獲得另一個目錄root許可權的程式無法訪問或命名此目錄之外的檔案,此目錄被稱為“chroot監獄”。 通過利用chroot環境,你可以限制MySQL進程及其子進程的寫操作,增加伺服器的安全性。 你要保證chroot環境的一個專用目錄,如/chroot/mysql。此外,為了方便利用資料庫的管理工具,你可以在MySQL設定檔的[client]部分改變下面的參數: [client] socket = /chroot/mysql/tmp/mysql.sock
14、禁用LOCAL INFILE命令 LOAD DATA LOCAL INFILE可以從檔案系統中讀取檔案,並顯示在螢幕中或儲存在資料庫中。如果攻擊者能夠從應用程式找到SQL注入漏洞,這個命令就相當危險了。下面的命令可以從MySQL控制台進行操作: > SELECT LOAD_FILE("/etc/passwd"); 該命令列示了所有的使用者。解決此問題的最佳方法是在MySQL配置中禁用它,在CentOS中找到/etc/my.cnf或在Ubuntu中找到/etc/mysql/my.cnf,在[mysqld]部分增加下面一行:set-variable=local-infile=0。搞定。 當然,唇亡齒寒,保護伺服器的安全對於保障MySQL資料庫的安全也是至關重要的。伺服器的安全對於資料庫來說可謂生死攸關。
保障MySQL安全的14個最佳方法