diff --git a/.forgejo/workflows/deploy.yaml b/.forgejo/workflows/deploy.yaml index 656db3f..78f6a1a 100644 --- a/.forgejo/workflows/deploy.yaml +++ b/.forgejo/workflows/deploy.yaml @@ -11,7 +11,7 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - + - name: Validate domains file run: | if [ ! -f domains.txt ]; then @@ -26,12 +26,21 @@ jobs: fi done - - name: Generate dnsmasq configuration files + - name: Prepare Makefile run: | - chmod +x scripts/generate-configs.sh - ./scripts/generate-configs.sh + chmod +x generate-configs.sh + chmod +x deploy-to-gateway.sh - - name: Deploy to gateway + - name: Run workflow (clean → check → all) run: | - chmod +x scripts/deploy-to-gateway.sh - ./scripts/deploy-to-gateway.sh + make clean + make check + make all + + - name: Upload configs as artifacts + uses: actions/upload-artifact@v3 + with: + name: dnsmasq-configs + path: | + /tmp/91-ipset-bbrkn.conf + /tmp/92-resolve-bbrkn.conf diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..de0eeb8 --- /dev/null +++ b/Makefile @@ -0,0 +1,46 @@ +# ========================== +# Makefile для проекта BBRKN +# ========================== + +DOMAINS := domains.txt +GEN_SCRIPT := ./generate-configs.sh +DEPLOY_SCRIPT := ./deploy-to-gateway.sh + +IPSET_CONF := /tmp/91-ipset-bbrkn.conf +RESOLVE_CONF := /tmp/92-resolve-bbrkn.conf + +# Генерация конфигов +generate: + @echo ">>> Генерация конфигурационных файлов из $(DOMAINS)" + $(GEN_SCRIPT) + +# Тестовый прогон (генерация + просмотр кусков файлов, но без деплоя) +test: generate + @echo ">>> Тестовый прогон (без деплоя)" + @echo "--- IPSET CONFIG ($(IPSET_CONF)) ---" + @head -n 10 $(IPSET_CONF) || true + @echo "... (всего $$(wc -l < $(IPSET_CONF)) строк)" + @echo + @echo "--- RESOLVE CONFIG ($(RESOLVE_CONF)) ---" + @head -n 10 $(RESOLVE_CONF) || true + @echo "... (всего $$(wc -l < $(RESOLVE_CONF)) строк)" + +# Проверка: только сводка из generate-configs.sh +check: + @echo ">>> Проверка списка доменов (без генерации файлов)" + $(GEN_SCRIPT) --dry-run + +# Деплой на шлюз (Pi-hole) +deploy: generate + @echo ">>> Деплой на шлюз" + $(DEPLOY_SCRIPT) + +# Полный цикл: генерация + деплой +all: deploy + +# Уборка временных файлов +clean: + @echo ">>> Удаление временных файлов" + @rm -f $(IPSET_CONF) $(RESOLVE_CONF) + +.PHONY: generate test check deploy all clean diff --git a/domains.txt b/domains.txt index 3324c36..a3a1c4b 100644 --- a/domains.txt +++ b/domains.txt @@ -68,8 +68,6 @@ aurora.web.telegram.org autoconfig.telegram.org autodiscover.telegram.org bbs.telegram.org -beta.telegram.org -blog.telegram.org booktracker.org bt1.t-ru.org bt2.rutracker.cc diff --git a/scripts/generate-configs.sh b/scripts/generate-configs.sh index ed6c44a..56c1a4f 100644 --- a/scripts/generate-configs.sh +++ b/scripts/generate-configs.sh @@ -4,48 +4,90 @@ set -euo pipefail INPUT_FILE="domains.txt" IPSET_CONF="/tmp/91-ipset-bbrkn.conf" RESOLVE_CONF="/tmp/92-resolve-bbrkn.conf" +API_URL="http://10.100.1.2:3000/domains?domain=" -# Очистка выходных файлов -: > "$IPSET_CONF" -: > "$RESOLVE_CONF" +DRY_RUN=false +if [[ "${1:-}" == "--dry-run" ]]; then + DRY_RUN=true +fi -echo "Generating configuration files..." +if ! $DRY_RUN; then + : > "$IPSET_CONF" + : > "$RESOLVE_CONF" +fi + +declare -A DOM_ROLE # роли для исходных доменов: site/service +declare -A EXPANDED # все уникальные домены (ключи = домены) +declare -A SOURCES # источник: base или related normalize_domain() { local raw="$1" - # Удаляем комментарии после домена (inline), обрезаем пробелы - raw="$(echo "$raw" | sed -E 's/#.*$//' | awk '{$1=$1};1')" - # Пустые строки отбрасываем + raw="$(echo "$raw" | sed -E 's/#.*$//' | awk '{$1=$1};1')" || return 1 [ -z "$raw" ] && return 1 - # Приводим к нижнему регистру raw="$(echo "$raw" | tr '[:upper:]' '[:lower:]')" - # Удаляем лидирующее "*." (wildcard из пользовательского файла) - raw="$(echo "$raw" | sed -E 's/^\*\.\s*//')" - # Удаляем лидирующие точки (исторически dnsmasq игнорирует их) - raw="$(echo "$raw" | sed -E 's/^\.+//')" - # Удаляем финальные точки (FQDN с точкой на конце) - raw="$(echo "$raw" | sed -E 's/\.+$//')" - # Удаляем дублирующиеся точки внутри - raw="$(echo "$raw" | sed -E 's/\.+/./g')" - # Базовая проверка формата домена: label(.label)+, tld >=2 + raw="$(echo "$raw" | sed -E 's/^\*\.\s*//; s/^\.+//; s/\.+$//; s/\.+/./g')" if echo "$raw" | grep -Eq '^[a-z0-9-]+(\.[a-z0-9-]+)+$' && \ echo "$raw" | grep -Eq '\.[a-z]{2,}$'; then printf '%s' "$raw" - return 0 else return 1 fi } -# Читаем вход и генерируем конфиги +# Обработка доменов из входного списка while IFS= read -r line || [ -n "$line" ]; do dom="$(normalize_domain "$line" || true)" [ -z "$dom" ] && continue - echo "ipset=/$dom/bbrkn" >> "$IPSET_CONF" - echo "server=/$dom/8.8.8.8" >> "$RESOLVE_CONF" + + echo "Querying service for $dom..." + resp="$(curl -s --max-time 15 "${API_URL}${dom}" || true)" + + if echo "$resp" | grep -q '"domains"'; then + DOM_ROLE["$dom"]="site" + EXPANDED["$dom"]=1 + SOURCES["$dom"]="base" + mapfile -t subs < <(echo "$resp" | jq -r '.domains[]?') + for s in "${subs[@]}"; do + nd="$(normalize_domain "$s" || true)" + [ -n "$nd" ] || continue + EXPANDED["$nd"]=1 + [[ -z "${SOURCES[$nd]:-}" ]] && SOURCES["$nd"]="related" + done + else + DOM_ROLE["$dom"]="service" + EXPANDED["$dom"]=1 + SOURCES["$dom"]="base" + fi done < "$INPUT_FILE" -echo "Configuration files generated:" -echo "- $IPSET_CONF ($(wc -l < "$IPSET_CONF") entries)" -echo "- $RESOLVE_CONF ($(wc -l < "$RESOLVE_CONF") entries)" +# Сортировка доменов +mapfile -t ALL_DOMAINS < <(printf "%s\n" "${!EXPANDED[@]}" | sort -u) +# Генерация конфигов +if ! $DRY_RUN; then + for d in "${ALL_DOMAINS[@]}"; do + echo "ipset=/$d/bbrkn" >> "$IPSET_CONF" + echo "server=/$d/8.8.8.8" >> "$RESOLVE_CONF" + done +fi + +# Подсчёты +count_in=$(wc -l < "$INPUT_FILE") +count_total=${#ALL_DOMAINS[@]} +count_base=$(printf "%s\n" "${!SOURCES[@]}" | grep -c '.*' || true) +count_related=$(printf "%s\n" "${!SOURCES[@]}" | grep -c '.*' || true) +count_related=$(( count_total - count_in )) + +# Отладочный вывод +echo +echo "===== DEBUG REPORT =====" +echo "Original domains file: $count_in entries" +echo "Final unique domains: $count_total" +echo " - Base domains: $count_in" +echo " - Related domains: $count_related" +echo +while IFS= read -r line || [ -n "$line" ]; do + dom="$(normalize_domain "$line" || true)" + [ -n "$dom" ] && echo "$dom - ${DOM_ROLE[$dom]:-unknown}" +done < "$INPUT_FILE" +echo "========================"