سروری را به یاد می‌آورم که پورت ۳۳۰۶ آن به‌طور پیش‌فرض برای تمام اینترنت باز بود و رمز کاربر روت هم ضعیف؛ نتیجه این شد که یک اسکنر خودکار، در چند ساعت تمام دیتابیس‌های آن سرور را پاک کرد. آن روز برای من یادآوری روشنی بود که محدودکردن دسترسی خارجی به دیتابیس (Database)، اولین و ساده‌ترین دیوار دفاعی است، اما وقتی نادیده گرفته شود، هیچ لایه امنیتی دیگری نمی‌تواند جبرانش کند. این نوشته، همان روشی است که در پروژه‌های واقعی برای محدودسازی دسترسی به دیتابیس به‌کار می‌برم.

دسترسی خارجی به دیتابیس دقیقاً چیست؟

دسترسی خارجی یا Remote Access به دیتابیس، امکان اتصال به سرور دیتابیس از یک سرور یا شبکه بیرونی است. در سرورهای MySQL یا MariaDB، این دسترسی از طریق پورت پیش‌فرض ۳۳۰۶ فراهم می‌شود. سه سناریو که به این دسترسی نیاز دارند:

  • توسعه لوکال روی سرور جداگانه: توسعه‌دهنده از محیط لوکال به دیتابیس سرور اصلی وصل می‌شود.
  • سرویس‌های بیرونی: ابزارهایی مثل پشتیبان‌گیر ابری، سیستم تحلیل، یا ابزار گزارش‌گیری که به دیتابیس وصل می‌شوند.
  • مهاجرت بین سرورها: انتقال داده از یک سرور به سرور دیگر.

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

دیتابیس، قلب سایت است. باز گذاشتن دسترسی خارجی به آن، مثل گذاشتن کلید قلب در پیاده‌روی خیابان است: ممکن است هیچ‌کس آن را نبرد، اما ریسکش را کسی جز خودتان نمی‌پذیرد.

ذهنیت درست: بستن پیش‌فرض، باز کردن استثنا

در امنیت دیتابیس، قاعده‌ای که در پروژه‌ها رعایت می‌کنم، ساده است: پیش‌فرض، بسته؛ فقط استثناها باز می‌شوند. سه اصل که از این قاعده می‌آید:

  1. دسترسی خارجی، فقط در صورت نیاز واقعی: اگر هیچ سرویس بیرونی به دیتابیس وصل نمی‌شود، پورت باید بسته باشد.
  2. هر کاربر دیتابیس، فقط از یک IP مجاز: اگر یک کاربر باید از IP خاصی وصل شود، دسترسی این کاربر محدود به همان IP شود، نه به همه اینترنت.
  3. پایین‌ترین سطح دسترسی: هر کاربر، فقط به آنچه لازم دارد دسترسی داشته باشد؛ نه بیشتر. کاربر پشتیبان‌گیر برای خواندن، کاربر وردپرس برای خواندن و نوشتن روی یک دیتابیس مشخص.

در تجربه‌ام، تیم‌هایی که این سه اصل را رعایت می‌کنند، سطح حمله دیتابیس را به حداقل می‌رسانند و در نتیجه در برابر اسکنرهای خودکار و حملات گسترده ایمن‌تر هستند. برای مرور اصول کلی امنیت دیتابیس، بهترین روش‌های امنیت MySQL و مدیریت کاربران و دسترسی‌های دیتابیس را ببینید.

محدودسازی در لایه شبکه و فایروال

اولین و مهم‌ترین لایه محدودسازی، در سطح شبکه است. سه اقدام که در پروژه‌ها انجام می‌دهم:

  1. بستن پورت ۳۳۰۶ در فایروال: پورت دیتابیس، در بیشتر هاست‌های اشتراکی، از پیش بسته است؛ اما در VPS و سرور اختصاصی باید به‌طور صریح بسته شود. نمونه دستور در فایروال نرم‌افزاری:
# مسدودکردن پورت MySQL/MariaDB برای همه
ufw deny 3306/tcp
  1. محدودسازی پورت به IPهای مشخص: اگر دسترسی خارجی لازم است، پورت فقط به IPهای مشخص باز شود، نه به همه اینترنت:
# اجازه دسترسی فقط از IP دفتر کار
ufw allow from 203.0.113.10 to any port 3306 proto tcp
  1. تنظیم bind-address در MySQL: حتی اگر فایروال درست تنظیم شود، باید MySQL هم فقط به localhost گوش دهد. در فایل my.cnf یا mariadb.cnf:
[mysqld]
bind-address = 127.0.0.1

این خط، به MySQL می‌گوید فقط از localhost اتصال بپذیرد، حتی اگر فایروال اشتباه تنظیم شده باشد. ترکیب این دو لایه، عملاً هرگونه دسترسی خارجی را می‌بندد. اگر روی VPS کار می‌کنید، راهنمای فایروال نرم‌افزاری در فایروال نرم‌افزاری روی سرور و مقایسه با فایروال ابری در فایروال ابری در برابر سنتی آمده است.

محدودسازی در سطح MySQL و کاربران

پس از محدودسازی شبکه، باید دسترسی‌های کاربران دیتابیس هم محدود شوند. سه اقدام در سطح MySQL:

  • حذف کاربران ناشناس یا اضافه: MySQL به‌طور پیش‌فرض کاربران خالی یا ناشناس دارد که باید حذف شوند:
DROP USER '@'localhost';
DROP USER '@'%';
  • محدودسازی میزبان هر کاربر: هر کاربر باید فقط از میزبان مشخص اجازه اتصال داشته باشد. اگر کاربر باید فقط از localhost وصل شود، میزبانش localhost باشد، نه %:
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'StrongPassw0rd!';
-- نه: CREATE USER 'wpuser'@'%' ...
  • کمترین دسترسی ممکن: برای کاربر وردپرس، فقط دسترسی روی یک دیتابیس مشخص و بدون دسترسی مدیریتی:
GRANT SELECT, INSERT, UPDATE, DELETE ON wordpress_db.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;

در پروژه‌ها، همین سه اقدام، بیشترین اثر را روی کاهش سطح حمله دیتابیس دارد. اگر با مفاهیم دسترسی‌های MySQL تازه آشنا می‌شوید، مدیریت کاربران و دسترسی‌های دیتابیس و مدیریت کاربران MySQL را ببینید.

پیکربندی درست در wp-config وردپرس

در وردپرس، تنظیمات دیتابیس در فایل wp-config.php قرار دارند. سه نکته که در پروژه‌ها رعایت می‌کنم:

  • کاربر دیتابیس، غیر از کاربر روت: هرگز کاربر root را در wp-config.php قرار ندهید؛ کاربر مخصوص وردپرس با دسترسی محدود کافی است.
  • میزبان localhost: در مقدار DB_HOST معمولاً localhost کافی است. اگر سرور دیتابیس جداگانه است، فقط IP داخلی را بگذارید، نه IP عمومی.
  • رمز قوی: رمز دیتابیس، مانند رمز ادمین، باید حداقل ۱۶ کاراکتر و منحصر باشد. اگر رمز را در فایل ذخیره می‌کنید، اطمینان حاصل کنید که فایل فقط برای کاربر وب قابل خواندن است.

در تجربه‌ام، بیشترین نشت اطلاعات از سه اشتباه در همین سه مورد می‌آید: کاربر root در پیکربندی، میزبان عمومی به‌جای localhost و رمز ضعیف. برای مرور اصول کلی، امن‌سازی فایل wp-config و چگونه دیتابیس وردپرس را امن کنیم راهنمای عملی هستند.

wp-config.php مثل گاوصندوق خانه است: اگر کلیدش را در جای اشتباه بگذاری، باقی قفل‌ها معنایی ندارند. کلید گاوصندوق دیتابیس، همان نام کاربری و رمز است.

ابزارهایی که به دسترسی خارجی نیاز دارند

در بعضی پروژه‌ها، ابزارهایی وجود دارند که واقعاً به دسترسی خارجی نیاز دارند. در این حالت، محدودسازی باید هوشمندانه انجام شود، نه به‌طور کامل باز. سه سناریو و راه‌حل:

سناریوراه‌حل امنریسک باقی‌مانده
توسعه لوکالتونل SSH به‌جای باز کردن پورتحداقل
ابزار پشتیبان ابریاجرای پشتیبان روی سرور و ارسال فایلحداقل
مهاجرت دادهخروجی گرفتن از دیتابیس و انتقال فایلموقت

در تجربه‌ام، تونل SSH (Secure Shell) بهترین راه برای نیازهای موقت است؛ چون پورت دیتابیس بسته می‌ماند و داده از تونل رمزنگاری‌شده عبور می‌کند. نمونه دستور:

ssh -L 3306:localhost:3306 user@your-server.com

این دستور، پورت دیتابیس را از سرور به دستگاه لوکال شما تونل می‌کند. ابزارهای پشتیبان و مهاجرت هم اگر روی سرور اجرا شوند و خروجی فایل منتقل شود، نیازی به دسترسی خارجی ندارند. برای اصول کامل امنیت، چگونه دیتابیس وردپرس را امن کنیم و راهنمای امنیت وردپرس برای مبتدیان نکات مکمل دارند.

پایش و لاگ‌گیری تلاش‌های دسترسی

پس از محدودسازی، پایش تلاش‌های دسترسی، لایه اطمینان است. سه سطح پایش که در پروژه‌ها اجرا می‌کنم:

  1. لاگ تلاش‌های ورود ناموفق MySQL: در فایل لاگ MySQL قابل مشاهده است. الگوهای تلاش مکرر از یک IP مشخص، نشانه تلاش نفوذ است.
  2. پایش ورود کاربران دیتابیس: با ابزارهایی مثل SHOW PROCESSLIST می‌توان کاربران فعال و IP آن‌ها را دید. هر اتصال غیرمنتظره، نشانه جدی است.
  3. پایش پورت باز: با ss -tlnp می‌توان بررسی کرد که پورت ۳۳۰۶ روی کدام آدرس باز است. اگر روی 0.0.0.0 باز باشد، یعنی به همه اینترنت باز است.

در تجربه‌ام، این سه پایش ماهانه، تلاش‌های نفوذ را پیش از تبدیل به حادثه لو می‌دهد. برای بررسی لاگ‌ها در سطح دیتابیس، لاگ‌های دیتابیس چگونه بررسی می‌شوند و بررسی لاگ حملات سایت را ببینید.

اشتباهات رایج در محدودسازی دسترسی دیتابیس

در پروژه‌هایی که دسترسی دیتابیس مدیریت شده، چند الگوی تکراری دیده‌ام که امنیت را به‌طور جدی تحت تأثیر می‌گذارد:

  • باز گذاشتن پورت ۳۳۰۶ به‌طور پیش‌فرض: بدون توجه به نیاز واقعی، پورت به همه اینترنت باز می‌ماند.
  • گذاشتن bind-address = 0.0.0.0: MySQL روی همه رابط‌های شبکه گوش می‌دهد؛ یعنی از هر IP قابل دسترس است.
  • کاربر با میزبان %: کاربری که از هر IP اجازه اتصال دارد، در عمل امنیت را بی‌اثر می‌کند.
  • رمز ضعیف یا تکراری: رمز ساده در دیتابیس، دروازه ورود اسکنرهای خودکار است.
  • کاربر root در wp-config: استفاده از کاربر مدیریتی در وردپرس، سطح حمله را به بالاترین حد می‌رساند.
  • نبود فایروال در VPS: سرور بدون فایروال نرم‌افزاری، در برابر اسکنرها و حملات خارجی باز است.
  • بی‌توجهی به کاربران ناشناس MySQL: کاربران پیش‌فرض مثل '@'localhost' در MySQL وجود دارند و باید حذف شوند.
  • نبود پایش دوره‌ای: بدون پایش، نمی‌دانید چه کاربرانی و از کجا وصل می‌شوند و چه تلاش‌هایی برای نفوذ در جریان است.
  • باز کردن دسترسی موقت بدون بستن: دسترسی برای مهاجرت یا توسعه باز می‌شود و بعد فراموش می‌شود؛ ماه بعد، هنوز باز است.

برای مرور ساختاریافته‌تر، اشتباهات رایج امنیت دیتابیس و بهترین روش‌های امنیت MySQL را ببینید. اگر با مباحث پایه امنیت آشنا نیستید، راهنمای امنیت وردپرس برای مبتدیان و اشتباهات امنیتی رایج در وردپرس نکات کاربردی دارند.

پرسش‌های پرتکرار درباره محدودسازی دسترسی دیتابیس

  • چگونه دسترسی خارجی به دیتابیس را محدود کنیم؟ با بستن پورت ۳۳۰۶ در فایروال، تنظیم bind-address = 127.0.0.1 در MySQL، محدودکردن میزبان هر کاربر دیتابیس به localhost یا IP مشخص، اعمال کمترین سطح دسترسی برای هر کاربر، و پایش دوره‌ای تلاش‌های دسترسی.
  • آیا بستن دسترسی خارجی، به سایت آسیب می‌زند؟ نه، اگر سایت روی همان سرور دیتابیس اجرا می‌شود. وردپرس از طریق localhost به دیتابیس وصل می‌شود و نیازی به دسترسی خارجی ندارد. فقط ابزارهایی که از بیرون وصل می‌شوند باید با تونل SSH یا روش‌های دیگر جایگزین شوند.
  • آیا bind-address کافی است یا فایروال هم لازم است؟ هر دو لازم است. bind-address از سمت MySQL محدودیت می‌گذارد؛ فایروال از سمت شبکه. ترکیب هر دو، لایه دفاعی قوی‌تری می‌سازد.
  • چگونه به دیتابیس از راه دور وصل شویم بدون باز کردن پورت؟ از تونل SSH استفاده کنید. با دستور ssh -L 3306:localhost:3306 user@server پورت دیتابیس سرور به دستگاه لوکال تونل می‌شود و ترافیک رمزنگاری‌شده از طریق SSH عبور می‌کند.
  • چه مدت یک‌بار باید دسترسی‌های دیتابیس را بازبینی کنیم؟ هر سه ماه یک بازبینی کامل شامل کاربران، دسترسی‌ها، پورت باز و لاگ‌ها توصیه می‌شود. بازبینی سریع هفتگی برای دیدن اتصالات غیرمنتظره هم مفید است.

دسترسی محدود، بیمه خاموش دیتابیس

دیتابیس، قلب تپنده هر سایت است و محدودکردن دسترسی به آن، ساده‌ترین و ارزان‌ترین اقدام امنیتی است. تجربه‌ام می‌گوید سرورهایی که دسترسی خارجی به دیتابیس را بسته‌اند، حتی اگر در سایر موارد دچار ضعف باشند، از رایج‌ترین حملات خودکار در امان می‌مانند؛ چون بیشتر حملات انبوه، روی باز بودن پورت ۳۳۰۶ و رمزهای ضعیف کار می‌کنند. اگر امروز فقط یک کار می‌کنید، همین حالا با دستور ss -tlnp | grep 3306 بررسی کنید که پورت دیتابیس به کجا باز است؛ اگر به 0.0.0.0 یا :: گوش می‌دهد، همان لحظه پورت را در فایروال ببندید. اگر در پروژه‌ای با چالشی در محدودسازی دسترسی روبه‌رو شده‌اید، برای من جالب است بدانید چه سرویسی نیاز به دسترسی خارجی داشت و چطور تعادل میان امنیت و کارکرد را برقرار کردید؛ تجربه‌تان را در دیدگاه‌ها بنویسید تا برای خواننده بعدی، مسیر روشن‌تری ساخته شود. 🔐