آموزش نحوه عملکرد WireGuard و cryptokey routing
پارامتر AllowedIPs در فایل wg0.conf همزمان نقش جدول مسیریابی و لیست دسترسی را دارد. با یادگیری مکانیزم cryptokey routing و پروتکل Noise، پیکربندی WireGuard را درک کنید.
نحوه عملکرد WireGuard در یک نگاه
WireGuard با متصل کردن هر بسته (packet) به یک کلید عمومی کار میکند. این مکانیزم «مسیریابی کلید-رمزنگاری» (cryptokey routing) نام دارد و کل طراحی آن را تشکیل میدهد: خط AllowedIPs در کنار یک همتا (peer)، در واقع جدول مسیریابی برای بستههای خروجی از ماشین شما و لیست کنترل دسترسی (ACL) برای بستههای ورودی از آن همتا است. یک تنظیم، دو وظیفه. فایل AllowedIPs را با این دید بخوانید تا هر فایل پیکربندی WireGuard برایتان قابلفهم شود.
در اینجا هیچ جدول نشست (session table) مبتنی بر آدرس IP یا پایگاهداده کاربر وجود ندارد. یک همتا، ترکیبی از یک کلید عمومی و مجموعهای از آدرسهایی است که آن کلید مجاز به استفاده از آنهاست. فرآیند دستدادن (handshake) و تایمرها برای حفظ صحت این اتصال در حین تغییرات شبکه زیرساختی وجود دارند. اگر پیش از درک تئوری، به دنبال یک تونل عملیاتی هستید، آن را با یک VPN شخصی WireGuard روی VPS خود بسازید و سپس هر زمان که یک خط از پیکربندی برایتان مبهم بود، به اینجا بازگردید.
پارامتر AllowedIPs هم یک جدول مسیریابی است و هم یک لیست دسترسی
ابتدا جهت خروجی (outbound) را در نظر بگیرید. هسته سیستمعامل شما بسته را طبق روال معمول و از طریق جدول مسیریابی اصلی به دستگاه wg0 هدایت میکند. سپس WireGuard آدرس مقصد آن بسته را با جدولی که شامل پیشوندهای مجاز (allowed prefixes) هر همتا (peer) است مطابقت میدهد؛ این تطبیق بر اساس طولانیترین پیشوند (longest prefix match) انجام میشود. در صورت یافتن تطابق، یک همتا مشخص میشود که به یک کلید عمومی، و در نهایت به یک کلید نشست (session key) و یک نقطه پایانی UDP اشاره دارد. بسته برای آن همتا رمزنگاری شده و به مقصد ارسال میشود.
اگر هیچکدام از AllowedIPs همتاها مقصد بسته را پوشش ندهند، بستهای ارسال نمیشود؛ زیرا کلیدی برای رمزنگاری آن وجود ندارد.
ping: sendmsg: Required key not availableاین خطا تنها یک معنی دارد: آدرس مورد نظر شما در لیست هیچ همتایی تعریف نشده است. خطای متفاوت ping: sendmsg: Destination address required به این معناست که تطابق با یک همتا انجام شده، اما WireGuard هیچ نقطه پایانی (endpoint) برای آن ندارد، زیرا نه پیکربندی شده و نه تا این لحظه آموخته شده است.
حالا جهت ورودی (inbound) را بررسی میکنیم. یک بسته UDP روی پورت گوشدهنده (listen port) دریافت میشود. WireGuard نشست مربوطه را از طریق ایندکس گیرنده در هدر پیدا میکند، شمارنده را با پنجره بازپخش (sliding replay window) چک میکند و سپس محموله (payload) را رمزگشایی و احراز هویت مینماید. تنها پس از این مرحله است که بسته داخلی خوانده میشود و آدرس مبدأ آن بسته داخلی باید حتماً در محدوده AllowedIPs همتای فرستنده باشد. اگر چنین نباشد، بسته دور ریخته میشود. با فعال بودن dynamic debug، هسته دلیل این اتفاق را در خطی مشابه زیر چاپ میکند:
wg0: Packet has unallowed src IP (10.8.0.9) from peer 2 (203.0.113.10:51820)به همین دلیل است که یک همتا در سمت سرور با /32 مواجه میشود. همتایی که با AllowedIPs = 10.8.0.2/32 پیکربندی شده است، فقط میتواند بستههایی را از 10.8.0.2 ارسال کند و نه هیچ آدرس دیگری. اگر به جای آن 0.0.0.0/0 را بنویسید، آن کلاینت اجازه مییابد بستههایی با هر آدرس مبدأیی که داخل تونل شما باشد (از جمله آدرس کلاینتهای دیگر) تزریق کند.
پیشوندهای همپوشان بر اساس اختصاصی بودن حل میشوند، زیرا جستجو بر مبنای طولانیترین پیشوند است. پیشوندهای یکسان در دو همتا رفتار متفاوتی دارند: ورودی به همتایی منتقل میشود که آخرین بار پیکربندی شده است و همتای اول بدون چاپ هیچ خطایی، دریافت آن ترافیک را متوقف میکند. دستور wg show wg0 allowed-ips جدولی را که در حال حاضر در هسته فعال است چاپ میکند؛ این همان چیزی است که در صورت مغایرت فایل روی دیسک با وضعیت در حال اجرا، ملاک عمل قرار میگیرد.
خواندن فایل پیکربندی با در نظر گرفتن مسیریابی کلید رمزنگاری
سمت سرور:
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = <server private key>
[Peer]
PublicKey = <laptop public key>
AllowedIPs = 10.8.0.2/32سمت کلاینت:
[Interface]
Address = 10.8.0.2/32
PrivateKey = <laptop private key>
[Peer]
PublicKey = <server public key>
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25یک کلمه کلیدی واحد، در دو سمت وزن متفاوتی دارد. در کلاینت به معنای «ارسال تمام مقاصد به این همتا» است. در سرور به معنای «پذیرش تنها این یک آدرس از این همتا» است. این عدم تقارن در مقادیر نهفته است، نه در نقشها.
نیمی از این کلیدها اصلاً بخشی از پروتکل نیستند. Address، DNS، MTU، PostUp و SaveConfig متعلق به wg-quick هستند؛ همان اسکریپت shell که رابط شبکه را بالا میآورد. هسته سیستمعامل هرگز آنها را نمیبیند. wg-quick strip wg0 پیکربندی خلاصهشدهای را چاپ میکند که ابزار wg واقعاً آن را بارگذاری میکند؛ این سریعترین راه برای مشاهده این تفکیک است.
عملکرد واقعی handshake
فرآیند handshake در WireGuard از پروتکل Noise_IKpsk2 از چارچوب Noise Protocol Framework استفاده میکند. بخش IK برای یک مدیر سیستم اهمیت عملی دارد: کلید عمومی ثابت پاسخدهنده (responder) از قبل برای آغازگر (initiator) شناختهشده است، زیرا این کلید همان PublicKey در بلوک [Peer] شماست و آغازگر نیز کلید عمومی ثابت خود را در اولین پیام بهصورت رمزنگاریشده ارسال میکند. بنابراین، تبادل گواهی و رفتوبرگشت برای احراز هویت وجود ندارد. یک ناظر غیرفعال نمیتواند تشخیص دهد کدام کلید در حال برقراری تماس است، مگر اینکه کلید خصوصی پاسخدهنده را در اختیار داشته باشد.
هزینه این کار یک رفتوبرگشت (round trip) است. پیام آغازین 148 بایت و پاسخ 92 بایت حجم دارد و پس از آن دادهها بلافاصله جریان مییابند. هر طرف برای هر handshake یک جفتکلید ephemeral از نوع Curve25519 تولید میکند و کلیدهای نشست (session keys) از زنجیرهای از نتایج Diffie-Hellman که کلیدهای ثابت و ephemeral را ترکیب میکند، به دست میآیند. کلیدهای خصوصی ephemeral سپس حذف میشوند که این امر باعث ایجاد forward secrecy میشود: کسی که ترافیک شما را امروز ضبط کند و سال آینده کلید خصوصی سرور را بدزدد، همچنان نمیتواند محتوای ضبطشده را بخواند.
آغاز handshake حاوی یک timestamp از نوع TAI64N است و هر peer بزرگترین timestamp دیدهشده از طرف مقابل را به خاطر میسپارد، بنابراین تلاش برای replay کردن پیام آغازین رد میشود. بستههای داده دارای یک شمارنده 64 بیتی بهعنوان nonce هستند و گیرنده یک پنجره لغزان (sliding window) از شمارندههای اخیر را نگه میدارد، بنابراین replayها و جابهجاییهای شدید در ترتیب بستهها بدون نیاز به وضعیت اتصال (connection state) مشابه TCP مدیریت میشوند.
کلیدهای نشست عمر کوتاهی دارند و تایمرها بهجای قابل تنظیم بودن، در کد کامپایل شدهاند.
The data behind this chart
[
{
"label": "REKEY_TIMEOUT",
"seconds": 5,
"notes": "resend a handshake initiation that got no answer"
},
{
"label": "KEEPALIVE_TIMEOUT",
"seconds": 10,
"notes": "send a keepalive after receiving data and sending none back"
},
{
"label": "REKEY_ATTEMPT_TIME",
"seconds": 90,
"notes": "give up on the handshake and report the peer as down"
},
{
"label": "REKEY_AFTER_TIME",
"seconds": 120,
"notes": "sender begins a fresh handshake for a new session key"
},
{
"label": "REJECT_AFTER_TIME",
"seconds": 180,
"notes": "the old session key is refused and traffic stops"
}
]اینها ثابتهایی از مشخصات پروتکل هستند، نه اندازهگیریهای متغیر. تعداد 5 عدد از آنها کل چرخه حیات نشست را هدایت میکنند. پس از 120 ثانیه استفاده، فرستنده یک handshake جدید را آغاز میکند و پس از 180 ثانیه، کلید قدیمی کاملاً رد میشود، بنابراین ترافیک تا زمانی که handshake جدید کامل نشود، متوقف میماند. پیامی که پاسخی دریافت نکند، هر 5 ثانیه دوباره ارسال شده و پس از 90 ثانیه رها میشود. به همین دلیل است که wg show مقدار latest handshake را بهعنوان یک عمر نسبی نمایش میدهد و یک تونل سالم و پرکار، این مقدار را کوچک نگه میدارد. اگر در حین ارسال فعال ترافیک، این عمر افزایش یابد، به این معناست که handshakeها با شکست مواجه شدهاند، نه اینکه تونل در حالت idle قرار دارد.
چرا یک همتا (peer) نقش کلاینت یا سرور ندارد
هر دو سمت، کد یکسانی را اجرا میکنند و از فرمت پیکربندی مشابهی استفاده میکنند. هیچ حالت سروری وجود ندارد. عدم تقارنی که احساس میکنید ناشی از Endpoint است و Endpoint اختیاری است.
یک همتا با یک endpoint پیکربندیشده میتواند یک handshake را آغاز کند. همتایی که چنین تنظیماتی ندارد، منتظر میماند و سپس آدرس و پورت سمت مقابل را از اولین بستهای که بهدرستی احراز هویت شده است، یاد میگیرد. آن endpoint آموختهشده ذخیره میشود و هر زمان که بسته معتبری از یک آدرس جدید برسد، بهروزرسانی میگردد. این همان نحوه عملکرد roaming است: لپتاپی که از شبکه wifi به شبکه موبایل منتقل میشود، همان تونل را حفظ میکند، زیرا نشست (session) به جای آدرس IP، توسط کلید و ایندکس شناسایی میشود. هیچ چیزی دوباره متصل نمیشود، زیرا هیچگاه اتصالی به معنای TCP وجود نداشته است.
همین مکانیزم حقیقتی را ایجاد میکند که دانستن آن ارزشمند است: همتایی که دارای آدرس عمومی است، همیشه آخرین IP عمومی شناختهشده سمت مقابل را در اختیار دارد و wg show آن را نمایش میدهد.
توابع پایه ثابت، بدون امکان مذاکره
در WireGuard هیچ فهرستی از ciphersuite وجود ندارد. برای رمزنگاری احراز هویتشده از ChaCha20-Poly1305، برای توافق کلید از Curve25519، برای هش کردن از BLAKE2s و برای مشتقسازی کلید از HKDF استفاده میشود. تمامی پیادهسازیها از همین توابع استفاده میکنند، بنابراین هیچ مرحله مذاکرهای برای تجزیه و هیچ مسیر تنزلی (downgrade) به گزینههای ضعیفتر وجود ندارد. این یک معامله واقعی است: اگر یکی از این توابع پایه شکسته شود، راه حل آن ارائه نسخه جدیدی از کل پروتکل و بهروزرسانی در هر دو سمت است، نه تغییر در پیکربندی. همین تصمیم واحد، بخش بزرگی از کد و اکثر حالتهای شکست که در تونلهای مبتنی بر TLS وجود دارد را حذف میکند؛ این همان نکتهای است که مقایسه در WireGuard در برابر OpenVPN عمدتاً به آن ختم میشود.
چرا پورت به اسکنر پاسخ نمیدهد
هر پیام handshake دارای فیلدی به نام mac1 است. این فیلد یک MAC (کد احراز اصالت پیام) است که با استفاده از کلیدی که از کلید عمومی ثابت پاسخدهنده مشتق شده، روی پیام محاسبه میشود. فرستندهای که آن کلید عمومی را نداشته باشد، نمیتواند یک mac1 معتبر تولید کند و گیرنده چنین بستهای را بدون هیچ پاسخی دور میاندازد. نه خطایی ارسال میشود، نه reset و نه پیام ICMP.
نتیجهٔ قابل مشاهده این است که اسکن UDP هیچ پاسخی دریافت نمیکند.
sudo nmap -sU -p 51820 vpn.example.comابزار nmap وضعیت open|filtered را گزارش میدهد که همان پاسخی است که برای پورتی که فایروال بهطور بیصدا بستهها را در آن دور میاندازد، ارائه میکند. رفتار پورت در حالتی که WireGuard در حال گوش دادن باشد با حالتی که نباشد یکسان است؛ حداقل برای هر کسی که کلید عمومی شما را در اختیار نداشته باشد.
فیلد دوم، mac2، فشار حملات منع سرویس (DoS) را مدیریت میکند. زمانی که گیرنده تحت بار کاری سنگین باشد، به یک initiation معتبر با یک پاسخ cookie به طول 64 بایت که به آدرس مبدأ فرستنده متصل است پاسخ میدهد و تا زمانی که فرستنده آن cookie را بازنگرداند، از انجام عملیات سنگین کلید عمومی خودداری میکند. این کار پیش از صرف هرگونه توان پردازشی، واقعی بودن آدرس مبدأ را اثبات میکند و تنها در شرایط تحت بار فعال میشود.
چرا 0.0.0.0/0 یک peer را به مسیر پیشفرض (default route) شما تبدیل میکند
به این دلیل که AllowedIPs جدول مسیریابی است و AllowedIPs = 0.0.0.0/0, ::/0 تمام مقاصد را برای آن peer مطالبه میکند. این همان تنظیم کامل تونل (full tunnel) است.
مسیریابیای که باعث کارکرد این وضعیت میشود، از خودِ خط دستور جالبتر است. یک مسیر پیشفرض ساده از طریق wg0 دچار حلقه (loop) میشود، زیرا بسته UDP رمزنگاریشدهای که ترافیک شما را حمل میکند نیز باید از دستگاه خارج شود و با همان مسیر پیشفرض خودش مطابقت پیدا میکند. wg-quick با استفاده از مسیریابی مبتنی بر سیاست (policy routing) از این مشکل جلوگیری میکند. این ابزار بستههای خروجی خودِ WireGuard را با یک fwmark علامتگذاری میکند، مسیر پیشفرض تونل را در یک جدول مسیریابی جداگانه قرار میدهد و قوانینی اضافه میکند تا فقط ترافیکهای بدون علامت به آن برسند. دستور ip rule show را اجرا کنید تا نتیجه را ببینید:
32764: from all lookup main suppress_prefixlength 0
32765: not from all fwmark 0xca6c lookup 51820
32766: from all lookup main0xca6c معادل 51820 در مبنای هگزادسیمال است و 51820 همان شماره جدول نیز هست. قانون suppress_prefixlength 0 باعث میشود جدول اصلی از مسیر پیشفرض خودش صرفنظر کند، بنابراین مسیرهای خاص مانند زیرشبکه محلی شما همچنان اولویت دارند، در حالی که سایر ترافیکها به جدول تونل هدایت میشوند. یک تونل تفکیکشده (split tunnel) به هیچکدام از اینها نیاز ندارد: یک لیست محدودتر مانند AllowedIPs = 10.8.0.0/24, 10.20.0.0/16 به مسیرهای عادی در جدول اصلی تبدیل میشود.
یک موردی که تونل کامل بهتنهایی آن را اصلاح نمیکند، وضوح نام (name resolution) است، زیرا resolverای که کلاینت شما از شبکه محلی دریافت کرده معمولاً فعال باقی میماند و مسیر آن خاصتر است. این یک وظیفه جداگانه است که در DNS که به خارج از تونل WireGuard نشت میکند پوشش داده شده است.
هدف واقعی PersistentKeepalive چیست
پروتکل WireGuard در زمان نبود ترافیک، هیچ بستهای ارسال نمیکند. نه ضربان قلب (heartbeat)، نه تازهسازی نشست (session refresh) و نه هیچ دادهای روی شبکه وجود ندارد. این سکوت به حفظ عمر باتری و همچنین در سناریوی اسکنر که در بالا ذکر شد کمک میکند، اما یک پیکربندی خاص را مختل میسازد.
یک همتا (peer) که پشت NAT (ترجمه آدرس شبکه) یا یک فایروال حالتمند (stateful firewall) قرار دارد، تنها زمانی از بیرون قابل دسترسی است که نگاشتی (mapping) در آن دستگاه وجود داشته باشد؛ این نگاشت توسط یک بسته خروجی ایجاد میشود. طول عمر معمول نگاشتهای UDP از حدود 30 ثانیه شروع میشود. پس از انقضای این نگاشت، بستههایی که از سمت عمومی (public side) میآیند توسط دستگاه میانی (middlebox) حذف میشوند و تونل تا زمانی که همتای پشت NAT بستهای ارسال نکند، قطع به نظر میرسد. PersistentKeepalive = 25 هر 25 ثانیه یک بسته خالی احراز هویتشده ارسال میکند که طول عمر آن کمتر از کوتاهترین طول عمر معمول است، بنابراین نگاشت باز میماند.
این گزینه را روی همتایی که پشت NAT قرار دارد تنظیم کنید. سروری که دارای آدرس عمومی و پورت UDP باز است به آن نیازی ندارد و تنظیم آن در آنجا فقط باعث ایجاد ترافیک اضافی میشود. آن را با قابلیت keepalive خودکار اشتباه نگیرید؛ قابلیتی که 10 ثانیه پس از دریافت داده توسط یک همتا، در صورتی که دادهای برای ارسال به عقب نداشته باشد، فعال میشود. آن قابلیت همیشه روشن است و قابل پیکربندی نیست.
مسیریابی شبکه محلی (LAN) از طریق تونل، قابلیتی در WireGuard نیست
فرض کنید peer B در یک شبکه خانگی 192.168.50.0/24 قرار دارد و peer A باید به آن دسترسی داشته باشد. دو سیستم مجزا باید با هم هماهنگ شوند که تنها یکی از آنها WireGuard است.
بخش مربوط به WireGuard: مقدار 192.168.50.0/24 را به AllowedIPs مربوط به B در سیستم A اضافه کنید. این کار باعث میشود A ترافیک مربوط به آن پیشوند (prefix) را به سمت B مسیریابی کند و همچنین به A اجازه میدهد بستههایی با آن آدرسهای مبدأ را از B بپذیرد. بدون این تنظیم، مسیریابی کلید رمزنگاری (cryptokey routing) نه کلیدی برای مقصد دارد و نه مجوزی برای مبدأ.
بخش مربوط به هسته سیستمعامل (Kernel): در سیستم B، مقدار net.ipv4.ip_forward باید 1 باشد؛ در غیر این صورت، هسته تمام بستههای رمزگشاییشدهای که مستقیماً برای خود B ارسال نشدهاند را دور میریزد. زنجیره forward در فایروال B باید اجازه عبور این ترافیک را بدهد. میزبانهای موجود در شبکه LAN نیز به یک مسیر بازگشت به سمت 10.8.0.0/24 نیاز دارند، یا اینکه B باید از source NAT استفاده کند تا پاسخها از طریق B بازگردند.
کار WireGuard زمانی پایان مییابد که بستهٔ رمزگشاییشده را به kernel تحویل دهد. پس از آن، همهچیز در چارچوب routing و filtering معمول Linux انجام میشود. به همین دلیل، این خطا در شمارندههای nft list ruleset یا در ip -s link show wg0 دیده میشود، نه در wg show. اگر ترجیح میدهید peerها را از طریق رابط وب مدیریت کنید، اجرای wg-easy در Docker ورودیهای peer را برای شما ایجاد میکند؛ اما ruleهای forwarding همچنان به host تعلق دارند. این تفکیک زمانی هم حفظ میشود که یک لایهٔ coordination، prefix را برای شما توزیع کند: اعلام یک شبکهٔ خصوصی از VPS با subnet router در Tailscale جایگزین ویرایش دستی AllowedIPs روی هر peer میشود، اما sysctl مربوط به forwarding و ruleهای firewall روی خود router همچنان باید توسط شما تنظیم شوند.
چرا WireGuard در هسته (Kernel) قرار دارد
wg0 یک درایور دستگاه شبکه است. بستهها از طریق پشته مسیریابی معمولی به آن میرسند، در context مربوط به softirq رمزگذاری میشوند و بدون اینکه هرگز وارد فضای کاربری (userspace) شوند، از طریق یک سوکت UDP خارج میشوند. این همان دلیلی است که باعث افزایش نرخ انتقال داده (throughput) میشود و همچنین دلیل آن است که حجم کد این ماژول در حدود 4000 خط باقی مانده است؛ مقداری که به اندازه کافی کوچک است تا بازبینی شود و در مارس 2020 به خط اصلی (mainline) هسته لینوکس 5.6 ادغام گردد. توزیعهای Ubuntu 24.04 و Debian 13 آن را به همراه دارند، بنابراین تنها بسته wireguard-tools است که در آنها وجود ندارد.
رابط (interface) معمولی بودن، پیامدهای عملی دارد. tcpdump -ni wg0 بستههای داخلی متنباز (plaintext) را نشان میدهد، در حالی که tcpdump -ni eth0 udp port 51820 بستههای خارجی رمزگذاریشده را نمایش میدهد و مقایسه این دو به شما بلافاصله میگوید که کدام جهت دچار اختلال شده است. netfilter و ابزارهای شکلدهی ترافیک (traffic shaping)، رابط wg0 را مانند هر لینک دیگری مدیریت میکنند. در مواردی که ماژول هسته در دسترس نیست، مانند مجازیسازی کانتینری که هسته میزبان را به اشتراک میگذارد، wireguard-go همان پروتکل را در فضای کاربری (userspace) و از طریق یک دستگاه TUN پیادهسازی میکند که هزینه واقعی آن کاهش نرخ انتقال داده است، زیرا هر بسته دو بار از مرز هسته عبور میکند.
مواردی که WireGuard از آنها محافظت نمیکند
مدل تهدید به عمد محدود در نظر گرفته شده است و ماهیت بیسروصدای این پروتکل ممکن است باعث تصورات نادرست شود. این موارد را بهصراحت بیان میکنیم:
- این پروتکل پنهان نمیکند که شما از WireGuard استفاده میکنید. پیامهای handshake اندازههای ثابتی دارند، بایت اول نوع پیام را مشخص میکند و بستر انتقال UDP است. بازرسی عمیق بسته (DPI) بهراحتی آن را شناسایی میکند و شبکهای که با VPN مخالف باشد، میتواند آن را مسدود کند. قابلیت obfuscation (مبهمسازی) بهطور عمدی در پروتکل گنجانده نشده است.
- این پروتکل حجم یا زمانبندی ترافیک را پنهان نمیکند. payloadها فقط تا مرز 16 بایت padding میشوند، بنابراین یک ناظر همچنان میبیند که چه زمانی داده ارسال میکنید و حجم تقریبی آن چقدر است.
- این پروتکل آخرین endpoint شناختهشده را نگه میدارد. همتایی که آدرس عمومی دارد، IP عمومی فعلی طرف مقابل را ذخیره میکند و
wg showآن را نمایش میدهد. این موضوع به همراه آدرس تونل که در فایل پیکربندی ثابت است، یک شناسه پایدار ایجاد میکند که کاربر را بین شبکههای مختلف دنبال میکند. روی VPS شخصی خودتان، این مسئله مشکلی ایجاد نمیکند. به همین دلیل است که سرویسهای تجاری یک لایه اضافه روی این پروتکل میسازند. - این پروتکل یک کلید را احراز هویت میکند، نه یک شخص را. هر کسی که فایل کلید خصوصی را در اختیار داشته باشد، همان همتا محسوب میشود. دسترسی
/etc/wireguardرا روی 700 و فایلهای کلید را روی 600 نگه دارید. - هیچ لیست ابطال یا تاریخ انقضایی وجود ندارد. دسترسی زمانی پایان مییابد که ورودی همتا را از تمام سرورهایی که آن را دارند حذف کنید و کلیدهای استاتیک تا زمانی که آنها را حذف نکنید، معتبر باقی میمانند.
هیچکدام از این موارد WireGuard را ضعیف نمیکند. این ویژگیها باعث کوچک ماندن آن میشوند و کوچک بودن، هدف اصلی است: این پروتکل احراز هویت و رمزنگاری را انجام میدهد و مدیریت هویت و تخصیص آدرس را به هر چیزی که شما روی آن میسازید واگذار میکند. یک لایه هماهنگسازی از نوعی که در مقایسه WireGuard با Tailscale توضیح داده شد، دقیقاً برای پر کردن همین شکاف وجود دارد و از همان data plane که مطالعه کردید استفاده میکند. هنگامی که چنین لایهای برقرار شد، تصمیم بعدی این است که چه کسی میتواند به سرویسی که داخل تونل اجرا میکنید دسترسی داشته باشد، که این همان موضوعی است که انتخاب بین Tailscale serve و funnel برای یک پورت خاص تعیین تکلیف میکند.
FAQ
مسیریابی کلید رمزنگاری (cryptokey routing) در WireGuard چیست؟
مسیریابی کلید رمزنگاری قانونی است که هر بسته را به یک کلید عمومی متصل میکند. هر ورودی peer شامل فهرستی از پیشوندها در AllowedIPs است. در ترافیک خروجی، WireGuard با تطبیق مقصد بسته با فهرست هر peer (با اولویت طولانیترین پیشوند)، peer مقصد را انتخاب میکند؛ بنابراین این فهرست مانند یک جدول مسیریابی عمل میکند. در ترافیک ورودی، پس از رمزگشایی و احراز هویت بسته، آدرس مبدأ داخلی آن باید در همان فهرست peer قرار داشته باشد، در غیر این صورت بسته حذف میشود؛ بنابراین این فهرست به عنوان یک لیست کنترل دسترسی (ACL) عمل میکند. WireGuard پیکربندی مسیریابی جداگانه یا فایروال داخلی مجزا ندارد، زیرا همان یک فهرست هر دو وظیفه را انجام میدهد.
آیا به PersistentKeepalive در هر دو سمت نیاز دارم؟
خیر. آن را در سمتی که پشت NAT (ترجمه آدرس شبکه) یا پشت یک فایروال stateful قرار دارد تنظیم کنید، که معمولاً سمت کلاینت است. WireGuard در زمان بیکاری هیچ دادهای ارسال نمیکند، بنابراین نگاشتی که به سمت مقابل اجازه میدهد به آن peer دسترسی داشته باشد، اغلب ظرف یک دقیقه منقضی میشود و تونل در یک جهت غیرفعال به نظر میرسد. PersistentKeepalive = 25 هر 25 ثانیه یک بسته احراز هویتشدهٔ خالی ارسال میکند و نگاشت را باز نگه میدارد. peerای که دارای آدرس عمومی و پورت UDP باز است، به این تنظیم نیاز ندارد.
چرا پینگ روی تونل خطای "Required key not available" را نشان میدهد؟
زیرا آدرس مقصد در هیچکدام از AllowedIPsهای peerها وجود ندارد؛ بنابراین مسیریابی کلید رمزنگاری هیچ کلیدی برای رمزنگاری بسته پیدا نکرده و هسته سیستمعامل از ارسال آن خودداری کرده است. دستور wg show wg0 allowed-ips را اجرا کنید و خروجی آن را با آدرسی که در حال پینگ کردن آن هستید مقایسه کنید. خطای مشابه Destination address required مشکل متفاوتی است: یک peer تطبیق داده شده، اما WireGuard هیچ endpointای برای آن ندارد، زیرا هیچ endpointای پیکربندی نشده و هنوز هیچ بسته احراز هویتشدهای از آن peer دریافت نشده است.
آیا فایروال میتواند WireGuard را شناسایی و مسدود کند؟
بله. WireGuard ترافیک شما را احراز هویت و رمزنگاری میکند و هیچ تلاشی برای پنهانسازی خود انجام نمیدهد. پیامهای handshake دارای اندازه ثابت 148 و 92 بایت هستند، بایت اول هر پیام نوع آن را مشخص میکند و پروتکل انتقال UDP است؛ بنابراین بازرسی عمیق بسته (DPI) به راحتی این پروتکل را شناسایی میکند. شبکههایی که UDP را مسدود میکنند یا پروتکلها را اثرانگشتگذاری (fingerprint) میکنند، آن را متوقف خواهند کرد. پنهان کردن تونل به معنای بستهبندی آن در یک پروتکل دیگر است که این کار توسط ابزارهای جانبی انجام میشود و جزو تنظیمات WireGuard نیست.