بخش ۱: تنظیمات هسته
WaterWall هنگام راهاندازی، تنظیمات اولیهی خود را از فایل core.json میخواند.
تنظیمات سراسری process، مانند logها، تعداد workerها، پروفایل
حافظه، MTU، تنظیم اختیاری BBR در Linux، مسیر libraryهای خارجی، DNS resolver مشترک
و فهرست فایلهای config nodeها، در این فایل قرار میگیرند.
خود nodeهای تونل مستقیماً در این فایل تعریف نمیشوند. chainهای تونل در فایلهایی
قرار دارند که زیر configs فهرست شدهاند.
نکات مهم هنگام راهاندازی
اگر مسیر config را با آرگومان CLI یا متغیر محیطی تغییر نداده باشید، WaterWall
فایل ./core.json را از working directory خود میخواند. چیدمان معمول فایلها:
waterwall/
WaterWall
core.json
configs/
server.json
WaterWall را از همین دایرکتوری اجرا کنید:
cd ~/waterwall
./WaterWall
برای انتخاب منبع دیگری برای JSON هسته، میتوانید از هر یک از شکلهای معادل زیر در CLI استفاده کنید:
-c:PATH
--c:PATH
-config:PATH
--config:PATH
config:PATH
وجود : الزامی است. مقدار PATH میتواند یک مسیر نسبی از working directory
یا یک مسیر مطلق باشد. مقدار ویژهی stdin باعث میشود JSON هسته از ورودی
استاندارد خوانده شود:
./WaterWall --config:/etc/waterwall/core.json
./WaterWall --config:stdin < core.json
متغیر محیطی WW_CORE_JSON_INPUT نیز همین مسیرها یا مقدار stdin را میپذیرد.
ترتیب اولویت انتخاب ورودی چنین است:
CLI option > WW_CORE_JSON_INPUT > ./core.json
محتوای core.json باید JSON معتبر باشد؛ بنابراین در آن commentهایی با //
ننویسید. قابلیت comment نوشتن و جایگزینی variable که در ادامه توضیح میدهیم،
فقط در loader فایلهای config nodeها پشتیبانی میشود، نه در parser تنظیمات هسته.
انتخاب منبع دیگری برای JSON هسته، working directory مربوط به process را تغییر نمیدهد.
همهی مسیرهای داخل core.json دقیقاً با همان شکلی که نوشته شدهاند به بخش مربوط
داده میشوند؛ بنابراین مسیرهای نسبی، از جمله اعضای configs، همچنان نسبت به
دایرکتوری اجرای WaterWall محاسبه میشوند، نه نسبت به محل فایل JSON هسته.
ساختار سطح اول
{
"log": {},
"misc": {},
"dns": {},
"configs": []
}
| فیلد | نوع | الزامی | کاربرد |
|---|---|---|---|
configs | آرایهای از stringها | بله | فایلهای config nodeها که باید parse و اجرا شوند. |
log | object | خیر | مسیر و فایل log، سطح log و خروجی console. |
misc | object | خیر | تعداد workerها، پروفایل حافظه، MTU، تنظیم BBR در Linux و مسیر libraryها. |
dns | object | خیر | DNS resolver مشترک و async و سیاست پیشفرض انتخاب آدرس domain. |
وجود configs الزامی است و باید دستکم یک مسیر string در آن باشد. بخشهای دیگر
اختیاریاند، اما در محیط production بهتر است misc و dns.domain-strategy را
صریحاً مشخص کنید.
گزینهی domain-strategy را در ریشهی core.json قرار ندهید:
{
"domain-strategy": "prefer-ipv4"
}
این ساختار هنگام راهاندازی رد میشود. شکل درست آن چنین است:
{
"dns": {
"domain-strategy": "prefer-ipv4"
}
}
configs
بخش configs مشخص میکند WaterWall پس از آمادهشدن runtime هسته، کدام فایلهای
config node را load کند.
{
"configs": [
"configs/server.json",
"configs/reverse.json"
]
}
قواعد:
| حالت | رفتار |
|---|---|
configs وجود ندارد | راهاندازی با خطا متوقف میشود. |
| آرایه خالی است | راهاندازی با خطا متوقف میشود. |
| هیچ عضو string در آرایه نیست | راهاندازی با خطا متوقف میشود. |
| مسیرها نسبیاند | نسبت به working directory مربوط به process resolve میشوند. |
| چند فایل وجود دارد | پس از parse شدن تنظیمات هسته، node manager آنها را load میکند. |
برای راهاندازیهای کوچک یک فایل کافی است. برای راهاندازیهای بزرگتر میتوانید گروههای مختلف chain را در چند فایل جدا قرار دهید.
log
بخش log چهار logger سراسری process را تنظیم میکند.
| logger | کاربرد |
|---|---|
internal | جزئیات سطح پایین runtime و اطلاعات تشخیصی داخلی. |
core | راهاندازی، parse کردن config و logهای سطح manager. |
network | logهای شبکه و runtime تونلها. |
dns | logهای DNS resolver مشترک و async. |
هر logger فیلدهای یکسانی میپذیرد:
| فیلد | نوع | مقدار پیشفرض | توضیح |
|---|---|---|---|
loglevel | string | "INFO" | پایینترین سطحی که این logger ثبت میکند. |
file | string | مختص همان logger | نام فایلی که به log.path افزوده میشود. |
console | boolean | true | خروجی این logger در console نیز چاپ شود. |
log.path دایرکتوری پایه برای ساخت مسیر فایلهای log است. مقدار پیشفرض آن
"log/" است. WaterWall در صورت نیاز این دایرکتوری را هنگام راهاندازی میسازد.
مقادیر پیشفرض:
| فیلد | مقدار پیشفرض |
|---|---|
log.path | "log/" |
log.internal.loglevel | "INFO" |
log.internal.file | "internal.log" |
log.internal.console | true |
log.core.loglevel | "INFO" |
log.core.file | "core.log" |
log.core.console | true |
log.network.loglevel | "INFO" |
log.network.file | "network.log" |
log.network.console | true |
log.dns.loglevel | "INFO" |
log.dns.file | "dns.log" |
log.dns.console | true |
سطحهای قابلقبول برای log:
VERBOSE, DEBUG, INFO, WARN, ERROR, FATAL, SILENT
logger پیش از اعمال مقدار، آن را به حروف بزرگ تبدیل میکند؛ بنابراین در این لایه
"debug" و "DEBUG" تفاوتی ندارند.
برای نمایش همهی سطحهای log در یک اجرا، گزینهی --verbose را اضافه کنید:
./WaterWall --verbose
./WaterWall --verbose --config:/etc/waterwall/core.json
شکلهای معادل این گزینه --log، -log، -verbose، --showlog، -showlog و
--debug-log هستند. در هر اجرا فقط یکی از این شکلها را مشخص کنید.
این گزینه خروجی console را فعال میکند و سطح loggerهای internal، core،
network و dns را روی VERBOSE قرار میدهد؛ بنابراین تنظیمات loglevel و
console حتی در حالت SILENT بازنویسی میشوند. فایلهای log فعال نیز پیامهای
اضافی را دریافت میکنند. مسیر فایلها و غیرفعالبودن خروجی فایل همچنان از config
پیروی میکنند. این تغییر پیش از مقداردهی اولیهی loggerها فقط در حافظه اعمال
میشود و فایل core.json را تغییر نمیدهد. گزینهی -v همچنان نسخه را چاپ میکند.
گزینهی --verbose را فقط یک بار مشخص کنید؛ ترکیب آن با درخواست نمایش نسخه یا
بازیابی Windows مجاز نیست.
نمونه:
{
"log": {
"path": "logs/",
"internal": {
"loglevel": "INFO",
"file": "internal.log",
"console": false
},
"core": {
"loglevel": "INFO",
"file": "core.log",
"console": true
},
"network": {
"loglevel": "WARN",
"file": "network.log",
"console": true
},
"dns": {
"loglevel": "DEBUG",
"file": "dns.log",
"console": true
}
}
}
پیشنهادهای عملی:
| موقعیت | پیشنهاد |
|---|---|
| نصب اولیه یا debug | خروجی console برای core، network و dns را فعال نگه دارید. |
| محیط production با اتصالهای زیاد | برای network از INFO یا WARN استفاده کنید؛ سطحهای پرحجم را فقط هنگام debug فعال کنید. |
| عیبیابی DNS | موقتاً log.dns.loglevel را روی "DEBUG" بگذارید. |
| سرویس بلندمدت | حتی اگر خروجی console غیرفعال است، ثبت log در فایل را فعال نگه دارید. |
misc
بخش misc اندازهی منابع runtime و نحوهی load libraryها را در سطح process
کنترل میکند.
{
"misc": {
"workers": 4,
"ram-profile": "server",
"mtu": 1500,
"tcp-tune": true,
"try-enabling-bbr": true,
"libs-path": "libs/"
}
}
| فیلد | نوع | مقدار پیشفرض | اعتبارسنجی و رفتار |
|---|---|---|---|
workers | integer | تعداد هستههای CPU | مقدار 0 یا منفی به تعداد هستههای CPU برمیگردد. مقادیر بیشتر از 254 به 254 کاهش مییابند. |
ram-profile | string یا integer | "server" | اندازهی memory poolها و پیشفرض nodeهای وابسته به پروفایل را انتخاب میکند. عدد باید یک عدد صحیح در بازهی 0..6 باشد. مقدار نامعتبر راهاندازی را متوقف میکند. |
mtu | integer | 1500 | مقدار سراسری MTU که تونلهای بدون مقدار اختصاصی آن را به ارث میبرند. باید یک عدد صحیح در بازهی 68..65535 باشد. مقدار نامعتبر راهاندازی را متوقف میکند. |
tcp-tune | boolean | true در Linux؛ در بقیهی سیستمها false | تنظیم هنگام راهاندازی هسته با سقف ثابت 128 MiB برای socket و تنظیم خودکار bufferهای TCP. |
try-enabling-bbr | boolean | true | فقط در Linux: اگر kernel از BBR پشتیبانی کند، WaterWall تلاش میکند TCP BBR را فعال کند؛ موفقیت این کار تضمینشده نیست. |
libs-path | string | "libs/" | دایرکتوری load libraryهای خارجی تونل. |
مقادیر پیشفرض بالا در هر سه حالت اعمال میشوند: چه misc موجود باشد، چه خالی و
چه بهکلی حذف شده باشد - از جمله mtu و ram-profile که پیشتر با حذف این بخش
بدون مقدار میماندند. مقدار نامعتبر هرگز با پیشفرض جایگزین نمیشود؛ برنامه با
خطایی که نام همان فیلد را نشان میدهد متوقف میشود. با این حال برای رفتار قابلپیشبینی بهتر است کل بخش
misc را صریح بنویسید.
workers
گزینهی workers تعداد worker threadهایی را مشخص میکند که WaterWall میسازد.
| نوع استفاده | نقطهی شروع مناسب |
|---|---|
| client کوچک یا محیط تست | 1 یا 2 |
| VPS عمومی | برابر با تعداد هستههای CPU |
| سرور پرترافیک | ابتدا تعداد هستههای CPU؛ سپس تنظیم بر اساس معیارهای CPU و latency |
worker بیشتر همیشه بهتر نیست. هر worker یک event loop و بخشی از منابع مختص خود
را دارد. مقادیر بسیار بزرگ به 254 محدود میشوند.
ram-profile
مقادیر string:
| مقدار | پروفایل داخلی | کاربرد معمول |
|---|---|---|
"server" | پروفایل حافظهی L2 | پروفایل پیشفرض سمت server با poolهای بزرگتر. |
"client" | پروفایل حافظهی M1 | پروفایل عمومی سمت client. |
"client-larger" | پروفایل حافظهی M2 | پروفایل بزرگتر سمت client. |
"minimal" | پروفایل حافظهی S1 | پروفایل با حداقل مصرف حافظه. |
"ultralow" | پروفایل حافظهی S1 | نام مستعار "minimal". |
parser پیش از تطبیق، مقدار string را به حروف کوچک تبدیل میکند. در configهای جدید بهتر است از مقدارهای string استفاده کنید.
مقادیر integer قدیمی نیز همچنان پذیرفته میشوند:
| مقدار | پروفایل |
|---|---|
0 یا 1 | پروفایل حافظهی S1 |
2 | پروفایل حافظهی S2 |
3 | پروفایل حافظهی M1 |
4 | پروفایل حافظهی M2 |
5 | پروفایل حافظهی L1 |
6 | پروفایل حافظهی L2 |
این پروفایل پیشفرض بعضی تنظیمات حساس به حافظه را نیز انتخاب میکند. بهطور مشخص، اگر
detached-buffer-limit و detached-child-limit در MuxClient یا MuxServer نوشته نشوند، مقدار آنها از حداقل S1
تا حداکثر L2 افزایش مییابد؛ تنظیم صریح node همچنان اولویت دارد. مقدار دقیق هر پروفایل در راهنمای nodeهای Mux آمده است.
هر مقدار عددی یا string نامعتبر، راهاندازی را متوقف میکند.
mtu
misc.mtu فقط پیشفرض زمان ساخت nodeهاست. هر node مقدار خود را اعتبارسنجی و ثابت
ذخیره میکند؛ override یک node، هسته یا nodeهای دیگر را تغییر نمیدهد. این مقدار
MTU اجباری مشترک همهٔ nodeها یا اندازهگیری MTU مسیر نیست.
مگر آنکه توپولوژی شما مقدار دیگری لازم داشته باشد، از 1500 استفاده کنید.
تونلهای packet، دستگاههای TUN، لایههای encapsulation و chainهای شبیه VPN ممکن
است برای جلوگیری از fragmentation به MTU مؤثر کوچکتری نیاز داشته باشند.
parser مقدار را بهصورت عدد صحیح در بازهی 68..65535 اعتبارسنجی میکند: 68
حداقل MTU برای IPv4 در RFC 791 است و 65535 بزرگترین مقداری است که این فیلد
میتواند نگه دارد. مقدار خارج از بازه، کسری یا از نوع نادرست راهاندازی را متوقف
میکند و با پیشفرض جایگزین نمیشود.
splice
مقدار پیشفرض splice برابر true است؛ مقدار false مسیر عادی TCP را فعال
میکند. splice فقط در پلتفرمها و chainهایی استفاده میشود که همهٔ نودهای آن
از این قابلیت پشتیبانی کنند.
در Linux پشتیبانیشده، WaterWall هنگام راهاندازی تلاش میکند مقدار
fs.pipe-user-pages-soft را تا بودجهٔ 512 MiB، تبدیلشده به تعداد pageهای سیستم،
افزایش دهد. اگر fs.pipe-user-pages-hard غیرصفر باشد، هدف از آن بیشتر نمیشود.
این تنظیمها مصرف مجموع pipeهای هر کاربر را در سطح سیستم محدود میکنند.
مقدار soft نامحدود (0) یا بزرگتر از هدف حفظ میشود. شکست این تنظیم مانع
راهاندازی نیست؛ مقدار hard و fs.pipe-max-size تغییر نمیکنند و تنظیم دائمی
نوشته نمیشود. افزایش موفق پس از خروج برنامه هم باقی میماند.
پس از نهاییشدن chainهای همهٔ configهای راهاندازی و پیش از اجرای hookهای
prepare/start یا آغاز تولید داده، bufferهای کامل splice با padding ثابتِ
برابر با بیشترین نیاز chainها و pipeهای با ظرفیت کامل 1 MiB ساخته میشوند.
سقف مجموع ظرفیت برای فرایند 512 MiB است. تعداد pipeها از
floor((RLIMIT_NOFILE.soft - open_descriptors) / 8) هم
بیشتر نمیشود؛ هر pipe دو descriptor دارد و بنابراین این مجموعه حداکثر
یکچهارم سهم باقیماندهٔ descriptorهای فرایند را مصرف میکند و باقی را برای
منابع config و runtime نگه میدارد. شمارش از /proc/self/fd بهصورت محافظهکارانه descriptor موقت خودِ شمارش را هم شامل
میشود؛ اگر حد یا شمارش در دسترس نباشد، مجموعه خالی میماند. محدودیتهای kernel
و خطای تخصیص ممکن است تعداد واقعی را کمتر کنند. تعداد و ظرفیت واقعی در log
راهاندازی ثبت میشود. این بودجهٔ ظرفیت pipe است و به معنی رزرو 512 MiB حافظهٔ
فیزیکی برای payload نیست.
هر worker حداکثر هشت buffer خالی splice را در cache محلی نگه میدارد.
اگر cache خالی باشد، از masterpool مشترک buffer میگیرد. اگر هر دو خالی
باشند، درخواست مقدار NULL برمیگرداند و caller معمولاً از buffer عادی
استفاده میکند، حتی اگر cache مربوط به worker دیگری هنوز pipe آزاد داشته
باشد. pipeهای سالم تا shutdown حفظ میشوند؛ هنگام ترافیک pipe تازه ساخته
یا بزرگ نمیشود و pipe کوچکتر هم پذیرفته نمیشود. pipe غیرقابلاستفاده بدون
جایگزین کنار گذاشته میشود.
splice: false هم تنظیم محدودیت pipe و هم ساخت این مجموعه را غیرفعال میکند.
tcp-tune
این گزینه در Linux بومی بهصورت پیشفرض true است و در سیستمهای دیگر، از جمله
Android و Cygwin، false است. این پیشفرض برای misc خالی یا حذفشده هم اعمال
میشود. فقط boolean پذیرفته میشود. مقدار false این مرحلهی راهاندازی هسته را
غیرفعال میکند؛ این گزینه مستقل از splice و try-enabling-bbr است. مقدار صریح
true در سیستمهای دیگر پذیرفته میشود، ولی هیچ تنظیمی انجام نمیدهد.
پس از آمادهشدن logهای runtime و پیش از بارگذاری config نودها، WaterWall دقیقاً چهار مقدار ثابت زیر را مستقل از پروفایل حافظه اعمال میکند:
| تنظیم | مقدار |
|---|---|
net.core.rmem_max | 134217728 (128 MiB) |
net.core.wmem_max | 134217728 (128 MiB) |
net.ipv4.tcp_rmem | 4096 87380 134217728 |
net.ipv4.tcp_wmem | 4096 87380 134217728 |
این مرحله net.core.netdev_max_backlog و net.core.somaxconn را تغییر نمیدهد.
وجود MuxClient یا MuxServer در chain باعث میشود نودهای TcpListener و TcpConnector
برای گزینههای حذفشدهی ارسال و دریافت، اندازهی 16 MiB را صریحاً درخواست کنند؛
این رفتار مستقل از tcp-tune و موفقیت اجرای sysctl است. در نبود Mux، گزینههای
حذفشده به kernel واگذار میشوند.
مقادیر صریح large-send-buffer و large-recv-buffer، از جمله تنظیمات هر مقصد
TcpConnector، در هر دو حالت اولویت دارند.
اگر اجرای دستوری ناموفق باشد، یک warning ثبت میشود و اجرای بقیهی دستورها ادامه پیدا میکند.
نداشتن مجوز یا نبودن sysctl راهاندازی را متوقف نمیکند. تغییرات موفق در تنظیمات
زندهی kernel اعمال میشوند و پس از خروج برگردانده نمیشوند؛ WaterWall آنها را
در /etc/sysctl.conf ذخیره نمیکند.
RawSocket مرحلهی تنظیم جداگانهای با گزینهی skip-sysctl برای backlogها و سایر
پارامترهای TCP دارد. نوشتن چهار تنظیم buffer بالا فقط در مرحلهی راهاندازی هسته
با tcp-tune انجام میشود.
try-enabling-bbr
وقتی این گزینه در Linux برابر true باشد، WaterWall الگوریتم فعلی کنترل ازدحام
TCP و مقدار net.ipv4.tcp_available_congestion_control را بررسی میکند. اگر kernel
در حال اجرا bbr را در فهرست پشتیبانیشده داشته باشد و BBR از قبل فعال نباشد،
WaterWall مقادیر فعلی sysctl را برای net.core.default_qdisc=fq و
net.ipv4.tcp_congestion_control=bbr اعمال میکند.
این فقط تلاشی برای تنظیم بهتر سیستم هنگام راهاندازی است و موفقیت آن تضمینشده
نیست. WaterWall نه kernel نصب میکند و نه /etc/sysctl.conf را تغییر میدهد. اگر
نمیخواهید تلاش برای فعالسازی BBR انجام شود، این گزینه را روی false بگذارید.
گزینهی tcp-tune مرحلهی جداگانهی تنظیم مقادیر ثابت bufferهای socket و TCP را کنترل میکند.
libs-path
libs-path دایرکتوری libraryهای خارجی تونل را مشخص میکند.
در بیشتر راهاندازیها از nodeهای داخلی استفاده میشود و این مقدار را میتوان بدون تغییر گذاشت:
{
"misc": {
"libs-path": "libs/"
}
}
فقط زمانی آن را تغییر دهید که عمداً library مربوط به nodeهای خارجی را از دایرکتوری دیگری load میکنید.
dns
بخش dns، resolver مشترک و async مبتنی بر c-ares را که workerهای WaterWall
به کار میبرند تنظیم میکند. همچنین سیاست پیشفرض انتخاب آدرس domain برای nodeهای
connector در همین بخش تعیین میشود.
اگر dns حذف شده یا خالی باشد:
| تنظیم | مقدار پیشفرض |
|---|---|
| گزینههای resolver | مقادیر پیشفرض c-ares در WaterWall |
dns.domain-strategy | "prefer-ipv4" |
timeout-ms | 1000 |
max-timeout-ms | 5000 |
tries | 2 |
query-cache-max-ttl | 1800 |
server-failover.retry-chance | 10 |
server-failover.retry-delay-ms | 5000 |
سایر گزینههای رفتاری DNS فقط در صورت تعریفشدن به c-ares فرستاده میشوند. در صورت حذف آنها، رفتارشان را c-ares و تنظیمات resolver سیستمعامل تعیین میکند.
dns.domain-strategy
domain-strategy مشخص میکند وقتی DNS رکورد IPv4، IPv6 یا هر دو را برمیگرداند،
WaterWall کدام آدرس را انتخاب کند.
این مقدار پیشفرض هسته برای nodeهایی است که سیاست جداگانهای ندارند.
TcpConnector و UdpConnector میتوانند در settings خود آن را override کنند.
هر مقصد در ورودیهای وزندار TcpConnector.addresses نیز میتواند سیاست مخصوص
خود را داشته باشد.
مقادیر string معتبر:
| مقدار | رفتار |
|---|---|
"prefer-ipv4" | در صورت وجود، نخستین آدرس IPv4 انتخاب میشود؛ در غیر این صورت IPv6 به کار میرود. این مقدار پیشفرض هسته است. |
"prefer-ipv6" | در صورت وجود، نخستین آدرس IPv6 انتخاب میشود؛ در غیر این صورت IPv4 به کار میرود. |
"only-ipv4" | فقط نتیجههای IPv4 پذیرفته میشوند. اگر آدرس IPv4 برنگردد، نتیجه برای آن اتصال قابلاستفاده نیست. |
"only-ipv6" | فقط نتیجههای IPv6 پذیرفته میشوند. اگر آدرس IPv6 برنگردد، نتیجه برای آن اتصال قابلاستفاده نیست. |
"accept-dns-returned-order" | نخستین آدرس قابلاستفاده با همان ترتیبی که DNS برگردانده انتخاب میشود. |
تطبیق stringها به بزرگی و کوچکی حروف حساس نیست.
مقادیر integer قدیمی:
| مقدار | سیاست |
|---|---|
0 | accept-dns-returned-order |
1 | prefer-ipv4 |
2 | prefer-ipv6 |
3 | only-ipv4 |
4 | only-ipv6 |
نمونه:
{
"dns": {
"domain-strategy": "prefer-ipv4"
}
}
راهنمای عملی:
| محیط | سیاست |
|---|---|
| بیشتر VPSهای مبتنی بر IPv4 | "prefer-ipv4" |
| شبکهای که IPv6 در آن اولویت دارد | "prefer-ipv6" |
| سرور یا قواعد firewall مختص IPv4 | "only-ipv4" |
| راهاندازی فقط با IPv6 | "only-ipv6" |
| به ترتیب اعلامشدهی resolver اعتماد دارید | "accept-dns-returned-order" |
زمانبندی و cache مربوط به resolver
| فیلد | نوع | مقدار پیشفرض | اعتبارسنجی | مفهوم |
|---|---|---|---|---|
timeout-ms | integer | 1000 | بزرگتر از 0 | timeout اولیهی query مربوط به DNS بر حسب میلیثانیه. |
max-timeout-ms | integer | 5000 | بزرگتر از 0 | بیشترین timeout برای query مربوط به DNS پس از retryها. |
tries | integer | 2 | بزرگتر از 0 | تعداد دفعات تلاش برای query. |
query-cache-max-ttl | integer | 1800 | 0 یا بیشتر | حداکثر TTL مربوط به DNS cache بر حسب ثانیه. |
نمونه:
{
"dns": {
"timeout-ms": 750,
"max-timeout-ms": 3000,
"tries": 2,
"query-cache-max-ttl": 600
}
}
timeout کوتاهتر باعث میشود شکست resolve شدن domain زودتر مشخص شود، اما در شبکههای کند یا دارای packet loss میتواند قابلیت اطمینان را کاهش دهد. TTL کوتاهتر cache هم باعث میشود تغییرات DNS زودتر دیده شوند، ولی ترافیک resolver را بیشتر میکند.
گزینههای رفتاری resolver
این گزینهها اختیاریاند. اگر حذف شوند، مقادیر پیشفرض c-ares اعمال خواهد شد.
| فیلد | نوع | اعتبارسنجی | مفهوم |
|---|---|---|---|
ndots | integer | از 0 تا 15 | تعداد نقطههای لازم پیش از آنکه c-ares نام را absolute در نظر بگیرد. |
udp-port | integer | از 1 تا 65535 | پورت UDP سرور DNS. |
tcp-port | integer | از 1 تا 65535 | پورت TCP سرور DNS. |
socket-send-buffer-size | integer | بزرگتر از 0 | اندازهی send buffer مربوط به socketِ DNS. |
socket-receive-buffer-size | integer | بزرگتر از 0 | اندازهی receive buffer مربوط به socketِ DNS. |
edns-packet-size | integer | از 1 تا 65535 | اندازهی packet مربوط به EDNS. |
udp-max-queries | integer | 0 یا بیشتر | محدودیت queryهای UDP در c-ares. |
rotate | boolean | مقدار boolean | چرخش میان serverهای c-ares را فعال یا غیرفعال میکند. |
نمونه:
{
"dns": {
"ndots": 1,
"udp-port": 53,
"tcp-port": 53,
"socket-send-buffer-size": 262144,
"socket-receive-buffer-size": 262144,
"edns-packet-size": 1232,
"udp-max-queries": 0,
"rotate": true
}
}
تا وقتی دلیل مشخصی ندارید، این گزینهها را تغییر ندهید. برای بیشتر کاربران،
servers، domain-strategy و گزینههای زمانبندی کافیاند.
گزینههای search و source
| فیلد | نوع | اعتبارسنجی | مفهوم |
|---|---|---|---|
domains | آرایهای از stringها | آرایه و stringها نباید خالی باشند | search domainهایی که به c-ares داده میشوند. |
lookups | string | فقط b و f، بدون کاراکتر تکراری | ترتیب lookup sourceها؛ b یعنی DNS و f یعنی فایل hosts. |
resolvconf-path | string | string غیرخالی | مسیر سفارشی resolv.conf. |
hosts-path | string | string غیرخالی | مسیر سفارشی فایل hosts. |
sortlist | string | string غیرخالی | مقدار sortlist مربوط به c-ares. |
servers | string یا آرایهای از stringها | غیرخالی؛ اعضای آرایه نباید کاما داشته باشند | سرورهای DNS که به c-ares داده میشوند. |
servers میتواند یک string با قالب CSV مورد قبول c-ares یا یک آرایه باشد. اگر
آرایه باشد، WaterWall اعضای آن را پیش از فرستادن به c-ares با کاما به هم متصل
میکند.
نمونه:
{
"dns": {
"servers": [
"1.1.1.1",
"8.8.8.8"
],
"lookups": "bf",
"domains": [
"example.com"
],
"resolvconf-path": "/etc/resolv.conf",
"hosts-path": "/etc/hosts",
"sortlist": "10.0.0.0/8"
}
}
مقادیر lookups:
| مقدار | مفهوم |
|---|---|
"b" | فقط DNS. |
"f" | فقط فایل hosts. |
"bf" | ابتدا DNS و سپس فایل hosts بررسی شود. |
"fb" | ابتدا فایل hosts و سپس DNS بررسی شود. |
sourceهای lookup را تکرار نکنید؛ مقادیر "bb"، "ff" و "bfb" رد میشوند.
dns.flags
flags گزینههای flag پشتیبانیشدهی c-ares را تنظیم میکند و چهار شکل نوشتاری
دارد.
bitmask عددی:
{
"dns": {
"flags": 0
}
}
نام یک flag:
{
"dns": {
"flags": "edns"
}
}
آرایهای از نام flagها:
{
"dns": {
"flags": [
"edns",
"dns0x20"
]
}
}
object با مقدارهای boolean:
{
"dns": {
"flags": {
"edns": true,
"dns0x20": true,
"use-vc": false
}
}
}
در شکل object، مقدار true یک flag را فعال میکند و false آن را غیرفعال باقی
میگذارد.
نام flagهای پشتیبانیشده:
| نام | flag در c-ares |
|---|---|
"usevc" | ARES_FLAG_USEVC |
"use-vc" | ARES_FLAG_USEVC |
"tcp" | ARES_FLAG_USEVC |
"primary" | ARES_FLAG_PRIMARY |
"igntc" | ARES_FLAG_IGNTC |
"ignore-truncated" | ARES_FLAG_IGNTC |
"norecurse" | ARES_FLAG_NORECURSE |
"no-recurse" | ARES_FLAG_NORECURSE |
"stayopen" | ARES_FLAG_STAYOPEN |
"stay-open" | ARES_FLAG_STAYOPEN |
"no-search" | ARES_FLAG_NOSEARCH |
"no-aliases" | ARES_FLAG_NOALIASES |
"nocheckresp" | ARES_FLAG_NOCHECKRESP |
"no-check-response" | ARES_FLAG_NOCHECKRESP |
"edns" | ARES_FLAG_EDNS |
"no-default-server" | ARES_FLAG_NO_DFLT_SVR |
"no-dflt-svr" | ARES_FLAG_NO_DFLT_SVR |
"dns0x20" | ARES_FLAG_DNS0x20 |
وجود نام ناشناخته برای flag، راهاندازی را متوقف میکند. bitmaskهای عددی نیز فقط میتوانند bitهای پشتیبانیشدهی c-ares را در خود داشته باشند.
dns.server-failover
بخش server-failover گزینههای failover سرور را در c-ares تنظیم میکند.
| فیلد | نوع | مقدار پیشفرض | اعتبارسنجی | مفهوم |
|---|---|---|---|---|
retry-chance | integer | 10 | از 0 تا 65535 | مقدار احتمال retry در c-ares. |
retry-delay-ms | integer | 5000 | 0 یا بیشتر | فاصلهی زمانی تا تلاش دوباره برای سرور DNS ناموفق. |
نمونه:
{
"dns": {
"server-failover": {
"retry-chance": 25,
"retry-delay-ms": 2000
}
}
}
اگر server-failover وجود داشته باشد، باید یک object باشد. فیلدهای داخل آن
اختیاریاند و فیلدهای حذفشده مقدار پیشفرض خود را حفظ میکنند.
نمونهی کامل ساختار
نمونهی زیر همهی بخشهای فعلی مستندشدهی هسته و بیشتر فیلدهای DNS را نشان میدهد. از آن بهعنوان مرجع استفاده کنید، نه توصیهای برای تغییر همهی مقادیر DNS.
{
"log": {
"path": "log/",
"internal": {
"loglevel": "INFO",
"file": "internal.log",
"console": true
},
"core": {
"loglevel": "INFO",
"file": "core.log",
"console": true
},
"network": {
"loglevel": "INFO",
"file": "network.log",
"console": true
},
"dns": {
"loglevel": "INFO",
"file": "dns.log",
"console": true
}
},
"misc": {
"workers": 4,
"ram-profile": "server",
"mtu": 1500,
"try-enabling-bbr": true,
"libs-path": "libs/"
},
"dns": {
"domain-strategy": "prefer-ipv4",
"timeout-ms": 1000,
"max-timeout-ms": 5000,
"tries": 2,
"query-cache-max-ttl": 1800,
"ndots": 1,
"udp-port": 53,
"tcp-port": 53,
"socket-send-buffer-size": 262144,
"socket-receive-buffer-size": 262144,
"edns-packet-size": 1232,
"udp-max-queries": 0,
"flags": [
"edns",
"dns0x20"
],
"rotate": true,
"domains": [
"example.com"
],
"lookups": "bf",
"resolvconf-path": "/etc/resolv.conf",
"hosts-path": "/etc/hosts",
"sortlist": "10.0.0.0/8",
"servers": [
"1.1.1.1",
"8.8.8.8"
],
"server-failover": {
"retry-chance": 10,
"retry-delay-ms": 5000
}
},
"configs": [
"configs/server.json"
]
}
نمونهی حداقلی و کاربردی
برای بیشتر کاربران، شروع با این نمونهی کوچکتر مناسبتر است:
{
"log": {
"path": "logs/",
"core": {
"loglevel": "INFO",
"file": "core.log",
"console": true
},
"network": {
"loglevel": "INFO",
"file": "network.log",
"console": true
},
"dns": {
"loglevel": "INFO",
"file": "dns.log",
"console": true
},
"internal": {
"loglevel": "INFO",
"file": "internal.log",
"console": true
}
},
"misc": {
"workers": 4,
"ram-profile": "server",
"mtu": 1500,
"try-enabling-bbr": true,
"libs-path": "libs/"
},
"dns": {
"domain-strategy": "prefer-ipv4"
},
"configs": [
"configs/server.json"
]
}
نمونهی تنظیمشده برای DNS
اگر میخواهید سرورهای DNS را صریحاً مشخص کنید و رفتار resolver را سریعتر عیبیابی کنید، نمونهی زیر نقطهی شروع مناسبی است:
{
"log": {
"path": "logs/",
"core": {
"loglevel": "INFO",
"file": "core.log",
"console": true
},
"network": {
"loglevel": "WARN",
"file": "network.log",
"console": false
},
"dns": {
"loglevel": "DEBUG",
"file": "dns.log",
"console": true
},
"internal": {
"loglevel": "INFO",
"file": "internal.log",
"console": false
}
},
"misc": {
"workers": 8,
"ram-profile": "client-larger",
"mtu": 1500,
"try-enabling-bbr": true,
"libs-path": "libs/"
},
"dns": {
"domain-strategy": "prefer-ipv4",
"servers": [
"1.1.1.1",
"8.8.8.8"
],
"timeout-ms": 1000,
"max-timeout-ms": 5000,
"tries": 2,
"query-cache-max-ttl": 600,
"lookups": "bf",
"flags": [
"edns",
"dns0x20"
],
"rotate": true,
"server-failover": {
"retry-chance": 10,
"retry-delay-ms": 5000
}
},
"configs": [
"configs/server.json",
"configs/reverse.json"
]
}
خطاهای رایج هنگام راهاندازی
| اشتباه | نتیجه | راهحل |
|---|---|---|
در core.json از commentهای // استفاده شده است | خطای parse در JSON | commentها را از core.json حذف کنید. |
configs وجود ندارد یا خالی است | راهاندازی متوقف میشود | مسیر دستکم یک فایل config را اضافه کنید. |
مسیر موجود در configs نسبت به دایرکتوری دیگری نوشته شده است | فایل config خوانده نمیشود | WaterWall را از working directory موردنظر اجرا کنید یا مسیرها را اصلاح کنید. |
domain-strategy در ریشه قرار دارد | راهاندازی متوقف میشود | آن را به dns.domain-strategy منتقل کنید. |
dns یک object نیست | راهاندازی متوقف میشود | برای dns از object استفاده کنید یا آن را حذف کنید. |
dns.flags نام ناشناختهای دارد | راهاندازی متوقف میشود | یکی از نامهای مستندشده را به کار ببرید. |
در misc.ram-profile اشتباه تایپی وجود دارد | راهاندازی متوقف میشود | از server، client، client-larger، minimal یا ultralow استفاده کنید. |
| تعداد workerها بیشازحد زیاد است | مقدار به 254 کاهش مییابد | تعداد واقعبینانهای برای workerها انتخاب کنید. |
ابتدا چه چیزهایی را تنظیم کنیم؟
در شروع، فقط روی این موارد تمرکز کنید:
| هدف | فیلد |
|---|---|
| اجرای chainهای درست | configs |
| کنترل مصرف CPU | misc.workers |
| انتخاب رفتار حافظه برای server یا client | misc.ram-profile |
| داشتن logهای کاربردی | log.network.loglevel، log.dns.loglevel |
| اولویتدادن به IPv4 یا IPv6 | dns.domain-strategy |
| استفاده از resolverهای مشخص | dns.servers |
تا زمانی که دلیل مشخصی برای تغییر گزینههای پیشرفتهی DNS ندارید، آنها را به حال خود بگذارید. مقادیر پیشفرض عمداً برای کاربردهای معمول محافظهکارانه انتخاب شدهاند.