تُعد PostgreSQL واحدة من أقوى قواعد البيانات العلائقية مفتوحة المصدر في العالم. لكن، دعنا نتفق على قاعدة ذهبية: القوة وحدها لا تكفي إذا كان الباب مفتوحاً. افتراضياً، تقبل PostgreSQL الاتصالات المحلية فقط، وعندما نفتح المجال للاتصال عن بُعد، فإن البيانات تنتقل بصورة نصوص غير مشفرة (Plain Text).
هذا الدليل سيأخذ بيدك خطوة بخطوة لتأمين خادم PostgreSQL الخاص بك باستخدام تشفير SSL/TLS على نظام Rocky Linux، لضمان أن بياناتك تنتقل بأمان تام ولا يمكن لأحد الاطلاع عليها في الطريق.
لماذا يعتبر تشفير SSL/TLS ضرورياً؟
عندما تتصل بقاعدة البيانات عبر الشبكة، فإن كل شيء ترسله – بما في ذلك اسم المستخدم، كلمة المرور، ونتائج استعلاماتك – يسافر بين جهازك والخادم. بدون تشفير، يمكن لأي شخص يراقب الشبكة قراءة هذه البيانات بسهولة.
يحل تشفير SSL/TLS هذه المشكلة عبر:
- تشفير البيانات: تحويل البيانات إلى رموز لا يمكن فهمها أثناء انتقالها.
- حماية الهوية: منع سرقة كلمات المرور وهي في طريقها للخادم.
- منع هجمات (MITM): التأكد من أنك تتصل بالخادم الحقيقي وليس بجهة وهمية تعترض الاتصال.
- الامتثال للمعايير: تلبية متطلبات أمان البيانات العالمية.
المتطلبات المسبقة
قبل أن نبدأ، تأكد من توفر الآتي:
- خادم يعمل بنظام Rocky Linux.
- قاعدة بيانات PostgreSQL 18 مثبتة.
- صلاحيات المدير (Root) أو حساب بصلاحيات
sudo. - معرفة بسيطة باستخدام سطر الأوامر (Command Line).
فهم هيكل الملفات في Rocky Linux
على عكس أنظمة Debian أو Ubuntu، تقوم توزيعات RHEL (مثل Rocky Linux) بتخزين ملفات PostgreSQL في مسار مختلف قليلاً:
المسار الرئيسي هو: /var/lib/pgsql/[version]/data/
بالنسبة للإصدار 18، سيكون المسار: /var/lib/pgsql/18/data/
هذا المجلد يحتوي على "عقل" قاعدة البيانات:
postgresql.conf: ملف الإعدادات الرئيسي.pg_hba.conf: ملف التحكم في من يُسمح له بالدخول (المصادقة).- ملفات البيانات والشهادات الأمنية (التي سنضيفها الآن).
الخطوة 1: إنشاء شهادات الأمان (SSL Certificates)
لديك خياران هنا: إما شهادة "موقعة ذاتياً" (Self-signed) أو شهادة رسمية من جهة موثوقة (CA).
الخيار أ: شهادة موقعة ذاتياً (الخيار الأسهل والأكثر شيوعاً)
هذا الخيار مثالي للتطبيقات الداخلية، بيئات التطوير، أو إذا لم يكن لديك اسم نطاق (Domain Name). التشفير هنا قوي تماماً مثل الشهادات المدفوعة، الفرق الوحيد هو أن المتصفحات أو البرامج قد تخبرك أنها "لا تعرف مصدر هذه الشهادة"، لكننا سنحل ذلك.
سنقوم بإنشاء شهادة صالحة لمدة عام كامل:
cd /tmp
sudo openssl req -new -x509 -days 365 -nodes -text \
-out server.crt \
-keyout server.key \
-subj "/CN=YOUR_SERVER_IP"
شرح سريع للأمر:
-days 365: الشهادة صالحة لمدة 365 يوماً.-nodes: لا تضع كلمة مرور على المفتاح الخاص (ضروري لكي تعمل الخدمة تلقائياً).-subj: هنا نحدد لمن هذه الشهادة. استبدلYOUR_SERVER_IPبعنوان IP الخاص بخادمك.
الخيار ب: شهادة Let's Encrypt (للإنتاج مع وجود نطاق)
إذا كان لديك اسم نطاق (Domain) يشير للخادم، يمكنك استخدام شهادة مجانية وموثوقة:
# تثبيت الأداة
sudo dnf install certbot
# طلب الشهادة (استبدل النطاق db.yourdomain.com بالنطاق الخاص بك)
sudo certbot certonly --standalone -d db.yourdomain.com
# نسخ الشهادات لمجلد قاعدة البيانات
sudo cp /etc/letsencrypt/live/[db.yourdomain.com/fullchain.pem](https://db.yourdomain.com/fullchain.pem) \
/var/lib/pgsql/18/data/server.crt
sudo cp /etc/letsencrypt/live/[db.yourdomain.com/privkey.pem](https://db.yourdomain.com/privkey.pem) \
/var/lib/pgsql/18/data/server.key
ملاحظة: شهادات Let's Encrypt تنتهي كل 90 يوماً، لذا ستحتاج لتجديدها.
الخطوة 2: تثبيت الشهادات وضبط الصلاحيات
الآن، لننقل الشهادات التي أنشأناها إلى مجلد بيانات PostgreSQL. هذه الخطوة حساسة جداً لأن PostgreSQL دقيق للغاية بشأن "من يملك الحق" في قراءة هذه الملفات.
# نقل الملفات
sudo mv server.key server.crt /var/lib/pgsql/18/data/
# تغيير المالك ليكون مستخدم postgres فقط
sudo chown postgres:postgres /var/lib/pgsql/18/data/server.key
sudo chown postgres:postgres /var/lib/pgsql/18/data/server.crt
# ضبط التصاريح (خطوة حرجة!)
sudo chmod 600 /var/lib/pgsql/18/data/server.key
sudo chmod 644 /var/lib/pgsql/18/data/server.crt
لماذا هذا التعقيد؟
chmod 600للمفتاح الخاص (server.key): يعني أنه لا يحق لأحد في النظام قراءة هذا الملف سوى المستخدمpostgres. إذا كان الملف متاحاً للغير، سترفض قاعدة البيانات العمل لحماية نفسها.
الخطوة 3: إعداد PostgreSQL لاستخدام SSL
الآن الملفات في مكانها، علينا إخبار PostgreSQL بتفعيل التشفير.
افتح ملف الإعدادات الرئيسي:
sudo vi /var/lib/pgsql/18/data/postgresql.conf
ابحث عن الإعدادات التالية وقم بتعديلها (أو إضافتها):
# تفعيل التشفير
ssl = on
# تحديد مكان الملفات (مسار نسبي داخل مجلد البيانات)
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
# اختياري: منع بروتوكولات التشفير القديمة
ssl_min_protocol_version = 'TLSv1.2'
تأكد أيضاً من أن الخادم يستمع للاتصالات الخارجية (إذا كنت تستخدم منفذاً مخصصاً مثل 3222):
listen_addresses = '*'
port = 3222
الخطوة 4: ضبط صلاحيات دخول العملاء (pg_hba.conf)
هذا الملف هو "حارس البوابة". هو الذي يقرر من يدخل وكيف.
افتح الملف:
sudo vi /var/lib/pgsql/18/data/pg_hba.conf
اختر مستوى الأمان الذي يناسبك وأضف السطر المناسب:
أ. المستوى المتوازن (مفضل): إجبار التشفير هذا الخيار يسمح بالاتصال فقط إذا كان مشفراً بـ SSL.
# TYPE DATABASE USER ADDRESS METHOD
hostssl all all 0.0.0.0/0 scram-sha-256
ب. مستوى "البارانويا" (أمان قصوى): يتطلب شهادة من العميل أيضاً (Client Certificate).
hostssl all all 0.0.0.0/0 scram-sha-256 clientcert=verify-full
hostssl: تعني "لا تقبل أي اتصال من هذا النوع إلا إذا كان مشفراً".scram-sha-256: هي آلية المصادقة والتحقق من كلمة المرور الأكثر أماناً حالياً (أفضل من md5 القديمة).0.0.0.0/0: تعني السماح لأي عنوان IP (يُفضل تقييدها بنطاق IPs محدد في بيئة الإنتاج).
الخطوة 5: إعداد جدار الحماية (Firewall)
لا تنسَ فتح المنفذ في جدار الحماية، وإلا لن يصل الاتصال للخادم أصلاً.
# إضافة المنفذ (استخدم 5432 إذا لم تغيره، أو 3222 كما في مثالنا)
sudo firewall-cmd --permanent --add-port=3222/tcp
sudo firewall-cmd --reload
# التأكد من نجاح الأمر
sudo firewall-cmd --list-ports
الخطوة 6: إعادة التشغيل والتحقق
لنعد تشغيل الخدمة لتطبيق التغييرات.
sudo systemctl restart postgresql-18
تأكد من أن الخدمة تعمل بسلام:
sudo systemctl status postgresql-18
تحقق محلياً هل تم تفعيل SSL؟
sudo -u postgres psql -p 3222 -c "SHOW ssl;"
يجب أن تكون النتيجة: on.
الخطوة 7: اختبار الاتصال
من جهاز العميل (Remote)
لنجرب الاتصال الآن من جهاز آخر باستخدام سطر الأوامر:
psql "host=YOUR_SERVER_IP port=3222 user=your_username dbname=your_db sslmode=require"
بمجرد الاتصال، اكتب هذا الأمر داخل SQL للتأكد من أنك محمي:
SELECT ssl_is_used();
إذا كانت الإجابة t (True) اتصالك مشفر.
أمثلة برمجية للمطورين
Node.js (مكتبة pg):
const client = new Client({
host: 'YOUR_SERVER_IP',
ssl: {
// لأننا نستخدم شهادة موقعة ذاتياً، يجب السماح بها
rejectUnauthorized: false
// في الإنتاج مع شهادة حقيقية، اجعلها true
}
});
Python (مكتبة psycopg2):
conn = psycopg2.connect(
host="YOUR_SERVER_IP",
sslmode="require"
)
Java (JDBC): أضف ?ssl=true&sslmode=require لنهاية رابط الاتصال (URL).
استكشاف الأخطاء وإصلاحها (Troubleshooting)
1. رسالة الخطأ: "private key file has group or world access"
- السبب: تصاريح ملف المفتاح
server.keyواسعة جداً. - الحل: نفذ الأمر
sudo chmod 600 .../server.keyفوراً.
2. رسالة الخطأ: "certificate verify failed"
- السبب: العميل يحاول التحقق من موثوقية الشهادة وهي "موقعة ذاتياً".
- الحل: غيّر إعداد العميل ليكون
sslmode=requireبدلاً منverify-full، أو فعّل خيار قبول الشهادات غير الموثوقة في الكود (مثلrejectUnauthorized: false).
3. لا يمكن الاتصال (Connection Refused)
- تأكد من إعداد
listen_addresses = '*'في ملفpostgresql.conf. - تأكد من أن جدار الحماية (Firewall) يسمح بمرور البيانات عبر المنفذ.
نصيحة أخيرة
باتباعك لهذه الخطوات، أنت لم تقم فقط بتنفيذ مهمة تقنية، بل قمت بحماية بياناتك وبيانات عملائك من المخاطر. العملية قد تبدو طويلة، لكنها استثمار ضروري لراحة بالك.
إذا واجهتك أي مشكلة، راجع السجلات (Logs):
sudo tail -f /var/lib/pgsql/18/data/log/postgresql-*.log