feat: geosite/geoip для Discord со сборкой из апстримов
Домены и сети 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>
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
#!/bin/sh
|
||||
# Обновляет локальные discord-geosite.dat и discord-geoip.dat из ветки release.
|
||||
# Рассчитан на запуск по cron.
|
||||
#
|
||||
# Каждый файл скачивается, только если его sha256 отличается от локального,
|
||||
# контрольная сумма проверяется до подмены, а сервис перезапускается один раз
|
||||
# и только если что-то реально изменилось. Молчит, когда обновлять нечего, —
|
||||
# cron не будет слать письма впустую.
|
||||
#
|
||||
# ./update-geodata.sh
|
||||
# BASE_URL=https://gitea.hsrv.site/mrleo1nid/discord-geodata/raw/branch/release \
|
||||
# DEST_DIR=/usr/local/x-ui/bin RESTART_CMD='x-ui restart' ./update-geodata.sh
|
||||
#
|
||||
# NAMES задаёт список файлов; по умолчанию — оба .dat.
|
||||
# Коды возврата: 0 — обновлено или уже актуально, 1 — ошибка.
|
||||
|
||||
set -eu
|
||||
|
||||
BASE_URL="${BASE_URL:-https://gitea.hsrv.site/mrleo1nid/discord-geodata/raw/branch/release}"
|
||||
DEST_DIR="${DEST_DIR:-/usr/local/x-ui/bin}"
|
||||
NAMES="${NAMES:-discord-geosite.dat discord-geoip.dat}"
|
||||
RESTART_CMD="${RESTART_CMD:-}"
|
||||
TIMEOUT="${TIMEOUT:-30}"
|
||||
|
||||
log() { printf '%s update-geodata: %s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$*"; }
|
||||
die() { log "ОШИБКА: $*" >&2; exit 1; }
|
||||
|
||||
command -v curl >/dev/null 2>&1 || die "нужен curl"
|
||||
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
hash_of() { sha256sum "$1" | cut -d' ' -f1; }
|
||||
elif command -v shasum >/dev/null 2>&1; then
|
||||
hash_of() { shasum -a 256 "$1" | cut -d' ' -f1; }
|
||||
else
|
||||
die "нужен sha256sum или shasum"
|
||||
fi
|
||||
|
||||
fetch() { curl -fsSL --retry 3 --retry-delay 2 --max-time "$TIMEOUT" "$1"; }
|
||||
|
||||
mkdir -p "$DEST_DIR"
|
||||
changed=0
|
||||
|
||||
for name in $NAMES; do
|
||||
dest="$DEST_DIR/$name"
|
||||
|
||||
# Без промежуточной переменной статус вернул бы cut, а не curl.
|
||||
remote_line=$(fetch "$BASE_URL/$name.sha256sum") ||
|
||||
die "не удалось скачать $BASE_URL/$name.sha256sum"
|
||||
remote_sum=$(printf '%s' "$remote_line" | cut -d' ' -f1)
|
||||
case "$remote_sum" in
|
||||
[0-9a-f][0-9a-f]*) [ "${#remote_sum}" -eq 64 ] || die "битая контрольная сумма: $remote_sum" ;;
|
||||
*) die "битая контрольная сумма: $remote_sum" ;;
|
||||
esac
|
||||
|
||||
if [ -f "$dest" ] && [ "$(hash_of "$dest")" = "$remote_sum" ]; then
|
||||
continue # уже актуально — тишина
|
||||
fi
|
||||
|
||||
tmp=$(mktemp "${TMPDIR:-/tmp}/discord-geodata.XXXXXX") || die "не удалось создать временный файл"
|
||||
trap 'rm -f "$tmp"' EXIT INT TERM
|
||||
|
||||
fetch "$BASE_URL/$name" > "$tmp" || die "не удалось скачать $BASE_URL/$name"
|
||||
|
||||
got=$(hash_of "$tmp")
|
||||
[ "$got" = "$remote_sum" ] || die "$name: ожидалось $remote_sum, получено $got"
|
||||
[ -s "$tmp" ] || die "$name: скачан пустой файл"
|
||||
|
||||
[ ! -f "$dest" ] || cp -p "$dest" "$dest.bak" || die "не удалось сохранить резервную копию"
|
||||
# mv в пределах одного каталога атомарен: Xray никогда не увидит половину файла.
|
||||
cat "$tmp" > "$dest.new" && mv -f "$dest.new" "$dest" || die "не удалось записать $dest"
|
||||
rm -f "$tmp"
|
||||
trap - EXIT INT TERM
|
||||
|
||||
log "обновлён $dest (sha256 $remote_sum)"
|
||||
changed=1
|
||||
done
|
||||
|
||||
[ "$changed" -eq 1 ] || exit 0
|
||||
|
||||
if [ -n "$RESTART_CMD" ]; then
|
||||
if sh -c "$RESTART_CMD"; then
|
||||
log "выполнено: $RESTART_CMD"
|
||||
else
|
||||
die "перезапуск не удался: $RESTART_CMD"
|
||||
fi
|
||||
fi
|
||||
Reference in New Issue
Block a user