تونل معکوس بدون port forward - وب هاستینگ خانگی برای توسعه دهنده ها
من مدتها بود که با z-tel آدرس ip-static داشتم. با port forward دامنه رو میاوردم روی vm های توسعه داخل خونه. مشتریها همیشه ته دامنه تستی یه پورت هم داشتن. هر چند 443 رو میشد آورد. تا این که با تانل cloudflare آشنا شدن. دیدم اصلا ip static هم نمیخواد. خیلی تمیز و شسته رفته وصل میکنه به دامنه. اسمش تانل معکوس هست. یعنی تانل شما میاید وصل میشید به سرور و یا شبکه در بیرون این ولی برعکس هست. یه تانل اجرا میکنید که شبکه بیرون با اون دامنه شما رو ببینه
توپولوژی میشه تصویر زیر
چرا تونل معکوس؟
با تونل معکوس، سرور شما از داخل به شبکهٔ ابری وصل میشود. بنابراین:
پروژه ای بر روی سیستم شماست و دنیایی از تنظیمات دارد، وقت هم نمکینید برای دمو بر روی هاست و سرور مشتری نصب کنید. الان دقیقا کدها کجاست؟ معلومه دیگه روی سیستم شخصی که دارید همین الان برنامه نویسی میکنید. دقیقا همین localhost روی مرورگرتون. من توی این پست مرحله به مرحله بهتون یاد میدم چطور یه دامنه رو به این localhost وصل کنید و مشتری هم از بیرون ببینه و تستها رو بگیره.
فقط دستورات این پست برای عزیزانی که روی سیستم خودشون لینوکس دارن کاربرد داره. ویندوز بلد نیستم و گرنه راهنمای اون رو هم میذاشتم.
نیازی به Port-Forward روی مودم و آیپی ثابت ندارید.
حتی اگر VPN روی سرور روشن باشد، دسترسی عمومی برقرار میماند (ورودیها از مسیر تونل میآیند).
گواهی HTTPS و CDN/حفاظت Cloudflare را بهراحتی میگیرید.
اگر Cloudflare برای دامنهتان قابلاستفاده است، Cloudflare Tunnel پیشنهاد میشود. اگر نمیخواهید Nameserver عوض کنید یا فقط یک URL سریع میخواهید، Tailscale Funnel گزینهٔ سریعتری است.
بخش ۱) Cloudflare Tunnel (پیشنهادی برای دامنهٔ شخصی)
پیشنیازها
دامنهتان را در Cloudflare اضافه کرده و Nameserverها را به Cloudflare تغییر دهید. (در صورت عدم اتصال تونل، خطای 1033 میبینید؛ این خطا یعنی تونل به Edge وصل نیست.)
Cloudflare Docs
وبسرور (Nginx/PHP-FPM و …) داخل سرور فعال باشد (روی 127.0.0.1:80 یا 127.0.0.1:443).
# Install Cloudflared via official apt repo sudo mkdir -p --mode=0755 /usr/share/keyrings curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main" | sudo tee /etc/apt/sources.list.d/cloudflared.list sudo apt-get update && sudo apt-get install -y cloudflared cloudflared --version # verify install
نصب از ریپو رسمی Cloudflare انجام میشود.
# 1) Authenticate to your Cloudflare account cloudflared tunnel login # -> pick your zone in the browser; it writes ~/.cloudflared/cert.pem # 2) Create a named tunnel (choose a friendly name) cloudflared tunnel create web-prod # -> note Tunnel UUID and credentials JSON path # 3) List tunnels; later use to check active connections cloudflared tunnel list
باید توی CloudFalre لاگین باشید تا بتونید از url ای که در لحظه auth میسازه وارد اکانت بشید و دامنه رو بر روی auth درخواست شده active کنید
# Create proxied DNS mapping for your hostname to this tunnel cloudflared tunnel route dns web-prod example.com # Repeat for each hostname you want to serve through this tunnel
بجای example.com نامه دامنه رو بزنید
این فرمان یک رکورد CNAME به تونل میسازد. خود رکورد مستقل از وضعیت تونل است؛ اگر تونل خاموش باشد معمولاً خطای 1016 میبینید، ولی 1033 یعنی تونل به Edge وصل نشده.
پیکربندی config.yml — دو الگو
الگوی سریع و تمیز (HTTP داخلی):
سادهترین راه این است که تونل به HTTP داخلی وصل شود؛ TLS سمت کاربر را Cloudflare هندل میکند.
# /etc/cloudflared/config.yml tunnel: <YOUR-TUNNEL-UUID> credentials-file: /root/.cloudflared/<YOUR-TUNNEL-UUID>.json ingress: - hostname: example.com service: http://127.0.0.1:80 # internal HTTP avoids TLS mismatch on 127.0.0.1 - service: http_status:404 # required catch-all
توی دستورات قبلی یک سری uuid و مسیر فایل json داده که به همران اسم دامنه و پورتی که بر روی سیستم در حال listen هست رو این جا میزارید
cloudflared tunnel ingress validate # should say OK
باید دیگه بهتون ok بده
اگر هم میخواد https کنید. مثلا شاید در حال توسعه بات تلگرام هستید. باید ادامه همین پست نحوه بردن روی https رو گفتم
همین الان با زدن این دستور اجرا میشه و از روی اون دامنه به سیستم شما تانل زده میشه و وب سرور شما جواب میده و اپ رو از بیرون میشه دید
# Run in foreground for a quick test cloudflared tunnel --config /etc/cloudflared/config.yml run web-prod
یا این که به شکل سرویس در بیارید که همش اجرا بشه. به هر حال برق میره و میاد و یکی نیازه که دوباره استارتش کنه. البته شاید این پست رو زمانی میخونید که روسیه نیروگاه های کوچیک هسته ای رو داده به ایران و مشکل برق حل شده
# Install as a system service (reads /etc/cloudflared/config.yml) sudo cloudflared service install sudo systemctl enable --now cloudflared systemctl status cloudflared
و اما https کردن همین مسیر
باید از certbot براش certificate بگیرید
ابتدا نصبش کنید
apt-get install -y ca-certificates curl apt install -y certbot python3-certbot-nginx
بعدش nginx که تنظیم هست. یعنی الان داره با پورت 80 روی همون دامنه کار میکنه
certbot --nginx -d site-sample.ir --email your@mail.com --agree-tos --redirect --hsts --staple-ocsp -n
فایل yaml رو هم بهش میگید من https هستم
# /etc/cloudflared/config.yml (English comments) tunnel: <YOUR-TUNNEL-UUID> credentials-file: /root/.cloudflared/<YOUR-TUNNEL-UUID>.json ingress: - hostname: example.com service: https://127.0.0.1:443 originRequest: originServerName: example.com # verify certificate against this name # noTLSVerify: true # last resort (not recommended) - service: http_status:404
اون تیکه noTLSVerifynoTLSVerify برای زمانی هست که self sign کنید و خودتون کلید بزارید. که خب چندان جالب نیست. با همین certbot معتبر بگیرید