From 19495ca05a6ec9cdffdb06ac9773fe81c6ee4b45 Mon Sep 17 00:00:00 2001 From: "s.shchipunov" Date: Mon, 29 Sep 2025 00:18:20 +0700 Subject: [PATCH] feat: update awg tools --- amneziawg-tools/Makefile | 44 +++---- amneziawg-tools/files/amneziawg.sh | 150 +++++++++++++++-------- amneziawg-tools/files/amneziawg_watchdog | 36 +++--- 3 files changed, 136 insertions(+), 94 deletions(-) diff --git a/amneziawg-tools/Makefile b/amneziawg-tools/Makefile index 6408e78..ffcee81 100644 --- a/amneziawg-tools/Makefile +++ b/amneziawg-tools/Makefile @@ -1,25 +1,18 @@ -# -# Copyright (C) 2016-2019 Jason A. Donenfeld -# Copyright (C) 2016 Baptiste Jonglez -# Copyright (C) 2016-2017 Dan Luedtke -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. - include $(TOPDIR)/rules.mk PKG_NAME:=amneziawg-tools +PKG_VERSION:=1.0.20250903 +PKG_RELEASE:=1 -PKG_VERSION:=1.0.20240213 -PKG_RELEASE:=$(AUTORELEASE) - -PKG_SOURCE:=v$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=https://github.com/amnezia-vpn/amneziawg-tools/archive/refs/tags/ -PKG_HASH:=4bde122630c9ddb1ec013c3e958f2c613b9eea56834674dda92fcb423c6f4d10 +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/amnezia-vpn/amneziawg-tools.git +# Version: latest stable release tag +PKG_SOURCE_VERSION:=v$(PKG_VERSION) PKG_LICENSE:=GPL-2.0 PKG_LICENSE_FILES:=COPYING +PKG_BUILD_DIR=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) include $(INCLUDE_DIR)/package.mk @@ -28,32 +21,29 @@ MAKE_VARS += PLATFORM=linux define Package/amneziawg-tools CATEGORY:=Network - URL:=https://www.wireguard.com - MAINTAINER:=Jason A. Donenfeld - TITLE:=WireGuard userspace control program (wg) + SUBMENU:=VPN + URL:=https://amnezia.org/ + MAINTAINER:=Amnezia Admin + TITLE:=AmneziaWG userspace control program (awg) DEPENDS:= \ +@BUSYBOX_CONFIG_IP \ +@BUSYBOX_CONFIG_FEATURE_IP_LINK endef define Package/amneziawg-tools/description - WireGuard is a novel VPN that runs inside the Linux Kernel and utilizes - state-of-the-art cryptography. It aims to be faster, simpler, leaner, and - more useful than IPSec, while avoiding the massive headache. It intends to - be considerably more performant than OpenVPN. WireGuard is designed as a - general purpose VPN for running on embedded interfaces and super computers - alike, fit for many different circumstances. It uses UDP. + Amnezia VPN — simple and free app to run a self-hosted VPN with + high privacy requirements. - This package provides the userspace control program for WireGuard, - `wg(8)`, a netifd protocol helper, and a re-resolve watchdog script. + This package provides the userspace control program for AmneziaWG, + `awg`, a netifd protocol helper, and a re-resolve watchdog script. endef define Package/amneziawg-tools/install $(INSTALL_DIR) $(1)/usr/bin/ - $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/wg $(1)/usr/bin/amneziawg + $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/wg $(1)/usr/bin/awg $(INSTALL_BIN) ./files/amneziawg_watchdog $(1)/usr/bin/ $(INSTALL_DIR) $(1)/lib/netifd/proto/ $(INSTALL_BIN) ./files/amneziawg.sh $(1)/lib/netifd/proto/ endef -$(eval $(call BuildPackage,amneziawg-tools)) \ No newline at end of file +$(eval $(call BuildPackage,amneziawg-tools)) diff --git a/amneziawg-tools/files/amneziawg.sh b/amneziawg-tools/files/amneziawg.sh index cb832af..e0587a8 100755 --- a/amneziawg-tools/files/amneziawg.sh +++ b/amneziawg-tools/files/amneziawg.sh @@ -2,9 +2,11 @@ # Copyright 2016-2017 Dan Luedtke # Licensed to the public under the Apache License 2.0. -WG=/usr/bin/amneziawg -if [ ! -x $WG ]; then - logger -t "amnezia-wg" "error: missing amneziawg-tools (${WG})" +# shellcheck disable=SC1091,SC3003,SC3043 + +AWG=/usr/bin/awg +if [ ! -x $AWG ]; then + logger -t "amneziawg" "error: missing amneziawg-tools (${AWG})" exit 0 fi @@ -24,25 +26,34 @@ proto_amneziawg_init_config() { proto_config_add_int "awg_jmax" proto_config_add_int "awg_s1" proto_config_add_int "awg_s2" - proto_config_add_int "awg_h1" - proto_config_add_int "awg_h2" - proto_config_add_int "awg_h3" - proto_config_add_int "awg_h4" + proto_config_add_int "awg_s3" + proto_config_add_int "awg_s4" + proto_config_add_string "awg_h1" + proto_config_add_string "awg_h2" + proto_config_add_string "awg_h3" + proto_config_add_string "awg_h4" + proto_config_add_string "awg_i1" + proto_config_add_string "awg_i2" + proto_config_add_string "awg_i3" + proto_config_add_string "awg_i4" + proto_config_add_string "awg_i5" +# shellcheck disable=SC2034 available=1 +# shellcheck disable=SC2034 no_proto_task=1 } proto_amneziawg_is_kernel_mode() { if [ ! -e /sys/module/amneziawg ]; then - modprobe amneziawg > /dev/null 2&>1 || true + modprobe amneziawg > /dev/null 2>&1 || true if [ -e /sys/module/amneziawg ]; then return 0 else - if [ ! command -v "${WG_QUICK_USERSPACE_IMPLEMENTATION:-amneziawg-go}" >/dev/null ]; then + if ! command -v "${WG_QUICK_USERSPACE_IMPLEMENTATION:-amneziawg-go}" >/dev/null; then ret=$? echo "Please install either kernel module (kmod-amneziawg package) or user-space implementation in /usr/bin/amneziawg-go." - exit $? + exit $ret else return 1 fi @@ -83,13 +94,13 @@ proto_amneziawg_setup_peer() { return 0 fi - echo "[Peer]" >> "${wg_cfg}" - echo "PublicKey=${public_key}" >> "${wg_cfg}" + echo "[Peer]" >> "${awg_cfg}" + echo "PublicKey=${public_key}" >> "${awg_cfg}" if [ "${preshared_key}" ]; then - echo "PresharedKey=${preshared_key}" >> "${wg_cfg}" + echo "PresharedKey=${preshared_key}" >> "${awg_cfg}" fi - for allowed_ip in $allowed_ips; do - echo "AllowedIPs=${allowed_ip}" >> "${wg_cfg}" + for allowed_ip in ${allowed_ips}; do + echo "AllowedIPs=${allowed_ip}" >> "${awg_cfg}" done if [ "${endpoint_host}" ]; then case "${endpoint_host}" in @@ -105,10 +116,10 @@ proto_amneziawg_setup_peer() { else endpoint="${endpoint}:51820" fi - echo "Endpoint=${endpoint}" >> "${wg_cfg}" + echo "Endpoint=${endpoint}" >> "${awg_cfg}" fi if [ "${persistent_keepalive}" ]; then - echo "PersistentKeepalive=${persistent_keepalive}" >> "${wg_cfg}" + echo "PersistentKeepalive=${persistent_keepalive}" >> "${awg_cfg}" fi if [ ${route_allowed_ips} -ne 0 ]; then @@ -140,7 +151,7 @@ ensure_key_is_generated() { oldmask="$(umask)" umask 077 ucitmp="$(mktemp -d)" - private_key="$("${WG}" genkey)" + private_key="$("${AWG}" genkey)" uci -q -t "$ucitmp" set network."$1".private_key="$private_key" && \ uci -q -t "$ucitmp" commit network rm -rf "$ucitmp" @@ -150,23 +161,35 @@ ensure_key_is_generated() { proto_amneziawg_setup() { local config="$1" - local wg_dir="/tmp/wireguard" - local wg_cfg="${wg_dir}/${config}" + local awg_dir="/tmp/amneziawg" + local awg_cfg="${awg_dir}/${config}" local private_key local listen_port + local addresses local mtu + local fwmark + local ip6prefix + local nohostroute + local tunlink - # Amnezia WG specific parameters + # AmneziaWG specific parameters local awg_jc local awg_jmin local awg_jmax local awg_s1 local awg_s2 + local awg_s3 + local awg_s4 local awg_h1 local awg_h2 local awg_h3 local awg_h4 + local awg_i1 + local awg_i2 + local awg_i3 + local awg_i4 + local awg_i5 ensure_key_is_generated "${config}" @@ -185,18 +208,25 @@ proto_amneziawg_setup() { config_get awg_jmax "${config}" "awg_jmax" config_get awg_s1 "${config}" "awg_s1" config_get awg_s2 "${config}" "awg_s2" + config_get awg_s3 "${config}" "awg_s3" + config_get awg_s4 "${config}" "awg_s4" config_get awg_h1 "${config}" "awg_h1" config_get awg_h2 "${config}" "awg_h2" config_get awg_h3 "${config}" "awg_h3" config_get awg_h4 "${config}" "awg_h4" + config_get awg_i1 "${config}" "awg_i1" + config_get awg_i2 "${config}" "awg_i2" + config_get awg_i3 "${config}" "awg_i3" + config_get awg_i4 "${config}" "awg_i4" + config_get awg_i5 "${config}" "awg_i5" if proto_amneziawg_is_kernel_mode; then - logger -t "amneziawg" "info: using kernel-space kmod-amneziawg for ${WG}" - ip link del dev "${config}" 2>/dev/null + logger -t "amneziawg" "info: using kernel-space kmod-amneziawg for ${AWG}" + ip link del dev "${config}" 2>/dev/null ip link add dev "${config}" type amneziawg else - logger -t "amneziawg" "info: using user-space amneziawg-go for ${WG}" - rm -f "/var/run/wireguard/${config}.sock" + logger -t "amneziawg" "info: using user-space amneziawg-go for ${AWG}" + rm -f "/var/run/amneziawg/${config}.sock" amneziawg-go "${config}" fi @@ -207,53 +237,73 @@ proto_amneziawg_setup() { proto_init_update "${config}" 1 umask 077 - mkdir -p "${wg_dir}" - echo "[Interface]" > "${wg_cfg}" - echo "PrivateKey=${private_key}" >> "${wg_cfg}" + mkdir -p "${awg_dir}" + echo "[Interface]" > "${awg_cfg}" + echo "PrivateKey=${private_key}" >> "${awg_cfg}" if [ "${listen_port}" ]; then - echo "ListenPort=${listen_port}" >> "${wg_cfg}" + echo "ListenPort=${listen_port}" >> "${awg_cfg}" fi if [ "${fwmark}" ]; then - echo "FwMark=${fwmark}" >> "${wg_cfg}" + echo "FwMark=${fwmark}" >> "${awg_cfg}" fi - # AWG + # AmneziaWG parameters if [ "${awg_jc}" ]; then - echo "Jc = ${awg_jc}" >> "${wg_cfg}" + echo "Jc=${awg_jc}" >> "${awg_cfg}" fi if [ "${awg_jmin}" ]; then - echo "Jmin = ${awg_jmin}" >> "${wg_cfg}" + echo "Jmin=${awg_jmin}" >> "${awg_cfg}" fi if [ "${awg_jmax}" ]; then - echo "Jmax = ${awg_jmax}" >> "${wg_cfg}" + echo "Jmax=${awg_jmax}" >> "${awg_cfg}" fi if [ "${awg_s1}" ]; then - echo "S1 = ${awg_s1}" >> "${wg_cfg}" + echo "S1=${awg_s1}" >> "${awg_cfg}" fi if [ "${awg_s2}" ]; then - echo "S2 = ${awg_s2}" >> "${wg_cfg}" + echo "S2=${awg_s2}" >> "${awg_cfg}" + fi + if [ "${awg_s3}" ]; then + echo "S3=${awg_s3}" >> "${awg_cfg}" + fi + if [ "${awg_s4}" ]; then + echo "S4=${awg_s4}" >> "${awg_cfg}" fi if [ "${awg_h1}" ]; then - echo "H1 = ${awg_h1}" >> "${wg_cfg}" + echo "H1=${awg_h1}" >> "${awg_cfg}" fi if [ "${awg_h2}" ]; then - echo "H2 = ${awg_h2}" >> "${wg_cfg}" + echo "H2=${awg_h2}" >> "${awg_cfg}" fi if [ "${awg_h3}" ]; then - echo "H3 = ${awg_h3}" >> "${wg_cfg}" + echo "H3=${awg_h3}" >> "${awg_cfg}" fi if [ "${awg_h4}" ]; then - echo "H4 = ${awg_h4}" >> "${wg_cfg}" + echo "H4=${awg_h4}" >> "${awg_cfg}" + fi + if [ "${awg_i1}" ]; then + echo "I1=${awg_i1}" >> "${awg_cfg}" + fi + if [ "${awg_i2}" ]; then + echo "I2=${awg_i2}" >> "${awg_cfg}" + fi + if [ "${awg_i3}" ]; then + echo "I3=${awg_i3}" >> "${awg_cfg}" + fi + if [ "${awg_i4}" ]; then + echo "I4=${awg_i4}" >> "${awg_cfg}" + fi + if [ "${awg_i5}" ]; then + echo "I5=${awg_i5}" >> "${awg_cfg}" fi - config_foreach proto_amneziawg_setup_peer "amneziawg_${config}" - # apply configuration file - ${WG} setconf ${config} "${wg_cfg}" - WG_RETURN=$? + # Apply configuration file + ${AWG} setconf "${config}" "${awg_cfg}" + AWG_RETURN=$? - rm -f "${wg_cfg}" + rm -f "${awg_cfg}" - if [ ${WG_RETURN} -ne 0 ]; then + if [ ${AWG_RETURN} -ne 0 ]; then sleep 5 proto_setup_failed "${config}" exit 1 @@ -282,7 +332,8 @@ proto_amneziawg_setup() { # endpoint dependency if [ "${nohostroute}" != "1" ]; then - ${WG} show "${config}" endpoints | \ + # shellcheck disable=SC2034 + ${AWG} show "${config}" endpoints | \ sed -E 's/\[?([0-9.:a-f]+)\]?:([0-9]+)/\1 \2/' | \ while IFS=$'\t ' read -r key address port; do [ -n "${port}" ] || continue @@ -295,14 +346,13 @@ proto_amneziawg_setup() { proto_amneziawg_teardown() { local config="$1" - proto_amneziawg_check_installed if proto_amneziawg_is_kernel_mode; then ip link del dev "${config}" >/dev/null 2>&1 else - rm -f /var/run/wireguard/${config}.sock + rm -f "/var/run/amneziawg/${config}.sock" fi } [ -n "$INCLUDE_ONLY" ] || { add_protocol amneziawg -} \ No newline at end of file +} diff --git a/amneziawg-tools/files/amneziawg_watchdog b/amneziawg-tools/files/amneziawg_watchdog index a9b631a..a8e825c 100755 --- a/amneziawg-tools/files/amneziawg_watchdog +++ b/amneziawg-tools/files/amneziawg_watchdog @@ -11,12 +11,13 @@ # Run this script from cron every minute: # echo '* * * * * /usr/bin/wireguard_watchdog' >> /etc/crontabs/root +# shellcheck disable=SC1091,SC3043 . /lib/functions.sh check_peer_activity() { - local cfg=$1 - local iface=$2 + local cfg="$1" + local iface="$2" local disabled local public_key local endpoint_host @@ -26,7 +27,7 @@ check_peer_activity() { local idle_seconds config_get_bool disabled "${cfg}" "disabled" 0 - config_get public_key "${cfg}" "public_key" + config_get public_key "${cfg}" "public_key" config_get endpoint_host "${cfg}" "endpoint_host" config_get endpoint_port "${cfg}" "endpoint_port" @@ -35,34 +36,35 @@ check_peer_activity() { return 0 fi - persistent_keepalive=$(wg show ${iface} persistent-keepalive | grep ${public_key} | awk '{print $2}') + persistent_keepalive=$(awg show "${iface}" persistent-keepalive | grep "${public_key}" | awk '{print $2}') # only process peers with endpoints and keepalive set - [ -z ${endpoint_host} ] && return 0; - [ -z ${persistent_keepalive} -o ${persistent_keepalive} = "off" ] && return 0; + [ -z "${endpoint_host}" ] && return 0; + if [ -z "${persistent_keepalive}" ] || [ "${persistent_keepalive}" = "off" ]; then return 0; fi # skip IP addresses # check taken from packages/net/ddns-scripts/files/dynamic_dns_functions.sh local IPV4_REGEX="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" local IPV6_REGEX="\(\([0-9A-Fa-f]\{1,4\}:\)\{1,\}\)\(\([0-9A-Fa-f]\{1,4\}\)\{0,1\}\)\(\(:[0-9A-Fa-f]\{1,4\}\)\{1,\}\)" - local IPV4=$(echo ${endpoint_host} | grep -m 1 -o "$IPV4_REGEX$") # do not detect ip in 0.0.0.0.example.com - local IPV6=$(echo ${endpoint_host} | grep -m 1 -o "$IPV6_REGEX") - [ -n "${IPV4}" -o -n "${IPV6}" ] && return 0; + local IPV4 IPV6 + IPV4="$(echo "${endpoint_host}" | grep -m 1 -o "$IPV4_REGEX$")" # do not detect ip in 0.0.0.0.example.com + IPV6="$(echo "${endpoint_host}" | grep -m 1 -o "$IPV6_REGEX")" + [ -n "${IPV4}${IPV6}" ] && return 0; # re-resolve endpoint hostname if not responding for too long - last_handshake=$(wg show ${iface} latest-handshakes | grep ${public_key} | awk '{print $2}') - [ -z ${last_handshake} ] && return 0; + last_handshake=$(awg show "${iface}" latest-handshakes | grep "${public_key}" | awk '{print $2}') + [ -z "${last_handshake}" ] && return 0; idle_seconds=$(($(date +%s)-${last_handshake})) [ ${idle_seconds} -lt 150 ] && return 0; - logger -t "wireguard_monitor" "${iface} endpoint ${endpoint_host}:${endpoint_port} is not responding for ${idle_seconds} seconds, trying to re-resolve hostname" - wg set ${iface} peer ${public_key} endpoint "${endpoint_host}:${endpoint_port}" + logger -t "amneziawg_monitor" "${iface} endpoint ${endpoint_host}:${endpoint_port} is not responding for ${idle_seconds} seconds, trying to re-resolve hostname" + awg set "${iface}" peer "${public_key}" endpoint "${endpoint_host}:${endpoint_port}" } # query ubus for all active wireguard interfaces -wg_ifaces=$(ubus -S call network.interface dump | jsonfilter -e '@.interface[@.up=true]' | jsonfilter -a -e '@[@.proto="wireguard"].interface' | tr "\n" " ") +awg_ifaces=$(ubus -S call network.interface dump | jsonfilter -e '@.interface[@.up=true]' | jsonfilter -a -e '@[@.proto="amneziawg"].interface' | tr "\n" " ") # check every peer in every active wireguard interface config_load network -for iface in $wg_ifaces; do - config_foreach check_peer_activity "wireguard_${iface}" "${iface}" -done \ No newline at end of file +for iface in $awg_ifaces; do + config_foreach check_peer_activity "amneziawg_${iface}" "${iface}" +done