انتخاب اینکه چه چیزی از تونل عبور کند
دستورهای اختیاری RouterOS برای روتر ForestVPN — عبوردادن یک گروه از اپلیکیشنها، عبوردادن همهچیز، و جلوگیری از نشتِ ترافیک وقتی تونل قطع است.
بهروزرسانی: ۱۶ مهر ۱۴۰۵
همهچیز در این صفحه اختیاری است. روتر ForestVPN بهمحض اتصال، ترافیک خودش را تونل میکند، و هیچکدام از اینها برای آن لازم نیست. این صفحه کار دیگری را پوشش میدهد: تصمیمگیری دربارهٔ اینکه کدام بخش از ترافیک LAN شما از سرور خروجی عبور کند، و وقتی سرور خروجی در دسترس نباشد چه اتفاقی میافتد.
تقسیمکار هرگز تغییر نمیکند. RouterOS تصمیم میگیرد چه چیزی به تونل برود، کانتینر هرچه به آن سپرده شود را تونل میکند، و حساب شما تصمیم میگیرد از کجا بیرون بیاید. پس همهٔ اینها یک پیکربندی معمولی RouterOS است — نشانههای mangle، یک جدول مسیریابی، یک قانون فایروال — و هیچکدام به کانتینر دست نمیزند.
اول این را بخوانید
سه واقعیت تعیین میکنند که آیا هیچکدام از اینها اصلاً کار میکند یا نه. ردشدن از آنها شبی است که پس نمیگیرید.
اینها را روی جعبهای بچسبانید که LAN شما را مسیریابی میکند. زنجیرهٔ prerouting در RouterOS
فقط ترافیکی را میبیند که خودِ آن جعبه مسیریابی میکند. روی یک اکسسپوینت که پاییندستِ دروازهٔ
واقعی شما نشسته، هر قانونی که در ادامه میآید بیاثر است — این روی یک cAP ax اندازهگیری شده که مسیر
پیشفرض خودش همان روتر بالادستِ آن است: کانتینر بینقص تونل زد و ترافیک هیچ کلاینت LAN هرگز نزدیک آن
نرفت. کانتینر میتواند روی همان اکسسپوینت زندگی کند؛ قانونها روی دروازه میروند.
سرور خروجی برای هر دستگاه فقط یک آدرس مبدأ میپذیرد — همان اجارهٔ (lease) overlay که خودش صادر کرده. بستهای که با هر مبدأ داخلی دیگری برسد، هرچقدر هم قانونهای شما درست باشند، دراپ میشود، نه مسیریابی. چیزی باید LAN شما را روی آن lease بازنویسی کند، و اینکه کدام چیز، به کانتینر بستگی دارد:
| کانتینر | کاری که باید انجام دهید |
|---|---|
suquant/fvpn — همان اپلیکیشن مدیریتشده با حساب | هیچکاری. از نسخهٔ 0.3.9، کانتینر هرچه به آن forward کنید را روی lease خودش masquerade میکند، و وقتی آن lease جابهجا شود دنبالش میرود. دستور نصب این را فعال میکند. |
suquant/fvpnq — تونل خام، از یک .conf که خودتان نوشتهاید | یک src-nat به Address در .conf خودتان اضافه کنید، که همان چیزی است که در AllowedIPs سرور خروجی هم گذاشتهاید. خودتان آن را انتخاب کردهاید، پس ثابت است و یک قانون میتواند آن را نام ببرد. |
کانتینری قدیمیتر از 0.3.9 اجرا میکنید؟ دستور نصب را دوباره اجرا کنید — در غیر اینصورت قانونهای زیر بینقص مارک و مسیریابی میکنند اما سرور خروجی هر بسته را دراپ میکند، که همان لحظهای که قانون مسیریابی را اضافه میکنید، مثل قطع کامل اینترنت LAN بهنظر میرسد.
Fasttrack از mangle عبور میکند. فایروال کارخانهای MikroTik اتصالهای برقرارشده را fasttrack
میکند، و یک اتصال fasttrackشده دیگر هرگز به زنجیرهٔ mangle نمیرسد — پس نشانههای شما فقط روی
نخستین بستهٔ یک جریان اعمال میشود و روی هیچچیز بعد از آن. هر دستوری که در ادامه میآید یک قانون
دارد که اتصالهای نشانهگذاریشده را از fasttrack بیرون نگه میدارد، و باید بالای قانون
fasttrack-connection بنشیند.
و نیمهٔ IPv6، که این قانونها نمیتوانند برایتان انجام دهند
هرچه اینجا آمده IPv4 است. اگر روتر شما IPv6 کارآمد دارد، هر مقصدی که در ادامه انتخاب میکنید
همزمان از طریق v6 هم، دورِ تونل، در دسترس است، و چیزی به شما هشدار نمیدهد. اگر برعکس، روتر خودش
را بهعنوان یک روتر IPv6 معرفی کند بدون آنکه مسیر پیشفرض v6 داشته باشد، کلاینتهای LAN ترافیک v6 را
به آن میفرستند و هیچ پاسخی نمیگیرند — حتی یک خطا هم نه، چون RouterOS 7 هیچ مسیر «غیرقابلدسترس»
برای v6 ندارد، فقط یک blackhole بیصدا. دستگاههای بدون Happy Eyeballs — تلویزیونها، ساعتها،
هرچیزی که یک اتصال ساده روی رکورد AAAA برقرار میکند — سپس برای یک مهلت کامل اتصال روی هر مقصد v6
معطل میمانند، که مثل «اینترنت گاهی خراب است» بهنظر میرسد و تقصیر را گردن Wi-Fi میاندازد. این یک
خط میگوید کدامیک از این دو حالتاید:
# Does this router tell LAN clients it is their IPv6 router?
/ipv6/nd/print where ra-lifetime!=none
# Does it have somewhere to send their v6 traffic?
/ipv6/route/print where dst-address="::/0" and routing-table="main"پاسخ به اولی و هیچ پاسخی به دومی، همان حالت دوم است. یا به IPv6 یک مسیر پیشفرض واقعی بدهید، یا با
/ipv6/nd/set [find] ra-lifetime=none تبلیغ آن را متوقف کنید.
گام 1 — داربست اولیه
برای هر سه دستور یکسان است. آدرس کانتینر خودتان را بهجای 172.31.254.2 (پیشفرض از
نصب؛ /interface/veth/print آن را نشان میدهد) بگذارید، و پیشوند LAN
خودتان را بهجای 192.168.88.0/24.
اول /container/print detail را بررسی کنید. remote-image باید 0.3.9 یا جدیدتر را نشان
دهد، و cmd باید --nat-lan را در خود داشته باشد. هر دو از دستور
نصب فعلی میآیند؛ کانتینری که پیش از آن نصب شده هیچکدام را ندارد، و نشانهٔ
آن، قطع کامل اینترنت LAN درست در لحظهای است که قانون مسیریابی را در گام 2 اضافه میکنید.
# A routing table of its own, so nothing here can disturb your normal
# default route.
/routing/table add name=via-fvpn fib
# Where marked traffic goes: the container, on the address RouterOS itself
# gave it.
/ip/route add dst-address=0.0.0.0/0 gateway=172.31.254.2 \
routing-table=via-fvpn comment="fvpn: traffic leaves via the container"
# Collapse the LAN to one source address on the way IN to the container. The
# exit never sees this one either -- the container masquerades again onto its
# own lease -- so this is about keeping your LAN's layout out of the
# container's connection table, not about being admitted.
/ip/firewall/nat add chain=srcnat out-interface=veth-fvpn action=masquerade \
comment="fvpn: hide LAN addressing from the container"
# The tunnel costs 80 bytes of MTU. Without this, large TCP flows stall
# rather than fail, which presents as "the internet is broken on Tuesdays".
/ip/firewall/mangle add chain=forward action=change-mss new-mss=clamp-to-pmtu \
protocol=tcp tcp-flags=syn connection-mark=via-fvpn \
comment="fvpn: clamp MSS on tunnelled TCP"
# Fasttrack bypasses mangle, so marked connections have to be accepted
# before they reach it. This rule is inert if it ends up below the fasttrack
# rule -- check with /ip/firewall/filter/print that it did not.
/ip/firewall/filter add chain=forward action=accept connection-mark=via-fvpn \
place-before=[find action=fasttrack-connection] \
comment="fvpn: marked flows skip fasttrack"سپس یکی از دو گزینهٔ بعدی را انتخاب کنید. هر دو همان نشانهٔ اتصال via-fvpn را تولید میکنند،
پس اگر هر دو را جایگذاری کنید، بر سر همان ترافیک با هم رقابت میکنند.
گام 2a — اختیاری: فقط تماسها و پیامرسانها
این پیکربندی است که ماههاست روی RB3011 خودمان اجرا میشود. مسئله را دقیقاً به همان شکلی تقسیم میکند که ترافیک واقعاً تقسیم میشود: سیگنالینگ چند نام میزبان از فروشندههاست، رسانه بازهای از پورتها روی رلههایی است که هیچکس آدرسشان را منتشر نمیکند.
# Signalling, by hostname. A hostname in a RouterOS address list is not a
# static entry -- the router resolves it and keeps the answers fresh, which
# is the only form that survives a CDN moving under you.
/ip/firewall/address-list
add list=fvpn-via address=g.whatsapp.net comment="fvpn: signalling"
add list=fvpn-via address=media.whatsapp.net comment="fvpn: signalling"
add list=fvpn-via address=mmg.whatsapp.net comment="fvpn: signalling"
add list=fvpn-via address=static.whatsapp.net comment="fvpn: signalling"
add list=fvpn-via address=web.whatsapp.com comment="fvpn: signalling"
add list=fvpn-via address=api.telegram.org comment="fvpn: signalling"
add list=fvpn-via address=core.telegram.org comment="fvpn: signalling"
add list=fvpn-via address=web.telegram.org comment="fvpn: signalling"
add list=fvpn-via address=chat.signal.org comment="fvpn: signalling"
add list=fvpn-via address=storage.signal.org comment="fvpn: signalling"
/ip/firewall/mangle
add chain=prerouting action=mark-connection new-connection-mark=via-fvpn \
dst-address-list=fvpn-via \
comment="fvpn: signalling by resolved vendor hostname"
# Media, by port -- the half an address list can never cover, because a call
# lands on whichever TURN relay the vendor picked that minute.
add chain=prerouting action=mark-connection new-connection-mark=via-fvpn \
protocol=udp dst-port=3478-3481 \
comment="fvpn: STUN/TURN media - calls in every major app"
add chain=prerouting action=mark-connection new-connection-mark=via-fvpn \
protocol=tcp dst-port=3478-3481,5349,5350 \
comment="fvpn: STUN/TURN over TCP and TLS"
add chain=prerouting action=mark-connection new-connection-mark=via-fvpn \
protocol=udp dst-port=5060,5061 comment="fvpn: SIP"
add chain=prerouting action=mark-connection new-connection-mark=via-fvpn \
protocol=tcp dst-port=5060,5061 comment="fvpn: SIP over TCP/TLS"
add chain=prerouting action=mark-connection new-connection-mark=via-fvpn \
protocol=tcp dst-port=5222,5223 comment="fvpn: XMPP signalling"
# One routing decision for the whole connection. Marking the connection
# first and the route second -- rather than marking the route directly -- is
# what keeps a call that started on the tunnel on the tunnel.
add chain=prerouting action=mark-routing new-routing-mark=via-fvpn \
passthrough=no src-address=192.168.88.0/24 connection-mark=via-fvpn \
comment="fvpn: route marked connections via the exit"این نامهای میزبان یک نقطهٔ شروعاند، نه یک مرجع. فروشندهها بدون اطلاع به کسی آنها را اضافه یا
کنار میگذارند. /ip/firewall/mangle/print stats را برای شمارندههایی که روی صفر ماندهاند بررسی
کنید — آن یعنی قانونی که با هیچچیز مطابقت نمییابد، نه قانونی که بیصدا کارش را انجام میدهد.
گام 2b — اختیاری: همهچیز
/ip/firewall/mangle
# The container's own packets must never be marked, or its tunnel gets
# routed into itself. The install puts the container's interface in the LAN
# list, so the rule below WOULD match it. Substitute the container's
# address.
add chain=prerouting action=accept src-address=172.31.254.2 \
comment="fvpn: never mark the container's own traffic"
# Everything from the LAN that is not addressed to this router.
# `dst-address-type=!local` is what keeps DNS, WebFig and the status page
# off the tunnel; `in-interface-list=LAN` rather than a source prefix keeps
# the rule correct when the LAN is renumbered.
add chain=prerouting action=mark-connection new-connection-mark=via-fvpn \
in-interface-list=LAN dst-address-type=!local \
comment="fvpn: everything from the LAN"
# `dst-address-type=!local` on this rule too, and it is not decoration. The
# install puts the container's veth in the LAN list, so replies coming back
# OUT of the container also match `in-interface-list=LAN`, and they still
# carry the connection mark. Mangle prerouting runs before dstnat, so at
# this moment their destination is still the router's own srcnat address --
# local. Without the test they would take the routing mark and be sent back
# into the container instead of on to the client that asked.
add chain=prerouting action=mark-routing new-routing-mark=via-fvpn \
passthrough=no in-interface-list=LAN dst-address-type=!local \
connection-mark=via-fvpn \
comment="fvpn: route marked connections via the exit"پیش از آزمایش، بشمارید چه چیزی جایگذاری کردهاید. /ip/firewall/mangle/print باید هر سهتای
این قانونها را نشان دهد. جایگذاریای در ترمینال که یکی از ادامهخطها را از دست بدهد، شما را با
قانونهای نشانهگذاری و بدون قانون مسیریابی رها میکند، که دقیقاً شبیه «تونل نادیده گرفته میشود»
بهنظر میرسد — اتصالها نشانهٔ connection-mark=via-fvpn را حمل میکنند، اما هیچچیز هرگز به آن
جدول مراجعه نمیکند، و هر بسته از اتصال معمولی شما بیرون میرود.
اگر همهچیز را بفرستید، DNS را هم میفرستید — که خودِ هدف همین است، اما یعنی تحلیلگر DNS سرور خروجی
به LAN شما پاسخ میدهد. پیش از آنکه تصمیم بگیرید این همان حالتی است که میخواهید، بررسی کنید هرچه به
نامهای محلی وابسته است (یک پرینتر، یک NAS، router.lan) هنوز هم درست حل میشود.
گام 3 — اختیاری: قابلیتی برای قطع خودکار ترافیک
مسیریابی گزینشی یک حالت خطا دارد که ارزش بستن دارد: وقتی تونل متوقف شود، ترافیک نشانهگذاریشده میتواند بیصدا دوباره از اتصال معمولی شما خارج شود. این سه قانون بهجای آن، آن را متوقف میکنند. آنها را بعد از هر دستوری که انتخاب کردید اضافه کنید.
هر دستور در این بخش پیش از نوشتهشدن روی RouterOS 7.24.1 اجرا شده است. نحو آن در یکجا با RouterOS 6 فرق دارد، که در ادامه مشخص شده.
# 1. The route to the container counts only while the container answers.
/ip/route/set [find routing-table=via-fvpn dst-address=0.0.0.0/0] \
check-gateway=ping
# 2. When it stops counting, drop rather than fall back. The higher distance
# keeps this route inactive for as long as the real one is up. `blackhole`
# is a bare flag here, not `type=blackhole` -- RouterOS 7 has no `type`
# property on a route at all, and rejects it with "bad parameter type".
/ip/route/add dst-address=0.0.0.0/0 blackhole distance=10 \
routing-table=via-fvpn comment="fvpn: kill switch - no exit, no traffic"
# 3. The leak the first two cannot see: a container that is alive and
# answering ping while its own tunnel is down forwards to its default
# gateway, which is you. Traffic wearing the address the srcnat above gave
# it must never reach the internet directly. Substitute your router's own
# address on the container's /30 if you changed it.
/ip/firewall/filter/add chain=forward action=drop src-address=172.31.254.1 \
out-interface-list=WAN \
place-before=[find comment="fvpn: marked flows skip fasttrack"] \
comment="fvpn: kill switch - overlay source must not leave over WAN"قانون 3 باید بالای قانون معافیت fasttrack از گام 1 بنشیند، وگرنه آن قانون اول ترافیک را میپذیرد
و هرگز به drop نمیرسد. اینجا place-before این کار را انجام میدهد؛ با
/ip/firewall/filter/print تأیید کنید.
نسخهٔ سختگیرانهتر: دستگاههایی که فقط باید از تونل استفاده کنند
اگر آنچه واقعاً میخواهید این است که «این لپتاپ هیچ اینترنتی ندارد مگر آنکه تونل شده باشد»، این را مستقیم بگویید، نه اینکه آن را از وضعیت مسیریابی استنتاج کنید:
/ip/firewall/address-list/add list=fvpn-only address=192.168.88.50 \
comment="fvpn: the work laptop"
/ip/firewall/filter/add chain=forward action=drop src-address-list=fvpn-only \
out-interface-list=WAN \
place-before=[find comment="fvpn: marked flows skip fasttrack"] \
comment="fvpn: kill switch - these devices are tunnel-only"از این پس آن دستگاه یا از طریق کانتینر به اینترنت میرسد یا اصلاً نمیرسد، هرچه جدولهای مسیریابی هر روز صبح بگویند.
بررسی اینکه کار کرد
# A rule sitting at zero packets is a rule matching nothing.
/ip/firewall/mangle/print stats
/ip/route/print where routing-table=via-fvpn
# The fasttrack-exemption rule has to be above the fasttrack rule.
/ip/firewall/filter/printاز یک دستگاه روی LAN، هر صفحهٔ «آیپی من چیست» را باز کنید. باید کشور سرور خروجی را برای ترافیکی که انتخاب کردهاید نشان دهد و کشور خودتان را برای بقیه. اگر کشور خودتان را برای همهچیز نشان میدهد، معمولترین دلیل همان نخستین واقعیت این صفحه است: قانونها روی جعبهای هستند که LAN را مسیریابی نمیکند.
برگرداندن آن
هر خط بالا با کامنتی شروع میشود که با fvpn: آغاز میشود، پس حذفکردن آنها دقیق است — و به اشیاء
خودِ کانتینر که نصبکننده آنها را forestvpn کامنتگذاری میکند دست نمیزند.
/ip/firewall/mangle/remove [find comment~"^fvpn:"]
/ip/firewall/filter/remove [find comment~"^fvpn:"]
/ip/firewall/nat/remove [find comment~"^fvpn:"]
/ip/firewall/address-list/remove [find comment~"^fvpn:"]
/ip/route/remove [find comment~"^fvpn:"]
/ip/address/remove [find comment~"^fvpn:"]
/routing/table/remove [find name="via-fvpn"]کانتینر همچنان اجرا میماند، پیوند حساب خود را حفظ میکند، و به تونلکردنِ فقط ترافیک خودش برمیگردد. اگر چیز دیگری اشتباه است، به عیبیابی مراجعه کنید.