entware
opkg install mc htop curl
cd ~;mkdir awg2-go;cd awg2-go
wget http://zyxnerd.zyxmon.org/files/awg2/amneziawg-go_v0.2.16-1_aarch64-3.10.ipk wget http://zyxnerd.zyxmon.org/files/awg2/amneziawg-tools_1.0.20250903-2_aarch64-3.10.ipk
opkg install /opt/root/awg2-go/amneziawg-tools*.ipk && opkg install /opt/root/awg2-go/amneziawg-go*.ipk
- Изменяем и загружаем conf-файл на роутер
На этапе подготовки был сделан файл awg0.conf с вписанными в него параметрами i1…i5. Для корректной работы с интерфейсом OpkgTun данный файл надо немного подправить, так же переименуем его в awg0-opkgtun0.conf, что бы не запутаться в файлах. В файле awg0-opkgtun0.conf обязательно удалить строчки Address и DNS или закомментировать их как на скриншоте ниже:
Теперь файл awg0-opkgtun0.conf требуется загрузить в роутер по пути /opt/etc/amnezia/amneziawg/ или же через общую сетевую папку:
- Добавляем интерфейс OpkgTun в роутер
! ВНИМАНИЕ ! команды ниже выполнять СТРОГО из под обычного логина ssh! НЕ через exec sh, иначе получите ошибку ndmc: system failed [0xcffd0060]
Есть два пути, хотя смысл у них один - добавление интерфейса через cli роутера. В данной статье будем добавлять через ssh-консоль. Для этого нужно последовательно выполнить команды ниже.
Создание самого интерфейса OpkgTun0:
ndmc -c interface OpkgTun0
Задаём описание, т.е. как интерфейс OpkgTun0 будет называться в веб-морде роутера, в данном случае это AWG-Go:
ndmc -c interface OpkgTun0 description AWG-Go
Вы можете придумать название самостоятельно. Команда для отображения, статуса, подсчёта трафика интерфейса OpkgTun0:
ndmc -c interface OpkgTun0 ip global auto
Назначаем IP-адрес и маску подсети интерфейсу OpkgTun0:
ndmc -c interface OpkgTun0 ip address 10.8.1.6 255.255.255.255
IP-адрес обязательно должен быть такой же, как и в поле\textcolor{ORANGE}{\text{IP-адрес обязательно должен быть такой же, как и в поле}}IP-адрес обязательно должен быть такой же, как и в поле Address в файле\textcolor{ORANGE}{\text{в файле}}в файле awg0-opkgtun0.conf! Устанавливаем MTU для интерфейса OpkgTun0:
ndmc -c interface OpkgTun0 ip mtu 1376
Что такое MTU и как его правильно вычислить в Вашем конкретном случае - ищите в сети. Что такое MTU и как его правильно вычислить в Вашем конкретном случае - ищите в сети.}}Что такое MTU и как его правильно вычислить в Вашем конкретном случае - ищите в сети. В моём случае подходит значение 1376. Если не уверены - Вы можете использовать значение 1280, как то, которое с вероятностью 99% Вам подойдёт.
Настройка, которая корректирует максимальный размер сегмента TCP, чтобы он соответствовал PMTU, то есть минимальному MTU на всём пути следования пакета до получателя, автоматически подстраивая его:
ndmc -c interface OpkgTun0 ip tcp adjust-mss pmtu
Поднимаем сам интерфейс OpkgTun0:
ndmc -c interface OpkgTun0 up
Добавляем правило маршрутизации для работы интерфейса OpkgTun0 в политиках доступа:
ndmc -c ip route default OpkgTun0
Сохраняем настройки системы:
ndmc -c system configuration save
Скрипты запуска
Для работы AWG-Go с интерфейсом OpkgTun0 требуется добавить в роутер другой скрипт запуска S52awg-opkgtun0. Скачать скрипт в папку запуска можно вводом команды:
cd /opt/etc/init.d/ && curl -OLf "https://gitlab.com/ShidlaSGC/keenetic-entware-awg-go/-/raw/main/blob/02__KeenOS_5.0_(OpkgTun)/S52awg-opkgtun0" && chmod +x S52awg-opkgtun0
Так же если требуется отключить автозапуск /opt/etc/init.d/S89amnezia-wg-quick- нужно переименовать S89amnezia-wg-quick в K89amnezia-wg-quick. Это можно сделать или через общую сетевую папку или через команду:
mv /opt/etc/init.d/S89amnezia-wg-quick /opt/etc/init.d/K89amnezia-wg-quick
/opt/etc/init.d/S52awg-opkgtun0 start
S52awg-opkgtun0
#!/bin/sh ENABLED=yes PROCS="amneziawg-go" PATH="/opt/sbin:/opt/bin:/opt/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" DESC="AmneziaWG OpkgTun" PROGRAM="${0##*/}" AWG_BIN="/opt/bin/awg" VER="v2025-12-26 Fin" KEENOS_VER_MAJOR=$(ndmc -c "show version" | grep -o 'title: [0-9]' | cut -d' ' -f2) KEENOS_VER=$(ndmc -c "show version" | grep -oE 'title: [0-9.]+' | cut -d' ' -f2) # ================== НАСТРОЙКИ ДЛЯ ПОЛЬЗОВАТЕЛЕЙ ================== # Интерфейс OpkgTun OPKGTUN_INTERFACE="opkgtun0" # Размер MTU, применяемый к интерфейсу OpkgTun OPKGTUN_MTU="1376" # Файл конфигурации AWG AWG_CONF="/opt/etc/amnezia/amneziawg/awg0-opkgtun0.conf" # Сервер:порт для проверки скорости через iperf3. SPEEDTEST_SRV_ADDRESSES=" it1.speedtest.aruba.it:5201 mskst.st.mtsws.net:3333 " # Время в секундах на тестирование скорости в каждую сторону SPEEDTEST_TIME="5" # ================================================================= cmd_start() { [ "$ENABLED" != "yes" ] && die "⚠️ Service is disabled in script (ENABLED=no)." check_binary_files [ -f "$AWG_CONF" ] || die "⚠️ AWG config-file \e[3m $AWG_CONF \e[0m does not exist!" if pgrep -f "/opt/bin/$PROCS $OPKGTUN_INTERFACE" > /dev/null; then log "ℹ️ AmneziaWG for \e[3m$OPKGTUN_INTERFACE\e[0m already running!" log "ℹ️ Use \"\e[3m$PROGRAM restart\e[0m\" if you need restart this interface." && echo "" && return 0 fi log "ℹ️ Starting AmneziaWG \e[3m$OPKGTUN_INTERFACE\e[0m interface..." logger -t "[Entware AWG-Go][Info]" "Starting AWG for \"$OPKGTUN_INTERFACE\" interface..." "/opt/bin/$PROCS" "$OPKGTUN_INTERFACE" >/dev/null 2>&1 & local retries=10 while [ ! -d "/sys/class/net/$OPKGTUN_INTERFACE" ] && [ $retries -gt 0 ]; do sleep 1 && retries=$((retries - 1)) done sleep 2 if [ -d "/sys/class/net/$OPKGTUN_INTERFACE" ]; then if ip link set dev "$OPKGTUN_INTERFACE" up; then if ("$AWG_BIN" setconf "$OPKGTUN_INTERFACE" "$AWG_CONF") ; then if ip link set dev "$OPKGTUN_INTERFACE" mtu "$OPKGTUN_MTU" 2>/dev/null; then logger -t "[Entware AWG-Go][Info]" "MTU \"$OPKGTUN_MTU\" successfully set on \"$OPKGTUN_INTERFACE\"" else logger -t "[Entware AWG-Go][Err]" "Failed to set MTU \"$OPKGTUN_MTU\" on \"$OPKGTUN_INTERFACE\"" fi logger -t "[Entware AWG-Go][Info]" "Successfully configured \"$OPKGTUN_INTERFACE\" with \"$AWG_CONF\"" log "✅ Successfully configured AWG-opkgtun: \e[3m$OPKGTUN_INTERFACE\e[0m | MTU \e[3m$OPKGTUN_MTU\e[0m" sleep 2 && echo ""&& cmd_status else sleep 2 && cmd_stop logger -t "[Entware AWG-Go][Err]" "Failed to apply config \"$AWG_CONF\" to \"$OPKGTUN_INTERFACE\"!" die "❌ Failed to apply config \e[3m$AWG_CONF\e[0m to \e[3m$OPKGTUN_INTERFACE\e[0m." fi else cmd_stop logger -t "[Entware AWG-Go][Err]" "Failed to UP network interface \"$OPKGTUN_INTERFACE\"!" die "❌ Failed to UP network interface \e[3m$OPKGTUN_INTERFACE\e[0m." fi else logger -t "[Entware AWG-Go][Err]" "Interface \"$OPKGTUN_INTERFACE\" did not appear after start!" die "❌ Interface \e[3m$OPKGTUN_INTERFACE\e[0m did not appear after start." fi } cmd_stop() { check_binary_files local AWG_PID=$(pgrep -f "/opt/bin/$PROCS $OPKGTUN_INTERFACE") if [ -n "$AWG_PID" ]; then logger -t "[Entware AWG-Go][Info]" "Stopping AWG for \"$OPKGTUN_INTERFACE\" with \"$AWG_CONF\"..." log "ℹ️ Stopping AmneziaWG for \e[3m$OPKGTUN_INTERFACE\e[0m (PID: $AWG_PID)..." kill "$AWG_PID" > /dev/null 2>&1 local timeout=5 while pgrep -f "/opt/bin/$PROCS $OPKGTUN_INTERFACE" > /dev/null && [ $timeout -gt 0 ]; do sleep 1 && timeout=$((timeout - 1)) done if pgrep -f "/opt/bin/$PROCS $OPKGTUN_INTERFACE" > /dev/null; then logger -t "[Entware AWG-Go][Warn]" "Process did not respond, forcing termination AWG for \"$OPKGTUN_INTERFACE\"..." log "⚠️ Process did not respond, forcing termination... ⚠️" kill -9 "$AWG_PID" > /dev/null 2>&1 fi if [ -d "/sys/class/net/$OPKGTUN_INTERFACE" ]; then ip link set dev "$OPKGTUN_INTERFACE" down fi logger -t "[Entware AWG-Go][Info]" "AWG for \"$OPKGTUN_INTERFACE\" with \"$AWG_CONF\" stopped successfully." log "✅ AmneziaWG for \e[3m$OPKGTUN_INTERFACE\e[0m stopped successfully." && echo "" else log "ℹ️ AmneziaWG for \e[3m$OPKGTUN_INTERFACE\e[0m is NOT running." && echo "" fi } cmd_status() { check_binary_files check_package_installed "curl" "^curl" echo -e "==================== INTERFACE \e[3m$OPKGTUN_INTERFACE\e[0m STATUS ====================" if [ ! -d "/sys/class/net/$OPKGTUN_INTERFACE" ]; then die "❌ Interface \e[3m$OPKGTUN_INTERFACE\e[0m does NOT exist!" else # ip -c -br link show dev "$OPKGTUN_INTERFACE" INTERFACE_INFO=$(ip addr show $OPKGTUN_INTERFACE 2>/dev/null) if [ -z "$INTERFACE_INFO" ]; then die "❌ Interface \e[3m$OPKGTUN_INTERFACE\e[0m does NOT exist!" && exit 1 fi INTERFACE_IP=$(echo "$INTERFACE_INFO" | grep -oE 'inet [0-9.]+' | cut -d' ' -f2) [ -z "$INTERFACE_IP" ] && INTERFACE_IP="❌ Not assigned" RAW_STATE=$(echo "$INTERFACE_INFO" | grep -oE 'state [A-Z]+' | cut -d' ' -f2) case "$RAW_STATE" in UP) INTERFACE_STATE="\033[1;32mUP\033[0m" ;; DOWN) INTERFACE_STATE="\033[1;31mDOWN\033[0m" ;; *) INTERFACE_STATE="\033[1;33mUNKNOWN\033[0m" ;; esac INTERFACE_MTU=$(echo "$INTERFACE_INFO" | grep -oE 'mtu [0-9]+' | cut -d' ' -f2) log "IP: \e[3m$INTERFACE_IP\e[0m | State: \e[3m$INTERFACE_STATE\e[0m | MTU: \e[3m$INTERFACE_MTU\e[0m" if pgrep -f "/opt/bin/$PROCS $OPKGTUN_INTERFACE" > /dev/null; then logger -t "[Entware AWG-Go][Info]" "AWG-Go for \"$OPKGTUN_INTERFACE\" with \"$AWG_CONF\" running" log "✅ AWG-Go for \e[3m$OPKGTUN_INTERFACE\e[0m running" local RAW_LASTHANDSHAKE=$("$AWG_BIN" show "$OPKGTUN_INTERFACE" latest-handshakes 2>/dev/null) LASTHANDSHAKE=$(echo "$RAW_LASTHANDSHAKE" | awk '{print $2}' 2>/dev/null) if [ -n "$LASTHANDSHAKE" ] && [ "$LASTHANDSHAKE" -ne 0 ] 2>/dev/null; then logger -t "[Entware AWG-Go][Info]" "\"$OPKGTUN_INTERFACE\" with \"$AWG_CONF\" Last Handshake: $(date -d "@$LASTHANDSHAKE" '+%Y-%m-%d %H:%M:%S')" log "ℹ️ Last Handshake: $(date -d "@$LASTHANDSHAKE" '+%Y-%m-%d %H:%M:%S')" else logger -t "[Entware AWG-Go][Warn]" "\"$OPKGTUN_INTERFACE\" with \"$AWG_CONF\" Last Handshake: NONE (No connection)" log "⚠️ Last Handshake: ❌ \e[31mNONE\e[0m (No connection)" fi echo "-------------------------------------------------------------------" log "ℹ️ Testing external IP via \e[3m$OPKGTUN_INTERFACE\e[0m..." local VPS_IP=$(curl --interface "$OPKGTUN_INTERFACE" -s --max-time 3 ifconfig.me 2>/dev/null) if [ -n "$VPS_IP" ]; then logger -t "[Entware AWG-Go][Info]" "External IP via \"$OPKGTUN_INTERFACE\": $VPS_IP" log "✅ External IP via \e[3m$OPKGTUN_INTERFACE\e[0m: \e[33m$VPS_IP\e[0m" else logger -t "[Entware AWG-Go][Warn]" "Failed to obtain external IP via \"$OPKGTUN_INTERFACE\"" log "❌ \e[31mFailed to obtain external IP\e[0m via \e[3m$OPKGTUN_INTERFACE\e[0m" fi else log "ℹ️ AmneziaWG for \e[3m$OPKGTUN_INTERFACE\e[0m NOT running!" fi fi echo "===================================================================" echo -e " \e[3;1;34m $VER \e[0m" && echo "" } select_speedtest_server() { for srv in $SPEEDTEST_SRV_ADDRESSES; do SPEEDTEST_SRV_ADDR=${srv%%:*} SPEEDTEST_SRV_PORT=${srv##*:} log "ℹ️ Checking SpeedTest server \e[3m$SPEEDTEST_SRV_ADDR:$SPEEDTEST_SRV_PORT\e[0m" if curl --interface "$OPKGTUN_INTERFACE" -s --head \ --connect-timeout 5 \ "http://$SPEEDTEST_SRV_ADDR" >/dev/null 2>&1; then log "✅ Selected SpeedTest server \e[3m$SPEEDTEST_SRV_ADDR:$SPEEDTEST_SRV_PORT\e[0m is accessible via \e[3m$OPKGTUN_INTERFACE\e[0m" return 0 fi done return 1 } cmd_speedtest () { check_binary_files check_package_installed "curl" "^curl" check_package_installed "iperf3" "^iperf3 -" echo -e "==================== INTERFACE \e[3m$OPKGTUN_INTERFACE\e[0m SPEEDTEST ====================" if [ ! -d "/sys/class/net/$OPKGTUN_INTERFACE" ]; then echo -e "❌ Interface \e[3m$OPKGTUN_INTERFACE\e[0m does NOT exist!" echo "======================================================================" && echo "" && return 1 fi if ! pgrep -f "/opt/bin/$PROCS $OPKGTUN_INTERFACE" >/dev/null; then log "⚠️ AmneziaWG for \e[3m$OPKGTUN_INTERFACE\e[0m NOT running!" log "ℹ️ Can't run SpeedTest." echo "======================================================================" && echo "" && return 1 fi logger -t "[Entware AWG-Go][Info]" \ "AWG-Go for \"$OPKGTUN_INTERFACE\" with \"$AWG_CONF\" running, begin SpeedTest..." log "✅ AWG-Go for \e[3m$OPKGTUN_INTERFACE\e[0m running, begin SpeedTest..." OPKGTUN_IP=$(ip -4 -br addr show "$OPKGTUN_INTERFACE" | awk '{print $3}' | cut -d'/' -f1 2>/dev/null) if [ -z "$OPKGTUN_IP" ]; then logger -t "[Entware AWG-Go][Err]" \ "Can't obtain \"$OPKGTUN_INTERFACE\" IPv4 address. Stopping SpeedTest." log "❌ \e[31mCan't obtain\e[0m \e[3m$OPKGTUN_INTERFACE\e[0m IPv4 address. Stopping SpeedTest." echo "======================================================================" && echo "" && return 1 fi if ! select_speedtest_server; then die "❌ No available SpeedTest servers via \e[3m$OPKGTUN_INTERFACE\e[0m" fi echo "----------------------------------------------------------------------" run_speedtest "↓↓ Download" "-R" "$OPKGTUN_IP" log "----------------------------------------" run_speedtest "↑↑ Upload" "" "$OPKGTUN_IP" echo "======================================================================" && echo "" } log() { echo -e "[$(date +'%Y-%m-%d %H:%M:%S')] $1" } die() { log "ERROR: $*" >&2 echo -e " \e[3;1;34m $VER \e[0m" && echo "" echo "" && exit 1 } run_speedtest() { local mode=$1 local extra_args=$2 local interface_ip=$3 for srv in $SPEEDTEST_SRV_ADDRESSES; do SPEEDTEST_SRV_ADDR=${srv%%:*} SPEEDTEST_SRV_PORT=${srv##*:} log "$mode: Trying server \e[3m$SPEEDTEST_SRV_ADDR:$SPEEDTEST_SRV_PORT\e[0m (\e[1;3;31mtest time: $SPEEDTEST_TIME sec.\e[0m)" OUTPUT=$(iperf3 -c "$SPEEDTEST_SRV_ADDR" \ -p "$SPEEDTEST_SRV_PORT" \ -B "$interface_ip" \ $extra_args \ -t $SPEEDTEST_TIME \ --connect-timeout 3000 \ --json 2>&1) if echo "$OUTPUT" | grep -q '"error"'; then log "$mode: Server \e[3m$SPEEDTEST_SRV_ADDR:$SPEEDTEST_SRV_PORT\e[0m connection error." echo "----------------------------------------------------------------------" continue fi BYTES=$(echo "$OUTPUT" | grep -A 10 '"sum_received"' | grep '"bytes"' | awk -F: '{print $2}' | tr -d ' ,') BITS=$(echo "$OUTPUT" | grep -A 10 '"sum_received"' | grep '"bits_per_second"' | awk -F: '{print $2}' | tr -d ' ,') MB=$(awk "BEGIN {printf \"%.2f\", $BYTES / 1048576}") MBIT=$(awk "BEGIN {printf \"%.2f\", $BITS / 1000000}") log "$mode Speed: \e[3m$MBIT Mbit/s\e[0m" log "$mode'ed: \e[3m$MB MBytes\e[0m" return 0 done log "$mode: ❌ Failed to check SpeedTest via specified servers" && return 1 } check_package_installed () { local package_name=$1 local package_name2find=$2 if !(opkg list-installed | grep -q "$package_name2find"); then logger -t "[Entware AWG-Go][Info]" "Package \"$package_name\" not founded. Installing..." log "⚠️ Package \e[3m$package_name\e[0m not founded. Installing..." (opkg update && opkg install $package_name) >/dev/null if [ $? -eq 0 ]; then logger -t "[Entware AWG-Go][Info]" "Package \"$package_name\" installed successful." log "ℹ️ Package \e[3m$package_name\e[0m installed successful." && echo "" else logger -t "[Entware AWG-Go][Err]" "Package \"$package_name\" installation ERROR!" die "❌ Package \e[3m$package_name\e[0m installation ERROR!." fi fi } check_binary_files () { [ -x "/opt/bin/$PROCS" ] || die "⚠️ Application \e[3m /opt/bin/$PROCS \e[0m not found or not executable." [ -x "$AWG_BIN" ] || die "⚠️ Application \e[3m $AWG_BIN \e[0m not found or not executable." [ "$KEENOS_VER_MAJOR" -lt 5 ] && die "❌ Your KeenOS is \e[3m$KEENOS_VER\e[0m. Version 5.0.2 or higher is required." } case "$1" in start) cmd_start ;; stop) cmd_stop ;; restart) cmd_stop; sleep 1; cmd_start ;; status) cmd_status ;; speedtest) cmd_speedtest ;; *) echo "Usage: $0 {start|stop|restart|status|speedtest}"; exit 1 ;; esac
