حوّل أي منفذ محلي إلى رابط HTTPS عام — على دومينك أنت.
التثبيت · البداية السريعة · الأوامر · وصفات عملية · حل المشاكل · English
$ linko 3000
✓ DNS record created (x92ka.example.com)
✓ Route published (x92ka.example.com -> http://localhost:3000)
✓ Tunnel connected
Public URL https://x92ka.example.com
Forwards http://localhost:3000
Tunnel example-linko-tunnel
Press Ctrl+C to stopبدون فتح بورت، بدون Port Forwarding، بدون شهادات SSL، بدون إنشاء سجلات DNS يدويًا.
| لماذا linko | ما يميّزه عن ngrok |
| ما تحتاجه | المتطلبات قبل البدء |
| التثبيت | سطر واحد، وطرق أخرى |
| البداية السريعة | التوكن ← الإعداد ← أول رابط |
| الفكرة الأساسية | لماذا لا يتغيّر رابطك |
| مرجع الأوامر | كل أمر وكل خيار |
| وصفات عملية | حالات استخدام جاهزة |
| قاعدة المستوى الواحد | أصعب عطل في النظام |
| الإعدادات | الملفات ومتغيرات البيئة |
| كيف يعمل | المعمارية |
| حل المشاكل | كل خطأ وسببه وحله |
| الأمان | ما يجب أن تعرفه |
ngrok ممتاز — حتى تريد دومينك أنت، بلا حدود جلسات وبلا صفحة تحذير وسيطة.
linko يعطيك ذلك فوق حسابك
8000
في Cloudflare: أمر واحد يدخل، ورابط عام يخرج.
| دومينك أنت | كل رابط تحت دومين تملكه. |
| روابط ثابتة | المنفذ يحتفظ برابطه. إعادة تشغيل مشروعك لا تغيّر الرابط الذي أرسلته. |
| HTTPS تلقائي | Cloudflare تصدر الشهادة وتجدّدها. |
| ملف تنفيذي واحد | مكتوب بـ Go. لا Node ولا Python ولا أي بيئة تشغيل. |
| نفق واحد لكل مشاريعك | كل مشروع اسم داخل النفق موجّه إلى منفذ مختلف. |
| يعمل كما تشاء | في المقدمة، أو بالخلفية، أو يبدأ مع كل إقلاع للجهاز. |
| ينظّف نفسه | روابط --temp وسجلات DNS الخاصة بها تُحذف عند الإيقاف. |
| مطلوب؟ | ملاحظات | |
|---|---|---|
| حساب Cloudflare | ✅ | الخطة المجانية تكفي — أنشئ حسابًا |
| دومين تملكه | ✅ | من أي مكان اشتريته: Namecheap أو GoDaddy أو غيرهما |
| أن تكون إدارة DNS عند Cloudflare | ✅ | اقرأ الفقرة التالية — مجاني، وتبقى مسجّلًا عند بائعك |
cloudflared |
❌ | يُنزَّل تلقائيًا عند أول استخدام |
| Go | ❌ | فقط إن أردت البناء من المصدر |
| Node أو Python أو Docker | ❌ | غير مستخدمة إطلاقًا |
Important
امتلاك الدومين وحده لا يكفي — يجب أن تشير nameservers الخاصة به إلى
Cloudflare. يُنشئ linko سجلات DNS عبر واجهة Cloudflare، فلا بد أن تكون
Cloudflare هي المرجع الرسمي للـ DNS. العملية مجانية وتستغرق عشر دقائق
معظمها انتظار.
كيف تنقل إدارة DNS إلى Cloudflare (مجانًا، وتبقى مسجّلًا عند بائعك)
أنت لا تنقل ملكية الدومين. يبقى مسجّلًا حيث اشتريته، وتستمر بالدفع لنفس الجهة، ويمكنك التراجع في أي وقت. الذي يتغيّر هو nameservers فقط.
١. أنشئ حسابًا مجانيًا من dash.cloudflare.com/sign-up.
٢. أضف دومينك. من اللوحة اضغط Add a site ← اكتب example.com ←
اختر خطة Free.
٣. دع Cloudflare تفحص سجلاتك. ستنسخ سجلات DNS الحالية تلقائيًا. راجع
القائمة وقارنها بمزوّدك الحالي — خصوصًا سجلات MX إن كان لديك بريد على
هذا الدومين، وإلا توقّف بريدك.
٤. انسخ الـ nameservers اللذين تعرضهما لك، مثل:
dana.ns.cloudflare.com
rick.ns.cloudflare.com
٥. ضعهما عند بائع الدومين. سجّل الدخول حيث اشتريت الدومين، وابحث عن Nameservers أو DNS settings أو Custom DNS، واحذف الموجود وضع اللذين نسختهما. أدلة حسب البائع: Namecheap · GoDaddy · Google Domains / Squarespace · Hostinger
٦. انتظر. عادة أقل من ساعة، وقد تصل إلى ٢٤ ساعة. تصلك رسالة من Cloudflare حين يصبح الدومين Active.
للتحقق بنفسك في أي وقت:
dig NS example.com +short # يجب أن تظهر *.ns.cloudflare.comوحين يظهر الدومين Active في اللوحة، شغّل linko init.
ليس لديك دومين أصلًا؟ Cloudflare تبيع الدومينات بسعر التكلفة مع إدارة DNS جاهزة — فلا تحتاج لنقل أي شيء.
curl -fsSL https://raw.githubusercontent.com/Devehab/linko/main/install.sh | bashيكتشف السكربت نظامك، ينزّل الملف المناسب، ويضعه في مجلد موجود في مسارك أصلًا.
وإن اضطر لاستخدام ~/.local/bin فسيضيف السطر إلى ملف الشِل بنفسه.
linko --versionطرق أخرى للتثبيت
عبر Go — تحتاج Go 1.23 أو أحدث:
go install github.com/Devehab/linko@latestإن لم يكن Go مثبتًا:
brew install go # macOS
sudo apt install golang-go # Debian / Ubuntu
sudo dnf install golang # Fedora
# أو نزّل الحزمة من https://go.dev/dl/من المصدر
git clone https://github.com/Devehab/linko.git
cd linko
make deps && make verify && make buildويندوز — نزّل ملف .zip من
صفحة الإصدارات، فك الضغط، وضع
linko.exe في مجلد ضمن PATH.
تحديد إصدار أو مجلد
LINKO_VERSION=v0.2.0 LINKO_INSTALL="$HOME/bin" \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/Devehab/linko/main/install.sh)"هذه الخطوة التي تتعثّر فيها الأغلبية. القاعدة في سطر واحد:
توكن واحد، صلاحيتان معًا. ليس توكنًا للـ DNS وآخر للنفق — بل توكن واحد يحمل الاثنتين، وكلتاهما Edit لا Read.
افتح dash.cloudflare.com/profile/api-tokens ← Create Token ← انزل إلى أسفل الصفحة واختر Create Custom Token.
في قسم Permissions أضف السطرين. اضغط + Add more لإضافة الثاني:
| # | الأول | الثاني | الثالث |
|---|---|---|---|
| ١ | Zone |
DNS |
Edit |
| ٢ | Account |
Cloudflare Tunnel |
Edit |
ثم حدّد الموارد:
- Account Resources ← اختر حسابك
- Zone Resources ←
Include→Specific zone→ دومينك
Warning
ترك Zone Resources فارغًا ينتج توكنًا يتصل بنجاح لكنه لا يرى أي دومين،
فيفشل linko init برسالة no zone named …. هذا أشيع خطأ في الإعداد كله.
ثم Continue to summary ← Create Token، وانسخ الرمز — يُعرض مرة واحدة فقط.
نسيت الخطوات؟ اكتب
linko docsوستظهر أمامك في الطرفية.
linko initيسألك ثلاثة أسئلة فقط. اضغط Enter لقبول الافتراضي:
Cloudflare credentials
Cloudflare API token: ················
✓ Cloudflare connected
Domain
Domain: [example.com]
✓ DNS zone found (example.com)
Base subdomain: [example.com]
✓ URLs will look like https://abc12.example.com
Tunnel
Tunnel name: [example-linko-tunnel]
✓ Tunnel created
✓ Configuration saved to ~/.linko/config.json
✓ cloudflared installed
You're ready.Important
عند سؤال Base subdomain اكتب دومينك مجرّدًا (example.com) — لا
demo.example.com. السبب في قاعدة المستوى الواحد.
npm run dev # مشروعك على المنفذ 3000
linko 3000 # في نافذة طرفية أخرىهذا هو السلوك الذي يجعل استخدام linko مريحًا يومًا بعد يوم.
linko 3000 # أول مرة → https://x92ka.example.com
# Ctrl+C
linko 3000 # المرة التالية → https://x92ka.example.com (نفسه تمامًا)الرابط الذي أرسلته لزميلك يبقى يعمل بعد كل إعادة تشغيل، ولا تتراكم سجلات DNS ميتة في حسابك. وحين تريد التغيير فعلًا:
| الأمر | ماذا يحدث |
|---|---|
linko 3000 --new |
رابط عشوائي جديد، ويحذف القديم |
linko 3000 --name crm |
اسم تختاره أنت → crm.example.com |
linko 3000 --temp |
رابط لمرة واحدة، يُحذف لحظة الإيقاف |
| الخيار | الأثر |
|---|---|
--no-color |
تعطيل الألوان |
--version |
عرض الإصدار |
-h, --help |
مساعدة أي أمر |
الإعداد لمرة واحدة: يتحقق من التوكن، يجد الـ zone، ينشئ النفق، ويحفظ كل شيء
في ~/.linko/config.json بصلاحيات 0600.
| الخيار | الأثر |
|---|---|
--token <t> |
توكن Cloudflare (أو استخدم LINKO_API_TOKEN) |
--domain <d> |
الدومين المُدار في Cloudflare |
--base <b> |
الـ subdomain الأساس للروابط |
--tunnel <n> |
اسم النفق (الافتراضي <domain>-linko-tunnel) |
--force |
إعادة الإعداد فوق إعداد موجود |
-y, --yes |
بلا أسئلة: يفشل بدل أن يسأل |
--skip-download |
لا تنزّل cloudflared الآن |
# إعداد كامل بلا تفاعل — مناسب لـ CI أو جهاز جديد
export LINKO_API_TOKEN='cfut_…'
linko init --yes --domain example.com --base example.comنشر خدمة محلية. linko 3000 اختصار لـ linko start 3000.
| الخيار | الأثر |
|---|---|
-n, --name <n> |
الاسم المطلوب (الافتراضي: رابط هذا المنفذ الحالي) |
-r, --new |
رابط عشوائي جديد بدل الحالي |
--temp |
يُحذف الاسم عند إيقاف النفق |
-d, --detach |
يعمل بالخلفية ويرجعك للسطر |
-o, --open |
يفتح المتصفح حين يصبح الرابط جاهزًا فعلًا |
| استبدال الاسم إن كان يشير لمكان آخر | |
-y, --yes |
بلا أسئلة |
-v, --verbose |
عرض سجلات cloudflared |
--loglevel <l> |
debug · info · warn · error · fatal |
صيغ المنفذ المقبولة
| ما تكتبه | ما يعنيه |
|---|---|
linko 3000 |
http://localhost:3000 |
linko :3000 |
http://localhost:3000 |
linko 127.0.0.1:8080 |
عنوان محدد |
linko https://localhost:8443 |
أصل يعمل بـ HTTPS |
linko tcp://localhost:22 |
خدمة TCP خام |
عرض ما نشرته.
$ linko list
NAME URL TARGET KIND
api https://api.example.com -> http://localhost:8080 persistent
web https://web.example.com -> http://localhost:3000 persistent
· 2 route(s) · tunnel example-linko-tunnel · ~/.linko/config.json| الخيار | الأثر |
|---|---|
--remote |
يقرأ المسارات الحيّة من Cloudflare بدل الملف المحلي |
إدارة الأنفاق العاملة بالخلفية.
$ linko ps
NAME URL TARGET PROCESS
web https://web.example.com -> http://localhost:3000 pid 41288linko stop web # إيقاف واحد
linko stop --all # إيقاف كل شيءحالة النفق، والاتصالات الحيّة، والمسارات المنشورة، وما يعمل بالخلفية.
$ linko status
Cloudflare Tunnel
Name example-linko-tunnel
ID 8f3c1a92-…
Account Acme
Domain example.com
Status connected (4 connections via AMS, FRA)
Routes
· https://web.example.com -> http://localhost:3000حذف رابط: قاعدة التوجيه، وسجل الـ DNS، والسطر المحلي — الثلاثة معًا.
| الخيار | الأثر |
|---|---|
--all |
حذف كل الروابط |
-y, --yes |
بلا تأكيد |
Note
لا يحذف linko أي سجل DNS لا يشير إلى نفق Cloudflare، فلا يمكنه أن يمسّ
سجلات موقعك الحقيقي بالخطأ.
إبقاء النفق يعمل عبر إعادات التشغيل — launchd على macOS وsystemd --user
على لينكس، مع إعادة تشغيل تلقائية إن توقف.
linko service install 3000 --name crm
linko service list
linko service uninstall crmثمانية فحوص بالترتيب، من وجود cloudflared إلى الاتصالات الحيّة. يخرج برمز
غير صفري عند الفشل، فيصلح للاستخدام داخل السكربتات.
| الخيار | الأثر |
|---|---|
--fix |
يصلح توكنًا ميتًا أو نفقًا محذوفًا أو سجلات DNS ومسارات ناقصة |
-y, --yes |
يصلح بلا أسئلة |
$ linko doctor
✓ cloudflared installed (2025.2.0)
✓ config valid (~/.linko/config.json)
✓ API token valid
✓ DNS zone reachable (example.com)
✓ tunnel exists (example-linko-tunnel)
✓ tunnel configuration readable (2 routes)
✓ DNS configured for 2 routes
✓ connection active (4 edge connections)
Everything looks good.الدليل في الطرفية. و--open يفتح الصفحة الكاملة في المتصفح.
تُري عميلًا عملك الحالي
linko 3000 --name preview --openخدمتان معًا في نفق واحد
linko 3000 -n web # نافذة ١
linko 8080 -n api # نافذة ٢بيئة تجريبية يجب أن تصمد بعد إعادة التشغيل
linko service install 8080 --name staging
linko service listنقطة استقبال webhooks تعمل طوال الأسبوع
linko 4000 -n hooks -d
linko psرابط لمرة واحدة ينظّف نفسه
linko 5173 --tempتطبيقك يستمع على الـ loopback فقط
linko 127.0.0.1:3000تدوير رابط انتشر أكثر مما ينبغي
linko 3000 --newشهادة Cloudflare المجانية تغطي اسمين اثنين بالضبط:
example.com الجذر
*.example.com مستوى واحد
و* في الشهادات لا تعبر النقطة:
| الرابط | يعمل؟ |
|---|---|
demo.example.com |
✅ يطابق *.example.com |
demo.app.example.com |
❌ مستويان — لا شهادة مجانية تغطيه |
Caution
هذا أصعب عطل في النظام كله. الـ DNS صحيح، والنفق متصل، وlinko doctor أخضر
بالكامل — ومع ذلك يرفض المتصفح الاتصال بـ
ERR_SSL_VERSION_OR_CIPHER_MISMATCH، لأن الرفض يحدث قبل وصول أي طلب
إلى نفقك. لهذا يحذّرك linko init منه مسبقًا.
تريد مستويين؟ يلزمك Advanced Certificate Manager من Cloudflare (١٠ دولارات شهريًا للدومين) ثم تفعيل Total TLS. البدائل المجانية — النطاقات الفرعية المستقلة وإعداد CNAME الجزئي — محصورة بخطط Enterprise وBusiness.
أبسط حل مجاني: اجعل التمييز في الاسم نفسه — myapp-dev.example.com بدل
myapp.dev.example.com.
كل شيء في ~/.linko/:
~/.linko/
├── config.json البيانات والمسارات (صلاحيات 0600)
├── bin/cloudflared نسخة خاصة، تُنزَّل عند أول استخدام
├── run/<name>.pid ملف لكل نفق يعمل بالخلفية
└── logs/<name>.log سجل لكل نفق يعمل بالخلفية
| المتغير | الأثر |
|---|---|
LINKO_API_TOKEN |
يتجاوز التوكن المحفوظ |
LINKO_HOME |
مجلد الإعدادات (الافتراضي ~/.linko) |
NO_COLOR |
تعطيل الألوان |
ينشئ linko نفقًا واحدًا في حسابك، وكل مشروع يصبح اسمًا داخله موجّهًا إلى
منفذ مختلف.
crm.example.com ──┐
│ ┌──▶ localhost:3000
api.example.com ──┼──▶ Cloudflare Edge ─┼──▶ localhost:8080
│ (نفق واحد) │
test.example.com ──┘ └──▶ localhost:5173
▲
│ اتصال صادر فقط
cloudflared على جهازك
عند تشغيل linko 3000 تحدث ثلاثة أشياء:
- يُنشأ سجل
CNAMEمُوكَّل يشير إلى<tunnel-id>.cfargotunnel.com - تُضاف قاعدة توجيه تربط الاسم بـ
http://localhost:3000 - يُشغَّل
cloudflaredفيفتح اتصالًا صادرًا نحو Cloudflare
لا شيء على جهازك ينتظر اتصالات واردة — لهذا لا تحتاج لمسّ الراوتر أو جدار الحماية إطلاقًا.
كل ما يلي أخطاء حقيقية ظهرت أثناء بناء الأداة واختبارها.
| الرسالة | السبب | الحل |
|---|---|---|
no zone named "example.com" |
التوكن ينقصه صلاحية Zone، أو أن Zone Resources فارغة |
أضف Zone → DNS → Edit مع تضمين دومينك. linko يعرض لك النطاقات التي يراها التوكن. |
Cloudflare refused to create the DNS record code 10000 |
صلاحية DNS على Read بدل Edit |
العثور على الـ zone يحتاج قراءة فقط، لذلك يمر الإعداد كاملًا ثم يفشل عند أول كتابة. غيّرها إلى Edit. |
Could not create the tunnel code 10000 |
التوكن يغطي DNS ولا يغطي الأنفاق | أضف Account → Cloudflare Tunnel → Edit على نفس التوكن. |
ERR_SSL_VERSION_OR_CIPHER_MISMATCH |
الرابط بعمق مستويين | linko init --force --base example.com أو اشترِ ACM. |
no API token: pass --token or set LINKO_API_TOKEN |
شغّلت linko init --yes بلا رمز |
export LINKO_API_TOKEN='…' أو مرّر --token. |
command not found: linko |
مجلد التثبيت ليس في مسارك | أعد فتح الطرفية، أو exec $SHELL. |
HTTP 502 · Error 1033 |
النفق يعمل لكن لا شيء يستمع على المنفذ | تحقق بـ curl http://localhost:3000. وإن كان تطبيقك يستمع على الـ loopback فقط، استخدم linko 127.0.0.1:3000. |
التوكنات تنتهي صلاحيتها، والأنفاق تُحذف من لوحة Zero Trust، وسجلات DNS تُمسح
يدويًا. يكتشف linko الثلاثة، ويشرح ما حدث بوضوح، ثم يصلحه — لا يكتفي
بطباعة رمز خطأ من Cloudflare.
التوكن توقّف عن العمل
$ linko 3000
✗ Cloudflare is no longer accepting the stored API token.
· It was most likely deleted, edited, or it expired.
Create a Cloudflare API token
1. https://dash.cloudflare.com/profile/api-tokens
2. Add both permission rows (+ Add more):
Zone → DNS → Edit
Account → Cloudflare Tunnel → Edit
New Cloudflare API token: ················
✓ Token updated and saved to ~/.linko/config.json
✓ Tunnel connectedيتحقق من التوكن الجديد قبل حفظه، فلا يمكن لخطأ مطبعي أن يقفل عليك إعدادك.
النفق حُذف
يعيد linko إنشاءه (أو يتبنّى واحدًا بنفس الاسم)، ويجلب توكن نفق جديدًا،
ويعيد توجيه كل سجلات DNS إلى النفق الجديد — لأن النفق الجديد يعني هدف
CNAME جديدًا — ثم يستعيد كل المسارات.
سجل DNS حُذف
يُعاد إنشاؤه عند أول linko <port>، أو كلها دفعة واحدة:
linko doctor --fixيصلح --fix التوكن الميت، والنفق المحذوف، وسجلات DNS الناقصة، والمسارات
المفقودة، ثم يعيد الفحص كاملًا. أضف --yes لتخطّي أسئلة التأكيد.
عند الشك:
linko doctorlinko remove --all --yes
rm -rf ~/.linko
linko init- الروابط المنشورة عامة. أي شخص يملك الرابط يصل إلى مشروعك. لا تنشر بيانات حساسة، وإن احتجت مصادقة فضع Cloudflare Access أمام الاسم.
- التوكن في
~/.linko/config.jsonبصلاحيات0600. لا ترفعه إلى Git أبدًا؛ للفرق وCI استخدمLINKO_API_TOKEN. - توكن النفق يُمرَّر إلى
cloudflaredعبر البيئة لا عبر سطر الأوامر، فلا يظهر فيps. - لا يمسّ سجلات غيره. إن كان الاسم يشير إلى موقعك الحقيقي فلن يستبدله أو يحذفه.
github.com/Devehab/linko · رخصة MIT