Repository: itdoginfo/domain-routing-openwrt Branch: master Commit: 2806a26a0721 Files: 16 Total size: 101.4 KB Directory structure: gitextract_333oxhhf/ ├── .github/ │ └── workflows/ │ └── public-galaxy.yml ├── README.EN.md ├── README.md ├── defaults/ │ └── main.yml ├── getdomains-check.sh ├── getdomains-install.sh ├── getdomains-uninstall.sh ├── handlers/ │ └── main.yml ├── meta/ │ └── main.yml ├── tasks/ │ └── main.yml ├── templates/ │ ├── config-sing-box.j2 │ ├── openwrt-30-vpnroute.j2 │ ├── openwrt-getdomains.j2 │ └── sing-box-json.j2 └── tests/ ├── inventory └── test.yml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/workflows/public-galaxy.yml ================================================ name: Public to Ansible Galaxy on: push: tags: - '*' jobs: build: runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v4 - name: Publish Ansible role to Galaxy uses: robertdebock/galaxy-action@1.2.1 with: galaxy_api_key: ${{ secrets.galaxy_api_key }} ================================================ FILE: README.EN.md ================================================ Domain routing OpenWrt ========= Configuring domain routing on Openwrt router. Role Variables -------------- Lists ``` country: russia-inside|russia-outside|ukraine list_domains: true|falase list_subnet: false|true list_ip: false|true list_community: false|true ``` Tunnel ``` tunnel: wg|openvpn|singbox|tun2socks ``` DoH or DoT ``` dns_encrypt: false|dnscrypt|stubby ``` Nano package ``` nano: true|false ``` Acces from wg network to router ``` wg_access: false|true wg_access_network: 192.168.80.0/24 (for example) ``` If wireguard is used: ``` wg_server_address: wg-server-host wg_private_key: privatekey-client wg_public_key: publickey-client wg_preshared_key: presharedkey-client wg_client_port: 51820 wg_client_address: ip-client wg_access: true wg_access_network: wg-network ``` Dependencies ------------ [gekmihesg.openwrt](https://github.com/gekmihesg/ansible-openwrt) Example Playbook ---------------- The inventory file must contain the group `[openwrt]` where your router will be located. Wireguard, only domains, stubby, Russia, acces from wg network, host 192.168.1.1 ``` - hosts: 192.168.1.1 remote_user: root roles: - itdoginfo.domain_routing_openwrt vars: tunnel: wg dns_encrypt: stubby country: russia-inside wg_access: true wg_server_address: wg-server-host wg_private_key: privatekey-client wg_public_key: publickey-client wg_preshared_key: presharedkey-client wg_listen_port: 51820 wg_client_port: 51820 wg_client_address: ip-client wg_access_network: wg-network ``` Sing-box, stubby, Russia ``` - hosts: 192.168.1.1 remote_user: root roles: - itdoginfo.domain_routing_openwrt vars: tunnel: singbox dns_encrypt: stubby country: russia-inside tasks: - name: sing-box config template: src: "templates/openwrt-sing-box-json.j2" dest: "/etc/sing-box/config.json" mode: 0644 notify: - Restart sing-box - Restart network ``` License ------- GNU General Public License v3.0 ================================================ FILE: README.md ================================================ [English role README](https://github.com/itdoginfo/domain-routing-openwrt/blob/master/README.EN.md) # Описание Shell скрипт и [роль для Ansible](https://galaxy.ansible.com/ui/standalone/roles/itdoginfo/domain_routing_openwrt). Автоматизируют настройку роутера на OpenWrt для роутинга по доменам и спискам IP-адресов. Полное описание происходящего: - [Статья на хабре](https://habr.com/ru/articles/767464/) - [Копия в моём блоге](https://itdog.info/tochechnyj-obhod-blokirovok-po-domenam-na-routere-s-openwrt/) # Скрипт для установки ``` sh <(wget -O - https://raw.githubusercontent.com/itdoginfo/domain-routing-openwrt/master/getdomains-install.sh) ``` # Скрипт для удаления ``` sh <(wget -O - https://raw.githubusercontent.com/itdoginfo/domain-routing-openwrt/refs/heads/master/getdomains-uninstall.sh) ``` ## AmneziaWG Через этот скрипт можно установить Amnezia wireguard. Скрипт проверяет наличие пакетов под вашу платформу в [стороннем репозитории](https://github.com/Slava-Shchipunov/awg-openwrt/releases), так как в официальном репозитории OpenWRT они отсутствуют, и автоматически их устанавливает. Если вам нужно установить только AWG, воспользуйтесь скриптом в репозитории: https://github.com/Slava-Shchipunov/awg-openwrt Если подходящих пакетов нет, перед настройкой необходимо будет самостоятельно [собрать бинарники AmneziaWG](https://github.com/itdoginfo/domain-routing-openwrt/wiki/Amnezia-WG-Build) для своего устройства и установить их. ## Скрипт для проверки конфигурации Написан для OpenWrt 23.05 и 22.03. На 21.02 работает только половина проверок. [x] - не обязательно означает, что эта часть не работает. Но это повод для ручной проверки. ### Запуск ``` wget -O - https://raw.githubusercontent.com/itdoginfo/domain-routing-openwrt/master/getdomains-check.sh | sh ``` По-умолчанию запускается на русском языке. Если нужно запустить на английском, то после `sh` нужно добавить `-s --lang en`. Аналогично для проверок на подмену DNS и создания дампа. ``` wget -O - https://raw.githubusercontent.com/itdoginfo/domain-routing-openwrt/master/getdomains-check.sh | sh -s --lang en ``` ### Запустить с проверкой на подмену DNS ``` wget -O - https://raw.githubusercontent.com/itdoginfo/domain-routing-openwrt/master/getdomains-check.sh | sh -s dns ``` ### Запустить с созданием dump Все чувствительные переменные затираются. ``` wget -O - https://raw.githubusercontent.com/itdoginfo/domain-routing-openwrt/master/getdomains-check.sh | sh -s dump ``` Поиск ошибок вручную: https://habr.com/ru/post/702388/ # Ansible Установить роль ``` ansible-galaxy role install itdoginfo.domain_routing_openwrt ``` Примеры playbooks Wireguard, only domains, stubby, Russia, acces from wg network (пример 192.168.80.0/24), host 192.168.1.1 ``` - hosts: 192.168.1.1 remote_user: root roles: - itdoginfo.domain_routing_openwrt vars: tunnel: wg dns_encrypt: stubby country: russia-inside wg_server_address: wg-server-host wg_private_key: privatekey-client wg_public_key: publickey-client wg_preshared_key: presharedkey-client wg_listen_port: 51820 wg_client_port: 51820 wg_client_address: ip-client wg_access: true wg_access_network: wg-network ``` Sing-box, stubby, Russia ``` - hosts: 192.168.1.1 remote_user: root roles: - itdoginfo.domain_routing_openwrt vars: tunnel: singbox dns_encrypt: stubby country: russia-inside tasks: - name: sing-box config template: src: "templates/openwrt-sing-box-json.j2" dest: "/etc/sing-box/config.json" mode: 0644 notify: - Restart sing-box - Restart network ``` В inventory файле роутер обязательно должен быть в группе `[openwrt]` ``` [openwrt] 192.168.1.1 ``` Для работы Ansible c OpenWrt необходимо, чтоб было выполнено одно из условий: - Отсутствие пароля для root (не рекомендуется) - Настроен доступ через публичный SSH-ключ в [конфиге dropbear](https://openwrt.org/docs/guide-user/security/dropbear.public-key.auth) После выполнения playbook роутер сразу начнёт роутить необходмые домены в туннель/прокси. Если у вас были ошибки и они исправились при повторном запуске playbook, но при этом роутинг не заработал, сделайте рестарт сети и скрипта: ``` service network restart service getdomains start ``` Тестировалось с - Ansible 2.10.8 - OpenWrt 21.02.7 - OpenWrt 22.03.5 - OpenWrt 23.05.2 ## Выбор туннеля - Wireguard настраивается автоматически через переменные - OpenVPN устанавливается пакет, настраивается роутинг и зона. Само подключение (скопировать конфиг и перезапустить openvpn) нужно [настроить вручную](https://itdog.info/nastrojka-klienta-openvpn-na-openwrt/) - Sing-box устанавливает пакет, настраивается роутинг и зона. Также кладётся темплейт в `/etc/sing-box/config.json`. [Нужно настроить](https://habr.com/ru/articles/767458/) `config.json` и сделать `service sing-box restart` Не работает под 21ой версией. Поэтому при его выборе playbook выдаст ошибку. Для 22ой версии нужно установить пакет вручную. - tun2socks настраивается только роутинг и зона. Всё остальное нужно настроить вручную Для **tunnel** шесть возможных значений: - wg - openvpn - singbox - tun2socks В случае использования WG: ``` wg_server_address: wg-server-host wg_private_key: privatekey-client wg_public_key: publickey-client wg_preshared_key: presharedkey-client wg_client_port: 51820 wg_client_address: ip-client ``` Если ваш wg сервер не использует `preshared_key`, то просто не задавайте её. **wg_access** и **wg_access_network** для доступа к роутеру через WG. Переменная wg_access_network должна иметь значение подсети, например 192.168.10.0/24. ``` wg_access_network: wg-network wg_access: true ``` ## Шифрование DNS Если ваш провайдер не подменяет DNS-запросы, ничего устанавливать не нужно. Для **dns_encrypt** три возможных значения: - dnscrypt - stubby - false/закомментировано - пропуск, ничего не устанавливается и не настраивается ## Выбор страны Выбор списка доменов. Для **county** три [возможных значения](https://github.com/itdoginfo/allow-domains): - russia-inside - russia-outside - ukraine ## Списки IP-адресов Списки IP-адресов берутся с [antifilter.download](https://antifilter.download/) Переменные **list_** обозначают, какие списки нужно установить. true - установить, false - не устанавливать и удалить, если уже есть Доступные переменные ``` list_domains: true list_subnet: false list_ip: falses list_community: false ``` Я советую использовать только домены ``` list_domains: true ``` Если вам требуются списки IP-адресов, они также поддерживаются. При использовании **list_domains** нужен пакет dnsmasq-full. Для 23.05 dnsmasq-full устанавливается автоматически. Для OpenWrt 22.03 версия dnsmasq-full должна быть => 2.87, её нет в официальном репозитории, но можно установить из dev репозитория. Если это условие не выполнено, плейбук завершится с ошибкой. [Инструкция для OpenWrt 22.03](https://t.me/itdoginf/12) [Инструкция для OpenWrt 21.02](https://t.me/itdoginfo/8) ## Текстовый редактор nano Устанавливается по умолчанию. Можно выключить ``` nano: false ``` --- [Telegram-канал с обновлениями](https://t.me/+lW1HmBO_Fa00M2Iy) ================================================ FILE: defaults/main.yml ================================================ --- list_domains: true list_subnet: false list_ip: false list_community: false tunnel: wg dns_encrypt: false country: russia-inside nano: true wg_access: false wg_listen_port: 51820 ================================================ FILE: getdomains-check.sh ================================================ #!/bin/sh SCRIPTS_DIR="/etc/init.d" TMP_DIR="/tmp" HIVPN_SCRIPT_FILENAME="hivpn" GETDOMAINS_SCRIPT_FILENAME="getdomains" DUMP_FILENAME="dump.txt" HIVPN_SCRIPT_PATH="$SCRIPTS_DIR/$HIVPN_SCRIPT_FILENAME" GETDOMAINS_SCRIPT_PATH="$SCRIPTS_DIR/$GETDOMAINS_SCRIPT_FILENAME" DUMP_PATH="$TMP_DIR/$DUMP_FILENAME" COLOR_BOLD_BLUE="\033[34;1m" COLOR_BOLD_GREEN="\033[32;1m" COLOR_BOLD_RED="\033[31;1m" COLOR_BOLD_CYAN="\033[36;1m" COLOR_RESET="\033[0m" UNSUPPORTED_OPENWRT_VERSION="21.02" MIN_RAM="256" DNSMASQ_FULL_REQUIRED_VERSION="2.87" SINGBOX_CONFIG_PATH="/etc/config/sing-box" CURL_PACKAGE="curl" DNSMASQ_PACKAGE="dnsmasq" DNSMASQ_FULL_PACKAGE="$DNSMASQ_PACKAGE-full" XRAY_CORE_PACKAGE="xray-core" LUCI_APP_XRAY_PACKAGE="luci-app-xray" WIREGUARD_TOOLS_PACKAGE="wireguard-tools" OPENVPN_PACKAGE="openvpn" SINGBOX_PACKAGE="sing-box" TUN2SOCKS_PACKAGE="tun2socks" DNSCRYPT_PACKAGE="dnscrypt-proxy2" STUBBY_PACKAGE="stubby" WIREGUARD_PROTOCOL="Wireguard" OPENVPN_PROTOCOL="OpenVPN" LANGUAGE="ru" SUPPORTED_LANGUAGES="ru, en" set_language_en() { DEVICE_MODEL="Model" OPENWRT_VERSION="Version" CURRENT_DATE="Date" INSTALLED="is installed" NOT_INSTALLED="is not installed" RUNNING="is running" NOT_RUNNING="is not running" ENABLED="is enabled" DISABLED="is disabled" EXISTS="exists" DOESNT_EXIST="doesn't exist" UNSUPPORTED_OPENWRT="You are using OpenWrt $UNSUPPORTED_OPENWRT_VERSION. This check script does not support it." RAM_WARNING="Your router has less than $MIN_RAM MB of RAM. It is recommended to use only the vpn_domains list." CURL_INSTALLED="$CURL_PACKAGE $INSTALLED" CURL_NOT_INSTALLED="$CURL_PACKAGE $NOT_INSTALLED. Install it: opkg install $CURL_PACKAGE" DNSMASQ_FULL_INSTALLED="$DNSMASQ_FULL_PACKAGE $INSTALLED" DNSMASQ_FULL_NOT_INSTALLED="$DNSMASQ_FULL_PACKAGE $NOT_INSTALLED" DNSMASQ_FULL_DETAILS="If you don't use vpn_domains set, it's OK\nCheck version: opkg list-installed | grep $DNSMASQ_FULL_PACKAGE\nRequired version >= $DNSMASQ_FULL_REQUIRED_VERSION. For OpenWrt 22.03 follow manual: https://t.me/itdoginfo/12" OPENWRT_21_DETAILS="\nYou are using OpenWrt $UNSUPPORTED_OPENWRT_VERSION. This check does not support it.\nManual for OpenWrt $UNSUPPORTED_OPENWRT_VERSION: https://t.me/itdoginfo/8" XRAY_CORE_PACKAGE_DETECTED="$XRAY_CORE_PACKAGE package detected" LUCI_APP_XRAY_PACKAGE_DETECTED="$LUCI_APP_XRAY_PACKAGE package detected which is incompatible. Remove it: opkg remove $LUCI_APP_XRAY_PACKAGE --force-removal-of-dependent-packages" DNSMASQ_SERVICE_RUNNING="$DNSMASQ_PACKAGE service $RUNNING" DNSMASQ_SERVICE_NOT_RUNNING="$DNSMASQ_PACKAGE service $NOT_RUNNING. Check configuration: /etc/config/dhcp" INTERNET_IS_AVAILABLE="Internet is available" INTERNET_IS_NOT_AVAILABLE="Internet is not available" INTERNET_DETAILS="Check internet connection. If it's ok, check date on router. Details: https://cli.co/2EaW4rO\nFor more info run: curl -Is https://community.antifilter.download/" IPV6_DETECTED="IPv6 detected. This script does not currently work with IPv6" WIREGUARD_TOOLS_INSTALLED="$WIREGUARD_TOOLS_PACKAGE $INSTALLED" WIREGUARD_ROUTING_DOESNT_WORK="Tunnel to the $WIREGUARD_PROTOCOL server works, but routing to the internet does not work. Check server configuration. Details: https://cli.co/RSCvOxI" WIREGUARD_TUNNEL_NOT_WORKING="Bad news: $WIREGUARD_PROTOCOL tunnel isn't working. Check your $WIREGUARD_PROTOCOL configuration. Details: https://cli.co/hGUUXDs\nIf you don't use $WIREGUARD_PROTOCOL, but $OPENVPN_PROTOCOL for example, it's OK" WIREGUARD_ROUTE_ALLOWED_IPS_ENABLED="$WIREGUARD_PROTOCOL route_allowed_ips $ENABLED. All traffic goes into the tunnel. Read more at: https://cli.co/SaxBzH7" WIREGUARD_ROUTE_ALLOWED_IPS_DISABLED="$WIREGUARD_PROTOCOL route_allowed_ips $DISABLED" WIREGUARD_ROUTING_TABLE_EXISTS="$WIREGUARD_PROTOCOL routing table $EXISTS" WIREGUARD_ROUTING_TABLE_DOESNT_EXIST="$WIREGUARD_PROTOCOL routing table $DOESNT_EXIST. Details: https://cli.co/Atxr6U3" OPENVPN_INSTALLED="$OPENVPN_PACKAGE $INSTALLED" OPENVPN_ROUTING_DOESNT_WORK="Tunnel to the $OPENVPN_PROTOCOL server works, but routing to the internet does not work. Check server configuration." OPENVPN_TUNNEL_NOT_WORKING="Bad news: $OPENVPN_PROTOCOL tunnel isn't working. Check your $OPENVPN_PROTOCOL configuration." OPENVPN_REDIRECT_GATEWAY_ENABLED="$OPENVPN_PROTOCOL redirect-gateway $ENABLED. All traffic goes into the tunnel. Read more at: https://cli.co/vzTNq_3" OPENVPN_REDIRECT_GATEWAY_DISABLED="$OPENVPN_PROTOCOL redirect-gateway $DISABLED" OPENVPN_ROUTING_TABLE_EXISTS="$OPENVPN_PROTOCOL routing table $EXISTS" OPENVPN_ROUTING_TABLE_DOESNT_EXIST="$OPENVPN_PROTOCOL routing table $DOESNT_EXIST. Details: https://cli.co/Atxr6U3" SINGBOX_INSTALLED="$SINGBOX_PACKAGE $INSTALLED" SINGBOX_ROUTING_TABLE_EXISTS="$SINGBOX_PACKAGE routing table $EXISTS" SINGBOX_ROUTING_TABLE_DOESNT_EXIST="$SINGBOX_PACKAGE routing table $DOESNT_EXIST. Try: service network restart. Details: https://cli.co/n7xAbc1" SINGBOX_UCI_CONFIG_OK="$SINGBOX_PACKAGE UCI configuration has been successfully validated" SINGBOX_UCI_CONFIG_ERROR="$SINGBOX_PACKAGE Error validation UCI configuration. Check $SINGBOX_CONFIG_PATH" SINGBOX_CONFIG_OK="$SINGBOX_PACKAGE configuration has been successfully validated" SINGBOX_CONFIG_ERROR="$SINGBOX_PACKAGE configuration validation error" SINGBOX_WORKING_TEMPLATE="$SINGBOX_PACKAGE works. VPN IP: %s" SINGBOX_ROUTING_DOESNT_WORK="$SINGBOX_PACKAGE: Your traffic is not routed through the VPN. Check configuration: https://cli.co/Badmn3K" TUN2SOCKS_INSTALLED="$TUN2SOCKS_PACKAGE $INSTALLED" TUN2SOCKS_ROUTING_TABLE_EXISTS="$TUN2SOCKS_PACKAGE routing table $EXISTS" TUN2SOCKS_ROUTING_TABLE_DOESNT_EXIST="$TUN2SOCKS_PACKAGE routing table $DOESNT_EXIST. Try: service network restart. Details: https://cli.co/n7xAbc1" TUN2SOCKS_WORKING_TEMPLATE="$TUN2SOCKS_PACKAGE works. VPN IP: %s" TUN2SOCKS_ROUTING_DOESNT_WORK="$TUN2SOCKS_PACKAGE: Your traffic is not routed through the VPN. Check configuration: https://cli.co/VNZISEM" VPN_DOMAINS_SET_EXISTS="vpn_domains set $EXISTS" VPN_DOMAINS_SET_DOESNT_EXIST="vpn_domains set $DOESNT_EXIST" IPS_IN_VPN_DOMAINS_SET_OK="IPs are successfully added to vpn_domains set" IPS_IN_VPN_DOMAINS_SET_ERROR="IPs were not added to vpn_domains set" VPN_DOMAINS_DETAILS="If you don't use vpn_domains, it's OK.\nBut if you want to use it, check the configuration and run: service getdomains start" VPN_DOMAINS_DETAILS_2="If you don't use vpn_domains, it's OK.\nBut if you want use, check the configuration: https://cli.co/AwUGeM6" VPN_IP_SET_EXISTS="vpn_ip set $EXISTS" VPN_IP_SET_DOESNT_EXIST="vpn_ip set $DOESNT_EXIST. Check configuration: https://cli.co/AwUGeM6" IPS_IN_VPN_IP_SET_OK="IPs are successfully added to vpn_ip set" IPS_IN_VPN_IP_SET_ERROR="IPs were not added to vpn_ip set. But if you want to use it, check configuration" VPN_SUBNET_SET_EXISTS="vpn_subnets set $EXISTS" VPN_SUBNET_SET_DOESNT_EXIST="vpn_subnets set $DOESNT_EXIST. Check configuration: https://cli.co/AwUGeM6" IPS_IN_VPN_SUBNET_SET_OK="IPs are successfully added to vpn_subnets set" IPS_IN_VPN_SUBNET_SET_ERROR="IPs were not added to vpn_subnets set. But if you want to use it, check configs" VPN_COMMUNITY_SET_EXISTS="vpn_community set $EXISTS" VPN_COMMUNITY_SET_DOESNT_EXIST="vpn_community set $DOESNT_EXIST. Check configuration: https://cli.co/AwUGeM6" IPS_IN_VPN_COMMUNITY_SET_OK="IPs are successfully added to vpn_community set" IPS_IN_VPN_COMMUNITY_SET_ERROR="IPs were not added to vpn_community set. But if you want to use it, check configs" GETDOMAINS_SCRIPT_EXISTS="Script $GETDOMAINS_SCRIPT_FILENAME $EXISTS" GETDOMAINS_SCRIPT_DOESNT_EXIST="Script $GETDOMAINS_SCRIPT_FILENAME $DOESNT_EXIST. Script doesn't exists in $GETDOMAINS_SCRIPT_PATH. If you don't use getdomains, it's OK" GETDOMAINS_SCRIPT_CRONTAB_OK="Script $GETDOMAINS_SCRIPT_FILENAME has been successfully added to crontab" GETDOMAINS_SCRIPT_CRONTAB_ERROR="Script $GETDOMAINS_SCRIPT_FILENAME has not been added to crontab. Check: crontab -l" DNSCRYPT_INSTALLED="$DNSCRYPT_PACKAGE $INSTALLED" DNSCRYPT_SERVICE_RUNNING="$DNSCRYPT_PACKAGE service $RUNNING" DNSCRYPT_SERVICE_NOT_RUNNING="$DNSCRYPT_PACKAGE service $NOT_RUNNING. Check configuration: https://cli.co/wN-tc_S" DNSMASQ_CONFIG_FOR_DNSCRYPT_OK="$DNSMASQ_PACKAGE configuration for $DNSCRYPT_PACKAGE is ok" DNSMASQ_CONFIG_FOR_DNSCRYPT_ERROR="$DNSMASQ_PACKAGE configuration for $DNSCRYPT_PACKAGE is not ok. Check configuration: https://cli.co/rooc0uz" STUBBY_INSTALLED="$STUBBY_PACKAGE $INSTALLED" STUBBY_SERVICE_RUNNING="$STUBBY_PACKAGE service $RUNNING" STUBBY_SERVICE_NOT_RUNNING="$STUBBY_PACKAGE service $NOT_RUNNING. Check configuration: https://cli.co/HbDBT2V" DNSMASQ_CONFIG_FOR_STUBBY_OK="$DNSMASQ_PACKAGE configuration for $STUBBY_PACKAGE is ok" DNSMASQ_CONFIG_FOR_STUBBY_ERROR="$DNSMASQ_PACKAGE configuration for $STUBBY_PACKAGE is not ok. Check configuration: https://cli.co/HbDBT2V" DUMP_CREATION="Creating dump without private variables" DUMP_DETAILS="Dump is here: $DUMP_PATH\nFor download on Linux/Mac use: scp root@IP_ROUTER:$DUMP_PATH .\nFor Windows use WinSCP/PSCP or WSL" DNS_CHECK="Checking DNS servers" IS_DNS_TRAFFIC_BLOCKED="Checking DNS traffic blocking (Port 53/udp is available)" IS_DOH_AVAILABLE="Checking DOH availability" RESPONSE_NOT_CONTAINS_127_0_0_8="Checking that the response does not contain an address from 127.0.0.8" ONE_IP_FOR_TWO_DOMAINS="Checking IP for two different domains" IPS_ARE_THE_SAME="IPs are the same" IPS_ARE_DIFFERENT="IPs are different" RESPONSE_IS_NOT_BLANK="Checking if response is not blank" DNS_POISONING_CHECK="Сomparing response from unencrypted DNS and DoH (DNS poisoning)" TELEGRAM_CHANNEL="Telegram channel" TELEGRAM_CHAT="Telegram chat" } set_language_ru() { DEVICE_MODEL="Модель" OPENWRT_VERSION="Версия" CURRENT_DATE="Дата" INSTALLED="установлен" NOT_INSTALLED="не установлен" RUNNING="запущен" NOT_RUNNING="не запущен" ENABLED="включен" DISABLED="выключен" EXISTS="существует" DOESNT_EXIST="не существует" UNSUPPORTED_OPENWRT="Вы используете OpenWrt $UNSUPPORTED_OPENWRT_VERSION. Этот скрипт проверки её не поддерживает." RAM_WARNING="У вашего роутера менее $MIN_RAM МБ ОЗУ. Рекомендуется использовать только vpn_domains set." CURL_INSTALLED="$CURL_PACKAGE $INSTALLED" CURL_NOT_INSTALLED="$CURL_PACKAGE $NOT_INSTALLED. Установите его: opkg install $CURL_PACKAGE" DNSMASQ_FULL_INSTALLED="$DNSMASQ_FULL_PACKAGE $INSTALLED" DNSMASQ_FULL_NOT_INSTALLED="$DNSMASQ_FULL_PACKAGE $NOT_INSTALLED" DNSMASQ_FULL_DETAILS="Если вы не используете vpn_domains set, это нормально\nПроверьте версию: opkg list-installed | grep $DNSMASQ_FULL_PACKAGE\nТребуемая версия >= $DNSMASQ_FULL_REQUIRED_VERSION. Для OpenWrt 22.03 следуйте инструкции: https://t.me/itdoginfo/12" OPENWRT_21_DETAILS="\nВы используете OpenWrt $UNSUPPORTED_OPENWRT_VERSION. Этот скрипт её не поддерживает.\nИнструкция для OpenWrt $UNSUPPORTED_OPENWRT_VERSION: https://t.me/itdoginfo/8" XRAY_CORE_PACKAGE_DETECTED="Обнаружен пакет $XRAY_CORE_PACKAGE" LUCI_APP_XRAY_PACKAGE_DETECTED="Обнаружен пакет $LUCI_APP_XRAY_PACKAGE, который не совместим. Удалите его: opkg remove $LUCI_APP_XRAY_PACKAGE --force-removal-of-dependent-packages" DNSMASQ_SERVICE_RUNNING="Сервис $DNSMASQ_PACKAGE $RUNNING" DNSMASQ_SERVICE_NOT_RUNNING="Сервис $DNSMASQ_PACKAGE $NOT_RUNNING. Проверьте конфигурацию: /etc/config/dhcp" INTERNET_IS_AVAILABLE="Интернет доступен" INTERNET_IS_NOT_AVAILABLE="Интернет недоступен" INTERNET_DETAILS="Проверьте подключение к интернету. Если оно в порядке, проверьте дату на роутере. Подробности: https://cli.co/2EaW4rO\nДополнительно выполните: curl -Is https://community.antifilter.download/" IPV6_DETECTED="Обнаружен IPv6. Этот скрипт не поддерживает работу с IPv6" WIREGUARD_TOOLS_INSTALLED="$WIREGUARD_TOOLS_PACKAGE $INSTALLED" WIREGUARD_ROUTING_DOESNT_WORK="Туннель к $WIREGUARD_PROTOCOL серверу работает, но маршрутизация в интернет не работает. Проверьте конфигурацию сервера. Подробности: https://cli.co/RSCvOxI" WIREGUARD_TUNNEL_NOT_WORKING="Плохие новости: туннель $WIREGUARD_PROTOCOL не работает. Проверьте конфигурацию $WIREGUARD_PROTOCOL. Подробности: https://cli.co/hGUUXDs\nЕсли вы не используете $WIREGUARD_PROTOCOL, а, например, $OPENVPN_PROTOCOL, то это нормально" WIREGUARD_ROUTE_ALLOWED_IPS_ENABLED="$WIREGUARD_PROTOCOL route_allowed_ips $ENABLED. Весь трафик идет в туннель. Подробнее: https://cli.co/SaxBzH7" WIREGUARD_ROUTE_ALLOWED_IPS_DISABLED="$WIREGUARD_PROTOCOL route_allowed_ips $DISABLED" WIREGUARD_ROUTING_TABLE_EXISTS="Таблица маршрутизации $WIREGUARD_PROTOCOL $EXISTS" WIREGUARD_ROUTING_TABLE_DOESNT_EXIST="Таблица маршрутизации $WIREGUARD_PROTOCOL $DOESNT_EXIST. Подробности: https://cli.co/Atxr6U3" OPENVPN_INSTALLED="$OPENVPN_PACKAGE $INSTALLED" OPENVPN_ROUTING_DOESNT_WORK="Туннель к $OPENVPN_PROTOCOL серверу работает, но маршрутизация в интернет не работает. Проверьте конфигурацию сервера." OPENVPN_TUNNEL_NOT_WORKING="Плохие новости: туннель $OPENVPN_PROTOCOL не работает. Проверьте конфигурацию $OPENVPN_PROTOCOL." OPENVPN_REDIRECT_GATEWAY_ENABLED="$OPENVPN_PROTOCOL redirect-gateway $ENABLED. Весь трафик идет в туннель. Подробнее: https://cli.co/vzTNq_3" OPENVPN_REDIRECT_GATEWAY_DISABLED="$OPENVPN_PROTOCOL redirect-gateway $DISABLED" OPENVPN_ROUTING_TABLE_EXISTS="Таблица маршрутизации $OPENVPN_PROTOCOL $EXISTS" OPENVPN_ROUTING_TABLE_DOESNT_EXIST="Таблица маршрутизации $OPENVPN_PROTOCOL $DOESNT_EXIST. Подробности: https://cli.co/Atxr6U3" SINGBOX_INSTALLED="$SINGBOX_PACKAGE $INSTALLED" SINGBOX_ROUTING_TABLE_EXISTS="Таблица маршрутизации $SINGBOX_PACKAGE $EXISTS" SINGBOX_ROUTING_TABLE_DOESNT_EXIST="Таблица маршрутизации $SINGBOX_PACKAGE $DOESNT_EXIST. Попробуйте: service network restart. Подробности: https://cli.co/n7xAbc1" SINGBOX_UCI_CONFIG_OK="UCI конфигурация для $SINGBOX_PACKAGE успешно проверена" SINGBOX_UCI_CONFIG_ERROR="Ошибка валидации UCI конфигурации для $SINGBOX_PACKAGE" SINGBOX_CONFIG_OK="Конфигурация $SINGBOX_PACKAGE успешно проверена" SINGBOX_CONFIG_ERROR="Ошибка валидации конфигурации $SINGBOX_PACKAGE" SINGBOX_WORKING_TEMPLATE="$SINGBOX_PACKAGE работает. VPN IP: %s" SINGBOX_ROUTING_DOESNT_WORK="$SINGBOX_PACKAGE: Ваш трафик не идёт через VPN. Проверьте конфигурацию: https://cli.co/Badmn3K" TUN2SOCKS_INSTALLED="$TUN2SOCKS_PACKAGE $INSTALLED" TUN2SOCKS_ROUTING_TABLE_EXISTS="Таблица маршрутизации $TUN2SOCKS_PROTOCOL $EXISTS" TUN2SOCKS_ROUTING_TABLE_DOESNT_EXIST="Таблица маршрутизации $TUN2SOCKS_PROTOCOL $DOESNT_EXIST. Подробности: https://cli.co/n7xAbc1" TUN2SOCKS_WORKING_TEMPLATE="$TUN2SOCKS_PACKAGE работает. VPN IP: %s" TUN2SOCKS_ROUTING_DOESNT_WORK="$TUN2SOCKS_PACKAGE: Ваш трафик не идёт через VPN. Проверьте конфигурацию: https://cli.co/VNZISEM" VPN_DOMAINS_SET_EXISTS="vpn_domains set $EXISTS" VPN_DOMAINS_SET_DOESNT_EXIST="vpn_domains set $DOESNT_EXIST" IPS_IN_VPN_DOMAINS_SET_OK="IP-адреса успешно добавлены в vpn_domains set" IPS_IN_VPN_DOMAINS_SET_ERROR="IP-адреса не добавлены в vpn_domains set" VPN_DOMAINS_DETAILS="Если вы не используете vpn_domains, все в порядке.\nНо если вы хотите использовать его, проверьте конфигурацию и выполните: service getdomains start" VPN_DOMAINS_DETAILS_2="Если вы не используете vpn_domains, все в порядке.\nНо если вы хотите использовать, проверьте конфигурацию: https://cli.co/AwUGeM6" VPN_IP_SET_EXISTS="vpn_ip set $EXISTS" VPN_IP_SET_DOESNT_EXIST="vpn_ip set $DOESNT_EXIST" IPS_IN_VPN_IP_SET_OK="IP-адреса успешно добавлены в set vpn_ip" IPS_IN_VPN_IP_SET_ERROR="IP-адреса не добавлены в set vpn_ip" VPN_SUBNET_SET_EXISTS="vpn_subnet set $EXISTS" VPN_SUBNET_SET_DOESNT_EXIST="vpn_subnet set $DOESNT_EXIST" IPS_IN_VPN_SUBNET_SET_OK="IP-адреса успешно добавлены в set vpn_subnet" IPS_IN_VPN_SUBNET_SET_ERROR="IP-адреса не добавлены в set vpn_subnet" VPN_COMMUNITY_SET_EXISTS="vpn_community set $EXISTS" VPN_COMMUNITY_SET_DOESNT_EXIST="vpn_community set $DOESNT_EXIST" IPS_IN_VPN_COMMUNITY_SET_OK="IP-адреса успешно добавлены в set vpn_community" IPS_IN_VPN_COMMUNITY_SET_ERROR="IP-адреса не добавлены в set vpn_community" GETDOMAINS_SCRIPT_EXISTS="Скрипт $GETDOMAINS_SCRIPT_FILENAME $EXISTS" GETDOMAINS_SCRIPT_DOESNT_EXIST="Скрипт $GETDOMAINS_SCRIPT_FILENAME $DOESNT_EXIST" GETDOMAINS_SCRIPT_CRONTAB_OK="Скрипт $GETDOMAINS_SCRIPT_FILENAME успешно добавлен в crontab" GETDOMAINS_SCRIPT_CRONTAB_ERROR="Скрипт $GETDOMAINS_SCRIPT_FILENAME не был добавлен в crontab. Проверьте: crontab -l" DNSCRYPT_INSTALLED="$DNSCRYPT_PACKAGE $INSTALLED" DNSCRYPT_SERVICE_RUNNING="Сервис $DNSCRYPT_PACKAGE $RUNNING" DNSCRYPT_SERVICE_NOT_RUNNING="Сервис $DNSCRYPT_PACKAGE $NOT_RUNNING. Проверьте конфигурацию: https://cli.co/wN-tc_S" DNSMASQ_CONFIG_FOR_DNSCRYPT_OK="Конфигурация $DNSMASQ_PACKAGE для $DNSCRYPT_PACKAGE в порядке" DNSMASQ_CONFIG_FOR_DNSCRYPT_ERROR="Конфигурация $DNSMASQ_PACKAGE для $DNSCRYPT_PACKAGE не в порядке. Проверьте конфигурацию: https://cli.co/rooc0uz" STUBBY_INSTALLED="$STUBBY_PACKAGE $INSTALLED" STUBBY_SERVICE_RUNNING="Сервис $STUBBY_PACKAGE $RUNNING" STUBBY_SERVICE_NOT_RUNNING="Сервис $STUBBY_PACKAGE $NOT_RUNNING. Проверьте конфигурацию: https://cli.co/HbDBT2V" DNSMASQ_CONFIG_FOR_STUBBY_OK="Конфигурация $DNSMASQ_PACKAGE для $STUBBY_PACKAGE в порядке" DNSMASQ_CONFIG_FOR_STUBBY_ERROR="Конфигурация $DNSMASQ_PACKAGE для $STUBBY_PACKAGE не в порядке. Проверьте конфигурацию: https://cli.co/HbDBT2V" DUMP_CREATION="Создание дампа без приватных переменных" DUMP_DETAILS="Дамп находится здесь: $DUMP_PATH\nДля загрузки на Linux/Mac используйте: scp root@IP_ROUTER:$DUMP_PATH .\nДля Windows используйте WinSCP/PSCP или WSL" DNS_CHECK="Проверка DNS серверов" IS_DNS_TRAFFIC_BLOCKED="Проверяем блокировку DNS трафика (Порт 53/udp доступен)" IS_DOH_AVAILABLE="Проверяем доступность DoH" RESPONSE_NOT_CONTAINS_127_0_0_8="Проверяем, что ответ на запрос не содержит адреса из 127.0.0.8" ONE_IP_FOR_TWO_DOMAINS="Проверяем IP для двух разных доменов" IPS_ARE_THE_SAME="IP совпадают" IPS_ARE_DIFFERENT="IP различаются" RESPONSE_IS_NOT_BLANK="Проверяем, что ответ не пустой" DNS_POISONING_CHECK="Сравниваем ответ от незащищенного DNS и DoH (Подмена DNS)" TELEGRAM_CHANNEL="Telegram канал" TELEGRAM_CHAT="Telegram чат" } checkpoint_true() { printf "$COLOR_BOLD_GREEN[\342\234\223] $1$COLOR_RESET\n" } checkpoint_false() { printf "$COLOR_BOLD_RED[x] $1$COLOR_RESET\n" } output_21() { if [ "$VERSION_ID" -eq 21 ]; then echo "$UNSUPPORTED_OPENWRT" fi } update_vpn_ip() { local template="$1" local ip="$2" echo "$(printf "$template" "$ip")" } while [ $# -gt 0 ]; do case "$1" in --lang) LANGUAGE="$2" shift 2 ;; dump | dns) COMMAND="$1" shift 1 ;; *) printf "$COLOR_BOLD_RED[ERROR]$COLOR_RESET Unknown option: %s\n" "$1" exit 1 ;; esac done case $LANGUAGE in ru) set_language_ru ;; en) set_language_en ;; *) printf "$COLOR_BOLD_RED[ERROR]$COLOR_RESET Unsupported language '$LANGUAGE'. Supported languages: $SUPPORTED_LANGUAGES %s\n" "$1" exit 1 ;; esac # System Details MODEL=$(cat /tmp/sysinfo/model) source /etc/os-release printf "$COLOR_BOLD_BLUE$DEVICE_MODEL: $MODEL$COLOR_RESET\n" printf "$COLOR_BOLD_BLUE$OPENWRT_VERSION: $OPENWRT_RELEASE$COLOR_RESET\n" printf "$COLOR_BOLD_BLUE$CURRENT_DATE: $(date)$COLOR_RESET\n" VERSION_ID=$(echo $VERSION | awk -F. '{print $1}') RAM=$(free -m | grep Mem: | awk '{print $2}') if [[ "$VERSION_ID" -ge 22 && "$RAM" -lt 150000 ]]; then echo "$RAM_WARNING" fi # Check packages CURL=$(opkg list-installed | grep -c curl) if [ $CURL -eq 2 ]; then checkpoint_true "$CURL_INSTALLED" else checkpoint_false "$CURL_NOT_INSTALLED" fi DNSMASQ=$(opkg list-installed | grep dnsmasq-full | awk -F "-" '{print $3}' | tr -d '.') if [ $DNSMASQ -ge 287 ]; then checkpoint_true "$DNSMASQ_FULL_INSTALLED" else checkpoint_false "$DNSMASQ_FULL_NOT_INSTALLED" printf "$DNSMASQ_FULL_DETAILS\n" if [ "$VERSION_ID" -eq 21 ]; then printf "$OPENWRT_21_DETAILS\n" fi fi # Chek xray package if opkg list-installed | grep -q xray-core; then checkpoint_false "$XRAY_CORE_PACKAGE_DETECTED" fi if opkg list-installed | grep -q luci-app-xray; then checkpoint_false "$LUCI_APP_XRAY_PACKAGE_DETECTED" fi # Check dnsmasq DNSMASQ_RUN=$(service dnsmasq status | grep -c 'running') if [ $DNSMASQ_RUN -eq 1 ]; then checkpoint_true "$DNSMASQ_SERVICE_RUNNING" else checkpoint_false "$DNSMASQ_SERVICE_NOT_RUNNING" output_21 fi # Check internet connection if curl -Is https://community.antifilter.download/ | grep -q 200; then checkpoint_true "$INTERNET_IS_AVAILABLE" else checkpoint_false "$INTERNET_IS_NOT_AVAILABLE" if [ $CURL -lt 2 ]; then echo "$CURL_NOT_INSTALLED" else printf "$INTERNET_DETAILS\n" fi fi # Check IPv6 if curl -6 -s https://ifconfig.io | egrep -q "(::)?[0-9a-fA-F]{1,4}(::?[0-9a-fA-F]{1,4}){1,7}(::)?"; then checkpoint_false "$IPV6_DETECTED" fi # Tunnels WIREGUARD=$(opkg list-installed | grep -c wireguard-tools) if [ $WIREGUARD -eq 1 ]; then checkpoint_true "$WIREGUARD_TOOLS_INSTALLED" WG=true fi if [ "$WG" == true ]; then WG_PING=$(ping -c 1 -q -I wg0 itdog.info | grep -c "1 packets received") if [ $WG_PING -eq 1 ]; then checkpoint_true "$WIREGUARD_PROTOCOL" else checkpoint_false "$WIREGUARD_PROTOCOL" WG_TRACE=$(traceroute -i wg0 itdog.info -m 1 | grep ms | awk '{print $2}' | grep -c -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') if [ $WG_TRACE -eq 1 ]; then echo "$WIREGUARD_ROUTING_DOESNT_WORK" else printf "$WIREGUARD_TUNNEL_NOT_WORKING\n" fi fi # Check WG route_allowed_ips if uci show network | grep -q ".route_allowed_ips='1'"; then checkpoint_false "$WIREGUARD_ROUTE_ALLOWED_IPS_ENABLED" else checkpoint_true "$WIREGUARD_ROUTE_ALLOWED_IPS_DISABLED" fi # Check route table ROUTE_TABLE=$(ip route show table vpn | grep -c "default dev wg0") if [ $ROUTE_TABLE -eq 1 ]; then checkpoint_true "$WIREGUARD_ROUTING_TABLE_EXISTS" else checkpoint_false "$WIREGUARD_ROUTING_TABLE_DOESNT_EXIST" fi fi if opkg list-installed | grep -q openvpn; then checkpoint_true "$OPENVPN_INSTALLED" OVPN=true fi # Check OpenVPN if [ "$OVPN" == true ]; then if ping -c 1 -q -I tun0 itdog.info | grep -q "1 packets received"; then checkpoint_true "$OPENVPN_PROTOCOL" else checkpoint_false "$OPENVPN_PROTOCOL" if traceroute -i tun0 itdog.info -m 1 | grep ms | awk '{print $2}' | grep -c -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'; then echo "$OPENVPN_ROUTING_DOESNT_WORK" else echo "$OPENVPN_TUNNEL_NOT_WORKING" fi fi # Check OpenVPN redirect-gateway if grep -q redirect-gateway /etc/openvpn/*; then checkpoint_false "$OPENVPN_REDIRECT_GATEWAY_ENABLED" else checkpoint_true "$OPENVPN_REDIRECT_GATEWAY_DISABLED" fi # Check route table if ip route show table vpn | grep -q "default dev tun0"; then checkpoint_true "$OPENVPN_ROUTING_TABLE_EXISTS" else checkpoint_false "$OPENVPN_ROUTING_TABLE_DOESNT_EXIST" fi fi if opkg list-installed | grep -q sing-box; then checkpoint_true "$SINGBOX_INSTALLED" # Check route table if ip route show table vpn | grep -q "default dev tun0"; then checkpoint_true "$SINGBOX_ROUTING_TABLE_EXISTS" else checkpoint_false "$SINGBOX_ROUTING_TABLE_DOESNT_EXIST" fi # Sing-box uci validation if uci show sing-box 2>&1 | grep -q "Parse error"; then checkpoint_false "$SINGBOX_UCI_CONFIG_ERROR" else checkpoint_true "$SINGBOX_UCI_CONFIG_OK" fi singbox_check_cmd="sing-box -c /etc/sing-box/config.json check" if $singbox_check_cmd >/dev/null 2>&1; then checkpoint_true "$SINGBOX_CONFIG_OK" # Check traffic IP_EXTERNAL=$(curl -s ifconfig.me) IFCONFIG=$(nslookup -type=a ifconfig.me | awk '/^Address: / {print $2}') IP_VPN=$(curl --interface tun0 -s ifconfig.me) SINGBOX_WORKING=$(update_vpn_ip "$SINGBOX_WORKING_TEMPLATE" "$IP_VPN") if [ "$IP_EXTERNAL" != $IP_VPN ]; then checkpoint_true "$SINGBOX_WORKING" else checkpoint_false "$SINGBOX_ROUTING_DOESNT_WORK" fi else checkpoint_false "$SINGBOX_CONFIG_ERROR:" $singbox_check_cmd fi fi if which tun2socks | grep -q tun2socks; then checkpoint_true "$TUN2SOCKS_INSTALLED" # Check route table if ip route show table vpn | grep -q "default dev tun0"; then checkpoint_true "$TUN2SOCKS_ROUTING_TABLE_EXISTS" else checkpoint_false "$TUN2SOCKS_ROUTING_TABLE_DOESNT_EXIST" fi IP_EXTERNAL=$(curl -s ifconfig.me) IFCONFIG=$(nslookup -type=a ifconfig.me | awk '/^Address: / {print $2}') IP_VPN=$(curl --interface tun0 -s ifconfig.me) TUN2SOCKS_WORKING=$(update_vpn_ip "$TUN2SOCKS_WORKING_TEMPLATE" "$IP_VPN") if [ "$IP_EXTERNAL" != $IP_VPN ]; then checkpoint_true "$TUN2SOCKS_WORKING" else checkpoint_false "$TUN2SOCKS_ROUTING_DOESNT_WORK" fi fi # Check sets # vpn_domains set vpn_domain_ipset_id=$(uci show firewall | grep -E '@ipset.*vpn_domains' | awk -F '[][{}]' '{print $2}' | head -n 1) vpn_domain_ipset_string=$(uci show firewall.@ipset[$vpn_domain_ipset_id] | grep -c "name='vpn_domains'\|match='dst_net'") vpn_domain_rule_id=$(uci show firewall | grep -E '@rule.*vpn_domains' | awk -F '[][{}]' '{print $2}' | head -n 1) vpn_domain_rule_string=$(uci show firewall.@rule[$vpn_domain_rule_id] | grep -c "name='mark_domains'\|src='lan'\|dest='*'\|proto='all'\|ipset='vpn_domains'\|set_mark='0x1'\|target='MARK'\|family='ipv4'") if [ $((vpn_domain_ipset_string + vpn_domain_rule_string)) -eq 10 ]; then checkpoint_true "$VPN_DOMAINS_SET_EXISTS" # force resolve for vpn_domains. All list nslookup terraform.io 127.0.0.1 >/dev/null nslookup pochta.ru 127.0.0.1 >/dev/null nslookup 2gis.ru 127.0.0.1 >/dev/null VPN_DOMAINS_IP=$(nft list ruleset | grep -A 10 vpn_domains | grep -c -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') if [ $VPN_DOMAINS_IP -ge 1 ]; then checkpoint_true "$IPS_IN_VPN_DOMAINS_SET_OK" else checkpoint_false "$IPS_IN_VPN_DOMAINS_SET_ERROR" printf "$VPN_DOMAINS_DETAILS\n" output_21 fi else checkpoint_false "$VPN_DOMAINS_SET_DOESNT_EXIST" printf "$VPN_DOMAINS_DETAILS_2\n" fi # vpn_ip set vpn_ip_ipset_id=$(uci show firewall | grep -E '@ipset.*vpn_ip' | awk -F '[][{}]' '{print $2}' | head -n 1) vpn_ip_ipset_string=$(uci show firewall.@ipset[$vpn_ip_ipset_id] | grep -c "name='vpn_ip'\|match='dst_net'\|loadfile='/tmp/lst/ip.lst'") vpn_ip_rule_id=$(uci show firewall | grep -E '@rule.*vpn_ip' | awk -F '[][{}]' '{print $2}' | head -n 1) vpn_ip_rule_string=$(uci show firewall.@rule[$vpn_ip_rule_id] | grep -c "name='mark_ip'\|src='lan'\|dest='*'\|proto='all'\|ipset='vpn_ip'\|set_mark='0x1'\|target='MARK'\|family='ipv4'") if [ $((vpn_ip_ipset_string + vpn_ip_rule_string)) -eq 11 ]; then checkpoint_true "$VPN_IP_SET_EXISTS" VPN_IP_IP=$(nft list ruleset | grep -A 10 vpn_ip | grep -c -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') if [ $VPN_IP_IP -ge 1 ]; then checkpoint_true "$IPS_IN_VPN_IP_SET_OK" else checkpoint_false "$IPS_IN_VPN_IP_SET_ERROR" output_21 fi elif uci show firewall | grep -q "vpn_ip"; then checkpoint_false "$VPN_IP_SET_DOESNT_EXIST" fi # vpn_subnet set vpn_subnet_ipset_id=$(uci show firewall | grep -E '@ipset.*vpn_subnet' | awk -F '[][{}]' '{print $2}' | head -n 1) vpn_subnet_ipset_string=$(uci show firewall.@ipset[$vpn_subnet_ipset_id] | grep -c "name='vpn_subnets'\|match='dst_net'\|loadfile='/tmp/lst/subnet.lst'") vpn_subnet_rule_id=$(uci show firewall | grep -E '@rule.*vpn_subnet' | awk -F '[][{}]' '{print $2}' | head -n 1) vpn_subnet_rule_string=$(uci show firewall.@rule[$vpn_subnet_rule_id] | grep -c "name='mark_subnet'\|src='lan'\|dest='*'\|proto='all'\|ipset='vpn_subnets'\|set_mark='0x1'\|target='MARK'\|family='ipv4'") if [ $((vpn_subnet_ipset_string + vpn_subnet_rule_string)) -eq 11 ]; then checkpoint_true "$VPN_SUBNET_SET_EXISTS" VPN_IP_SUBNET=$(nft list ruleset | grep -A 10 vpn_subnet | grep -c -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') if [ $VPN_IP_SUBNET -ge 1 ]; then checkpoint_true "$IPS_IN_VPN_SUBNET_SET_OK" else checkpoint_false "$IPS_IN_VPN_SUBNET_SET_ERROR" output_21 fi elif uci show firewall | grep -q "vpn_subnet"; then checkpoint_false "$VPN_SUBNET_SET_DOESNT_EXIST" fi # vpn_community set vpn_community_ipset_id=$(uci show firewall | grep -E '@ipset.*vpn_community' | awk -F '[][{}]' '{print $2}' | head -n 1) vpn_community_ipset_string=$(uci show firewall.@ipset[$vpn_community_ipset_id] | grep -c "name='vpn_community'\|match='dst_net'\|loadfile='/tmp/lst/community.lst'") vpn_community_rule_id=$(uci show firewall | grep -E '@rule.*vpn_community' | awk -F '[][{}]' '{print $2}' | head -n 1) vpn_community_rule_string=$(uci show firewall.@rule[$vpn_community_rule_id] | grep -c "name='mark_community'\|src='lan'\|dest='*'\|proto='all'\|ipset='vpn_community'\|set_mark='0x1'\|target='MARK'\|family='ipv4'") if [ $((vpn_community_ipset_string + vpn_community_rule_string)) -eq 11 ]; then checkpoint_true "$VPN_COMMUNITY_SET_EXISTS" VPN_COMMUNITY_IP=$(nft list ruleset | grep -A 10 vpn_community | grep -c -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') if [ $VPN_COMMUNITY_IP -ge 1 ]; then checkpoint_true "$IPS_IN_VPN_COMMUNITY_SET_OK" else checkpoint_false "$IPS_IN_VPN_COMMUNITY_SET_ERROR" output_21 fi elif uci show firewall | grep -q "vpn_community"; then checkpoint_false "$VPN_COMMUNITY_SET_DOESNT_EXIST" fi # getdomains script if [ -s "$GETDOMAINS_SCRIPT_PATH" ]; then checkpoint_true "$GETDOMAINS_SCRIPT_EXISTS" if crontab -l | grep -q $GETDOMAINS_SCRIPT_PATH; then checkpoint_true "$GETDOMAINS_SCRIPT_CRONTAB_OK" else checkpoint_false "$GETDOMAINS_SCRIPT_CRONTAB_ERROR" fi else checkpoint_false "$GETDOMAINS_SCRIPT_DOESNT_EXIST" fi # DNS # DNSCrypt if opkg list-installed | grep -q dnscrypt-proxy2; then checkpoint_true "$DNSCRYPT_INSTALLED" if service dnscrypt-proxy status | grep -q 'running'; then checkpoint_true "$DNSCRYPT_SERVICE_RUNNING" else checkpoint_false "$DNSCRYPT_SERVICE_NOT_RUNNING" output_21 fi DNSMASQ_STRING=$(uci show dhcp.@dnsmasq[0] | grep -c "127.0.0.53#53\|noresolv='1'") if [ $DNSMASQ_STRING -eq 2 ]; then checkpoint_true "$DNSMASQ_CONFIG_FOR_DNSCRYPT_OK" else checkpoint_false "$DNSMASQ_CONFIG_FOR_DNSCRYPT_ERROR" fi fi # Stubby if opkg list-installed | grep -q stubby; then checkpoint_true "$STUBBY_INSTALLED" if service stubby status | grep -q 'running'; then checkpoint_true "$STUBBY_SERVICE_RUNNING" else checkpoint_false "$STUBBY_SERVICE_NOT_RUNNING" output_21 fi STUBBY_STRING=$(uci show dhcp.@dnsmasq[0] | grep -c "127.0.0.1#5453\|noresolv='1'") if [ $STUBBY_STRING -eq 2 ]; then checkpoint_true "$DNSMASQ_CONFIG_FOR_STUBBY_OK" else checkpoint_false "$DNSMASQ_CONFIG_FOR_STUBBY_ERROR" fi fi case $COMMAND in dump) # Create dump printf "\n$COLOR_BOLD_CYAN$DUMP_CREATION$COLOR_RESET\n" date >$DUMP_PATH $HIVPN start >>$DUMP_PATH 2>&1 $GETDOMAINS_SCRIPT_PATH start >>$DUMP_PATH 2>&1 uci show firewall >>$DUMP_PATH uci show network | sed -r 's/(.*private_key=|.*preshared_key=|.*public_key=|.*endpoint_host=|.*wan.ipaddr=|.*wan.netmask=|.*wan.gateway=|.*wan.dns|.*.macaddr=).*/\1REMOVED/' >>$DUMP_PATH printf "$DUMP_DETAILS\n" ;; dns) # Check DNS printf "\n$COLOR_BOLD_CYAN$DNS_CHECK$COLOR_RESET\n" DNS_SERVERS="1.1.1.1 8.8.8.8 8.8.4.4" DOH_DNS_SERVERS="cloudflare-dns.com 1.1.1.1 mozilla.cloudflare-dns.com security.cloudflare-dns.com" DOMAINS="instagram.com facebook.com" echo "1. $IS_DNS_TRAFFIC_BLOCKED" for i in $DNS_SERVERS; do if nslookup -type=a -timeout=2 -retry=1 itdog.info $i | grep -q "timed out"; then checkpoint_false "$i" else checkpoint_true "$i" fi done echo "2. $IS_DOH_AVAILABLE" for i in $DOH_DNS_SERVERS; do if curl --connect-timeout 5 -s -H "accept: application/dns-json" "https://$i/dns-query?name=itdog.info&type=A" | awk -F"data\":\"" '/data":"/{print $2}' | grep -q -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'; then checkpoint_true "$i" else checkpoint_false "$i" fi done echo "3. $RESPONSE_NOT_CONTAINS_127_0_0_8" for i in $DOMAINS; do if nslookup -type=a -timeout=2 -retry=1 $i | awk '/^Address: / {print $2}' | grep -q -E '127\.[0-9]{1,3}\.'; then checkpoint_false "$i" else checkpoint_true "$i" fi done echo "4. $ONE_IP_FOR_TWO_DOMAINS" FIRSTIP=$(nslookup -type=a instagram.com | awk '/^Address: / {print $2}') SECONDIP=$(nslookup -type=a facebook.com | awk '/^Address: / {print $2}') if [ "$FIRSTIP" = "$SECONDIP" ]; then checkpoint_false "$IPS_ARE_THE_SAME" else checkpoint_true "$IPS_ARE_DIFFERENT" fi echo "5. $RESPONSE_IS_NOT_BLANK" for i in $DOMAINS; do if nslookup -type=a -timeout=2 -retry=1 $i | awk '/^Address: / {print $2}' | grep -q -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'; then checkpoint_true "$i" else checkpoint_false "$i" fi done echo "6. $DNS_POISONING_CHECK" DOHIP=$(curl -s -H "accept: application/dns-json" "https://1.1.1.1/dns-query?name=facebook.com&type=A" | awk -F"data\":\"" '/data":"/{print $2}' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') OPENIP=$(nslookup -type=a -timeout=2 facebook.com 1.1.1.1 | awk '/^Address: / {print $2}') if [ "$DOHIP" = "$OPENIP" ]; then checkpoint_true "$IPS_ARE_THE_SAME" else checkpoint_false "$IPS_ARE_DIFFERENT" fi ;; *) ;; esac # Info echo -e "\n$TELEGRAM_CHANNEL: https://t.me/itdoginfo" echo "$TELEGRAM_CHAT: https://t.me/itdogchat" ================================================ FILE: getdomains-install.sh ================================================ #!/bin/sh #set -x check_repo() { printf "\033[32;1mChecking OpenWrt repo availability...\033[0m\n" opkg update | grep -q "Failed to download" && printf "\033[32;1mopkg failed. Check internet or date. Command for force ntp sync: ntpd -p ptbtime1.ptb.de\033[0m\n" && exit 1 } route_vpn () { if [ "$TUNNEL" == wg ]; then cat << EOF > /etc/hotplug.d/iface/30-vpnroute #!/bin/sh ip route add table vpn default dev wg0 EOF elif [ "$TUNNEL" == awg ]; then cat << EOF > /etc/hotplug.d/iface/30-vpnroute #!/bin/sh ip route add table vpn default dev awg0 EOF elif [ "$TUNNEL" == singbox ] || [ "$TUNNEL" == ovpn ] || [ "$TUNNEL" == tun2socks ]; then cat << EOF > /etc/hotplug.d/iface/30-vpnroute #!/bin/sh sleep 10 ip route add table vpn default dev tun0 EOF fi cp /etc/hotplug.d/iface/30-vpnroute /etc/hotplug.d/net/30-vpnroute } add_mark() { grep -q "99 vpn" /etc/iproute2/rt_tables || echo '99 vpn' >> /etc/iproute2/rt_tables if ! uci show network | grep -q mark0x1; then printf "\033[32;1mConfigure mark rule\033[0m\n" uci add network rule uci set network.@rule[-1].name='mark0x1' uci set network.@rule[-1].mark='0x1' uci set network.@rule[-1].priority='100' uci set network.@rule[-1].lookup='vpn' uci commit fi } add_tunnel() { echo "We can automatically configure only Wireguard and Amnezia WireGuard. OpenVPN, Sing-box(Shadowsocks2022, VMess, VLESS, etc) and tun2socks will need to be configured manually" echo "Select a tunnel:" echo "1) WireGuard" echo "2) OpenVPN" echo "3) Sing-box" echo "4) tun2socks" echo "5) wgForYoutube" echo "6) Amnezia WireGuard" echo "7) Amnezia WireGuard For Youtube" echo "8) Skip this step" while true; do read -r -p '' TUNNEL case $TUNNEL in 1) TUNNEL=wg break ;; 2) TUNNEL=ovpn break ;; 3) TUNNEL=singbox break ;; 4) TUNNEL=tun2socks break ;; 5) TUNNEL=wgForYoutube break ;; 6) TUNNEL=awg break ;; 7) TUNNEL=awgForYoutube break ;; 8) echo "Skip" TUNNEL=0 break ;; *) echo "Choose from the following options" ;; esac done if [ "$TUNNEL" == 'wg' ]; then printf "\033[32;1mConfigure WireGuard\033[0m\n" if opkg list-installed | grep -q wireguard-tools; then echo "Wireguard already installed" else echo "Installed wg..." opkg install wireguard-tools fi route_vpn read -r -p "Enter the private key (from [Interface]):"$'\n' WG_PRIVATE_KEY while true; do read -r -p "Enter internal IP address with subnet, example 192.168.100.5/24 (from [Interface]):"$'\n' WG_IP if echo "$WG_IP" | egrep -oq '^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]+$'; then break else echo "This IP is not valid. Please repeat" fi done read -r -p "Enter the public key (from [Peer]):"$'\n' WG_PUBLIC_KEY read -r -p "If use PresharedKey, Enter this (from [Peer]). If your don't use leave blank:"$'\n' WG_PRESHARED_KEY read -r -p "Enter Endpoint host without port (Domain or IP) (from [Peer]):"$'\n' WG_ENDPOINT read -r -p "Enter Endpoint host port (from [Peer]) [51820]:"$'\n' WG_ENDPOINT_PORT WG_ENDPOINT_PORT=${WG_ENDPOINT_PORT:-51820} if [ "$WG_ENDPOINT_PORT" = '51820' ]; then echo $WG_ENDPOINT_PORT fi uci set network.wg0=interface uci set network.wg0.proto='wireguard' uci set network.wg0.private_key=$WG_PRIVATE_KEY uci set network.wg0.listen_port='51820' uci set network.wg0.addresses=$WG_IP if ! uci show network | grep -q wireguard_wg0; then uci add network wireguard_wg0 fi uci set network.@wireguard_wg0[0]=wireguard_wg0 uci set network.@wireguard_wg0[0].name='wg0_client' uci set network.@wireguard_wg0[0].public_key=$WG_PUBLIC_KEY uci set network.@wireguard_wg0[0].preshared_key=$WG_PRESHARED_KEY uci set network.@wireguard_wg0[0].route_allowed_ips='0' uci set network.@wireguard_wg0[0].persistent_keepalive='25' uci set network.@wireguard_wg0[0].endpoint_host=$WG_ENDPOINT uci set network.@wireguard_wg0[0].allowed_ips='0.0.0.0/0' uci set network.@wireguard_wg0[0].endpoint_port=$WG_ENDPOINT_PORT uci commit fi if [ "$TUNNEL" == 'ovpn' ]; then if opkg list-installed | grep -q openvpn-openssl; then echo "OpenVPN already installed" else echo "Installed openvpn" opkg install openvpn-openssl fi printf "\033[32;1mConfigure route for OpenVPN\033[0m\n" route_vpn fi if [ "$TUNNEL" == 'singbox' ]; then if opkg list-installed | grep -q sing-box; then echo "Sing-box already installed" else AVAILABLE_SPACE=$(df / | awk 'NR>1 { print $4 }') if [[ "$AVAILABLE_SPACE" -gt 2000 ]]; then echo "Installed sing-box" opkg install sing-box else printf "\033[31;1mNo free space for a sing-box. Sing-box is not installed.\033[0m\n" exit 1 fi fi if grep -q "option enabled '0'" /etc/config/sing-box; then sed -i "s/ option enabled \'0\'/ option enabled \'1\'/" /etc/config/sing-box fi if grep -q "option user 'sing-box'" /etc/config/sing-box; then sed -i "s/ option user \'sing-box\'/ option user \'root\'/" /etc/config/sing-box fi if grep -q "tun0" /etc/sing-box/config.json; then printf "\033[32;1mConfig /etc/sing-box/config.json already exists\033[0m\n" else cat << 'EOF' > /etc/sing-box/config.json { "log": { "level": "debug" }, "inbounds": [ { "type": "tun", "interface_name": "tun0", "domain_strategy": "ipv4_only", "address": ["172.16.250.1/30"], "auto_route": false, "strict_route": false, "sniff": true } ], "outbounds": [ { "type": "$TYPE", "server": "$HOST", "server_port": $PORT, "method": "$METHOD", "password": "$PASS" } ], "route": { "auto_detect_interface": true } } EOF printf "\033[32;1mCreate template config in /etc/sing-box/config.json. Edit it manually. Official doc: https://sing-box.sagernet.org/configuration/outbound/\033[0m\n" printf "\033[32;1mOfficial doc: https://sing-box.sagernet.org/configuration/outbound/\033[0m\n" printf "\033[32;1mManual with example SS: https://cli.co/Badmn3K \033[0m\n" fi printf "\033[32;1mConfigure route for Sing-box\033[0m\n" route_vpn fi if [ "$TUNNEL" == 'wgForYoutube' ]; then add_internal_wg Wireguard fi if [ "$TUNNEL" == 'awgForYoutube' ]; then add_internal_wg AmneziaWG fi if [ "$TUNNEL" == 'awg' ]; then printf "\033[32;1mConfigure Amnezia WireGuard\033[0m\n" install_awg_packages route_vpn read -r -p "Enter the private key (from [Interface]):"$'\n' AWG_PRIVATE_KEY while true; do read -r -p "Enter internal IP address with subnet, example 192.168.100.5/24 (Address from [Interface]):"$'\n' AWG_IP if echo "$AWG_IP" | egrep -oq '^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]+$'; then break else echo "This IP is not valid. Please repeat" fi done read -r -p "Enter Jc value (from [Interface]):"$'\n' AWG_JC read -r -p "Enter Jmin value (from [Interface]):"$'\n' AWG_JMIN read -r -p "Enter Jmax value (from [Interface]):"$'\n' AWG_JMAX read -r -p "Enter S1 value (from [Interface]):"$'\n' AWG_S1 read -r -p "Enter S2 value (from [Interface]):"$'\n' AWG_S2 read -r -p "Enter H1 value (from [Interface]):"$'\n' AWG_H1 read -r -p "Enter H2 value (from [Interface]):"$'\n' AWG_H2 read -r -p "Enter H3 value (from [Interface]):"$'\n' AWG_H3 read -r -p "Enter H4 value (from [Interface]):"$'\n' AWG_H4 read -r -p "Enter the public key (from [Peer]):"$'\n' AWG_PUBLIC_KEY read -r -p "If use PresharedKey, Enter this (from [Peer]). If your don't use leave blank:"$'\n' AWG_PRESHARED_KEY read -r -p "Enter Endpoint host without port (Domain or IP) (from [Peer]):"$'\n' AWG_ENDPOINT read -r -p "Enter Endpoint host port (from [Peer]) [51820]:"$'\n' AWG_ENDPOINT_PORT AWG_ENDPOINT_PORT=${AWG_ENDPOINT_PORT:-51820} if [ "$AWG_ENDPOINT_PORT" = '51820' ]; then echo $AWG_ENDPOINT_PORT fi uci set network.awg0=interface uci set network.awg0.proto='amneziawg' uci set network.awg0.private_key=$AWG_PRIVATE_KEY uci set network.awg0.listen_port='51820' uci set network.awg0.addresses=$AWG_IP uci set network.awg0.awg_jc=$AWG_JC uci set network.awg0.awg_jmin=$AWG_JMIN uci set network.awg0.awg_jmax=$AWG_JMAX uci set network.awg0.awg_s1=$AWG_S1 uci set network.awg0.awg_s2=$AWG_S2 uci set network.awg0.awg_h1=$AWG_H1 uci set network.awg0.awg_h2=$AWG_H2 uci set network.awg0.awg_h3=$AWG_H3 uci set network.awg0.awg_h4=$AWG_H4 if ! uci show network | grep -q amneziawg_awg0; then uci add network amneziawg_awg0 fi uci set network.@amneziawg_awg0[0]=amneziawg_awg0 uci set network.@amneziawg_awg0[0].name='awg0_client' uci set network.@amneziawg_awg0[0].public_key=$AWG_PUBLIC_KEY uci set network.@amneziawg_awg0[0].preshared_key=$AWG_PRESHARED_KEY uci set network.@amneziawg_awg0[0].route_allowed_ips='0' uci set network.@amneziawg_awg0[0].persistent_keepalive='25' uci set network.@amneziawg_awg0[0].endpoint_host=$AWG_ENDPOINT uci set network.@amneziawg_awg0[0].allowed_ips='0.0.0.0/0' uci set network.@amneziawg_awg0[0].endpoint_port=$AWG_ENDPOINT_PORT uci commit fi } dnsmasqfull() { if opkg list-installed | grep -q dnsmasq-full; then printf "\033[32;1mdnsmasq-full already installed\033[0m\n" else printf "\033[32;1mInstalled dnsmasq-full\033[0m\n" cd /tmp/ && opkg download dnsmasq-full opkg remove dnsmasq && opkg install dnsmasq-full --cache /tmp/ [ -f /etc/config/dhcp-opkg ] && cp /etc/config/dhcp /etc/config/dhcp-old && mv /etc/config/dhcp-opkg /etc/config/dhcp fi } dnsmasqconfdir() { if [ $VERSION_ID -ge 24 ]; then if uci get dhcp.@dnsmasq[0].confdir | grep -q /tmp/dnsmasq.d; then printf "\033[32;1mconfdir already set\033[0m\n" else printf "\033[32;1mSetting confdir\033[0m\n" uci set dhcp.@dnsmasq[0].confdir='/tmp/dnsmasq.d' uci commit dhcp fi fi } remove_forwarding() { if [ ! -z "$forward_id" ]; then while uci -q delete firewall.@forwarding[$forward_id]; do :; done fi } add_zone() { if [ "$TUNNEL" == 0 ]; then printf "\033[32;1mZone setting skipped\033[0m\n" elif uci show firewall | grep -q "@zone.*name='$TUNNEL'"; then printf "\033[32;1mZone already exist\033[0m\n" else printf "\033[32;1mCreate zone\033[0m\n" # Delete exists zone zone_tun_id=$(uci show firewall | grep -E '@zone.*tun0' | awk -F '[][{}]' '{print $2}' | head -n 1) if [ "$zone_tun_id" == 0 ] || [ "$zone_tun_id" == 1 ]; then printf "\033[32;1mtun0 zone has an identifier of 0 or 1. That's not ok. Fix your firewall. lan and wan zones should have identifiers 0 and 1. \033[0m\n" exit 1 fi if [ ! -z "$zone_tun_id" ]; then while uci -q delete firewall.@zone[$zone_tun_id]; do :; done fi zone_wg_id=$(uci show firewall | grep -E '@zone.*wg0' | awk -F '[][{}]' '{print $2}' | head -n 1) if [ "$zone_wg_id" == 0 ] || [ "$zone_wg_id" == 1 ]; then printf "\033[32;1mwg0 zone has an identifier of 0 or 1. That's not ok. Fix your firewall. lan and wan zones should have identifiers 0 and 1. \033[0m\n" exit 1 fi if [ ! -z "$zone_wg_id" ]; then while uci -q delete firewall.@zone[$zone_wg_id]; do :; done fi zone_awg_id=$(uci show firewall | grep -E '@zone.*awg0' | awk -F '[][{}]' '{print $2}' | head -n 1) if [ "$zone_awg_id" == 0 ] || [ "$zone_awg_id" == 1 ]; then printf "\033[32;1mawg0 zone has an identifier of 0 or 1. That's not ok. Fix your firewall. lan and wan zones should have identifiers 0 and 1. \033[0m\n" exit 1 fi if [ ! -z "$zone_awg_id" ]; then while uci -q delete firewall.@zone[$zone_awg_id]; do :; done fi uci add firewall zone uci set firewall.@zone[-1].name="$TUNNEL" if [ "$TUNNEL" == wg ]; then uci set firewall.@zone[-1].network='wg0' elif [ "$TUNNEL" == awg ]; then uci set firewall.@zone[-1].network='awg0' elif [ "$TUNNEL" == singbox ] || [ "$TUNNEL" == ovpn ] || [ "$TUNNEL" == tun2socks ]; then uci set firewall.@zone[-1].device='tun0' fi if [ "$TUNNEL" == wg ] || [ "$TUNNEL" == awg ] || [ "$TUNNEL" == ovpn ] || [ "$TUNNEL" == tun2socks ]; then uci set firewall.@zone[-1].forward='REJECT' uci set firewall.@zone[-1].output='ACCEPT' uci set firewall.@zone[-1].input='REJECT' elif [ "$TUNNEL" == singbox ]; then uci set firewall.@zone[-1].forward='ACCEPT' uci set firewall.@zone[-1].output='ACCEPT' uci set firewall.@zone[-1].input='ACCEPT' fi uci set firewall.@zone[-1].masq='1' uci set firewall.@zone[-1].mtu_fix='1' uci set firewall.@zone[-1].family='ipv4' uci commit firewall fi if [ "$TUNNEL" == 0 ]; then printf "\033[32;1mForwarding setting skipped\033[0m\n" elif uci show firewall | grep -q "@forwarding.*name='$TUNNEL-lan'"; then printf "\033[32;1mForwarding already configured\033[0m\n" else printf "\033[32;1mConfigured forwarding\033[0m\n" # Delete exists forwarding if [[ $TUNNEL != "wg" ]]; then forward_id=$(uci show firewall | grep -E "@forwarding.*dest='wg'" | awk -F '[][{}]' '{print $2}' | head -n 1) remove_forwarding fi if [[ $TUNNEL != "awg" ]]; then forward_id=$(uci show firewall | grep -E "@forwarding.*dest='awg'" | awk -F '[][{}]' '{print $2}' | head -n 1) remove_forwarding fi if [[ $TUNNEL != "ovpn" ]]; then forward_id=$(uci show firewall | grep -E "@forwarding.*dest='ovpn'" | awk -F '[][{}]' '{print $2}' | head -n 1) remove_forwarding fi if [[ $TUNNEL != "singbox" ]]; then forward_id=$(uci show firewall | grep -E "@forwarding.*dest='singbox'" | awk -F '[][{}]' '{print $2}' | head -n 1) remove_forwarding fi if [[ $TUNNEL != "tun2socks" ]]; then forward_id=$(uci show firewall | grep -E "@forwarding.*dest='tun2socks'" | awk -F '[][{}]' '{print $2}' | head -n 1) remove_forwarding fi uci add firewall forwarding uci set firewall.@forwarding[-1]=forwarding uci set firewall.@forwarding[-1].name="$TUNNEL-lan" uci set firewall.@forwarding[-1].dest="$TUNNEL" uci set firewall.@forwarding[-1].src='lan' uci set firewall.@forwarding[-1].family='ipv4' uci commit firewall fi } show_manual() { if [ "$TUNNEL" == tun2socks ]; then printf "\033[42;1mZone for tun2socks cofigured. But you need to set up the tunnel yourself.\033[0m\n" echo "Use this manual: https://cli.co/VNZISEM" elif [ "$TUNNEL" == ovpn ]; then printf "\033[42;1mZone for OpenVPN cofigured. But you need to set up the tunnel yourself.\033[0m\n" echo "Use this manual: https://itdog.info/nastrojka-klienta-openvpn-na-openwrt/" fi } add_set() { if uci show firewall | grep -q "@ipset.*name='vpn_domains'"; then printf "\033[32;1mSet already exist\033[0m\n" else printf "\033[32;1mCreate set\033[0m\n" uci add firewall ipset uci set firewall.@ipset[-1].name='vpn_domains' uci set firewall.@ipset[-1].match='dst_net' uci commit fi if uci show firewall | grep -q "@rule.*name='mark_domains'"; then printf "\033[32;1mRule for set already exist\033[0m\n" else printf "\033[32;1mCreate rule set\033[0m\n" uci add firewall rule uci set firewall.@rule[-1]=rule uci set firewall.@rule[-1].name='mark_domains' uci set firewall.@rule[-1].src='lan' uci set firewall.@rule[-1].dest='*' uci set firewall.@rule[-1].proto='all' uci set firewall.@rule[-1].ipset='vpn_domains' uci set firewall.@rule[-1].set_mark='0x1' uci set firewall.@rule[-1].target='MARK' uci set firewall.@rule[-1].family='ipv4' uci commit fi } add_dns_resolver() { echo "Configure DNSCrypt2 or Stubby? It does matter if your ISP is spoofing DNS requests" DISK=$(df -m / | awk 'NR==2{ print $2 }') if [[ "$DISK" -lt 32 ]]; then printf "\033[31;1mYour router a disk have less than 32MB. It is not recommended to install DNSCrypt, it takes 10MB\033[0m\n" fi echo "Select:" echo "1) No [Default]" echo "2) DNSCrypt2 (10.7M)" echo "3) Stubby (36K)" while true; do read -r -p '' DNS_RESOLVER case $DNS_RESOLVER in 1) echo "Skiped" break ;; 2) DNS_RESOLVER=DNSCRYPT break ;; 3) DNS_RESOLVER=STUBBY break ;; *) echo "Choose from the following options" ;; esac done if [ "$DNS_RESOLVER" == 'DNSCRYPT' ]; then if opkg list-installed | grep -q dnscrypt-proxy2; then printf "\033[32;1mDNSCrypt2 already installed\033[0m\n" else printf "\033[32;1mInstalled dnscrypt-proxy2\033[0m\n" opkg install dnscrypt-proxy2 if grep -q "# server_names" /etc/dnscrypt-proxy2/dnscrypt-proxy.toml; then sed -i "s/^# server_names =.*/server_names = [\'google\', \'cloudflare\', \'scaleway-fr\', \'yandex\']/g" /etc/dnscrypt-proxy2/dnscrypt-proxy.toml fi printf "\033[32;1mDNSCrypt restart\033[0m\n" service dnscrypt-proxy restart printf "\033[32;1mDNSCrypt needs to load the relays list. Please wait\033[0m\n" sleep 30 if [ -f /etc/dnscrypt-proxy2/relays.md ]; then uci set dhcp.@dnsmasq[0].noresolv="1" uci -q delete dhcp.@dnsmasq[0].server uci add_list dhcp.@dnsmasq[0].server="127.0.0.53#53" uci add_list dhcp.@dnsmasq[0].server='/use-application-dns.net/' uci commit dhcp printf "\033[32;1mDnsmasq restart\033[0m\n" /etc/init.d/dnsmasq restart else printf "\033[31;1mDNSCrypt not download list on /etc/dnscrypt-proxy2. Repeat install DNSCrypt by script.\033[0m\n" fi fi fi if [ "$DNS_RESOLVER" == 'STUBBY' ]; then printf "\033[32;1mConfigure Stubby\033[0m\n" if opkg list-installed | grep -q stubby; then printf "\033[32;1mStubby already installed\033[0m\n" else printf "\033[32;1mInstalled stubby\033[0m\n" opkg install stubby printf "\033[32;1mConfigure Dnsmasq for Stubby\033[0m\n" uci set dhcp.@dnsmasq[0].noresolv="1" uci -q delete dhcp.@dnsmasq[0].server uci add_list dhcp.@dnsmasq[0].server="127.0.0.1#5453" uci add_list dhcp.@dnsmasq[0].server='/use-application-dns.net/' uci commit dhcp printf "\033[32;1mDnsmasq restart\033[0m\n" /etc/init.d/dnsmasq restart fi fi } add_packages() { for package in curl nano; do if opkg list-installed | grep -q "^$package "; then printf "\033[32;1m$package already installed\033[0m\n" else printf "\033[32;1mInstalling $package...\033[0m\n" opkg install "$package" if "$package" --version >/dev/null 2>&1; then printf "\033[32;1m$package was successfully installed and available\033[0m\n" else printf "\033[31;1mError: failed to install $package\033[0m\n" exit 1 fi fi done } add_getdomains() { echo "Choose you country" echo "Select:" echo "1) Russia inside. You are inside Russia" echo "2) Russia outside. You are outside of Russia, but you need access to Russian resources" echo "3) Ukraine. uablacklist.net list" echo "4) Skip script creation" while true; do read -r -p '' COUNTRY case $COUNTRY in 1) COUNTRY=russia_inside break ;; 2) COUNTRY=russia_outside break ;; 3) COUNTRY=ukraine break ;; 4) echo "Skiped" COUNTRY=0 break ;; *) echo "Choose from the following options" ;; esac done if [ "$COUNTRY" == 'russia_inside' ]; then EOF_DOMAINS=DOMAINS=https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Russia/inside-dnsmasq-nfset.lst elif [ "$COUNTRY" == 'russia_outside' ]; then EOF_DOMAINS=DOMAINS=https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Russia/outside-dnsmasq-nfset.lst elif [ "$COUNTRY" == 'ukraine' ]; then EOF_DOMAINS=DOMAINS=https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Ukraine/inside-dnsmasq-nfset.lst fi if [ "$COUNTRY" != '0' ]; then printf "\033[32;1mCreate script /etc/init.d/getdomains\033[0m\n" cat << EOF > /etc/init.d/getdomains #!/bin/sh /etc/rc.common START=99 start () { $EOF_DOMAINS EOF cat << 'EOF' >> /etc/init.d/getdomains count=0 while true; do if curl -m 3 github.com; then curl -f $DOMAINS --output /tmp/dnsmasq.d/domains.lst break else echo "GitHub is not available. Check the internet availability [$count]" count=$((count+1)) fi done if dnsmasq --conf-file=/tmp/dnsmasq.d/domains.lst --test 2>&1 | grep -q "syntax check OK"; then /etc/init.d/dnsmasq restart fi } EOF chmod +x /etc/init.d/getdomains /etc/init.d/getdomains enable if crontab -l | grep -q /etc/init.d/getdomains; then printf "\033[32;1mCrontab already configured\033[0m\n" else crontab -l | { cat; echo "0 */8 * * * /etc/init.d/getdomains start"; } | crontab - printf "\033[32;1mIgnore this error. This is normal for a new installation\033[0m\n" /etc/init.d/cron restart fi printf "\033[32;1mStart script\033[0m\n" /etc/init.d/getdomains start fi } add_internal_wg() { PROTOCOL_NAME=$1 printf "\033[32;1mConfigure ${PROTOCOL_NAME}\033[0m\n" if [ "$PROTOCOL_NAME" = 'Wireguard' ]; then INTERFACE_NAME="wg1" CONFIG_NAME="wireguard_wg1" PROTO="wireguard" ZONE_NAME="wg_internal" if opkg list-installed | grep -q wireguard-tools; then echo "Wireguard already installed" else echo "Installed wg..." opkg install wireguard-tools fi fi if [ "$PROTOCOL_NAME" = 'AmneziaWG' ]; then INTERFACE_NAME="awg1" CONFIG_NAME="amneziawg_awg1" PROTO="amneziawg" ZONE_NAME="awg_internal" install_awg_packages fi read -r -p "Enter the private key (from [Interface]):"$'\n' WG_PRIVATE_KEY_INT while true; do read -r -p "Enter internal IP address with subnet, example 192.168.100.5/24 (from [Interface]):"$'\n' WG_IP if echo "$WG_IP" | egrep -oq '^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]+$'; then break else echo "This IP is not valid. Please repeat" fi done read -r -p "Enter the public key (from [Peer]):"$'\n' WG_PUBLIC_KEY_INT read -r -p "If use PresharedKey, Enter this (from [Peer]). If your don't use leave blank:"$'\n' WG_PRESHARED_KEY_INT read -r -p "Enter Endpoint host without port (Domain or IP) (from [Peer]):"$'\n' WG_ENDPOINT_INT read -r -p "Enter Endpoint host port (from [Peer]) [51820]:"$'\n' WG_ENDPOINT_PORT_INT WG_ENDPOINT_PORT_INT=${WG_ENDPOINT_PORT_INT:-51820} if [ "$WG_ENDPOINT_PORT_INT" = '51820' ]; then echo $WG_ENDPOINT_PORT_INT fi if [ "$PROTOCOL_NAME" = 'AmneziaWG' ]; then read -r -p "Enter Jc value (from [Interface]):"$'\n' AWG_JC read -r -p "Enter Jmin value (from [Interface]):"$'\n' AWG_JMIN read -r -p "Enter Jmax value (from [Interface]):"$'\n' AWG_JMAX read -r -p "Enter S1 value (from [Interface]):"$'\n' AWG_S1 read -r -p "Enter S2 value (from [Interface]):"$'\n' AWG_S2 read -r -p "Enter H1 value (from [Interface]):"$'\n' AWG_H1 read -r -p "Enter H2 value (from [Interface]):"$'\n' AWG_H2 read -r -p "Enter H3 value (from [Interface]):"$'\n' AWG_H3 read -r -p "Enter H4 value (from [Interface]):"$'\n' AWG_H4 fi uci set network.${INTERFACE_NAME}=interface uci set network.${INTERFACE_NAME}.proto=$PROTO uci set network.${INTERFACE_NAME}.private_key=$WG_PRIVATE_KEY_INT uci set network.${INTERFACE_NAME}.listen_port='51821' uci set network.${INTERFACE_NAME}.addresses=$WG_IP if [ "$PROTOCOL_NAME" = 'AmneziaWG' ]; then uci set network.${INTERFACE_NAME}.awg_jc=$AWG_JC uci set network.${INTERFACE_NAME}.awg_jmin=$AWG_JMIN uci set network.${INTERFACE_NAME}.awg_jmax=$AWG_JMAX uci set network.${INTERFACE_NAME}.awg_s1=$AWG_S1 uci set network.${INTERFACE_NAME}.awg_s2=$AWG_S2 uci set network.${INTERFACE_NAME}.awg_h1=$AWG_H1 uci set network.${INTERFACE_NAME}.awg_h2=$AWG_H2 uci set network.${INTERFACE_NAME}.awg_h3=$AWG_H3 uci set network.${INTERFACE_NAME}.awg_h4=$AWG_H4 fi if ! uci show network | grep -q ${CONFIG_NAME}; then uci add network ${CONFIG_NAME} fi uci set network.@${CONFIG_NAME}[0]=$CONFIG_NAME uci set network.@${CONFIG_NAME}[0].name="${INTERFACE_NAME}_client" uci set network.@${CONFIG_NAME}[0].public_key=$WG_PUBLIC_KEY_INT uci set network.@${CONFIG_NAME}[0].preshared_key=$WG_PRESHARED_KEY_INT uci set network.@${CONFIG_NAME}[0].route_allowed_ips='0' uci set network.@${CONFIG_NAME}[0].persistent_keepalive='25' uci set network.@${CONFIG_NAME}[0].endpoint_host=$WG_ENDPOINT_INT uci set network.@${CONFIG_NAME}[0].allowed_ips='0.0.0.0/0' uci set network.@${CONFIG_NAME}[0].endpoint_port=$WG_ENDPOINT_PORT_INT uci commit network grep -q "110 vpninternal" /etc/iproute2/rt_tables || echo '110 vpninternal' >> /etc/iproute2/rt_tables if ! uci show network | grep -q mark0x2; then printf "\033[32;1mConfigure mark rule\033[0m\n" uci add network rule uci set network.@rule[-1].name='mark0x2' uci set network.@rule[-1].mark='0x2' uci set network.@rule[-1].priority='110' uci set network.@rule[-1].lookup='vpninternal' uci commit fi if ! uci show network | grep -q vpn_route_internal; then printf "\033[32;1mAdd route\033[0m\n" uci set network.vpn_route_internal=route uci set network.vpn_route_internal.name='vpninternal' uci set network.vpn_route_internal.interface=$INTERFACE_NAME uci set network.vpn_route_internal.table='vpninternal' uci set network.vpn_route_internal.target='0.0.0.0/0' uci commit network fi if ! uci show firewall | grep -q "@zone.*name='${ZONE_NAME}'"; then printf "\033[32;1mZone Create\033[0m\n" uci add firewall zone uci set firewall.@zone[-1].name=$ZONE_NAME uci set firewall.@zone[-1].network=$INTERFACE_NAME uci set firewall.@zone[-1].forward='REJECT' uci set firewall.@zone[-1].output='ACCEPT' uci set firewall.@zone[-1].input='REJECT' uci set firewall.@zone[-1].masq='1' uci set firewall.@zone[-1].mtu_fix='1' uci set firewall.@zone[-1].family='ipv4' uci commit firewall fi if ! uci show firewall | grep -q "@forwarding.*name='${ZONE_NAME}'"; then printf "\033[32;1mConfigured forwarding\033[0m\n" uci add firewall forwarding uci set firewall.@forwarding[-1]=forwarding uci set firewall.@forwarding[-1].name="${ZONE_NAME}-lan" uci set firewall.@forwarding[-1].dest=${ZONE_NAME} uci set firewall.@forwarding[-1].src='lan' uci set firewall.@forwarding[-1].family='ipv4' uci commit firewall fi if uci show firewall | grep -q "@ipset.*name='vpn_domains_internal'"; then printf "\033[32;1mSet already exist\033[0m\n" else printf "\033[32;1mCreate set\033[0m\n" uci add firewall ipset uci set firewall.@ipset[-1].name='vpn_domains_internal' uci set firewall.@ipset[-1].match='dst_net' uci commit firewall fi if uci show firewall | grep -q "@rule.*name='mark_domains_intenal'"; then printf "\033[32;1mRule for set already exist\033[0m\n" else printf "\033[32;1mCreate rule set\033[0m\n" uci add firewall rule uci set firewall.@rule[-1]=rule uci set firewall.@rule[-1].name='mark_domains_intenal' uci set firewall.@rule[-1].src='lan' uci set firewall.@rule[-1].dest='*' uci set firewall.@rule[-1].proto='all' uci set firewall.@rule[-1].ipset='vpn_domains_internal' uci set firewall.@rule[-1].set_mark='0x2' uci set firewall.@rule[-1].target='MARK' uci set firewall.@rule[-1].family='ipv4' uci commit firewall fi if uci show dhcp | grep -q "@ipset.*name='vpn_domains_internal'"; then printf "\033[32;1mDomain on vpn_domains_internal already exist\033[0m\n" else printf "\033[32;1mCreate domain for vpn_domains_internal\033[0m\n" uci add dhcp ipset uci add_list dhcp.@ipset[-1].name='vpn_domains_internal' uci add_list dhcp.@ipset[-1].domain='youtube.com' uci add_list dhcp.@ipset[-1].domain='googlevideo.com' uci add_list dhcp.@ipset[-1].domain='youtubekids.com' uci add_list dhcp.@ipset[-1].domain='googleapis.com' uci add_list dhcp.@ipset[-1].domain='ytimg.com' uci add_list dhcp.@ipset[-1].domain='ggpht.com' uci commit dhcp fi sed -i "/done/a sed -i '/youtube.com\\\|ytimg.com\\\|ggpht.com\\\|googlevideo.com\\\|googleapis.com\\\|youtubekids.com/d' /tmp/dnsmasq.d/domains.lst" "/etc/init.d/getdomains" service dnsmasq restart service network restart exit 0 } install_awg_packages() { # Получение pkgarch с наибольшим приоритетом PKGARCH=$(opkg print-architecture | awk 'BEGIN {max=0} {if ($3 > max) {max = $3; arch = $2}} END {print arch}') TARGET=$(ubus call system board | jsonfilter -e '@.release.target' | cut -d '/' -f 1) SUBTARGET=$(ubus call system board | jsonfilter -e '@.release.target' | cut -d '/' -f 2) VERSION=$(ubus call system board | jsonfilter -e '@.release.version') PKGPOSTFIX="_v${VERSION}_${PKGARCH}_${TARGET}_${SUBTARGET}.ipk" BASE_URL="https://github.com/Slava-Shchipunov/awg-openwrt/releases/download/" AWG_DIR="/tmp/amneziawg" mkdir -p "$AWG_DIR" if opkg list-installed | grep -q amneziawg-tools; then echo "amneziawg-tools already installed" else AMNEZIAWG_TOOLS_FILENAME="amneziawg-tools${PKGPOSTFIX}" DOWNLOAD_URL="${BASE_URL}v${VERSION}/${AMNEZIAWG_TOOLS_FILENAME}" curl -L -o "$AWG_DIR/$AMNEZIAWG_TOOLS_FILENAME" "$DOWNLOAD_URL" if [ $? -eq 0 ]; then echo "amneziawg-tools file downloaded successfully" else echo "Error downloading amneziawg-tools. Please, install amneziawg-tools manually and run the script again" exit 1 fi opkg install "$AWG_DIR/$AMNEZIAWG_TOOLS_FILENAME" if [ $? -eq 0 ]; then echo "amneziawg-tools file downloaded successfully" else echo "Error installing amneziawg-tools. Please, install amneziawg-tools manually and run the script again" exit 1 fi fi if opkg list-installed | grep -q kmod-amneziawg; then echo "kmod-amneziawg already installed" else KMOD_AMNEZIAWG_FILENAME="kmod-amneziawg${PKGPOSTFIX}" DOWNLOAD_URL="${BASE_URL}v${VERSION}/${KMOD_AMNEZIAWG_FILENAME}" curl -L -o "$AWG_DIR/$KMOD_AMNEZIAWG_FILENAME" "$DOWNLOAD_URL" if [ $? -eq 0 ]; then echo "kmod-amneziawg file downloaded successfully" else echo "Error downloading kmod-amneziawg. Please, install kmod-amneziawg manually and run the script again" exit 1 fi opkg install "$AWG_DIR/$KMOD_AMNEZIAWG_FILENAME" if [ $? -eq 0 ]; then echo "kmod-amneziawg file downloaded successfully" else echo "Error installing kmod-amneziawg. Please, install kmod-amneziawg manually and run the script again" exit 1 fi fi if opkg list-installed | grep -q luci-app-amneziawg; then echo "luci-app-amneziawg already installed" else LUCI_APP_AMNEZIAWG_FILENAME="luci-app-amneziawg${PKGPOSTFIX}" DOWNLOAD_URL="${BASE_URL}v${VERSION}/${LUCI_APP_AMNEZIAWG_FILENAME}" curl -L -o "$AWG_DIR/$LUCI_APP_AMNEZIAWG_FILENAME" "$DOWNLOAD_URL" if [ $? -eq 0 ]; then echo "luci-app-amneziawg file downloaded successfully" else echo "Error downloading luci-app-amneziawg. Please, install luci-app-amneziawg manually and run the script again" exit 1 fi opkg install "$AWG_DIR/$LUCI_APP_AMNEZIAWG_FILENAME" if [ $? -eq 0 ]; then echo "luci-app-amneziawg file downloaded successfully" else echo "Error installing luci-app-amneziawg. Please, install luci-app-amneziawg manually and run the script again" exit 1 fi fi rm -rf "$AWG_DIR" } # System Details MODEL=$(cat /tmp/sysinfo/model) source /etc/os-release printf "\033[34;1mModel: $MODEL\033[0m\n" printf "\033[34;1mVersion: $OPENWRT_RELEASE\033[0m\n" VERSION_ID=$(echo $VERSION | awk -F. '{print $1}') if [ "$VERSION_ID" -ne 23 ] && [ "$VERSION_ID" -ne 24 ]; then printf "\033[31;1mScript only support OpenWrt 23.05 and 24.10\033[0m\n" echo "For OpenWrt 21.02 and 22.03 you can:" echo "1) Use ansible https://github.com/itdoginfo/domain-routing-openwrt" echo "2) Configure manually. Old manual: https://itdog.info/tochechnaya-marshrutizaciya-na-routere-s-openwrt-wireguard-i-dnscrypt/" exit 1 fi printf "\033[31;1mAll actions performed here cannot be rolled back automatically.\033[0m\n" check_repo add_packages add_tunnel add_mark add_zone show_manual add_set dnsmasqfull dnsmasqconfdir add_dns_resolver add_getdomains printf "\033[32;1mRestart network\033[0m\n" /etc/init.d/network restart printf "\033[32;1mDone\033[0m\n" ================================================ FILE: getdomains-uninstall.sh ================================================ #!/bin/ash echo "Выпиливаем скрипты" /etc/init.d/getdomains disable rm -rf /etc/init.d/getdomains rm -f /etc/hotplug.d/iface/30-vpnroute /etc/hotplug.d/net/30-vpnroute echo "Выпиливаем из crontab" sed -i '/getdomains start/d' /etc/crontabs/root echo "Выпиливаем домены" rm -f /tmp/dnsmasq.d/domains.lst echo "Чистим firewall, раз раз 🍴" ipset_id=$(uci show firewall | grep -E '@ipset.*name=.vpn_domains.' | awk -F '[][{}]' '{print $2}' | head -n 1) if [ ! -z "$ipset_id" ]; then while uci -q delete firewall.@ipset[$ipset_id]; do :; done fi rule_id=$(uci show firewall | grep -E '@rule.*name=.mark_domains.' | awk -F '[][{}]' '{print $2}' | head -n 1) if [ ! -z "$rule_id" ]; then while uci -q delete firewall.@rule[$rule_id]; do :; done fi ipset_id=$(uci show firewall | grep -E '@ipset.*name=.vpn_domains_internal.' | awk -F '[][{}]' '{print $2}' | head -n 1) if [ ! -z "$ipset_id" ]; then while uci -q delete firewall.@ipset[$ipset_id]; do :; done fi rule_id=$(uci show firewall | grep -E '@rule.*name=.mark_domains_intenal.' | awk -F '[][{}]' '{print $2}' | head -n 1) if [ ! -z "$rule_id" ]; then while uci -q delete firewall.@rule[$rule_id]; do :; done fi ipset_id=$(uci show firewall | grep -E '@ipset.*name=.vpn_subnet.' | awk -F '[][{}]' '{print $2}' | head -n 1) if [ ! -z "$ipset_id" ]; then while uci -q delete firewall.@ipset[$ipset_id]; do :; done fi rule_id=$(uci show firewall | grep -E '@rule.*name=.mark_subnet.' | awk -F '[][{}]' '{print $2}' | head -n 1) if [ ! -z "$rule_id" ]; then while uci -q delete firewall.@rule[$rule_id]; do :; done fi uci commit firewall /etc/init.d/firewall restart echo "Чистим сеть" sed -i '/99 vpn/d' /etc/iproute2/rt_tables rule_id=$(uci show network | grep -E '@rule.*name=.mark0x1.' | awk -F '[][{}]' '{print $2}' | head -n 1) if [ ! -z "$rule_id" ]; then while uci -q delete network.@rule[$rule_id]; do :; done fi rule_id=$(uci show network | grep -E '@rule.*name=.mark0x2.' | awk -F '[][{}]' '{print $2}' | head -n 1) if [ ! -z "$rule_id" ]; then while uci -q delete network.@rule[$rule_id]; do :; done fi while uci -q delete network.vpn_route_internal; do :; done uci commit network /etc/init.d/network restart echo "Проверяем Dnsmasq" if uci show dhcp | grep -q ipset; then echo "В dnsmasq (/etc/config/dhcp) заданы домены. Нужные из них сохраните, остальные удалите вместе с ipset" fi echo "Все туннели, прокси, зоны и forwarding к ним оставляем на месте, они вам не помешают и скорее пригодятся" echo "Dnscrypt, stubby тоже не трогаем" echo " ______ _____ _____ _____ ______ _ _ _____ _____" echo " | ____ | | |_____] | | | \ |____/ | | |_____]" echo " |_____| |_____| | |_____| |_____/ | \_ |_____| | " ================================================ FILE: handlers/main.yml ================================================ --- - name: Restart sing-box service: name: sing-box state: restarted - name: Restart network service: name: network state: restarted - name: Restart firewall service: name: firewall state: restarted - name: Run getdomains script service: name: getdomains state: restarted - name: Restart dnscrypt-proxy service: name: dnscrypt-proxy state: restarted enabled: yes - name: Restart dnsmasq service: name: dnsmasq state: restarted ================================================ FILE: meta/main.yml ================================================ --- galaxy_info: role_name: domain_routing_openwrt namespace: itdoginfo author: itdog description: Configuring domain routing on Openwrt router issue_tracker_url: https://github.com/itdoginfo/domain-routing-openwrt/issues license: GPL-3.0 min_ansible_version: 2.10.7 platforms: - name: OpenWrt galaxy_tags: - openwrt - dnsmasq - ipset - wireguard - sing-box - openvpn - bypass - routing dependencies: - role: gekmihesg.openwrt ================================================ FILE: tasks/main.yml ================================================ --- # Dnsmasq version check - name: Get dnsmasq version shell: opkg list-installed | grep dnsmasq-full | awk '{print $3}' register: dnsmasqfull_version - name: Check confdir option shell: uci get dhcp.@dnsmasq[0].confdir register: dnsmasq_confdir ignore_errors: true - name: Get openwrt major release shell: cat /etc/openwrt_release | grep -Eo [0-9]{2}[.][0-9]{2}[.][0-9]* | cut -d '.' -f 1 | tail -n 1 register: openwrt_major_release - name: debug debug: var: ansible_distribution_major_version # Packages installation - name: install wg opkg: name: "{{ item }}" state: present loop: - kmod-wireguard - wireguard-tools when: tunnel == "wg" - name: install openvpn opkg: name: "{{ item }}" state: present loop: - openvpn-openssl when: tunnel == "openvpn" - name: install singbox opkg: name: "{{ item }}" state: present loop: - sing-box when: tunnel == "singbox" and ansible_distribution_major_version >= "23" - name: install curl opkg: name: "{{ item }}" state: present loop: - curl - name: install nano opkg: name: "{{ item }}" state: present loop: - nano when: nano - name: install ipset opkg: name: ipset state: present when: ansible_distribution_major_version < "22" - name: install dnsmasq-full (23) shell: opkg update && cd /tmp/ && opkg download dnsmasq-full && opkg remove dnsmasq && opkg install dnsmasq-full --cache /tmp/ && [ -f /etc/config/dhcp-opkg ] && cp etc/config/dhcp /etc/config/dhcp-old && mv /etc/config/dhcp-opkg /etc/config/dhcp when: ansible_distribution_major_version >= "23" and list_domains and not dnsmasqfull_version.stdout ignore_errors: true - name: set confdir for dnsmasq uci: command: set key: dhcp.@dnsmasq[0] value: confdir: "/tmp/dnsmasq.d" when: ansible_distribution_major_version >= 24 notify: - Restart dnsmasq # Getdomains script configure - name: getdomains script copy template: src: "openwrt-getdomains.j2" dest: "/etc/init.d/getdomains" mode: a+x trim_blocks: false notify: - Run getdomains script - name: create simplink in rc.d file: src: "/etc/init.d/getdomains" dest: "/etc/rc.d/S99getdomains" state: link notify: - Run getdomains script - name: check string in crontab shell: grep "getdomains" /etc/crontabs/root register: check_cron ignore_errors: true - name: add script to cron lineinfile: path: /etc/crontabs/root create: yes line: "0 4 * * * /etc/init.d/getdomains start" when: check_cron.stdout == "" - name: enable and start crontab service: name: cron state: started enabled: yes # Configure route table - name: Route for vpn table template: src: "openwrt-30-vpnroute.j2" dest: "/etc/hotplug.d/iface/30-vpnroute" mode: 0644 - name: Check string in rt_tables shell: grep "99 vpn" /etc/iproute2/rt_tables register: check_rt_tables ignore_errors: true - name: add route table lineinfile: path: /etc/iproute2/rt_tables line: "99 vpn" when: check_rt_tables.stdout == "" notify: - Restart network # Configure WG - name: add wg interface uci: command: add config: network type: interface name: wg0 when: tunnel == "wg" - name: configure wg interface uci: command: set key: network.wg0 value: proto: wireguard private_key: "{{ wg_private_key }}" listen_port: "{{ wg_listen_port }}" addresses: - "{{ wg_client_address }}" when: tunnel == "wg" notify: - Restart network - name: set wg client without wg_preshared_key uci: command: section config: network type: wireguard_wg0 find_by: name: wg0_client value: public_key: "{{ wg_public_key }}" route_allowed_ips: 0 persistent_keepalive: 25 endpoint_host: "{{ wg_server_address }}" allowed_ips: 0.0.0.0/0 endpoint_port: "{{ wg_client_port }}" when: wg_preshared_key is undefined and tunnel == "wg" notify: - Restart network - name: set wg client with wg_preshared_key uci: command: section config: network type: wireguard_wg0 find_by: name: wg0_client value: public_key: "{{ wg_public_key }}" preshared_key: "{{ wg_preshared_key }}" route_allowed_ips: 0 persistent_keepalive: 25 endpoint_host: "{{ wg_server_address }}" allowed_ips: 0.0.0.0/0 endpoint_port: "{{ wg_client_port }}" when: wg_preshared_key is defined and tunnel == "wg" - name: set WG firewall zone uci: command: section config: firewall type: zone find_by: name: wg value: forward: REJECT output: ACCEPT name: wg input: REJECT masq: 1 mtu_fix: 1 network: wg0 family: ipv4 when: tunnel == "wg" - name: add WG forwarding uci: command: section config: firewall type: forwarding find_by: name: wg-lan value: dest: wg src: lan family: ipv4 when: tunnel == "wg" # Configure Sing-box - name: set sing-box firewall zone. Only >=22 uci: command: section config: firewall type: zone find_by: name: tun value: forward: ACCEPT output: ACCEPT name: tun input: ACCEPT masq: 1 mtu_fix: 1 device: tun0 family: ipv4 when: tunnel == "singbox" failed_when: ansible_distribution_major_version < "22" notify: - Restart firewall - name: template for sing-box.json template: src: "sing-box-json.j2" dest: "/etc/sing-box/config.json" mode: 0644 when: tunnel == "singbox" failed_when: ansible_distribution_major_version < "22" - name: template for config/sing-box template: src: "config-sing-box.j2" dest: "/etc/config/sing-box" mode: 0600 when: tunnel == "singbox" failed_when: ansible_distribution_major_version < "22" # Configure OpenVPN, tun2socks - name: set {{ tunnel }} firewall zone uci: command: section config: firewall type: zone find_by: name: tun value: forward: REJECT output: ACCEPT name: tun input: REJECT masq: 1 mtu_fix: 1 device: tun0 family: ipv4 when: tunnel == "openvpn" or tunnel == "tun2socks" notify: - Restart firewall - name: add {{ tunnel }} forwarding uci: command: section config: firewall type: forwarding find_by: name: lan-tun value: dest: tun src: lan family: ipv4 when: tunnel == "openvpn" or tunnel == "tun2socks" or tunnel == "singbox" notify: - Restart firewall # Configure network - name: set rule mark0x1 uci: command: section config: network type: rule find_by: name: mark0x1 value: mark: "0x1" priority: 100 lookup: vpn - name: set disable dns for wan uci: command: set key: network.wan value: peerdns: 0 when: ansible_distribution_major_version < "22" - name: uci commit firewall uci: command: commit config: firewall notify: - Restart firewall - name: uci commit network uci: command: commit config: network notify: - Restart network # Configure firewall - name: add ipset for subnet (<22) uci: command: section config: firewall type: ipset find_by: name: vpn_subnets value: match: dst_net storage: hash loadfile: /tmp/lst/subnet.lst when: ansible_distribution_major_version < "22" and list_subnet - name: add ipset for ip (<22) uci: command: section config: firewall type: ipset find_by: name: vpn_ip value: match: dst_net storage: hash loadfile: /tmp/lst/ip.lst hashsize: 9900000 maxelem: 9900000 when: ansible_distribution_major_version < "22" and list_ip - name: add ipset for community (<22) uci: command: section config: firewall type: ipset find_by: name: vpn_community value: match: dst_net storage: hash loadfile: /tmp/lst/community.lst hashsize: 9900000 maxelem: 9900000 when: ansible_distribution_major_version < "22" and list_community - name: add nfset for subnet (22) uci: command: section config: firewall type: ipset find_by: name: vpn_subnets value: match: dst_net loadfile: /tmp/lst/subnet.lst when: ansible_distribution_major_version >= "22" and list_subnet - name: add nfset for ip (22) uci: command: section config: firewall type: ipset find_by: name: vpn_ip value: match: dst_net loadfile: /tmp/lst/ip.lst when: ansible_distribution_major_version >= "22" and list_ip - name: add nfset for community (22) uci: command: section config: firewall type: ipset find_by: name: vpn_community value: match: dst_net loadfile: /tmp/lst/community.lst when: ansible_distribution_major_version >= "22" and list_community - name: add ipset for domains (<22). If failed, repeat playbook. If failed is repeated check dnsmasq-full. uci: command: section config: firewall type: ipset find_by: name: vpn_domains value: match: dst_net storage: hash when: ansible_distribution_major_version < "22" and list_domains - name: add nfset for domains (>=22). If failed, repeat playbook. If failed is repeated check dnsmasq-full. uci: command: section config: firewall type: ipset find_by: name: vpn_domains value: match: dst_net when: ansible_distribution_major_version >= "22" and list_domains - name: add mark rule vpn_subnet uci: command: section config: firewall type: rule find_by: name: mark_subnet value: src: lan dest: "*" proto: all ipset: vpn_subnets set_mark: "0x1" target: MARK family: ipv4 when: list_subnet - name: add mark rule vpn_ip uci: command: section config: firewall type: rule find_by: name: mark_ip value: src: lan dest: "*" proto: all ipset: vpn_ip set_mark: "0x1" target: MARK family: ipv4 when: list_ip - name: add mark rule vpn_community uci: command: section config: firewall type: rule find_by: name: mark_community value: src: lan dest: "*" proto: all ipset: vpn_community set_mark: "0x1" target: MARK family: ipv4 when: list_community - name: add mark rule vpn_domains uci: command: section config: firewall type: rule find_by: name: mark_domains value: src: lan dest: "*" proto: all ipset: vpn_domains set_mark: "0x1" target: MARK family: ipv4 when: (ansible_distribution_major_version < "22" and list_domains) or (ansible_distribution_major_version >= "22" and list_domains) - name: wg access route uci: command: section config: network type: route find_by: name: wg_access_route value: interface: wg0 target: "{{ wg_access_network }}" when: wg_access - name: set WG firewall zone uci: command: section config: firewall type: zone find_by: name: wg value: input: ACCEPT when: wg_access # Remove unused rules and ipset - name: Remove ipset for ip uci: command: absent config: firewall type: ipset find_by: name: vpn_ip when: not list_ip - name: Remove rule for ip uci: command: absent config: firewall type: rule find_by: name: mark_ip when: not list_ip - name: Remove ipset for subnet uci: command: absent config: firewall type: ipset find_by: name: vpn_subnets when: not list_subnet - name: Remove rule for subnet uci: command: absent config: firewall type: rule find_by: name: mark_subnet when: not list_subnet - name: Remove ipset for community uci: command: absent config: firewall type: ipset find_by: name: vpn_community when: not list_community - name: Remove rule for community uci: command: absent config: firewall type: rule find_by: name: mark_community when: not list_community - name: Remove ipset for domains uci: command: absent config: firewall type: ipset find_by: name: vpn_domains when: not list_domains - name: Remove rule for domains uci: command: absent config: firewall type: rule find_by: name: mark_domains when: not list_domains # Configure DNS resolver - name: install dnscrypt-proxy2 opkg: name: dnscrypt-proxy2 state: present when: dns_encrypt == "dnscrypt" - name: check string in dnscrypt-proxy.toml shell: grep "# server_names" /etc/dnscrypt-proxy2/dnscrypt-proxy.toml register: check_server_names ignore_errors: true when: dns_encrypt == "dnscrypt" - name: dnscrypt2 enable exact servers lineinfile: path: /etc/dnscrypt-proxy2/dnscrypt-proxy.toml regexp: "# server_names =" line: "server_names = ['google', 'cloudflare', 'scaleway-fr', 'yandex']" when: dns_encrypt == "dnscrypt" and check_server_names.stdout notify: - Restart dnscrypt-proxy - name: edit dhcp config. add localhost server lineinfile: path: /etc/config/dhcp firstmatch: "true" insertafter: "option leasefile '/tmp/dhcp.leases'" line: "{{ item }}" with_items: - " list server '127.0.0.53#53'" - " option noresolv '1'" notify: - Restart dnsmasq when: dns_encrypt == "dnscrypt" - name: install stubby opkg: name: stubby state: present when: dns_encrypt == "stubby" - name: edit dhcp config. add localhost server lineinfile: path: /etc/config/dhcp firstmatch: "true" insertafter: "option leasefile '/tmp/dhcp.leases'" line: "{{ item }}" with_items: - " list server '127.0.0.1#5453'" - " option noresolv '1'" notify: - Restart dnsmasq when: dns_encrypt == "stubby" # Commit - name: uci commit firewall uci: command: commit config: firewall notify: - Restart firewall - name: uci commit dhcp uci: command: commit config: dhcp notify: - Restart dnsmasq - name: uci commit network uci: command: commit config: network notify: - Restart network ================================================ FILE: templates/config-sing-box.j2 ================================================ config sing-box 'main' option enabled '1' option user 'root' option conffile '/etc/sing-box/config.json' option workdir '/usr/share/sing-box' ================================================ FILE: templates/openwrt-30-vpnroute.j2 ================================================ #!/bin/sh {% if tunnel == "wg" %} ip route add table vpn default dev wg0 {% elif (tunnel == "openvpn") or (tunnel == "singbox") or (tunnel == "tun2socks") %} sleep 10 ip route add table vpn default dev tun0 {% endif %} ================================================ FILE: templates/openwrt-getdomains.j2 ================================================ #!/bin/sh /etc/rc.common START=99 start () { {% if ansible_distribution_major_version >= "22" and country == "russia-inside" %} DOMAINS=https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Russia/inside-dnsmasq-nfset.lst {% endif %} {% if ansible_distribution_major_version >= "22" and country == "russia-outside" %} DOMAINS=https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Russia/outside-dnsmasq-nfset.lst {% endif %} {% if ansible_distribution_major_version >= "22" and country == "ukraine" %} DOMAINS=https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Ukraine/inside-dnsmasq-nfset.lst {% endif %} {% if ansible_distribution_major_version < "22" and country == "russia-inside" %} DOMAINS=https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Russia/inside-dnsmasq-ipset.lst {% endif %} {% if ansible_distribution_major_version < "22" and country == "russia-outside" %} DOMAINS=https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Russia/outside-dnsmasq-ipset.lst {% endif %} {% if ansible_distribution_major_version < "22" and country == "ukraine" %} DOMAINS=https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Ukraine/inside-dnsmasq-ipset.lst {% endif %} count=0 while true; do if curl -m 3 github.com; then curl -f $DOMAINS --output /tmp/dnsmasq.d/domains.lst break else echo "GitHub is not available. Check the internet availability [$count]" count=$((count+1)) fi done if dnsmasq --conf-file=/tmp/dnsmasq.d/domains.lst --test 2>&1 | grep -q "syntax check OK"; then /etc/init.d/dnsmasq restart fi {% if ansible_distribution_major_version >= "22" and (list_ip or list_community) %} echo "Flush sets" nft flush ruleset {% endif %} {% if list_subnet or list_ip or list_community %} dir=/tmp/lst mkdir -p $dir count=0 while true; do if curl -m 3 https://antifilter.download/; then {% if list_subnet %} curl -f -z $dir/subnet.lst https://antifilter.download/list/subnet.lst --output $dir/subnet.lst {% endif %} {% if list_ip %} curl -f -z $dir/ip.lst https://antifilter.download/list/ip.lst --output $dir/ip.lst {% endif %} {% if list_community %} curl -f -z $dir/community.lst https://community.antifilter.download/list/community.lst --output $dir/community.lst {% endif %} break else echo "antifilter.download is not available. Check the internet availability [$count]" count=$((count+1)) fi done echo "Firewall restart" /etc/init.d/firewall restart {% endif %} } ================================================ FILE: templates/sing-box-json.j2 ================================================ { "log": { "level": "debug" }, "inbounds": [ { "type": "tun", "interface_name": "tun0", "domain_strategy": "ipv4_only", "address": ["172.16.250.1/30"], "auto_route": false, "strict_route": false, "sniff": true } ], "outbounds": [ { "type": "$TYPE", "server": "$HOST", "server_port": $PORT, "method": "$METHOD", "password": "$PASS" } ], "route": { "auto_detect_interface": true } } ================================================ FILE: tests/inventory ================================================ [openwrt] 192.168.56.23 ================================================ FILE: tests/test.yml ================================================ --- - hosts: openwrt remote_user: root roles: - domain_routing_openwrt