تونل شما بالاست، سرویس گوش می‌دهد، و LAN دفتر هنوز هیچ چیز برنمی‌گرداند. هیچ‌کس VPN را نشکسته است. از سمت LAN، نشانی تونل لپ‌تاپ وجود ندارد تا وقتی چیزی به LAN بگوید چگونه به آن برسد، و پاسخ باید از همان راهی برگردد که درخواست بیرون رفت. دیده‌ام که مردم سه بار یک تونل کاملاً سالم را از نو ساخته‌اند پیش از آنکه کسی به مسیر بازگشت نگاه کند.

چیزی که شکسته، تونل نیست

دو سر در محدوده‌های خصوصی هستند، که حالت عادی است و پیکربندی غلط نیست. نشانی‌ای مثل 10.8.0.6 درون تونل واقعی است و جای دیگری وجود ندارد، پس LAN دلیلی برای فرستادن چیزی به آن ندارد. پیش از دست زدن به مسیریابی، تأیید کنید که سرویس اصلاً درون تونل در دسترس است: روی کارخواه، ss -ltn نشان می‌دهد که شنونده به 127.0.0.1، به واسط LAN یا به نشانی تونل گره خورده است. سرویسی که فقط به loopback گره خورده باشد به هیچ‌کس جز خودش پاسخ نمی‌دهد، و هیچ مسیر، DNAT یا هدایت درگاهی آن را عوض نمی‌کند.

پروکسی روی درگاه 80 یا 443 ابزار دیگری با دید دیگری است. این درخواست‌ها را جابه‌جا می‌کند، نه بسته‌ها را، پس لایه اشتباهی برای اتصال خام به پایگاه داده است، و دست بردن به آن همان راهی است که این مشکل پیش از آنکه کسی چیزی را اندازه بگیرد، سه ابزار عمیق می‌شود.

شکل مسیر: به LAN بگویید استخر کجاست

یک مسیر ایستا روی دروازه LAN پاکیزه‌ترین پاسخ است وقتی LAN و استخر تونل همپوشانی ندارند. استخر را به ماشینی اشاره دهید که تونل را پایان می‌دهد:

ip route add 10.8.0.0/24 via 192.168.1.12
route add -p 10.8.0.0 mask 255.255.255.0 192.168.1.12   # Windows, persistent

این فقط یک جهت را درست می‌کند، و برای همین نسخه‌های نیمه‌کارهٔ این تغییر شبیه پیشرفت به نظر می‌رسند. سمت تونل به نیمهٔ متناظر نیاز دارد، وگرنه پاسخ کارخواه را از مسیر پیش‌فرض خودش ترک می‌کند و در راه می‌میرد:

push "route 192.168.1.0 255.255.255.0"

برای زیرشبکه‌ای که پشت یک کارخواه است نه پشت سرور، سرور هم به یک مسیر سیستمی نیاز دارد و هم به یک ورودی iroute در پروندهٔ آن کارخواه زیر client-config-dir. بدون iroute، OpenVPN می‌داند که پیشوند وجود دارد و هیچ ایده‌ای ندارد کدام کارخواه مالک آن است: بسته‌ها می‌رسند و دیمن چیزی برای تطبیق دادن آن‌ها ندارد.

این همان افسانه‌ای است که ارزش نام بردن دارد. مسیر یک نشانی را در دسترس‌پذیر می‌کند؛ اما طرف مقابل را راغب به پاسخ نمی‌کند. همتایان سایت‌به‌سایت لایهٔ دیگری روی آن می‌افزایند، چون دروازهٔ دور فقط مبدأهایی را می‌پذیرد که درون پیشوندهای سیاستش باشند، و لپ‌تاپی که از استخر خانگی می‌آید درون آن‌ها نیست.

شکل NAT: DNAT به درون، و خط SNAT که همه از آن می‌گذرند

وقتی نمی‌توانید به دروازهٔ LAN دست بزنید، یا می‌خواهید دقیقاً یک درگاه را منتشر کنید، ترجمه روی میزبان VPN بدون هیچ مسیری روی LAN کار می‌کند. درگاه را منتشر کنید، هدایتش کنید، و مبدأ را در راه ورود به تونل ترجمه کنید:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 10.8.0.6:3000
iptables -A FORWARD -i eth0 -o tun0 -p tcp -d 10.8.0.6 --dport 3000 -j ACCEPT
iptables -t nat -A POSTROUTING -o tun0 -d 10.8.0.6 -p tcp --dport 3000 -j SNAT --to-source 10.8.0.1

خط سوم همان خطی است که گم می‌شود. از آن بگذرید و کارخواه نشانی اصلی LAN را به عنوان مبدأ می‌بیند، از مسیر پیش‌فرض خودش پاسخ می‌دهد، و آن پاسخ به جای بازگشت به سوی LAN به تونل می‌رود. اینکه اتصال زنده بماند یا نه، آن‌گاه به مسیریابی‌ای بستگی دارد که هرگز برنامه‌ریزی نکرده بودید. با SNAT کارخواه نشانی تونل سرور را می‌بیند، پس پاسخ تونل را تا تنها میزبانی دنبال می‌کند که می‌تواند ترجمه را برگرداند.

فرم‌افزار مصرفی از نام‌های زنجیرهٔ خودش استفاده می‌کند و آن ترجمه را برای شما تولید نمی‌کند. در Tomato، یک قاعدهٔ ورودی در WANPREROUTING فرود می‌آید و سپس در زنجیرهٔ فیلتری مثل wanin، و مجموعه قواعدی که کامل به نظر می‌رسد هنوز به یک خط POSTROUTING دستی نیاز دارد. این باگ فرم‌افزار نیست؛ این مجموعه قواعدی است که فقط برای ترافیک ورودی نوشته شده است.

چرا قاعده‌ای که درست به نظر می‌رسد باز هم بسته را می‌اندازد

بیشتر این شکست‌ها در قاعده‌ای نیست که به آن خیره شده‌اید. چهار چیز را به این ترتیب بررسی کنید و در اولین چیزی که برقرار نیست بایستید:

  • ترتیب زنجیره‌ها. iptables -I در بالا درج می‌کند و -A در پایان می‌افزاید، پس قاعدهٔ مجاز یا مسدودکنندهٔ پیشین اول تصمیم می‌گیرد.
  • زنجیرهٔ اشتباه. ترافیکی که به خود روتر نشانه رفته از INPUT می‌گذرد، و ترافیک هدایت‌شده هرگز آن را لمس نمی‌کند. انتشار یک سرویس می‌تواند در هر دو قاعده بخواهد.
  • پرچم‌های جهت. -i tun0 با ترافیکی که از کارخواه‌ها می‌آید تطبیق می‌یابد و -o tun0 با ترافیکی که به سوی آن‌ها می‌رود. یک REJECT با پرچم اشتباه چیزی را مسدود می‌کند که قصدش را نداشتید.
  • محدودیت مبدأ. هدایتی که یک نشانی کارخواه را می‌پذیرد از همان کارخواه کار می‌کند و هر مبدأ دیگر را بی‌یک کلمه می‌اندازد.

قاعده‌ای با شمارندهٔ بستهٔ صفر اصلاً در مسیر نیست، و خواندن شمارنده‌ها سریع‌ترین راه جدا کردن مشکل زنجیرهٔ اشتباه از مشکل قاعدهٔ اشتباه است.

هدایت محلی، وقتی روی LAN هیچ چیز قابل تغییر نیست

هدایت محلی SSH از کل پرسش می‌گریزد. نه به مسیری روی LAN نیاز دارد، نه به همکاری دیوار آتش کارخواه، و نه به درگاهی که جایی منتشر شده باشد:

ssh -N -f -L 3000:10.8.0.6:3000 user@vpn-host

سرویس آن‌گاه روی localhost:3000 ماشینی که تونل را نگه می‌دارد ظاهر می‌شود، و جای دیگری نه. این همان مرز است: یک ایستگاه کاری، یک درگاه، و هدایت با نشست می‌میرد مگر اینکه چیزی دوباره راهش بیندازد. برای مدیری که یک پایگاه دادهٔ آزمایشی را بررسی می‌کند ابزار درستی است. برای دوربین یا پویشگری که آدم‌های دیگر باید به آن برسند، نیست، چون هر کاربر به هدایت خودش نیاز می‌داشت.

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

ترجمه ردپا می‌گذارد و خواندنشان از حدس زدن بهتر است. روی میزبان VPN، conntrack -L نشان می‌دهد که ترجمه اصلاً رخ داد یا نه، iptables -t nat -L -n -v نشان می‌دهد که شمارنده‌ها حرکت کردند یا نه، و tcpdump -ni any port 3000 نشان می‌دهد کدام نشانی مبدأ واقعاً رسید. روی کارخواه، ss -ltn تأیید می‌کند که شنونده روی نشانی‌ای است که تونل می‌تواند به آن برسد.

سپس شکلی را که نگه می‌دارید انتخاب کنید. یک درگاه منتشرشده، یک مسیر برای کل استخر، و یک هدایت برای یک مدیر تنها سه تعهد متفاوت‌اند، و درهم آمیختنشان همان راهی است که یک پیکربندی کارآمد شش ماه بعد به چیزی تبدیل می‌شود که هیچ‌کس نمی‌تواند توضیحش دهد. بنویسید کدام نشانی از کجا در دسترس است، و نفر بعدی که این را عیب‌یابی می‌کند از پاسخ شروع می‌کند نه از تونل.

مقالات مرتبط