Redis 安全概述
Redis 是一個高效能的記憶體鍵值資料庫,廣泛應用於快取、訊息佇列和即時資料處理。然而,預設安裝的 Redis 並未針對安全性進行最佳化,這使得它容易成為攻擊目標。本文將介紹如何在 Ubuntu 22.04 上對 Redis 進行全面的安全加固。
常見的 Redis 安全風險
- 未授權存取:預設情況下 Redis 不需要認證
- 危險指令暴露:如
FLUSHALL、CONFIG 等可能被濫用 - 明文傳輸:資料在網路上以明文形式傳輸
- 權限過高:以 root 身份執行增加安全風險
綁定特定介面
預設情況下,Redis 可能會監聽所有網路介面。為了減少攻擊面,應該只綁定必要的介面。
編輯 Redis 設定檔:
1
| sudo nano /etc/redis/redis.conf
|
修改 bind 參數,只允許本機連線:
1
2
3
4
5
| # 只允許本機連線
bind 127.0.0.1 ::1
# 如果需要允許特定內網 IP
# bind 127.0.0.1 192.168.1.100
|
同時停用保護模式外的連線:
重新啟動 Redis 使設定生效:
1
| sudo systemctl restart redis-server
|
設定認證密碼
為 Redis 設定強密碼是最基本的安全措施。
在 /etc/redis/redis.conf 中設定密碼:
1
2
| # 設定一個強密碼(建議至少 32 個字元)
requirepass your_very_strong_password_here_at_least_32_chars
|
產生強密碼的方式:
1
2
| # 使用 OpenSSL 產生隨機密碼
openssl rand -base64 32
|
連線時使用密碼認證:
1
2
3
4
5
6
| # 方式一:連線後認證
redis-cli
AUTH your_very_strong_password_here_at_least_32_chars
# 方式二:連線時直接認證
redis-cli -a your_very_strong_password_here_at_least_32_chars
|
ACL 存取控制
Redis 6.0 引入了 ACL(Access Control List)功能,可以建立多個使用者並設定細緻的權限。
建立 ACL 使用者
在 /etc/redis/redis.conf 中新增 ACL 規則:
1
2
3
4
5
6
7
8
9
10
11
| # 停用預設使用者
user default off
# 建立管理員使用者(完整權限)
user admin on >admin_strong_password ~* &* +@all
# 建立唯讀使用者
user readonly on >readonly_password ~* &* +@read -@dangerous
# 建立應用程式使用者(限制特定 key 模式)
user appuser on >app_password ~app:* &* +@read +@write -@dangerous
|
ACL 規則說明
| 規則 | 說明 |
|---|
on/off | 啟用/停用使用者 |
>password | 設定密碼 |
~pattern | 允許存取的 key 模式 |
+@category | 允許的指令類別 |
-@category | 禁止的指令類別 |
使用外部 ACL 檔案
建立 /etc/redis/users.acl:
1
2
3
| user admin on >admin_password ~* &* +@all
user readonly on >readonly_password ~* &* +@read
user appuser on >app_password ~app:* &* +@read +@write -@dangerous
|
在 redis.conf 中引用:
1
| aclfile /etc/redis/users.acl
|
停用危險指令
某些 Redis 指令可能被用於攻擊,應該停用或重新命名。
在 /etc/redis/redis.conf 中新增:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # 完全停用危險指令
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command KEYS ""
rename-command CONFIG ""
rename-command DEBUG ""
rename-command SHUTDOWN ""
rename-command SLAVEOF ""
rename-command REPLICAOF ""
rename-command MIGRATE ""
rename-command RESTORE ""
rename-command EVAL ""
rename-command SCRIPT ""
# 或者重新命名為難以猜測的名稱
# rename-command CONFIG "CONFIG_a1b2c3d4e5f6"
|
注意:停用 CONFIG 指令後,將無法在執行期間動態修改設定。
TLS 加密連線
從 Redis 6.0 開始原生支援 TLS 加密。
產生憑證
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # 建立憑證目錄
sudo mkdir -p /etc/redis/tls
cd /etc/redis/tls
# 產生 CA 憑證
sudo openssl genrsa -out ca.key 4096
sudo openssl req -x509 -new -nodes -sha256 -key ca.key -days 3650 -out ca.crt -subj "/CN=Redis-CA"
# 產生伺服器憑證
sudo openssl genrsa -out redis.key 2048
sudo openssl req -new -key redis.key -out redis.csr -subj "/CN=redis-server"
sudo openssl x509 -req -in redis.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out redis.crt -days 365 -sha256
# 設定權限
sudo chown redis:redis /etc/redis/tls/*
sudo chmod 600 /etc/redis/tls/*.key
|
設定 Redis TLS
在 /etc/redis/redis.conf 中新增:
1
2
3
4
5
6
7
8
9
10
11
12
13
| # 啟用 TLS
tls-port 6379
port 0
# 憑證路徑
tls-cert-file /etc/redis/tls/redis.crt
tls-key-file /etc/redis/tls/redis.key
tls-ca-cert-file /etc/redis/tls/ca.crt
# TLS 設定
tls-auth-clients optional
tls-protocols "TLSv1.2 TLSv1.3"
tls-ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
|
TLS 連線測試
1
| redis-cli --tls --cacert /etc/redis/tls/ca.crt -h 127.0.0.1 -p 6379
|
防火牆設定
使用 UFW 限制對 Redis 的存取。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 啟用 UFW
sudo ufw enable
# 只允許本機連線 Redis
sudo ufw allow from 127.0.0.1 to any port 6379
# 如果需要允許特定 IP
sudo ufw allow from 192.168.1.0/24 to any port 6379
# 拒絕其他所有 Redis 連線
sudo ufw deny 6379
# 檢視規則
sudo ufw status numbered
|
如果使用 iptables:
1
2
3
4
5
6
| # 只允許本機
sudo iptables -A INPUT -i lo -p tcp --dport 6379 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 6379 -j DROP
# 儲存規則
sudo netfilter-persistent save
|
以非 root 執行
確保 Redis 以專用的低權限使用者執行。
1
2
3
4
5
6
7
8
9
| # 確認 Redis 使用者存在
id redis
# 確認服務以 redis 使用者執行
ps aux | grep redis-server
# 檢查檔案權限
ls -la /var/lib/redis/
ls -la /var/log/redis/
|
修正權限(如有需要):
1
2
3
4
5
6
7
8
| # 設定正確的擁有者
sudo chown -R redis:redis /var/lib/redis
sudo chown -R redis:redis /var/log/redis
sudo chown redis:redis /etc/redis/redis.conf
# 設定正確的權限
sudo chmod 750 /var/lib/redis
sudo chmod 640 /etc/redis/redis.conf
|
在 systemd 服務檔案中確認:
1
2
3
4
| sudo cat /lib/systemd/system/redis-server.service | grep -E "User|Group"
# 應該顯示:
# User=redis
# Group=redis
|
監控與稽核
啟用日誌記錄
在 /etc/redis/redis.conf 中設定:
1
2
3
4
5
6
7
8
9
| # 設定日誌等級
loglevel notice
# 設定日誌檔案
logfile /var/log/redis/redis-server.log
# 啟用慢查詢日誌
slowlog-log-slower-than 10000
slowlog-max-len 128
|
監控指令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 即時監控所有指令(僅用於除錯)
redis-cli MONITOR
# 查看慢查詢
redis-cli SLOWLOG GET 10
# 查看連線資訊
redis-cli CLIENT LIST
# 查看記憶體使用
redis-cli INFO memory
# 查看統計資訊
redis-cli INFO stats
|
設定 Logrotate
建立 /etc/logrotate.d/redis-server:
1
2
3
4
5
6
7
8
9
10
11
12
| /var/log/redis/redis-server.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 640 redis redis
postrotate
/bin/kill -USR1 $(cat /var/run/redis/redis-server.pid 2>/dev/null) 2>/dev/null || true
endscript
}
|
安全檢查清單
完成加固後,請確認以下項目:
參考資料