在Ubuntu 22.04上安裝和保護Redis

介紹

Redis是一個以靈活性、性能和廣泛的語言支持而聞名的內存鍵值存儲。本教程演示了如何在 Ubuntu 22.04 伺服器上安裝、配置和保護 Redis。

先決條件

要完成本指南,您需要訪問一台已配置了 sudo 權限的非 root 用戶並且配置了 ufw 防火牆的 Ubuntu 22.04 伺服器。您可以按照我們的 Ubuntu 22.04 的初始伺服器設置指南 進行設置。

步驟 1 — 安裝和配置 Redis

我們將使用 APT 軟件包管理器從官方 Ubuntu 存儲庫安裝 redis。截至本文撰寫時,預設存儲庫中可用的版本是 6.0.16

首先,更新本地的 apt 軟件包緩存:

  1. sudo apt update

然後,輸入以下命令來安裝 Redis:

  1. sudo apt install redis-server

這將下載並安裝 Redis 及其相依項目。在此之後,有一個重要的配置更改需要在 Redis 配置文件中進行,該文件在安裝過程中自動生成。

使用您偏好的文本編輯器打開此文件:

  1. sudo nano /etc/redis/redis.conf

在文件內部,找到 supervised 指令。此指令允許您聲明一個 init 系統來管理 Redis 作為服務,從而更好地控制其運行。預設情況下,supervised 指令設置為 no。由於您正在運行使用 systemd init 系統的 Ubuntu,將其更改為 systemd

/etc/redis/redis.conf
. . .

# 如果您從 upstart 或 systemd 運行 Redis,Redis 可以與您的
# 監管樹進行交互。選項:
#   supervised no      - 不進行監管交互
#   supervised upstart - 通過將 Redis 放入 SIGSTOP 模式來向 upstart 發送信號
#   supervised systemd - 通過將 READY=1 寫入 $NOTIFY_SOCKET 向 systemd 發送信號
#   supervised auto    - 基於
#                        UPSTART_JOB 或 NOTIFY_SOCKET 環境變量檢測 upstart 或 systemd 方法
# 注意:這些監管方法僅發出 "進程準備就緒" 的信號。
#       它們不啟用持續的活躍檢測返回給您的監管系統。
supervised systemd

. . .

這是您現在需要對 Redis 配置文件進行的唯一更改,因此在完成後請保存並關閉它。如果您使用 nano 編輯文件,請按 CTRL + X,然後按 Y,最後按 ENTER

然後,重新啟動 Redis 服務以反映您對配置文件所做的更改:

  1. sudo systemctl restart redis.service

有了這個,您已經安裝並配置了 Redis,它正在您的機器上運行。但在開始使用它之前,最好先檢查一下 Redis 是否正常運作。

第 2 步 — 測試 Redis

與任何新安裝的軟件一樣,確保 Redis 在進行任何進一步的配置更改之前正常運行是一個好主意。在這一步中,我們將介紹幾種檢查 Redis 正常運行的方法。

首先,檢查 Redis 服務是否正在運行:

  1. sudo systemctl status redis

如果它正常運行且沒有任何錯誤,則此命令將產生類似以下的輸出:

Output
● redis-server.service - Advanced key-value store Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2022-04-20 20:40:52 UTC; 4s ago Docs: http://redis.io/documentation, man:redis-server(1) Main PID: 2899 (redis-server) Status: "Ready to accept connections" Tasks: 5 (limit: 2327) Memory: 2.5M CPU: 65ms CGroup: /system.slice/redis-server.service └─2899 "/usr/bin/redis-server 127.0.0.1:6379 . . .

這個輸出表示 Redis 正在運行並且已經啟用,這意味著它被設置為在每次服務器啟動時啟動。

注意:這個設置對於許多常見的 Redis 使用案例來說是理想的。但是,如果您更喜歡在每次服務器啟動時手動啟動 Redis,您可以使用以下命令進行配置:

  1. sudo systemctl disable redis

為了測試 Redis 是否正常運作,請使用 redis-cli 連接到伺服器,這是 Redis 的命令行客戶端:

  1. redis-cli

在隨後的提示符中,使用 ping 命令測試連通性:

  1. ping
Output
PONG

這個輸出確認了伺服器連接仍然有效。接下來,運行以下命令來檢查您是否能夠設置鍵:

  1. set test "It's working!"
Output
OK

通過輸入以下命令來檢索值:

  1. get test

假設一切正常,您將能夠檢索到您存儲的值:

Output
"It's working!"

確認您可以取回值後,退出 Redis 提示符,返回到 shell:

  1. exit

作為最後的測試,我們將檢查 Redis 是否能夠在停止或重新啟動後仍然持久化數據。為此,首先重新啟動 Redis 實例:

  1. sudo systemctl restart redis

然後再次使用命令行客戶端進行連接:

  1. redis-cli

並確認您的測試值仍然可用:

  1. get test

您的鍵的值應該仍然可訪問:

Output
"It's working!"

完成後再次退出到 shell:

  1. exit

至此,您的 Redis 安裝已經完全運作,準備好供您使用。然而,它的一些默認配置設置存在安全風險,可能會給惡意操作者提供攻擊和訪問您的伺服器和數據的機會。本教程的其餘步驟將介紹緩解這些漏洞的方法,根據官方 Redis 網站的建議進行。儘管這些步驟是可選的,如果您選擇不執行它們,Redis 仍將正常運作,但強烈建議您完成這些步驟以加固系統的安全性。

步驟 3 — 綁定到本地主機

預設情況下,Redis 只能從 localhost 訪問。但是,如果您通過其他教程安裝和配置了 Redis,則可能已經更新了配置文件以允許從任何地方進行連接。這不如綁定到 localhost 安全。

要更正這一點,請打開 Redis 配置文件進行編輯:

  1. sudo nano /etc/redis/redis.conf

找到此行並確保已取消註釋(如果存在,請刪除 #):

/etc/redis/redis.conf
. . .
bind 127.0.0.1 ::1
. . .

完成後保存並關閉文件(按 CTRL + XY,然後 ENTER)。

然後,重新啟動服務以確保 systemd 讀取您的更改:

  1. sudo systemctl restart redis

要檢查此更改是否生效,請運行以下 netstat 命令:

  1. sudo netstat -lnp | grep redis
Output
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 14222/redis-server tcp6 0 0 ::1:6379 :::* LISTEN 14222/redis-server

注意:在您的系統上,netstat 命令可能不是默認可用的。如果是這種情況,您可以使用以下命令安裝它(以及其他一些方便的網絡工具):

  1. sudo apt install net-tools

此輸出顯示 redis-server 程序已綁定到 localhost127.0.0.1),反映了您剛剛對配置文件所做的更改。如果在該列中有另一個 IP 地址(例如 0.0.0.0),那麼您應該仔細檢查您是否取消了正確的行並重新啟動了 Redis 服務。

現在您的 Redis 安裝只聽取 localhost 的連線,惡意行為者將更難以進行請求或獲取訪問您的伺服器。然而,Redis 目前未設定為在修改其配置或所持有的數據之前要求使用者進行身份驗證。為了解決這個問題,Redis 允許您要求使用者在通過 Redis 客戶端(redis-cli)進行更改之前進行身份驗證。

步驟 4 — 配置 Redis 密碼

配置 Redis 密碼啟用了其兩個內建安全功能之一 — auth 命令,該命令要求客戶端進行身份驗證以訪問數據庫。密碼直接配置在 Redis 的配置文件 /etc/redis/redis.conf 中,因此再次使用您首選的編輯器打開該文件:

  1. sudo nano /etc/redis/redis.conf

滾動至 SECURITY 部分,找到一個被註釋的指令,其內容如下:

/etc/redis/redis.conf
. . .
# requirepass foobared
. . .

通過刪除 # 來取消註釋,並將 foobared 更改為安全的密碼。

注意:redis.conf 文件中的 requirepass 指令上方,有一個被註釋的警告:

/etc/redis/redis.conf
. . .
#警告:由於 Redis 非常快速,外部用戶可以對一個好的伺服器每秒嘗試高達
# 150k個密碼。這意味著您應該
# 使用非常強大的密碼,否則很容易被破解。
#
. . .

因此,重要的是您指定一個非常強大且非常長的值作為您的密碼。您可以使用openssl命令生成一個隨機密碼,而不是自己想出一個密碼,如以下示例所示。通過將第一個命令的輸出導向到第二個openssl命令,如下所示,它將刪除由第一個命令產生的任何換行符:

  1. openssl rand 60 | openssl base64 -A

此命令將返回以下類似的輸出:

Output
RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE

將該命令的輸出復製並粘貼為requirepass的新值後,它應該是:

/etc/redis/redis.conf
requirepass RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE

設置密碼後,保存並關閉文件。然後重新啟動 Redis:

  1. sudo systemctl restart redis.service

要測試密碼是否有效,打開 Redis 客戶端:

  1. redis-cli

以下顯示了用於測試 Redis 密碼是否有效的命令序列。第一個命令在驗證之前嘗試將鍵設置為值:

  1. set key1 10

這不會成功,因為您尚未驗證,因此 Redis 返回錯誤:

Output
(error) NOAUTH Authentication required.

接下來的命令使用 Redis 配置文件中指定的密碼進行身份驗證:

  1. auth your_redis_password

Redis 確認:

Output
OK

之後,再次運行先前的命令將成功:

  1. set key1 10
Output
OK

get key1查詢 Redis 中新鍵的值。

  1. get key1
Output
"10"

確認您能夠在驗證後運行 Redis 客戶端命令後,您可以退出 redis-cli:

  1. quit

接下來,我們將討論重新命名 Redis 命令,如果出錯或被惡意操作者輸入,可能會對您的數據造成嚴重影響。

步驟 5 — 重新命名危險命令

Redis 中內建的另一個安全功能涉及重新命名或完全禁用某些被認為危險的命令。

當未經授權的用戶運行這些命令時,這些命令可以用於重新配置、銷毀或以其他方式清除您的數據。與身份驗證密碼一樣,重新命名或禁用命令是在相同的 /etc/redis/redis.conf 文件的 SECURITY 部分中配置的。

被認為危險的一些命令包括:FLUSHDBFLUSHALLKEYSPEXPIREDELCONFIGSHUTDOWNBGREWRITEAOFBGSAVESAVESPOPSREMRENAMEDEBUG。這不是一個詳盡的清單,但重新命名或禁用該清單中的所有命令是增強 Redis 服務器安全性的一個良好起點。

無論您是否應該禁用或重新命名命令,取決於您的具體需求或您的網站的需求。如果您知道您永遠不會使用可能被濫用的命令,那麼您可以將其禁用。否則,將其重新命名可能符合您的最佳利益。

要重新命名或禁用 Redis 命令,請再次打開配置文件:

  1. sudo nano /etc/redis/redis.conf

警告:以下步驟顯示如何禁用和重新命名命令僅為示例。您應僅選擇禁用或重新命名對您有意義的命令。您可以自行查看完整的命令列表,並確定它們可能如何被誤用,網址為:redis.io/commands

要禁用命令,將其重新命名為空字符串(由一對雙引號表示,其中間沒有字符),如下所示:

/etc/redis/redis.conf
. . .
# 也可以將命令完全禁用,將其重新命名為
# 空字符串:
#
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command DEBUG ""
. . .

要重新命名命令,請像以下示例中所示給它另一個名稱。重新命名的命令應該對他人難以猜測,但對您來說易於記憶:

/etc/redis/redis.conf
. . .
# rename-command CONFIG ""
rename-command SHUTDOWN SHUTDOWN_MENOT
rename-command CONFIG ASC12_CONFIG
. . .

保存更改並關閉文件。

重新命名命令後,請通過重新啟動 Redis 來應用更改:

  1. sudo systemctl restart redis.service

要測試新命令,請進入 Redis 命令行:

  1. redis-cli

然後,進行身份驗證:

  1. auth your_redis_password
Output
OK

假設您將 CONFIG 命令重新命名為 ASC12_CONFIG,如前述示例所示。首先,嘗試使用原始的 CONFIG 命令。它應該失敗,因為您已將其重新命名:

  1. config get requirepass
Output
(error) ERR unknown command `config`, with args beginning with:

調用重新命名的命令,然而將成功。它不區分大小寫:

  1. asc12_config get requirepass
Output
1) "requirepass" 2) "your_redis_password"

最後,您可以退出redis-cli

  1. exit

請注意,如果您已經在使用 Redis 命令行,然後重新啟動 Redis,您需要重新驗證。否則,如果您輸入一個命令,您將會收到此錯誤:

Output
NOAUTH Authentication required.

警告:關於重新命名命令的實踐,在/etc/redis/redis.confSECURITY部分末尾有一個警告性語句,它說:

/etc/redis/redis.conf
. . .
# 請注意,更改寫入 AOF 文件或傳輸到從屬的命令的名稱可能會引起問題。

. . .

注意:Redis 項目選擇使用“主”和“從”這些術語,而 DigitalOcean 通常更喜歡使用“主要”和“次要”這些替代詞。為了避免混淆,我們選擇在這裡使用 Redis 文檔中使用的術語。

這意味著如果重新命名的命令不在 AOF 文件中,或者如果它在其中但是 AOF 文件尚未傳輸到從屬,那麼應該沒有問題。

因此,在嘗試重新命名命令時請記住這一點。重新命名命令的最佳時間是在不使用 AOF 持久性時,或者在安裝後的立即,也就是在您的 Redis 使用應用程序部署之前。

當您使用 AOF 並處理主從安裝時,請考慮此回答來自該項目的 GitHub 問題頁面。以下是對作者問題的回覆:

命令被记录到AOF并以发送的方式复制到从属,因此如果您尝试在没有相同重命名的实例上重放AOF,您可能会遇到不一致,因为命令无法执行(从属也是如此)。

因此,在这种情况下处理重命名的最佳方法是确保重命名的命令被应用到主从安装的所有实例中。

结论

在本教程中,您安装并配置了Redis,验证了Redis安装是否正常运行,并使用其内置的安全功能使其对来自恶意行为者的攻击更不易受到影响。

请记住,一旦有人登录到您的服务器,绕过我们已经设置的特定于Redis的安全功能就非常容易了。因此,您的Redis服务器上最重要的安全功能是您的防火墙(如果您遵循了先决条件 初始服务器设置 教程进行了配置),因为这使得恶意行为者极其难以越过这道障碍。

Source:
https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-22-04