پرش به محتوا
آرش حاتمی

hatamiarash7/ adguard-dns-rewriter

سال توسعه: ۱۴۰۵ متن‌باز

افزودن گروهی قوانین DNS Rewrite در AdGuard Home

ابزاری پایتونی برای افزودن قوانین بازنویسی DNS از روی فهرست دامنه‌ها به AdGuard Home، با پوشش زیردامنه‌ها، تشخیص قوانین موجود و پیش‌نمایش تغییرات.

وقتی می‌خواهید تعداد زیادی دامنه در شبکهٔ شما به یک IP مشخص پاسخ داده شوند، وارد کردن تک‌تک قوانین در پنل AdGuard Home زمان‌بر می‌شود. پروژهٔ AdGuard DNS Rewriter این کار را از روی یک فهرست متنی انجام می‌دهد: دامنه‌ها را دریافت می‌کند، قوانین موجود را می‌خواند و فقط موارد جاافتاده را اضافه می‌کند.

این ابزار با Python نوشته شده و از کتابخانهٔ Requests برای ارتباط با API مدیریتی AdGuard Home استفاده می‌کند. برای هر دامنهٔ معمولی، یک قانون wildcard هم می‌سازد؛ مثلاً example.com و *.example.com هر دو به IP مقصد تنظیم‌شده اشاره می‌کنند.

امکانات و نحوهٔ کار

  • دریافت فهرست دامنه‌ها از یک URL، با پشتیبانی از فهرست ساده و خطوط مشابه فایل hosts.
  • حذف موارد تکراری، یکسان‌سازی حروف بزرگ و کوچک و نادیده گرفتن خطوط خالی و توضیحات.
  • کنار گذاشتن ورودی‌های نامعتبر مانند URL کامل، IP تنها و نام تک‌بخشی مثل localhost، همراه با ثبت هشدار.
  • مقایسه با قوانین موجود برای همان IP مقصد؛ اجرای دوباره، قوانین یکسان موجود را دوباره اضافه نمی‌کند.
  • پیش‌نمایش قوانین جدید با حالت dry-run و افزودن موازی آن‌ها با تعداد worker قابل تنظیم.

طبق پیاده‌سازی برنامه، ابتدا فهرست دامنه‌ها دانلود می‌شود، سپس ابزار از مسیر /control/login وارد AdGuard Home می‌شود و قوانین را از /control/rewrite/list می‌خواند. در پایان، موارد جدید را به /control/rewrite/add می‌فرستد.

مقایسه بر اساس دامنه و IP مقصد است. اگر دامنه‌ای از قبل به IP دیگری اشاره کند، آن قانون تغییر نمی‌کند؛ ابزار برای IP جدید درخواست افزودن قانون می‌فرستد. همچنین حذف یک دامنه از فهرست ورودی، قانون قبلی آن را از AdGuard Home پاک نمی‌کند. بنابراین این ابزار برای افزودن تدریجی قوانین است و همگام‌سازی همراه با حذف یا جایگزینی انجام نمی‌دهد.

نصب

به Python نسخهٔ ۳٫۱۰ یا جدیدتر، Git، Make و پشتیبانی از venv و pip نیاز دارید. یک نمونهٔ AdGuard Home با API مدیریتی در دسترس و اطلاعات ورود معتبر نیز باید آماده باشد. دستورهای زیر برای محیط لینوکسی هستند:

git clone https://github.com/hatamiarash7/adguard-dns-rewriter.git
cd adguard-dns-rewriter
python3 -m venv .venv
make install PYTHON=.venv/bin/python
cp .env.example .env

هدف make install وابستگی‌های ثبت‌شده در requirements.txt را نصب می‌کند. با تعیین PYTHON، نصب و اجرای برنامه از همان محیط مجازی انجام می‌شود و نیازی به فعال کردن آن در شل نیست.

تنظیم اتصال و مقصد بازنویسی

فایل .env را مطابق محیط خود ویرایش کنید. مقادیر زیر صرفاً نمونه‌اند؛ آدرس سرویس، نام کاربری، رمز عبور، IP مقصد و URL فهرست را با مقادیر واقعی خود جایگزین کنید:

ADGUARD_URL=https://adguard.example.com
ADGUARD_USER=admin
ADGUARD_PASS=replace-with-your-password
REWRITE_IP=192.0.2.10
DOMAINS_URL=https://example.com/domains.txt
DRY_RUN=false
WORKERS=10
LOG_LEVEL=INFO

پنج متغیر اول الزامی‌اند. ADGUARD_URL آدرس پایهٔ سرویس است؛ مسیرهای /control/... را خود برنامه به آن اضافه می‌کند. REWRITE_IP باید یک آدرس معتبر IPv4 یا IPv6 باشد و همهٔ دامنه‌های این اجرا به همان مقصد بازنویسی می‌شوند. DOMAINS_URL هم باید به محتوای متنی فهرست اشاره کند، نه صفحهٔ HTML نمایش فایل.

تنظیمات اختیاری مطابق راهنمای مخزن عبارت‌اند از:

متغیر مقدار پیش‌فرض کاربرد
DRY_RUN false با مقدار true، تغییرات فقط گزارش می‌شوند.
WORKERS 10 تعداد workerهای افزودن موازی؛ باید عدد صحیح حداقل ۱ باشد.
LOG_LEVEL INFO سطح گزارش‌ها؛ مقادیر مستند شامل DEBUG، INFO، WARNING و ERROR هستند.

فایل .env را Makefile پروژه با include می‌خواند؛ خود main.py فایل dotenv را بارگذاری نمی‌کند. خطوط را به شکل سادهٔ KEY=value نگه دارید و به قواعد Make برای نویسه‌هایی مثل # و $ توجه کنید. اگر متغیرها را مستقیماً از محیط اجرا تأمین می‌کنید، می‌توانید بدون فایل .env برنامه را اجرا کنید:

.venv/bin/python main.py

اطلاعات ورود مدیریتی را در مخزن یا فهرست دامنه‌ها قرار ندهید. برای اتصال از شبکهٔ غیرقابل‌اعتماد، از HTTPS با گواهی معتبر استفاده کنید؛ برنامه نام کاربری و رمز عبور را به API ورود ارسال می‌کند.

قالب فهرست دامنه‌ها

یک فایل متنی در آدرس DOMAINS_URL قرار دهید. برای مثال:

# Internal routing example
example.com
api.example.net
0.0.0.0 service.example.org

در خط آخر، 0.0.0.0 فقط بخشی از قالب hosts است و مقصد بازنویسی را تعیین نمی‌کند؛ مقصد همچنان REWRITE_IP خواهد بود. با تنظیمات نمونه، برای example.com و *.example.com قوانین جداگانه با پاسخ 192.0.2.10 در نظر گرفته می‌شود؛ همین الگو برای دو دامنهٔ دیگر هم اعمال می‌شود.

توضیحات بعد از #، حتی در انتهای خط، حذف می‌شوند. نقطهٔ انتهایی دامنه نیز حذف می‌شود و دامنه‌ها به حروف کوچک تبدیل می‌شوند. در خطوط hosts بهتر است فقط یک نام میزبان بعد از IP بنویسید؛ پیاده‌سازی فعلی در خط چندنامی فقط آخرین نام را برمی‌دارد. همچنین برای ورودی wildcard مانند *.example.com، خود دامنهٔ پایه به‌صورت خودکار اضافه نمی‌شود؛ اگر هر دو را نیاز دارید، دامنهٔ پایه را هم در فهرست قرار دهید.

پیش‌نمایش و اعمال قوانین

ابتدا قوانین پیشنهادی را بررسی کنید:

make dry-run PYTHON=.venv/bin/python

این دستور افزودن قوانین را انجام نمی‌دهد، اما همچنان فهرست را دانلود می‌کند، وارد AdGuard Home می‌شود و قوانین فعلی را می‌خواند. بنابراین برای پیش‌نمایش هم اتصال شبکه و اطلاعات ورود معتبر لازم است.

پس از بررسی دامنه‌ها و IP مقصد، با مقدار DRY_RUN=false در تنظیمات، قوانین را اعمال کنید:

make run PYTHON=.venv/bin/python

گزارش اجرا تعداد قوانین افزوده‌شده، ناموفق و ازپیش‌موجود را نشان می‌دهد. اگر بخشی از درخواست‌ها شکست بخورد، قوانین موفق قبلی باقی می‌مانند؛ برنامه عملیات را به عقب برنمی‌گرداند. اجرای بعدی دوباره وضعیت سرور را می‌خواند و فقط موارد باقی‌مانده را برای افزودن انتخاب می‌کند.

برای استفاده در cron یا ابزارهای خودکارسازی، کد خروج را بررسی کنید: 0 به معنی موفقیت یا نبود تغییر جدید، 1 خطای شبکه یا API یا شکست در افزودن بخشی از قوانین، 2 تنظیمات نامعتبر و 130 توقف با Ctrl-C است. برنامه در هر اجرا یک بار فهرست را پردازش می‌کند؛ زمان‌بندی اجرای دوره‌ای باید بیرون از آن انجام شود.

نکات استفاده

پیش از اعمال یک فهرست بزرگ، منبع آن و پوشش wildcardها را بررسی کنید؛ تمام دامنه‌های پذیرفته‌شده و wildcardهای تولیدشده به یک مقصد مشترک اشاره خواهند کرد. این تنظیم پاسخ DNS را تغییر می‌دهد و به‌تنهایی پراکسی یا ریدایرکت HTTP راه‌اندازی نمی‌کند؛ سرویس مقصد باید برای دامنه‌ها و ارتباط موردنظر شما آماده باشد.

کد پروژه با مجوز MIT منتشر شده است. جزئیات بیشتر دربارهٔ تنظیمات، اهداف Make و توسعه در مستندات مخزن قرار دارد.