如何在 Redis 或 ElastiCache Redis 禁用部份高風險的命令? (How to disable high risk commands on Redis?)

多許多高複雜度的命令(例如 KEYS)、或是高風險的命令(例如 CONFIG, FLUSHDB, FLUSHALL),而導致您的 Redis 集群在處於風險的狀況下,您不會知道那一天您的開發人員,不小心刪庫挖坑,所以您可以考慮在 redis.conf 中、或是在 ElastiCache Redis 參數組中,調整 rename-command 配置,來對這些風險的命令做更名的動作。

Jerry’s Notes
What’s next?
4 min readSep 13, 2023

--

首先在 Redis security[+] 有提及關於 “Disallowing specific commands” 如何去調整。

[+] Redis security | Redis:
https://redis.io/docs/management/security/

Disallowing specific commands

It is possible to disallow commands in Redis or to rename them as an unguessable name, so that normal clients are limited to a specified set of commands.

In this case, it is possible to either rename or completely shadow commands from the command table. This feature is available as a statement that can be used inside the redis.conf configuration file.

For example:
rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52

調整方式,就是在 redis.conf 檔中,去調整 “rename-command” 配置。

[+] Redis configuration file example:
https://redis.io/docs/management/config-file/

# Redis configuration file example.
#
# Note that in order to read the configuration file, Redis must be
# started with the file path as first argument:
#
# ./redis-server /path/to/redis.conf
...
# It is possible to change the name of dangerous commands in a shared
# environment. For instance the CONFIG command may be renamed into something
# hard to guess so that it will still be available for internal-use tools
# but not available for general clients.
#
# Example:
#
# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
#
# It is also possible to completely kill a command by renaming it into
# an empty string:
#
# rename-command CONFIG ""

ElastiCache for Redis 5.0.3 以後的版本,您可以透過調整參數 “ rename-commands”,來達到這個目的。

[+] Amazon ElastiCache for Redis 新增 Redis 5.0.3 支援以及 Redis 命令名稱的變更能力:
https://aws.amazon.com/tw/about-aws/whats-new/2019/02/amazon-elasticache-for-redis-adds-support-for-redis-503-and-the-ability-to-change-redis-command-names/

隨著 Redis 5.0.3 的推出,我們現在支援 Redis命令名稱的變更功能。
您可以利用名為 rename-commands 的新參數,該參數允許您將命令重新命名為使用者指定的名稱,
並防止誤用可能具有侵入性或耗費成本的命令。

Amazon ElastiCache for Redis 可確保命令名稱的變更,
會以線上方式立即傳播到叢集中的所有節點,無需手動干預。

此外,命令名稱的變更會在節點重新啟動和替換時保持不變,從而提供全受管的體驗。

參數 — rename-commands 說明如下。

[+] Redis 特定的参数 — Redis 5.0.3 参数更改:
https://docs.aws.amazon.com/zh_cn/AmazonElastiCache/latest/red-ug/ParameterGroups.Redis.html#ParameterGroups.Redis.5-0-3

rename-commands 
默认值:无
类型:字符串
可修改:是
更改生效:立即跨集群中的所有节点生效
描述: 重命名的 Redis 命令列表,以空格分隔。以下是可用于重命名的命令的限制列表: <----
KEYS FLUSHALL FLUSHDB ...

ElastiCache Redis 對於每個一版本的 Redis Engine 提供不同的 “預設參數組”,而該預設參數組是無法直接修改的,不過您可以透過 “創建參數組” 來複制 “預設參數組” 的內容,再去針對特定參數進行修改。

[+] Redis 專用參數:
https://docs.aws.amazon.com/zh_tw/AmazonElastiCache/latest/red-ug/ParameterGroups.Redis.html
---
您無法變更預設參數群組中任何參數的值。
---

[+] 建立參數群組:
https://docs.aws.amazon.com/zh_tw/AmazonElastiCache/latest/red-ug/ParameterGroups.Creating.html
---
若您希望修改不同於預設值的一或多個參數值,便需要建立新的參數群組。
---

第一步: 建立一個新的參數群組,如下圖,請選擇您目前 Redis 集群所運行的版本。

第二步: 調整參數 rename-commands 中的配置,若您有多個操作要更名,請您用 "空白" 當間隔。

以下範例是調整兩個命令 (例如: FLUSHALL 及 FLUSHDB)。

rename-commands: FLUSHALL flushalldisables FLUSHDB flushdbdisables

第三步: 將這一個參數組,套用在您運行中的 Redis 集群。

!!! 調整 rename-commands 參數,不會對您當前操作或是連線造成影響。

以下為測試記錄:

$ redis-cli -h single.xxx.usw2.cache.amazonaws.com
> set key 111
OK
> get key
"111"
> flushall
(error) ERR unknown command `flushall`, with args beginning with:
> flushdb
(error) ERR unknown command `flushdb`, with args beginning with:
> flushalldisables
OK
> flushdbdisables
OK
> get key
(nil)

以下是參考資料。

[+] KEYS | Redis:
https://redis.io/commands/keys/

Time complexity:
O(N) with N being the number of keys in the database, under the assumption that the key names in the database and the given pattern have limited length.

Warning: consider KEYS as a command that should only be used in production environments with extreme care. It may ruin performance when it is executed against large databases. This command is intended for debugging and special operations, such as changing your keyspace layout. Don’t use KEYS in your regular application code. If you’re looking for a way to find keys in a subset of your keyspace, consider using SCAN or sets.

!!! 由於 Redis 原生是 “單執行序” 的服務,所以每一個命令是 “一個一個” 依序來執行,所以當客戶端(Redis Client)在短時間內、大量讀寫的動作時、或是執行高複雜度命令(例如您執行的 KEYS 命令)時,就容易造成操作延遲上升的狀況發生。

[+] FLUSHALL | Redis:
https://redis.io/commands/flushall/

Delete all the keys of all the existing databases, not just the currently selected one. This command never fails.

!!! FLUSHALL 是清空 “整個” Redis 服務器的數。

[+] FLUSHDB | Redis:
https://redis.io/commands/flushdb/

Delete all the keys of the currently selected DB. This command never fails.

!!! FLUSHDB 這個命令用於清空 “當前” 數據庫中的所有 key。

[+] Redis危险命令重命名、禁用_一世琥珀色的博客-CSDN博客:
https://blog.csdn.net/WeiXin_zjmgly/article/details/53692106

Redis的危險命令主要有:
* flushdb,清空數據庫
* flushall,清空所有記錄,數據庫
* config,客戶端連接後可配置服務器
* keys,客戶端連接後可查看所有存在的鍵

[+] 一个致命的Redis命令,导致公司损失400万!! — 知乎:
https://zhuanlan.zhihu.com/p/45665153

什么样的Redis命令会有这么威力,造成这么大的损失?

具体消息如下:

据云头条报道,某公司技术部本年度发生2起PO级特大事故,造成公司资金损失400万,原因如下:

由于PHP工程师直接操作上线redis,执行键* wxdb(此处按下)cf8 *这样的命令,导致redis锁住,导致CPU高峰,导致所有支付队列卡住,等十几秒结束后,所有的请求流量全部挤压到了rds数据库中,使数据库产生了雪崩效应,发生了数据库宕机事件。

该公司表示,如再犯类似事故,将直接开除,并表示此后会追回运维部各项权限。

!!! 上面案例,應後是使用 KEYS 命令,去掃所有符合 *wxdb 的鍵值,而這個動作會去掃 “整個” Redis 內所有符合的數據,當數據量越高,影響就越長。

--

--

Jerry’s Notes
What’s next?

An cloud support engineer focus on troubleshooting with customer reported issue ,and cloud solution architecture.