全部產品
Search
文件中心

ApsaraDB RDS:SQL防火牆(sql_firewall)

更新時間:Jun 19, 2024

SQL防火牆是資料庫層面的防火牆功能,可以防止惡意SQL注入。可以用來學習一些定義好的SQL規則,並將這些規則儲存在資料庫中作為白名單,學習完成後,可以限制使用者執行這些定義規則之外的風險操作。

前提條件

RDS PostgreSQL執行個體需為以下版本之一:
  • PostgreSQL 12
  • PostgreSQL 11
  • PostgreSQL 10
重要 RDS PostgreSQL已不再支援sql_firewall外掛程式,雖然之前已經建立的外掛程式仍可使用,但是由於使用該外掛程式可能導致系統崩潰,我們建議您儘早停止使用,以避免潛在風險。

如果您想要移除sql_firewall外掛程式,可以使用drop extension sql_firewall;語句卸載此外掛程式,並在shared_preload_libraries參數中移除它,具體修改參數方法,請參見設定執行個體參數

學習模式、預警模式與防火牆模式

流程圖

SQL防火牆支援如下三種模式:

  • 學習模式:防火牆記錄使用者執行的SQL,並添加到常用SQL白名單。
  • 預警模式:防火牆對使用者將執行的SQL進行判斷,如果SQL不在白名單中,仍然會執行該SQL,但是會警示使用者該SQL不在白名單中。
  • 防火牆模式:防火牆對使用者將執行的SQL進行判斷,如果SQL不在白名單中,防火牆會拒絕執行該SQL並返回錯誤提示。

SQL防火牆的使用步驟

  1. 開啟防火牆的學習模式,讓防火牆記錄使用者執行的SQL,並加入白名單。這個過程建議持續一段較長的時間,盡量讓防火牆學習到所有可能執行的SQL。
  2. 切換防火牆為預警模式,這個過程防火牆會對使用者的一些不在白名單的SQL進行警示,使用者結合自己的業務判斷是否為風險SQL,如果這些SQL確實是使用者需要的業務語句,則記錄這些SQL,之後開啟學習模式進行二次學習。
  3. 經過前兩步,使用者常用SQL已經被記錄完畢,開啟防火牆模式,此時不在白名單的SQL均會被拒絕執行。

操作說明

  • 建立外掛程式
    create extension sql_firewall;
  • 刪除外掛程式
    drop extension sql_firewall;
  • 切換模式

    在控制台找到sql_firewall.firewall參數,修改參數值並重啟執行個體。詳情請參見設定執行個體參數

    sql_firewall.firewall取值如下:

    • disable:關閉SQL防火牆
    • learning:學習模式
    • permissive:預警模式
    • enforcing:防火牆模式
  • 功能函數
    • sql_firewall_reset()

      清空白名單。該函數只有在防火牆關閉模式下,rds_superuser許可權的使用者可執行該函數。

    • sql_firewall_stat_reset()

      清空統計資訊。該函數只有在防火牆關閉模式下,rds_superuser許可權的使用者可執行該函數。

  • 視圖函數
    • sql_firewall.sql_firewall_statements

      展示目前資料庫中所有的白名單及其被調用的次數。

      postgres=# select * from sql_firewall.sql_firewall_statements;
           userid |  queryid   |              query              | calls
          --------+------------+---------------------------------+-------
               10 | 3294787656 | select * from k1 where uid = ?; |     4
          (1 row)
    • sql_firewall.sql_firewall_stat

      展示預警模式下的警告數量(sql_warning)和防火牆模式下的錯誤數量(sql_error)。

      postgres=# select * from sql_firewall.sql_firewall_stat;
           sql_warning | sql_error
          -------------+-----------
                     2 |         1
          (1 row)

樣本

--預警模式

    postgres=# select * from sql_firewall.sql_firewall_statements;
    WARNING:  Prohibited SQL statement
     userid |  queryid   |              query              | calls
    --------+------------+---------------------------------+-------
         10 | 3294787656 | select * from k1 where uid = 1; |     1
    (1 row)

    postgres=# select * from k1 where uid = 1;
     uid |    uname
    -----+-------------
       1 | Park Gyu-ri
    (1 row)

    postgres=# select * from k1 where uid = 3;
     uid |   uname
    -----+-----------
       3 | Goo Ha-ra
    (1 row)

    postgres=# select * from k1 where uid = 3 or 1 = 1;
    WARNING:  Prohibited SQL statement
     uid |     uname
    -----+----------------
       1 | Park Gyu-ri
       2 | Nicole Jung
       3 | Goo Ha-ra
       4 | Han Seung-yeon
       5 | Kang Ji-young
    (5 rows)

--防火牆模式

    postgres=# select * from k1 where uid = 3;
     uid |   uname
    -----+-----------
       3 | Goo Ha-ra
    (1 row)

    postgres=# select * from k1 where uid = 3 or 1 = 1;
    ERROR:  Prohibited SQL statement
    postgres=#