آموزش سرور

نصب و امن‌سازی Redis روی اوبونتو؛ از نصب تا تنظیمات امنیتی و حافظه

تهیه: کلودیفای (نگارش با کمک هوش مصنوعی) · انتشار: · زمان مطالعه: ۷ دقیقه

Redisآموزش سرورنصب و امن‌سازی Redisروی اوبونتو؛ از نصب تاتنظیمات امنیتی و حافظهمجلهٔ کلودیفایclodify.net/blog
پاسخ کوتاه

Redis را با apt نصب کنید و بلافاصله امنش کنید: در redis.conf آن را فقط روی 127.0.0.1 گوش‌به‌زنگ نگه دارید، protected-mode را روشن بگذارید، یک کاربر ACL با رمز قوی بسازید و کاربر پیش‌فرض را محدود کنید. با maxmemory و سیاست حذف مناسب جلوی پر شدن رم را بگیرید و نوع ماندگاری RDB یا AOF را بر اساس کاربرد انتخاب کنید. پورت ۶۳۷۹ هرگز نباید روی اینترنت باز باشد.

Redis چیست و چرا امنیتش مهم است؟

Redis یک پایگاه دادهٔ کلید-مقدار است که داده‌ها را در حافظهٔ رم نگه می‌دارد و به همین دلیل بسیار سریع است. کاربردهای رایجش: کش کردن نتیجهٔ کوئری‌ها و صفحه‌ها، نگهداری نشست کاربران، صف کارهای پس‌زمینه، شمارنده‌ها و محدودیت نرخ. بسیاری از فریم‌ورک‌ها و ابزارها مثل لاراول، جنگو، n8n و Sidekiq از آن استفاده می‌کنند. اگر با مفهوم کش آشنا نیستید، مقالهٔ کش چیست را ببینید.

Redis برای اجرا در شبکهٔ داخلی و مورد اعتماد طراحی شده است، نه برای قرار گرفتن مستقیم روی اینترنت. یک Redis بی‌رمز که روی آی‌پی عمومی باز باشد، در مدت کوتاهی توسط ربات‌های اسکنر پیدا می‌شود. مهاجم می‌تواند همهٔ داده‌ها را بخواند یا پاک کند و در پیکربندی‌های ناامن حتی از قابلیت‌های Redis برای نوشتن فایل روی سرور و گرفتن دسترسی کامل استفاده کند. به همین دلیل امن‌سازی بخش جدانشدنی نصب است، نه یک کار اختیاری بعدی.

لایه‌های امنیت Redis
فایروالپورت ۶۳۷۹ از بیرون بسته
bind و protected-modeگوش دادن فقط روی 127.0.0.1 یا شبکهٔ خصوصی
ACL و رمزکاربر پیش‌فرض غیرفعال، کاربر محدود برای برنامه
محدودیت دستوراتFLUSHALL، CONFIG و DEBUG فقط برای مدیر
maxmemoryجلوگیری از پر شدن رم سرور
شکل ۱ هر لایه اگر لایهٔ دیگر شکست بخورد، همچنان از Redis محافظت می‌کند.

نصب Redis روی اوبونتو

نسخهٔ موجود در مخازن اوبونتو برای بیشتر کاربردها کافی است:

sudo apt update
sudo apt install -y redis-server

پس از نصب، سرویس با systemd مدیریت می‌شود:

sudo systemctl enable --now redis-server
sudo systemctl status redis-server
redis-cli ping

اگر پاسخ PONG گرفتید، Redis اجرا شده است. برای آشنایی با مدیریت سرویس‌ها، آموزش systemd را ببینید. فایل اصلی پیکربندی در /etc/redis/redis.conf قرار دارد و همهٔ تنظیمات بعدی در همین فایل انجام می‌شود. پیش از تغییر، از آن نسخهٔ پشتیبان بگیرید.

گام ۱: فقط روی localhost گوش دهد

مهم‌ترین تنظیم امنیتی این است که Redis فقط از روی همان سرور در دسترس باشد. در redis.conf مطمئن شوید این خطوط فعال‌اند:

bind 127.0.0.1 -::1
protected-mode yes
port 6379

با bind 127.0.0.1 Redis فقط روی آدرس محلی گوش می‌دهد و از بیرون سرور اصلاً قابل‌دسترسی نیست. protected-mode یک لایهٔ محافظ اضافه است: اگر Redis بدون رمز و روی همهٔ آدرس‌ها اجرا شود، اتصال‌های بیرونی را رد می‌کند. این گزینه را خاموش نکنید.

پس از تغییر، سرویس را راه‌اندازی مجدد کنید و بررسی کنید روی چه آدرسی گوش می‌دهد:

sudo systemctl restart redis-server
sudo ss -ltnp | grep 6379

باید فقط 127.0.0.1:6379 و [::1]:6379 را ببینید، نه 0.0.0.0:6379.

گام ۲: رمز و کاربر ACL

حتی وقتی Redis فقط روی localhost است، تعیین رمز توصیه می‌شود؛ چون هر برنامه یا کاربر دیگری روی همان سرور هم به آن دسترسی دارد. نسخه‌های جدید Redis سیستم ACL دارند که اجازه می‌دهد کاربرهای جدا با دسترسی‌های محدود بسازید. در redis.conf:

user default off
user app on >YOUR-LONG-RANDOM-PASSWORD ~app:* &* +@all -@dangerous

این تنظیم کاربر پیش‌فرض بی‌رمز را غیرفعال می‌کند و کاربری به نام app می‌سازد که فقط به کلیدهایی که با app: شروع می‌شوند دسترسی دارد و دستورات خطرناک را نمی‌تواند اجرا کند. برای ساختن رمز تصادفی قوی از openssl rand -base64 32 استفاده کنید و آن را در فایل تنظیمات برنامه، نه در کد، نگه دارید.

اتصال با کاربر جدید:

redis-cli --user app --askpass

اگر برنامهٔ شما قدیمی است و فقط از رمز تکی پشتیبانی می‌کند، می‌توانید به‌جای ACL از requirepass استفاده کنید که رمز کاربر پیش‌فرض را تعیین می‌کند.

root@server: ~
$ sudo ss -ltnp | grep 6379LISTEN 0 511 127.0.0.1:6379  0.0.0.0:*  users:(("redis-server",pid=812))LISTEN 0 511     [::1]:6379     [::]:*  users:(("redis-server",pid=812))$ redis-cli ping(error) NOAUTH Authentication required.$ redis-cli --user app --askpass pingPONG$ 
شکل ۲ Redis فقط روی localhost گوش می‌دهد و بدون احراز هویت پاسخ نمی‌دهد.

گام ۳: دستورات خطرناک را محدود کنید

دستوراتی مانند FLUSHALL که همهٔ داده‌ها را پاک می‌کند، CONFIG که تنظیمات را در حال اجرا تغییر می‌دهد و DEBUG نباید در دسترس برنامهٔ عادی باشند. با ACL، بخش -@dangerous در تعریف کاربر همین کار را انجام می‌دهد. برای مدیریت، یک کاربر جداگانهٔ مدیر با رمز دیگر بسازید که فقط خودتان از آن استفاده کنید. این تفکیک باعث می‌شود حتی اگر رمز برنامه لو برود، آسیب محدود بماند.

گام ۴: مدیریت حافظه

چون Redis داده‌ها را در رم نگه می‌دارد، بدون محدودیت می‌تواند آن‌قدر رشد کند که رم سرور تمام شود و سیستم‌عامل فرایندها را متوقف کند؛ پدیده‌ای که در مقالهٔ کمبود رم سرور توضیح داده شده است. سقف حافظه و سیاست حذف را تعیین کنید:

maxmemory 256mb
maxmemory-policy allkeys-lru

انتخاب سیاست به کاربرد بستگی دارد:

  • فقط کش: allkeys-lru قدیمی‌ترین کلیدهای کم‌استفاده را حذف می‌کند و جا برای داده‌های جدید باز می‌کند.
  • کش همراه با کلیدهای دائمی: volatile-lru فقط کلیدهایی را حذف می‌کند که زمان انقضا دارند.
  • صف یا دادهٔ مهم: noeviction هیچ چیزی را حذف نمی‌کند و وقتی حافظه پر شد، نوشتن جدید را با خطا رد می‌کند؛ بهتر از گم شدن بی‌صدای کارها در صف است.

مقدار maxmemory را طوری انتخاب کنید که برای سیستم‌عامل، دیتابیس و برنامه‌های دیگر هم رم کافی باقی بماند.

گام ۵: ماندگاری داده

Redis به‌صورت پیش‌فرض گاه‌به‌گاه یک عکس فوری از داده‌ها روی دیسک ذخیره می‌کند که به آن RDB می‌گویند. اگر سرور ناگهان خاموش شود، تغییرات پس از آخرین عکس از دست می‌روند. گزینهٔ دیگر AOF است که هر دستور نوشتن را در یک فایل ثبت می‌کند و دوام بیشتری دارد:

appendonly yes
appendfsync everysec

اگر Redis را فقط به‌عنوان کش استفاده می‌کنید، از دست رفتن داده مهم نیست و می‌توانید ماندگاری را حتی خاموش کنید. اما برای صف کارها یا نشست کاربران، AOF را فعال کنید. فایل‌های داده در /var/lib/redis قرار دارند و باید در برنامهٔ پشتیبان‌گیری سرور گنجانده شوند.

RDB یا AOF؟
RDB
  • عکس فوری دوره‌ای از کل داده
  • فایل فشرده و بازیابی سریع
  • تغییرات پس از آخرین عکس ممکن است گم شوند
  • مناسب کش و داده‌های قابل‌بازسازی
در برابر
AOF
  • ثبت پیوستهٔ هر دستور نوشتن
  • دوام بیشتر در خاموشی ناگهانی
  • فایل بزرگ‌تر و بازنویسی دوره‌ای
  • مناسب صف کارها و نشست‌ها
شکل ۳ برای دادهٔ مهم، بسیاری از مدیران هر دو را هم‌زمان فعال می‌کنند.

اگر سرور دیگری باید به Redis وصل شود

گاهی برنامه روی یک سرور و Redis روی سرور دیگری است. در این حالت هرگز Redis را روی آی‌پی عمومی باز نکنید. راه‌های امن‌تر:

  • شبکهٔ خصوصی: اگر ارائه‌دهنده شبکهٔ خصوصی بین سرورها دارد، Redis را فقط روی آی‌پی خصوصی bind کنید.
  • فایروال محدود: پورت ۶۳۷۹ را فقط برای آی‌پی سرور برنامه باز کنید؛ مثلاً با sudo ufw allow from 10.0.0.5 to any port 6379. جزئیات در آموزش UFW.
  • TLS: نسخه‌های جدید Redis از اتصال رمزنگاری‌شده پشتیبانی می‌کنند که برای ارتباط از شبکهٔ غیرقابل‌اعتماد ضروری است.

Redis در داکر

اگر برنامه‌هایتان را با داکر اجرا می‌کنید، Redis را هم می‌توانید در همان فایل Compose تعریف کنید. در این حالت پورت را اصلاً منتشر نکنید؛ برنامه‌ها از طریق شبکهٔ داخلی Compose و با نام سرویس به آن وصل می‌شوند:

services:
  redis:
    image: redis:7
    restart: unless-stopped
    command: ["redis-server", "--appendonly", "yes", "--requirepass", "${REDIS_PASSWORD}"]
    volumes:
      - redis-data:/data
volumes:
  redis-data:

رمز را در فایل .env کنار Compose نگه دارید و آن فایل را در مخزن کد قرار ندهید. اگر حتماً به دسترسی از روی خود سرور نیاز دارید، پورت را فقط روی 127.0.0.1:6379:6379 منتشر کنید؛ انتشار بدون آی‌پی ممکن است فایروال را دور بزند. مقدمهٔ Compose در آموزش Docker Compose آمده است.

چک‌لیست نهایی

  • Redis فقط روی 127.0.0.1 یا شبکهٔ خصوصی گوش می‌دهد و protected-mode روشن است.
  • کاربر پیش‌فرض غیرفعال یا رمزدار است و برنامه کاربر محدود خودش را دارد.
  • maxmemory و سیاست حذف متناسب با کاربرد تنظیم شده است.
  • ماندگاری مناسب انتخاب و پوشهٔ داده در پشتیبان‌گیری آمده است.
  • پورت ۶۳۷۹ از بیرون بسته است.

سؤالات متداول

آیا Redis بدون رمز روی localhost امن است؟

تا حد زیادی، چون از بیرون سرور قابل‌دسترسی نیست. اما هر برنامه یا کاربر دیگری روی همان سرور می‌تواند به آن وصل شود و اگر یکی از آن‌ها آسیب‌پذیر باشد، Redis هم در خطر است. تعیین رمز یا ACL هزینه‌ای ندارد و توصیه می‌شود.

چطور بفهمم Redis از بیرون باز است؟

روی سرور با ss -ltnp | grep 6379 ببینید روی کدام آدرس گوش می‌دهد. اگر 0.0.0.0 یا آی‌پی عمومی دیدید، bind را اصلاح کنید و از یک سیستم دیگر هم تست کنید که اتصال به پورت ۶۳۷۹ برقرار نمی‌شود.

Redis چقدر رم لازم دارد؟

به حجم داده‌هایی که نگه می‌دارید بستگی دارد. برای کش یک سایت کوچک معمولاً مقدار کمی کافی است. با دستور INFO memory مصرف واقعی را ببینید و maxmemory را کمی بالاتر از نیاز معمول و پایین‌تر از رم آزاد سرور تنظیم کنید.

RDB بهتر است یا AOF؟

برای کش خالص هیچ‌کدام ضروری نیست. برای داده‌هایی که از دست رفتنشان مهم است، AOF با appendfsync everysec دوام بیشتری دارد. بسیاری از سرورها هر دو را هم‌زمان فعال می‌کنند تا هم بازیابی سریع و هم دوام بیشتر داشته باشند.

آماده‌اید؟ سرورتان را بسازید.

از ۱٬۲۰۰ تومان در ساعت · پرداخت ریالی

سرورتان را همین حالا بسازید.

ساعتی بپردازید. هر وقت خواستید حذف کنید.