English: Node.js application guide
نسخهٔ Node این پروژه (bale-vpn-node/) یک فایل اجرایی واحد است که این قابلیتها را در خود دارد:
- یک کلاینت WebSocket برای سیگنالدهی بله،
- یک رابط کاربری وب روی
http://localhost:3001که در حالت کلاینت بهصورت خودکار در مرورگر پیشفرض باز میشود — تمام پیکربندی (ورود، انتخاب مخاطب، فعالسازی تونل) از همین صفحه انجام میشود؛ نیازی به تنظیمات از طریق ترمینال نیست. - حالت پراکسی SOCKS5 برای کلاینت و سرور،
- حالت سرور VPN روی TUN هسته (لینوکس و مک) که اجازه میدهد کلاینت اندرویدی با مسیریابی کامل IP وصل شود.
همان فایل اجرایی روی لینوکس، مک و ویندوز اجرا میشود. فقط حالت سرور VPN مختصِ لینوکس است، چون به دستگاه TUN هسته و قاعدهٔ MASQUERADE در iptables نیاز دارد.
| حالت | پلتفرم | کارش چیست |
|---|---|---|
| کلاینت SOCKS5 | لینوکس / مک / ویندوز | روی 127.0.0.1:1080 گوش میدهد و TCP را از طریق مخاطب انتخابشدهٔ بله تونل میکند (آن مخاطب باید سرور را اجرا کند). |
| سرور SOCKS5 | لینوکس / مک / ویندوز | تماسهای ورودی از مخاطبین فهرست مجاز را میپذیرد و TCP کاربر تماسگیرنده را رله میکند. بدون نیاز به TUN هسته، iptables/pf یا root. |
| سرور VPN (TUN) | لینوکس / مک | تماسهای ورودی از مخاطبین فهرست مجاز را میپذیرد و بستههای IP خام را روی دستگاه TUN هسته میگیرد (bale0 در لینوکس، utunN در مک) و با NAT هسته (iptables در لینوکس، pf در مک) به اینترنت آزاد میفرستد. |
یک فایل اجرایی، نقش خود را موقع راهاندازی انتخاب میکند: با آرگومان server بهعنوان سرور اجرا میشود، بدون آرگومان بهعنوان کلاینت. در حالت سرور روی لینوکس/مک بهصورت ترکیبی اجرا میشود — هم کلاینتهای SOCKS5 و هم کلاینتهای TUN را همزمان میپذیرد؛ روی ویندوز فقط SOCKS5 سرویس میدهد.
از صفحهٔ Releases همین مخزن، فایل دودویی balevpn-<version>-<platform> را برای سیستم خود دانلود کنید.
# لینوکس / مک:
chmod +x balevpn-*-{linux,macos}-*
./balevpn-... # حالت کلاینت (پیشفرض) — UI روی http://localhost:3001
./balevpn-... server # حالت سرور
./balevpn-... 3001 # حالت کلاینت با ذکر صریح پورت (هر عدد خام کار میکند)
./balevpn-... server 3001 # حالت سرور با ذکر صریح پورت
# ویندوز (PowerShell):
.\balevpn-...-win-x64.exe
.\balevpn-...-win-x64.exe server
.\balevpn-...-win-x64.exe 3001آرگومانها موقعیتی و بدون ترتیباند: هر عدد خام بهعنوان پورت UI وب در نظر گرفته میشود (پیشفرض 3001)؛ کلمهٔ server نقش را به سرور تغییر میدهد. بقیه نادیده گرفته میشود.
در حالت کلاینت فایل اجرایی بهصورت خودکار http://localhost:<port> را در مرورگر پیشفرض باز میکند — همهچیز از همان صفحه انجام میشود (ورود، انتخاب مخاطب بله، کلیک روی Activate). حالت سرور بهصورت خودکار مرورگر را باز نمیکند، چون معمولاً روی سرورهای بدون نمایشگر اجرا میشود.
UI وب فقط روی
127.0.0.1گوش میدهد — از هیچ دستگاه دیگری در شبکه قابل دسترس نیست. برای سرور بدون نمایشگر، با SSH local port forwarding آن را روی لپتاپتان قابل دسترس کنید:ssh -L 3001:127.0.0.1:3001 user@your-serverسپس در مرورگر محلی خودتان
http://localhost:3001را باز کنید. تا وقتی از UI استفاده میکنید، این تونل SSH باید باز بماند.
وقتی در حالت کلاینت اجرا میکنید، فایل اجرایی http://localhost:3001 را در مرورگر پیشفرض باز میکند. مراحل کار:
-
ورود — شماره تلفن، سپس کد پیامکی؛ یا کوکی JWT
access_tokenرا ازweb.bale.aiدر کادر مربوطه پِیست کنید. توکن در سمت سرور در${RUNTIME_DIR}/.bale-vpn_config.json(با مجوز 0600) ذخیره میشود؛ مرورگر فقط یک مقدار بولیtokenSetمیبیند، نه خودِ JWT را. -
پراکسی تونل — یک مخاطب بله را از فهرست انتخاب کنید (یا با شمارهٔ تلفن جستجو کرده و اضافه کنید)، پورت SOCKS5 را تعیین کنید (پیشفرض ۱۰۸۰)، روی Activate بزنید.
-
وقتی نوار وضعیت سبز شد، تونل WebRTC برقرار است. از این لحظه میتوانید برنامههای خود را به
127.0.0.1:1080بهعنوان پراکسی SOCKS5 وصل کنید.
در حالت سرور همین صفحه کلاینتهای متصل، فهرست درخواستهای در انتظار تأیید (با دکمههای Accept / Allow always / Reject) و فهرست مجاز را نشان میدهد.
SOCKS5 یک پروتکل رلهٔ TCP در سطح هر برنامه است — برنامه به 127.0.0.1:1080 وصل میشود و پراکسی آن را از داخل تونل عبور میدهد. این یک VPN سراسری نیست: فقط برنامههایی که خودتان طوری تنظیم کنید که از پراکسی استفاده کنند، از تونل میگذرند؛ بقیهٔ اتصالها از اینترنت واقعی شما عبور میکنند. این رفتار عمدی و گاهی مفید است (مثلاً یک سایت را از تونل ببینید و بقیه را مستقیم)، اما به این معناست که یک برنامهٔ بد تنظیمشده در سکوت تونل را دور میزند.
محدودیتهای دیگر SOCKS5 نسبت به VPN واقعی:
- فقط TCP. UDP (شامل QUIC، بعضی تماسهای ویدیویی، مالتیکست و…) رله نمیشود. اگر سایتی به QUIC نیاز داشته باشد و مرورگر به TCP/HTTPS برنگردد، آن سایت کار نخواهد کرد. (قالب سیمی این پروژه فریم رلهٔ UDP را پشتیبانی میکند ولی بیشتر مرورگرها چنین چیزی را از طریق SOCKS5 ارسال نمیکنند.)
- ICMP کار نمیکند، پس
pingهمچنان از اینترنت واقعی شما میرود. - IP خام نه، یعنی برنامههایی مثل WireGuard که میخواهند روی تونل سوار شوند، تونل نمیشوند.
اگر مسیریابی کامل IP میخواهید، یا از اپلیکیشن اندروید استفاده کنید یا سرور VPN لینوکسی (TUN) را راه بیندازید و از طریق کلاینت اندرویدی وصل شوید.
کلاینت یکی از مخاطبان بله را انتخاب میکند (که باید در حالت سرور — Node یا اندروید — باشد) و TCP را از طریق او رد میکند. ترافیک پایدار روی کانال دادهٔ LiveKit جریان دارد و WebSocket بله فقط برای سیگنالدهی کوتاه استفاده میشود و پس از برقراری کانال LK دوباره قطع میگردد.
بعد از فعالسازی، هر برنامهای که از SOCKS5 پشتیبانی کند را به 127.0.0.1:1080 وصل کنید.
⚠️ برای تونل از یک مرورگر (یا پروفایل) جداگانه استفاده کنید. UI رویhttp://localhost:3001است. اگر در همان مرورگری که تونل را مدیریت میکنید،127.0.0.1:1080را بهعنوان SOCKS5 تنظیم کنید، تمام صفحههای آن مرورگر — از جمله خودِ UI — تلاش میکنند از طریق همان پراکسی رد شوند. بهمحض اینکه چیزی در تونل خراب شود، دیگر نمیتوانید UI را باز کنید تا تعمیرش کنید. یک مرورگر برای مدیریت تونل و یک مرورگر دیگر برای ترافیک تونلشده نگه دارید.
⚠️ حواستان باشد DNS هم از پراکسی برود. بسیاری از مرورگرها بهصورت پیشفرض نام میزبان را محلی رزولو میکنند و فقط آدرس IP را به سرور SOCKS5 میفرستند — یعنی هرچند ترافیک TCP شما تونل میشود، پرسوجوی DNS همچنان از رزولور محلی شما عبور میکند و هدف اصلی تونل (دور زدن مسدودی دامنه) را نقض میکند.سرور SOCKS5 این پروژه از تفسیر نام میزبان روی سرور پشتیبانی میکند (ATYP=0x03 در SOCKS5 را میپذیرد). پس کافی است کلاینت نام را بهجای IP بفرستد:
- Firefox — Settings → Network Settings → Manual proxy → SOCKS v5 با میزبان
127.0.0.1و پورت1080، و گزینهٔ Proxy DNS when using SOCKS v5 را تیک بزنید (یا درabout:configمقدارnetwork.proxy.socks_remote_dnsرا رویtrueبگذارید).- Chrome / Chromium / Edge — مرورگر را با
--proxy-server="socks5://127.0.0.1:1080"اجرا کنید. در این حالت، Chrome رزولو DNS را به سرور SOCKS5 میسپارد. افزونههایی مانند FoxyProxy یا SwitchyOmega همین گزینه را در UI دارند؛ مطمئن شوید گزینهٔ remote DNS فعال باشد.curl— از--socks5-hostname 127.0.0.1:1080استفاده کنید، نه--socks5(که اول DNS را محلی رزولو میکند).- سایر ابزارها — دنبال گزینهای با نام «remote DNS»، «SOCKS5h» یا «tunnel DNS lookups» بگردید. اسکیم URL استاندارد برای این رفتار
socks5h://است.
اگر بخواهید یک نسخهٔ Node را بهعنوان کلاینت اجرا کنید (یعنی این برنامه، که به سرور Node یا اندرویدی وصل میشود)، شنوندهٔ SOCKS5 داخلی همین قاعده را رعایت میکند: ATYP=0x03 (نام میزبان)، ATYP=0x01 (IPv4) و ATYP=0x04 (IPv6) را میپذیرد. نام میزبان دستنخورده به سمت سرور فرستاده میشود و DNS هیچگاه روی کلاینت محلی رزولو نمیشود. بنابراین خودِ برنامه نشتی DNS ندارد و هر نشت احتمالی صرفاً از تنظیمات برنامهٔ شما (مرورگر و بقیه) میآید.
رمزنگاری در سطح برنامه (HTTPS / TLS) چیزی است که محتوای پیامهای شما را از سرور همتا و زیرساخت LiveKit بله مخفی نگه میدارد. به یادداشت حریم خصوصی در README اصلی مراجعه کنید.
با آرگومان server اجرا کنید. تماسهای ورودی بله پاسخ داده میشوند (با عبور از فهرست مجاز — پایینتر میبینید) و سرور بهعنوان رلهٔ TCP عمل میکند. نیاز به دسترسی خاص ندارد.
./balevpn-... serverاین آسانترین راه برای دادن یک رلهٔ TCP به دوستتان است، بدون نیاز به راهاندازی VPN.
این پربازدهترین حالت سرور است و روی لینوکس و مک کار میکند. فرآیند Node به یک دستگاه TUN هسته متصل میشود (bale0 در لینوکس، utunN در مک) و خود هسته عملِ مسیریابی و NAT را انجام میدهد. این رویکرد بهمراتب سریعتر از پشتهٔ TCP/IP فضای کاربری است که در سرور اندرویدی استفاده میشود.
ترکیب پیشنهادی: سرور TUN + کلاینت اندرویدی — بهترین تجربهٔ سمت کلاینت (اندروید با VpnService تمام بستههای IP دستگاه را به تونل میفرستد).
# ۱. اجازهٔ مدیریت دستگاه TUN را بدون root، به همان فایل دودویی منتشرشده بدهید
sudo setcap cap_net_admin+eip ./balevpn-<version>-linux-x64
# ۲. قاعدهٔ MASQUERADE برای NAT ترافیک تونل (یکبار اجرا کنید)
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADEسپس اجرا:
./balevpn-<version>-linux-x64 serverروی مک معادل setcap وجود ندارد، پس حالت سرور با root اجرا میشود. قاعدهٔ NAT (anchor balevpn در pf) و فوروارد IP در زمان اجرا بهصورت خودکار بارگذاری میشوند؛ اینترفیس WAN با route -n get default تشخیص داده میشود.
sudo ./balevpn-<version>-macos-arm64 server۱. اینترفیس TUN قبلی را (در صورت وجود) حذف میکند.
۲. دستگاه TUN را میسازد و آدرس 10.8.0.1/24 را به آن اختصاص میدهد.
۳. فوروارد IPv4 را روشن میکند (/proc/sys/net/ipv4/ip_forward در لینوکس، net.inet.ip.forwarding در مک).
۴. قاعدهٔ NAT را بارگذاری میکند (iptables MASQUERADE در لینوکس، pf anchor در مک).
۵. شروع به دریافت تماسهای ورودی بله میکند — تماسگیرندههای مجاز خودکار پذیرفته میشوند؛ بقیه به صف انتظار میروند (به کنترل پذیرش سرور مراجعه کنید).
وقتی یک کلاینت اندرویدی وصل میشود، آدرس 10.8.0.2/24 به او داده میشود و تمام ترافیکش وارد تونل میگردد. تا ۲۵۳ کلاینت میتوانند همزمان وصل شوند — سرور بهطور شفاف آدرس مبدأ هر کلاینت را به یک IP متمایز در 10.8.0.0/24 بازنویسی میکند تا هسته بتواند جریانهای همزمان را از هم تشخیص دهد.
- فقط IPv4. بستههای IPv6 از کلاینت دور انداخته میشوند (کلاینت اندرویدی با ICMPv6 Destination Unreachable بهسرعت به IPv4 برمیگردد).
چه در نقش سرور SOCKS5 و چه TUN VPN، هر تماس ورودی از مخاطبی که در فهرست مجاز نیست، در صف در انتظار قرار میگیرد. UI آن را بهشکل ردیف زرد با دکمههای Accept once / Allow always / Reject نشان میدهد.
- Accept once فقط همین تماس را پذیرش میکند و تماسگیرنده را در فهرست مجاز قرار نمیدهد. تماسهای بعدی دوباره در صف انتظار مینشینند.
- Allow always تماسگیرنده را به فهرست مجاز اضافه میکند (در سمت سرور در
${RUNTIME_DIR}/.bale-vpn_config.jsonکلیدadmission، با مجوز 0600 ذخیره میشود). تماسهای بعدی از همان کاربر خودکار پذیرفته میشوند. - Reject یک
DiscardCallمیفرستد تا تونل کلاینت بلافاصله بسته شود و شناسهٔ کاربر را به فهرست مسدود اضافه میکند — تماسهای بعدی از این شناسه بیصدا رد میشوند (بدون نوتیفیکیشن، بدون صف انتظار). برای لغو، فهرست Blocked callers را پایین صف انتظار باز کنید و دکمهٔ Unblock ردیفش را بزنید. - ردیفهای در انتظار، بعد از ۶۰ ثانیه بهصورت خودکار رد میشوند. این تایماوت ۶۰ ثانیهای کاربر را مسدود نمیکند — فقط Reject صریح مسدود میکند.
دو راه برای آوردن JWT access_token به برنامه:
۱. OTP تلفنی از طریق UI — شماره را وارد کنید، کد پیامکی را تایپ کنید؛ برنامه کوکی را از مسیر استاندارد web.bale.ai/set-cookie/?jwt=… میگیرد و در ${RUNTIME_DIR}/.bale-vpn_config.json (با مجوز 0600) ذخیره میکند. مسیر توصیهشده.
۲. پِیست توکن — کوکی access_token را از یک سشن web.bale.ai فعال در Chrome کپی کنید (DevTools → Application → Cookies) و در کادر مربوطه پِیست کنید.
کد بستن WebSocket برابر 4401 یعنی توکن منقضی شده — دوباره وارد شوید.
کانال دادهٔ LiveKit با DTLS رمزنگاری میشود، پس ترافیک از دید ناظرهای مسیر و میدلباکسها مبهم است. اما سرورهای LiveKit بله نقش SFU/TURN را بازی میکنند و به دادهٔ رمزگشاییشده دسترسی دارند — میتوانند مقصدهای شما و محتوای ترافیک رمزنگارینشدهٔ لایهٔ کاربرد را ببینند. در لایهٔ کاربرد از TLS (HTTPS، DNS رمزنگاریشده و…) استفاده کنید و این تونل را مثل یک VPN عمل کنید که گردانندهاش را کاملاً نمیشناسید.
برای یادداشت کاملتر به README اصلی مراجعه کنید.




