From 3fef63801ff1b96a09b45f6b13932fabae0c5d13 Mon Sep 17 00:00:00 2001 From: Snowy-Fluffy Date: Sat, 3 Jan 2026 15:45:56 +0300 Subject: [PATCH] config check + new features --- files/config.sh | 264 ++++++++++++++++++++++++++++++++++++++++++++++ files/install.sh | 2 +- files/menu.sh | 52 ++++++++- files/utils.sh | 22 ++++ zapret-control.sh | 1 + 5 files changed, 339 insertions(+), 2 deletions(-) diff --git a/files/config.sh b/files/config.sh index 701661c..02fefa6 100755 --- a/files/config.sh +++ b/files/config.sh @@ -129,7 +129,10 @@ toggle_game_mode() { if [[ $game_mode_status == "включен" ]]; then rm -f /opt/zapret/ipset/ipset-game.txt touch /opt/zapret/ipset/ipset-game.txt || error_exit "не удалось создать ipset для игрвого режима" + echo "203.0.113.77" >> /opt/zapret/ipset/ipset-game.txt else + rm -f /opt/zapret/ipset/ipset-game.txt + touch /opt/zapret/ipset/ipset-game.txt || error_exit "не удалось создать ipset для игрвого режима" echo "0.0.0.0/0" >> /opt/zapret/ipset/ipset-game.txt fi manage_service restart @@ -345,3 +348,264 @@ search_in_zapret() { main_menu } + +test_domain() { + local domain="$1" + local results=() + domain=$(echo "$domain" | sed 's/#.*//' | xargs) + [[ -z "$domain" ]] && return + if [[ "$domain" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + ping_result=$(ping -c 2 -W 2 "$domain" 2>/dev/null | grep -E "rtt min/avg/max/mdev" | awk -F'/' '{print $5}') + if [[ -n "$ping_result" ]]; then + results=("${ping_result}ms" "N/A" "N/A" "N/A") + else + results=("FAIL" "N/A" "N/A" "N/A") + fi + else + ping_result=$(ping -c 2 -W 2 "$domain" 2>/dev/null | grep -E "rtt min/avg/max/mdev" | awk -F'/' '{print $5}') + if [[ -n "$ping_result" ]]; then + results+=("${ping_result}ms") + else + results+=("FAIL") + fi + http_result=$(timeout 5 curl -s -o /dev/null -w "%{http_code}" "http://$domain" 2>/dev/null || echo "FAIL") + if [[ "$http_result" =~ ^[0-9]+$ ]]; then + results+=("HTTP:$http_result") + else + results+=("FAIL") + fi + tls12_result=$(timeout 5 curl -s -o /dev/null -w "%{http_code}" --tlsv1.2 "https://$domain" 2>/dev/null || echo "FAIL") + if [[ "$tls12_result" =~ ^[0-9]+$ ]]; then + results+=("TLS1.2:$tls12_result") + else + results+=("FAIL") + fi + tls13_result=$(timeout 5 curl -s -o /dev/null -w "%{http_code}" --tlsv1.3 "https://$domain" 2>/dev/null || echo "FAIL") + if [[ "$tls13_result" =~ ^[0-9]+$ ]]; then + results+=("TLS1.3:$tls13_result") + else + results+=("FAIL") + fi + fi + echo "${results[@]}" +} + +print_table_header() { + echo "┌─────────────────────────────────────────────────────────────────────────────┐" + printf "│ %-30s │ %-8s │ %-10s │ %-10s │ %-10s │\n" "Домен/IP" "Ping" "HTTP" "TLS1.2" "TLS1.3" + echo "├─────────────────────────────────────────────────────────────────────────────┤" +} + +print_table_row() { + local domain="$1" + local ping="$2" + local http="$3" + local tls12="$4" + local tls13="$5" + local display_domain="$domain" + if [[ ${#domain} -gt 30 ]]; then + display_domain="${domain:0:27}..." + fi + printf "│ %-30s %-8s %-10s %-10s %-10s \n" "$display_domain" "$ping" "$http" "$tls12" "$tls13" +} + +test_all_domains() { + local config_name="$1" + local list_path="$2" + local total=0 + local available=0 + echo "┌─────────────────────────────────────────────────────────────────────────────┐" + echo "│ Стратегия: $config_name" + echo "├─────────────────────────────────────────────────────────────────────────────┤" + print_table_header + local results_lines=() + while IFS= read -r line || [[ -n "$line" ]]; do + line=$(echo "$line" | sed 's/#.*//' | xargs) + [[ -z "$line" ]] && continue + total=$((total + 1)) + results=($(test_domain "$line")) + local is_available=0 + if [[ "${results[0]}" != "FAIL" ]] && \ + ([[ "${results[2]}" =~ ^TLS1\.2:[23] ]] || [[ "${results[3]}" =~ ^TLS1\.3:[23] ]]); then + available=$((available + 1)) + is_available=1 + fi + results_lines+=("$line|${results[0]}|${results[1]}|${results[2]}|${results[3]}|$is_available") + done < "$list_path" + for line_info in "${results_lines[@]}"; do + IFS='|' read -r domain ping http tls12 tls13 is_available <<< "$line_info" + print_table_row "$domain" "$ping" "$http" "$tls12" "$tls13" + done + echo "├─────────────────────────────────────────────────────────────────────────────┤" + printf "│ Доступно: %d/%d доменов/IP │\n" "$available" "$total" + echo "└─────────────────────────────────────────────────────────────────────────────┘" + echo "" + echo "$available" +} + +apply_config() { + local config="$1" + echo -e "\e[33mПрименяем стратегию: $config\e[0m" + CONFIG_PATH="/opt/zapret/zapret.cfgs/configurations/$config" + if [[ ! -f "$CONFIG_PATH" ]]; then + echo -e "\e[31mФайл конфигурации не найден: $CONFIG_PATH\e[0m" + fi + rm -f /opt/zapret/config + cp "$CONFIG_PATH" /opt/zapret/config || error_exit "не удалось скопировать стратегию" + get_fwtype + sed -i "s/^FWTYPE=.*/FWTYPE=$FWTYPE/" /opt/zapret/config + manage_service restart +} + +check_conf() { + configure_zapret_list + check_list + echo -e "\e[36mНачинаем проверку всех стратегий...\e[0m" + echo -e "\e[33mВсего стратегий: ${#configs[@]}\e[0m" + echo "" + stats_file="/tmp/zapret_final_stats_$$.txt" + > "$stats_file" + local best_config="" + local best_available=0 + local total_domains=0 + total_domains=0 + while IFS= read -r line || [[ -n "$line" ]]; do + line=$(echo "$line" | sed 's/#.*//' | xargs) + [[ -n "$line" ]] && total_domains=$((total_domains + 1)) + done < "$LIST_PATH" + for config in "${configs[@]}"; do + echo "──────────────────────────────────────────────────────────────────────────────" + echo "" + if ! apply_config "$config"; then + echo -e "\e[31mНе удалось применить стратегию: $config\e[0m" + echo "" + continue + fi + available=$(test_all_domains "$config" "$LIST_PATH" | tee /dev/tty | tail -1) + if [[ "$available" =~ ^[0-9]+$ ]]; then + echo "$config $available" >> "$stats_file" + if [[ $available -gt $best_available ]]; then + best_available=$available + best_config="$config" + fi + else + echo -e "\e[31mОшибка при тестировании стратегии: $config\e[0m" + fi + done + echo "" + echo -e "\e[42m\e[30m╔══════════════════════════════════════════════════════════════════════════╗\e[0m" + echo -e "\e[42m\e[30m║ ИТОГОВЫЙ РЕЗУЛЬТАТ ║\e[0m" + echo -e "\e[42m\e[30m╠══════════════════════════════════════════════════════════════════════════╣\e[0m" + echo -e "\e[42m\e[30m║ ║\e[0m" + printf "\e[42m\e[30m║ Лучшая стратегия: %-52s ║\n\e[0m" "$best_config" + printf "\e[42m\e[30m║ Доступно доменов/IP: %-3d из %-3d (%.1f%%) ║\n\e[0m" "$best_available" "$total_domains" $(echo "scale=1; $best_available * 100 / $total_domains" | bc) + echo -e "\e[42m\e[30m║ ║\e[0m" + echo -e "\e[42m\e[30m╚══════════════════════════════════════════════════════════════════════════╝\e[0m" + echo "" + echo -e "\e[33mПрименяем лучшую стратегию: $best_config\e[0m" + apply_config "$best_config" + if [[ -f "$stats_file" ]] && [[ $(wc -l < "$stats_file") -gt 0 ]]; then + echo "" + echo -e "\e[36mСтатистика по всем стратегиям:\e[0m" + echo "┌──────────────────────────────────────────────────────┐" + printf "│ %-30s │ %-10s │ %-6s │\n" "Стратегия" "Доступно" "%" + echo "├──────────────────────────────────────────────────────┤" + while read -r line; do + read -r config count <<< "$line" + if [[ "$count" =~ ^[0-9]+$ ]] && [[ $total_domains -gt 0 ]]; then + percentage=$(echo "scale=1; $count * 100 / $total_domains" | bc) + printf "│ %-30s │ %-10s │ %-5s%% │\n" "$config" "$count/$total_domains" "$percentage" + fi + done < "$stats_file" + echo "└──────────────────────────────────────────────────────┘" + fi + rm -f "$stats_file" + return 0 +} +check_list() { + + LINE_COUNT=$(wc -l < "/opt/zapret/ipset/zapret-hosts-user.txt" 2>/dev/null || echo "0") + if [ "$LINE_COUNT" = "0" ] && [ -s "/opt/zapret/ipset/zapret-hosts-user.txt" ]; then + LINE_COUNT=$(awk 'END{print NR}' "/opt/zapret/ipset/zapret-hosts-user.txt" 2>/dev/null || echo "0") + fi + + if ! [[ "$LINE_COUNT" =~ ^[0-9]+$ ]]; then + echo "Ошибка: Не удалось подсчитать строки в файле" + exit 1 + fi + + echo "В выбраном листе $LINE_COUNT доменов/айпи." + + if [ "$LINE_COUNT" -gt 100 ]; then + echo "Проверка может занять *ОЧЕНЬ* много времени!" + + echo "" + read -p "Нажмите Enter для продолжения или Ctrl+C для отмены... " + fi +} +check_conf_simple() { + rm -f /opt/zapret/ipset/zapret-hosts-user.txt + cp -r /opt/zapret/zapret.cfgs/lists/list-simple.txt /opt/zapret/ipset/zapret-hosts-user.txt + check_list + echo -e "\e[36mНачинаем проверку всех стратегий...\e[0m" + echo -e "\e[33mВсего стратегий: ${#configs[@]}\e[0m" + echo "" + stats_file="/tmp/zapret_final_stats_$$.txt" + > "$stats_file" + local best_config="" + local best_available=0 + local total_domains=0 + total_domains=0 + while IFS= read -r line || [[ -n "$line" ]]; do + line=$(echo "$line" | sed 's/#.*//' | xargs) + [[ -n "$line" ]] && total_domains=$((total_domains + 1)) + done < "$LIST_PATH" + for config in "${configs[@]}"; do + echo "──────────────────────────────────────────────────────────────────────────────" + echo "" + if ! apply_config "$config"; then + echo -e "\e[31mНе удалось применить стратегию: $config\e[0m" + echo "" + continue + fi + available=$(test_all_domains "$config" "$LIST_PATH" | tee /dev/tty | tail -1) + if [[ "$available" =~ ^[0-9]+$ ]]; then + echo "$config $available" >> "$stats_file" + if [[ $available -gt $best_available ]]; then + best_available=$available + best_config="$config" + fi + else + echo -e "\e[31mОшибка при тестировании стратегии: $config\e[0m" + fi + done + echo "" + echo -e "\e[42m\e[30m╔══════════════════════════════════════════════════════════════════════════╗\e[0m" + echo -e "\e[42m\e[30m║ ИТОГОВЫЙ РЕЗУЛЬТАТ ║\e[0m" + echo -e "\e[42m\e[30m╠══════════════════════════════════════════════════════════════════════════╣\e[0m" + echo -e "\e[42m\e[30m║ ║\e[0m" + printf "\e[42m\e[30m║ Лучшая стратегия: %-52s ║\n\e[0m" "$best_config" + printf "\e[42m\e[30m║ Доступно доменов/IP: %-3d из %-3d (%.1f%%) ║\n\e[0m" "$best_available" "$total_domains" $(echo "scale=1; $best_available * 100 / $total_domains" | bc) + echo -e "\e[42m\e[30m║ ║\e[0m" + echo -e "\e[42m\e[30m╚══════════════════════════════════════════════════════════════════════════╝\e[0m" + echo "" + echo -e "\e[33mПрименяем лучшую стратегию: $best_config\e[0m" + apply_config "$best_config" + if [[ -f "$stats_file" ]] && [[ $(wc -l < "$stats_file") -gt 0 ]]; then + echo "" + echo -e "\e[36mСтатистика по всем стратегиям:\e[0m" + echo "┌──────────────────────────────────────────────────────┐" + printf "│ %-30s │ %-10s │ %-6s │\n" "Стратегия" "Доступно" "%" + echo "├──────────────────────────────────────────────────────┤" + while read -r line; do + read -r config count <<< "$line" + if [[ "$count" =~ ^[0-9]+$ ]] && [[ $total_domains -gt 0 ]]; then + percentage=$(echo "scale=1; $count * 100 / $total_domains" | bc) + printf "│ %-30s │ %-10s │ %-5s%% │\n" "$config" "$count/$total_domains" "$percentage" + fi + done < "$stats_file" + echo "└──────────────────────────────────────────────────────┘" + fi + rm -f "$stats_file" + return 0 +} diff --git a/files/install.sh b/files/install.sh index b1fb755..73b7e5b 100755 --- a/files/install.sh +++ b/files/install.sh @@ -292,7 +292,7 @@ update_zapret() { rm -rf $TEMP_DIR_BIN rm -f /opt/zapret/config cp -r /opt/zapret/zapret.cfgs/configurations/general /opt/zapret/config || error_exit "не удалось автоматически скопировать конфиг" - cp -r /opt/zapret/zapret.cfgs/bin/* /opt/zapret/files/fake || error_exit "не удалось автоматически скопировать fake bin" + cp -r /opt/zapret/zapret.cfgs/bin/* /opt/zapret/files/fake/ || error_exit "не удалось автоматически скопировать fake bin" rm -f /opt/zapret/ipset/zapret-hosts-user.txt touch /opt/zapret/ipset/ipset-game.txt || error_exit "не удалось автоматически создать game ipset" cp -r /opt/zapret/zapret.cfgs/lists/list-basic.txt /opt/zapret/ipset/zapret-hosts-user.txt || error_exit "не удалось автоматически скопировать хостлист" diff --git a/files/menu.sh b/files/menu.sh index 9fb7b1a..0f6d9e1 100755 --- a/files/menu.sh +++ b/files/menu.sh @@ -107,6 +107,8 @@ change_configuration() { echo -e " \e[1;34m6)\e[0m Найти IP или домены в листе" echo -e " \e[1;34m7)\e[0m Установить стратегию из файла (путь)" echo -e " \e[1;34m8)\e[0m Установить хостлист из файла (путь)" + echo -e " \e[1;34m9)\e[0m Редактировать стратегию напрямую" + echo -e " \e[1;34m10)\e[0m Редактировать хостлист напрямую" echo "" echo -e "\e[1;96mСделано\e[0m by: \e[4;94mhttps://t.me/linux_hi\e[0m" echo "" @@ -114,18 +116,66 @@ change_configuration() { read -p $'\e[1;36mВыберите действие: \e[0m' CHOICE case "$CHOICE" in 1) toggle_game_mode ;; - 2) configure_zapret_conf ;; + 2) configure_zapret_menu ;; 3) configure_zapret_list ;; 4) add_to_zapret ;; 5) delete_from_zapret ;; 6) search_in_zapret ;; 7) configure_custom_conf_path ;; 8) configure_custom_list_path ;; + 9) open_editor /opt/zapret/config ;; + 10) open_editor /opt/zapret/ipset/zapret-hosts-user.txt ;; 0) main_menu ;; *) echo -e "\e[1;31mНеверный ввод! Попробуйте снова.\e[0m"; sleep 2 ;; esac done } +configure_zapret_menu(){ + while true; do + clear + cur_conf + echo -e "\e[1;36m╔══════════════════════════════════════════════╗" + echo -e "║ Управление стратегиями Запрета ║" + echo -e "╚══════════════════════════════════════════════╝\e[0m" + echo -e " \e[1;33m Используемая стратегия:\e[0m \e[1;32m$cr_cnf\e[0m" + echo -e " \e[1;31m0)\e[0m Выйти в меню" + echo -e " \e[1;34m1)\e[0m Выбрать стратегию вручную" + echo -e " \e[1;34m2)\e[0m Подобрать стратегию автоматически" + echo "" + echo -e "\e[1;96mСделано\e[0m by: \e[4;94mhttps://t.me/linux_hi\e[0m" + echo "" + read -p $'\e[1;36m Выберите действие: \e[0m' CHOICE + case "$CHOICE" in + 1) configure_zapret_conf;; + 2) auto_conf_check;; + 0) main_menu;; + *) echo -e "\e[1;31m Неверный ввод! Попробуйте снова.\e[0m"; sleep 2;; + esac + done +} +auto_conf_check(){ + while true; do + clear + cur_conf + echo -e "\e[1;36m╔══════════════════════════════════════════════╗" + echo -e "║ Управление стратегиями Запрета ║" + echo -e "╚══════════════════════════════════════════════╝\e[0m" + echo -e " \e[1;33m Используемая стратегия:\e[0m \e[1;32m$cr_cnf\e[0m" + echo -e " \e[1;31m0)\e[0m Выйти в меню" + echo -e " \e[1;34m1)\e[0m Подобрать стратегию автоматически" + echo -e " \e[1;34m2)\e[0m Подобрать стратегию автоматически по кастомному листу" + echo "" + echo -e "\e[1;96mСделано\e[0m by: \e[4;94mhttps://t.me/linux_hi\e[0m" + echo "" + read -p $'\e[1;36m Выберите действие: \e[0m' CHOICE + case "$CHOICE" in + 1) check_conf_simple;; + 2) check_conf;; + 0) main_menu;; + *) echo -e "\e[1;31m Неверный ввод! Попробуйте снова.\e[0m"; sleep 2;; + esac + done +} update_zapret_menu(){ while true; do diff --git a/files/utils.sh b/files/utils.sh index 92e0473..7d3093e 100755 --- a/files/utils.sh +++ b/files/utils.sh @@ -71,3 +71,25 @@ try_again() { (( success == 0 )) && error_exit "$error_message" } +open_editor() { + local file_path="$1" + if [ ! -f "$1" ]; then + error_exit "заданного файла не существует" + fi + + if [ -z "$EDITOR" ] || [ ! -n "$EDITOR" ]; then + echo "Переменная EDITOR пуста" + echo "" + echo "Продолжаю через 5 секунд..." + sleep 5 + main_menu + fi + + "$EDITOR" "$1" + main_menu +} +fast_exit(){ + $TPUT_E + echo "Выход по запросу пользователя" + exit 1 +} diff --git a/zapret-control.sh b/zapret-control.sh index 3b0d1b5..3f075af 100755 --- a/zapret-control.sh +++ b/zapret-control.sh @@ -25,6 +25,7 @@ fi if [[ $EUID -ne 0 ]]; then exec $SUDO "$0" "$@" fi +trap fast_exit SIGINT check_openwrt check_tput $TPUT_B