mirror of
https://github.com/Slava-Shchipunov/awg-openwrt.git
synced 2026-03-14 09:23:10 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d01d64868 | ||
|
|
97d6ac45b5 | ||
|
|
c87b5b9d10 | ||
|
|
ae0bc9da89 | ||
|
|
5afb93092d | ||
|
|
e9ade36db1 | ||
|
|
0e3dcba686 | ||
|
|
37f496e9e0 | ||
|
|
f186bf1b76 | ||
|
|
9bc094ec4d | ||
|
|
7740f55534 | ||
|
|
19495ca05a |
158
.github/workflows/build-module.yml
vendored
158
.github/workflows/build-module.yml
vendored
@@ -53,94 +53,122 @@ jobs:
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
repository: openwrt/openwrt
|
||||
ref: v${{ matrix.build_env.tag }}
|
||||
fetch-depth: 0
|
||||
- name: Checkout AWG source code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Cache Tools and Kernel
|
||||
id: cache-tools-kernel
|
||||
- name: Cache OpenWrt SDK
|
||||
id: cache-sdk
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: "cache-tools-kernel-${{ matrix.build_env.tag }}-${{ matrix.build_env.pkgarch}}-${{ matrix.build_env.target}}-${{ matrix.build_env.subtarget}}"
|
||||
cache-name: "cache-sdk-${{ matrix.build_env.tag }}-${{ matrix.build_env.target}}-${{ matrix.build_env.subtarget}}"
|
||||
with:
|
||||
path: "**"
|
||||
key: ${{ runner.os }}-build-vm4-${{ env.cache-name }}
|
||||
path: openwrt-sdk-*/
|
||||
key: ${{ runner.os }}-sdk-${{ env.cache-name }}
|
||||
|
||||
- name: Building kernel and tools
|
||||
#if: ${{ steps.cache-tools-kernel.outputs.cache-hit != 'true' }}
|
||||
- name: Download and extract OpenWrt SDK
|
||||
if: steps.cache-sdk.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
echo "pkgarch: ${{ matrix.build_env.pkgarch}}, target:${{ matrix.build_env.target}}, subtarget: ${{ matrix.build_env.subtarget}}"
|
||||
|
||||
# Setup & install feeds
|
||||
wget https://downloads.openwrt.org/releases/${{ matrix.build_env.tag }}/targets/${{ matrix.build_env.target}}/${{ matrix.build_env.subtarget}}/feeds.buildinfo -O feeds.conf
|
||||
echo "src-git awgopenwrt https://github.com/Slava-Shchipunov/awg-openwrt.git" >> ./feeds.conf
|
||||
./scripts/feeds update && ./scripts/feeds install -a
|
||||
# Get the actual SDK filename from the directory listing
|
||||
SDK_FILE=$(curl -s "https://downloads.openwrt.org/releases/${{ matrix.build_env.tag }}/targets/${{ matrix.build_env.target}}/${{ matrix.build_env.subtarget}}/" | grep -o "openwrt-sdk-${{ matrix.build_env.tag }}-${{ matrix.build_env.target}}-${{ matrix.build_env.subtarget}}_gcc-[^\"]*_musl[^\"]*\.Linux-x86_64\.tar\.[xz|zst]*" | head -n1)
|
||||
|
||||
if [ -z "$SDK_FILE" ]; then
|
||||
echo "SDK file not found for ${{ matrix.build_env.tag }} ${{ matrix.build_env.target}} ${{ matrix.build_env.subtarget}}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SDK_DOWNLOAD_URL="https://downloads.openwrt.org/releases/${{ matrix.build_env.tag }}/targets/${{ matrix.build_env.target}}/${{ matrix.build_env.subtarget}}/${SDK_FILE}"
|
||||
echo "Downloading SDK: $SDK_DOWNLOAD_URL"
|
||||
|
||||
wget "$SDK_DOWNLOAD_URL"
|
||||
|
||||
# Extract based on file extension
|
||||
if [[ "$SDK_FILE" == *.tar.zst ]]; then
|
||||
tar --zstd -xf "$SDK_FILE"
|
||||
elif [[ "$SDK_FILE" == *.tar.xz ]]; then
|
||||
tar -xf "$SDK_FILE"
|
||||
else
|
||||
echo "Unknown archive format: $SDK_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm "$SDK_FILE"
|
||||
|
||||
# Setup config with AWG and dependencies
|
||||
wget https://downloads.openwrt.org/releases/${{ matrix.build_env.tag }}/targets/${{ matrix.build_env.target}}/${{ matrix.build_env.subtarget}}/config.buildinfo -O .config
|
||||
echo "CONFIG_PACKAGE_kmod-amneziawg=m" >> .config
|
||||
- name: Setup SDK and feeds
|
||||
run: |
|
||||
# Find SDK directory
|
||||
SDK_DIR=$(find . -maxdepth 1 -name "openwrt-sdk-*" -type d | head -n1)
|
||||
|
||||
if [ -z "$SDK_DIR" ]; then
|
||||
echo "SDK directory not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get absolute paths
|
||||
WORKSPACE_DIR=$(pwd)
|
||||
|
||||
cd "$SDK_DIR"
|
||||
|
||||
# Update feeds to include LuCI
|
||||
./scripts/feeds update -a
|
||||
./scripts/feeds install -a
|
||||
|
||||
# Copy current repository packages directly to package directory
|
||||
cp -r "$WORKSPACE_DIR/kmod-amneziawg" package/
|
||||
cp -r "$WORKSPACE_DIR/amneziawg-tools" package/
|
||||
cp -r "$WORKSPACE_DIR/luci-proto-amneziawg" package/
|
||||
|
||||
# Configure packages to build
|
||||
echo "CONFIG_PACKAGE_kmod-amneziawg=m" > .config
|
||||
echo "CONFIG_PACKAGE_amneziawg-tools=y" >> .config
|
||||
echo "CONFIG_PACKAGE_luci-app-amneziawg=y" >> .config
|
||||
echo "CONFIG_PACKAGE_kmod-crypto-lib-chacha20=m" >> .config
|
||||
echo "CONFIG_PACKAGE_kmod-crypto-lib-chacha20poly1305=m" >> .config
|
||||
echo "CONFIG_PACKAGE_kmod-crypto-chacha20poly1305=m" >> .config
|
||||
|
||||
echo "CONFIG_PACKAGE_luci-proto-amneziawg=y" >> .config
|
||||
echo "CONFIG_PACKAGE_luci-i18n-amneziawg-ru=y" >> .config
|
||||
|
||||
make defconfig
|
||||
|
||||
echo " > make tools/install"
|
||||
make tools/install -i -j `nproc`
|
||||
|
||||
cat ./build_dir/target-*/linux-*/linux-*/.vermagic || true
|
||||
|
||||
echo " > make toolchain/install"
|
||||
make toolchain/install -i -j `nproc`
|
||||
|
||||
cat ./build_dir/target-*/linux-*/linux-*/.vermagic || true
|
||||
|
||||
# compile kernel module
|
||||
echo " > make target/linux/compile"
|
||||
make target/linux/compile -i -j `nproc` V=s
|
||||
|
||||
VERMAGIC=`cat ./build_dir/target-*/linux-*/linux-*/.vermagic`
|
||||
VERMAGIC_EXPECTED=${{ matrix.build_env.vermagic }}
|
||||
|
||||
if [ "$VERMAGIC" != "$VERMAGIC_EXPECTED" ]; then
|
||||
echo Vermagic mismatch: $VERMAGIC, expected $VERMAGIC_EXPECTED
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Build AmneziaWG
|
||||
- name: Build AmneziaWG packages
|
||||
run: |
|
||||
VERMAGIC=`cat ./build_dir/target-*/linux-*/linux-*/.vermagic`
|
||||
echo "Vermagic: $VERMAGIC"
|
||||
# Find SDK directory
|
||||
SDK_DIR=$(find . -maxdepth 1 -name "openwrt-sdk-*" -type d | head -n1)
|
||||
cd "$SDK_DIR"
|
||||
|
||||
VERMAGIC_EXPECTED=${{ matrix.build_env.vermagic }}
|
||||
echo "Building AmneziaWG packages..."
|
||||
|
||||
if [ "$VERMAGIC" != "$VERMAGIC_EXPECTED" ]; then
|
||||
echo Vermagic mismatch: $VERMAGIC, expected $VERMAGIC_EXPECTED
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Ignore kmod build for some targets, replace with the awg-go
|
||||
make package/kmod-amneziawg/{clean,download,prepare} V=s || true
|
||||
# Build kmod-amneziawg (kernel module)
|
||||
echo "Building kmod-amneziawg..."
|
||||
make package/kmod-amneziawg/{download,prepare} V=s || true
|
||||
make package/kmod-amneziawg/compile V=s || true
|
||||
|
||||
make package/luci-app-amneziawg/{clean,download,prepare}
|
||||
make package/luci-app-amneziawg/compile V=s
|
||||
# Build luci-proto-amneziawg (web interface)
|
||||
echo "Building luci-proto-amneziawg..."
|
||||
make package/luci-proto-amneziawg/{download,prepare} V=s
|
||||
make package/luci-proto-amneziawg/compile V=s
|
||||
|
||||
make V=s package/amneziawg-tools/{clean,download,prepare}
|
||||
make V=s package/amneziawg-tools/compile
|
||||
# Build amneziawg-tools (userspace tools)
|
||||
echo "Building amneziawg-tools..."
|
||||
make package/amneziawg-tools/{download,prepare} V=s
|
||||
make package/amneziawg-tools/compile V=s
|
||||
|
||||
echo "Build completed. Checking for built packages..."
|
||||
find bin/ -name "*.ipk" | grep -E "(amneziawg|luci-proto-amneziawg|luci-i18n-amneziawg)" | head -10
|
||||
|
||||
- name: Prepare artifacts
|
||||
run: |
|
||||
tag_name=${{ github.ref_name }}
|
||||
# Find SDK directory
|
||||
SDK_DIR=$(find . -maxdepth 1 -name "openwrt-sdk-*" -type d | head -n1)
|
||||
|
||||
mkdir -p awgrelease
|
||||
postfix="v${{ matrix.build_env.tag }}_${{ matrix.build_env.pkgarch}}_${{ matrix.build_env.target}}_${{ matrix.build_env.subtarget}}"
|
||||
cp bin/packages/${{ matrix.build_env.pkgarch }}/awgopenwrt/amneziawg-tools_*.ipk awgrelease/amneziawg-tools_${postfix}.ipk
|
||||
cp bin/packages/${{ matrix.build_env.pkgarch }}/awgopenwrt/luci-app-amneziawg_*.ipk awgrelease/luci-app-amneziawg_${postfix}.ipk
|
||||
cp bin/targets/${{ matrix.build_env.target}}/${{ matrix.build_env.subtarget}}/packages/kmod-amneziawg_*.ipk awgrelease/kmod-amneziawg_${postfix}.ipk
|
||||
|
||||
# Copy built packages
|
||||
find "$SDK_DIR/bin/packages" -name "amneziawg-tools_*.ipk" -exec cp {} awgrelease/amneziawg-tools_${postfix}.ipk \; || echo "amneziawg-tools package not found"
|
||||
find "$SDK_DIR/bin/packages" -name "luci-proto-amneziawg_*.ipk" -exec cp {} awgrelease/luci-proto-amneziawg_${postfix}.ipk \; || echo "luci-proto-amneziawg package not found"
|
||||
find "$SDK_DIR/bin/packages" -name "luci-i18n-amneziawg-ru_*.ipk" -exec cp {} awgrelease/luci-i18n-amneziawg-ru_${postfix}.ipk \; || echo "luci-i18n-amneziawg-ru package not found"
|
||||
find "$SDK_DIR/bin/targets" -name "kmod-amneziawg_*.ipk" -exec cp {} awgrelease/kmod-amneziawg_${postfix}.ipk \; || echo "kmod-amneziawg package not found"
|
||||
|
||||
echo "Built packages:"
|
||||
ls -la awgrelease/
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
|
||||
2
.github/workflows/run-release.yml
vendored
2
.github/workflows/run-release.yml
vendored
@@ -3,7 +3,7 @@ name: Sync OpenWRT Releases
|
||||
on:
|
||||
# schedule:
|
||||
# - cron: '0 0 */3 * *' # Проверка новых релизов раз в три дня
|
||||
workflow_dispatch: # Возможность вручную запустить Action
|
||||
# workflow_dispatch: # Возможность вручную запустить Action
|
||||
|
||||
jobs:
|
||||
sync-releases:
|
||||
|
||||
10
README.md
10
README.md
@@ -16,16 +16,16 @@ sh <(wget -O - https://raw.githubusercontent.com/Slava-Shchipunov/awg-openwrt/re
|
||||
4) [23.05.3](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v23.05.3)
|
||||
5) [23.05.4](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v23.05.4)
|
||||
6) [23.05.5](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v23.05.5)
|
||||
|
||||
И собрал пакеты для популярных устройств для OpenWRT [SNAPSHOT](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/SNAPSHOT)
|
||||
7) [23.05.6](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v23.05.6)
|
||||
8) [24.10.0](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.0)
|
||||
9) [24.10.1](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.1)
|
||||
10) [24.10.2](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.2)
|
||||
11) [24.10.3](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.3)
|
||||
|
||||
Также запускал сборку для версии [22.03.7](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v22.03.7), но там для двух платформ сборка завершилась ошибкой. Так как это достаточно старая версия OpenWRT, я не стал разбираться, в чем проблема.
|
||||
|
||||
В дальнейшем при выходе новых релизов OpenWRT будут автоматически создаваться релизы с пакетами AmneziaWG и запускаться сборка пакетов под все устройства, поддерживаемые новой версией. Github action для проверки появления нового релиза запускается автоматически раз в 3 дня, а также может быть запущен вручную.
|
||||
|
||||
## Автоматическая сборка пакетов для SNAPSHOT версии
|
||||
В репозитории настроен github action, который запускается каждые 4 часа и проверяет [страницу снапшотов](https://downloads.openwrt.org/snapshots/targets/) сайта OpenWRT. При этом, если для какой-то платформы обнаруживается снапшот с более новой версией ядра, запускается сборка пакетов под эту платформу, а новые файлы заменяют старые. В целях экономии ресурсов и ускорения процесса сборки, пакеты собираются только для популярных платформ, которые указаны в массиве `SNAPSHOT_SUBTARGETS_TO_BUILD` в файле index.js.
|
||||
|
||||
## Выбор пакетов для своего устройства
|
||||
В соответствии с пунктом [Указываем переменные для сборки](https://github.com/itdoginfo/domain-routing-openwrt/wiki/Amnezia-WG-Build#%D1%83%D0%BA%D0%B0%D0%B7%D1%8B%D0%B2%D0%B0%D0%B5%D0%BC-%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5-%D0%B4%D0%BB%D1%8F-%D1%81%D0%B1%D0%BE%D1%80%D0%BA%D0%B8)
|
||||
определить `target` и `subtarget` вашего устройства. Далее перейти на страницу релиза, соответствующего вашей версии OpenWRT, затем поиском по странице (Ctrl+F) найти 3 пакета, название которых оканчивается на `target_subtarget.ipk`, соответствующие вашему устройству.
|
||||
|
||||
@@ -38,7 +38,7 @@ install_awg_packages() {
|
||||
opkg install "$AWG_DIR/$KMOD_AMNEZIAWG_FILENAME"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "kmod-amneziawg file downloaded successfully"
|
||||
echo "kmod-amneziawg installed successfully"
|
||||
else
|
||||
echo "Error installing kmod-amneziawg. Please, install kmod-amneziawg manually and run the script again"
|
||||
exit 1
|
||||
@@ -62,37 +62,66 @@ install_awg_packages() {
|
||||
opkg install "$AWG_DIR/$AMNEZIAWG_TOOLS_FILENAME"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "amneziawg-tools file downloaded successfully"
|
||||
echo "amneziawg-tools installed 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 luci-app-amneziawg; then
|
||||
echo "luci-app-amneziawg already installed"
|
||||
if opkg list-installed | grep -q luci-proto-amneziawg; then
|
||||
echo "luci-proto-amneziawg already installed"
|
||||
else
|
||||
LUCI_APP_AMNEZIAWG_FILENAME="luci-app-amneziawg${PKGPOSTFIX}"
|
||||
LUCI_APP_AMNEZIAWG_FILENAME="luci-proto-amneziawg${PKGPOSTFIX}"
|
||||
DOWNLOAD_URL="${BASE_URL}v${VERSION}/${LUCI_APP_AMNEZIAWG_FILENAME}"
|
||||
wget -O "$AWG_DIR/$LUCI_APP_AMNEZIAWG_FILENAME" "$DOWNLOAD_URL"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "luci-app-amneziawg file downloaded successfully"
|
||||
echo "luci-proto-amneziawg file downloaded successfully"
|
||||
else
|
||||
echo "Error downloading luci-app-amneziawg. Please, install luci-app-amneziawg manually and run the script again"
|
||||
echo "Error downloading luci-proto-amneziawg. Please, install luci-proto-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"
|
||||
echo "luci-proto-amneziawg installed successfully"
|
||||
else
|
||||
echo "Error installing luci-app-amneziawg. Please, install luci-app-amneziawg manually and run the script again"
|
||||
echo "Error installing luci-proto-amneziawg. Please, install luci-proto-amneziawg manually and run the script again"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Ask about Russian localization
|
||||
printf "\033[32;1mУстанавливаем пакет с русской локализацией? Install Russian language pack? (y/n) [n]: \033[0m\n"
|
||||
read INSTALL_RU_LANG
|
||||
INSTALL_RU_LANG=${INSTALL_RU_LANG:-n}
|
||||
|
||||
if [ "$INSTALL_RU_LANG" = "y" ] || [ "$INSTALL_RU_LANG" = "Y" ]; then
|
||||
if opkg list-installed | grep -q luci-i18n-amneziawg-ru; then
|
||||
echo "luci-i18n-amneziawg-ru already installed"
|
||||
else
|
||||
LUCI_I18N_AMNEZIAWG_RU_FILENAME="luci-i18n-amneziawg-ru${PKGPOSTFIX}"
|
||||
DOWNLOAD_URL="${BASE_URL}v${VERSION}/${LUCI_I18N_AMNEZIAWG_RU_FILENAME}"
|
||||
wget -O "$AWG_DIR/$LUCI_I18N_AMNEZIAWG_RU_FILENAME" "$DOWNLOAD_URL"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "luci-i18n-amneziawg-ru file downloaded successfully"
|
||||
opkg install "$AWG_DIR/$LUCI_I18N_AMNEZIAWG_RU_FILENAME"
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "luci-i18n-amneziawg-ru installed successfully"
|
||||
else
|
||||
echo "Warning: Error installing luci-i18n-amneziawg-ru (non-critical)"
|
||||
fi
|
||||
else
|
||||
echo "Warning: Russian localization not available for this version/platform (non-critical)"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
printf "\033[32;1mSkipping Russian language pack installation.\033[0m\n"
|
||||
fi
|
||||
|
||||
rm -rf "$AWG_DIR"
|
||||
}
|
||||
|
||||
|
||||
@@ -1,25 +1,18 @@
|
||||
#
|
||||
# Copyright (C) 2016-2019 Jason A. Donenfeld <Jason@zx2c4.com>
|
||||
# Copyright (C) 2016 Baptiste Jonglez <openwrt@bitsofnetworks.org>
|
||||
# Copyright (C) 2016-2017 Dan Luedtke <mail@danrl.com>
|
||||
#
|
||||
# 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 <Jason@zx2c4.com>
|
||||
TITLE:=WireGuard userspace control program (wg)
|
||||
SUBMENU:=VPN
|
||||
URL:=https://amnezia.org/
|
||||
MAINTAINER:=Amnezia Admin <admin@amnezia.org>
|
||||
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))
|
||||
$(eval $(call BuildPackage,amneziawg-tools))
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
# Copyright 2016-2017 Dan Luedtke <mail@danrl.com>
|
||||
# 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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
for iface in $awg_ifaces; do
|
||||
config_foreach check_peer_activity "amneziawg_${iface}" "${iface}"
|
||||
done
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=kmod-amneziawg
|
||||
PKG_VERSION:=1.0.20250924
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/amnezia-vpn/amneziawg-linux-kernel-module.git
|
||||
# Latest commit from feature/awg2 branch as of 2025-09-24
|
||||
PKG_SOURCE_VERSION:=2a94fcc67c332bbb4b983fcebe03ac31057ead19
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
MAKE_PATH:=src
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define KernelPackage/amneziawg
|
||||
@@ -12,7 +19,7 @@ define KernelPackage/amneziawg
|
||||
CATEGORY:=Kernel modules
|
||||
SUBMENU:=Network Support
|
||||
TITLE:=AmneziaWG VPN Kernel Module
|
||||
FILES:=$(PKG_BUILD_DIR)/amneziawg.ko
|
||||
FILES:=$(PKG_BUILD_DIR)/$(MAKE_PATH)/amneziawg.ko
|
||||
DEPENDS:= \
|
||||
+kmod-udptunnel4 \
|
||||
+kmod-udptunnel6 \
|
||||
@@ -21,19 +28,17 @@ define KernelPackage/amneziawg
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
cp -fr $(LINUX_DIR)/drivers/net/wireguard/{*.c,*.h,selftest/} $(PKG_BUILD_DIR)
|
||||
mkdir -p $(PKG_BUILD_DIR)/uapi
|
||||
cp -f $(LINUX_DIR)/include/uapi/linux/wireguard.h $(PKG_BUILD_DIR)/uapi/
|
||||
patch -d $(PKG_BUILD_DIR)/ < files/amnezia-sources.patch
|
||||
patch -d $(PKG_BUILD_DIR)/uapi/ < files/amnezia-uapi.patch
|
||||
cp -f src/Makefile $(PKG_BUILD_DIR)
|
||||
$(call Build/Prepare/Default)
|
||||
mkdir -p $(PKG_BUILD_DIR)/$(MAKE_PATH)/kernel
|
||||
$(CP) $(LINUX_DIR)/* $(PKG_BUILD_DIR)/$(MAKE_PATH)/kernel/
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(MAKE) -C "$(LINUX_DIR)" \
|
||||
$(MAKE_VARS) $(MAKE) -C "$(LINUX_DIR)" \
|
||||
$(KERNEL_MAKE_FLAGS) \
|
||||
M="$(PKG_BUILD_DIR)" \
|
||||
M="$(PKG_BUILD_DIR)/$(MAKE_PATH)" \
|
||||
EXTRA_CFLAGS="$(BUILDFLAGS)" \
|
||||
WIREGUARD_VERSION="$(WIREGUARD_VERSION)" \
|
||||
modules
|
||||
endef
|
||||
|
||||
|
||||
@@ -1,798 +0,0 @@
|
||||
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/cookie.c ./cookie.c
|
||||
--- ../../linux-source-6.2.0/drivers/net/wireguard/cookie.c 2023-11-10 18:10:29
|
||||
+++ ./cookie.c 2023-11-23 18:59:07
|
||||
@@ -179,13 +179,13 @@
|
||||
|
||||
void wg_cookie_message_create(struct message_handshake_cookie *dst,
|
||||
struct sk_buff *skb, __le32 index,
|
||||
- struct cookie_checker *checker)
|
||||
+ struct cookie_checker *checker, u32 message_type)
|
||||
{
|
||||
struct message_macs *macs = (struct message_macs *)
|
||||
((u8 *)skb->data + skb->len - sizeof(*macs));
|
||||
u8 cookie[COOKIE_LEN];
|
||||
|
||||
- dst->header.type = cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE);
|
||||
+ dst->header.type = cpu_to_le32(message_type);
|
||||
dst->receiver_index = index;
|
||||
get_random_bytes_wait(dst->nonce, COOKIE_NONCE_LEN);
|
||||
|
||||
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/cookie.h ./cookie.h
|
||||
--- ../../linux-source-6.2.0/drivers/net/wireguard/cookie.h 2023-11-10 18:10:29
|
||||
+++ ./cookie.h 2023-11-23 13:11:40
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
void wg_cookie_message_create(struct message_handshake_cookie *src,
|
||||
struct sk_buff *skb, __le32 index,
|
||||
- struct cookie_checker *checker);
|
||||
+ struct cookie_checker *checker, u32 message_type);
|
||||
void wg_cookie_message_consume(struct message_handshake_cookie *src,
|
||||
struct wg_device *wg);
|
||||
|
||||
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/device.c ./device.c
|
||||
--- ../../linux-source-6.2.0/drivers/net/wireguard/device.c 2023-11-10 18:10:29
|
||||
+++ ./device.c 2023-11-26 17:42:17
|
||||
@@ -379,6 +379,11 @@
|
||||
*/
|
||||
dev->priv_destructor = wg_destruct;
|
||||
|
||||
+ wg->advanced_security_config.init_packet_magic_header = MESSAGE_HANDSHAKE_INITIATION;
|
||||
+ wg->advanced_security_config.response_packet_magic_header = MESSAGE_HANDSHAKE_RESPONSE;
|
||||
+ wg->advanced_security_config.cookie_packet_magic_header = MESSAGE_HANDSHAKE_COOKIE;
|
||||
+ wg->advanced_security_config.transport_packet_magic_header = MESSAGE_DATA;
|
||||
+
|
||||
pr_debug("%s: Interface created\n", dev->name);
|
||||
return ret;
|
||||
|
||||
@@ -475,4 +480,118 @@
|
||||
unregister_random_vmfork_notifier(&vm_notifier);
|
||||
unregister_pm_notifier(&pm_notifier);
|
||||
rcu_barrier();
|
||||
+}
|
||||
+
|
||||
+int wg_device_handle_post_config(struct net_device *dev, struct amnezia_config *asc)
|
||||
+{
|
||||
+ struct wg_device *wg = netdev_priv(dev);
|
||||
+ bool a_sec_on = false;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (!asc->advanced_security_enabled)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (asc->junk_packet_count < 0) {
|
||||
+ net_dbg_ratelimited("%s: JunkPacketCount should be non negative\n", dev->name);
|
||||
+ ret = -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ wg->advanced_security_config.junk_packet_count = asc->junk_packet_count;
|
||||
+ if (asc->junk_packet_count != 0)
|
||||
+ a_sec_on = true;
|
||||
+
|
||||
+ wg->advanced_security_config.junk_packet_min_size = asc->junk_packet_min_size;
|
||||
+ if (asc->junk_packet_min_size != 0)
|
||||
+ a_sec_on = true;
|
||||
+
|
||||
+ if (asc->junk_packet_count > 0 && asc->junk_packet_min_size == asc->junk_packet_max_size)
|
||||
+ asc->junk_packet_max_size++;
|
||||
+
|
||||
+ if (asc->junk_packet_max_size >= MESSAGE_MAX_SIZE) {
|
||||
+ wg->advanced_security_config.junk_packet_min_size = 0;
|
||||
+ wg->advanced_security_config.junk_packet_max_size = 1;
|
||||
+
|
||||
+ net_dbg_ratelimited("%s: JunkPacketMaxSize: %d; should be smaller than maxSegmentSize: %d\n",
|
||||
+ dev->name, asc->junk_packet_max_size,
|
||||
+ MESSAGE_MAX_SIZE);
|
||||
+ ret = -EINVAL;
|
||||
+ } else if (asc->junk_packet_max_size < asc->junk_packet_min_size) {
|
||||
+ net_dbg_ratelimited("%s: maxSize: %d; should be greater than minSize: %d\n",
|
||||
+ dev->name, asc->junk_packet_max_size,
|
||||
+ asc->junk_packet_min_size);
|
||||
+ ret = -EINVAL;
|
||||
+ } else
|
||||
+ wg->advanced_security_config.junk_packet_max_size = asc->junk_packet_max_size;
|
||||
+
|
||||
+ if (asc->junk_packet_max_size != 0)
|
||||
+ a_sec_on = true;
|
||||
+
|
||||
+ if (asc->init_packet_junk_size + MESSAGE_INITIATION_SIZE >= MESSAGE_MAX_SIZE) {
|
||||
+ net_dbg_ratelimited("%s: init header size (%d) + junkSize (%d) should be smaller than maxSegmentSize: %d\n",
|
||||
+ dev->name, MESSAGE_INITIATION_SIZE,
|
||||
+ asc->init_packet_junk_size, MESSAGE_MAX_SIZE);
|
||||
+ ret = -EINVAL;
|
||||
+ } else
|
||||
+ wg->advanced_security_config.init_packet_junk_size = asc->init_packet_junk_size;
|
||||
+
|
||||
+ if (asc->init_packet_junk_size != 0)
|
||||
+ a_sec_on = true;
|
||||
+
|
||||
+ if (asc->response_packet_junk_size + MESSAGE_RESPONSE_SIZE >= MESSAGE_MAX_SIZE) {
|
||||
+ net_dbg_ratelimited("%s: response header size (%d) + junkSize (%d) should be smaller than maxSegmentSize: %d\n",
|
||||
+ dev->name, MESSAGE_RESPONSE_SIZE,
|
||||
+ asc->response_packet_junk_size, MESSAGE_MAX_SIZE);
|
||||
+ ret = -EINVAL;
|
||||
+ } else
|
||||
+ wg->advanced_security_config.response_packet_junk_size = asc->response_packet_junk_size;
|
||||
+
|
||||
+ if (asc->response_packet_junk_size != 0)
|
||||
+ a_sec_on = true;
|
||||
+
|
||||
+ if (asc->init_packet_magic_header > MESSAGE_DATA) {
|
||||
+ a_sec_on = true;
|
||||
+ wg->advanced_security_config.init_packet_magic_header = asc->init_packet_magic_header;
|
||||
+ }
|
||||
+
|
||||
+ if (asc->response_packet_magic_header > MESSAGE_DATA) {
|
||||
+ a_sec_on = true;
|
||||
+ wg->advanced_security_config.response_packet_magic_header = asc->response_packet_magic_header;
|
||||
+ }
|
||||
+
|
||||
+ if (asc->cookie_packet_magic_header > MESSAGE_DATA) {
|
||||
+ a_sec_on = true;
|
||||
+ wg->advanced_security_config.cookie_packet_magic_header = asc->cookie_packet_magic_header;
|
||||
+ }
|
||||
+
|
||||
+ if (asc->transport_packet_magic_header > MESSAGE_DATA) {
|
||||
+ a_sec_on = true;
|
||||
+ wg->advanced_security_config.transport_packet_magic_header = asc->transport_packet_magic_header;
|
||||
+ }
|
||||
+
|
||||
+ if (asc->init_packet_magic_header == asc->response_packet_magic_header ||
|
||||
+ asc->init_packet_magic_header == asc->cookie_packet_magic_header ||
|
||||
+ asc->init_packet_magic_header == asc->transport_packet_magic_header ||
|
||||
+ asc->response_packet_magic_header == asc->cookie_packet_magic_header ||
|
||||
+ asc->response_packet_magic_header == asc->transport_packet_magic_header ||
|
||||
+ asc->cookie_packet_magic_header == asc->transport_packet_magic_header) {
|
||||
+ net_dbg_ratelimited("%s: magic headers should differ; got: init:%d; recv:%d; unde:%d; tran:%d\n",
|
||||
+ dev->name,
|
||||
+ asc->init_packet_magic_header,
|
||||
+ asc->response_packet_magic_header,
|
||||
+ asc->cookie_packet_magic_header,
|
||||
+ asc->transport_packet_magic_header);
|
||||
+ ret = -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (MESSAGE_INITIATION_SIZE + asc->init_packet_junk_size == MESSAGE_RESPONSE_SIZE + asc->response_packet_junk_size) {
|
||||
+ net_dbg_ratelimited("%s: new init size:%d; and new response size:%d; should differ\n",
|
||||
+ dev->name,
|
||||
+ MESSAGE_INITIATION_SIZE + asc->init_packet_junk_size,
|
||||
+ MESSAGE_RESPONSE_SIZE + asc->response_packet_junk_size);
|
||||
+ ret = -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ wg->advanced_security_config.advanced_security_enabled = a_sec_on;
|
||||
+out:
|
||||
+ return ret;
|
||||
}
|
||||
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/device.h ./device.h
|
||||
--- ../../linux-source-6.2.0/drivers/net/wireguard/device.h 2023-11-10 18:10:29
|
||||
+++ ./device.h 2023-11-23 18:48:52
|
||||
@@ -37,6 +37,19 @@
|
||||
atomic_t count;
|
||||
};
|
||||
|
||||
+struct amnezia_config {
|
||||
+ bool advanced_security_enabled;
|
||||
+ u16 junk_packet_count;
|
||||
+ u16 junk_packet_min_size;
|
||||
+ u16 junk_packet_max_size;
|
||||
+ u16 init_packet_junk_size;
|
||||
+ u16 response_packet_junk_size;
|
||||
+ u32 init_packet_magic_header;
|
||||
+ u32 response_packet_magic_header;
|
||||
+ u32 cookie_packet_magic_header;
|
||||
+ u32 transport_packet_magic_header;
|
||||
+};
|
||||
+
|
||||
struct wg_device {
|
||||
struct net_device *dev;
|
||||
struct crypt_queue encrypt_queue, decrypt_queue, handshake_queue;
|
||||
@@ -50,6 +63,7 @@
|
||||
struct allowedips peer_allowedips;
|
||||
struct mutex device_update_lock, socket_update_lock;
|
||||
struct list_head device_list, peer_list;
|
||||
+ struct amnezia_config advanced_security_config;
|
||||
atomic_t handshake_queue_len;
|
||||
unsigned int num_peers, device_update_gen;
|
||||
u32 fwmark;
|
||||
@@ -58,5 +72,6 @@
|
||||
|
||||
int wg_device_init(void);
|
||||
void wg_device_uninit(void);
|
||||
+int wg_device_handle_post_config(struct net_device *dev, struct amnezia_config *asc);
|
||||
|
||||
#endif /* _WG_DEVICE_H */
|
||||
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/main.c ./main.c
|
||||
--- ../../linux-source-6.2.0/drivers/net/wireguard/main.c 2023-11-10 18:10:29
|
||||
+++ ./main.c 2023-11-22 16:37:56
|
||||
@@ -3,14 +3,13 @@
|
||||
* Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||
*/
|
||||
|
||||
-#include "version.h"
|
||||
#include "device.h"
|
||||
#include "noise.h"
|
||||
#include "queueing.h"
|
||||
#include "ratelimiter.h"
|
||||
#include "netlink.h"
|
||||
|
||||
-#include <uapi/linux/wireguard.h>
|
||||
+#include "uapi/wireguard.h"
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
@@ -45,7 +44,7 @@
|
||||
if (ret < 0)
|
||||
goto err_netlink;
|
||||
|
||||
- pr_info("WireGuard " WIREGUARD_VERSION " loaded. See www.wireguard.com for information.\n");
|
||||
+ pr_info("WireGuard " WIREGUARD_VERSION " (Amnezia VPN) loaded. See www.wireguard.com for information.\n");
|
||||
pr_info("Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.\n");
|
||||
|
||||
return 0;
|
||||
@@ -71,7 +70,7 @@
|
||||
module_init(wg_mod_init);
|
||||
module_exit(wg_mod_exit);
|
||||
MODULE_LICENSE("GPL v2");
|
||||
-MODULE_DESCRIPTION("WireGuard secure network tunnel");
|
||||
+MODULE_DESCRIPTION("WireGuard (Amnezia VPN) secure network tunnel");
|
||||
MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");
|
||||
MODULE_VERSION(WIREGUARD_VERSION);
|
||||
MODULE_ALIAS_RTNL_LINK(KBUILD_MODNAME);
|
||||
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/messages.h ./messages.h
|
||||
--- ../../linux-source-6.2.0/drivers/net/wireguard/messages.h 2023-11-10 18:10:29
|
||||
+++ ./messages.h 2023-11-22 19:16:03
|
||||
@@ -117,6 +117,14 @@
|
||||
MESSAGE_MINIMUM_LENGTH = message_data_len(0)
|
||||
};
|
||||
|
||||
+enum message_size {
|
||||
+ MESSAGE_INITIATION_SIZE = sizeof(struct message_handshake_initiation),
|
||||
+ MESSAGE_RESPONSE_SIZE = sizeof(struct message_handshake_response),
|
||||
+ MESSAGE_COOKIE_REPLY_SIZE = sizeof(struct message_handshake_cookie),
|
||||
+ MESSAGE_TRANSPORT_SIZE = sizeof(struct message_data),
|
||||
+ MESSAGE_MAX_SIZE = 65535
|
||||
+};
|
||||
+
|
||||
#define SKB_HEADER_LEN \
|
||||
(max(sizeof(struct iphdr), sizeof(struct ipv6hdr)) + \
|
||||
sizeof(struct udphdr) + NET_SKB_PAD)
|
||||
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/netlink.c ./netlink.c
|
||||
--- ../../linux-source-6.2.0/drivers/net/wireguard/netlink.c 2023-11-10 18:10:29
|
||||
+++ ./netlink.c 2023-11-26 17:34:30
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "queueing.h"
|
||||
#include "messages.h"
|
||||
|
||||
-#include <uapi/linux/wireguard.h>
|
||||
+#include "uapi/wireguard.h"
|
||||
|
||||
#include <linux/if.h>
|
||||
#include <net/genetlink.h>
|
||||
@@ -27,7 +27,16 @@
|
||||
[WGDEVICE_A_FLAGS] = { .type = NLA_U32 },
|
||||
[WGDEVICE_A_LISTEN_PORT] = { .type = NLA_U16 },
|
||||
[WGDEVICE_A_FWMARK] = { .type = NLA_U32 },
|
||||
- [WGDEVICE_A_PEERS] = { .type = NLA_NESTED }
|
||||
+ [WGDEVICE_A_PEERS] = { .type = NLA_NESTED },
|
||||
+ [WGDEVICE_A_JC] = { .type = NLA_U16 },
|
||||
+ [WGDEVICE_A_JMIN] = { .type = NLA_U16 },
|
||||
+ [WGDEVICE_A_JMAX] = { .type = NLA_U16 },
|
||||
+ [WGDEVICE_A_S1] = { .type = NLA_U16 },
|
||||
+ [WGDEVICE_A_S2] = { .type = NLA_U16 },
|
||||
+ [WGDEVICE_A_H1] = { .type = NLA_U32 },
|
||||
+ [WGDEVICE_A_H2] = { .type = NLA_U32 },
|
||||
+ [WGDEVICE_A_H3] = { .type = NLA_U32 },
|
||||
+ [WGDEVICE_A_H4] = { .type = NLA_U32 }
|
||||
};
|
||||
|
||||
static const struct nla_policy peer_policy[WGPEER_A_MAX + 1] = {
|
||||
@@ -233,7 +242,25 @@
|
||||
wg->incoming_port) ||
|
||||
nla_put_u32(skb, WGDEVICE_A_FWMARK, wg->fwmark) ||
|
||||
nla_put_u32(skb, WGDEVICE_A_IFINDEX, wg->dev->ifindex) ||
|
||||
- nla_put_string(skb, WGDEVICE_A_IFNAME, wg->dev->name))
|
||||
+ nla_put_string(skb, WGDEVICE_A_IFNAME, wg->dev->name) ||
|
||||
+ nla_put_u16(skb, WGDEVICE_A_JC,
|
||||
+ wg->advanced_security_config.junk_packet_count) ||
|
||||
+ nla_put_u16(skb, WGDEVICE_A_JMIN,
|
||||
+ wg->advanced_security_config.junk_packet_min_size) ||
|
||||
+ nla_put_u16(skb, WGDEVICE_A_JMAX,
|
||||
+ wg->advanced_security_config.junk_packet_max_size) ||
|
||||
+ nla_put_u16(skb, WGDEVICE_A_S1,
|
||||
+ wg->advanced_security_config.init_packet_junk_size) ||
|
||||
+ nla_put_u16(skb, WGDEVICE_A_S2,
|
||||
+ wg->advanced_security_config.response_packet_junk_size) ||
|
||||
+ nla_put_u32(skb, WGDEVICE_A_H1,
|
||||
+ wg->advanced_security_config.init_packet_magic_header) ||
|
||||
+ nla_put_u32(skb, WGDEVICE_A_H2,
|
||||
+ wg->advanced_security_config.response_packet_magic_header) ||
|
||||
+ nla_put_u32(skb, WGDEVICE_A_H3,
|
||||
+ wg->advanced_security_config.cookie_packet_magic_header) ||
|
||||
+ nla_put_u32(skb, WGDEVICE_A_H4,
|
||||
+ wg->advanced_security_config.transport_packet_magic_header))
|
||||
goto out;
|
||||
|
||||
down_read(&wg->static_identity.lock);
|
||||
@@ -493,6 +520,7 @@
|
||||
static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct wg_device *wg = lookup_interface(info->attrs, skb);
|
||||
+ struct amnezia_config *asc = kzalloc(sizeof(*asc), GFP_KERNEL);
|
||||
u32 flags = 0;
|
||||
int ret;
|
||||
|
||||
@@ -537,6 +565,51 @@
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ if (info->attrs[WGDEVICE_A_JC]) {
|
||||
+ asc->advanced_security_enabled = true;
|
||||
+ asc->junk_packet_count = nla_get_u16(info->attrs[WGDEVICE_A_JC]);
|
||||
+ }
|
||||
+
|
||||
+ if (info->attrs[WGDEVICE_A_JMIN]) {
|
||||
+ asc->advanced_security_enabled = true;
|
||||
+ asc->junk_packet_min_size = nla_get_u16(info->attrs[WGDEVICE_A_JMIN]);
|
||||
+ }
|
||||
+
|
||||
+ if (info->attrs[WGDEVICE_A_JMAX]) {
|
||||
+ asc->advanced_security_enabled = true;
|
||||
+ asc->junk_packet_max_size = nla_get_u16(info->attrs[WGDEVICE_A_JMAX]);
|
||||
+ }
|
||||
+
|
||||
+ if (info->attrs[WGDEVICE_A_S1]) {
|
||||
+ asc->advanced_security_enabled = true;
|
||||
+ asc->init_packet_junk_size = nla_get_u16(info->attrs[WGDEVICE_A_S1]);
|
||||
+ }
|
||||
+
|
||||
+ if (info->attrs[WGDEVICE_A_S2]) {
|
||||
+ asc->advanced_security_enabled = true;
|
||||
+ asc->response_packet_junk_size = nla_get_u16(info->attrs[WGDEVICE_A_S2]);
|
||||
+ }
|
||||
+
|
||||
+ if (info->attrs[WGDEVICE_A_H1]) {
|
||||
+ asc->advanced_security_enabled = true;
|
||||
+ asc->init_packet_magic_header = nla_get_u32(info->attrs[WGDEVICE_A_H1]);
|
||||
+ }
|
||||
+
|
||||
+ if (info->attrs[WGDEVICE_A_H2]) {
|
||||
+ asc->advanced_security_enabled = true;
|
||||
+ asc->response_packet_magic_header = nla_get_u32(info->attrs[WGDEVICE_A_H2]);
|
||||
+ }
|
||||
+
|
||||
+ if (info->attrs[WGDEVICE_A_H3]) {
|
||||
+ asc->advanced_security_enabled = true;
|
||||
+ asc->cookie_packet_magic_header = nla_get_u32(info->attrs[WGDEVICE_A_H3]);
|
||||
+ }
|
||||
+
|
||||
+ if (info->attrs[WGDEVICE_A_H4]) {
|
||||
+ asc->advanced_security_enabled = true;
|
||||
+ asc->transport_packet_magic_header = nla_get_u32(info->attrs[WGDEVICE_A_H4]);
|
||||
+ }
|
||||
+
|
||||
if (flags & WGDEVICE_F_REPLACE_PEERS)
|
||||
wg_peer_remove_all(wg);
|
||||
|
||||
@@ -597,10 +670,14 @@
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
+ if (!ret)
|
||||
+ ret = wg_device_handle_post_config(wg->dev, asc);
|
||||
+
|
||||
mutex_unlock(&wg->device_update_lock);
|
||||
rtnl_unlock();
|
||||
dev_put(wg->dev);
|
||||
out_nodev:
|
||||
+ kfree(asc);
|
||||
if (info->attrs[WGDEVICE_A_PRIVATE_KEY])
|
||||
memzero_explicit(nla_data(info->attrs[WGDEVICE_A_PRIVATE_KEY]),
|
||||
nla_len(info->attrs[WGDEVICE_A_PRIVATE_KEY]));
|
||||
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/noise.c ./noise.c
|
||||
--- ../../linux-source-6.2.0/drivers/net/wireguard/noise.c 2023-11-10 18:10:29
|
||||
+++ ./noise.c 2023-11-23 18:58:26
|
||||
@@ -515,7 +515,7 @@
|
||||
|
||||
bool
|
||||
wg_noise_handshake_create_initiation(struct message_handshake_initiation *dst,
|
||||
- struct noise_handshake *handshake)
|
||||
+ struct noise_handshake *handshake, u32 message_type)
|
||||
{
|
||||
u8 timestamp[NOISE_TIMESTAMP_LEN];
|
||||
u8 key[NOISE_SYMMETRIC_KEY_LEN];
|
||||
@@ -532,7 +532,7 @@
|
||||
if (unlikely(!handshake->static_identity->has_identity))
|
||||
goto out;
|
||||
|
||||
- dst->header.type = cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION);
|
||||
+ dst->header.type = cpu_to_le32(message_type);
|
||||
|
||||
handshake_init(handshake->chaining_key, handshake->hash,
|
||||
handshake->remote_static);
|
||||
@@ -665,7 +665,7 @@
|
||||
}
|
||||
|
||||
bool wg_noise_handshake_create_response(struct message_handshake_response *dst,
|
||||
- struct noise_handshake *handshake)
|
||||
+ struct noise_handshake *handshake, u32 message_type)
|
||||
{
|
||||
u8 key[NOISE_SYMMETRIC_KEY_LEN];
|
||||
bool ret = false;
|
||||
@@ -681,7 +681,7 @@
|
||||
if (handshake->state != HANDSHAKE_CONSUMED_INITIATION)
|
||||
goto out;
|
||||
|
||||
- dst->header.type = cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE);
|
||||
+ dst->header.type = cpu_to_le32(message_type);
|
||||
dst->receiver_index = handshake->remote_index;
|
||||
|
||||
/* e */
|
||||
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/noise.h ./noise.h
|
||||
--- ../../linux-source-6.2.0/drivers/net/wireguard/noise.h 2023-11-10 18:10:29
|
||||
+++ ./noise.h 2023-11-23 13:12:55
|
||||
@@ -118,13 +118,13 @@
|
||||
|
||||
bool
|
||||
wg_noise_handshake_create_initiation(struct message_handshake_initiation *dst,
|
||||
- struct noise_handshake *handshake);
|
||||
+ struct noise_handshake *handshake, u32 message_type);
|
||||
struct wg_peer *
|
||||
wg_noise_handshake_consume_initiation(struct message_handshake_initiation *src,
|
||||
struct wg_device *wg);
|
||||
|
||||
bool wg_noise_handshake_create_response(struct message_handshake_response *dst,
|
||||
- struct noise_handshake *handshake);
|
||||
+ struct noise_handshake *handshake, u32 message_type);
|
||||
struct wg_peer *
|
||||
wg_noise_handshake_consume_response(struct message_handshake_response *src,
|
||||
struct wg_device *wg);
|
||||
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/receive.c ./receive.c
|
||||
--- ../../linux-source-6.2.0/drivers/net/wireguard/receive.c 2023-11-10 18:10:29
|
||||
+++ ./receive.c 2023-11-23 19:15:51
|
||||
@@ -25,25 +25,51 @@
|
||||
|
||||
#define SKB_TYPE_LE32(skb) (((struct message_header *)(skb)->data)->type)
|
||||
|
||||
-static size_t validate_header_len(struct sk_buff *skb)
|
||||
+static size_t validate_header_len(struct sk_buff *skb, struct wg_device *wg)
|
||||
{
|
||||
if (unlikely(skb->len < sizeof(struct message_header)))
|
||||
return 0;
|
||||
- if (SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_DATA) &&
|
||||
+ if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.transport_packet_magic_header) &&
|
||||
skb->len >= MESSAGE_MINIMUM_LENGTH)
|
||||
return sizeof(struct message_data);
|
||||
- if (SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION) &&
|
||||
- skb->len == sizeof(struct message_handshake_initiation))
|
||||
- return sizeof(struct message_handshake_initiation);
|
||||
- if (SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE) &&
|
||||
- skb->len == sizeof(struct message_handshake_response))
|
||||
- return sizeof(struct message_handshake_response);
|
||||
- if (SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE) &&
|
||||
- skb->len == sizeof(struct message_handshake_cookie))
|
||||
- return sizeof(struct message_handshake_cookie);
|
||||
+ if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.init_packet_magic_header) &&
|
||||
+ skb->len == MESSAGE_INITIATION_SIZE)
|
||||
+ return MESSAGE_INITIATION_SIZE;
|
||||
+ if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.response_packet_magic_header) &&
|
||||
+ skb->len == MESSAGE_RESPONSE_SIZE)
|
||||
+ return MESSAGE_RESPONSE_SIZE;
|
||||
+ if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.cookie_packet_magic_header) &&
|
||||
+ skb->len == MESSAGE_COOKIE_REPLY_SIZE)
|
||||
+ return MESSAGE_COOKIE_REPLY_SIZE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
+void prepare_advanced_secured_message(struct sk_buff *skb, struct wg_device *wg)
|
||||
+{
|
||||
+ u32 assumed_type = SKB_TYPE_LE32(skb);
|
||||
+ u32 assumed_offset;
|
||||
+
|
||||
+ if (wg->advanced_security_config.advanced_security_enabled) {
|
||||
+ if (skb->len == MESSAGE_INITIATION_SIZE + wg->advanced_security_config.init_packet_junk_size) {
|
||||
+ assumed_type = cpu_to_le32(wg->advanced_security_config.init_packet_magic_header);
|
||||
+ assumed_offset = wg->advanced_security_config.init_packet_junk_size;
|
||||
+ } else if (skb->len == MESSAGE_RESPONSE_SIZE + wg->advanced_security_config.response_packet_junk_size) {
|
||||
+ assumed_type = cpu_to_le32(wg->advanced_security_config.response_packet_magic_header);
|
||||
+ assumed_offset = wg->advanced_security_config.response_packet_junk_size;
|
||||
+ } else
|
||||
+ return;
|
||||
+
|
||||
+ if (unlikely(assumed_offset <= 0) || unlikely(!pskb_may_pull(skb, assumed_offset)))
|
||||
+ return;
|
||||
+
|
||||
+ skb_pull(skb, assumed_offset);
|
||||
+
|
||||
+ if (SKB_TYPE_LE32(skb) != assumed_type) {
|
||||
+ skb_push(skb, assumed_offset);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int prepare_skb_header(struct sk_buff *skb, struct wg_device *wg)
|
||||
{
|
||||
size_t data_offset, data_len, header_len;
|
||||
@@ -79,7 +105,8 @@
|
||||
if (unlikely(skb->len != data_len))
|
||||
/* Final len does not agree with calculated len */
|
||||
return -EINVAL;
|
||||
- header_len = validate_header_len(skb);
|
||||
+ prepare_advanced_secured_message(skb, wg);
|
||||
+ header_len = validate_header_len(skb, wg);
|
||||
if (unlikely(!header_len))
|
||||
return -EINVAL;
|
||||
__skb_push(skb, data_offset);
|
||||
@@ -101,7 +128,7 @@
|
||||
bool packet_needs_cookie;
|
||||
bool under_load;
|
||||
|
||||
- if (SKB_TYPE_LE32(skb) == cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE)) {
|
||||
+ if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.cookie_packet_magic_header)) {
|
||||
net_dbg_skb_ratelimited("%s: Receiving cookie response from %pISpfsc\n",
|
||||
wg->dev->name, skb);
|
||||
wg_cookie_message_consume(
|
||||
@@ -131,8 +158,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
- switch (SKB_TYPE_LE32(skb)) {
|
||||
- case cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION): {
|
||||
+ if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.init_packet_magic_header)) {
|
||||
struct message_handshake_initiation *message =
|
||||
(struct message_handshake_initiation *)skb->data;
|
||||
|
||||
@@ -152,9 +178,8 @@
|
||||
wg->dev->name, peer->internal_id,
|
||||
&peer->endpoint.addr);
|
||||
wg_packet_send_handshake_response(peer);
|
||||
- break;
|
||||
}
|
||||
- case cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE): {
|
||||
+ if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.response_packet_magic_header)) {
|
||||
struct message_handshake_response *message =
|
||||
(struct message_handshake_response *)skb->data;
|
||||
|
||||
@@ -185,9 +210,7 @@
|
||||
*/
|
||||
wg_packet_send_keepalive(peer);
|
||||
}
|
||||
- break;
|
||||
}
|
||||
- }
|
||||
|
||||
if (unlikely(!peer)) {
|
||||
WARN(1, "Somehow a wrong type of packet wound up in the handshake queue!\n");
|
||||
@@ -543,10 +566,10 @@
|
||||
{
|
||||
if (unlikely(prepare_skb_header(skb, wg) < 0))
|
||||
goto err;
|
||||
- switch (SKB_TYPE_LE32(skb)) {
|
||||
- case cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION):
|
||||
- case cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE):
|
||||
- case cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE): {
|
||||
+
|
||||
+ if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.init_packet_magic_header) ||
|
||||
+ SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.response_packet_magic_header) ||
|
||||
+ SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.cookie_packet_magic_header)) {
|
||||
int cpu, ret = -EBUSY;
|
||||
|
||||
if (unlikely(!rng_is_initialized()))
|
||||
@@ -559,23 +582,20 @@
|
||||
} else
|
||||
ret = ptr_ring_produce_bh(&wg->handshake_queue.ring, skb);
|
||||
if (ret) {
|
||||
- drop:
|
||||
+drop:
|
||||
net_dbg_skb_ratelimited("%s: Dropping handshake packet from %pISpfsc\n",
|
||||
- wg->dev->name, skb);
|
||||
+ wg->dev->name, skb);
|
||||
goto err;
|
||||
}
|
||||
atomic_inc(&wg->handshake_queue_len);
|
||||
cpu = wg_cpumask_next_online(&wg->handshake_queue.last_cpu);
|
||||
/* Queues up a call to packet_process_queued_handshake_packets(skb): */
|
||||
queue_work_on(cpu, wg->handshake_receive_wq,
|
||||
- &per_cpu_ptr(wg->handshake_queue.worker, cpu)->work);
|
||||
- break;
|
||||
- }
|
||||
- case cpu_to_le32(MESSAGE_DATA):
|
||||
+ &per_cpu_ptr(wg->handshake_queue.worker, cpu)->work);
|
||||
+ } else if (SKB_TYPE_LE32(skb) == cpu_to_le32(wg->advanced_security_config.transport_packet_magic_header)) {
|
||||
PACKET_CB(skb)->ds = ip_tunnel_get_dsfield(ip_hdr(skb), skb);
|
||||
wg_packet_consume_data(wg, skb);
|
||||
- break;
|
||||
- default:
|
||||
+ } else {
|
||||
WARN(1, "Non-exhaustive parsing of packet header lead to unknown packet type!\n");
|
||||
goto err;
|
||||
}
|
||||
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/send.c ./send.c
|
||||
--- ../../linux-source-6.2.0/drivers/net/wireguard/send.c 2023-11-10 18:10:29
|
||||
+++ ./send.c 2023-11-24 18:25:50
|
||||
@@ -14,13 +14,24 @@
|
||||
#include <linux/uio.h>
|
||||
#include <linux/inetdevice.h>
|
||||
#include <linux/socket.h>
|
||||
+#include <linux/random.h>
|
||||
#include <net/ip_tunnels.h>
|
||||
#include <net/udp.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
+u32 wg_get_random_u32_inclusive(u32 floor, u32 ceil)
|
||||
+{
|
||||
+ u32 diff = ceil - floor + 1;
|
||||
+ return floor + (get_random_u32() % diff);
|
||||
+}
|
||||
+
|
||||
static void wg_packet_send_handshake_initiation(struct wg_peer *peer)
|
||||
{
|
||||
struct message_handshake_initiation packet;
|
||||
+ struct wg_device *wg = peer->device;
|
||||
+ void *buffer;
|
||||
+ u8 ds;
|
||||
+ u16 junk_packet_count, junk_packet_size;
|
||||
|
||||
if (!wg_birthdate_has_expired(atomic64_read(&peer->last_sent_handshake),
|
||||
REKEY_TIMEOUT))
|
||||
@@ -31,14 +42,37 @@
|
||||
peer->device->dev->name, peer->internal_id,
|
||||
&peer->endpoint.addr);
|
||||
|
||||
- if (wg_noise_handshake_create_initiation(&packet, &peer->handshake)) {
|
||||
+ if (wg->advanced_security_config.advanced_security_enabled) {
|
||||
+ junk_packet_count = wg->advanced_security_config.junk_packet_count;
|
||||
+ buffer = kzalloc(wg->advanced_security_config.junk_packet_max_size, GFP_KERNEL);
|
||||
+
|
||||
+ while (junk_packet_count-- > 0) {
|
||||
+ junk_packet_size = (u16) wg_get_random_u32_inclusive(
|
||||
+ wg->advanced_security_config.junk_packet_min_size,
|
||||
+ wg->advanced_security_config.junk_packet_max_size);
|
||||
+
|
||||
+ get_random_bytes(buffer, junk_packet_size);
|
||||
+ get_random_bytes(&ds, 1);
|
||||
+ wg_socket_send_buffer_to_peer(peer, buffer, junk_packet_size, ds);
|
||||
+ }
|
||||
+
|
||||
+ kfree(buffer);
|
||||
+ }
|
||||
+
|
||||
+ if (wg_noise_handshake_create_initiation(&packet, &peer->handshake, wg->advanced_security_config.init_packet_magic_header)) {
|
||||
wg_cookie_add_mac_to_packet(&packet, sizeof(packet), peer);
|
||||
wg_timers_any_authenticated_packet_traversal(peer);
|
||||
wg_timers_any_authenticated_packet_sent(peer);
|
||||
atomic64_set(&peer->last_sent_handshake,
|
||||
ktime_get_coarse_boottime_ns());
|
||||
- wg_socket_send_buffer_to_peer(peer, &packet, sizeof(packet),
|
||||
- HANDSHAKE_DSCP);
|
||||
+
|
||||
+ if (wg->advanced_security_config.advanced_security_enabled) {
|
||||
+ wg_socket_send_junked_buffer_to_peer(peer, &packet, sizeof(packet),
|
||||
+ HANDSHAKE_DSCP, wg->advanced_security_config.init_packet_junk_size);
|
||||
+ } else {
|
||||
+ wg_socket_send_buffer_to_peer(peer, &packet, sizeof(packet),
|
||||
+ HANDSHAKE_DSCP);
|
||||
+ }
|
||||
wg_timers_handshake_initiated(peer);
|
||||
}
|
||||
}
|
||||
@@ -85,13 +119,14 @@
|
||||
void wg_packet_send_handshake_response(struct wg_peer *peer)
|
||||
{
|
||||
struct message_handshake_response packet;
|
||||
+ struct wg_device *wg = peer->device;
|
||||
|
||||
atomic64_set(&peer->last_sent_handshake, ktime_get_coarse_boottime_ns());
|
||||
net_dbg_ratelimited("%s: Sending handshake response to peer %llu (%pISpfsc)\n",
|
||||
peer->device->dev->name, peer->internal_id,
|
||||
&peer->endpoint.addr);
|
||||
|
||||
- if (wg_noise_handshake_create_response(&packet, &peer->handshake)) {
|
||||
+ if (wg_noise_handshake_create_response(&packet, &peer->handshake, wg->advanced_security_config.response_packet_magic_header)) {
|
||||
wg_cookie_add_mac_to_packet(&packet, sizeof(packet), peer);
|
||||
if (wg_noise_handshake_begin_session(&peer->handshake,
|
||||
&peer->keypairs)) {
|
||||
@@ -100,9 +135,16 @@
|
||||
wg_timers_any_authenticated_packet_sent(peer);
|
||||
atomic64_set(&peer->last_sent_handshake,
|
||||
ktime_get_coarse_boottime_ns());
|
||||
- wg_socket_send_buffer_to_peer(peer, &packet,
|
||||
- sizeof(packet),
|
||||
- HANDSHAKE_DSCP);
|
||||
+ if (wg->advanced_security_config.advanced_security_enabled) {
|
||||
+ wg_socket_send_junked_buffer_to_peer(peer, &packet,
|
||||
+ sizeof(packet),
|
||||
+ HANDSHAKE_DSCP,
|
||||
+ wg->advanced_security_config.response_packet_junk_size);
|
||||
+ } else {
|
||||
+ wg_socket_send_buffer_to_peer(peer, &packet,
|
||||
+ sizeof(packet),
|
||||
+ HANDSHAKE_DSCP);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,7 +158,7 @@
|
||||
net_dbg_skb_ratelimited("%s: Sending cookie response for denied handshake message for %pISpfsc\n",
|
||||
wg->dev->name, initiating_skb);
|
||||
wg_cookie_message_create(&packet, initiating_skb, sender_index,
|
||||
- &wg->cookie_checker);
|
||||
+ &wg->cookie_checker, wg->advanced_security_config.cookie_packet_magic_header);
|
||||
wg_socket_send_buffer_as_reply_to_skb(wg, initiating_skb, &packet,
|
||||
sizeof(packet));
|
||||
}
|
||||
@@ -159,7 +201,7 @@
|
||||
return padded_size - last_unit;
|
||||
}
|
||||
|
||||
-static bool encrypt_packet(struct sk_buff *skb, struct noise_keypair *keypair)
|
||||
+static bool encrypt_packet(struct sk_buff *skb, struct noise_keypair *keypair, u32 message_type)
|
||||
{
|
||||
unsigned int padding_len, plaintext_len, trailer_len;
|
||||
struct scatterlist sg[MAX_SKB_FRAGS + 8];
|
||||
@@ -203,7 +245,7 @@
|
||||
*/
|
||||
skb_set_inner_network_header(skb, 0);
|
||||
header = (struct message_data *)skb_push(skb, sizeof(*header));
|
||||
- header->header.type = cpu_to_le32(MESSAGE_DATA);
|
||||
+ header->header.type = cpu_to_le32(message_type);
|
||||
header->key_idx = keypair->remote_index;
|
||||
header->counter = cpu_to_le64(PACKET_CB(skb)->nonce);
|
||||
pskb_put(skb, trailer, trailer_len);
|
||||
@@ -289,13 +331,17 @@
|
||||
struct crypt_queue *queue = container_of(work, struct multicore_worker,
|
||||
work)->ptr;
|
||||
struct sk_buff *first, *skb, *next;
|
||||
+ struct wg_device *wg;
|
||||
|
||||
while ((first = ptr_ring_consume_bh(&queue->ring)) != NULL) {
|
||||
enum packet_state state = PACKET_STATE_CRYPTED;
|
||||
|
||||
skb_list_walk_safe(first, skb, next) {
|
||||
+ wg = PACKET_PEER(first)->device;
|
||||
+
|
||||
if (likely(encrypt_packet(skb,
|
||||
- PACKET_CB(first)->keypair))) {
|
||||
+ PACKET_CB(first)->keypair,
|
||||
+ wg->advanced_security_config.transport_packet_magic_header))) {
|
||||
wg_reset_packet(skb, true);
|
||||
} else {
|
||||
state = PACKET_STATE_DEAD;
|
||||
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/socket.c ./socket.c
|
||||
--- ../../linux-source-6.2.0/drivers/net/wireguard/socket.c 2023-11-10 18:10:29
|
||||
+++ ./socket.c 2023-11-23 15:45:07
|
||||
@@ -200,6 +200,18 @@
|
||||
return wg_socket_send_skb_to_peer(peer, skb, ds);
|
||||
}
|
||||
|
||||
+int wg_socket_send_junked_buffer_to_peer(struct wg_peer *peer, void *buffer,
|
||||
+ size_t len, u8 ds, u16 junk_size)
|
||||
+{
|
||||
+ int ret;
|
||||
+ void *new_buffer = kzalloc(len + junk_size, GFP_KERNEL);
|
||||
+ get_random_bytes(new_buffer, junk_size);
|
||||
+ memcpy(new_buffer + junk_size, buffer, len);
|
||||
+ ret = wg_socket_send_buffer_to_peer(peer, new_buffer, len + junk_size, ds);
|
||||
+ kfree(new_buffer);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
int wg_socket_send_buffer_as_reply_to_skb(struct wg_device *wg,
|
||||
struct sk_buff *in_skb, void *buffer,
|
||||
size_t len)
|
||||
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/socket.h ./socket.h
|
||||
--- ../../linux-source-6.2.0/drivers/net/wireguard/socket.h 2023-11-10 18:10:29
|
||||
+++ ./socket.h 2023-11-23 13:20:24
|
||||
@@ -16,6 +16,8 @@
|
||||
struct sock *new6);
|
||||
int wg_socket_send_buffer_to_peer(struct wg_peer *peer, void *data,
|
||||
size_t len, u8 ds);
|
||||
+int wg_socket_send_junked_buffer_to_peer(struct wg_peer *peer, void *data,
|
||||
+ size_t len, u8 ds, u16 junk_size);
|
||||
int wg_socket_send_skb_to_peer(struct wg_peer *peer, struct sk_buff *skb,
|
||||
u8 ds);
|
||||
int wg_socket_send_buffer_as_reply_to_skb(struct wg_device *wg,
|
||||
diff --color -urN -x uapi -x compat -x crypto -x .idea -x tests -x Kbuild -x Kconfig -x Makefile -x dkms.conf ../../linux-source-6.2.0/drivers/net/wireguard/version.h ./version.h
|
||||
--- ../../linux-source-6.2.0/drivers/net/wireguard/version.h 2023-11-10 18:10:29
|
||||
+++ ./version.h 1970-01-01 02:00:00
|
||||
@@ -1 +0,0 @@
|
||||
-#define WIREGUARD_VERSION "1.0.0"
|
||||
@@ -1,27 +0,0 @@
|
||||
--- ../../linux-source-6.2.0/include/uapi/linux/wireguard.h 2023-09-23 12:11:13
|
||||
+++ ./uapi/wireguard.h 2023-11-28 16:12:36
|
||||
@@ -131,7 +131,7 @@
|
||||
#ifndef _WG_UAPI_WIREGUARD_H
|
||||
#define _WG_UAPI_WIREGUARD_H
|
||||
|
||||
-#define WG_GENL_NAME "wireguard"
|
||||
+#define WG_GENL_NAME "amneziawg"
|
||||
#define WG_GENL_VERSION 1
|
||||
|
||||
#define WG_KEY_LEN 32
|
||||
@@ -157,6 +157,15 @@
|
||||
WGDEVICE_A_LISTEN_PORT,
|
||||
WGDEVICE_A_FWMARK,
|
||||
WGDEVICE_A_PEERS,
|
||||
+ WGDEVICE_A_JC,
|
||||
+ WGDEVICE_A_JMIN,
|
||||
+ WGDEVICE_A_JMAX,
|
||||
+ WGDEVICE_A_S1,
|
||||
+ WGDEVICE_A_S2,
|
||||
+ WGDEVICE_A_H1,
|
||||
+ WGDEVICE_A_H2,
|
||||
+ WGDEVICE_A_H3,
|
||||
+ WGDEVICE_A_H4,
|
||||
__WGDEVICE_A_LAST
|
||||
};
|
||||
#define WGDEVICE_A_MAX (__WGDEVICE_A_LAST - 1)
|
||||
@@ -1,20 +0,0 @@
|
||||
WIREGUARD_VERSION = 1.0.0-awg
|
||||
|
||||
ccflags-y := -D'pr_fmt(fmt)=KBUILD_MODNAME ": " fmt'
|
||||
ccflags-y += -D'WIREGUARD_VERSION="$(WIREGUARD_VERSION)"'
|
||||
# ccflags-y += -DDEBUG
|
||||
amneziawg-y := main.o
|
||||
amneziawg-y += noise.o
|
||||
amneziawg-y += device.o
|
||||
amneziawg-y += peer.o
|
||||
amneziawg-y += timers.o
|
||||
amneziawg-y += queueing.o
|
||||
amneziawg-y += send.o
|
||||
amneziawg-y += receive.o
|
||||
amneziawg-y += socket.o
|
||||
amneziawg-y += peerlookup.o
|
||||
amneziawg-y += allowedips.o
|
||||
amneziawg-y += ratelimiter.o
|
||||
amneziawg-y += cookie.o
|
||||
amneziawg-y += netlink.o
|
||||
obj-m := amneziawg.o
|
||||
@@ -1,17 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2016 Dan Luedtke <mail@danrl.com>
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=Support for AmneziaWG VPN
|
||||
LUCI_DEPENDS:=+amneziawg-tools +ucode +qrencode
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
PKG_PROVIDES:=luci-app-amneziawg
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
13
luci-proto-amneziawg/Makefile
Normal file
13
luci-proto-amneziawg/Makefile
Normal file
@@ -0,0 +1,13 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=Support for AmneziaWG VPN
|
||||
LUCI_DESCRIPTION:=Provides support and Web UI for AmneziaWG VPN
|
||||
PKG_VERSION:=2.0.4
|
||||
LUCI_DEPENDS:=+amneziawg-tools +ucode +luci-lib-uqr +resolveip
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 38 KiB |
@@ -7,6 +7,7 @@
|
||||
'require form';
|
||||
'require network';
|
||||
'require validation';
|
||||
'require uqr';
|
||||
|
||||
var generateKey = rpc.declare({
|
||||
object: 'luci.amneziawg',
|
||||
@@ -64,42 +65,16 @@ function generateDescription(name, texts) {
|
||||
]);
|
||||
}
|
||||
|
||||
function invokeQREncode(data, div) {
|
||||
|
||||
var code = div.children[0];
|
||||
var btn = div.children[1];
|
||||
|
||||
dom.content(btn, [
|
||||
E('a', {
|
||||
'class': 'btn cbi-button-action',
|
||||
'style': 'text-align: center',
|
||||
'href': 'data:text/plain;charset=utf-8,' + encodeURIComponent(data),
|
||||
'download': 'amneziawg.conf'
|
||||
|
||||
}, ['Download Configuration']),
|
||||
]);
|
||||
|
||||
return fs.exec_direct('/usr/bin/qrencode', [
|
||||
'--inline', '--8bit', '--type=SVG',
|
||||
'--output=-', '--', data
|
||||
]).then(function(svg) {
|
||||
div.style.opacity = '';
|
||||
dom.content(code, Object.assign(E(svg), { style: 'width:100%;height:auto' }));
|
||||
}).catch(function(error) {
|
||||
div.style.opacity = '';
|
||||
|
||||
if (L.isObject(error) && error.name == 'NotFoundError') {
|
||||
dom.content(code, [
|
||||
Object.assign(E(qrIcon), { style: 'width:32px;height:32px;opacity:.2' }),
|
||||
E('p', _('The <em>qrencode</em> package is required for generating an QR code image of the configuration.'))
|
||||
]);
|
||||
}
|
||||
else {
|
||||
dom.content(code, [
|
||||
_('Unable to generate QR code: %s').format(L.isObject(error) ? error.message : error)
|
||||
]);
|
||||
}
|
||||
});
|
||||
function buildSVGQRCode(data, code) {
|
||||
// pixel size larger than 4 clips right and bottom edges of complex configs
|
||||
const options = {
|
||||
pixelSize: 4,
|
||||
whiteColor: 'white',
|
||||
blackColor: 'black'
|
||||
};
|
||||
const svg = uqr.renderSVG(data, options);
|
||||
code.style.opacity = '';
|
||||
dom.content(code, Object.assign(E(svg), { style: 'width:100%;height:auto' }));
|
||||
}
|
||||
|
||||
var cbiKeyPairGenerate = form.DummyValue.extend({
|
||||
@@ -111,9 +86,6 @@ var cbiKeyPairGenerate = form.DummyValue.extend({
|
||||
pub = this.section.getUIElement(section_id, 'public_key'),
|
||||
map = this.map;
|
||||
|
||||
if ((prv.getValue() || pub.getValue()) && !confirm(_('Do you want to replace the current keys?')))
|
||||
return;
|
||||
|
||||
return generateKey().then(function(keypair) {
|
||||
prv.setValue(keypair.priv);
|
||||
pub.setValue(keypair.pub);
|
||||
@@ -137,7 +109,7 @@ return network.registerProtocol('amneziawg', {
|
||||
return this._ubus('l3_device') || this.sid;
|
||||
},
|
||||
|
||||
getOpkgPackage: function() {
|
||||
getPackageName: function() {
|
||||
return 'amneziawg-tools';
|
||||
},
|
||||
|
||||
@@ -212,7 +184,7 @@ return network.registerProtocol('amneziawg', {
|
||||
o.placeholder = '1420';
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('advanced', form.Value, 'fwmark', _('Firewall Mark'), _('Optional. 32-bit mark for outgoing encrypted packets. Enter value in hex, starting with <code>0x</code>.'));
|
||||
o = s.taboption('advanced', form.Value, 'fwmark', _('Firewall Mark'), _('Optional. 32-bit mark for packets during firewall processing. Enter value in hex, starting with <code>0x</code>.'));
|
||||
o.optional = true;
|
||||
o.validate = function(section_id, value) {
|
||||
if (value.length > 0 && !value.match(/^0x[a-fA-F0-9]{1,8}$/))
|
||||
@@ -224,62 +196,102 @@ return network.registerProtocol('amneziawg', {
|
||||
// AmneziaWG
|
||||
|
||||
try {
|
||||
s.tab('amneziawg', _('AmneziaWG Settings'), _('Further information about AmneziaWG interfaces and peers at <a href=\'http://amnezia.org\'>amnezia.org</a>.'));
|
||||
s.tab('amneziawg', _('AmneziaWG Settings'), _('Further information about AmneziaWG interfaces and peers at <a href=\'https://docs.amnezia.org/documentation/amnezia-wg\'>amnezia.org</a>.'));
|
||||
}
|
||||
catch(e) {}
|
||||
|
||||
o = s.taboption('amneziawg', form.Value, 'awg_jc', _('Jc'), _('Junk packet count.'));
|
||||
o.datatype = 'uinteger';
|
||||
o.placeholder = '0';
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('amneziawg', form.Value, 'awg_jmin', _('Jmin'), _('Junk packet minimum size.'));
|
||||
o.datatype = 'uinteger';
|
||||
o.placeholder = '0';
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('amneziawg', form.Value, 'awg_jmax', _('Jmax'), _('Junk packet maximum size.'));
|
||||
o.datatype = 'uinteger';
|
||||
o.placeholder = '0';
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('amneziawg', form.Value, 'awg_s1', _('S1'), _('Handshake initiation packet junk header size.'));
|
||||
o.datatype = 'uinteger';
|
||||
o.placeholder = '0';
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('amneziawg', form.Value, 'awg_s2', _('S2'), _('Handshake response packet junk header size.'));
|
||||
o.datatype = 'uinteger';
|
||||
o.placeholder = '0';
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('amneziawg', form.Value, 'awg_s3', _('S3'), _('Cookie reply packet junk header size.'));
|
||||
o.datatype = 'uinteger';
|
||||
o.placeholder = '0';
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('amneziawg', form.Value, 'awg_s4', _('S4'), _('Transport packet junk header size.'));
|
||||
o.datatype = 'uinteger';
|
||||
o.placeholder = '0';
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('amneziawg', form.Value, 'awg_h1', _('H1'), _('Handshake initiation packet type header.'));
|
||||
o.datatype = 'uinteger';
|
||||
o.datatype = 'string';
|
||||
o.placeholder = '1';
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('amneziawg', form.Value, 'awg_h2', _('H2'), _('Handshake response packet type header.'));
|
||||
o.datatype = 'uinteger';
|
||||
o.datatype = 'string';
|
||||
o.placeholder = '2';
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('amneziawg', form.Value, 'awg_h3', _('H3'), _('Handshake cookie packet type header.'));
|
||||
o.datatype = 'uinteger';
|
||||
o.datatype = 'string';
|
||||
o.placeholder = '3';
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('amneziawg', form.Value, 'awg_h4', _('H4'), _('Transport packet type header.'));
|
||||
o.datatype = 'uinteger';
|
||||
o.datatype = 'string';
|
||||
o.placeholder = '4';
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('amneziawg', form.Value, 'awg_i1', _('I1'), _('First special junk packet signature.'));
|
||||
o.datatype = 'string';
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('amneziawg', form.Value, 'awg_i2', _('I2'), _('Second special junk packet signature.'));
|
||||
o.datatype = 'string';
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('amneziawg', form.Value, 'awg_i3', _('I3'), _('Third special junk packet signature.'));
|
||||
o.datatype = 'string';
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('amneziawg', form.Value, 'awg_i4', _('I4'), _('Fourth special junk packet signature.'));
|
||||
o.datatype = 'string';
|
||||
o.optional = true;
|
||||
|
||||
o = s.taboption('amneziawg', form.Value, 'awg_i5', _('I5'), _('Fifth special junk packet signature.'));
|
||||
o.datatype = 'string';
|
||||
o.optional = true;
|
||||
|
||||
// -- peers -----------------------------------------------------------------------
|
||||
|
||||
try {
|
||||
s.tab('peers', _('Peers'), _('Further information about AmneziaWG interfaces and peers at <a href=\'http://amneziawg.com\'>amneziawg.com</a>.'));
|
||||
s.tab('peers', _('Peers'), _('Further information about AmneziaWG interfaces and peers at <a href=\'https://docs.amnezia.org/documentation/amnezia-wg\'>amnezia.org</a>.'));
|
||||
}
|
||||
catch(e) {}
|
||||
|
||||
o = s.taboption('peers', form.SectionValue, '_peers', form.GridSection, 'amneziawg_%s'.format(s.section));
|
||||
o.depends('proto', 'amneziawg');
|
||||
|
||||
ss = o.subsection;
|
||||
ss = o.subsection;
|
||||
ss.anonymous = true;
|
||||
ss.addremove = true;
|
||||
ss.addbtntitle = _('Add peer');
|
||||
ss.nodescriptions = true;
|
||||
ss.modaltitle = _('Edit peer');
|
||||
ss.sortable = true;
|
||||
|
||||
ss.handleDragConfig = function(ev) {
|
||||
ev.stopPropagation();
|
||||
@@ -416,15 +428,22 @@ return network.registerProtocol('amneziawg', {
|
||||
s.getOption('public_key').getUIElement(s.section).setValue(keypair.pub);
|
||||
s.getOption('listen_port').getUIElement(s.section).setValue(config.interface_listenport || '');
|
||||
s.getOption('addresses').getUIElement(s.section).setValue(config.interface_address);
|
||||
s.getOption('awg_jc').getUIElement(s.section).setValue(config.interface_jc);
|
||||
s.getOption('awg_jmin').getUIElement(s.section).setValue(config.interface_jmin);
|
||||
s.getOption('awg_jmax').getUIElement(s.section).setValue(config.interface_jmax);
|
||||
s.getOption('awg_s1').getUIElement(s.section).setValue(config.interface_s1);
|
||||
s.getOption('awg_s2').getUIElement(s.section).setValue(config.interface_s2);
|
||||
s.getOption('awg_h1').getUIElement(s.section).setValue(config.interface_h1);
|
||||
s.getOption('awg_h2').getUIElement(s.section).setValue(config.interface_h2);
|
||||
s.getOption('awg_h3').getUIElement(s.section).setValue(config.interface_h3);
|
||||
s.getOption('awg_h4').getUIElement(s.section).setValue(config.interface_h4);
|
||||
s.getOption('awg_jc').getUIElement(s.section).setValue(config.interface_jc || '');
|
||||
s.getOption('awg_jmin').getUIElement(s.section).setValue(config.interface_jmin || '');
|
||||
s.getOption('awg_jmax').getUIElement(s.section).setValue(config.interface_jmax || '');
|
||||
s.getOption('awg_s1').getUIElement(s.section).setValue(config.interface_s1 || '');
|
||||
s.getOption('awg_s2').getUIElement(s.section).setValue(config.interface_s2 || '');
|
||||
s.getOption('awg_s3').getUIElement(s.section).setValue(config.interface_s3 || '');
|
||||
s.getOption('awg_s4').getUIElement(s.section).setValue(config.interface_s4 || '');
|
||||
s.getOption('awg_h1').getUIElement(s.section).setValue(config.interface_h1 || '');
|
||||
s.getOption('awg_h2').getUIElement(s.section).setValue(config.interface_h2 || '');
|
||||
s.getOption('awg_h3').getUIElement(s.section).setValue(config.interface_h3 || '');
|
||||
s.getOption('awg_h4').getUIElement(s.section).setValue(config.interface_h4 || '');
|
||||
s.getOption('awg_i1').getUIElement(s.section).setValue(config.interface_i1 || '');
|
||||
s.getOption('awg_i2').getUIElement(s.section).setValue(config.interface_i2 || '');
|
||||
s.getOption('awg_i3').getUIElement(s.section).setValue(config.interface_i3 || '');
|
||||
s.getOption('awg_i4').getUIElement(s.section).setValue(config.interface_i4 || '');
|
||||
s.getOption('awg_i5').getUIElement(s.section).setValue(config.interface_i5 || '');
|
||||
|
||||
if (config.interface_dns)
|
||||
s.getOption('dns').getUIElement(s.section).setValue(config.interface_dns);
|
||||
@@ -500,7 +519,7 @@ return network.registerProtocol('amneziawg', {
|
||||
E('p', _('Drag or paste a valid <em>*.conf</em> file below to configure the local AmneziaWG interface.'))
|
||||
] : [
|
||||
E('p', _('Paste or drag a AmneziaWG configuration (commonly <em>wg0.conf</em>) from another system below to create a matching peer entry allowing that system to connect to the local AmneziaWG interface.')),
|
||||
E('p', _('To fully configure the local AmneziaWG interface from an existing (e.g. provider supplied) configuration file, use the <strong><a class="full-import" href="#">configuration import</a></strong> instead.'))
|
||||
E('p', _('To configure fully the local AmneziaWG interface from an existing (e.g. provider supplied) configuration file, use the <strong><a class="full-import" href="#">configuration import</a></strong> instead.'))
|
||||
]),
|
||||
E('p', [
|
||||
E('textarea', {
|
||||
@@ -575,9 +594,10 @@ return network.registerProtocol('amneziawg', {
|
||||
return E('em', _('No peers defined yet.'));
|
||||
};
|
||||
|
||||
o = ss.option(form.Flag, 'disabled', _('Peer disabled'), _('Enable / Disable peer. Restart amneziawg interface to apply changes.'));
|
||||
o.modalonly = true;
|
||||
o = ss.option(form.Flag, 'disabled', _('Disabled'), _('Enable / Disable peer. Restart amneziawg interface to apply changes.'));
|
||||
o.editable = true;
|
||||
o.optional = true;
|
||||
o.width = '5%';
|
||||
|
||||
o = ss.option(form.Value, 'description', _('Description'), _('Optional. Description of peer.'));
|
||||
o.placeholder = 'My Peer';
|
||||
@@ -675,9 +695,6 @@ return network.registerProtocol('amneziawg', {
|
||||
var psk = this.section.getUIElement(section_id, 'preshared_key'),
|
||||
map = this.map;
|
||||
|
||||
if (psk.getValue() && !confirm(_('Do you want to replace the current PSK?')))
|
||||
return;
|
||||
|
||||
return generatePsk().then(function(key) {
|
||||
psk.setValue(key);
|
||||
map.save(null, true);
|
||||
@@ -757,69 +774,78 @@ return network.registerProtocol('amneziawg', {
|
||||
|
||||
o.modalonly = true;
|
||||
|
||||
o.createPeerConfig = function (section_id, endpoint, ips, eips, dns) {
|
||||
o.createPeerConfig = function(section_id, endpoint, ips, eips, dns) {
|
||||
var pub = s.formvalue(s.section, 'public_key'),
|
||||
port = s.formvalue(s.section, 'listen_port') || '51820',
|
||||
prv = this.section.formvalue(section_id, 'private_key'),
|
||||
psk = this.section.formvalue(section_id, 'preshared_key'),
|
||||
eport = this.section.formvalue(section_id, 'endpoint_port'),
|
||||
keep = this.section.formvalue(section_id, 'persistent_keepalive'),
|
||||
jc = s.formvalue(s.section, 'awg_jc'),
|
||||
jmin = s.formvalue(s.section, 'awg_jmin'),
|
||||
jmax = s.formvalue(s.section, 'awg_jmax'),
|
||||
s1 = s.formvalue(s.section, 'awg_s1'),
|
||||
s2 = s.formvalue(s.section, 'awg_s2'),
|
||||
h1 = s.formvalue(s.section, 'awg_h1'),
|
||||
h2 = s.formvalue(s.section, 'awg_h2'),
|
||||
h3 = s.formvalue(s.section, 'awg_h3'),
|
||||
h4 = s.formvalue(s.section, 'awg_h4');
|
||||
|
||||
port = s.formvalue(s.section, 'listen_port') || '51820',
|
||||
jc = s.formvalue(s.section, 'awg_jc'),
|
||||
jmin = s.formvalue(s.section, 'awg_jmin'),
|
||||
jmax = s.formvalue(s.section, 'awg_jmax'),
|
||||
s1 = s.formvalue(s.section, 'awg_s1'),
|
||||
s2 = s.formvalue(s.section, 'awg_s2'),
|
||||
s3 = s.formvalue(s.section, 'awg_s3'),
|
||||
s4 = s.formvalue(s.section, 'awg_s4'),
|
||||
h1 = s.formvalue(s.section, 'awg_h1'),
|
||||
h2 = s.formvalue(s.section, 'awg_h2'),
|
||||
h3 = s.formvalue(s.section, 'awg_h3'),
|
||||
h4 = s.formvalue(s.section, 'awg_h4'),
|
||||
i1 = s.formvalue(s.section, 'awg_i1'),
|
||||
i2 = s.formvalue(s.section, 'awg_i2'),
|
||||
i3 = s.formvalue(s.section, 'awg_i3'),
|
||||
i4 = s.formvalue(s.section, 'awg_i4'),
|
||||
i5 = s.formvalue(s.section, 'awg_i5'),
|
||||
prv = this.section.formvalue(section_id, 'private_key'),
|
||||
psk = this.section.formvalue(section_id, 'preshared_key'),
|
||||
eport = this.section.formvalue(section_id, 'endpoint_port'),
|
||||
keep = this.section.formvalue(section_id, 'persistent_keepalive');
|
||||
|
||||
// If endpoint is IPv6 we must escape it with []
|
||||
if (endpoint.indexOf(':') > 0) {
|
||||
endpoint = '[' + endpoint + ']';
|
||||
endpoint = '['+endpoint+']';
|
||||
}
|
||||
var configLines = [
|
||||
|
||||
return [
|
||||
'[Interface]',
|
||||
'PrivateKey = ' + prv,
|
||||
eport ? 'ListenPort = ' + eport : '# ListenPort not defined',
|
||||
eips && eips.length ? 'Address = ' + eips.join(', ') : '# Address not defined',
|
||||
eport ? 'ListenPort = ' + eport : '# ListenPort not defined',
|
||||
dns && dns.length ? 'DNS = ' + dns.join(', ') : '# DNS not defined',
|
||||
''
|
||||
];
|
||||
|
||||
if (jc) configLines.push('jc = ' + jc);
|
||||
if (jmin) configLines.push('jmin = ' + jmin);
|
||||
if (jmax) configLines.push('jmax = ' + jmax);
|
||||
if (s1) configLines.push('s1 = ' + s1);
|
||||
if (s2) configLines.push('s2 = ' + s2);
|
||||
if (h1) configLines.push('h1 = ' + h1);
|
||||
if (h2) configLines.push('h2 = ' + h2);
|
||||
if (h3) configLines.push('h3 = ' + h3);
|
||||
if (h4) configLines.push('h4 = ' + h4);
|
||||
|
||||
configLines.push(
|
||||
jc ? 'Jc = ' + jc : '# Jc not defined',
|
||||
jmin ? 'Jmin = ' + jmin : '# Jmin not defined',
|
||||
jmax ? 'Jmax = ' + jmax : '# Jmax not defined',
|
||||
s1 ? 'S1 = ' + s1 : '# S1 not defined',
|
||||
s2 ? 'S2 = ' + s2 : '# S2 not defined',
|
||||
s3 ? 'S3 = ' + s3 : '# S3 not defined',
|
||||
s4 ? 'S4 = ' + s4 : '# S4 not defined',
|
||||
h1 ? 'H1 = ' + h1 : '# H1 not defined',
|
||||
h2 ? 'H2 = ' + h2 : '# H2 not defined',
|
||||
h3 ? 'H3 = ' + h3 : '# H3 not defined',
|
||||
h4 ? 'H4 = ' + h4 : '# H4 not defined',
|
||||
i1 ? 'I1 = ' + i1 : '# I1 not defined',
|
||||
i2 ? 'I2 = ' + i2 : '# I2 not defined',
|
||||
i3 ? 'I3 = ' + i3 : '# I3 not defined',
|
||||
i4 ? 'I4 = ' + i4 : '# I4 not defined',
|
||||
i5 ? 'I5 = ' + i5 : '# I5 not defined',
|
||||
'',
|
||||
'[Peer]',
|
||||
'PublicKey = ' + pub,
|
||||
psk ? 'PresharedKey = ' + psk : '# PresharedKey not used',
|
||||
ips && ips.length ? 'AllowedIPs = ' + ips.join(', ') : '# AllowedIPs not defined',
|
||||
endpoint ? 'Endpoint = ' + endpoint + ':' + port : '# Endpoint not defined',
|
||||
keep ? 'PersistentKeepAlive = ' + keep : '# PersistentKeepAlive not defined',
|
||||
''
|
||||
);
|
||||
|
||||
return configLines.join('\n');
|
||||
};
|
||||
keep ? 'PersistentKeepAlive = ' + keep : '# PersistentKeepAlive not defined'
|
||||
].join('\n');
|
||||
};
|
||||
|
||||
o.handleGenerateQR = function(section_id, ev) {
|
||||
var mapNode = ss.getActiveModalMap(),
|
||||
headNode = mapNode.parentNode.querySelector('h4'),
|
||||
configGenerator = this.createPeerConfig.bind(this, section_id),
|
||||
parent = this.map,
|
||||
headNode = mapNode.parentNode.querySelector('h4'),
|
||||
configGenerator = this.createPeerConfig.bind(this, section_id),
|
||||
parent = this.map,
|
||||
eips = this.section.formvalue(section_id, 'allowed_ips');
|
||||
|
||||
return Promise.all([
|
||||
network.getWANNetworks(),
|
||||
network.getWAN6Networks(),
|
||||
network.getNetwork('lan'),
|
||||
L.resolveDefault(uci.load('ddns')),
|
||||
L.resolveDefault(uci.load('system')),
|
||||
parent.save(null, true)
|
||||
@@ -827,12 +853,12 @@ return network.registerProtocol('amneziawg', {
|
||||
var hostnames = [];
|
||||
|
||||
uci.sections('ddns', 'service', function(s) {
|
||||
if (typeof(s.lookup_host) == 'string' && s.enabled == '1')
|
||||
if (typeof(s?.lookup_host) == 'string' && s?.enabled == '1')
|
||||
hostnames.push(s.lookup_host);
|
||||
});
|
||||
|
||||
uci.sections('system', 'system', function(s) {
|
||||
if (typeof(s.hostname) == 'string' && s.hostname.indexOf('.') > 0)
|
||||
if (typeof(s?.hostname) == 'string' && s?.hostname?.indexOf('.') > 0)
|
||||
hostnames.push(s.hostname);
|
||||
});
|
||||
|
||||
@@ -846,34 +872,34 @@ return network.registerProtocol('amneziawg', {
|
||||
|
||||
var dns = [];
|
||||
|
||||
var lan = data[2];
|
||||
if (lan) {
|
||||
var lanIp = lan.getIPAddr();
|
||||
if (lanIp) {
|
||||
dns.unshift(lanIp)
|
||||
}
|
||||
}
|
||||
|
||||
var qrm, qrs, qro;
|
||||
|
||||
qrm = new form.JSONMap({
|
||||
config: {
|
||||
endpoint: hostnames[0],
|
||||
allowed_ips: ips,
|
||||
addresses: eips,
|
||||
dns_servers: dns
|
||||
}
|
||||
}, null, _('The generated configuration can be imported into a AmneziaWG client application to set up a connection towards this device.'));
|
||||
|
||||
qrm = new form.JSONMap({ config: { endpoint: hostnames[0], allowed_ips: ips, addresses: eips, dns_servers: dns } }, null, _('The generated configuration can be imported into a WireGuard client application to set up a connection towards this device.'));
|
||||
qrm.parent = parent;
|
||||
|
||||
qrs = qrm.section(form.NamedSection, 'config');
|
||||
|
||||
function handleConfigChange(ev, section_id, value) {
|
||||
var code = this.map.findElement('.qr-code'),
|
||||
conf = this.map.findElement('.client-config'),
|
||||
endpoint = this.section.getUIElement(section_id, 'endpoint'),
|
||||
ips = this.section.getUIElement(section_id, 'allowed_ips');
|
||||
eips = this.section.getUIElement(section_id, 'addresses');
|
||||
dns = this.section.getUIElement(section_id, 'dns_servers');
|
||||
conf = this.map.findElement('.client-config'),
|
||||
endpoint = this.section.getUIElement(section_id, 'endpoint'),
|
||||
ips = this.section.getUIElement(section_id, 'allowed_ips');
|
||||
eips = this.section.getUIElement(section_id, 'addresses');
|
||||
dns = this.section.getUIElement(section_id, 'dns_servers');
|
||||
|
||||
if (this.isValid(section_id)) {
|
||||
conf.firstChild.data = configGenerator(endpoint.getValue(), ips.getValue(), eips.getValue(), dns.getValue());
|
||||
code.style.opacity = '.5';
|
||||
|
||||
invokeQREncode(conf.firstChild.data, code);
|
||||
buildSVGQRCode(conf.firstChild.data, code);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -897,7 +923,7 @@ return network.registerProtocol('amneziawg', {
|
||||
qro.datatype = 'ipaddr';
|
||||
qro.default = eips;
|
||||
eips.forEach(function(eip) { qro.value(eip) });
|
||||
qro.onchange = handleConfigChange;
|
||||
qro.onchange = handleConfigChange;
|
||||
|
||||
qro = qrs.option(form.DummyValue, 'output');
|
||||
qro.renderWidget = function() {
|
||||
@@ -908,16 +934,9 @@ return network.registerProtocol('amneziawg', {
|
||||
}, [
|
||||
E('div', {
|
||||
'class': 'qr-code',
|
||||
'style': 'display:flex; flex-direction: column; text-align: center',
|
||||
'style': 'width:320px;flex:0 1 320px;text-align:center'
|
||||
}, [
|
||||
E('div', {
|
||||
'style': 'width:320px;flex:0 1 320px;text-align:center'
|
||||
}, [
|
||||
E('em', { 'class': 'spinning' }, [ _('Generating QR code…') ])
|
||||
]),
|
||||
|
||||
E('div', {
|
||||
}, ['Download Configuration']),
|
||||
E('em', { 'class': 'spinning' }, [ _('Generating QR code…') ])
|
||||
]),
|
||||
E('pre', {
|
||||
'class': 'client-config',
|
||||
@@ -934,7 +953,7 @@ return network.registerProtocol('amneziawg', {
|
||||
}, [ peer_config ])
|
||||
]);
|
||||
|
||||
invokeQREncode(peer_config, node.firstChild);
|
||||
buildSVGQRCode(peer_config, node.firstChild);
|
||||
|
||||
return node;
|
||||
};
|
||||
@@ -6,9 +6,9 @@
|
||||
'require ui';
|
||||
|
||||
|
||||
var callGetWgInstances = rpc.declare({
|
||||
var callgetAwgInstances = rpc.declare({
|
||||
object: 'luci.amneziawg',
|
||||
method: 'getWgInstances'
|
||||
method: 'getAwgInstances'
|
||||
});
|
||||
|
||||
function timestampToStr(timestamp) {
|
||||
@@ -128,7 +128,7 @@ return view.extend({
|
||||
'click': ui.createHandlerFn(this, handleInterfaceDetails, ifaces[instanceName])
|
||||
}, [
|
||||
E('span', { 'class': 'ifacebadge' }, [
|
||||
E('img', { 'src': L.resource('icons', 'tunnel.svg') }),
|
||||
E('img', { 'src': L.resource('icons', 'amneziawg.svg') }),
|
||||
'\xa0',
|
||||
instanceName
|
||||
]),
|
||||
@@ -153,7 +153,7 @@ return view.extend({
|
||||
|
||||
render: function() {
|
||||
poll.add(L.bind(function () {
|
||||
return callGetWgInstances().then(L.bind(function(ifaces) {
|
||||
return callgetAwgInstances().then(L.bind(function(ifaces) {
|
||||
dom.content(
|
||||
document.querySelector('#view'),
|
||||
this.renderIfaces(ifaces)
|
||||
158
luci-proto-amneziawg/po/ru/amneziawg.po
Normal file
158
luci-proto-amneziawg/po/ru/amneziawg.po
Normal file
@@ -0,0 +1,158 @@
|
||||
msgid "Imports settings from an existing AmneziaWG configuration file"
|
||||
msgstr "Импортирует настройки из существующего файла конфигурации AmneziaWG"
|
||||
|
||||
msgid ""
|
||||
"Drag or paste a valid <em>*.conf</em> file below to configure the local "
|
||||
"AmneziaWG interface."
|
||||
msgstr ""
|
||||
"Перетащите или вставьте правильный файл <em>*.conf</em> ниже, чтобы "
|
||||
"настроить локальный интерфейс AmneziaWG."
|
||||
|
||||
msgid ""
|
||||
"Paste or drag a AmneziaWG configuration (commonly <em>wg0.conf</em>) from "
|
||||
"another system below to create a matching peer entry allowing that system to "
|
||||
"connect to the local AmneziaWG interface."
|
||||
msgstr ""
|
||||
"Вставьте или перетащите конфигурацию AmneziaWG (обычно <em>wg0.conf</em>) из "
|
||||
"другой системы ниже, чтобы создать соответствующую запись узла, позволяющую "
|
||||
"этой системе подключиться к локальному интерфейсу AmneziaWG."
|
||||
|
||||
msgid ""
|
||||
"To configure fully the local AmneziaWG interface from an existing (e.g. "
|
||||
"provider supplied) configuration file, use the <strong><a class=\"full-"
|
||||
"import\" href=\"#\">configuration import</a></strong> instead."
|
||||
msgstr ""
|
||||
"Чтобы полностью настроить локальный интерфейс AmneziaWG из существующего "
|
||||
"(например, предоставленного провайдером) файла конфигурации, используйте "
|
||||
"вместо этого <strong><a class=\"full-import\" href=\"#\">импорт "
|
||||
"конфигурации</a></strong>."
|
||||
|
||||
msgid "Paste or drag supplied AmneziaWG configuration file…"
|
||||
msgstr "Вставьте или перетащите имеющийся файл конфигурации AmneziaWG…"
|
||||
|
||||
msgid "Paste or drag AmneziaWG peer configuration (wg0.conf) file…"
|
||||
msgstr "Вставьте или перетащите файл конфигурации узлов AmneziaWG (wg0.conf)…"
|
||||
|
||||
msgid "Recommended. IP addresses of the AmneziaWG interface."
|
||||
msgstr "Рекомендуемый. IP адреса интерфейса AmneziaWG."
|
||||
|
||||
msgid "Imports settings from an existing AmneziaWG configuration file"
|
||||
msgstr "Импортирует настройки из существующего файла конфигурации AmneziaWG"
|
||||
|
||||
msgid "AmneziaWG Settings"
|
||||
msgstr "Настройки AmneziaWG"
|
||||
|
||||
msgid "Imports settings from an existing AmneziaWG configuration file"
|
||||
msgstr "Импортирует настройки из существующего файла конфигурации AmneziaWG"
|
||||
|
||||
msgid "Imports settings from an existing AmneziaWG configuration file"
|
||||
msgstr "Импортирует настройки из существующего файла конфигурации AmneziaWG"
|
||||
|
||||
msgid "Imports settings from an existing AmneziaWG configuration file"
|
||||
msgstr "Импортирует настройки из существующего файла конфигурации AmneziaWG"
|
||||
|
||||
msgid ""
|
||||
"Further information about AmneziaWG interfaces and peers at <a href='https://"
|
||||
"docs.amnezia.org/documentation/amnezia-wg'>amnezia.org</a>."
|
||||
msgstr ""
|
||||
"Дополнительная информация об AmneziaWG интерфейсах и узлах приведена по "
|
||||
"адресу <a href='https://docs.amnezia.org/documentation/amnezia-wg'>amnezia.org</a>."
|
||||
|
||||
msgid "Junk packet count."
|
||||
msgstr "Количество мусорных пакетов."
|
||||
|
||||
msgid "Junk packet minimum size."
|
||||
msgstr "Минимальный размер мусорного пакета."
|
||||
|
||||
msgid "Junk packet maximum size."
|
||||
msgstr "Максимальный размер мусорного пакета."
|
||||
|
||||
msgid "Handshake initiation packet junk header size."
|
||||
msgstr "Размер мусорного заголовка пакета инициации рукопожатия."
|
||||
|
||||
msgid "Handshake response packet junk header size."
|
||||
msgstr "Размер мусорного заголовка пакета ответа на рукопожатие."
|
||||
|
||||
msgid "Cookie reply packet junk header size."
|
||||
msgstr "Размер мусорного заголовка пакета ответа cookie."
|
||||
|
||||
msgid "Transport packet junk header size."
|
||||
msgstr "Размер мусорного заголовка транспортного пакета."
|
||||
|
||||
msgid "Handshake initiation packet type header."
|
||||
msgstr "Тип заголовка пакета инициации рукопожатия."
|
||||
|
||||
msgid "Handshake response packet type header."
|
||||
msgstr "Тип заголовка пакета ответа на рукопожатие."
|
||||
|
||||
msgid "Handshake cookie packet type header."
|
||||
msgstr "Тип заголовка пакета под нагрузкой."
|
||||
|
||||
msgid "Transport packet type header."
|
||||
msgstr "Тип заголовка транспортного пакета."
|
||||
|
||||
msgid "First special junk packet signature."
|
||||
msgstr "Сигнатура первого special junk пакета."
|
||||
|
||||
msgid "Second special junk packet signature."
|
||||
msgstr "Сигнатура второго special junk пакета."
|
||||
|
||||
msgid "Third special junk packet signature."
|
||||
msgstr "Сигнатура третьего special junk пакета."
|
||||
|
||||
msgid "Fourth special junk packet signature."
|
||||
msgstr "Сигнатура четвертого special junk пакета."
|
||||
|
||||
msgid "Fifth special junk packet signature."
|
||||
msgstr "Сигнатура пятого special junk пакета."
|
||||
|
||||
msgid "Enable / Disable peer. Restart amneziawg interface to apply changes."
|
||||
msgstr ""
|
||||
"Включить/выключить узел. Перезапустите интерфейс AmneziaWG, чтобы применить "
|
||||
"изменения."
|
||||
|
||||
msgid "AmneziaWG peer is disabled"
|
||||
msgstr "Узел AmneziaWG отключён"
|
||||
|
||||
msgctxt "Label indicating that AmneziaWG peer is disabled"
|
||||
msgid "Disabled"
|
||||
msgstr "Отключено"
|
||||
|
||||
msgctxt "Label indicating that AmneziaWG peer lacks public key"
|
||||
msgid "Key missing"
|
||||
msgstr "Отсутствует ключ"
|
||||
|
||||
msgctxt "Tooltip displaying full AmneziaWG peer public key"
|
||||
msgid "Public key: %h"
|
||||
msgstr "Публичный ключ: %h"
|
||||
|
||||
msgctxt "Label indicating that AmneziaWG peer private key is stored"
|
||||
msgid "Private"
|
||||
msgstr "Private"
|
||||
|
||||
msgctxt "Label indicating that AmneziaWG peer uses a PSK"
|
||||
msgid "PSK"
|
||||
msgstr "PSK"
|
||||
|
||||
msgid "Required. Public key of the AmneziaWG peer."
|
||||
msgstr "Обязательно. Публичный ключ AmneziaWG узла."
|
||||
|
||||
"Optional. Private key of the AmneziaWG peer. The key is not required for "
|
||||
"establishing a connection but allows generating a peer configuration or QR "
|
||||
"code if available. It can be removed after the configuration has been "
|
||||
"exported."
|
||||
msgstr ""
|
||||
"Необязательно. Закрытый ключ узла AmneziaWG. Ключ не требуется для "
|
||||
"установления соединения, но позволяет сгенерировать конфигурацию узла или QR-"
|
||||
"код, если он доступен. Он может быть удален после экспорта конфигурации."
|
||||
|
||||
msgid "Generates a configuration suitable for import on a AmneziaWG peer"
|
||||
msgstr "Создает конфигурацию, подходящую для импорта на узле AmneziaWG"
|
||||
|
||||
msgid ""
|
||||
"No fixed interface listening port defined, peers might not be able to "
|
||||
"initiate connections to this AmneziaWG instance!"
|
||||
msgstr ""
|
||||
"Не определен фиксированный порт прослушивания интерфейса, поэтому узлы могут "
|
||||
"оказаться не в состоянии инициировать соединения с этим экземпляром "
|
||||
"AmneziaWG!"
|
||||
25
luci-proto-amneziawg/po/ru/status.po
Normal file
25
luci-proto-amneziawg/po/ru/status.po
Normal file
@@ -0,0 +1,25 @@
|
||||
msgid "AmneziaWG Status"
|
||||
msgstr "Состояние AmneziaWG"
|
||||
|
||||
msgctxt "AmneziaWG instance heading"
|
||||
msgid "Instance \"%h\""
|
||||
msgstr "Экземпляр «%h»"
|
||||
|
||||
msgctxt "No AmneziaWG peer handshake yet"
|
||||
msgid "Never"
|
||||
msgstr "Никогда"
|
||||
|
||||
msgctxt "AmneziaWG keep alive interval"
|
||||
msgid "every %ds"
|
||||
msgstr "каждые %dс"
|
||||
|
||||
msgctxt "Tooltip displaying full AmneziaWG peer public key"
|
||||
msgid "Public key: %h"
|
||||
msgstr "Публичный ключ: %h"
|
||||
|
||||
msgctxt "AmneziaWG listen port"
|
||||
msgid "Port %d"
|
||||
msgstr "Порт %d"
|
||||
|
||||
msgid "No AmneziaWG interfaces configured."
|
||||
msgstr "Интерфейсы AmneziaWG не настроены."
|
||||
@@ -2,15 +2,12 @@
|
||||
"luci-proto-amneziawg": {
|
||||
"description": "Grant access to LuCI AmneziaWG procedures",
|
||||
"read": {
|
||||
"file": {
|
||||
"/usr/bin/qrencode --inline --8bit --type=SVG --output=- -- *": [ "exec" ]
|
||||
},
|
||||
"ubus": {
|
||||
"luci.amneziawg": [
|
||||
"getWgInstances"
|
||||
"getAwgInstances"
|
||||
]
|
||||
},
|
||||
"uci": [ "ddns", "system" ]
|
||||
"uci": [ "ddns", "system", "network" ]
|
||||
},
|
||||
"write": {
|
||||
"ubus": {
|
||||
@@ -15,18 +15,33 @@ function command(cmd) {
|
||||
return trim(popen(cmd)?.read?.('all'));
|
||||
}
|
||||
|
||||
function checkPeerHost(configHost, configPort, wgHost) {
|
||||
const ips = popen(`resolveip ${shellquote(configHost)} 2>/dev/null`);
|
||||
const hostIp = replace(wgHost, /\[|\]/g, "");
|
||||
if (ips) {
|
||||
for (let line = ips.read('line'); length(line); line = ips.read('line')) {
|
||||
const ip = rtrim(line, '\n');
|
||||
if (configPort && (ip + ":" + configPort == hostIp)) {
|
||||
return true;
|
||||
} else if (ip == substr(hostIp, 0, rindex(hostIp, ":"))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const methods = {
|
||||
generatePsk: {
|
||||
call: function() {
|
||||
return { psk: command('amneziawg genpsk 2>/dev/null') };
|
||||
return { psk: command('awg genpsk 2>/dev/null') };
|
||||
}
|
||||
},
|
||||
|
||||
generateKeyPair: {
|
||||
call: function() {
|
||||
const priv = command('amneziawg genkey 2>/dev/null');
|
||||
const pub = command(`echo ${shellquote(priv)} | amneziawg pubkey 2>/dev/null`);
|
||||
const priv = command('awg genkey 2>/dev/null');
|
||||
const pub = command(`echo ${shellquote(priv)} | awg pubkey 2>/dev/null`);
|
||||
|
||||
return { keys: { priv, pub } };
|
||||
}
|
||||
@@ -36,20 +51,20 @@ const methods = {
|
||||
args: { privkey: "privkey" },
|
||||
call: function(req) {
|
||||
const priv = req.args?.privkey;
|
||||
const pub = command(`echo ${shellquote(priv)} | amneziawg pubkey 2>/dev/null`);
|
||||
const pub = command(`echo ${shellquote(priv)} | awg pubkey 2>/dev/null`);
|
||||
|
||||
return { keys: { priv, pub } };
|
||||
}
|
||||
},
|
||||
|
||||
getWgInstances: {
|
||||
getAwgInstances: {
|
||||
call: function() {
|
||||
const data = {};
|
||||
let last_device;
|
||||
let qr_pubkey = {};
|
||||
|
||||
const uci = cursor();
|
||||
const wg_dump = popen("amneziawg show all dump 2>/dev/null");
|
||||
const wg_dump = popen("awg show all dump 2>/dev/null");
|
||||
|
||||
if (wg_dump) {
|
||||
uci.load("network");
|
||||
@@ -74,12 +89,17 @@ const methods = {
|
||||
}
|
||||
else {
|
||||
let peer_name;
|
||||
let peer_name_legacy;
|
||||
|
||||
uci.foreach('network', `amneziawg_${last_device}`, (s) => {
|
||||
if (s.public_key == record[1])
|
||||
if (!s.disabled && s.public_key == record[1] && (!s.endpoint_host || checkPeerHost(s.endpoint_host, s.endpoint_port, record[3])))
|
||||
peer_name = s.description;
|
||||
if (s.public_key == record[1])
|
||||
peer_name_legacy = s.description;
|
||||
});
|
||||
|
||||
if (!peer_name) peer_name = peer_name_legacy;
|
||||
|
||||
const peer = {
|
||||
name: peer_name,
|
||||
public_key: record[1],
|
||||
Reference in New Issue
Block a user