ВНИМАНИЕ! Авторы не несут ответственность за работоспособность, безопасность и стабильность ПО, представленного в инструкции. Все действия (прошивка / настройка роутера) выполняются пользователями с учетом данного факта

Сценарии использования:

  1. Обеспечение приватности интернет-соединения всех или части устройств в LAN-сети

  2. Обход региональных блокировок на всех или части устройств в LAN-сети

  3. Реализация двойного VPN:

    - VPN-провайдер № 1 (на роутере): видит IP клиента, но не видит IP посещаемых ресурсов

    - VPN-провайдер № 2 (на клиентских устройствах): видит IP посещаемых ресурсов, но не IP клиента

Требования:

  • Роутер c OpenWRT

    Варианты:

    • Приобретение роутера с предустановленной OpenWRT (например, на маркетплейсах)

    • Самостоятельная установка OpenWRT на совместимый роутер. Таблица поддерживаемых устройств c инструкциями по установке: https://toh.openwrt.org

  • Личный VPN или подписка на коммерческий VPN, использующий протокол VLESS

1. Сброс до заводских настроек

Сброс роутера до настроек по-умолчанию удалит несовместимое с Passwall ПО при его наличии (другие VPN-клиенты, программы для анализа трафика, DoH- и DoT-конфигурации и т.д.) и временные файлы:

  1. Подключиться по кабелю к LAN-порту роутера с компьютера (после сброса точка доступа WiFi может быть в выключенном состоянии), ввести локальный IP роутера (обычно, 192.168.0.1, 192.168.1.1) в браузере, после чего прописать пароль от роутера (при наличии)

  2. Нажать на кнопку Perform reset в System - Backup/Flash Firmware и подтвердить сброс. В течение пары минут роутер перезагрузится и сбросится до изначального состояния

2. Настройка доступа в Интернет

Если после сброса доступ в интернет не появится, настроить WAN-интерфейс по инструкции от интернет-провайдера:

  1. Ввести предложенные провайдером или прописанные в договоре об оказании услуг связи IP, шлюз по-умолчанию и DNS-сервера в настройках WAN-интерфейса (Network - Interfaces - Interfaces - WAN). Перезагрузить роутер

  2. Если провайдер реализует фильтрацию по MAC-адресу, изменить MAC-адрес WAN-интерфейса в Network - Interfaces - Devices - WAN - Configure на представленный в личном кабинете провайдера, договоре или чате с технической поддержкой. Перезагрузить роутер и проверить подключение к интернету на клиентских устройствах

3. Установка Passwall

Passwall - программное обеспечение, позволяющее настроить VPN-подключение (в том числе и по протоколу VLESS) на роутере. Шаги установки:

  1. Подключиться к роутеру по ssh и ввести пароль от роутера (при наличии):

    - На Windows использовать ssh-клиент PuTTY: https://putty.org/

    - На macOS и Linux ввести в терминал:

    ssh root@router_ip   # заменить router_ip на локальный IP роутера

  2. Выполнить команду, загружающую, разрешающую исполнение и запускающую скрипт по установке Passwall:

    rm -f passwallx.sh && wget https://raw.githubusercontent.com/amirhosseinchoghaei/Passwall/main/passwallx.sh && chmod 777 passwallx.sh && sh passwallx.sh

  3. Выбрать Вариант 1 (если объем оперативной памяти роутера меньше 256МБ) или Вариант 2 (если объем оперативной памяти роутера больше 256МБ)

  4. Дождаться окончания установки Passwall и перезагрузить роутер

  5. (Опционально) Если после выполнения скрипта название роутера (hostname) изменилось, вернуть его обратно :

    uci set system.@system[0].hostname = "Name" # заменить Name на желаемое название 

    uci commit system

    echo $(uci get system.@system[0].hostname) > /proc/sys/kernel/hostname

    reboot

    После этих действий файл hostname должен содержать новое название, которое также будет отображаться в веб-интерфейсе OpenWRT:

    cat /proc/sys/kernel/hostname

  6. Проверить наличие нового меню Services - Passwall в веб-интерфейсе роутера

4. Настройка Passwall

  1. Добавить подписку на VPN в Services - Passwall - Node Subscribe - Add, введя название подписки в поле Subscribe Remark и ссылку, предоставленную VPN-провайдером, в поле Subscribe URL

  2. Произвести подписку вручную, нажав на Manual Subscription в Services - Passwall - Node Subscribe и дождаться окончания процесса. Список VPN-серверов с возможностью проверить их Пинг отобразится в Services - Passwall - Node List

    Логи Passwall после добавления/обновления подписки (Services - Passwall - Watch Logs)
    Логи Passwall после добавления/обновления подписки (Services - Passwall - Watch Logs)
  3. Выбрать локацию / сервер в Services - Passwall - Basic Settings - Main - Node и поставить галочку рядом с Main switch для подключения к VPN. После успешного подключения рядом с пунктом Core появится зеленая надпись RUNNING.

    Главное окно Passwall, в котором можно включить/выключить VPN, выбрать сервер для подключения и проверить пинг
    Главное окно Passwall, в котором можно включить/выключить VPN, выбрать сервер для подключения и проверить пинг

    Проверить публичный IP на клиентских устройствах (например, на https://whatismyipaddress.com или curl ip.me в терминале) - отобразится IP VPN-сервиса

5. Добавление устройств в исключения Passwall

  1. Отключить рандомизацию MAC-адреса при каждом переподключении к сети на клиентском устройстве, трафик которого должен идти в обход VPN. Например, в настройках Wi-Fi на Android и Linux с GNOME можно выбрать Стабильный MAC-адрес – для каждой WiFi-сети он будет разный, но меняться со временем внутри одной Wi-Fi-сети не будет

  2. Нажать Add в Services - Passwall - ACL

    - В поле Source выбрать MAC-адрес желаемого устройства

    - В полях TCP No Redir Ports и UDP No Redir Ports выбрать All

    - Нажать Save & Apply

  3. В меню Services - Passwall - ACL поставить галочки напротив созданного правила и Main switch. Нажать Save & Apply. Проверить публичный IP-адрес на добавленных в этот список устройствах

Security Notes | RU

Telegram-канал

Комментарии (11)


  1. Lainhard
    27.03.2026 21:44

    ВНИМАНИЕ! Авторы не несут ответственность за работоспособность, безопасность и стабильность ПО, представленного в инструкции. Все действия (прошивка / настройка роутера) выполняются пользователями с учетом данного факта

    Это конечно хорошо, защитился так защитился, но есть мнение, что человек (человек ведь?), условно, специалист, должен отвечать за свои "инструкции". Как минимум нести моральную ответственность как автор.


  1. sohmstyle
    27.03.2026 21:44

    Какие классные скрипты...
    Автор, опишите, пожалуйста, что делает скрипт cdnopw.sh, который вызывается в passwallx.sh ?
    Вы же изучили скрипты, правда? Не вслепую выпоняли все команды?


    1. Derevtso
      27.03.2026 21:44

      Этот файл можно деобфусцировать, но он и другой тащит внутри, мне уже лень было.
      На https://cocalc.com в бесплатной песочнице потыкал палочкой: замена eval на printf, а потом сколько-то раз превратить внутренний base64 в текст.
      Вот навайбкоженный скрипт деобфускации, он работает, в той же песочнице.

      unpack.sh
      #!/bin/bash
      # unpack.sh — Распаковка: переменные + eval → цепочка base64
      # Использование: ./unpack.sh <файл> [имя_вывода]
      
      set -e
      
      INPUT="${1:?Ошибка: укажите входной файл}"
      OUTPUT="${2:-unwrapped_final}"
      WORK_DIR=$(mktemp -d)
      
      echo "[*] Распаковка: $INPUT"
      echo "[*] Рабочая папка: $WORK_DIR"
      echo "========================================"
      
      # -------------------------------------------------------------
      # ЭТАП 1: Раскрытие переменных (замена eval на printf)
      # -------------------------------------------------------------
      echo ""
      echo "[ЭТАП 1/2] Раскрываем переменные..."
      
      cp "$INPUT" "$WORK_DIR/input.sh"
      
      # Находим строку с eval и заменяем eval на printf
      # Это заставит bash собрать строку из переменных и вывести её
      if grep -qE '^\s*eval\s+' "$WORK_DIR/input.sh"; then
          sed -E 's/^\s*eval\s+/printf "%s\\n" /' "$WORK_DIR/input.sh" > "$WORK_DIR/modified.sh"
          
          # Запускаем модифицированный скрипт, чтобы получить собранную строку
          # 2>/dev/null скрывает ошибки, так как после printf скрипт упадёт
          bash "$WORK_DIR/modified.sh" > "$WORK_DIR/layer1.txt" 2>/dev/null || true
          
          if [ -s "$WORK_DIR/layer1.txt" ]; then
              echo "[+] Переменные раскрыты"
          else
              echo "[!] Не удалось раскрыть переменные"
              exit 1
          fi
      else
          echo "[+] eval не найден, копируем файл как есть"
          cp "$WORK_DIR/input.sh" "$WORK_DIR/layer1.txt"
      fi
      
      # -------------------------------------------------------------
      # ЭТАП 2: Раскрутка base64
      # -------------------------------------------------------------
      echo ""
      echo "[ЭТАП 2/2] Раскручиваем base64..."
      
      cp "$WORK_DIR/layer1.txt" "$WORK_DIR/current.tmp"
      LAYER=0
      MAX_LAYERS=20
      
      while [ $LAYER -lt $MAX_LAYERS ]; do
          LAYER=$((LAYER + 1))
          
          # Проверяем наличие base64
          if ! grep -q 'base64' "$WORK_DIR/current.tmp" 2>/dev/null; then
              echo "[+] Слой $LAYER: base64 не найден — готово"
              break
          fi
          
          # Извлекаем base64 (удаляем всё, кроме символов кодировки)
          CONTENT=$(cat "$WORK_DIR/current.tmp" | tr -d '\n\r\t' | grep -oE '[A-Za-z0-9+/=]{100,}' | head -1)
          
          if [ -z "$CONTENT" ]; then
              echo "[!] Не удалось найти base64 на слое $LAYER"
              break
          fi
          
          echo "[*] Слой $LAYER: декодируем ${#CONTENT} символов..."
          
          # Декодируем
          if ! echo "$CONTENT" | base64 -d > "$WORK_DIR/next.tmp" 2>/dev/null; then
              echo "[!] Ошибка декодирования на слое $LAYER"
              break
          fi
          
          mv "$WORK_DIR/next.tmp" "$WORK_DIR/current.tmp"
          echo "[+] Слой $LAYER распакован"
      done
      
      # -------------------------------------------------------------
      # ФИНАЛ: Сохранение
      # -------------------------------------------------------------
      echo ""
      echo "[*] Сохранение результата..."
      
      if file "$WORK_DIR/current.tmp" | grep -q "ELF"; then
          mv "$WORK_DIR/current.tmp" "${OUTPUT}.bin"
          echo "[✓] Результат: ${OUTPUT}.bin (бинарник)"
          strings "${OUTPUT}.bin" 2>/dev/null | head -20 | sed 's/^/  /'
      elif file "$WORK_DIR/current.tmp" | grep -qE "script|ASCII|text"; then
          mv "$WORK_DIR/current.tmp" "${OUTPUT}.sh"
          echo "[✓] Результат: ${OUTPUT}.sh (скрипт)"
          head -30 "${OUTPUT}.sh" 2>/dev/null | sed 's/^/  /'
      else
          mv "$WORK_DIR/current.tmp" "${OUTPUT}.raw"
          echo "[✓] Результат: ${OUTPUT}.raw"
      fi
      
      rm -rf "$WORK_DIR"
      echo ""
      echo "[*] Готово!"

      Вот, если интересно cdnopw.sh.

      cdnopw.sh
      #!/bin/bash
      export LANG=en_US.UTF-8
      case "$(uname -m)" in
      	x86_64 | x64 | amd64 )
      	cpu=amd64
      	;;
      	i386 | i686 )
              cpu=386
      	;;
      	armv8 | armv8l | arm64 | aarch64 )
              cpu=arm64
      	;;
      	armv7l )
              cpu=arm
      	;;
              mips64le )
              cpu=mips64le
      	;;
              mips64 )
              cpu=mips64
      	;;
              mips )
              cpu=mipsle
      	;;
              mipsle )
              cpu=mipsle
      	;;
      	* )
      	echo "当前架构为$(uname -m),暂不支持"
      	exit
      	;;
      esac
      if [ ! -f ygop_update ]; then
      # 初始化包列表
      packages=""
      # 创建一个包名数组和一个命令名数组
      package_names=("bash" "jq" "wget" "curl" "sed" "unzip" "coreutils" "coreutils-timeout" "coreutils-base64")
      command_names=("bash" "jq" "wget" "curl" "sed" "unzip" "tr" "timeout" "base64")
      # 遍历命令名数组
      for i in ${!command_names[@]}; do
        # 如果对应的命令没有安装,那么就把对应的包名添加到包列表中
        if ! command -v ${command_names[$i]} &> /dev/null; then
          packages="$packages ${package_names[$i]}"
        fi
      done
      	# 判断系统进行安装
      	if [ -n "$packages" ]; then
      	    echo "经检测,需要安装依赖: $packages"    
      	    if cat /etc/issue /proc/version /etc/os-release 2>/dev/null | grep -q -E -i "alpine"; then
      	        apk update
      	        apk add $packages
      	    elif cat /etc/issue /proc/version /etc/os-release 2>/dev/null | grep -q -E -i "openwrt"; then
      	        opkg update
      	        opkg install $packages
      	        opkg install coreutils-timeout
      	        opkg install coreutils-base64
                  elif cat /etc/issue /proc/version /etc/os-release 2>/dev/null | grep -q -E -i "ubuntu|debian"; then
      	        sudo apt-get update -y
      	        sudo apt-get install $packages -y
      	    elif cat /etc/issue /proc/version /etc/os-release 2>/dev/null | grep -q -E -i "centos|red hat|redhat"; then
      	        sudo yum install $packages -y
      	    else
      	        echo "未能检测出你的系统:$(uname),请自行安装$packages这些软件。"
      	        exit 1
      	    fi
      	fi
       touch ygop_update
       fi
      v6=$(curl -s6m5 ip.gs -k)
      ipv6test(){
      if [[ -n $v6 ]]; then
      echo "2:优选IPV6"
      else
      echo "2:无IPV6网络,请不要选择"
      fi
      }
      cdnv4v6(){
      echo
      echo "1:优选IPV4"
      ipv6test
      read -p "请选择(回车默认为IPV4): " menu
      if [ -z $menu ] || [ "$menu" == "1" ]; then
      rm -rf ipv6.txt
      curl -s -O https://gitlab.com/rwkgyg/CFwarp/-/raw/main/point/cpu3/ip.txt
      IP_ADDR=ipv4
      elif [ "$menu" == "2" ]; then
      if [[ -n $v6 ]]; then
      rm -rf ip.txt
      curl -s -O https://gitlab.com/rwkgyg/CFwarp/-/raw/main/point/cpu3/ipv6.txt
      IP_ADDR=ipv6
      else
      echo "无IPV6网络" && cdnv4v6
      fi
      else
      echo "输入有误" && cdnv4v6
      fi
      }
      cdnport(){
      echo
      echo "开启tls的端口:443、8443、2053、2083、2087、2096"
      echo "关闭tls的端口:80、8080、8880、2052、2082、2086、2095"
      read -p "请选择以上13个端口之一:" point
      if ! [[ "$point" =~ ^(2052|2082|2086|2095|80|8880|8080|2053|2083|2087|2096|8443|443)$ ]]; then
      echo "输入的端口为$opint,输入有误" && cdnport
      fi
      }
      cdnspedurl(){
      echo
      echo "是否测速?(选择 1 表示测速,回车默认关闭测速)"
      read -p "请选择: " menu
      if [ -z $menu ]; then
      CFST_URL_R=""
      sed -i '29s/^CFST_SPD=.*/CFST_SPD=-dd/' /root/cfipopw/cdnip.sh
      elif [ "$menu" == "1" ];then
      echo "是否使用其他测速地址?(可直接输入其他测速地址 【 注意,不要带http(s):// 】 ,回车使用默认测速地址)"
      read -p "请输入: " menu
      if [ -z $menu ]; then
      CFST_URL="е.eu.org/500.zip"
      else
      CFST_URL="$menu"
      fi
      [[ $point =~ 2053|2083|2087|2096|8443|443 ]] && htp="https://" || htp="http://"
      CFST_URL_R="-url $htp$CFST_URL"
      sed -i '29s/^CFST_SPD=.*/CFST_SPD=""/' /root/cfipopw/cdnip.sh
      else
      echo "输入有误" && cdnspedurl
      fi
      }
      cdnym(){
      echo
      echo "请输入Cloudflare解析好的域名(二级域名格式)"
      echo "例:1.test.eu.org空格2.test.eu.org空格3.test.eu.org…………以此类推,多域名之间有空格"
      read -p "请输入域名: " cfym
      if [ -z $cfym ]; then
      echo "不可为空,请重新输入" && cdnym
      fi
      hostname="($cfym)"
      }
      cdnymonly(){
      echo
      read -p "请输入Cloudflare解析好的一级域名: " opymyj
      if [ -z $opymyj ]; then
      echo "不可为空,请重新输入" && cdnymonly
      fi
      domain=$opymyj
      read -p "请输入二级域自定义的名称: " opymmc
      if [ -z $opymmc ]; then
      echo "不可为空,请重新输入" && cdnymonly
      fi
      subdomain=$opymmc
      }
      cdnsptime(){
      echo
      read -p "请输入重启代理插件后的等待时间多少秒(回车默认30秒): " sptime
      if [ -z $sptime ]; then
      sed -i "35s/^sleepTime=.*/sleepTime=30/" /root/cfipopw/cdnip.sh
      else
      sed -i "35s/^sleepTime=.*/sleepTime=$sptime/" /root/cfipopw/cdnip.sh
      fi
      }
      cdnyik(){
      echo
      read -p "请输入Cloudflare登录邮箱: " cfmail
      x_email=$cfmail
      echo
      read -p "请输入Cloudflare域名-概述-区域ID: " cfid
      zone_id=$cfid
      echo
      read -p "请输入Cloudflare域名-概述-获取您的API令牌-Global API Key: " cfkey
      api_key=$cfkey
      }
      cdntg(){
      echo
      read -p "是否启用Telegram机器人通知(回车默认不启用,选择1启用): " menu
      if [ -z $menu ]; then
      tgken=""
      tguserid=""
      elif [ "$menu" == "1" ];then
      read -p "输入Telegram机器人Token: " token
      tgken=$token
      read -p "输入Telegram机器人用户ID: " userid
      tguserid=$userid
      else
      echo "输入有误" && cdntg
      fi
      }
      cdnpush(){
      echo
      read -p "是否启用Pushplus微信通知(回车默认不启用,选择1启用): " menu
      if [ -z $menu ]; then
      token=""
      elif [ "$menu" == "1" ];then
      read -p "输入Pushplus的Token: " menu
      token=$menu
      else
      echo "输入有误" && cdnpush
      fi
      }
      cdnopcl(){
      echo
      echo "输入使用的代理插件【 0代表不使用任何插件 1代表Passwall 2代表Passwall2 3代表SSR-Plus 4代表Clash 5代表Openclash 6代表Bypass 7代表V2raya 8代表Hello-World 9代表Homeproxy 10代表MihomoTProxy 11代表ShellCrash 】"
      read -p "请输入一个数值(0-11): " num
      if [[ $num =~ ^[0-9]$ || $num == 10 || $num == 11 ]]; then
      clien=$num
      else
      echo "输入有误" && cdnopcl
      fi
      }
      install(){
      rm -rf /root/cfipopw/cdnip.sh
      mkdir -p cfipopw
      cd cfipopw
      curl -sSL https://gitlab.com/rwkgyg/cdnopw/-/raw/main/cdnip.sh -o cdnip.sh
      curl -sSL https://gitlab.com/rwkgyg/cdnopw/-/raw/main/cdnac.sh -o cdnac.sh
      if [ ! -f cfst ]; then
      curl -L -o cfst -# --retry 2 https://gitlab.com/rwkgyg/CFwarp/-/raw/main/point/cpu3/$cpu
      chmod +x cfst
      fi
      if [ ! -f cfst ] || [ ! -f cdnip.sh ] || [ ! -f cdnac.sh ]; then
      echo "下载必要文件失败,请确保你的网络通畅,建议开启代理" && exit
      fi
      echo
      echo "1:域名解析推送模式(需要域名,推荐)"
      echo "2:IP直接推送模式(无需域名)"
      read -p "请选择: " ymorip
      if [ "$ymorip" == "1" ]; then
      echo
      echo "选择优选IP分配到域名解析的方案"
      echo "1:多个优选IP解析到一个域名"
      echo "2:每个优选IP解析到每个域名"
      read -p "请选择: " ymoryms
      if [ "$ymoryms" == "1" ]; then
      cdnymonly
      else
      cdnym
      sed -i "33s/^ymoryms=.*/ymoryms=2/" /root/cfipopw/cdnip.sh
      fi
      echo
      else
      sed -i "30s/^ymorip=.*/ymorip=2/" /root/cfipopw/cdnip.sh
      echo
      fi
      echo "使用哪种优选IP方式"
      echo "1:Cloudflare CDN官方IP(强烈推荐!支持IPV4与IPV6)"
      echo "2:Cloudflare CDN反代IP(仅支持ipv4)"
      read -p "请选择(回车默认为官方IP): " menu
      if [ -z $menu ] || [ "$menu" == "1" ]; then
      cdnv4v6
      else
      rm -rf ipv6.txt
      curl -Ls https://cf.yg-kkk.gq -o txt.zip
      unzip -o txt.zip -d txt > /dev/null 2>&1
      IP_ADDR=ipv4
      fi
      sleep 1
      cdnport
      sleep 1
      cdnspedurl
      sleep 1
      echo
      read -p "请输入测试线程数量【不懂就回车,默认200 最多1000】: " menu
      if [ -z $menu ]; then
      CFST_N=200
      else
      CFST_N=$menu
      fi
      sleep 1
      echo
      read -p "请输入测试并显示的IP数量【不懂就回车,默认10】: " menu
      if [ -z $menu ]; then
      CFST_DN=10
      else
      CFST_DN=$menu
      fi
      sleep 1
      echo
      read -p "请输入平均延迟上限【不懂就回车】: " menu
      if [ -z $menu ]; then
      CFST_TL=9999
      else
      CFST_TL=$menu
      fi
      sleep 1
      echo
      read -p "请输入平均延迟下限【不懂就回车】: " menu
      if [ -z $menu ]; then
      CFST_TLL=0
      else
      CFST_TLL=$menu
      fi
      sleep 1
      echo
      read -p "请输入下载速度下限【不懂就回车】: " menu
      if [ -z $menu ]; then
      CFST_SL=0
      else
      CFST_SL=$menu
      fi
      sleep 1
      cdnopcl
      sleep 1
      cdnsptime
      sleep 1
      if [ "$ymorip" == "1" ]; then
      cdnyik
      sleep 1
      fi
      cdntg
      sleep 1
      cdnpush
      sleep 1
      sed -i "s/oppoint/$point/" /root/cfipopw/cdnip.sh
      sed -i "s/opv4v6/$IP_ADDR/" /root/cfipopw/cdnip.sh
      if [ "$ymorip" == "1" ]; then
      if [ "$ymoryms" == "1" ]; then
      hostname="(NO_name)"
      sed -i "s/opymyj/$domain/" /root/cfipopw/cdnip.sh
      sed -i "s/opymmc/$subdomain/" /root/cfipopw/cdnip.sh
      sed -i "s/opym/$hostname/" /root/cfipopw/cdnip.sh
      else
      domain="NO_name"
      subdomain="NO_name"
      sed -i "s/opymyj/$domain/" /root/cfipopw/cdnip.sh
      sed -i "s/opymmc/$subdomain/" /root/cfipopw/cdnip.sh
      sed -i "s/opym/$hostname/" /root/cfipopw/cdnip.sh
      fi
      sed -i "s/opmail/$x_email/" /root/cfipopw/cdnip.sh
      sed -i "s/opcfid/$zone_id/" /root/cfipopw/cdnip.sh
      sed -i "s/opcfkey/$api_key/" /root/cfipopw/cdnip.sh
      fi
      sed -i "s/opnum/$CFST_N/" /root/cfipopw/cdnip.sh
      sed -i "s/opsnum/$CFST_DN/" /root/cfipopw/cdnip.sh
      sed -i "s/opup/$CFST_TL/" /root/cfipopw/cdnip.sh
      sed -i "s/opdo/$CFST_TLL/" /root/cfipopw/cdnip.sh
      sed -i "s/opsd/$CFST_SL/" /root/cfipopw/cdnip.sh
      sed -i "s/opcli/$clien/" /root/cfipopw/cdnip.sh
      sed -i "s#opspd#$CFST_URL_R#" /root/cfipopw/cdnip.sh
      sed -i "s/optgken/$tgken/" /root/cfipopw/cdnip.sh
      sed -i "s/optgid/$tguserid/" /root/cfipopw/cdnip.sh
      sed -i "s/oppushtk/$token/" /root/cfipopw/cdnip.sh
      bash cdnip.sh
      }
      spedlinktr(){
      echo
      echo "是否测速?(选择 1 表示测速,回车默认关闭测速)"
      read -p "请选择: " menu
      if [ -z $menu ]; then
      sed -i '12s/CFST_URL_R="[^"]*"/CFST_URL_R=""/' /root/cfipopw/cdnip.sh
      sed -i '29s/^CFST_SPD=.*/CFST_SPD=-dd/' /root/cfipopw/cdnip.sh
      elif [ "$menu" == "1" ];then
      echo "是否使用其他测速地址?(可直接输入其他测速地址 【 不要带http(s):// 】 ,回车使用默认测速地址)"
      read -p "请输入: " menu
      if [ -z $menu ]; then
      CFST_URL="е.eu.org/500.zip"
      else
      CFST_URL="$menu"
      fi
      sed -i "12s#$oldport#$CFST_URL#" /root/cfipopw/cdnip.sh
      sed -i '29s/^CFST_SPD=.*/CFST_SPD=""/' /root/cfipopw/cdnip.sh
      else
      echo "输入有误" && exit
      fi
      }
      spedlinkfa(){
      echo
      echo "是否使用其他测速地址?(可直接输入其他测速地址 【 不要带http(s):// 】 ,回车使用默认测速地址)"
      read -p "请输入: " menu
      if [ -z $menu ]; then
      CFST_URL="е.eu.org/500.zip"
      else
      CFST_URL="$menu"
      fi
      [[ $(sed -n '3s/.*=//p' /root/cfipopw/cdnip.sh) =~ 2053|2083|2087|2096|8443|443 ]] && htp="https://" || htp="http://"
      spedlink="-url $htp$CFST_URL"
      sed -i '12s#CFST_URL_R=""#CFST_URL_R="'"$spedlink"'"#' /root/cfipopw/cdnip.sh
      sed -i '29s/^CFST_SPD=.*/CFST_SPD=""/' /root/cfipopw/cdnip.sh
      }
      changeinstall(){
      if [ ! -f /root/cfipopw/cdnip.sh ]; then
      echo "未安装脚本,无法变更参数配置" && exit
      fi
      echo
      [[ $(sed -n '30p' /root/cfipopw/cdnip.sh | grep "1") ]] && echo "1.当前为域名解析推送模式(需要域名,推荐),更换为IP直接推送模式(无需域名)" || echo "1.当前为IP直接推送模式(无需域名),更换为域名解析推送模式(需要域名,推荐),注意:请确认选项 8 与 9 已有参数后再确认执行"
      [ -f /root/cfipopw/txt.zip ] && echo "2.当前为CDN反代IP模式,更换为CDN官方IP模式" || echo "2.当前为CDN官方IP模式,更换为CDN反代IP模式"
      if [[ $(sed -n '33p' /root/cfipopw/cdnip.sh | grep "1") ]] && [[ $(sed -n '30p' /root/cfipopw/cdnip.sh | grep "1") ]]; then
      echo "3.当前为多个优选IP解析到一个域名方案,更换为每个优选IP解析到每个域名方案"
      elif [[ ! $(sed -n '33p' /root/cfipopw/cdnip.sh | grep "1") ]] && [[ $(sed -n '30p' /root/cfipopw/cdnip.sh | grep "1") ]]; then
      echo "3.当前为每个优选IP解析到每个域名方案,更换为多个优选IP解析到一个域名方案"
      else
      echo "3.当前为IP直接推送模式,不支持域名解析方案的选择"
      fi
      echo "4.切换优选IPV4或者IPV6"
      echo "5.更换端口"
      echo "6.开启、关闭测速,更换测速网站"
      echo "7.更换软路由OpenWrt代理插件"
      echo "8.更改重启代理插件后的等待时间"
      echo "9.更换CF解析的域名"
      echo "10.更换CF邮箱、区域ID、API Key"
      echo "11.关闭、开启Telegram机器人通知,更换Token、用户ID"
      echo "12.切换Telegram api接口的域名地址"
      echo "13.关闭、开启Pushplus微信通知,更换Token"
      echo "============================================"
      echo "以上选项更改完毕之后,请输入 Y/y ,表示确认执行"
      echo "============================================"
      echo "14.退出"
      echo
      read -p "请输入: " menu
      if [[ "$menu" == [Yy] ]]; then
      bash cdnip.sh
      elif [ "$menu" == "1" ]; then
      if [[ $(sed -n '30p' /root/cfipopw/cdnip.sh | grep "1") ]]; then
      sed -i "30s/^ymorip=.*/ymorip=2/" /root/cfipopw/cdnip.sh
      echo "当前为IP直接推送模式(无需域名)" && sleep 2
      else
      sed -i "30s/^ymorip=.*/ymorip=1/" /root/cfipopw/cdnip.sh
      echo "当前为域名解析推送模式(需要域名,推荐),注意,请确认选项 7 与 8 已有参数后再确认执行" && sleep 2
      fi
      changeinstall
      elif [ "$menu" == "2" ]; then
      oldport=$(sed -n '4s/.*=//p' /root/cfipopw/cdnip.sh)
      if [ -f txt.zip ]; then
      rm -rf txt.zip
      cdnv4v6
      else
      rm -rf ipv6.txt
      curl -Ls https://cf.yg-kkk.gq -o txt.zip
      unzip -o txt.zip -d txt > /dev/null 2>&1
      IP_ADDR=ipv4
      fi
      sed -i "4s/$oldport/$IP_ADDR/" /root/cfipopw/cdnip.sh
      changeinstall
      elif [ "$menu" == "3" ]; then
      echo
      if [[ ! $(sed -n '33p' /root/cfipopw/cdnip.sh | grep "1") ]] && [[ $(sed -n '30p' /root/cfipopw/cdnip.sh | grep "1") ]]; then
      sed -i "33s/^ymoryms=.*/ymoryms=1/" /root/cfipopw/cdnip.sh
      echo "已切换为多个优选IP解析到一个域名方案,注意,请确认 域名 与 CF相关信息 已有参数后再确认执行" && sleep 2
      elif [[ $(sed -n '33p' /root/cfipopw/cdnip.sh | grep "1") ]] && [[ $(sed -n '30p' /root/cfipopw/cdnip.sh | grep "1") ]]; then
      sed -i "33s/^ymoryms=.*/ymoryms=2/" /root/cfipopw/cdnip.sh
      echo "已切换为每个优选IP解析到每个域名方案,注意,请确认 域名 与 CF相关信息 已有参数后再确认执行" && sleep 2
      else
      echo "当前为无域名解析方案,请先在选项1,选择域名解析推送模式" && sleep 2
      fi
      changeinstall
      elif [ "$menu" == "4" ]; then
      echo
      oldport=$(sed -n '4s/.*=//p' /root/cfipopw/cdnip.sh)
      echo "当前为优选$oldport"
      echo
      if [ -f txt.zip ]; then
      echo "当前为CDN反代IP模式,仅支持优选ipv4" && sleep 2 && changeinstall
      else
      cdnv4v6
      fi
      sed -i "4s/$oldport/$IP_ADDR/" /root/cfipopw/cdnip.sh
      changeinstall
      elif [ "$menu" == "5" ]; then
      echo
      oldport=$(sed -n '3s/.*=//p' /root/cfipopw/cdnip.sh)
      echo "当前使用的端口:$oldport"
      cdnport
      sed -i "3s/$oldport/$point/" /root/cfipopw/cdnip.sh
      [[ $point =~ 2053|2083|2087|2096|8443|443 ]] && htp="https" || htp="http"
      sed -i "12s/http\|https/$htp/" /root/cfipopw/cdnip.sh
      changeinstall
      elif [ "$menu" == "6" ]; then
      echo
      oldport=$(sed -n '12s/.*:\/\/\([^ ]*\).*/\1/p' /root/cfipopw/cdnip.sh | tr -d '"')
      if [[ $oldport =~ 'bestip' ]] && [[ ! $(sed -n '29p' /root/cfipopw/cdnip.sh) == *"-dd"* ]]; then
      echo "测速已开启,当前为默认测速网站"
      spedlinktr
      elif [[ ! $oldport =~ 'bestip' ]] && [[ ! $(sed -n '29p' /root/cfipopw/cdnip.sh) == *"-dd"* ]]; then
      echo "测速已开启,当前使用的测速网站:$oldport"
      spedlinktr
      else
      echo "当前已关闭测速"
      spedlinkfa
      fi
      changeinstall
      elif [ "$menu" == "7" ]; then
      echo
      oldport=$(sed -n '10s/.*=//p' /root/cfipopw/cdnip.sh)
      case $oldport in
        "11") oldport1=ShellCrash;;
        "10") oldport1=MihomoTProxy;;
        "9") oldport1=Homeproxy;;
        "8") oldport1=Hello-World;;
        "7") oldport1=V2raya;;
        "6") oldport1=Bypass;;
        "5") oldport1=Openclash;;
        "4") oldport1=Clash;;
        "3") oldport1=SSR-Plus;;
        "2") oldport1=Passwall2;;
        "1") oldport1=Passwall;;
        "0") oldport1=不使用任何插件;;
      esac
      echo "当前使用的代理插件:$oldport1"
      cdnopcl
      sed -i "10s/$oldport/$clien/" /root/cfipopw/cdnip.sh
      changeinstall
      elif [ "$menu" == "8" ]; then
      echo
      oldport=$(sed -n '35s/.*=//p' /root/cfipopw/cdnip.sh)
      echo "当前重启代理插件后的等待时间:$oldport秒"
      cdnsptime
      changeinstall
      elif [ "$menu" == "9" ]; then
      if [[ $(sed -n '33p' /root/cfipopw/cdnip.sh | grep "1") ]] && [[ $(sed -n '30p' /root/cfipopw/cdnip.sh | grep "1") ]]; then
      echo "当前为多个优选IP解析到一个域名方案"
      echo
      oldport=$(sed -n '31s/.*=//p' /root/cfipopw/cdnip.sh)
      oldport1=$(sed -n '32s/.*=//p' /root/cfipopw/cdnip.sh)
      echo "当前使用的一级域名:$oldport"
      echo "当前使用的二级域自定义名称:$oldport1"
      cdnymonly
      sed -i "31s/$oldport/$domain/" /root/cfipopw/cdnip.sh
      sed -i "32s/^subdomain=.*/subdomain=$subdomain/" /root/cfipopw/cdnip.sh
      elif [[ ! $(sed -n '33p' /root/cfipopw/cdnip.sh | grep "1") ]] && [[ $(sed -n '30p' /root/cfipopw/cdnip.sh | grep "1") ]]; then
      echo "当前为每个优选IP解析到每个域名方案"
      echo
      oldport=$(sed -n '6s/.*=//p' /root/cfipopw/cdnip.sh | tr -d '()')
      echo "当前使用的域名:$oldport"
      cdnym
      sed -i "6s/($oldport)/$hostname/" /root/cfipopw/cdnip.sh
      else
      echo "当前为无域名解析方案,如要切换域名解析推送模式,请在更改配置菜单-选项1中进行切换" && sleep 2
      fi
      changeinstall
      elif [ "$menu" == "10" ]; then
      echo
      oldport1=$(sed -n '5s/.*=//p' /root/cfipopw/cdnip.sh)
      oldport2=$(sed -n '7s/.*=//p' /root/cfipopw/cdnip.sh)
      oldport3=$(sed -n '8s/.*=//p' /root/cfipopw/cdnip.sh)
      echo "当前使用的邮箱:$oldport1"
      echo "当前使用的区域ID:$oldport2"
      echo "当前使用的API Key:$oldport3"
      cdnyik
      sed -i "5s/$oldport1/$x_email/" /root/cfipopw/cdnip.sh
      sed -i "7s/$oldport2/$zone_id/" /root/cfipopw/cdnip.sh
      sed -i "8s/$oldport3/$api_key/" /root/cfipopw/cdnip.sh
      changeinstall
      elif [ "$menu" == "11" ]; then
      echo
      oldport1=$(sed -n '26s/.*=//p' /root/cfipopw/cdnip.sh)
      oldport2=$(sed -n '27s/.*=//p' /root/cfipopw/cdnip.sh)
      if [[ -z $oldport1 || -z $oldport2 ]]; then
      echo "未设置telegram机器人通知"
      else
      echo "当前Telegram机器人Token:$oldport1"
      echo "当前Telegram机器人用户ID:$oldport2"
      fi
      cdntg
      sed -i "26s/^telegramBotToken=.*/telegramBotToken=$tgken/" /root/cfipopw/cdnip.sh
      sed -i "27s/^telegramBotUserId=.*/telegramBotUserId=$tguserid/" /root/cfipopw/cdnip.sh
      changeinstall
      elif [ "$menu" == "12" ]; then
      echo
      oldport1=$(sed -n '36s/.*=//p' /root/cfipopw/cdnip.sh)
      echo "当前使用的TG api接口的域名地址:$oldport1"
      echo
      read -p "请输入要更改的TG api接口的域名地址【 回车默认使用TG官方api,输入时不要带https:// 】: " menu
      if [ -z $menu ]; then
      tgapi=api.telegram.org
      else
      tgapi=$menu
      fi
      sed -i "36s#^tgapi=.*#tgapi=$tgapi#" /root/cfipopw/cdnip.sh
      changeinstall
      elif [ "$menu" == "13" ]; then
      echo
      oldport1=$(sed -n '34s/.*=//p' /root/cfipopw/cdnip.sh)
      if [[ -z $oldport1 ]]; then
      echo "未设置Pushplus微信通知"
      else
      echo "当前Pushplus的Token:$oldport1"
      fi
      cdnpush
      sed -i "34s/^token=.*/token=$token/" /root/cfipopw/cdnip.sh
      changeinstall
      else
      exit
      fi
      }
      #sed -n '3s/.*=//p' /root/cfipopw/cdnip.sh
      #sed -n '4s/.*=//p' /root/cfipopw/cdnip.sh
      #sed -n '5s/.*=//p' /root/cfipopw/cdnip.sh
      #sed -n '6s/.*=//p' /root/cfipopw/cdnip.sh | tr -d '()'
      #sed -n '7s/.*=//p' /root/cfipopw/cdnip.sh
      #sed -n '8s/.*=//p' /root/cfipopw/cdnip.sh
      #sed -n '10s/.*=//p' /root/cfipopw/cdnip.sh
      #sed -n '12s/.*:\/\/\([^ ]*\).*/\1/p' /root/cfipopw/cdnip.sh | tr -d '"'
      #sed -n '14s/.*=//p' /root/cfipopw/cdnip.sh
      #sed -n '18s/.*=//p' /root/cfipopw/cdnip.sh
      #sed -n '20s/.*=//p' /root/cfipopw/cdnip.sh
      #sed -n '22s/.*=//p' /root/cfipopw/cdnip.sh
      #sed -n '24s/.*=//p' /root/cfipopw/cdnip.sh
      #sed -n '26s/.*=//p' /root/cfipopw/cdnip.sh
      #sed -n '27s/.*=//p' /root/cfipopw/cdnip.sh
      #sed -i '29s/^CFST_SPD=.*/CFST_SPD=""/' /root/cfipopw/cdnip.sh
      #sed -i '29s/^CFST_SPD=.*/CFST_SPD=-dd/' /root/cfipopw/cdnip.sh
      showcdn(){
      if [ -f /root/cfipopw/cdnip.sh ]; then
      echo
      echo "自动优选IP脚本正在运行中,详细配置如下:"
      echo "====================================================="
      [[ $(sed -n '30p' /root/cfipopw/cdnip.sh | grep "1") ]] && echo "1、当前为域名解析推送模式(需要域名,推荐)" || echo "1、当前为IP直接推送模式(无需域名)"
      echo
      if [[ $(sed -n '33p' /root/cfipopw/cdnip.sh | grep "1") ]] && [[ $(sed -n '30p' /root/cfipopw/cdnip.sh | grep "1") ]]; then
      echo "2、当前为多个优选IP解析到一个域名方案"
      elif [[ ! $(sed -n '33p' /root/cfipopw/cdnip.sh | grep "1") ]] && [[ $(sed -n '30p' /root/cfipopw/cdnip.sh | grep "1") ]]; then
      echo "2、当前为每个优选IP解析到每个域名方案"
      else
      echo "2、当前为无域名解析方案"
      fi
      echo
      [ -f /root/cfipopw/txt.zip ] && echo "3、当前为CDN反代IP模式" || echo "3、当前为CDN官方IP模式"
      echo
      echo "4、当前为优选$(sed -n '4s/.*=//p' /root/cfipopw/cdnip.sh)"
      echo
      echo "5、使用的端口:$(sed -n '3s/.*=//p' /root/cfipopw/cdnip.sh)"
      echo
      old12=$(sed -n '12s/.*:\/\/\([^ ]*\).*/\1/p' /root/cfipopw/cdnip.sh | tr -d '"')
      if [[ $old12 =~ 'bestip' ]] && [[ ! $(sed -n '29p' /root/cfipopw/cdnip.sh) == *"-dd"* ]]; then
      echo "6、测速已开启,当前为默认测速网站"
      elif [[ ! $old12 =~ 'bestip' ]] && [[ ! $(sed -n '29p' /root/cfipopw/cdnip.sh) == *"-dd"* ]]; then
      echo "6、测速已开启,当前使用的测速网站:$old12"
      else
      echo "6、当前已关闭测速"
      fi
      echo
      oldport=$(sed -n '10s/.*=//p' /root/cfipopw/cdnip.sh)
      case $oldport in
        "10") oldport=MihomoTProxy;;
        "9") oldport=Homeproxy;;
        "8") oldport=Hello-World;;
        "7") oldport=V2raya;;
        "6") oldport=Bypass;;
        "5") oldport=Openclash;;
        "4") oldport=Clash;;
        "3") oldport=SSR-Plus;;
        "2") oldport=Passwall2;;
        "1") oldport=Passwall;;
        "0") oldport=不使用任何插件;;
      esac
      echo "7、当前使用的代理插件:$oldport"
      echo
      oldport35=$(sed -n '35s/.*=//p' /root/cfipopw/cdnip.sh)
      echo "8、当前重启代理插件后的等待时间:$oldport35秒"
      echo
      if [[ $(sed -n '33p' /root/cfipopw/cdnip.sh | grep "1") ]] && [[ $(sed -n '30p' /root/cfipopw/cdnip.sh | grep "1") ]]; then
      old31=$(sed -n '31s/.*=//p' /root/cfipopw/cdnip.sh)
      old32=$(sed -n '32s/.*=//p' /root/cfipopw/cdnip.sh)
      echo "9、当前使用的二级域自定义名称:$old32  一级域名:$old31 "
      elif [[ ! $(sed -n '33p' /root/cfipopw/cdnip.sh | grep "1") ]] && [[ $(sed -n '30p' /root/cfipopw/cdnip.sh | grep "1") ]]; then
      old6=$(sed -n '6s/.*=//p' /root/cfipopw/cdnip.sh | tr -d '()')
      echo "9、当前使用的域名:$old6"
      else
      echo "9、当前无域名显示"
      fi
      echo
      echo "10、使用的邮箱:$(sed -n '5s/.*=//p' /root/cfipopw/cdnip.sh)"
      echo
      echo "11、使用的区域ID:$(sed -n '7s/.*=//p' /root/cfipopw/cdnip.sh)"
      echo
      echo "12、使用的API Key:$(sed -n '8s/.*=//p' /root/cfipopw/cdnip.sh)"
      echo
      old26=$(sed -n '26s/.*=//p' /root/cfipopw/cdnip.sh)
      old27=$(sed -n '27s/.*=//p' /root/cfipopw/cdnip.sh)
      if [[ -z $old26 && -z $old27 ]]; then
      echo "13、未设置telegram机器人通知"
      else
      echo "13、Telegram机器人Token:$old26"
      echo
      echo "13、Telegram机器人用户ID:$old27"
      echo
      old36=$(sed -n '36s/.*=//p' /root/cfipopw/cdnip.sh)
      echo "13、当前使用的TG api:$old36"
      fi
      echo
      old34=$(sed -n '34s/.*=//p' /root/cfipopw/cdnip.sh)
      if [[ -z $old34 ]]; then
      echo "14、未设置Pushplus微信通知"
      else
      echo "14、Pushplus的Token:$old34"
      fi
      echo
      echo "测速线程数量:$(sed -n '14s/.*=//p' /root/cfipopw/cdnip.sh)"
      echo
      echo "测速显示数量:$(sed -n '18s/.*=//p' /root/cfipopw/cdnip.sh)"
      echo
      echo "平均延迟上限:$(sed -n '20s/.*=//p' /root/cfipopw/cdnip.sh)"
      echo
      echo "平均延迟下限:$(sed -n '22s/.*=//p' /root/cfipopw/cdnip.sh)"
      echo
      echo "下载速度下限:$(sed -n '24s/.*=//p' /root/cfipopw/cdnip.sh)"
      echo
      echo "切记:在软路由-计划任务选项中,加入优选IP自动执行时间的cron表达式"
      echo "比如每天早上三点执行:0 3 * * * cd /root/cfipopw/ && bash cdnip.sh"
      echo "====================================================="
      echo
      fi
      }
      runcdnopw(){
      if [ -f /root/cfipopw/cdnip.sh ]; then
      cd /root/cfipopw/ && bash cdnip.sh
      else
      echo "未安装此脚本,无法执行"
      fi
      }
      rmrf(){
      rm -rf /root/cfipopw cdnopw.sh ygop_update
      echo "卸载完成"
      }
      ipv4ipv6(){
      if [[ -n $v6 ]]; then
      echo "当前网络:支持IPV4与IPV6"
      else
      echo "当前网络:仅支持IPV4,无IPV6"
      fi
      }
      deallym(){
      echo
      read -p "请输入Cloudflare解析好的一级域名: " domain
      echo
      read -p "请输入二级域指定的名称: " subdomain
      cdnyik
      url="https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records"
      params="name=${subdomain}.${domain}&type="
      response=$(curl -sm10 -X GET "$url?$params" -H "X-Auth-Email: $x_email" -H "X-Auth-Key: $api_key")
      if [[ $(echo "$response" | jq -r '.success') == "true" ]]; then
          records=$(echo "$response" | jq -r '.result')
          if [[ $(echo "$records" | jq 'length') -gt 0 ]]; then
              for record in $(echo "$records" | jq -c '.[]'); do
                  record_id=$(echo "$record" | jq -r '.id')
                  delete_url="$url/$record_id"
                  delete_response=$(curl -sm10 -X DELETE "$delete_url" -H "X-Auth-Email: $x_email" -H "X-Auth-Key: $api_key")
                  if [[ $(echo "$delete_response" | jq -r '.success') == "true" ]]; then
                      echo "成功删除 DNS 记录:$(echo "$record" | jq -r '.name')"
                  else
                      echo "删除 DNS 记录失败"
                  fi
              done
          else
              echo "没有找到指定的 DNS 记录"
          fi
      else
          echo "获取 DNS 记录失败"
      fi
      }
      echo "--------------------------------------------------------------"
      echo "甬哥Github项目  :github.com/yonggekkk"
      echo "甬哥Blogger博客 :ygkkk.blogspot.com"
      echo "甬哥YouTube频道 :www.youtube.com/@ygkkk"
      echo "--------------------------------------------------------------"
      echo "OpenWrt软路由-优选IP解析到CF域名脚本    V2024.4.1"
      ipv4ipv6
      echo "--------------------------------------------------------------"
      showcdn
      echo "1.安装/重置脚本"
      echo "2.更改各项参数配置"
      echo "3.运行一次已配置完成的脚本"
      echo "4.删除CF域名指定名称解析记录"
      echo "5.卸载"
      echo "0.退出"
      read -p "请选择: " menu
      if [ "$menu" == "1" ];then
      install
      elif [ "$menu" == "2" ];then
      cd cfipopw
      changeinstall
      elif [ "$menu" == "3" ];then
      runcdnopw
      elif [ "$menu" == "4" ];th

      А вот cdnac.sh, что скачивается внутри этого скрипта.

      cdnac.sh
      #!/bin/bash
      export LANG=en_US.UTF-8
      if [[ -f /root/cfipopw/txt.zip && -f /root/cfipopw/informlog ]]; then
      echo
      echo "请稍等,对优选反代IP进行地区识别,最多显示前10个IP"
      rm -rf cdnIP.csv b.csv a.csv
      awk -F ',' 'NR>1 && NR<=11 {print $1}' result.csv > a.csv
      while IFS= read -r ip_address; do
      UA_Browser="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36"
      response=$(curl -sm5 --user-agent "${UA_Browser}" "https://api.ip.sb/geoip/$ip_address" -k | awk -F "country_code" '{print $2}' | awk -F'":"|","|"' '{print $2}')
      if [ $? -eq 0 ]; then
      echo "IP地址 $ip_address 的地区是: $response" | tee -a b.csv
      else
      echo "无法获取IP地址 $ip_address 的地区信息" | tee -a b.csv
      fi
      sleep 1
      done < "a.csv"
      echo -e "\n优选反代IP--国家地区识别" >> cdnIP.csv
      cat b.csv >> cdnIP.csv
      #grep 'SG' b.csv | head -n 10 >> cdnIP.csv
      #grep 'HK' b.csv | head -n 10 >> cdnIP.csv
      #grep 'JP' b.csv | head -n 10 >> cdnIP.csv
      #grep 'KR' b.csv | head -n 10 >> cdnIP.csv
      #grep 'TW' b.csv | head -n 10 >> cdnIP.csv
      #grep 'US' b.csv | head -n 10 >> cdnIP.csv
      #grep 'GB' b.csv | head -n 10 >> cdnIP.csv
      #grep 'DE' b.csv | head -n 10 >> cdnIP.csv
      #grep 'NL' b.csv | head -n 10 >> cdnIP.csv
      #grep 'FR' b.csv | head -n 10 >> cdnIP.csv
      echo
      cat cdnIP.csv >> informlog
      fi
      if [[ -f /root/cfipopw/txt.zip && ! -f /root/cfipopw/informlog ]]; then
      echo "下载更新反代IP库txt.zip文件……"
      wget -q https://zip.baipiao.eu.org -O txt.zip
      if [ $? -eq 0 ]; then
      echo "下载成功"
      else
      curl -L -# --retry 2 https://cf.yg-kkk.gq -o txt.zip
      if [ $? -eq 0 ]; then
      echo "下载成功"
      else
      echo "下载失败,继续使用之前的反代IP库"
      fi
      fi
      rm -rf txt
      unzip -o txt.zip -d txt > /dev/null 2>&1
      if [[ ! -e "txt" ]]; then
      echo "反代IP库txt.zip文件下载失败" && exit
      fi
      point=$(sed -n '3s/.*=//p' /root/cfipopw/cdnip.sh)
      if [ "$point" == "443" ]; then
      find txt -type f -name "*443*" ! -name "*8443*" -exec cat {} \; > ip.txt
      elif [ "$point" == "80" ]; then
      find txt -type f -name "*80*" ! -name "*8880*" ! -name "*8080*" -exec cat {} \; > ip.txt
      else
      find txt -type f -name "*${point}*"  -exec cat {} \; > ip.txt
      fi
      grep -E '^8|^47|^43|^130|^132|^152|^193|^140|^138|^150|^143|^141|^155|^168|^124|^170|^119' ip.txt > pass.txt && mv pass.txt ip.txt
      fi
      

      А ещё в cdnopw используется необфусцированный https://gitlab.com/rwkgyg/cdnopw/-/raw/main/cdnip.sh
      Может, ещё что-то можно разобрать/понять. Я просто дал простенький инструмент деобфускации если кому будет ну очень интересно.


      1. BOLNICHKA399
        27.03.2026 21:44

        А суть то заминусованности в чем? В скрипте добавлены бэкдоры? Можете пояснить что не так? Я на себе попробовал, passwall2 поставился, поднял vless клиент, все работает. Что не так?


        1. Derevtso
          27.03.2026 21:44

          Лично я не минусовал. И не плюсовал.


          Меня, конечно, слегка смущает обфусцированность скриптов, вызывает ощущение, будто, "что-то, наверное, не так". Но кто знает, может, это что-то на тему "прятать от правительства", я хз, у китайцев с этим тоже проблемы.


        1. Alexander_th
          27.03.2026 21:44

          Суть в том, что душнила, который разбирается больше вас считает что все вокруг идиоты и пишут всякую ерунду, и чтобы он злится и ставит минусы, еще вероятно расстраивается, что нейросеть дает доступ к информации, которую раньше только он один мог освоить. Другого объяснения не вижу - чувак дал инструкцию, ну не хочешь ты по ней ничего настраивать, ну не настраивай, е мое, че говнить то? Или лучше на stack overflow к своим. А, ой, он же уже не популярен.


  1. maxus87
    27.03.2026 21:44

    Под какой роутер писалась инструкция?


  1. Xendler
    27.03.2026 21:44

    И чем это лучше podkop?


    1. Amaev777
      27.03.2026 21:44

      Podkop не поддерживает xray reality, и мне он показался каким то не стабильным, рандомно лезет торренты проксировать причем выборочно, ip диапазоны что задавались для проксирования тоже проксирует как-то выборочно, любит вешать сеть на время, ping с vless сервероов становится двухкратным из-за каких-то особенностей сингбокса, ну и вечные беды с проксированием what's app (хотя может уже пофиксили)


    1. lorgar_xvii
      27.03.2026 21:44

      Подкоп использует singbox. Passwall же использует xray, singbox и hysteria2


    1. denbog1
      27.03.2026 21:44

      Например Подкоп не поддерживает мой конфиг VLESS XHTTP REALITY EXTRA.
      Также в passwall2 очень гибко настраиваются правила маршрутизации, можно задавать любые источники geosite и geoip и их автообновление.