update-geodata.sh теперь ходит по списку SOURCES (строка «URL-базы|имя»), а не по одной базе: ipcheck.dat и оба discord-.dat обновляются за один запуск и с одним перезапуском сервиса. Старый вызов с DEST продолжает работать — каталог берётся из него. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
16 KiB
discord-geodata
Домены и сети Discord, собранные в geosite.dat и geoip.dat для Xray/3x-ui —
плюс те же списки в форматах sing-box, Clash/mihomo, AdGuard и обычным текстом.
Списки не выдумываются: рукописная база лежит в data/discord-base.txt и
data/ip/discord-base.txt, всё остальное tools/sync.py тянет из публичных
апстримов (см. Апстримы) и раскладывает по отдельным категориям.
Категории
Домены (geosite.dat):
| Категория | Что внутри |
|---|---|
discord |
всё вместе — то, что обычно и нужно в роутинге |
discord-base |
рукописный список: домены Discord и его проектов |
discord-metacubex |
из MetaCubeX meta-rules-dat |
discord-itdoginfo |
из itdoginfo/allow-domains |
discord-youoops |
из you-oops-dev/ipranges-singbox, включая имена голосовых узлов |
Сети (geoip.dat):
| Категория | Что внутри | Ограничения |
|---|---|---|
discord |
все безусловные списки вместе | — |
discord-base |
адреса, снятые резолвом доменов | — |
discord-legiz |
адреса голосовых узлов (legiz-ru/sb-rule-sets) | — |
discord-youoops |
диапазоны сетей (you-oops-dev/ipranges-singbox) | — |
discord-vernette-udp |
голосовой трафик (vernette/rulesets) | udp, порты 50000-50099 |
discord-itdoginfo-udp-* |
голосовой трафик (itdoginfo) | udp, свои диапазоны портов |
Категории с ограничениями по протоколу и портам не входят в сводную
discord: там широкие сети вроде 172.64.0.0/13 и 162.158.0.0/15, то есть
пол-Cloudflare. Без ограничения по UDP-портам такое правило утащило бы в туннель
кучу чужого трафика. Точные счётчики по каждой категории — в metadata.json.
Скачать
Ветка release — распакованный dist/, релизы — те же файлы архивом:
https://gitea.hsrv.site/mrleo1nid/discord-geodata/raw/branch/release/<файл>
| Файл | Для чего |
|---|---|
discord-geosite.dat |
Xray / v2ray / 3x-ui — домены, кладётся рядом со штатным geosite.dat |
discord-geoip.dat |
то же для сетей, рядом со штатным geoip.dat |
geosite.dat, geoip.dat |
те же данные под именами по умолчанию — если хотите заменить штатные файлы |
*.dat.sha256sum |
контрольные суммы, по ним работает автообновление |
xray/routing.json |
готовый фрагмент routing со всеми правилами |
update-geodata.sh |
скрипт обновления для cron (см. ниже) |
sing-box/site/<категория>.json, .srs |
sing-box, домены: исходный и скомпилированный rule-set |
sing-box/ip/<категория>.json, .srs |
sing-box, сети — здесь же живут network и port_range |
mihomo/site/<категория>.mrs, mihomo/ip/<категория>.mrs |
mihomo, бинарные rule-provider |
clash/site/<категория>.yaml, .list |
Clash/mihomo, behavior: domain и classical |
clash/ip/<категория>.yaml, .list |
Clash/mihomo, behavior: ipcidr и classical |
txt/site/<категория>.txt, txt/ip/<категория>.txt |
просто домены и сети, по одной на строку |
json/… |
структурированные списки с типами правил и ограничениями |
adguard/<категория>.txt |
AdGuard Home / uBlock — если нужно блокировать, а не роутить |
metadata.json, SHA256SUMS |
время сборки, счётчики, суммы по всем файлам |
3x-ui
Положите оба файла рядом с бинарём (обычно /usr/local/x-ui/bin):
cd /usr/local/x-ui/bin
base=https://gitea.hsrv.site/mrleo1nid/discord-geodata/raw/branch/release
curl -fsSLO "$base/discord-geosite.dat"
curl -fsSLO "$base/discord-geoip.dat"
x-ui restart
Дальше в панели: Настройки → Xray → Маршруты (или прямо в JSON-конфиге).
Готовые правила лежат в xray/routing.json, менять там нужно только
outboundTag:
{
"type": "field",
"domain": ["ext:discord-geosite.dat:discord"],
"outboundTag": "proxy"
},
{
"type": "field",
"ip": ["ext:discord-geoip.dat:discord"],
"outboundTag": "proxy"
},
{
"type": "field",
"network": "udp",
"port": "50000-50099",
"ip": ["ext:discord-geoip.dat:discord-vernette-udp"],
"outboundTag": "proxy"
}
ext:<файл>:<тег> работает и для domain, и для ip — файл ищется в
XRAY_LOCATION_ASSET (по умолчанию каталог с бинарём). Тег — имя категории,
регистр не важен.
Порядок правил — это приоритет: Xray берёт первое подошедшее, поэтому ограниченные по портам правила идут последними, чтобы более общие не перехватывали их раньше.
Автообновление на сервере
update-geodata.sh качает файлы, только если их sha256 разошлись с
удалёнными, проверяет сумму до подмены и перезапускает сервис один раз —
и только если что-то реально изменилось.
base=https://gitea.hsrv.site/mrleo1nid/discord-geodata/raw/branch/release
curl -fsSLo /usr/local/bin/update-geodata.sh "$base/update-geodata.sh"
chmod +x /usr/local/bin/update-geodata.sh
RESTART_CMD='x-ui restart' /usr/local/bin/update-geodata.sh
cron раз в сутки:
23 4 * * * RESTART_CMD='x-ui restart' /usr/local/bin/update-geodata.sh >> /var/log/discord-geodata.log 2>&1
Скрипт умеет тянуть файлы из нескольких репозиториев сразу — один cron-job
вместо двух. По умолчанию это ipcheck.dat из
ipcheck-domains и оба
.dat отсюда; перезапуск при этом один на все файлы.
| Переменная | По умолчанию | Значение |
|---|---|---|
SOURCES |
три строки ниже | что качать, по строке на файл: URL-базы|имя-файла |
BASE_URL |
…/ipcheck-domains/raw/branch/release |
база для строк без | |
DISCORD_URL |
…/discord-geodata/raw/branch/release |
база для файлов этого репозитория |
DEST_DIR |
/usr/local/x-ui/bin |
куда класть файлы |
RESTART_CMD |
пусто | что выполнить после успешного обновления |
TIMEOUT |
30 |
таймаут curl, секунды |
Нужны только файлы Discord — задайте SOURCES явно:
SOURCES='https://gitea.hsrv.site/mrleo1nid/discord-geodata/raw/branch/release|discord-geosite.dat
https://gitea.hsrv.site/mrleo1nid/discord-geodata/raw/branch/release|discord-geoip.dat' \
RESTART_CMD='x-ui restart' /usr/local/bin/update-geodata.sh
Старый вызов с DEST=/путь/файл.dat продолжает работать: каталог берётся из
него, а имя файла подставляется в первую строку SOURCES.
Если 3x-ui в Docker — укажите DEST_DIR на смонтированный каталог и
RESTART_CMD='docker restart 3x-ui'.
sing-box
{
"route": {
"rule_set": [
{
"type": "remote",
"tag": "discord",
"format": "binary",
"url": "https://gitea.hsrv.site/mrleo1nid/discord-geodata/raw/branch/release/sing-box/site/discord.srs"
},
{
"type": "remote",
"tag": "discord-ip",
"format": "binary",
"url": "https://gitea.hsrv.site/mrleo1nid/discord-geodata/raw/branch/release/sing-box/ip/discord.srs"
},
{
"type": "remote",
"tag": "discord-voice",
"format": "binary",
"url": "https://gitea.hsrv.site/mrleo1nid/discord-geodata/raw/branch/release/sing-box/ip/discord-vernette-udp.srs"
}
],
"rules": [{"rule_set": ["discord", "discord-ip", "discord-voice"], "outbound": "proxy"}]
}
}
network и port_range зашиты внутрь самого rule-set — отдельно в правиле их
указывать не нужно.
Clash / mihomo
rule-providers:
discord:
type: http
behavior: domain
format: yaml
url: https://gitea.hsrv.site/mrleo1nid/discord-geodata/raw/branch/release/clash/site/discord.yaml
path: ./providers/discord.yaml
interval: 86400
discord-ip:
type: http
behavior: ipcidr
format: yaml
url: https://gitea.hsrv.site/mrleo1nid/discord-geodata/raw/branch/release/clash/ip/discord.yaml
path: ./providers/discord-ip.yaml
interval: 86400
rules:
- RULE-SET,discord,PROXY
- RULE-SET,discord-ip,PROXY
Ограничения по протоколу и портам в форматы Clash не переносятся — в шапке таких файлов об этом написано прямо. Нужен голосовой трафик с портами — берите sing-box или Xray.
Апстримы
tools/sources.json — список источников, tools/sync.py их синхронизирует:
| Источник | Что берём |
|---|---|
| MetaCubeX/meta-rules-dat | домены |
| itdoginfo/allow-domains | домены и голосовые сети с портами |
| you-oops-dev/ipranges-singbox | сети и имена голосовых узлов |
| legiz-ru/sb-rule-sets | адреса голосовых узлов |
| vernette/rulesets | голосовой трафик UDP 50000-50099 |
python3 tools/sync.py # синхронизировать всё
python3 tools/sync.py --only legiz # только один источник
python3 tools/sync.py --strict # падать, если хоть один источник недоступен
Что происходит внутри:
- каждый источник кладётся в свой файл
data/discord-<источник>.txt— так видно, кто что принёс, и можно выключить конкретный список; - правила с
network/port_rangeуезжают в отдельную категорию с директивами!networkи!portв шапке; если у источника таких наборов несколько, в имя добавляются порты (discord-itdoginfo-udp-19000-20000); - сводные
data/discord.txtиdata/ip/discord.txtпересобираются как списокinclude:— руками их править бесполезно; - недоступный источник не обнуляет свой файл: остаются прежние данные и печатается предупреждение. Устаревший список лучше пустого;
- источники в формате
.srsскомпилированы, для них нужен бинарьsing-box(tools/fetch-tools.shего ставит). Без него они просто пропускаются.
Файлы, которые пишет sync.py, помечены шапкой # GENERATED — файл без такой
шапки скрипт не тронет. Поэтому рукописный discord-base.txt в безопасности.
Как добавить домен или сеть руками
Правьте data/discord-base.txt (домены) и data/ip/discord-base.txt (сети) —
они попадут в сводные категории автоматически.
Формат доменного файла: example.com — суффикс (сам домен и все поддомены),
full:example.com — точное совпадение, keyword:, regexp:, include:другая-категория.
Атрибуты — через @: example.com @ads.
Формат IP-файла: 1.2.3.4 или 1.2.3.0/24 (IPv6 тоже), include:, и директивы
в шапке:
!network: udp
!port: 50000-50099
Ограничения действуют на весь файл. include: разрешён только между
категориями с одинаковыми ограничениями, иначе сборка упадёт: так не выйдет
случайно снять «только UDP на голосовых портах» с половины Cloudflare.
Дальше:
python3 tools/build.py --check
--check ругается на дубликаты, на домены, уже покрытые суффиксом, на сети,
вложенные в другие сети того же файла, на циклы в include и на конфликт
ограничений.
Локальная сборка
python3 tools/build.py --check # проверить исходники
python3 tools/build.py # собрать dist/
python3 -m unittest discover -s tools -t tools
Зависимостей нет — только стандартная библиотека Python 3.10+. Для .srs и
.mrs нужны бинарники sing-box и mihomo; без них сборка проходит, просто эти
файлы не появляются:
sh tools/fetch-tools.sh ./bin && export PATH="$PWD/bin:$PATH"
Полезные флаги: --out <каталог>, --sing-box <путь>, --mihomo <путь>,
--outbound <тег> (какой outboundTag подставить в xray/routing.json).
Сборка детерминирована: одни и те же данные дают побайтово одинаковый .dat.
Оба файла после записи читаются обратно и сверяются с исходными правилами.
CI
.gitea/workflows/build.yml на каждый push в main, на PR и ежедневно по cron:
ставит внешние инструменты, синхронизирует апстримы, проверяет исходники,
гоняет тесты, собирает dist/, скармливает оба .dat настоящему Xray и
проверяет, что в скомпилированных .srs доехали протокол и порты. После этого
коммитит обновлённый data/ обратно в main, обновляет ветку release и
публикует релиз.
Если автокоммит в main не нужен — удалите шаг «Обновление data/ в main»:
сборка от этого не сломается, просто списки в репозитории останутся прежними.
Лицензия
MIT — см. LICENSE. Списки собраны из публичных источников, перечисленных выше; лицензии апстримов смотрите в их репозиториях.