介紹
Redis是一個開源的、內存鍵值數據存儲庫,擅長於緩存。Redis是一個非關聯型數據庫,以其靈活性、性能、可擴展性和廣泛的語言支持而聞名。
Redis設計用於在可信的環境中由可信客戶端使用,並且沒有自己的強大安全功能。然而,Redis確實具有一些安全功能,如密碼驗證和重命名或禁用某些命令的能力。本教程提供了有關如何安裝Redis並配置這些安全功能的說明。它還涵蓋了一些其他可以增強Rocky Linux 8獨立Redis安裝安全性的設置。
請注意,本指南不涉及Redis服務器和客戶端應用程序位於不同主機或不同數據中心的情況。需要在Redis流量必須穿越不安全或不受信任的網絡的安裝將需要一組不同的配置,例如設置SSL代理或在Redis機器之間建立VPN。
您也可以使用DigitalOcean的托管Redis服務。
先决条件
要完成本教程,您需要运行Rocky Linux 8的服务器。该服务器应具有具有管理员权限的非根用户,并配置了使用firewalld
的防火墙。要设置此项,请参照我们的Rocky Linux 8初始服务器设置指南。
步骤1 — 安装并启动Redis
您可以使用DNF软件包管理器安装Redis。使用DNF,您可以安装Redis及其依赖项,以及用户友好的文本编辑器nano
。您不必安装nano
,但我们将在整个指南中使用它作为示例:
- sudo dnf install redis nano
此命令将提示您确认是否要安装所选软件包。按y
然后按ENTER
以执行:
Output. . .
Total download size: 1.5 M
Installed size: 5.4 M
Is this ok [y/N]: y
随后,在Redis配置文件中自动生成的情况下,需要进行一项重要的配置更改。
使用您喜欢的文本编辑器打开此文件。在这里,我们将使用nano
:
- sudo nano /etc/redis.conf
在文件中找到supervised
指令。该指令允许您声明一个init系统来管理Redis作为一个服务,从而提供对其操作的更多控制。默认情况下,supervised
指令设置为no
。由于您正在运行使用systemd init系统的Rocky Linux,请将其更改为systemd
:
. . .
# 如果您从upstart或systemd运行Redis,Redis可以与您的
# 监控树进行交互。选项:
# supervised no - 没有监控交互
# supervised upstart - 通过将Redis放入SIGSTOP模式来通知upstart
# supervised systemd - 通过向$NOTIFY_SOCKET写入READY=1来通知systemd
# supervised auto - 基于
# UPSTART_JOB或NOTIFY_SOCKET环境变量来检测upstart或systemd方法
# 注意:这些监控方法只会发送"进程就绪"的信号。
# 它们不会启用连续的活跃性检查。
supervised systemd
. . .
这是您在Redis配置文件中需要进行的唯一更改,完成后保存并关闭它。如果您使用nano
编辑文件,则可以使用CTRL + X
保存并退出,然后在提示时输入Y
,然后按Enter键。
编辑文件后,启动Redis服务:
- sudo systemctl start redis.service
如果您希望Redis在启动时启动,可以使用enable
命令启用它:
- sudo systemctl enable redis
請注意,此命令在單元檔名後面不包括.service
字尾。通常情況下,你可以在systemctl
命令中省略這個字尾,因為它可以從服務名稱中自動解析出來。
你可以執行以下命令來檢查 Redis 的狀態:
- sudo systemctl status redis
Output● redis.service - Redis persistent key-value database
Loaded: loaded (/usr/lib/systemd/system/redis.service; enabled; vendor preset: disabled)
Drop-In: /etc/systemd/system/redis.service.d
└─limit.conf
Active: active (running) since Tue 2022-09-06 22:11:52 UTC; 40s ago
Main PID: 14478 (redis-server)
Tasks: 4 (limit: 11152)
Memory: 6.6M
CGroup: /system.slice/redis.service
└─14478 /usr/bin/redis-server 127.0.0.1:6379
確認 Redis 確實正在運行後,你可以使用以下命令來測試其功能:
- redis-cli ping
這應該會將PONG
作為回應打印出來:
OutputPONG
如果是這種情況,這意味著你的服務器上現在正在運行 Redis,你可以開始配置它以增強安全性。
第2步 – 配置 Redis 並通過防火牆保護它
保護 Redis 的一種有效方法是確保它只綁定到本地主機或私有 IP 地址,並且服務器上運行著防火牆。
然而,如果你選擇使用其他教程來設置 Redis,則可能已經更新了配置文件以允許從任何地方進行連接。這不如綁定到本地主機或私有 IP 安全。
為了解決這個問題,再次使用你偏好的文本編輯器打開 Redis 配置文件:
- sudo nano /etc/redis.conf
請定位以bind
開頭的行,並確保它未被註解掉或停用,必要時刪除行首的#
符號:
. . .
bind 127.0.0.1
如果您需要將 Redis 綁定到另一個 IP 地址(例如您將從另一台主機訪問 Redis 的情況),您應該強烈考慮將其綁定到私有 IP 地址。將其綁定到公共 IP 地址會增加 Redis 介面對外部方的暴露:
. . .
bind your_private_ip
確認bind
指令未被註解掉後,您可以保存並關閉文件。
如果您已經按照先決條件的「初始伺服器設置教程」並在您的伺服器上安裝了 firewalld,而且您不打算從其他主機連接到 Redis,那麼您不需要為 Redis 添加任何額外的防火牆規則。畢竟,除非防火牆規則明確允許,否則所有傳入流量都將默認被拒絕。由於默認獨立安裝的 Redis 伺服器僅在回送介面(127.0.0.1
或 localhost)上監聽,因此對其默認端口的傳入流量不應引起擔憂。
然而,如果您打算從其他主機訪問 Redis,則需要使用firewall-cmd
命令對您的 firewalld 配置進行一些更改。同樣,您應該只允許從您的主機訪問您的 Redis 伺服器,方法是使用它們的私有 IP 地址,以限制您的服務暴露給的主機數量。
首先,將一個專用的 Redis 區域添加到您的 firewalld 策略中:
- sudo firewall-cmd --permanent --new-zone=redis
然後指定要開啟的端口。 Redis 默認使用端口 6379
:
- sudo firewall-cmd --permanent --zone=redis --add-port=6379/tcp
接下來,指定允許通過防火牆並訪問 Redis 的任何私有 IP 地址:
- sudo firewall-cmd --permanent --zone=redis --add-source=client_server_private_IP
運行這些命令後,重新加載防火牆以實施新規則:
- sudo firewall-cmd --reload
在此配置下,當防火牆遇到來自客戶端 IP 地址的封包時,它將對該連接應用專用 Redis 區域中的規則。所有其他連接將由默認的 public
區域處理。默認區域中的服務適用於每個連接,而不僅僅是那些不明確匹配的連接,因此您無需將其他服務(例如 SSH)添加到 Redis 區域,因為這些規則將自動應用於該連接。
請記住,使用任何防火牆工具都將起作用,無論您使用的是 firewalld
、ufw
還是 iptables
。重要的是防火牆是啟動並運行的,以便未知個體無法訪問您的服務器。在下一步中,您將配置 Redis 僅通過強密碼可訪問。
步驟 3 — 配置 Redis 密碼
配置 Redis 密碼啟用其中一個內建的安全功能 – `auth` 命令 – 這要求客戶端在被允許訪問資料庫之前進行身份驗證。就像 `bind` 設置一樣,密碼直接配置在 Redis 的配置文件中,即 `/etc/redis.conf`。重新打開該文件:
- sudo nano /etc/redis.conf
滾動到 `SECURITY` 部分,查找一個被註釋的指令,其內容為:
. . .
# requirepass foobared
刪除註釋 `#`,將 `foobared` 更改為您選擇的非常強大的密碼。
注意: 與其自己創造一個密碼,您可以使用像 `apg` 或 `pwgen` 這樣的工具來生成一個。如果您不想安裝應用程序來生成密碼,您可以使用以下命令。此命令回顯字符串值並將其管道到下面的 `sha256sum` 命令中,該命令將顯示字符串的 SHA256 校驗和。
請注意,按照原樣輸入此命令將每次生成相同的密碼。為了創建一個唯一的密碼,將引號中的字符串更改為任何其他單詞或短語:
- echo "digital-ocean" | sha256sum
儘管生成的密碼可能不容易記住,但它將非常強大和長,這正是 Redis 需要的密碼類型。在將該命令的輸出複製並粘貼為 `requirepass` 的新值之後,它應該顯示:
. . .
requirepass password_copied_from_output
或者,如果您更喜歡較短的密碼,您可以使用不同校驗的輸出。同樣,更改引號中的單詞,以便它不會生成與此命令相同的密碼:
- echo "digital-ocean" | sha1sum
設置密碼後,保存並關閉文件,然後重新啟動Redis:
- sudo systemctl restart redis
要測試密碼是否有效,打開Redis客戶端:
- redis-cli
以下是用於測試Redis密碼是否有效的一系列命令。第一個命令在身份驗證之前嘗試將鍵設置為值:
- set key1 10
由於您尚未進行身份驗證,因此這將不起作用,所以Redis會返回錯誤:
Output(error) NOAUTH Authentication required.
以下命令使用Redis配置文件中指定的密碼進行身份驗證:
- auth your_redis_password
Redis將確認您已經通過身份驗證:
OutputOK
之後,再次運行先前的命令應該成功:
- set key1 10
OutputOK
命令get key1
查詢新密鑰的值:
- get key1
Output"10"
最後一個命令退出redis-cli
。您也可以使用exit
:
- quit
現在,未經授權的用戶應該很難訪問您的Redis安裝。請注意,如果您已經在使用Redis命令行客戶端,然後重新啟動Redis,您需要重新進行身份驗證。此外,請注意,如果您遠程連接到Redis,並且沒有使用SSL或VPN,則此密碼仍然可能被外部方拦截。
接下來,本指南將介紹將Redis命令重新命名以進一步保護Redis免受惡意行為者的侵害。
第4步 – 重新命名危險命令
另一個內建於 Redis 中的安全功能允許您重新命名或完全禁用某些被視為危險的指令。當未經授權的用戶運行這些指令時,這些指令可能被用來重新配置、摧毀或清除您的數據。一些被認為是危險的指令包括:
FLUSHDB
FLUSHALL
KEYS
PEXPIRE
DEL
CONFIG
SHUTDOWN
BGREWRITEAOF
BGSAVE
SAVE
SPOP
SREM
RENAME
DEBUG
這不是一個全面的清單,但重新命名或禁用此清單中的所有指令可以有助於提高您的數據存儲安全性。您應該禁用或重新命名特定指令將取決於您的具體需求。如果您知道您永遠不會使用可能被濫用的指令,則可以禁用它。否則,您應該將其重新命名。
像身份驗證密碼一樣,重新命名或禁用指令是在 /etc/redis.conf
文件的 SECURITY
部分中配置的。要啟用或禁用 Redis 指令,再次打開配置文件進行編輯:
- sudo nano /etc/redis.conf
注意: 這些只是範例。您應該選擇禁用或重新命名對您有意義的命令。您可以在redis.io/commands了解有關 Redis 命令的更多信息,並確定它們可能被誤用的方式。
要禁用或終止命令,將其重命名為空字符串,如下所示:
# 也可以通過將其重命名為
# 空字符串來完全終止命令:
#
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command DEBUG ""
要重命名命令,請給它另一個名稱,就像以下示例中所示。重新命名的命令應該讓其他人難以猜測,但對您來說應該很容易記住:
# 也可以通過將其重命名為
# 空字符串來完全終止命令:
#
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command DEBUG ""
rename-command SHUTDOWN SHUTDOWN_MENOT
rename-command CONFIG ASC12_CONFIG
保存更改並關閉文件。然後通過重新啟動 Redis 來應用更改:
- sudo systemctl restart redis.service
要測試新命令,輸入 Redis 命令行:
- redis-cli
使用您之前定義的密碼進行身份驗證:
- auth your_redis_password
OutputOK
假設您將 CONFIG
命令重命名為 ASC12_CONFIG
,嘗試使用 config
命令將失敗:
- config get requirepass
Output(error) ERR unknown command 'config'
而使用已重命名的命令將成功。請注意,Redis 命令不區分大小寫:
- asc12_config get requirepass
Output1) "requirepass"
2) "your_redis_password"
最後,您可以退出redis-cli
:
- exit
警告: 關於重命名命令,請注意在/etc/redis.conf
文件的SECURITY
部分末尾有一條警語,其中寫著:
. . .
# 請注意,更改記錄到
# AOF文件或傳輸到副本的命令的名稱可能會導致問題。
. . .
這意味著如果更名的命令未在AOF文件中,或者如果在但AOF文件尚未傳輸到副本,那麼應該不會有問題。在重新命名命令時,請牢記這一點。最好的重新命名命令的時機是在不使用AOF持久性的情況下或剛安裝完畢後(也就是在您的Redis使用的應用程式部署之前)。
步驟5 — 設定資料目錄所有權和檔案權限
此步驟將介紹您可能需要進行的一些所有權和權限更改,以提高Redis安裝的安全性。這包括確保只有需要訪問Redis的用戶有權讀取其數據。該用戶默認為redis用戶。
您可以通過在其父目錄的長列表中尋找Redis數據目錄來驗證這一點。以下提供了此命令及其輸出:
- ls -l /var/lib | grep redis
Outputdrwxr-x---. 2 redis redis 22 Sep 6 22:22 redis
此輸出指示Redis數據目錄的擁有者是redis用戶,次要訪問權限授予redis組。此擁有權設置是安全的,這個文件夾的權限使用八進制表示法設置為750。
如果您的Redis數據目錄具有不安全的權限,您可以通過運行chmod命令確保僅Redis用戶和組可以訪問該文件夾及其內容。以下示例更改此文件夾的權限設置為770:
- sudo chmod 770 /var/lib/redis
您可能需要更改的另一個權限是Redis配置文件的權限。默認情況下,它具有文件權限640,由root擁有,次要擁有權由root組擁有:
- ls -l /etc/redis.conf
Output-rw-r-----. 1 redis root 62192 Sep 6 22:20 /etc/redis.conf
該權限(640)意味著Redis配置文件僅對redis用戶和root組可讀。由於配置文件包含您在第4步中配置的未加密密碼,redis.conf應由redis用戶擁有,次要擁有權由redis組擁有。要設置此權限,請運行以下命令:
- sudo chown redis:redis /etc/redis.conf
然後更改權限,以便僅擁有文件的所有者可以讀取和寫入它:
- sudo chmod 600 /etc/redis.conf
您可以再次運行先前的ls命令來驗證新的所有權和權限:
- ls -l /var/lib | grep redis
Outputtotal 40
drwxrwx---. 2 redis redis 22 Sep 6 22:22 redis
- ls -l /etc/redis.conf
Outputtotal 40
-rw-------. 1 redis redis 62192 Sep 6 22:20 /etc/redis.conf
最後,重新啟動Redis以反映這些更改:
- sudo systemctl restart redis
完成後,您的Redis安裝已經得到安全保護。
結論
請記住,一旦有人登錄到您的服務器,就有可能規避您所設置的 Redis 特定安全功能。這就是為什麼本教程中涵蓋的最重要的安全功能是防火牆,因為它防止未知用戶首先登錄到您的服務器。
如果您試圖在不受信任的網絡上保護 Redis 通信,您將不得不使用 SSL 代理,正如 Redis 開發人員在官方 Redis 安全指南中所建議的那樣。official Redis security guide。
Source:
https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-rocky-linux-8