Домены и сети Discord в geosite.dat и geoip.dat для Xray/3x-ui, плюс sing-box, Clash/mihomo, AdGuard, текст и готовый фрагмент routing. Рукописная база живёт в data/discord-base.txt и data/ip/discord-base.txt, остальное tools/sync.py тянет из пяти публичных апстримов: JSON-исходники парсятся напрямую, скомпилированные .srs распаковываются через sing-box. Каждый источник кладётся в свою категорию, недоступный источник не обнуляет данные, файлы без шапки GENERATED скрипт не трогает. Ограничения по протоколу и портам (директивы !network / !port) доезжают до sing-box rule-set и до xray/routing.json. Такие категории намеренно не входят в сводную discord: там сети вроде 172.64.0.0/13, и без привязки к UDP-портам правило утащило бы в туннель чужой трафик. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
301 lines
15 KiB
Markdown
301 lines
15 KiB
Markdown
# 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`):
|
||
|
||
```sh
|
||
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`:
|
||
|
||
```json
|
||
{
|
||
"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` качает оба `.dat`, только если их sha256 разошлись с
|
||
удалёнными, проверяет сумму до подмены и перезапускает сервис один раз —
|
||
и только если что-то реально изменилось.
|
||
|
||
```sh
|
||
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 раз в сутки:
|
||
|
||
```cron
|
||
23 4 * * * RESTART_CMD='x-ui restart' /usr/local/bin/update-geodata.sh >> /var/log/discord-geodata.log 2>&1
|
||
```
|
||
|
||
| Переменная | По умолчанию | Значение |
|
||
| --- | --- | --- |
|
||
| `BASE_URL` | `https://gitea.hsrv.site/mrleo1nid/discord-geodata/raw/branch/release` | база, откуда качать |
|
||
| `DEST_DIR` | `/usr/local/x-ui/bin` | куда класть файлы |
|
||
| `NAMES` | `discord-geosite.dat discord-geoip.dat` | что качать |
|
||
| `RESTART_CMD` | пусто | что выполнить после успешного обновления |
|
||
| `TIMEOUT` | `30` | таймаут curl, секунды |
|
||
|
||
Если 3x-ui в Docker — укажите `DEST_DIR` на смонтированный каталог и
|
||
`RESTART_CMD='docker restart 3x-ui'`.
|
||
|
||
## sing-box
|
||
|
||
```json
|
||
{
|
||
"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
|
||
|
||
```yaml
|
||
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](https://github.com/MetaCubeX/meta-rules-dat) | домены |
|
||
| [itdoginfo/allow-domains](https://github.com/itdoginfo/allow-domains) | домены и голосовые сети с портами |
|
||
| [you-oops-dev/ipranges-singbox](https://github.com/you-oops-dev/ipranges-singbox) | сети и имена голосовых узлов |
|
||
| [legiz-ru/sb-rule-sets](https://github.com/legiz-ru/sb-rule-sets) | адреса голосовых узлов |
|
||
| [vernette/rulesets](https://github.com/vernette/rulesets) | голосовой трафик UDP 50000-50099 |
|
||
|
||
```sh
|
||
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.
|
||
|
||
Дальше:
|
||
|
||
```sh
|
||
python3 tools/build.py --check
|
||
```
|
||
|
||
`--check` ругается на дубликаты, на домены, уже покрытые суффиксом, на сети,
|
||
вложенные в другие сети того же файла, на циклы в `include` и на конфликт
|
||
ограничений.
|
||
|
||
## Локальная сборка
|
||
|
||
```sh
|
||
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
|
||
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](LICENSE). Списки собраны из публичных источников,
|
||
перечисленных выше; лицензии апстримов смотрите в их репозиториях.
|