> ## Content Index
> Fetch the complete content index at: https://arabroot.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# ما هو النفق Tunnel في الشبكات؟ أنفاق SSH والأنفاق العكسية وGRE وVXLAN
- URL: https://arabroot.io/articles/ما-هو-النفق-tunnel-في-الشبكات/
- Published: 2026-10-05T07:45:00.000Z
- Updated: 2026-10-05T13:28:32.000Z
- Description: كيف تصل إلى قاعدة بيانات لا تراها من الإنترنت، وتنشر خدمة من خلف CGNAT دون فتح منافذ، وتربط شبكتين، بأنفاق SSH وfrp وVXLAN مع أوامر ومخرجات حقيقية، ومتى تحتاج إلى VPN بدلاً منها.
- Author: فريق عرب رووت
- Tags: الأدلة التقنية, الشبكات والوصول, الاستضافة الذاتية, هوم لاب

لنفرض أن قاعدة البيانات Database على سيرفرك تستمع على `localhost` فقط كما ينبغي، وأنك تريد اليوم أن تفتحها من جهازك ببرنامج مثل DBeaver لتصلح سجلاً واحداً، أو أن لديك تطبيقاً يعمل على جهاز في المنزل خلف CGNAT ولا يوجد لديك عنوان عام تفتح عليه منفذاً، أو أنك في شبكة عمل لا تسمح إلا باتصال واحد محدد. والحل السريع الذي يخطر على البال في كل هذه الحالات هو أن تفتح المنفذ Port للإنترنت، وهذا الحل إما أنه لا يعمل أصلاً، وإما أنه يكشف خدمة لا ينبغي أن يراها أحد. والحل الذي يستخدمه مديرو الأنظمة منذ سنوات هو النفق Tunnel، أي أن تحمل الاتصال الذي تحتاجه داخل اتصال آخر مسموح به.

وكلمة النفق تظهر في أماكن كثيرة على الموقع، في نفق SSH الذي نفتح به واجهات الإدارة في أغلب الأدلة، وفي Cloudflare Tunnel الذي ننشر به خدمات المنزل، وفي WireGuard وشبكات VPN، لذلك سوف نجمعها هنا مرة واحدة ونشرح ما الذي يجمعها وما الذي يفرق بينها. أما شبكات VPN نفسها، أي أنواعها وبروتوكولاتها ومصطلحاتها، فقد شرحناها في [ما هو VPN؟ شرح للمبتدئين](https://arabroot.io/articles/%D9%85%D8%A7-%D9%87%D9%88-vpn-%D8%B4%D8%B1%D8%AD-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/)، ولن نكررها هنا.

وسوف نناقش في هذا المقال ما يلي:

- فكرة النفق، والمشكلات الأربع التي يحلها.
- أنفاق SSH بأنواعها الثلاثة: التوجيه المحلي `-L`، والتوجيه العكسي `-R`، والتوجيه الديناميكي `-D`، بأوامر ومخرجات حقيقية، ومعها حالة عملية للوصول إلى جهاز في المنزل خلف CGNAT من شبكة عمل لا تسمح إلا ب RDP.
- الأنفاق العكسية Reverse Tunnels التي تنشر خدمة من خلف NAT عبر سيرفر وسيط: Cloudflare Tunnel وfrp وrathole وPangolin، مع مثال كامل ل frp.
- أنفاق طبقة الشبكة GRE وIP-in-IP وVXLAN، ولماذا لا يوجد فيها أي تشفير.
- جدول يقارن بين الأنواع، ثم كيف تختار النفق المناسب لحالتك، وأخطاء الأمان الشائعة.

## ما هو النفق، ولماذا نحتاجه؟

النفق Tunnel هو أن تأخذ اتصالاً أو بروتوكولاً Protocol وتضعه داخل اتصال آخر، فيسير الأول محمولاً داخل الثاني حتى يصل إلى الطرف الآخر من النفق، وهناك يخرج ويكمل طريقه كأنه بدأ من هناك. والتشبيه الأقرب هو الظرف داخل الظرف، فأنت تضع رسالة موجهة إلى زميل في قسم داخلي داخل ظرف موجه إلى استقبال الشركة، فساعي البريد لا يرى إلا العنوان الخارجي، والاستقبال يفتح الظرف الخارجي ويوصل الرسالة الداخلية إلى صاحبها. واسم هذه العملية في الشبكات التغليف Encapsulation.

الصورة التالية تبين الفكرة في أبسط أشكالها، فجدار الحماية Firewall لا يسمح إلا بالمنفذ 22، والاتصال بقاعدة البيانات على المنفذ 5432 يمر داخل اتصال SSH:

![رسم من جزأين: في الأول يحاول جهاز محمول الاتصال بقاعدة بيانات على المنفذ 5432 فيمنعه جدار الحماية، وفي الثاني يمر الاتصال نفسه داخل أنبوب SSH على المنفذ 22 عبر جدار الحماية إلى السيرفر ثم إلى قاعدة البيانات](https://arabroot.io/content/images/2026/10/tunnels-01-why-tunnel.webp)

جدار الحماية يرى اتصال SSH فقط، واتصال قاعدة البيانات يسير داخله

ونحتاج إلى النفق في أربع حالات تتكرر كثيراً:

1. **الوصول إلى خدمة غير منشورة**: قاعدة بيانات أو واجهة إدارة Admin UI تستمع على `127.0.0.1` على السيرفر، ولا تريد أن تفتح منفذها للإنترنت ولو لساعة.
2. **المرور عبر شبكة تمنعك**: شبكة عمل أو فندق لا تسمح إلا بمنافذ معينة، فتحمل ما تحتاجه داخل الاتصال المسموح.
3. **ربط شبكتين لا تستطيعان التوجيه Routing إلى بعضهما**: فرع وفرع آخر، أو سيرفرات في مزودين مختلفين، كل منها بعناوين خاصة Private IPs لا يعرفها الإنترنت.
4. **نشر خدمة من خلف NAT أو CGNAT دون فتح منافذ**: جهاز في المنزل ليس له عنوان عام، فيتصل هو بسيرفر وسيط ويستقبل الزوار عبر هذا الاتصال.

وقد يتساءل البعض: أليس هذا كله هو VPN؟ والإجابة أن كل VPN نفق، وليس كل نفق VPN، فالشبكة الخاصة الافتراضية VPN نفق على مستوى الشبكة يربط جهازاً أو شبكة كاملة بشبكة أخرى مع التشفير Encryption والمصادقة Authentication، أما نفق SSH مثلاً فيحمل منفذاً واحداً أو بضعة منافذ، ونفق VXLAN يحمل الحزم Packets دون أي تشفير. لذلك سوف نبدأ بأبسط الأنواع وأكثرها استخداماً، وهو نفق SSH الموجود على كل سيرفر Linux.

## أنفاق SSH: النفق الموجود على كل سيرفر

برنامج OpenSSH الذي تدخل به إلى سيرفرك لا ينقل الأوامر فقط، وإنما يستطيع أن يحمل اتصالات TCP أخرى داخل الاتصال المشفر نفسه، واسم هذه الميزة توجيه المنافذ Port Forwarding، ولها ثلاثة أشكال يشرحها [دليل الأمر ssh](https://man.openbsd.org/ssh?ref=arabroot.io): المحلي `-L` والعكسي `-R` والديناميكي `-D`. وكل الأمثلة التالية تفترض أنك تدخل إلى السيرفر بمفتاح SSH Key وليس بكلمة مرور، كما في [دليل تأمين خادم VPS من أول دخول](https://arabroot.io/articles/%D8%AA%D8%A3%D9%85%D9%8A%D9%86-%D8%AE%D8%A7%D8%AF%D9%85-vps-%D9%85%D9%86-%D8%A3%D9%88%D9%84-%D8%AF%D8%AE%D9%88%D9%84/).

### التوجيه المحلي ssh -L: الوصول إلى قاعدة بيانات على السيرفر

لنأخذ مثالاً، سيرفر عليه PostgreSQL تستمع على `localhost` فقط، وأنت تريد أن تتصل بها من جهازك. الحل الأول الذي يخطر على البال هو أن تغير `listen_addresses` إلى `*` وتفتح المنفذ 5432 في جدار الحماية، أو أن تضيف السطر `ports: ["5432:5432"]` في ملف Compose، وهذا الحل غير مناسب إطلاقاً، والسبب أن قاعدة البيانات تصبح أمام كل من يفحص الإنترنت، وأن Docker يتجاوز `ufw` كما شرحنا في [شبكات Docker وأفضل الممارسات](https://arabroot.io/articles/%D8%B4%D8%A8%D9%83%D8%A7%D8%AA-docker-%D9%88%D8%A3%D9%81%D8%B6%D9%84-%D8%A7%D9%84%D9%85%D9%85%D8%A7%D8%B1%D8%B3%D8%A7%D8%AA/). والحل الثاني أن تفتح المنفذ لعنوانك فقط، ولكن عنوان المنزل يتغير، وعنوان المقهى لا تعرفه مسبقاً. أما الحل الصحيح فهو أن تترك قاعدة البيانات كما هي، وتفتح نفقاً من جهازك عبر SSH.

وقبل ذلك لاحظ أن الاتصال المباشر من جهازك يفشل كما هو متوقع:

```bash
psql -h 203.0.113.10 -U postgres -c "select 1"
```

```text
psql: error: connection to server at "203.0.113.10", port 5432 failed: Connection refused
	Is the server running on that host and accepting TCP/IP connections?
```

الآن سوف نقوم بفتح النفق، والأمر التالي يجعل ssh يستمع على المنفذ 5432 على جهازك، وكل اتصال يصل إليه يحمله داخل اتصال SSH إلى السيرفر، وهناك يتصل sshd بالعنوان `localhost:5432`:

```bash
ssh -f -N -L 5432:localhost:5432 deploy@203.0.113.10
```

والصورة التالية تبين ما يحدث في الخطوات الثلاث:

![رسم يوضح جهازاً محمولاً يستمع فيه ssh على 127.0.0.1:5432، وأنبوب SSH على المنفذ 22 يعبر الإنترنت إلى sshd على السيرفر، ثم يتصل sshd بقاعدة PostgreSQL على localhost:5432، مع ثلاث خطوات مرقمة](https://arabroot.io/content/images/2026/10/tunnels-02-ssh-local.webp)

التوجيه المحلي: المنفذ على جهازك، والاتصال الأخير يفتحه السيرفر

نتأكد أن ssh يستمع على جهازك، ثم نتصل بقاعدة البيانات عبر النفق:

```bash
ss -tlnp | grep 5432
psql -h 127.0.0.1 -U postgres -c "select version();"
```

والمخرج سوف يكون كما يلي:

```text
LISTEN 0      128        127.0.0.1:5432       0.0.0.0:*    users:(("ssh",pid=303,fd=5))
LISTEN 0      128            [::1]:5432          [::]:*    users:(("ssh",pid=303,fd=4))
                                         version
-----------------------------------------------------------------------------------------
 PostgreSQL 18.0 on x86_64-pc-linux-musl, compiled by gcc (Alpine 14.2.0) 14.2.0, 64-bit
(1 row)
```

في الإعداد أعلاه لاحظ التالي:

- الصيغة هي `-L [عنوان_محلي:]منفذ_محلي:الوجهة:منفذ_الوجهة`، والوجهة `localhost` تعني السيرفر وليس جهازك، والسبب أن sshd على السيرفر هو من يفتح الاتصال الأخير.
- ssh يستمع على `127.0.0.1` فقط افتراضياً، فلا يستطيع جهاز آخر في شبكتك أن يستخدم النفق، وهذا ما تريده في الغالب.
- الخيار `-N` يعني لا تشغل أي أمر على السيرفر، والخيار `-f` يرسل ssh إلى الخلفية بعد الاتصال. وإذا كان المنفذ 5432 مستخدماً على جهازك فاختر منفذاً آخر مثل `-L 15432:localhost:5432` واتصل ب `127.0.0.1:15432`.

والوجهة لا يلزم أن تكون على السيرفر نفسه، فأي جهاز يصل إليه السيرفر يمكنك الوصول إليه عبر النفق. لنفرض أن لدى السيرفر شبكة داخلية فيها تطبيق اسمه `app.internal` لا يراه جهازك أصلاً:

```bash
curl -sS -m 5 http://app.internal/
ssh -f -N -L 8080:app.internal:80 deploy@203.0.113.10
curl -s http://127.0.0.1:8080/ | grep -E "^(Hostname|RemoteAddr|Host):"
```

```text
curl: (6) Could not resolve host: app.internal (Domain name not found)
Hostname: app
RemoteAddr: 192.168.80.2:46310
Host: 127.0.0.1:8080
```

لاحظ أن التطبيق يرى الاتصال قادماً من `192.168.80.2`، وهو عنوان السيرفر على الشبكة الداخلية وليس عنوان جهازك، لذلك فإن أي قاعدة في التطبيق تسمح بعناوين الشبكة الداخلية سوف تسمح لك أيضاً، وهذا يفيدك ويفيد من يسرق مفتاحك بالقدر نفسه.

### ماذا لو كان التوجيه ممنوعاً على السيرفر؟

الإعداد [AllowTcpForwarding](https://man.openbsd.org/sshd%5Fconfig?ref=arabroot.io#AllowTcpForwarding) في ملف `/etc/ssh/sshd_config` قيمته الافتراضية `yes`، وهذا حال Ubuntu وDebian، ولكن بعض التوزيعات والسيرفرات المؤمنة تغيره إلى `no`، ومنها Alpine التي يأتي ملفها بالسطر `AllowTcpForwarding no`. وفي هذه الحالة ينجح الأمر نفسه ويستمع ssh على جهازك، ولكن كل اتصال عبر النفق يفشل، والمخرج سوف يكون كما يلي من psql ثم من ssh:

```text
psql: error: connection to server at "127.0.0.1", port 5432 failed: server closed the connection unexpectedly
	This probably means the server terminated abnormally
	before or while processing the request.
channel 2: open failed: administratively prohibited: open failed
```

والعبارة `administratively prohibited` تعني أن السيرفر رفض فتح القناة Channel بسبب إعداده، وليس بسبب الشبكة، وفي سجل sshd سوف تجد السطر التالي:

```text
refused local port forward: originator 127.0.0.1 port 35972, target localhost port 5432
```

وإذا كان السيرفر سيرفرك فغير القيمة إلى `yes` وأعد تحميل sshd، أما إذا كان سيرفر جهة أخرى فهذا قرار أمني من مديره، فلا تحاول الالتفاف عليه.

### التوجيه العكسي ssh -R: السيرفر يفتح منفذاً يعود إلى جهازك

التوجيه العكسي هو عكس السابق تماماً، فالمنفذ يفتح على السيرفر، وكل اتصال يصل إليه يعود عبر النفق إلى جهازك. والفائدة الكبرى هنا أن الاتصال يبدأ من جهازك، فيعمل حتى لو كان جهازك خلف NAT أو CGNAT ولا يوجد له عنوان عام، كما في الصورة التالية:

![رسم يوضح جهازاً في المنزل خلف Router يفتح اتصال SSH خارجاً إلى VPS، فيفتح sshd على ال VPS المنفذ 127.0.0.1:9000، والطلبات على هذا المنفذ تعود عبر الاتصال نفسه إلى تطبيق ويب على المنفذ 3000 في المنزل](https://arabroot.io/content/images/2026/10/tunnels-03-ssh-remote.webp)

التوجيه العكسي: جهاز المنزل يتصل، والطلبات تعود عبر اتصاله

لنفرض أن على جهازك تطبيق ويب يعمل على `127.0.0.1:3000`، والأمر التالي ينشره على السيرفر على المنفذ 9000:

```bash
ssh -f -N -R 9000:localhost:3000 deploy@203.0.113.10
```

ثم على السيرفر نتأكد من المنفذ ونطلب الصفحة:

```bash
ss -tlnp | grep 9000
curl -s http://127.0.0.1:9000/
```

```text
LISTEN 0      128        127.0.0.1:9000       0.0.0.0:*
LISTEN 0      128            [::1]:9000          [::]:*
hello from the laptop behind NAT
```

لاحظ أن sshd فتح المنفذ على `127.0.0.1` فقط، فمن جهاز آخر على الشبكة نفسها يفشل الاتصال:

```text
curl: (7) Failed to connect to 203.0.113.10:9000 after 3 ms: Could not connect to server
```

والسبب هو الإعداد [GatewayPorts](https://man.openbsd.org/sshd%5Fconfig?ref=arabroot.io#GatewayPorts) وقيمته الافتراضية `no`، فحتى لو طلبت صراحة `-R 0.0.0.0:9000:localhost:3000` فإن sshd يتجاهل العنوان ويبقي المنفذ على `127.0.0.1`. وإذا غيرت القيمة إلى `clientspecified` فإن sshd يحترم العنوان الذي يطلبه الكلاينت، والمخرج بعد الطلب نفسه سوف يكون كما يلي:

```text
LISTEN 0      128          0.0.0.0:9000       0.0.0.0:*
hello from the laptop behind NAT
```

أي أن المنفذ أصبح مفتوحاً على كل عناوين السيرفر، والجملة الثانية جاءت من جهاز آخر على الشبكة. وهنا يكمن الخطر، فخدمة على جهازك لم تصمم لتواجه الإنترنت أصبحت على الإنترنت بأمر واحد، لذلك لا تغير `GatewayPorts` إلا إذا احتجت إليه فعلاً، وعندها احصر المنفذ في جدار الحماية كما في الحالة التالية. ولا تستخدم القيمة `yes`، والسبب أنها تفتح كل منفذ عكسي على كل العناوين حتى لو لم يطلب الكلاينت ذلك.

### حالة عملية: الوصول إلى جهاز المنزل خلف CGNAT من شبكة لا تسمح إلا ب RDP

وهذه حالة من تجربة شخصية، فاتصال منزلي خلف CGNAT، فلا يوجد عنوان عام أفتح عليه منفذاً، وشبكة العمل لا تسمح بتثبيت أي برنامج VPN، والاتصال الوحيد المسموح بالخروج منها هو سطح المكتب البعيد Remote Desktop Protocol واختصاراً RDP. والحل الذي أستخدمه هو نفق SSH عكسي عبر سيرفر آخر، فجهاز المنزل يفتح بنفسه اتصال SSH إلى سيرفر VPS ويطلب منه أن يستمع على المنفذ 3389، ومن العمل أتصل ب RDP بهذا السيرفر، فيحمل النفق الاتصال إلى جهاز المنزل:

![رسم من ثلاثة أجزاء: جهاز في العمل يتصل ب RDP عبر جدار حماية العمل الذي لا يسمح إلا ب RDP إلى VPS يسمح جدار حمايته بالمنفذ 3389 من عنوان العمل فقط، وجهاز المنزل خلف CGNAT يفتح نفق SSH عكسياً إلى ال VPS فيصل اتصال RDP إليه](https://arabroot.io/content/images/2026/10/tunnels-06-rdp-case.webp)

الطريق إلى المنزل يفتحه جهاز المنزل، ومن العمل لا يخرج إلا RDP

⚠️

شبكة العمل لها سياسة استخدام مقبول Acceptable Use Policy، وأي طريقة تتجاوز قيود الشبكة، ومنها هذا النفق، قد تخالف هذه السياسة حتى لو كان الاتصال نفسه مسموحاً تقنياً، لذلك اسأل فريق تقنية المعلومات IT في جهتك قبل أن تستخدمها.

وقد يتساءل البعض: لماذا لا يبقى المنفذ على `127.0.0.1` كما نصحنا أعلاه؟ والإجابة أن جهاز العمل لا يستطيع أن يفتح SSH إلى السيرفر أصلاً، فلا يوجد طريق ل `ssh -L` من هناك، وبالتالي يجب أن يكون المنفذ 3389 على عنوان السيرفر العام. ولكن هذا لا يعني أن تفتحه للعالم، فالمنفذ 3389 من أكثر المنافذ التي يفحصها المخترقون ويجربون عليها كلمات المرور، والحل أن تجمع عدة طبقات معاً كما يلي.

أولاً على ال VPS، نسمح للمستخدم الذي يملك النفق أن يطلب العنوان بنفسه، فنضيف السطر التالي إلى `/etc/ssh/sshd_config` ثم نعيد تحميل sshd:

```ini
GatewayPorts clientspecified
```

ثم نقيد مفتاح جهاز المنزل في ملف `authorized_keys` لمستخدم مخصص للنفق، فلا يستطيع هذا المفتاح أن يفتح Shell، ولا أن يطلب أي منفذ غير 3389، وهذه الخيارات يشرحها [قسم authorized\_keys في دليل sshd](https://man.openbsd.org/sshd.8?ref=arabroot.io#AUTHORIZED%5FKEYS%5FFILE%5FFORMAT):

```text
restrict,port-forwarding,permitlisten="0.0.0.0:3389",command="/sbin/nologin" ssh-ed25519 AAAAC3Nza... home-pc
```

ثم نفتح المنفذ في جدار الحماية لعنوان العمل العام وحده، وليكن `198.51.100.25`، كما في [إعداد ufw في دليل تأمين ال VPS](https://arabroot.io/articles/%D8%AA%D8%A3%D9%85%D9%8A%D9%86-%D8%AE%D8%A7%D8%AF%D9%85-vps-%D9%85%D9%86-%D8%A3%D9%88%D9%84-%D8%AF%D8%AE%D9%88%D9%84/#ufw):

```bash
sudo ufw allow from 198.51.100.25 to any port 3389 proto tcp
```

ثانياً على جهاز المنزل، النفق يجب أن يبقى متصلاً طوال الوقت، وأن يعود وحده إذا انقطع الإنترنت أو أعيد تشغيل ال Router، ولهذا نستخدم [autossh](https://www.harding.motd.ca/autossh/?ref=arabroot.io) الذي يراقب ssh ويعيد تشغيله:

```bash
AUTOSSH_GATETIME=0 autossh -M 0 -f -N \
  -o ServerAliveInterval=30 -o ServerAliveCountMax=3 \
  -o ExitOnForwardFailure=yes \
  -R 0.0.0.0:3389:localhost:3389 tunnel@203.0.113.10
```

في الإعداد أعلاه لاحظ التالي:

- `ServerAliveInterval=30` و`ServerAliveCountMax=3` يجعلان ssh يرسل رسالة كل 30 ثانية، فإذا لم يرد السيرفر على ثلاث رسائل متتالية أغلق الاتصال، وعندها يعيد autossh فتحه. وبدونهما قد يبقى ssh معلقاً على اتصال ميت لدقائق طويلة.
- `ExitOnForwardFailure=yes` يجعل ssh يخرج إذا رفض السيرفر فتح المنفذ، بدلاً من أن يبقى متصلاً دون نفق، وهذا يحدث مثلاً عندما يبقى اتصال قديم ممسكاً بالمنفذ 3389 على السيرفر.
- `-M 0` يلغي منفذ المراقبة الخاص ب autossh ويعتمد على خيارات ssh السابقة، و`AUTOSSH_GATETIME=0` يجعله يعيد المحاولة حتى لو فشل الاتصال الأول.

ولتتأكد، افحص المنفذ على ال VPS، ثم اتصل به من جهاز آخر. في المثال التالي وضعنا مكان RDP خدمة TCP بسيطة على المنفذ 3389 في جهاز المنزل ترد بسطر واحد:

```bash
ss -tln | grep 3389
nc -w 2 203.0.113.10 3389
```

```text
LISTEN 0      128          0.0.0.0:3389       0.0.0.0:*
home-pc RDP stand-in on port 3389
```

وعندما قطعنا جلسة SSH من جهة السيرفر ظهر في سجل sshd السطر `mm_reap: child terminated by signal 15`، وبعد ثوان فتح autossh اتصالاً جديداً وعاد المنفذ 3389 يستمع، دون أن نلمس جهاز المنزل. أما إذا حاول المفتاح نفسه أن يطلب منفذاً آخر غير المسموح به في `permitlisten` فالمخرج سوف يكون كما يلي:

```bash
ssh -N -o ExitOnForwardFailure=yes -R 0.0.0.0:2222:localhost:22 tunnel@203.0.113.10
```

```text
Error: remote port forwarding failed for listen port 2222
```

ولكي يعمل النفق بعد إعادة تشغيل جهاز المنزل، اجعله خدمة System Service. فإذا كان جهاز المنزل يعمل بنظام Linux فملف systemd التالي يكفي، ولاحظ أن `Restart=always` هنا يقوم بعمل autossh، فنستخدم ssh مباشرة:

```ini
# /etc/systemd/system/rdp-tunnel.service
[Unit]
Description=Reverse SSH tunnel for RDP
After=network-online.target
Wants=network-online.target

[Service]
User=tunnel
ExecStart=/usr/bin/ssh -N -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes -R 0.0.0.0:3389:localhost:3389 tunnel@203.0.113.10
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
```

```bash
sudo systemctl enable --now rdp-tunnel.service
```

أما إذا كان جهاز المنزل يعمل بنظام Windows، وهو الغالب عندما يكون الهدف RDP، فإن [برنامج OpenSSH المدمج في Windows](https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh%5Finstall%5Ffirstuse?ref=arabroot.io) يقبل أمر `ssh` نفسه بالخيارات نفسها، وتجعله يعمل دائماً عبر مهمة مجدولة Scheduled Task تبدأ عند تشغيل الجهاز At startup، وتعمل سواءً سجل المستخدم دخوله أم لا، مع خيار إعادة التشغيل عند الفشل Restart on failure.

ثالثاً جهاز المنزل نفسه، فالنفق يوصل المخترق إلى شاشة الدخول إذا عرف عنوان السيرفر واستطاع تجاوز جدار الحماية، لذلك أبق خيار [المصادقة على مستوى الشبكة Network Level Authentication](https://learn.microsoft.com/en-us/windows-server/remote/remote-desktop-services/clients/remote-desktop-allow-access?ref=arabroot.io) واختصاراً NLA مفعلاً، واستخدم كلمة مرور قوية لحساب Windows، وفعل قفل الحساب بعد عدد من المحاولات الفاشلة Account Lockout. وبهذا الشكل نكون قد جمعنا أربع طبقات: جدار حماية لا يقبل إلا عنوان العمل، ومفتاح SSH لا يفتح إلا منفذاً واحداً، وNLA، وقفل الحساب.

🛑

لا تترك المنفذ 3389 مفتوحاً على ال VPS لكل الإنترنت ولو ليوم واحد، ولا تستخدم `GatewayPorts yes`، والسبب أن خدمة RDP المكشوفة من أكثر الطرق التي يدخل منها المخترقون، ويكفي أن يجد الفاحص المنفذ مفتوحاً حتى يبدأ بتجربة كلمات المرور.

### التوجيه الديناميكي ssh -D: بروكسي SOCKS عبر السيرفر

في التوجيه المحلي تحدد وجهة واحدة في الأمر، فإذا احتجت إلى عشر خدمات داخلية احتجت إلى عشرة خيارات `-L`. أما التوجيه الديناميكي فيجعل ssh بروكسي SOCKS على جهازك، فكل طلب يحدد وجهته بنفسه، ويفتحها sshd من داخل شبكة السيرفر، كما في الصورة التالية:

![رسم يوضح جهازاً محمولاً عليه بروكسي SOCKS على 127.0.0.1:1080، وأنبوب SSH إلى sshd داخل شبكة خاصة، ومن sshd ثلاثة أسهم إلى app.internal وwiki.internal و10.0.0.25:8443](https://arabroot.io/content/images/2026/10/tunnels-04-ssh-dynamic.webp)

منفذ واحد على جهازك يصل إلى أي عنوان يراه السيرفر

```bash
ssh -f -N -D 1080 deploy@203.0.113.10
ss -tln | grep 1080
curl -s --socks5-hostname 127.0.0.1:1080 http://app.internal/ | grep -E "^(Hostname|RemoteAddr|Host):"
```

```text
LISTEN 0      128        127.0.0.1:1080       0.0.0.0:*
LISTEN 0      128            [::1]:1080          [::]:*
Hostname: app
RemoteAddr: 192.168.80.2:49198
Host: app.internal
```

لاحظ أن الخيار `--socks5-hostname` يجعل اسم `app.internal` يحل على السيرفر وليس على جهازك، ولهذا نجح الطلب رغم أن جهازك لا يعرف هذا الاسم. وفي المتصفح تضع العنوان `127.0.0.1:1080` في إعداد بروكسي SOCKS5، وتفعل خيار تمرير طلبات DNS عبر البروكسي، فتفتح الواجهات الداخلية كأنك على السيرفر. ولا تستخدم هذا النوع بديلاً دائماً لشبكة VPN للفريق، والسبب أن كل من يملك المفتاح يصل إلى كل ما يصل إليه السيرفر دون أي قائمة وصول.

### كيف تحمي أنفاق SSH على سيرفرك؟

توجيه المنافذ مفيد لك ولغيرك، فمن يسرق مفتاحاً يدخل به إلى السيرفر يستطيع أن يستخدم السيرفر جسراً إلى شبكتك الداخلية، لذلك عليك بما يلي:

- **المفاتيح فقط**: عطل الدخول بكلمة المرور كما في [دليل تأمين ال VPS](https://arabroot.io/articles/%D8%AA%D8%A3%D9%85%D9%8A%D9%86-%D8%AE%D8%A7%D8%AF%D9%85-vps-%D9%85%D9%86-%D8%A3%D9%88%D9%84-%D8%AF%D8%AE%D9%88%D9%84/#harden-ssh)، والسبب أن النفق الدائم يعني اتصالاً دائماً، وكلمة المرور على اتصال دائم دعوة مفتوحة للتخمين.
- **حدد ما يسمح به كل مفتاح**: الخيار `restrict` في `authorized_keys` يمنع كل شيء، ثم تضيف ما تحتاجه فقط، مثل `permitopen="localhost:5432"` للتوجيه المحلي أو `permitlisten="0.0.0.0:3389"` للعكسي. وعندما قيدنا مفتاحاً ب `permitopen="localhost:5432"` نجح الاتصال بقاعدة البيانات، وفشل الوصول إلى `app.internal:80` بالخطأ `channel 4: open failed: administratively prohibited: open failed`، أما محاولة فتح Shell بالمفتاح نفسه فردت بالعبارة `This account is not available`.
- **عطل التوجيه لمن لا يحتاجه**: إذا كان على السيرفر مستخدمون لا يحتاجون إلى الأنفاق فاجعل `AllowTcpForwarding no` لهم في كتلة `Match User`. ولاحظ أن الدليل نفسه ينبه إلى أن منع التوجيه لا يحمي السيرفر إذا كان المستخدم يملك Shell، والسبب أنه يستطيع تشغيل برنامج توجيه خاص به.
- **أبق `GatewayPorts` على `no`** إلا في حالة محددة مثل حالة RDP أعلاه، ومعها جدار حماية يحصر المنفذ.

## نشر خدمة من خلف NAT دون فتح منافذ

في التوجيه العكسي رأينا الفكرة التي تقوم عليها كل أدوات هذا القسم: الجهاز الداخلي يتصل خارجاً بسيرفر وسيط Relay له عنوان عام، ويبقي هذا الاتصال مفتوحاً، ثم يصل الزائر إلى السيرفر الوسيط، فيرسل الطلب عبر الاتصال المفتوح إلى الداخل. ولا يحتاج جهازك إلى عنوان عام ولا إلى منفذ مفتوح في ال Router، والفرق بين الطريقتين في الصورة التالية:

![رسم من جزأين: في الأول يصل الزائر والفاحص إلى سيرفر المنزل عبر منفذ 443 مفتوح في ال Router ويحتاج إلى عنوان عام، وفي الثاني يفتح وكيل frpc أو cloudflared اتصالاً خارجاً عبر NAT أو CGNAT إلى سيرفر وسيط يصل إليه الزائر فيرسل الطلب عبر الاتصال نفسه](https://arabroot.io/content/images/2026/10/tunnels-05-relay-vs-port.webp)

فتح منفذ يجعل سيرفرك ينتظر الإنترنت، والنفق العكسي يجعل سيرفرك يتصل هو

وقد يتساءل البعض: إذا كان `ssh -R` يفعل ذلك، فلماذا توجد أدوات أخرى؟ والإجابة أن ssh يحمل منافذ TCP فقط، ولا يعرف أسماء النطاقات، فلا يستطيع أن يوجه `app.example.com` إلى جهاز و`wiki.example.com` إلى جهاز آخر على المنفذ نفسه، ولا يحمل UDP، ولا توجد فيه لوحة تحكم، ولا يصدر شهادات TLS. وهذا ما تضيفه الأدوات التالية:

- **Cloudflare Tunnel**: السيرفر الوسيط هو شبكة Cloudflare نفسها، والبرنامج `cloudflared` على سيرفرك هو الوكيل Agent. ولن نكرر شرحه هنا، فقد شرحنا ما يقدمه وأين يقف في [خدمات Cloudflare وبدائلها](https://arabroot.io/articles/%D8%AE%D8%AF%D9%85%D8%A7%D8%AA-cloudflare-%D9%88%D8%A8%D8%AF%D8%A7%D8%A6%D9%84%D9%87%D8%A7-%D9%85%D9%81%D8%AA%D9%88%D8%AD%D8%A9-%D8%A7%D9%84%D9%85%D8%B5%D8%AF%D8%B1/#tunnel)، وإعداده خطوة خطوة في [تشغيل خادمك من إنترنت المنزل](https://arabroot.io/articles/%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D8%AE%D8%A7%D8%AF%D9%85%D9%83-%D9%85%D9%86-%D8%A5%D9%86%D8%AA%D8%B1%D9%86%D8%AA-%D8%A7%D9%84%D9%85%D9%86%D8%B2%D9%84/#cloudflare-tunnel). وتذكر أن TLS ينتهي عند Cloudflare، أي أنها ترى حركة موقعك دون تشفير.
- [**frp**](https://github.com/fatedier/frp?ref=arabroot.io) برخصة Apache-2.0: سيرفر `frps` على VPS لك ووكيل `frpc` في الداخل، وينشر TCP وUDP وHTTP وHTTPS، ويوجه حسب اسم النطاق. والمشروع نشط، فآخر إصدار عند كتابة المقال [v0.71.0](https://github.com/fatedier/frp/releases/tag/v0.71.0?ref=arabroot.io) في أغسطس 2026.
- [**rathole**](https://github.com/rathole-org/rathole?ref=arabroot.io) برخصة Apache-2.0: نفق خفيف مكتوب بلغة Rust وفكرته مثل frp، ولكن آخر إصدار مستقر منه هو [v0.5.0](https://github.com/rathole-org/rathole/releases/tag/v0.5.0?ref=arabroot.io) في أكتوبر 2023، وما بعده بضعة تعديلات متفرقة وإصدار تجريبي dev-latest، فاعتبره مشروعاً قليل الصيانة ولا تبن عليه خدمة مهمة.
- [**Pangolin**](https://pangolin.net/?ref=arabroot.io): الأقرب لتجربة Cloudflare Tunnel على سيرفرك، فهو Reverse Proxy مع لوحة تحكم وتسجيل دخول للمستخدمين، ووكيله الداخلي اسمه Newt ويتصل عبر WireGuard. و[ملف الرخصة](https://github.com/fosrl/pangolin/blob/main/LICENSE?ref=arabroot.io) يقول إن الملفات برخصة AGPL-3.0 ما لم يذكر رأس الملف رخصة Fossorial التجارية، أي أن بعض الأجزاء تجارية. والمشروع نشط جداً، فقد صدر منه 1.24.0 في 30 سبتمبر 2026.
- [**ngrok**](https://ngrok.com/?ref=arabroot.io): خدمة تجارية مشهورة للفكرة نفسها، تفيد عندما تريد أن تعرض تطبيقاً على جهازك لزميل أو لتجربة Webhook لدقائق، والسيرفر الوسيط هنا تملكه الشركة وليس أنت.

### مثال كامل: نشر تطبيق من خلف NAT مع frp

سوف نقوم بنشر تطبيق ويب على جهاز في المنزل ليس له عنوان عام، باستخدام VPS عليه `frps` وعنوانه `relay.example.com`. والتطبيق في مثالنا هو `traefik/whoami` على جهاز اسمه `homeapp` في شبكة المنزل، وهو لا يصل إلى الإنترنت ولا يصل إليه أحد، والوكيل `frpc` هو الوحيد الذي يرى الشبكتين. ونبدأ بتوكن مشترك بين الطرفين:

```bash
openssl rand -hex 32
```

ملف `frps.toml` على ال VPS:

```ini
bindPort = 7000
vhostHTTPPort = 8080

auth.method = "token"
auth.token = "ضع-التوكن-هنا"
```

وملف `frpc.toml` على جهاز المنزل:

```ini
serverAddr = "relay.example.com"
serverPort = 7000

auth.method = "token"
auth.token = "ضع-التوكن-هنا"

[[proxies]]
name = "web"
type = "http"
localIP = "homeapp"
localPort = 80
customDomains = ["app.example.com"]
```

ثم نشغل `frps -c frps.toml` على ال VPS، و`frpc -c frpc.toml` في المنزل. والمخرج في سجل `frps` سوف يكون كما يلي:

```text
[I] [frps/root.go:115] frps uses config file: /etc/frp/frps.toml
[I] [server/service.go:253] frps tcp listen on 0.0.0.0:7000
[I] [server/service.go:325] http service listen on 0.0.0.0:8080
[I] [frps/root.go:124] frps started successfully
[I] [server/service.go:803] [f743c2f23b6548ae] client login info: ip [192.168.96.3:48540] version [0.71.0] hostname [home] os [linux] arch [amd64]
[I] [proxy/http.go:106] [f743c2f23b6548ae] [web] http proxy listen for host [app.example.com] location [] group [], routeByHTTPUser []
[I] [server/control.go:761] [f743c2f23b6548ae] new proxy [web] type [http] success
```

وفي سجل `frpc`:

```text
[I] [client/service.go:312] try to connect to server...
[I] [client/service.go:332] [f743c2f23b6548ae] login to server success, get run id [f743c2f23b6548ae]
[I] [proxy/proxy_manager.go:183] [f743c2f23b6548ae] proxy added: [web]
[I] [client/control.go:174] [f743c2f23b6548ae] [web] start proxy success
```

الآن نطلب التطبيق من الخارج عبر ال VPS باسم النطاق، ثم باسم آخر غير معرف:

```bash
curl -s -H "Host: app.example.com" http://relay.example.com:8080/ | grep -E "^(Hostname|Host|X-Forwarded-For):"
curl -s -o /dev/null -w "%{http_code}\n" -H "Host: other.example.com" http://relay.example.com:8080/
```

```text
Hostname: homeapp
Host: app.example.com
X-Forwarded-For: 192.168.96.1
404
```

في الإعداد أعلاه لاحظ التالي:

- الاتصال بين `frpc` و`frps` على المنفذ 7000 بدأ من المنزل، فلا يوجد أي منفذ مفتوح في Router المنزل، وعلى ال VPS تفتح المنفذ 7000 والمنفذ الذي يصل إليه الزوار فقط.
- `frps` يوجه الطلب حسب الترويسة `Host`، فالاسم غير المعرف أعاد 404، ويضيف عنوان الزائر في `X-Forwarded-For`، وتجد كيف يقرأ تطبيقك هذه الترويسة في [تطبيقك خلف Reverse Proxy](https://arabroot.io/articles/%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D9%83-%D8%AE%D9%84%D9%81-reverse-proxy/).
- الاتصال بين الطرفين مشفر ب TLS افتراضياً منذ الإصدار v0.50.0، ولكن [توثيق frp](https://gofrp.org/en/docs/features/common/network/network-tls/?ref=arabroot.io) يذكر أن `frpc` لا يتحقق من شهادة `frps` افتراضياً، فإذا كان الطريق بين الطرفين غير موثوق فأضف شهادة وتحقق منها بالخيار `transport.tls.trustedCaFile`.
- المنفذ `vhostHTTPPort` يقدم HTTP دون تشفير للزائر، لذلك ضع أمامه على ال VPS Reverse Proxy مع شهادة، مثل [Nginx Proxy Manager](https://arabroot.io/articles/nginx-proxy-manager-%D9%86%D8%B7%D8%A7%D9%82%D8%A7%D8%AA-%D9%88%D8%B4%D9%87%D8%A7%D8%AF%D8%A7%D8%AA-tls/)، أو استخدم نوع `https` في frp.

والآن لنكسر الإعداد عن قصد، فنشغل `frpc` بتوكن خاطئ، والمخرج سوف يكون كما يلي:

```text
[W] [client/service.go:323] connect to server error: token in login doesn't match token from configuration
login to the server failed: token in login doesn't match token from configuration. With loginFailExit enabled, no additional retries will be attempted
```

وهذا ما تريده تماماً. أما إذا حذفت سطري `auth` من `frps.toml` فإن أي أحد يعرف عنوان سيرفرك يستطيع أن يسجل عليه نفقاً، وعندما شغلنا `frps` بالسطر `bindPort = 7000` وحده، اتصل به `frpc` غريب دون أي توكن وفتح على سيرفرنا المنفذ 6000:

```text
[I] [client/service.go:332] [11272b3a1268c9f0] login to server success, get run id [11272b3a1268c9f0]
[I] [proxy/proxy_manager.go:183] [11272b3a1268c9f0] proxy added: [stranger]
[I] [client/control.go:174] [11272b3a1268c9f0] [stranger] start proxy success
```

أي أن سيرفرك يصبح بوابة مجانية لأي شخص ينشر عبرها ما يريد باسم عنوانك، لذلك لا تشغل `frps` أبداً دون [المصادقة بالتوكن](https://gofrp.org/en/docs/features/common/authentication/?ref=arabroot.io) أو OIDC، وحدد المنافذ التي يسمح بفتحها بالإعداد `allowPorts`.

## أنفاق طبقة الشبكة: GRE وIP-in-IP وVXLAN

كل ما سبق يحمل اتصالات TCP أو طلبات HTTP، أما هذا النوع فيحمل حزم IP كاملة، أو إطارات Ethernet كاملة، ويستخدم لربط شبكتين كأنهما شبكة واحدة. والفكرة هي التغليف نفسه الذي بدأنا به، فالحزمة الأصلية بعناوينها الخاصة توضع داخل حزمة جديدة عناوينها هي عناوين طرفي النفق على الإنترنت، واسم الشبكة التي تحمل النفق Underlay، والشبكة التي تعمل داخله Overlay، كما في الصورة التالية:

![رسم يوضح موقعين متصلين بنفق عبر الإنترنت، وتحته أربعة صفوف للحزمة: الحزمة الأصلية، ثم داخل IP-in-IP أو GRE، ثم داخل VXLAN مع UDP 4789 وEthernet، ثم داخل WireGuard أو IPsec مشفرة، مع علامة عين على الأنواع غير المشفرة وقفل على المشفرة](https://arabroot.io/content/images/2026/10/tunnels-07-encapsulation.webp)

كل نوع يضيف طبقات إلى الحزمة، والتشفير لا يأتي إلا مع WireGuard أو IPsec

- **IP-in-IP** كما في [RFC 2003](https://www.rfc-editor.org/rfc/rfc2003?ref=arabroot.io): أبسط الأنواع، رأس IP جديد فوق الحزمة الأصلية، ويحمل IPv4 فقط، ويضيف 20 بايت.
- **GRE** واختصاره Generic Routing Encapsulation كما في [RFC 2784](https://www.rfc-editor.org/rfc/rfc2784?ref=arabroot.io): يضيف رأساً صغيراً يحدد نوع ما بداخله، فيحمل IPv4 وIPv6 وبروتوكولات أخرى، ويضيف 24 بايت، وتجده في أجهزة الشبكات وعند مزودي الحماية من DDoS.
- **VXLAN** واختصاره Virtual Extensible LAN كما في [RFC 7348](https://www.rfc-editor.org/rfc/rfc7348?ref=arabroot.io): يحمل إطارات Ethernet كاملة داخل UDP على المنفذ 4789، ومعها رقم شبكة VNI يسمح بأكثر من 16 مليون شبكة منفصلة، ويضيف 50 بايت. وهو ما تستخدمه [شبكة overlay في Docker Swarm](https://docs.docker.com/engine/network/drivers/overlay/?ref=arabroot.io) التي ذكرناها في [شبكات Docker](https://arabroot.io/articles/%D8%B4%D8%A8%D9%83%D8%A7%D8%AA-docker-%D9%88%D8%A3%D9%81%D8%B6%D9%84-%D8%A7%D9%84%D9%85%D9%85%D8%A7%D8%B1%D8%B3%D8%A7%D8%AA/#overlay)، وتستخدمه شبكات Kubernetes مثل [Calico بخياري VXLAN وIP-in-IP](https://docs.tigera.io/calico/latest/networking/configuring/vxlan-ipip?ref=arabroot.io)، لتصل ال Pods على سيرفرات مختلفة إلى بعضها.

وفي Linux تنشئ هذه الأنفاق بالأمر [ip link](https://man7.org/linux/man-pages/man8/ip-link.8.html?ref=arabroot.io). المثال التالي ينشئ نفق IP-in-IP بين موقعين، عنوان الأول على شبكة ال Underlay هو `192.168.128.2` والثاني `192.168.128.3`، ويعطي طرفي النفق العنوانين `10.200.0.1` و`10.200.0.2`. على الموقع الأول:

```bash
ip link add t1 type ipip local 192.168.128.2 remote 192.168.128.3
ip addr add 10.200.0.1/30 dev t1
ip link set t1 up
```

وعلى الموقع الثاني الأوامر نفسها مع عكس العنوانين و`10.200.0.2/30`، ثم نرسل ping من الأول، ونراقب على الثاني ما يمر على الشبكة الحقيقية:

```bash
ping -c 2 10.200.0.2
tcpdump -n -i eth0 -c 2 ip proto 4
```

```text
64 bytes from 10.200.0.2: seq=0 ttl=64 time=2.033 ms
64 bytes from 10.200.0.2: seq=1 ttl=64 time=0.295 ms
12:59:44.120701 IP 192.168.128.2 > 192.168.128.3: IP 10.200.0.1 > 10.200.0.2: ICMP echo request, id 75, seq 0, length 64
12:59:44.121924 IP 192.168.128.3 > 192.168.128.2: IP 10.200.0.2 > 10.200.0.1: ICMP echo reply, id 75, seq 0, length 64
```

لاحظ أن كل سطر في مخرج tcpdump فيه حزمتان، الخارجية بعناوين ال Underlay، وداخلها الحزمة الأصلية بعناوين النفق. وأنفاق GRE تنشأ بالطريقة نفسها مع `type gre`، ولكنها تحتاج إلى الوحدة `ip_gre` في النواة Kernel، وبعض البيئات لا تحملها، فيظهر الخطأ `Error: Unknown device type.`.

والآن نفق VXLAN بين الموقعين نفسيهما، برقم شبكة 100 على المنفذ 4789:

```bash
ip link add vxlan100 type vxlan id 100 remote 192.168.128.3 dstport 4789 dev eth0
ip addr add 10.100.0.1/24 dev vxlan100
ip link set vxlan100 up
ip -d link show vxlan100
```

```text
3: vxlan100: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether b6:d5:75:80:19:6a brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65535
    vxlan id 100 remote 192.168.128.3 dev eth0 srcport 0 0 dstport 4789 ttl auto ageing 300 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 
```

لاحظ أن `mtu` أصبح 1450 بدلاً من 1500، وفي نفق IP-in-IP كان 1480، وهذه هي البايتات التي أخذها التغليف من كل حزمة. وإذا نسيت ذلك في شبكة أكبر فسوف ترى أغرب مشكلة في الشبكات، وهي أن ping يعمل وبعض الصفحات لا يكتمل تحميلها، وقد شرحنا أثرها في [مشكلات MTU في دليل WireGuard](https://arabroot.io/articles/%D8%B4%D8%A8%D9%83%D8%A9-%D8%AE%D8%A7%D8%B5%D8%A9-%D9%85%D8%B9-wireguard-%D9%88-wg-easy/#mtu-issues).

والسؤال المهم هنا: هل هذا النفق آمن؟ لا، والتفصيل فيما يلي. أرسلنا عبر نفق VXLAN سطراً يشبه بيانات دخول، وراقبنا الشبكة الحقيقية من الطرف الآخر:

```bash
echo "user=admin password=S3cret" | nc -w 1 10.100.0.2 5000
tcpdump -n -i eth0 -vv -X udp port 4789
```

والحزمة التي تحمل البيانات ظهرت في مخرج tcpdump كما يلي:

```text
12:58:37.196183 IP (tos 0x0, ttl 64, id 47834, offset 0, flags [none], proto UDP (17), length 129)
    192.168.128.2.47718 > 192.168.128.3.4789: [bad udp cksum 0xef25 -> 0xe085!] VXLAN, flags [I] (0x08), vni 100
IP (tos 0x0, ttl 64, id 65294, offset 0, flags [DF], proto TCP (6), length 79)
    10.100.0.1.42349 > 10.100.0.2.5000: Flags [P.], cksum 0x150c (incorrect -> 0x066c), seq 1:28, ack 1, win 507, options [nop,nop,TS val 1157313672 ecr 2897517599], length 27
	0x0060:  3488 acb4 9c1f 7573 6572 3d61 646d 696e  4.....user=admin
	0x0070:  2070 6173 7377 6f72 643d 5333 6372 6574  .password=S3cret
	0x0080:  0a                                       .
```

أي أن كل من يقف على الطريق بين الموقعين، من مزود الإنترنت إلى أي جهاز في المنتصف، يقرأ ما بداخل النفق كما هو، والسبب أن GRE وIP-in-IP وVXLAN صممت لتغليف الحزم وتوجيهها وليس لحمايتها، فلا يوجد فيها تشفير ولا تحقق من هوية الطرف الآخر. لذلك عندما تمر هذه الأنفاق عبر الإنترنت توضع فوق IPsec، أو تستبدل كلياً بنفق مشفر مثل WireGuard، ولهذا السبب أيضاً يوفر Docker الخيار `--opt encrypted` لشبكة overlay، والذي يضيف IPsec فوق VXLAN.

## أنفاق VPN: النفق المشفر لشبكة كاملة

شبكة VPN هي النوع الذي يجمع ما سبق، فهي نفق على مستوى الشبكة مثل GRE، ولكن مع التشفير والمصادقة، فيدخل جهازك أو فرعك إلى شبكة أخرى كأنه جزء منها، وكل ما يمر بينهما مشفر. وقد شرحنا أنواعها، أي الوصول عن بعد Remote Access والربط بين موقعين Site-to-Site والشبكة المتداخلة Mesh، وبروتوكولاتها ومصطلحاتها في [ما هو VPN؟ شرح للمبتدئين](https://arabroot.io/articles/%D9%85%D8%A7-%D9%87%D9%88-vpn-%D8%B4%D8%B1%D8%AD-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/)، وطريقة تشغيل واحدة على سيرفرك في [شبكة خاصة مع WireGuard وواجهة wg-easy](https://arabroot.io/articles/%D8%B4%D8%A8%D9%83%D8%A9-%D8%AE%D8%A7%D8%B5%D8%A9-%D9%85%D8%B9-wireguard-%D9%88-wg-easy/).

## المقارنة بين أنواع الأنفاق

| النوع             | ما يحمله                   | من يبدأ الاتصال                      | مشفر؟                                     | الاستخدام الشائع                                 | أمثلة                                            |
| ----------------- | -------------------------- | ------------------------------------ | ----------------------------------------- | ------------------------------------------------ | ------------------------------------------------ |
| SSH محلي \-L      | منفذ TCP واحد لكل خيار     | جهازك إلى السيرفر                    | نعم، داخل SSH                             | فتح قاعدة بيانات أو واجهة إدارة على السيرفر      | OpenSSH                                          |
| SSH عكسي \-R      | منفذ TCP يعود إلى جهازك    | الجهاز الداخلي إلى السيرفر           | نعم، داخل SSH                             | الوصول إلى جهاز خلف NAT أو CGNAT                 | OpenSSH، autossh                                 |
| SSH ديناميكي \-D  | أي وجهة TCP عبر SOCKS      | جهازك إلى السيرفر                    | نعم، داخل SSH                             | تصفح الواجهات الداخلية مؤقتاً                    | OpenSSH                                          |
| نفق عكسي عبر وسيط | HTTP وHTTPS وTCP وUDP      | الوكيل الداخلي إلى ال Relay          | بين الوكيل والوسيط، وTLS ينتهي عند الوسيط | نشر خدمة من المنزل دون فتح منافذ                 | Cloudflare Tunnel، frp، Pangolin، rathole، ngrok |
| تغليف طبقة الشبكة | حزم IP أو إطارات Ethernet  | الطرفان معاً، دون مصادقة             | لا                                        | ربط الشبكات، وشبكات Overlay في Swarm وKubernetes | GRE، IP-in-IP، VXLAN                             |
| VPN               | حزم IP لجهاز أو شبكة كاملة | الكلاينت، أو الطرفان في Site-to-Site | نعم                                       | وصول الفريق إلى الشبكة الخاصة وربط الفروع        | WireGuard، IPsec، OpenVPN                        |

## أي نفق تحتاج؟

- **أريد أن أفتح قاعدة البيانات أو واجهة إدارة على سيرفري مرة واحدة**: `ssh -L`، ثم أغلقه عندما تنتهي، ولا تنشر المنفذ أبداً.
- **أريد أن أتصفح عدة واجهات داخلية لبعض الوقت**: `ssh -D` مع بروكسي SOCKS في المتصفح.
- **أريد أن أنشر تطبيقاً من المختبر المنزلي Homelab للعامة دون فتح منافذ**: Cloudflare Tunnel إذا قبلت أن ترى Cloudflare الحركة، أو frp أو Pangolin على VPS لك إذا أردت أن يبقى كل شيء عندك.
- **أريد أن أصل إلى جهاز في المنزل خلف CGNAT من مكان واحد معروف**: `ssh -R` إلى VPS مع جدار حماية يقبل عنوان ذلك المكان فقط، كما في حالة RDP أعلاه.
- **أريد أن أربط موقعين أو سيرفرين كأنهما شبكة واحدة**: WireGuard Site-to-Site، أو GRE وVXLAN فوق IPsec إذا كانت أجهزتك تتطلب ذلك، ولا تمرر GRE أو VXLAN عبر الإنترنت دون تشفير.
- **أريد أن يصل فريقي إلى الخدمات الخاصة كل يوم**: هذه حالة VPN وليست حالة نفق SSH، فراجع [شرح VPN](https://arabroot.io/articles/%D9%85%D8%A7-%D9%87%D9%88-vpn-%D8%B4%D8%B1%D8%AD-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/) و[دليل WireGuard](https://arabroot.io/articles/%D8%B4%D8%A8%D9%83%D8%A9-%D8%AE%D8%A7%D8%B5%D8%A9-%D9%85%D8%B9-wireguard-%D9%88-wg-easy/).

## أخطاء الأمان الشائعة مع الأنفاق

- **النفق يتجاوز سياسة جدار الحماية**: جدار الحماية يرى اتصال SSH أو اتصالاً خارجاً على 443، ولا يرى ما بداخله، لذلك فإن كل نفق هو فتحة في سياستك أنت قررت وجودها. فاكتب قائمة بالأنفاق الدائمة على سيرفراتك، ومن يملك كل منها، ولماذا يوجد.
- **كشف خدمة داخلية للإنترنت دون قصد**: `GatewayPorts yes` أو `clientspecified` دون جدار حماية، أو `ssh -L 0.0.0.0:5432:...` على جهاز في شبكة مشتركة، أو `frps` دون توكن، وكل منها رأيناه أعلاه بمخرجه الحقيقي.
- **نفق دائم بكلمة مرور أو بمفتاح دون قيود**: النفق العكسي الدائم يعني أن على جهاز المنزل مفتاحاً يدخل إلى ال VPS طوال الوقت، فاجعل له مستخدماً خاصاً ومفتاحاً مقيداً ب `restrict` و`permitlisten`، ولا تستخدم مفتاحك الشخصي أو حساب root. أما الدخول التفاعلي إلى السيرفر فأضف إليه عاملاً ثانياً للمصادقة MFA إذا كان متاحاً لك.
- **الثقة في السيرفر الوسيط**: اسأل نفسك أين ينتهي TLS، ففي Cloudflare Tunnel ينتهي عند Cloudflare، وفي frp مع `vhostHTTPPort` لا يوجد TLS للزائر أصلاً إلا إذا أضفته، ومن يتحكم في الوسيط يرى الحركة أو يستطيع تغييرها.
- **أنفاق لا يراقبها أحد**: راقب المنافذ التي تستمع على سيرفراتك بالأمر `ss -tlnp`، وسجل sshd الذي يذكر كل توجيه مرفوض، وسجلات `frps` التي تذكر كل كلاينت يسجل دخوله وعنوانه، والسبب أن النفق الذي نسيته هو النفق الذي سوف يستخدمه غيرك.
- **سياسة الجهة التي تعمل بها**: في الشركات والجهات الحكومية قد تكون الأنفاق ممنوعة في سياسة أمن المعلومات حتى لو سمحت بها الشبكة تقنياً، لذلك لا تفتح نفقاً من شبكة العمل أو إليها قبل أن يوافق عليه فريق تقنية المعلومات.

## الخلاصة

وصلنا لنهاية الموضوع، وأهم ما فيه:

- النفق يحمل اتصالاً داخل اتصال آخر، ويحل أربع مشكلات: الوصول إلى خدمة غير منشورة، والمرور عبر شبكة تمنعك، وربط شبكتين، ونشر خدمة من خلف NAT دون فتح منافذ.
- `ssh -L` يوصلك إلى خدمة على السيرفر أو خلفه، و`ssh -R` يفتح على السيرفر منفذاً يعود إلى جهازك، و`ssh -D` يجعل السيرفر بروكسي SOCKS لك، وكلها مشفرة داخل SSH.
- أبق `GatewayPorts` على `no`، وقيد كل مفتاح نفق ب `restrict` و`permitopen` أو `permitlisten`، وإذا احتجت إلى منفذ عكسي عام فاحصره في جدار الحماية على عنوان واحد.
- الأنفاق العكسية عبر وسيط، مثل Cloudflare Tunnel وfrp وPangolin، تنشر خدمات المنزل دون منافذ مفتوحة، فلا تشغل `frps` دون توكن، واعرف أين ينتهي TLS. أما rathole فلم يصدر منه إصدار مستقر منذ 2023.
- GRE وIP-in-IP وVXLAN تغلف الحزم دون أي تشفير، وتأخذ من MTU، فضعها فوق IPsec أو استخدم WireGuard عندما تمر عبر الإنترنت.
- وصول الفريق اليومي إلى الشبكة الخاصة مكانه VPN وليس نفق SSH.

[![](https://arabroot.io/content/images/2026/10/vpn-basics-cover-cover.webp)دليلما هو VPN؟ شرح الشبكة الخاصة الافتراضية من المشكلة إلى الأنواع والبروتوكولاتلماذا تحتاج شبكة خاصة افتراضية VPN، وكيف تغلف حزمك وتشفرها داخل نفق، وما الفرق بين Remote Access وSite-to-Site وMesh وZero Trust، مع مقارنة WireGuard وOpenVPN وIPsec وتجربة عملية تريك النفق من الداخل.](https://arabroot.io/articles/%D9%85%D8%A7-%D9%87%D9%88-vpn-%D8%B4%D8%B1%D8%AD-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/)[![](https://arabroot.io/content/images/2026/10/wireguard-cover-cover.webp)دليلشبكة خاصة مع WireGuard وواجهة wg-easyلا تحتاج لوحات الإدارة إلى أن تكون مكشوفة للإنترنت. ننشئ شبكة VPN خاصة باستخدام WireGuard وواجهة wg-easy، ونضيف إليها الأجهزة برمز QR، فلا يصل إلى أدواتك إلا أجهزة فريقك.](https://arabroot.io/articles/%D8%B4%D8%A8%D9%83%D8%A9-%D8%AE%D8%A7%D8%B5%D8%A9-%D9%85%D8%B9-wireguard-%D9%88-wg-easy/)[![](https://arabroot.io/content/images/2026/10/cloudflare-services-cover-cover.webp)دليلخدمات Cloudflare بكلمات بسيطة وبدائلها مفتوحة المصدرما الذي تقدمه كل خدمة من Cloudflare، من DNS والتخزين المؤقت وWAF إلى Tunnel وWorkers، وما المتاح منها مجاناً، وما البديل مفتوح المصدر الذي تشغله على سيرفرك، وأين يستبدلها فعلاً وأين لا يمكن استبدالها.](https://arabroot.io/articles/%D8%AE%D8%AF%D9%85%D8%A7%D8%AA-cloudflare-%D9%88%D8%A8%D8%AF%D8%A7%D8%A6%D9%84%D9%87%D8%A7-%D9%85%D9%81%D8%AA%D9%88%D8%AD%D8%A9-%D8%A7%D9%84%D9%85%D8%B5%D8%AF%D8%B1/)[![](https://arabroot.io/content/images/2026/10/home-internet-cover-cover.webp)دليلتشغيل خادمك من إنترنت المنزل: CGNAT وDDNS وCloudflare Tunnelهل يمكنك تشغيل خدماتك من اتصال الإنترنت في منزلك؟ يشرح هذا الدليل كيف تعرف ما يسمح به اتصالك، ومتى يكفي توجيه المنافذ، ولماذا يكون Cloudflare Tunnel غالباً الحل الأسهل والأكثر أماناً.](https://arabroot.io/articles/%D8%AA%D8%B4%D8%BA%D9%8A%D9%84-%D8%AE%D8%A7%D8%AF%D9%85%D9%83-%D9%85%D9%86-%D8%A5%D9%86%D8%AA%D8%B1%D9%86%D8%AA-%D8%A7%D9%84%D9%85%D9%86%D8%B2%D9%84/)[![](https://arabroot.io/content/images/2026/10/secure-vps-cover-cover-1.webp)دليلتأمين خادم VPS من أول دخول على Ubuntu 24.04استلمت خادمك للتو؟ قبل أن تثبت عليه أي تطبيق، اتبع هذه الخطوات لإغلاق أبرز الثغرات: الدخول بمفتاح SSH بدلاً من كلمة المرور، وجدار حماية، وتحديثات أمنية تلقائية.](https://arabroot.io/articles/%D8%AA%D8%A3%D9%85%D9%8A%D9%86-%D8%AE%D8%A7%D8%AF%D9%85-vps-%D9%85%D9%86-%D8%A3%D9%88%D9%84-%D8%AF%D8%AE%D9%88%D9%84/)

## سجل التحديثات

- أكتوبر 2026: كتابة المقال واختبار أمثلته على OpenSSH 10.3p1 وfrp 0.71.0 وautossh 1.4g وiproute2 7.0.0.