WireGuardDevice
WireGuardDevice پیادهسازی WireGuard درون chain واتروال است. این نود IP packetهای داخلی را به پیامهای WireGuard مانند handshake، cookie و transport تبدیل میکند و مسیر برعکس را نیز انجام میدهد.
این نود نه UDP socket میسازد و نه WireGuard interface سیستمعامل را ایجاد میکند. تقسیم مسئولیت معمول به این شکل است:
TunDevice،RawSocket،PacketsToConnectionیا یک packet node دیگر سمت packet داخلی را فراهم میکندWireGuardDevicecrypto، 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"
}
تنظیمات ضروری
| فیلد | نوع | توضیح |
|---|---|---|
privatekey | string | private key دستگاه WireGuard، بهصورت base64 و 32 بایتی. |
peers | array | آرایه غیرخالی از peerها. حداکثر فعلی 32 peer است. |
object مربوط به settings الزامی است و نباید خالی باشد.
تنظیمات اختیاری
| فیلد | پیشفرض | توضیح |
|---|---|---|
transport-direction | تشخیص خودکار | مشخص میکند سمت پیامهای UDP WireGuard کدام طرف است. مقدارهای next، up، upstream، prev، down و downstream پذیرفته میشوند. |
auth-client-node-name | ندارد | یک UserController داخلی در سمت transport میسازد و از این AuthenticationClient استفاده میکند. |
sweep-interval-ms | 1000 | با تنظیم auth-client-node-name، این مقدار به UserController داخلی داده میشود. |
verbose | false | با تنظیم 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:
| فیلد | نوع | توضیح |
|---|---|---|
publickey | string | public key peer بهصورت base64 و 32 بایتی. |
allowedips | string | فهرستی از CIDRها با جداکننده comma؛ IPv4 و IPv6 پشتیبانی میشوند. هر peer حداقل یک و حداکثر 16 entry دارد. |
endpoint | string | endpoint peer به شکل host:port، ipv4:port یا [ipv6]:port. hostname در زمان ساخت tunnel resolve میشود. |
فیلدهای اختیاری هر peer:
| فیلد | پیشفرض | توضیح |
|---|---|---|
presharedkey | ندارد | PSK اختیاری WireGuard بهصورت base64 و 32 بایتی. |
persistentkeepalive | 0 | فاصله keepalive بر حسب ثانیه. بازه معتبر 0 تا 65535 است؛ 0 یعنی غیرفعال. |
فاصلههای داخل allowedips نادیده گرفته میشوند؛ بنابراین مقداری مثل 10.0.0.2/32, 10.1.0.0/16 معتبر است.
چه چیزهایی را تنظیم نمیکند
WireGuardDevice جایگزین wg-quick نیست و این موارد را مدیریت نمیکند:
AddressinterfaceListenPortMTU- route table سیستم
PostUpیاPostDown- firewall، NAT یا forwarding
- OS WireGuard interface
برای address و route داخلی از TunDevice، برای bind کردن UDP از UdpStatelessSocket و برای firewall یا NAT از تنظیمات host یا script استفاده کنید.
مسیر packet داخلی
وقتی IP packet داخلی به WireGuardDevice برسد:
- packet باید IPv4 یا IPv6 باشد
- destination IP از packet خوانده میشود
- peer با longest-prefix match روی
AllowedIPsانتخاب میشود - packet به WireGuard transport-data message رمز میشود
- endpoint مربوط به peer در destination routing context مربوط به transport line نوشته میشود
- پیام WireGuard به سمت UDP transport فرستاده میشود
اگر مقصد داخلی با هیچ peer متناظر نباشد، packet دور ریخته میشود.
در نتیجه، AllowedIPs مسیریابی outbound بر اساس cryptokey را کنترل میکند و prefix مشخصتر اولویت دارد.
مسیر transport
سمت transport پیامهای خام WireGuard را حمل میکند. وقتی datagram از UdpStatelessSocket برسد:
- source IP و port از routing context خوانده میشود
- نوع پیام WireGuard تشخیص داده میشود
- handshake، cookie یا transport data پردازش میشود
- transport data معتبر decrypt میشود
- plaintext باید IPv4 یا IPv6 معتبر باشد
- source IP داخل plaintext باید با
AllowedIPsهمان peer match شود - در پایان، 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، نود:
- برای هر worker یک normal companion transport line میسازد
- peerهای تنظیمشده را با
wireguardifConnect()فعال میکند - loop دورهای device را روی worker
0شروع میکند - 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 model | pure packet tunnel به همراه companion transport lineهای owned |
| Per-line packet state | ندارد |
| Required left padding | 16 |
| Peer limit | 32 |
| Allowed IP entries per peer | 16 |
| Periodic loop interval | 400 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ها.