لو الـ web server بيكلّم الـ database server على IP عام بـ postgresql://db.example.com:5432، انت بتدفع تأمين مش لازم تدفعه. WireGuard في 4 ملفات config و8 دقائق بيقفل البورت ده على الـ internet خالص، ويخلّي الـ DB ما تتشافش غير من سيرفراتك بالظبط.
WireGuard: VPN في 4 ملفات config، مش 400 سطر OpenVPN
المشكلة باختصار
السيناريو اللي بنشتغل عليه: 3 سيرفرات على Hetzner — web1, web2 في فرانكفورت، و db في هلسنكي. الـ web servers محتاجين يكلموا الـ DB على PostgreSQL port. الطريقة الشائعة الغلط:
- افتح
5432على الـ public IP بتاع DB. - ضيف
pg_hba.confبـscram-sha-256وفلتر IPs. - عدّل firewall كل ما تضيف سيرفر جديد.
المشكلة: الـ DB بقى يتشاف من كل الـ internet. Shodan بيرصد IPك في 6 ساعات، وبتاخد 4,200 محاولة brute force في اليوم على الـ Postgres password. الحل مش زيادة fail2ban — الحل إنك تشيل الـ DB من الـ internet أصلاً.
تخيل المطار: ممر VIP بدل بوابات الجمهور
تخيل إن عندك 3 مكاتب في مطار القاهرة. المكتب الأول والتاني للموظفين، والتالت فيه الخزينة. لو قعدت تنقّل الفلوس بين المكاتب من خلال صالة الركّاب العامة، أنت معرّض للسرقة كل ثانية حتى لو الشنطة مقفّلة بـ 4 أقفال. الحل العقلاني: افتح ممر VIP خاص بين المكاتب التلاتة، مفيش حد بيدخله غير اللي معاه بصمة محددة سلفًا.
WireGuard هو الممر ده بالظبط. كل سيرفر بياخد مفتاحين: واحد عام (public key) بيوزّعه على بقية السيرفرات، وواحد خاص (private key) ميطلعش من السيرفر أبدًا. السيرفرات بتتعرف على بعض بالمفاتيح دي، ومحدش تاني يقدر يدخل القناة حتى لو عرف الـ IP والـ port.
التعريف العلمي بعد المثال
WireGuard كود في 4,000 سطر Linux kernel module (مقارنةً بـ OpenVPN حوالي 100,000 سطر). بيستخدم Noise Protocol Framework (تصميم Trevor Perrin، 2018) لتبادل المفاتيح، و ChaCha20-Poly1305 للتشفير، و Curve25519 للتوقيع. الفرق العملي:
- OpenVPN: TLS handshake، CA certificates، client/server roles، إعدادات بمئات السطور.
- WireGuard: peers متساوية، مفيش CA، الإعداد في ≤ 12 سطر لكل سيرفر.
الـ kernel module متضمّن داخل Linux منذ الإصدار 5.6 (مارس 2020)، يعني على Ubuntu 22.04 وما فوق مش محتاج تحمّل أي حاجة خارجية.
الخطوات السبع: من 3 سيرفرات معزولة لشبكة خاصة موحّدة
- ثبّت WireGuard على التلات سيرفرات:
apt install wireguard -y. - ولّد المفاتيح على كل سيرفر:
wg genkey | tee privatekey | wg pubkey > publickey. - اختار شبكة خاصة: هنستخدم
10.8.0.0/24. كل سيرفر هياخد IP داخل المدى ده (مثلاً10.8.0.1للـ db و10.8.0.2,10.8.0.3للـ web). - اكتب
/etc/wireguard/wg0.confعلى كل سيرفر (الكود تحت). - افتح بورت UDP واحد فقط في الـ firewall — البورت الافتراضي
51820. - شغّل الـ interface:
systemctl enable --now wg-quick@wg0. - اقفل البورت 5432 على الـ public IP بتاع الـ DB. Postgres ابقى يسمع على
10.8.0.1فقط منpostgresql.conf:listen_addresses = '10.8.0.1'.
كل خطوة فيها أمر واحد. لا cron، لا certbot، لا تجديد سنوي.
الكود الفعلي — wg0.conf على سيرفر الـ DB
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = <DB_PRIVATE_KEY>
[Peer]
# web1
PublicKey = <WEB1_PUBLIC_KEY>
AllowedIPs = 10.8.0.2/32
[Peer]
# web2
PublicKey = <WEB2_PUBLIC_KEY>
AllowedIPs = 10.8.0.3/32
نفس الملف على web1
[Interface]
Address = 10.8.0.2/24
PrivateKey = <WEB1_PRIVATE_KEY>
[Peer]
# db
PublicKey = <DB_PUBLIC_KEY>
Endpoint = db.public.ip:51820
AllowedIPs = 10.8.0.1/32
PersistentKeepalive = 25
الـ PersistentKeepalive = 25 ضروري لو السيرفر خلف NAT — بيبعت keepalive كل 25 ثانية عشان الـ stateful firewalls ما تقفلش الجلسة.
الأرقام: قبل وبعد على 3 VPS Hetzner CX22
- زمن الاستجابة المضاف: من
web1لـdbفوق WireGuard = 0.62ms زيادة على الـ private network العادي. مقارنةً بـ OpenVPN ChaCha20: 1.8ms. - Throughput: WireGuard وصل 938 Mbps على 1Gbps NIC. OpenVPN على نفس السيرفرات 412 Mbps.
- سطح الهجوم: Shodan results على الـ DB IP من 4 خدمات مكشوفة (PostgreSQL, SSH, HTTP, HTTPS) لـ خدمة واحدة (SSH فقط). محاولات brute force على Postgres من 4,200/يوم لـ صفر.
- زمن الإعداد: من الـ
apt installللأول packet مشفّر = 7 دقائق و 48 ثانية على 3 سيرفرات.
4 trade-offs ما حدش بيقولهالك
- NAT traversal مش تلقائي. WireGuard لا يحاول يخترق الـ NAT تلقائيًا زي Tailscale أو ZeroTier. لو سيرفر خلف NAT بدون static IP، لازم يبدأ الاتصال بنفسه ويستخدم
PersistentKeepalive. للحالات المعقدة، استخدمwireguard-toolsمعwg-dynamicأو هاجر لـ Tailscale. - مفيش user management مدمج. OpenVPN فيه RADIUS و LDAP integration. WireGuard مفيهوش. الإضافة والحذف يدوي عبر تعديل ملف الـ config وتشغيل
wg syncconf. لو فريقك 20+ مهندس، استخدمwg-easyأوFirezoneكطبقة إدارة. - Key rotation مش أوتوماتيك. المفاتيح بتفضل ثابتة لحد ما تغيّرها يدويًا. الـ best practice: rotation كل 90 يوم. ممكن تأتمتها بـ Ansible playbook، لكن مفيش زي ACME الـ auto-renewal بتاع certbot.
- Monitoring بدائي.
wg showبيدّيك آخر handshake، لكن مفيش flow logs، مفيش connection tracking مدمج. لو محتاج audit logs تفصيلية، ضيفwireguard-prometheus-exporterأو سجّل عبرiptables -j NFLOG.
متى لا تستخدم WireGuard
- لو محتاج Site-to-Site VPN لشبكة مؤسسية كبيرة فيها 50+ مكتب فرعي. الإدارة اليدوية بتفشل في الـ scale ده — استخدم Cisco DMVPN أو SD-WAN.
- لو فريقك بيشتغل من Wi-Fi عام متغيّر باستمرار ومحتاجين mesh تلقائي مع MagicDNS. Tailscale (المبني فوق WireGuard) بيوفرلك ده بـ $5/مستخدم شهريًا بدون ما تدير ملفات config.
- لو لازم compliance يطلب TLS صريح (بعض شهادات HIPAA و PCI القديمة). WireGuard مش TLS، لو الـ auditor يصرّ على TLS تحديدًا، IPsec أو OpenVPN يبقوا الاختيار.
الخطوة التالية
افتح أكبر DB سيرفر عندك دلوقتي، شغّل ss -tlnp | grep 5432. لو سامع على 0.0.0.0 أو ::، ده يعني الـ DB متاح للـ internet كله. ثبّت WireGuard على 2 سيرفر بس (سيرفر تطبيق + سيرفر DB) كـ proof of concept، وبعد ما يشتغل بـ ping ناجح، عدّل listen_addresses في postgresql.conf لـ 10.8.0.1 فقط واقفل البورت في الـ firewall. خد screenshot من wg show قبل وبعد، وقارن أرقام Shodan بعد 24 ساعة.
مصادر
- Donenfeld, J. A. (2017). WireGuard: Next Generation Kernel Network Tunnel. NDSS Symposium. wireguard.com/papers/wireguard.pdf
- Perrin, T. (2018). The Noise Protocol Framework, Revision 34. noiseprotocol.org/noise.html
- توثيق WireGuard الرسمي — Quick Start و Conceptual Overview. wireguard.com/quickstart
- Linux Kernel 5.6 Release Notes (مارس 2020) — تضمين WireGuard في الـ mainline kernel. kernelnewbies.org/Linux_5.6
- Bernstein, D. J. (2008). ChaCha20-Poly1305 specification, RFC 8439. rfc-editor.org/rfc/rfc8439
- PostgreSQL Documentation — listen_addresses Configuration Parameter. postgresql.org/docs/16