پرش به مطلب اصلی

WireGuardDevice

WireGuardDevice پیاده‌سازی WireGuard درون chain واتروال است. این نود IP packetهای داخلی را به پیام‌های WireGuard مانند handshake، cookie و transport تبدیل می‌کند و مسیر برعکس را نیز انجام می‌دهد.

این نود نه UDP socket می‌سازد و نه WireGuard interface سیستم‌عامل را ایجاد می‌کند. تقسیم مسئولیت معمول به این شکل است:

  • TunDevice، RawSocket، PacketsToConnection یا یک packet node دیگر سمت packet داخلی را فراهم می‌کند
  • WireGuardDevice crypto، state مربوط به peer، مسیریابی allowed IP، handshake، keepalive، rekey و endpoint roaming را مدیریت می‌کند
  • UdpStatelessSocket مسئول UDP socket بیرونی است

جایگاه رایج

TunDevice -> WireGuardDevice -> UdpStatelessSocket
UdpStatelessSocket -> WireGuardDevice -> TunDevice
TesterClient(packet) -> WireGuardDevice -> UdpStatelessSocket

سمت transport می‌تواند next یا prev باشد. اگر topology واضح نیست، transport-direction را صریح تنظیم کنید.

اگر auth-client-node-name تنظیم شود، WireGuardDevice یک UserController داخلی فقط در سمت transport می‌سازد:

UdpStatelessSocket -> UserController -> WireGuardDevice -> packet side node
packet side node -> WireGuardDevice -> UserController -> UdpStatelessSocket

سمت packet عمداً دست‌نخورده می‌ماند. packet lineهای worker از UserController داخلی عبور نمی‌کنند؛ فقط companion transport lineهای معمولی و تحت مالکیت WireGuardDevice به آن داده می‌شوند.

نمونه تنظیم

{
"name": "wg-device",
"type": "WireGuardDevice",
"settings": {
"privatekey": "<base64-32-byte-private-key>",
"transport-direction": "next",
"peers": [
{
"publickey": "<base64-32-byte-peer-public-key>",
"allowedips": "10.44.0.2/32,10.44.1.0/24,fd00::2/128",
"endpoint": "vpn.example.com:51820",
"presharedkey": "<optional-base64-32-byte-psk>",
"persistentkeepalive": 25
}
]
},
"next": "udp-edge"
}

تنظیمات ضروری

فیلدنوعتوضیح
privatekeystringprivate key دستگاه WireGuard، به‌صورت base64 و 32 بایتی.
peersarrayآرایه غیرخالی از peerها. حداکثر فعلی 32 peer است.

object مربوط به settings الزامی است و نباید خالی باشد.

تنظیمات اختیاری

فیلدپیش‌فرضتوضیح
transport-directionتشخیص خودکارمشخص می‌کند سمت پیام‌های UDP WireGuard کدام طرف است. مقدارهای next، up، upstream، prev، down و downstream پذیرفته می‌شوند.
auth-client-node-nameنداردیک UserController داخلی در سمت transport می‌سازد و از این AuthenticationClient استفاده می‌کند.
sweep-interval-ms1000با تنظیم auth-client-node-name، این مقدار به UserController داخلی داده می‌شود.
verbosefalseبا تنظیم auth-client-node-name، این مقدار به UserController داخلی داده می‌شود.

اگر این گزینه را ننویسید، نود در هر دو جهت به‌دنبال UdpStatelessSocket می‌گردد. پیدا شدن آن در هر دو سمت باعث خطای راه‌اندازی می‌شود و باید transport-direction را مشخص کنید. اگر فقط در یک سمت باشد، همان جهت transport خواهد بود. در نبود UdpStatelessSocket، ابتدا سمت Layer 4 انتخاب می‌شود و در نهایت مقدار قدیمی پیش‌فرض، یعنی next، به کار می‌رود.

در حال حاضر UserController داخلی فقط ساختار chain را آماده می‌کند. authentication در WireGuard همچنان بر پایه peers تنظیم‌شده است و WireGuardDevice هنوز peerها را به userهای database متصل نمی‌کند. تا زمان پیاده‌سازی این بخش، lineهای transport بدون مدیریت از UserController داخلی عبور می‌کنند.

تنظیمات Peer

فیلدهای ضروری هر peer:

فیلدنوعتوضیح
publickeystringpublic key peer به‌صورت base64 و 32 بایتی.
allowedipsstringفهرستی از CIDRها با جداکننده comma؛ IPv4 و IPv6 پشتیبانی می‌شوند. هر peer حداقل یک و حداکثر 16 entry دارد.
endpointstringendpoint peer به شکل host:port، ipv4:port یا [ipv6]:port. hostname در زمان ساخت tunnel resolve می‌شود.

فیلدهای اختیاری هر peer:

فیلدپیش‌فرضتوضیح
presharedkeyنداردPSK اختیاری WireGuard به‌صورت base64 و 32 بایتی.
persistentkeepalive0فاصله keepalive بر حسب ثانیه. بازه معتبر 0 تا 65535 است؛ 0 یعنی غیرفعال.

فاصله‌های داخل allowedips نادیده گرفته می‌شوند؛ بنابراین مقداری مثل 10.0.0.2/32, 10.1.0.0/16 معتبر است.

چه چیزهایی را تنظیم نمی‌کند

WireGuardDevice جایگزین wg-quick نیست و این موارد را مدیریت نمی‌کند:

  • Address interface
  • ListenPort
  • MTU
  • route table سیستم
  • PostUp یا PostDown
  • firewall، NAT یا forwarding
  • OS WireGuard interface

برای address و route داخلی از TunDevice، برای bind کردن UDP از UdpStatelessSocket و برای firewall یا NAT از تنظیمات host یا script استفاده کنید.

مسیر packet داخلی

وقتی IP packet داخلی به WireGuardDevice برسد:

  1. packet باید IPv4 یا IPv6 باشد
  2. destination IP از packet خوانده می‌شود
  3. peer با longest-prefix match روی AllowedIPs انتخاب می‌شود
  4. packet به WireGuard transport-data message رمز می‌شود
  5. endpoint مربوط به peer در destination routing context مربوط به transport line نوشته می‌شود
  6. پیام WireGuard به سمت UDP transport فرستاده می‌شود

اگر مقصد داخلی با هیچ peer متناظر نباشد، packet دور ریخته می‌شود.

در نتیجه، AllowedIPs مسیریابی outbound بر اساس cryptokey را کنترل می‌کند و prefix مشخص‌تر اولویت دارد.

مسیر transport

سمت transport پیام‌های خام WireGuard را حمل می‌کند. وقتی datagram از UdpStatelessSocket برسد:

  1. source IP و port از routing context خوانده می‌شود
  2. نوع پیام WireGuard تشخیص داده می‌شود
  3. handshake، cookie یا transport data پردازش می‌شود
  4. transport data معتبر decrypt می‌شود
  5. plaintext باید IPv4 یا IPv6 معتبر باشد
  6. source IP داخل plaintext باید با AllowedIPs همان peer match شود
  7. در پایان، packet داخلی به سمت packet فرستاده می‌شود

بنابراین AllowedIPs دو کاربرد دارد: در outbound، peer را بر اساس destination انتخاب می‌کند؛ در inbound نیز پس از decrypt شدن packet، source را اعتبارسنجی می‌کند.

Endpoint و Roaming

هر peer یک endpoint تنظیم‌شده و یک endpoint زنده دارد. اولی از JSON می‌آید و هنگام ساخت resolve می‌شود. پس از دریافت ترافیک معتبر inbound، endpoint زنده با آدرس و پورت فرستنده به‌روزرسانی می‌شود.

این همان roaming معمول WireGuard را ممکن می‌کند: پس از آنکه peer از آدرس یا پورت تازه‌ای ترافیک معتبر بفرستد، packetهای بعدی می‌توانند به همان endpoint یادگرفته‌شده برگردند. اگر state مربوط به peer یا session به‌اندازه کافی reset شود، live endpoint دوباره به configured endpoint برمی‌گردد.

hostname مربوط به endpoint فقط هنگام ساخت tunnel resolve می‌شود و به‌طور پیوسته دوباره resolve نخواهد شد.

Startup و Lineها

هنگام start، نود:

  1. برای هر worker یک normal companion transport line می‌سازد
  2. peerهای تنظیم‌شده را با wireguardifConnect() فعال می‌کند
  3. loop دوره‌ای device را روی worker 0 شروع می‌کند
  4. loop هر 400 ms اجرا می‌شود

این loop handshake اولیه، keepalive، retry، rekey و پاک‌سازی sessionها را انجام می‌دهد.

WireGuardDevice با packet-tunnel API واتروال ساخته می‌شود و per-line packet state ندارد. سمت داخلی از packet lineهای worker در chain استفاده می‌کند. سمت transport نیز lineهای معمولی تحت مالکیت WireGuardDevice را به کار می‌گیرد تا نودهای UDP، پیام WireGuard را با packet line داخلی اشتباه نگیرند.

اگر سمت transport برابر prev باشد، نود ممکن است هنگام startup مقداردهی اولیه موردنیاز worker packet line را به سمت packet در next بفرستد.

اگر UserController داخلی فعال باشد، همین companion transport lineهای معمولی از مسیر آن مقداردهی می‌شوند؛ مقداردهی packet line همچنان از آن عبور نمی‌کند.

انتخاب جهت

اگر transport side برابر next باشد:

  • upstream payload به‌عنوان packet داخلی رمزنگاری می‌شود
  • downstream payload به‌عنوان transport data رمزگشایی می‌شود
  • packet داخلی رمزگشایی‌شده در جهت downstream به‌سمت prev فرستاده می‌شود

اگر transport side برابر prev باشد:

  • upstream payload به‌عنوان transport data رمزگشایی می‌شود
  • downstream payload به‌عنوان packet داخلی رمزنگاری می‌شود
  • packet داخلی رمزگشایی‌شده در جهت upstream به‌سمت next فرستاده می‌شود

برای topologyهای غیرمعمول، transport-direction را حتماً صریح تنظیم کنید.

Padding

WireGuardDevice به 16 بایت left padding نیاز دارد. پیش از فرستادن ciphertext به سمت UDP، header مربوط به WireGuard transport-data در این فضا قرار می‌گیرد.

auth tag رمزنگاری نیز به انتهای packet اضافه می‌شود.

نمونه کامل

سمت client:

{
"name": "tun-client",
"type": "TunDevice",
"settings": {
"device-name": "tun0",
"device-ip": "10.44.0.1/24"
},
"next": "wg-client"
}
{
"name": "wg-client",
"type": "WireGuardDevice",
"settings": {
"privatekey": "<client-private-key>",
"peers": [
{
"publickey": "<server-public-key>",
"allowedips": "10.44.0.2/32,10.55.0.0/16",
"endpoint": "198.51.100.20:51820",
"persistentkeepalive": 25
}
]
},
"next": "udp-client"
}
{
"name": "udp-client",
"type": "UdpStatelessSocket",
"settings": {
"listen-address": "0.0.0.0",
"listen-port": 51820
}
}

سمت server:

{
"name": "udp-server",
"type": "UdpStatelessSocket",
"settings": {
"listen-address": "0.0.0.0",
"listen-port": 51820
},
"next": "wg-server"
}
{
"name": "wg-server",
"type": "WireGuardDevice",
"settings": {
"privatekey": "<server-private-key>",
"peers": [
{
"publickey": "<client-public-key>",
"allowedips": "10.44.0.1/32",
"endpoint": "203.0.113.10:51820"
}
]
},
"next": "tun-server"
}

متادیتای نود

ویژگیمقدار
Runtime modelpure packet tunnel به همراه companion transport lineهای owned
Per-line packet stateندارد
Required left padding16
Peer limit32
Allowed IP entries per peer16
Periodic loop interval400 ms

خطاهای رایج

  • انتظار اینکه این نود UDP socket بسازد. برای آن از UdpStatelessSocket استفاده کنید.
  • انتظار اینکه OS WireGuard interface ساخته شود.
  • قرار دادن UdpStatelessSocket در هر دو سمت بدون transport-direction.
  • قرار دادن دستی UserController در سمت transport در حالی که auth-client-node-name هم تنظیم شده است؛ WireGuardDevice خودش این نود داخلی را می‌سازد.
  • فراموش کردن اینکه در نسخه فعلی هر peer به endpoint نیاز دارد.
  • تنظیم نکردن AllowedIPs مطابق destinationهای داخلی مورد نیاز.
  • انتظار re-resolve شدن مداوم hostname endpointها.