شبکه

سرور مناسب تانل — انتخاب و راه‌اندازی تونل GRE بین دو سرور

انتخاب سرور مناسب تانل و برقراری تونل GRE بین سرور ایران و سرور خارج روی یک شبکه‌ی خصوصی

انتخاب سرور مناسب تانل بیش از آنکه به تعداد هسته و حجم رم مربوط باشد، به کیفیت مسیر شبکه گره خورده است؛ یک سرور کوچک روی مسیری تمیز، از سروری پرقدرت روی مسیری شلوغ بهتر عمل می‌کند. در این راهنما معیارهای انتخاب، تفاوت پروتکل‌ها، راه‌اندازی گام‌به‌گام تونل GRE و نقش حیاتی MSS clamping را می‌بینیم.

تونل سرور یعنی چه و چه مسئله‌ای را حل می‌کند؟

تونل سرور یعنی بسته‌های شبکه‌ی شما داخل بسته‌های دیگری بسته‌بندی می‌شوند و از مسیری مشخص بین دو سرورِ خودتان عبور می‌کنند («تانل» و «تونل» یک واژه‌اند). نتیجه این است که دو سرورِ جدا در دو دیتاسنتر، انگار روی یک سوییچ محلی نشسته‌اند و با آدرس‌های خصوصی همدیگر را می‌بینند.

دستاورد اول یکپارچگی شبکه است: فضای آدرس خصوصی مشترکی که فایروال و مدیریت دسترسی را ساده می‌کند. دستاورد دوم کنترل مسیر است و مشروط: اگر مسیر پیش‌فرض ناپایدار باشد، عبور ترافیک از نقطه‌ی میانیِ بهتر می‌تواند نوسان را کم کند — چیزی که باید سنجید، نه فرض کرد.

چهار کاربرد واقعی تونل بین سرور ایران و سرور خارج

  • ریورس‌پراکسی سایتی که اوریجینش خارج است. کاربر به سرور ایران وصل می‌شود و اتصال TCP با او روی مسیر کوتاه بسته می‌شود. اما در عبور خام (تونل لایه‌ی سه یا پراکسی TCP) مذاکره‌ی TLS همچنان انتها‌به‌انتها با اوریجین است و کل مسیر بلند را طی می‌کند؛ برای کوتاه‌کردنش باید گواهی را روی سرور ایران بنشانید.
  • دیپلوی و به‌روزرسانی. سروری که مدام به ریپازیتوری، رجیستری کانتینر یا API بیرونی وصل می‌شود، روی مسیر پایدارتر خطای کمتری می‌گیرد.
  • انتقال بکاپ. جابه‌جایی نسخه‌های پشتیبان با rsync روی شبکه‌ی خصوصی، هم امن‌تر است و هم کمتر نیمه‌کاره می‌ماند.
  • یکپارچه‌کردن چند سرور. دیتابیس، اپلیکیشن و مانیتورینگ با آدرس‌های 10.x و پورت‌هایی که هرگز روی اینترنت باز نمی‌شوند.

معیارهای انتخاب سرور مناسب تانل — چرا CPU و رم آخرین اولویت‌اند

سرور مناسب تانل سروری است که مسیر شبکه‌ی تمیز، ترافیک کافی و کرنل در اختیار شما داشته باشد. کپسوله‌کردن بسته‌ها در کرنل انجام می‌شود و برای چند صد مگابیت بر ثانیه دو هسته و ۱ گیگابایت رم کافی است؛ بودجه را صرف شبکه کنید، نه پردازنده.

کیفیت پیرینگ و مسیر را در هر دو جهت بسنجید

مسیر رفت و برگشت در اینترنت لزوماً یکی نیست؛ ممکن است یک جهت تمیز باشد و جهت معکوس از چند اپراتور شلوغ عبور کند. پس پیش از انتخاب سرور تانل، مسیر را روی هر دو سر بسنجید:

mtr -rwzc 100 <peer-ip>

خواندن درست ستون Loss% و جداکردن افت بسته‌ی کاذبِ هاپ‌های میانی از افت واقعی را در راهنمای تست کیفیت سرور ایران شرح داده‌ایم. آنچه مخصوص تونل است، مقایسه‌ی دو خروجی با هم است نه خواندن یکی: اگر مسیر A به B تمیز باشد ولی B به A روی هاپ سوم بشکند، تونل بالا می‌آید و به‌ظاهر کار می‌کند اما توان عبوری فقط در یک جهت سقوط می‌کند — و همین نامتقارنی است که عیب‌یابی را کور می‌کند.

نوسان تأخیر (jitter) و افت بسته مهم‌تر از عدد میانگین پینگ‌اند

میانگین پینگ عدد فریبنده‌ای است. اتصالی با پینگ ۹۰ میلی‌ثانیه و نوسان ناچیز، برای تونل بهتر از اتصالی با پینگ ۷۰ و نوسان ۴۰ میلی‌ثانیه است؛ چون افت بسته پنجره‌ی ازدحام TCP را کوچک می‌کند و نوسان تأخیر واریانس RTT و مهلت بازارسال را بالا می‌برد و گاهی بازارسال بی‌مورد می‌سازد. حاصل، سقوط توان عبوری (throughput) است:

ping -c 100 -i 0.2 <peer-ip> | tail -2
# rtt min/avg/max/mdev = 71.2/74.8/191.4/12.6 ms

عدد mdev همان چیزی است که کاربر به‌شکل «گاهی کند می‌شود» تجربه می‌کند؛ یک آزمایش در ساعت پیک بیشتر از ده آزمایش نیم‌شب می‌گوید. مبانی این اعداد در راهنمای کاهش پینگ آمده است.

سهمیه و نرخ ترافیک — تونل هر بایت را دو بار جابه‌جا می‌کند

سرور واسط هر بایت را دو بار جابه‌جا می‌کند: یک بار ورودی و یک بار خروجی، به‌علاوه‌ی سربار هدرها. اینکه این دو بار چگونه صورتحساب شود به سیاست شمارش اپراتور بستگی دارد؛ روش اندازه‌گیری در راهنمای پهنای باند سرور مجازی آمده است. از آنجا که سرور واسط معمولاً کوچک است و در دوره‌ی آزمودن مسیرها هم اغلب موقتی، مدل صورتحساب ساعتی برایش انتخاب طبیعی است؛ مرز اقتصادی‌اش را در راهنمای هزینه و نقطه‌ی سربه‌سر سرور ساعتی حساب کرده‌ایم.

کیفیت و سابقه‌ی آی‌پی

آی‌پی سرور واسط همان آی‌پی‌ای است که سرویس‌های بیرونی می‌بینند. پیش از تعهد بلندمدت آن را بیازمایید: با curl چند درخواست به مقصدهای واقعی خودتان بفرستید؛ کد وضعیت ۴۰۳ یا ۴۲۹ یعنی سابقه‌ی آی‌پی مشکل دارد.

curl -s -o /dev/null -w '%{http_code}\n' https://api.example.com/health

امکان بارگذاری ماژول‌های کرنل — چرا KVM لازم است

تونل‌های لایه‌ی سه با ماژول‌های کرنل کار می‌کنند: ip_gre برای GRE، ipip برای IPIP و sit برای IPv6 روی IPv4. در مجازی‌سازی کانتینری کرنل میزبان مشترک است و modprobe مجاز نیست؛ در KVM سرور شما کرنل خودش را دارد (توضیح KVM و NVMe).

sudo modprobe ip_gre && lsmod | grep -E '^ip_gre|^ip_tunnel'
ip tunnel show
# اگر خطای «Operation not permitted» گرفتید، کرنل در اختیار شما نیست

MTU مسیر و سربار هدر

هر لایه‌ی کپسوله‌سازی چند بایت به بسته اضافه می‌کند و همین چند بایت بزرگ‌ترین منبع اشکالات مرموز تونل است: روی مسیری با MTU برابر ۱۵۰۰، تونل GRE فقط ۱۴۷۶ بایت فضای مفید باقی می‌گذارد.

دیاگرام تونل GRE بین سرور ایران و سرور خارج با هدر اضافه، MTU و MSS clamping در سرور مناسب تانل

مقایسه‌ی پروتکل‌های تونل: GRE، IPIP، VXLAN و تونل رمزنگاری‌شده

برای دو سرور با آی‌پی عمومی و داده‌ی غیرحساس، GRE پیش‌فرض درست است: سربار ۲۴ بایت، پشتیبانی از IPv4 و IPv6 و پیاده‌سازی پایدار در کرنل. اگر فقط IPv4 دارید IPIP سبک‌تر است، اگر شبکه‌ی لایه‌دو می‌خواهید VXLAN، و اگر یک سر پشت NAT یا داده حساس است، تونل رمزنگاری‌شده روی UDP تنها گزینه‌ی کارآمد است.

پروتکلسربار هر بستهچه چیزی حمل می‌کندرمزنگاریعبور از NATمناسب برای
GRE (پروتکل ۴۷)۲۴ بایتIPv4، IPv6، چندپخشینداردخیربین دو آی‌پی عمومی
IPIP (پروتکل ۴)۲۰ بایتفقط IPv4 تک‌پخشینداردخیرسبک‌ترین حالت
SIT / 6in4 (پروتکل ۴۱)۲۰ بایتIPv6 روی بستر IPv4نداردخیرIPv6 روی سرور IPv4
VXLAN (UDP ۴۷۸۹)حدود ۵۰ بایتفریم لایه‌ی دونداردبلهشبکه‌ی لایه‌دو مشترک
تونل رمزنگاری‌شده (WireGuard)حدود ۶۰ بایتIPv4 و IPv6داردبلهداده‌ی حساس یا NAT
⚠️ GRE و IPIP هیچ رمزنگاری و احراز هویتی ندارند. اگر داده‌ی حساس از تونل عبور می‌کند، یا تونل رمزنگاری‌شده بگیرید یا لایه‌ی کاربردی را رمز کنید، مثلاً انتقال بکاپ روی SSH.

راه‌اندازی گام‌به‌گام تونل GRE بین دو سرور

در این مثال سرور A در ایران با 198.51.100.10 و سرور B در خارج با 203.0.113.20 است (هر دو از فضای مستندسازی). داخل تونل یک زیرشبکه‌ی /30 برمی‌داریم که دقیقاً دو آدرس دارد. پیش از شروع، اتصال SSH را طبق راهنمای اتصال امن SSH برقرار کنید.

گام اول: ساخت تونل روی هر دو سر

روی سرور ایران:

sudo modprobe ip_gre
sudo ip tunnel add gre1 mode gre local 198.51.100.10 remote 203.0.113.20 ttl 255
sudo ip addr add 10.10.10.1/30 dev gre1
sudo ip link set gre1 mtu 1476 up

روی سرور خارج، همان دستورها با جای عوض‌شده‌ی local و remote:

sudo modprobe ip_gre
sudo ip tunnel add gre1 mode gre local 203.0.113.20 remote 198.51.100.10 ttl 255
sudo ip addr add 10.10.10.2/30 dev gre1
sudo ip link set gre1 mtu 1476 up
ping -c 4 10.10.10.2
ip -br addr show gre1
# gre1  UNKNOWN  10.10.10.1/30

وضعیت UNKNOWN برای اینترفیس تونل طبیعی است؛ لایه‌ی فیزیکی‌ای برای گزارش لینک وجود ندارد.

گام دوم: باز کردن پروتکل ۴۷ در فایروال

اگر ping جواب نداد، اولین مظنون فایروال است. GRE نه TCP است و نه UDP؛ پورت ندارد و فایروال باید پروتکل شماره‌ی ۴۷ را مجاز کند:

# iptables
sudo iptables -A INPUT -p 47 -s 203.0.113.20 -j ACCEPT

# nftables — اگر هنوز جدول و زنجیره ندارید، این دو خط را هم بزنید
sudo nft add table inet filter
sudo nft 'add chain inet filter input { type filter hook input priority 0 ; policy accept ; }'
sudo nft add rule inet filter input ip protocol gre ip saddr 203.0.113.20 accept

نکته برای کاربران ufw: نحو ufw allow فقط TCP و UDP را می‌شناسد و قاعده‌ی GRE را باید دستی در /etc/ufw/before.rules نوشت. اگر فایروال firewalld است، به‌جای قاعده‌ی دستی firewall-cmd --permanent --add-protocol=gre را به کار ببرید تا پاک نشود. برای دیدن اینکه اصلاً بسته‌ای می‌رسد یا نه:

sudo tcpdump -ni eth0 proto gre

اگر بسته‌ی ورودی می‌بینید ولی پاسخی نمی‌رود، مشکل سمت شماست؛ اگر هیچ بسته‌ای نمی‌بینید، یا سر مقابل نمی‌فرستد یا فایروالی در مسیر آن را دور ریخته است (چک‌لیست امنیت سرور).

گام سوم: دائمی‌کردن تونل

هر چیزی که با ip ساخته‌اید با اولین ریبوت از بین می‌رود. روی systemd تمیزترین راه دو فایل کوچک است:

# /etc/systemd/network/10-gre1.netdev
[NetDev]
Name=gre1
Kind=gre
MTUBytes=1476

[Tunnel]
Local=198.51.100.10
Remote=203.0.113.20
TTL=255
Independent=true
# /etc/systemd/network/10-gre1.network
[Match]
Name=gre1

[Network]
Address=10.10.10.1/30
sudo systemctl enable --now systemd-networkd
networkctl status gre1

کلید Independent=true اهمیت دارد: بدون آن، تونل فقط وقتی ساخته می‌شود که یک اینترفیس فیزیکی با Tunnel= آن را بخواهد. اگر شبکه را netplan مدیریت می‌کند، تونل را در /etc/netplan/60-gre.yaml تعریف کنید:

network:
  version: 2
  tunnels:
    gre1:
      mode: gre
      local: 198.51.100.10
      remote: 203.0.113.20
      mtu: 1476
      addresses: [10.10.10.1/30]
sudo netplan try     # با بازگشت خودکار در صورت قطع اتصال
sudo netplan apply
⚠️ اگر شبکه را NetworkManager یا ifupdown مدیریت می‌کند، فعال‌کردن ناگهانی systemd-networkd می‌تواند اتصال را قطع کند؛ این کار را با کنسول VNC باز انجام دهید.

معادل‌ها روی آلمالینوکس و راکی لینوکس

نمونه‌های بالا با پیش‌فرض‌های اوبونتو و دبیان نوشته شده‌اند. در خانواده‌ی RHEL شبکه را NetworkManager مدیریت می‌کند و تونل با nmcli ساخته و دائمی می‌شود:

sudo nmcli connection add type ip-tunnel con-name gre1 ifname gre1 \
     mode gre local 198.51.100.10 remote 203.0.113.20 \
     ip-tunnel.ttl 255 ip-tunnel.mtu 1476 \
     ipv4.method manual ipv4.addresses 10.10.10.1/30
sudo nmcli connection up gre1
# فایروال: firewalld به‌جای ufw
sudo firewall-cmd --permanent --add-protocol=gre
sudo firewall-cmd --reload

# ماندگاری قواعد nftables
sudo nft list ruleset | sudo tee /etc/sysconfig/nftables.conf
sudo systemctl enable --now nftables
⚠️ روی آلمالینوکس و راکی، net.ipv4.conf.all.rp_filter پیش‌فرض ۱ (سخت‌گیر) است و با مسیریابی نامتقارنِ تونل بسته‌ها بی‌صدا دور ریخته می‌شوند؛ روی اوبونتو معمولاً ۲ است. اول مقدار فعلی را ببینید.

گام چهارم: مسیر، فورواردینگ و NAT

دو سرور همدیگر را می‌بینند ولی هنوز ترافیک دیگران را عبور نمی‌دهند:

echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-tunnel.conf
sudo sysctl --system

حالا باید تعیین کنید چه ترافیکی وارد تونل شود؛ تا وقتی مسیری به سمت gre1 نساخته‌اید هیچ بسته‌ای از تونل عبور نمی‌کند و قاعده‌های NAT و MSS هرگز فعال نمی‌شوند. کم‌ریسک‌ترین حالت، مسیر اختصاصی برای مقصدهای مهم است:

# روی سرور ایران — فقط این مقصد از تونل برود
sudo ip route add 203.0.113.10/32 via 10.10.10.2 dev gre1
ip route get 203.0.113.10
⚠️ مسیر پیش‌فرض را با ip route replace default via 10.10.10.2 عوض نکنید، مگر آنکه پیش از آن مسیر میزبانیِ آی‌پی عمومی سر مقابل را از گیت‌وی اصلی ساخته باشید؛ وگرنه بسته‌های خودِ تونل هم به داخل تونل می‌روند، مسیر حلقه می‌زند و SSH قطع می‌شود. فقط با کنسول VNC باز انجامش دهید.

اگر ترافیکِ داخل تونل باید از سر مقابل به اینترنت برود، قاعده‌ی masquerade لازم است:

# iptables
sudo iptables -t nat -A POSTROUTING -s 10.10.10.0/30 -o eth0 -j MASQUERADE

# nftables
sudo nft add table ip nat
sudo nft 'add chain ip nat postrouting { type nat hook postrouting priority 100 ; }'
sudo nft add rule ip nat postrouting ip saddr 10.10.10.0/30 oifname "eth0" masquerade

نام eth0 را با اینترفیس عمومی واقعی سرور (از ip -br link) جایگزین کنید. قواعد iptables با ریبوت پاک می‌شوند مگر ذخیره شوند: روی دبیان با iptables-persistent و روی آلمالینوکس با iptables-services.

MTU و MSS clamping — چرا ping کار می‌کند ولی HTTPS هنگ می‌کند

این شایع‌ترین و گیج‌کننده‌ترین اشکال تونل است: ping بی‌نقص جواب می‌دهد، SSH وصل می‌شود اما چند ثانیه بعد یخ می‌زند و صفحه‌ی HTTPS نیمه‌کاره می‌ماند. علت این است که بسته‌های کوچک عبور می‌کنند و بسته‌های بزرگ — حامل داده‌ی واقعی — دور ریخته می‌شوند.

سازوکارش این است: دو طرفِ اتصال TCP در ابتدا MSS خود را اعلام می‌کنند، معمولاً ۱۴۶۰ بر اساس MTU برابر ۱۵۰۰. چنین بسته‌ای در تونل GRE بیست‌وچهار بایت هدر اضافه می‌گیرد و از سقف مسیر رد می‌شود. در حالت سالم، خودِ سرور کپسوله‌کننده پیام ICMP «نیاز به تکه‌تکه‌شدن» (نوع ۳، کد ۴) را با اعلام MTU=۱۴۷۶ به فرستنده برمی‌گرداند تا بسته‌ها را کوچک کند — همان Path MTU Discovery. مقصرِ نرسیدن این پیام معمولاً فایروال خودِ فرستنده یا شبکه‌ی داخلی است که همه‌ی ICMP را می‌بندد، نه اپراتوری دوردست؛ نتیجه حفره‌ی سیاه PMTU است.

دو درمان دارد و بهتر است هر دو را انجام دهید. اول، ICMP را کامل نبندید:

sudo iptables -A INPUT -p icmp --icmp-type fragmentation-needed -j ACCEPT

دوم و مهم‌تر، هنگام عبور بسته‌های SYN مقدار MSS را به MTU واقعی مسیر مهار (clamp) کنید:

# iptables — هر دو جهتِ عبور از تونل
sudo iptables -t mangle -A FORWARD -o gre1 -p tcp --tcp-flags SYN,RST SYN \
     -j TCPMSS --clamp-mss-to-pmtu
sudo iptables -t mangle -A FORWARD -i gre1 -p tcp --tcp-flags SYN,RST SYN \
     -j TCPMSS --clamp-mss-to-pmtu

# nftables — همان دو قاعده. اجرای دوباره‌ی خط‌های add بی‌خطر است.
sudo nft add table inet filter
sudo nft 'add chain inet filter forward { type filter hook forward priority 0 ; policy accept ; }'
sudo nft add rule inet filter forward oifname "gre1" tcp flags syn tcp option maxseg size set rt mtu
sudo nft add rule inet filter forward iifname "gre1" tcp flags syn tcp option maxseg size set rt mtu

چرا دو قاعده و چرا روی هر دو سر؟ چون MSSِ اعلام‌شده در هر SYN سقف بسته‌های جهت مخالف را تعیین می‌کند؛ SYN را یک طرف مهار می‌کند و SYN-ACK را طرف دیگر. با یک قاعده، یک جهت همچنان بسته‌ی بزرگ می‌فرستد و همان «SSH وصل می‌شود ولی یخ می‌زند» می‌ماند. عدد نهایی را کرنل حساب می‌کند: ۱۴۷۶ منهای ۴۰ یعنی ۱۴۳۶.

برای یافتن سقف واقعی، بسته‌ای بدون اجازه‌ی تکه‌شدن بفرستید:

# سقف مسیر زیرین را مستقیم روی آی‌پی عمومی سر مقابل بسنجید (1472+28=1500)
ping -M do -s 1472 -c 3 203.0.113.20

# سپس عبور از خود تونل را تأیید کنید
ping -M do -s 1448 -c 3 10.10.10.2   # باید جواب بدهد
ping -M do -s 1449 -c 3 10.10.10.2
# ping: local error: Message too long, mtu=1476

پیام دوم یک خطای محلی است، نه پاسخ روتر: چون مقصد از gre1 مسیریابی می‌شود، کرنل پیش از ارسال جلوی بسته را می‌گیرد. شکست آزمایش اول یعنی MTU مسیر زیرین کمتر از ۱۵۰۰ است؛ آنگاه MTU تونل را پله‌پله کم کنید و عدد سالم را در .netdev ثبت کنید. نسخه‌ی مقاومِ کشف MTU مسیر در RFC 4821 آمده است.

وقتی فقط یک سرویس مهم است: انتقال TCP به‌جای تونل لایه‌ی سه

اگر تنها هدف شما رساندن یک سرویس مشخص به کاربر ایرانی است، تونل لایه‌ی سه بیش از نیازتان است. پراکسی TCP همان کار را با نقاط شکست کمتری انجام می‌دهد: نه ماژول کرنل می‌خواهد، نه MTU دردسر می‌شود و نه فایروال باید پروتکل غیرمعمول را باز کند. HAProxy در حالت TCP اتصال را بدون باز کردن TLS عبور می‌دهد؛ پس گواهی روی سرور واسط لازم نیست، اما TLS هم کوتاه نمی‌شود:

# /etc/haproxy/haproxy.cfg
defaults
    mode    tcp
    timeout connect 5s
    timeout client  1m
    timeout server  1m

frontend fe_https
    bind :443
    default_backend be_origin

backend be_origin
    server origin 203.0.113.10:443 check inter 5s
sudo haproxy -c -f /etc/haproxy/haproxy.cfg   # اعتبارسنجی کانفیگ
sudo systemctl reload haproxy

برای آزمایش سریع، socat کافی است:

socat TCP4-LISTEN:8443,reuseaddr,fork TCP4:203.0.113.10:443
💡 نکته: در پراکسی TCP، اوریجین همه‌ی اتصال‌ها را از آی‌پی سرور واسط می‌بیند و آی‌پی واقعی بازدیدکننده گم می‌شود. راه‌حل PROXY protocol است؛ تبعاتش در راهنمای آمار بازدید و آی‌پی واقعی کاربر آمده.

نتیجه را بسنجید: آیا تونل واقعاً کمک کرد؟

تنها راه فهمیدن اینکه تونل کمک کرده یا نه، اندازه‌گیری قبل و بعد با سه معیار است: نرخ انتقال با iperf3 در هر دو جهت، پایداری مسیر با mtr روی آدرس داخل تونل، و زمان دریافت اولین بایت با curl -w. اگر هر سه بهبود نداشتند، تونل را کنار بگذارید.

# روی سر مقابل: پورت 5201 را فقط برای آی‌پی خودتان باز کنید
sudo iptables -A INPUT -p tcp --dport 5201 -s 198.51.100.10 -j ACCEPT
iperf3 -s
# بعد از پایان تست، قاعده را با -D حذف و سرویس را متوقف کنید
iperf3 -c 10.10.10.2     -t 30    # از داخل تونل
iperf3 -c 203.0.113.20   -t 30    # مستقیم، بدون تونل
iperf3 -c 10.10.10.2     -t 30 -R # جهت معکوس (دانلود)

سوییچ -R را حتماً بزنید؛ آپلود و دانلود در بسیاری از مسیرها رفتار متفاوتی دارند. مقایسه‌ی TTFB هم وقتی معنا دارد که همان دامنه را بسنجید و تنها مسیر را عوض کنید؛ کار --resolve همین است:

# مستقیم به اوریجین
curl -o /dev/null -s -w "ttfb: %{time_starttransfer}s\n" \
     --resolve example.com:443:203.0.113.10 https://example.com/

# از مسیر سرور واسط
curl -o /dev/null -s -w "ttfb: %{time_starttransfer}s\n" \
     --resolve example.com:443:198.51.100.10 https://example.com/

هر سنجه را دست‌کم ده بار و در ساعت‌های مختلف بگیرید. انتظار واقع‌بینانه: اگر مسیر پیش‌فرض سالم است، تونل معمولاً TTFB را کمی بدتر می‌کند؛ سود واقعی جایی است که مسیر مستقیم افت بسته و نوسان زیاد دارد.

عیب‌یابی تونل سرور: نشانه، علت، راه‌حل

وقتی تونل بالا نمی‌آید یا نیمه‌کاره کار می‌کند، علت تقریباً همیشه یکی از این موارد است: بسته‌بودن پروتکل ۴۷ در فایروال، MTU بزرگ به‌همراه بلاک‌شدن ICMP، نبود مسیر به سمت اینترفیس تونل، فیلتر مسیر معکوس، خاموش‌بودن فورواردینگ یا نبود قاعده‌ی NAT، نداشتن کرنل اختصاصی، و ناپدیدشدن تونل بعد از ریبوت.

نشانهعلت محتملراه‌حل
اینترفیس up است ولی ping داخل تونل جواب نمی‌دهدپروتکل ۴۷ در فایروال بسته استبا tcpdump -ni eth0 proto gre ورودی را ببینید و قاعده‌ی -p 47 بگذارید
ping کار می‌کند ولی SSH و HTTPS هنگ می‌کنندMTU بزرگ و بلاک‌شدن ICMP نوع ۳ کد ۴MSS clamping را در هر دو جهت فعال و ICMP را باز کنید
ترافیک اصلاً وارد تونل نمی‌شود و شمارنده‌ی gre1 صفر استمسیری به سمت اینترفیس تونل تعریف نشدهبا ip route get <مقصد> ببینید خروجی dev gre1 باشد
بسته‌ها می‌رسند ولی کرنل بی‌صدا دورشان می‌ریزدفیلتر مسیر معکوس در مسیریابی نامتقارنnet.ipv4.conf.all.rp_filter=2
ترافیک وارد تونل می‌شود ولی به اینترنت نمی‌رسدip_forward خاموش یا masquerade جا افتادهفورواردینگ را روشن و قاعده‌ی NAT را اضافه کنید
خطای Operation not permitted هنگام ساخت تونلمجازی‌سازی کانتینری؛ کرنل در اختیار شما نیستسروری با مجازی‌سازی کامل KVM بگیرید
تونل بعد از ریبوت ناپدید می‌شوددستورهای ip تا ریبوت بعدی زنده‌اندبا systemd-networkd، netplan یا nmcli دائمی‌اش کنید
توان عبوری داخل تونل خیلی کمتر از مسیر مستقیم استMTU خیلی کوچک، افت بسته یا مسیر بدترMTU را تنظیم و با iperf3 در هر دو جهت دوباره بسنجید

درباره‌ی rp_filter دو نکته هست: کرنل مقدار مؤثر را از بیشترین مقدار بین کلید all و کلید همان اینترفیس می‌گیرد، و تنظیم موقت با ریبوت پاک می‌شود. کلید default را هم بگذارید تا اینترفیس‌های بعد از بوت مقدار درست را ارث ببرند:

# موقت، برای آزمایش
sudo sysctl -w net.ipv4.conf.all.rp_filter=2
sudo sysctl -w net.ipv4.conf.gre1.rp_filter=2

# دائمی — همان فایلی که ip_forward را در آن گذاشتید
# /etc/sysctl.d/99-tunnel.conf
net.ipv4.ip_forward=1
net.ipv4.conf.all.rp_filter=2
net.ipv4.conf.default.rp_filter=2

sudo sysctl --system

و اگر تونل بالاست ولی سرویس وب پشت آن خطای درگاه می‌دهد، راهنمای رفع خطای 502 Bad Gateway را ببینید؛ گاهی مقصر اوریجین است.

چک‌لیست انتخاب و راه‌اندازی سرور مناسب تانل

این هشت قدم را به‌ترتیب بروید تا سرور مناسب تانل را بدون عیب‌یابی کور به نتیجه برسانید:

  1. هدف را دقیق بنویسید. یک سرویس یا کل شبکه؟ در حالت اول پراکسی TCP کافی است.
  2. مسیر را قبل از خرید بسنجیدmtr و ping در هر دو جهت و در ساعت پیک.
  3. مجازی‌سازی را چک کنید. باید KVM باشد تا modprobe ip_gre کار کند.
  4. ترافیک را با ضریب دو حساب کنید و سیاست شمارش اپراتور را بپرسید.
  5. پروتکل را از جدول انتخاب کنید. دو آی‌پی عمومی؟ GRE. یکی پشت NAT؟ تونل UDP.
  6. مسیر، MTU و MSS را روز اول تنظیم کنید، نه بعد از شکایت کاربران.
  7. تونل را دائمی و قابل مانیتور کنید — با systemd-networkd یا nmcli.
  8. قبل و بعد را مستند کنید. اگر اعداد بهبود ندادند، کنارش بگذارید.

سؤالات پرتکرار

سرور مناسب تانل چه مشخصاتی باید داشته باشد؟

مسیر شبکه‌ی تمیز، سهمیه‌ی ترافیک کافی و مجازی‌سازی KVM — نه پردازنده‌ی قوی. کپسوله‌سازی GRE و IPIP در کرنل انجام می‌شود و برای نرخ‌های معمول، یک تا دو هسته و ۱ گیگابایت رم کاملاً کافی است. تنها حالتی که پردازنده اهمیت پیدا می‌کند، تونل رمزنگاری‌شده در نرخ‌های خیلی بالا یا خاتمه‌دادن TLS روی سرور واسط است.

چرا تونل GRE روی سرور من ساخته نمی‌شود؟

تقریباً همیشه به این دلیل که سرور روی مجازی‌سازی کانتینری (OpenVZ یا LXC) اجرا می‌شود و کرنل مستقل ندارد؛ در این حالت modprobe ip_gre با خطای «Operation not permitted» شکست می‌خورد. راه‌حل، سروری با مجازی‌سازی کامل KVM است. اگر KVM دارید و باز هم خطا می‌گیرید، احتمالاً ماژول کامپایل نشده که با modinfo ip_gre قابل بررسی است.

چرا بعد از راه‌اندازی تونل، ping کار می‌کند ولی سایت باز نمی‌شود؟

چون بسته‌های کوچک عبور می‌کنند و بسته‌های بزرگ نه. هدر GRE بیست‌وچهار بایت به هر بسته اضافه می‌کند و بسته‌های پر از سقف MTU مسیر رد می‌شوند؛ اگر ICMP نوع ۳ کد ۴ هم در مسیر بسته باشد، فرستنده هرگز خبردار نمی‌شود و اتصال بی‌صدا هنگ می‌کند. درمانش MSS clamping روی بسته‌های SYN در هر دو جهت و باز گذاشتن ICMP است.

ترافیک تونل چطور محاسبه می‌شود؟

سرور واسط هر بایت را دو بار جابه‌جا می‌کند: یک بار ورودی و یک بار خروجی. اینکه این دو بار چگونه صورتحساب شود به سیاست شمارش اپراتور بستگی دارد؛ اگر هر دو جهت شمرده شوند، ۱۰۰ گیگابایت ترافیک کاربر حدود ۲۰۰ گیگابایت ثبت می‌شود و اگر فقط خروجی شمرده شود حدود ۱۰۰ گیگابایت. مصرف واقعی را با vnstat روی اینترفیس عمومی و تونل جداگانه بسنجید.

قدم بعدی

خلاصه: اول بسنجید، بعد بسازید. مسیر را با mtr در هر دو جهت ببینید، تونل GRE را بالا بیاورید، مسیر و MSS را تنظیم کنید و با iperf3 نتیجه را ثابت کنید. برای یافتن سرور مناسب تانل هم بهترین کار آزمودن چند مسیر پیش از تعهد بلندمدت است: یک سرور ابری ساعتی در مهران هاست بسازید — روی KVM و NVMe در دیتاسنتر ایران با تحویل خودکار معمولاً زیر ۶۰ ثانیه — چند ساعت تست کنید و اگر جواب نداد حذفش کنید تا صورتحساب هم متوقف شود. برآورد هزینه در محاسبه‌گر صفحه‌ی اصلی است و برای پروژه‌های چندسروره راهکارهای سازمانی را ببینید.

آموزش‌های مرتبط

آماده‌ی تمرین عملی هستید؟

سرور ابری ساعتی مهران هاست در ۶۰ ثانیه تحویل می‌شود — تمرین کنید و فقط بابت همان ساعت‌ها پرداخت کنید. هزینه را پیش از ثبت‌نام با محاسبه‌گر برآورد کنید.