اثنا عشر بناءً

خادم WireGuard مُحصّن مع IPv6 يعمل توجيهه فعليًا

أنشئ نقطة نهاية WireGuard تمنح العملاء عنوان v4 خاصًا وبادئة IPv6 موجهة فعلًا، خلف سياسة nftables التي تحذف كل ما لم يُطلب.

ماذا يُبني هذا

مثيل واحد يشغّل WireGuard، يمنح كل عميل عنوان IPv4 خاص، وعنوان IPv6 موجَّه من /48 الخاص بك، ومحللاً يعيش داخل النفق بحيث لا تسلك استعلامات DNS مساراً مختلفاً عن بقية حركة المرور. جدار الحماية يُسقِط افتراضياً في كلا الاتجاهين. التوجيه مُفعَّل فقط لواجهة النفق، وفقط للاتجاه الصادر.

اختُبر على R-4 في AMS-01 مع Debian 13. WireGuard أحادي التدفق ويعمل في النواة، لذا فإن المزيد من الأنوية لا يفيدك شيئاً حتى تدفع عدة غيغابت عبره. الأهم بكثير هو الموقع: اختر الأقرب إلى مكانك الفعلي، لأن كل ميلي ثانية تضيفها هنا تضيفها إلى كل حزمة.

قبل البدء

  • مثيل منشور وصول جذر عبر SSH.
  • إضافة /48 لـ IPv6 مُفعّلة في اللوحة. الـ /64 المضمن يكفي لعميل واحد، لكن شبكات فرعية لكل عميل من /64 واحد تعني وساطة اكتشاف الجيران، وهذا هواية وليس إعداداً.
  • اسم مضيف يشير إلى المثيل. كل ما يلي يستخدم vpn.example.com.
  • كل عنوان 2001:db8: هنا مساحة توثيق. استبدل البادئة بالمعروضة في صفحة مثيلك.

1. الحزم وإعدادات النواة

apt update && apt full-upgrade -y
apt install -y wireguard-tools nftables unbound qrencode
ip -br link

تلك الأوامر الأخيرة تطبع اسم واجهتك الصادرة. على صور KVM لدينا هو ens3؛ إذا كان مختلفاً، استبدله في كل ما يلي. الآن النواة:

cat > /etc/sysctl.d/99-wireguard.conf <<EOF
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.ens3.accept_ra = 2
net.ipv4.conf.all.rp_filter = 1
EOF
sysctl --system

سطر accept_ra = 2 هو الذي ينساه الناس. تشغيل توجيه IPv6 يجعل النواة تتوقف عن قبول إعلانات الموجّه، يختفي المسار الافتراضي خلال عشر دقائق، وتصبح الآلة مظلمة عبر v6 بينما تستجيب على v4. ضبطه على اثنين يبقي قبول إعلانات الموجّه على مضيف موجِّه.

2. المفاتيح

install -d -m 700 /etc/wireguard
umask 077
wg genkey | tee /etc/wireguard/server.key | wg pubkey > /etc/wireguard/server.pub
wg genkey | tee /etc/wireguard/laptop.key | wg pubkey > /etc/wireguard/laptop.pub
wg genpsk > /etc/wireguard/laptop.psk

المفتاح المشترك مسبقاً ليس اختيارياً في هذا البناء. لا يكلف شيئاً، وهو سطر واحد في كل إعداد، وهو الفرق بين نفق آمن اليوم فقط ونفق يبقى آمناً ضد خصم يسجل الحركة الآن لفك تشفيرها لاحقاً.

3. واجهة الخادم

اكتب /etc/wireguard/wg0.conf، والصق محتويات المفاتيح حيث هو موضح:

[Interface]
Address = 10.7.0.1/24, 2001:db8:1a2b:7::1/64
ListenPort = 51820
PrivateKey = <contents of /etc/wireguard/server.key>
MTU = 1420

[Peer]
# laptop
PublicKey = <contents of /etc/wireguard/laptop.pub>
PresharedKey = <contents of /etc/wireguard/laptop.psk>
AllowedIPs = 10.7.0.2/32, 2001:db8:1a2b:7::2/128

على جانب الخادم AllowedIPs جدول توجيه، وليس قائمة صلاحيات. أعطِ كل نظير العناوين التي يملكها بالضبط ولا أوسع، أو سيتصارع عميلان على نفس المسار وسيتوقف الخاسر ببساطة عن استقبال الحزم.

chmod 600 /etc/wireguard/wg0.conf

4. محلل داخل النفق

توجيه العملاء إلى محلل عام يبطل جزءاً كبيراً من الغاية. Unbound مثبت بالفعل؛ أعطِه /etc/unbound/unbound.conf.d/tunnel.conf:

server:
  interface: 10.7.0.1
  interface: 2001:db8:1a2b:7::1
  access-control: 10.7.0.0/24 allow
  access-control: 2001:db8:1a2b:7::/64 allow
  do-ip6: yes
  prefetch: yes
  hide-identity: yes
  hide-version: yes
  qname-minimisation: yes

لن يبدأ Unbound قبل وجود النفق، لأن تلك العناوين ليست مرفوعة بعد. رتّب الأمر بشكل صحيح بدلاً من محاربته:

systemctl edit unbound
[Unit]
[email protected]
[email protected]

5. جدار الحماية

استبدل /etc/nftables.conf بالكامل:

flush ruleset

table inet filter {
  chain input {
    type filter hook input priority filter; policy drop;
    ct state established,related accept
    ct state invalid drop
    iif lo accept
    ip protocol icmp accept
    ip6 nexthdr icmpv6 accept
    tcp dport 22 accept
    udp dport 51820 accept
    iifname "wg0" udp dport 53 accept
    iifname "wg0" tcp dport 53 accept
  }
  chain forward {
    type filter hook forward priority filter; policy drop;
    ct state established,related accept
    iifname "wg0" oifname "ens3" accept
    iifname "wg0" oifname "wg0" drop
  }
  chain output {
    type filter hook output priority filter; policy accept;
  }
}

table ip nat {
  chain postrouting {
    type nat hook postrouting priority srcnat; policy accept;
    ip saddr 10.7.0.0/24 oifname "ens3" masquerade
  }
}

لاحظ ما هو غائب: لا يوجد جدول NAT لـ IPv6. يخرج العملاء بعنوانهم الخاص من /48 الخاص بك، وهو السبب الكامل لأخذ الـ /48 في المقام الأول. سطر iifname "wg0" oifname "wg0" drop يمنع النظيرين من الوصول لبعضهما، وهو ما تريده إلا إذا كنت تبني شبكة شبكية عمداً.

systemctl enable --now nftables
nft list ruleset | head -20

6. شغّله

systemctl enable --now wg-quick@wg0
systemctl restart unbound
wg show wg0

7. العميل

[Interface]
PrivateKey = <contents of /etc/wireguard/laptop.key>
Address = 10.7.0.2/24, 2001:db8:1a2b:7::2/64
DNS = 10.7.0.1
MTU = 1420

[Peer]
PublicKey = <contents of /etc/wireguard/server.pub>
PresharedKey = <contents of /etc/wireguard/laptop.psk>
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25

لهاتف، حوّل ذلك إلى رمز QR على الخادم وصوّر الطرفية:

qrencode -t ansiutf8 < /root/laptop.conf

على عميل Debian أو Ubuntu، سطر DNS = يتطلب تثبيت openresolv، وإلا فسيطبع wg-quick تحذيراً ويترك محللك القديم في مكانه بصمت. هذا هو السبب الأكثر شيوعاً لنفق يعمل تماماً ويسرّب كل استعلام.

تحقق منه

أربعة فحوصات، بالترتيب. أي فشل يخبرك بالخطوة التي يجب أن تعود إليها.

# on the server, after connecting the client
wg show wg0 latest-handshakes
wg show wg0 transfer

طابع زمني للمصافحة خلال الدقيقتين الأخيرتين وعدادات غير صفرية في كلا الاتجاهين يعنيان أن التشفير والتوجيه سليمان.

# on the client
ping -c3 10.7.0.1
ping -c3 2001:db8:1a2b:7::1
dig @10.7.0.1 paragonvps.com AAAA +short

الأمر الثالث يثبت أن محلل النفق يستجيب. إذا انتهت مهلته، فقد بدأ unbound قبل وجود wg0؛ أعد تشغيله.

الفحص الأخير هو الوحيد الذي يثبت أن حركة مرورك تغادر من حيث تظن، ويتطلب جهازاً ثانياً. أي مثيل آخر في الأسطول يفي بالغرض، في أي مدينة:

# on the second instance
nc -lv 9101

# on the client, tunnel up
curl -m5 -4 http://second.example.com:9101/
curl -m5 -6 http://second.example.com:9101/

يطبع المستمع عنوان مصدر كل اتصال. يجب أن يصل اتصال v4 من خادم WireGuard، لأنه تم تمويهه. يجب أن يصل اتصال v6 من عنوان نفق العميل نفسه داخل /48 الخاص بك، دون تغيير، وهذا هو معنى موجَّه وليس وسيطاً.

عندما يحدث خطأ

العرضالسببالإصلاح
تنجح المصافحة، لا تمر حركة المرورالتوجيه معطّل، أو سلسلة الإرسال تُسقطsysctl net.ipv4.ip_forward، ثم أعد قراءة سلسلة الإرسال
الطلبات الصغيرة تمام، التنزيلات الكبيرة تعلقMTU واكتشاف المساراخفض كلا الإعدادين إلى MTU = 1380 وأعد المحاولة
يختفي IPv6 بعد عشر دقائق تقريباً من الإقلاعالتوجيه قتل إعلانات الموجّهaccept_ra = 2 على الواجهة الصادرة
يحل DNS خارج النفقالعميل تجاهل DNS =ثبّت openresolv على العميل
كل شيء اختفى بعد إعادة تشغيلالوحدات لم تُفعّل أبداًsystemctl enable wg-quick@wg0 nftables unbound

من هنا، الخطوات التالية المنطقية هي نقطة نهاية ثانية في منطقة أخرى ومجموعة مراقبة تخبرك عندما تتوقف إحداهما عن الاستجابة. كلاهما مغطى في مكان آخر في الأدلة؛ صفحة الشبكة تشرح ما تفعله الحافة بحركة مرورك قبل أن تصل إليك.

جاهز عندما تكون

اختر مدينة. اختر الحجم. ادفع بالعملة الرقمية.

لا نماذج عن هويتك، ولا انتظار لموافقة بشرية، ولا مكالمة للتحقق من أي شيء. بمجرد تصفية الفاتورة، تصل بيانات الدخول إلى بريدك الإلكتروني.