زنده نگهداشتن Docker، Git و CI/CD روی سرورهای ایران در اختلال اینترنت با تونل معکوس SSH
(با SSH Reverse Tunneling + پروکسی محلی)
وقتی اینترنت ناپایدار میشود، معمولاً اول بخشهای «نامرئی» کار مهندسی میشکنند: دانلود پکیج، docker pull، پایپلاین CI/CD، و حتی دسترسی ساده به سرورهای داخلی.
اخیراً وضعیتی داشتم که اتصال آنقدر ناپایدار بود که حتی رسیدن به سرورهای داخلی هم مطمئن نبود. گاهی میتوانستم SSH بزنم، اما خود سرور دسترسی پایدار به اینترنت عمومی نداشت. یعنی نصب Docker، دانلود dependency و workflow عادی deploy ممکن نبود.
این نوشته یک راهکار اضطراری است که برایم کار کرد: تونل کردن دسترسی اینترنت از ماشین خودم به سرور با SSH reverse port forwarding، با در دسترس گذاشتن یک پروکسی HTTP/SOCKS محلی روی localhost سرور.
راهکار عملی برای شرایط اضطراری است — نه طراحی شبکهٔ بلندمدت ایدهآل.
ایده (سطح بالا)
فرضها:
- ماشینی (لپتاپ/دسکتاپ) با دسترسی نسبتاً کارآمد به اینترنت دارید.
- گاهی حداقل میتوانید با SSH به سرور وصل شوید (حتی با اینترنت موبایل).
- روی ماشین محلی میتوانید پروکسی (HTTP و/یا SOCKS5) اجرا کنید: Clash، V2Ray، Squid و مشابه.
هدف:
- سرور بتواند ترافیک خروجی را «از طریق» پروکسی محلی شما بفرستد — تا بتواند:
- پکیج نصب کند (
dnf/yum/apt) - ایمیج بکشد (
docker pull) - در صورت نیاز به Git / registry دسترسی داشته باشد
- پکیج نصب کند (
گام ۱: اجرای پروکسی محلی
روی ماشین محلی مطمئن شوید پروکسی روی LAN (یا localhost) گوش میدهد. در مورد من در دسترس بود در:
192.168.1.102:2080
مقادیر شما بسته به ستاپ فرق میکند.
گام ۲: در دسترس گذاشتن پروکسی روی سرور با SSH reverse
از ماشین محلی:
ssh -o ServerAliveInterval=20 -o ServerAliveCountMax=3 \
-R 127.0.0.1:10809:192.168.1.102:2080 \
-R 127.0.0.1:10808:192.168.1.102:2080 \
root@X.X.X.Xاین کار چه میکند:
- دو پورت را فقط روی
127.0.0.1سرور bind میکند:127.0.0.1:10808127.0.0.1:10809
- هر اتصال به این پورتها روی سرور به endpoint پروکسی محلی شما (
192.168.1.102:2080) برمیگردد.
من استفاده کردم از:
10808بهعنوان HTTP proxy10809بهعنوان SOCKS5 proxy
(اگر نرمافزار پروکسی فقط یک پروتکل دارد، یک mapping کافی است.)
نکتهٔ امنیتی: bind به 127.0.0.1 مهم است. جلوی افشای پروکسی به اینترنت عمومی را میگیرد.
گام ۳: تست خروجی از سرور
SOCKS5 با curl:
curl --socks5 127.0.0.1:10809 https://cloudflare.comاجرای اسکریپت از طریق پروکسی:
ALL_PROXY=socks5://127.0.0.1:10809 \
curl -fsSL --socks5 127.0.0.1:10809 \
https://example.com/script.sh | shگام ۴: پیکربندی Docker برای پروکسی (systemd)
روی سیستمهای مبتنی بر RHEL (CentOS / AlmaLinux / Rocky):
sudo mkdir -p /etc/systemd/system/docker.service.d/
sudo nano /etc/systemd/system/docker.service.d/proxy.confمحتوا:
[Service]
Environment="ALL_PROXY=socks5://127.0.0.1:10809"
Environment="HTTP_PROXY=http://127.0.0.1:10808"
Environment="HTTPS_PROXY=http://127.0.0.1:10808"سپس:
sudo systemctl daemon-reload
sudo systemctl restart dockerاگر تونل بالا باشد، docker pull باید شروع به کار کند.
گام ۵: استفاده با dnf / yum
با dnf:
sudo dnf --setopt=proxy=http://127.0.0.1:10808 install unzipبا yum:
sudo yum --setopt=proxy=http://127.0.0.1:10808 install unzipکم کردن وابستگی به اینترنت عمومی (پیشنهادی)
وقتی عملیات پایهٔ سرور پایدار شد، کمتر به سرویسهای خارجی وابسته شوید.
ابزارهای مفید self-hosted:
- Gitea — میزبانی سبک Git
- Verdaccio — کش رجیستری خصوصی npm
- Kellnr — رجیستری / پروکسی crateهای Rust
حتی خودمیزبانی جزئی، بقا در قطعی را خیلی بهتر میکند.
نکات پایانی
- این یک workaround است، نه جایگزین زیرساخت درست.
- آن را پل اضطراری برای نصب پکیج، pull ایمیج و بازیابی کوتاهمدت بدانید.
- نشست SSH را پایدار نگه دارید (
ServerAliveIntervalکمک میکند). - پورتهای remote forward را به
0.0.0.0bind نکنید مگر کاملاً پیامد امنیتیاش را بفهمید.
نسخهٔ canonical. همچنین در Medium.