mirror of
https://github.com/Slava-Shchipunov/awg-openwrt.git
synced 2026-03-14 09:23:10 +00:00
Compare commits
32 Commits
draft-24.1
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fb008b93c8 | ||
|
|
1607241233 | ||
|
|
09256b1cc5 | ||
|
|
2c4fe317b3 | ||
|
|
676c821362 | ||
|
|
aa17c7a25c | ||
|
|
46f0cba90b | ||
|
|
ad4c3e27c0 | ||
|
|
d64ea7b53e | ||
|
|
e075dcb43f | ||
|
|
449988b8e6 | ||
|
|
9591ffdebe | ||
|
|
3498354348 | ||
|
|
f4c13f262d | ||
|
|
6164b8e8d3 | ||
|
|
c4e45cd3bc | ||
|
|
ce827121a1 | ||
|
|
1589abe9ec | ||
|
|
8b3f1c1e5d | ||
|
|
9a3f4520b3 | ||
|
|
c3264c3a99 | ||
|
|
aca98becff | ||
|
|
28c7463dd8 | ||
|
|
afcee2c1bd | ||
|
|
72112902be | ||
|
|
bad6a2005d | ||
|
|
d3372b1535 | ||
|
|
199ec6a51a | ||
|
|
0c726cacbf | ||
|
|
d91b8929de | ||
|
|
33e363e9d9 | ||
|
|
3d865a8d4d |
199
.github/workflows/build-module.yml
vendored
199
.github/workflows/build-module.yml
vendored
@@ -9,6 +9,21 @@ on:
|
|||||||
tag_name:
|
tag_name:
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: 'OpenWRT version (e.g., 24.10.5)'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
targets:
|
||||||
|
description: 'Targets (comma-separated, optional)'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
subtargets:
|
||||||
|
description: 'Subtargets (comma-separated, optional)'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
generate-config:
|
generate-config:
|
||||||
@@ -24,12 +39,22 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
node-version: '20.16.0'
|
node-version: '20.16.0'
|
||||||
|
|
||||||
- name: Get OpenWRT version from tag
|
- name: Get OpenWRT version from inputs or tag
|
||||||
id: get_version
|
|
||||||
run: |
|
run: |
|
||||||
if [ "${{ github.event_name }}" == "workflow_call" ]; then
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||||
|
echo "VERSION=${{ inputs.version }}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
if [ -n "${{ inputs.targets }}" ]; then
|
||||||
|
echo "TARGETS=${{ inputs.targets }}" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${{ inputs.subtargets }}" ]; then
|
||||||
|
echo "SUBTARGETS=${{ inputs.subtargets }}" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
|
||||||
|
elif [ "${{ github.event_name }}" = "workflow_call" ]; then
|
||||||
echo "VERSION=${{ inputs.tag_name }}" >> $GITHUB_ENV
|
echo "VERSION=${{ inputs.tag_name }}" >> $GITHUB_ENV
|
||||||
echo "VERSION=${VERSION#v}" >> $GITHUB_ENV
|
|
||||||
else
|
else
|
||||||
echo "VERSION=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_ENV
|
echo "VERSION=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_ENV
|
||||||
fi
|
fi
|
||||||
@@ -39,7 +64,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Generate Job Config
|
- name: Generate Job Config
|
||||||
id: generate-config
|
id: generate-config
|
||||||
run: node index.js ${{ env.VERSION }}
|
run: node index.js ${{ env.VERSION }} "${{ env.TARGETS }}" "${{ env.SUBTARGETS }}"
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
@@ -53,96 +78,130 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- name: Checkout AWG source code
|
||||||
with:
|
uses: actions/checkout@v4
|
||||||
repository: openwrt/openwrt
|
|
||||||
ref: v${{ matrix.build_env.tag }}
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Cache Tools and Kernel
|
- name: Install Python dependencies
|
||||||
id: cache-tools-kernel
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y python3-pyelftools
|
||||||
|
|
||||||
|
- name: Cache OpenWrt SDK
|
||||||
|
id: cache-sdk
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
env:
|
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:
|
with:
|
||||||
path: "**"
|
path: openwrt-sdk-*/
|
||||||
key: ${{ runner.os }}-build-vm4-${{ env.cache-name }}
|
key: ${{ runner.os }}-sdk-${{ env.cache-name }}
|
||||||
|
|
||||||
- name: Building kernel and tools
|
- name: Download and extract OpenWrt SDK
|
||||||
#if: ${{ steps.cache-tools-kernel.outputs.cache-hit != 'true' }}
|
if: steps.cache-sdk.outputs.cache-hit != 'true'
|
||||||
run: |
|
run: |
|
||||||
echo "pkgarch: ${{ matrix.build_env.pkgarch}}, target:${{ matrix.build_env.target}}, subtarget: ${{ matrix.build_env.subtarget}}"
|
echo "pkgarch: ${{ matrix.build_env.pkgarch}}, target:${{ matrix.build_env.target}}, subtarget: ${{ matrix.build_env.subtarget}}"
|
||||||
|
|
||||||
# Setup & install feeds
|
# Get the actual SDK filename from the directory listing
|
||||||
wget https://downloads.openwrt.org/releases/${{ matrix.build_env.tag }}/targets/${{ matrix.build_env.target}}/${{ matrix.build_env.subtarget}}/feeds.buildinfo -O feeds.conf
|
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)
|
||||||
echo "src-git awgopenwrt https://github.com/Slava-Shchipunov/awg-openwrt.git" >> ./feeds.conf
|
|
||||||
./scripts/feeds update && ./scripts/feeds install -a
|
|
||||||
|
|
||||||
# Setup config with AWG and dependencies
|
if [ -z "$SDK_FILE" ]; then
|
||||||
wget https://downloads.openwrt.org/releases/${{ matrix.build_env.tag }}/targets/${{ matrix.build_env.target}}/${{ matrix.build_env.subtarget}}/config.buildinfo -O .config
|
echo "SDK file not found for ${{ matrix.build_env.tag }} ${{ matrix.build_env.target}} ${{ matrix.build_env.subtarget}}"
|
||||||
echo "CONFIG_PACKAGE_kmod-amneziawg=m" >> .config
|
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"
|
||||||
|
|
||||||
|
- 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_amneziawg-tools=y" >> .config
|
||||||
echo "CONFIG_PACKAGE_luci-app-amneziawg=y" >> .config
|
echo "CONFIG_PACKAGE_luci-proto-amneziawg=y" >> .config
|
||||||
echo "CONFIG_PACKAGE_kmod-crypto-lib-chacha20=m" >> .config
|
echo "CONFIG_PACKAGE_luci-i18n-amneziawg-ru=y" >> .config
|
||||||
echo "CONFIG_PACKAGE_kmod-crypto-lib-chacha20poly1305=m" >> .config
|
|
||||||
echo "CONFIG_PACKAGE_kmod-crypto-chacha20poly1305=m" >> .config
|
|
||||||
|
|
||||||
make defconfig
|
make defconfig
|
||||||
|
|
||||||
echo " > make tools/install"
|
- name: Build AmneziaWG packages
|
||||||
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
|
|
||||||
run: |
|
run: |
|
||||||
VERMAGIC=`cat ./build_dir/target-*/linux-*/linux-*/.vermagic`
|
# Find SDK directory
|
||||||
echo "Vermagic: $VERMAGIC"
|
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
|
# Build kmod-amneziawg (kernel module)
|
||||||
echo Vermagic mismatch: $VERMAGIC, expected $VERMAGIC_EXPECTED
|
echo "Building kmod-amneziawg..."
|
||||||
exit 1
|
make package/kmod-amneziawg/{download,prepare} V=s || true
|
||||||
fi
|
|
||||||
|
|
||||||
# Ignore kmod build for some targets, replace with the awg-go
|
|
||||||
make package/kmod-amneziawg/{clean,download,prepare} V=s || true
|
|
||||||
make package/kmod-amneziawg/compile V=s || true
|
make package/kmod-amneziawg/compile V=s || true
|
||||||
|
|
||||||
make package/luci-app-amneziawg/{clean,download,prepare}
|
# Build luci-proto-amneziawg (web interface)
|
||||||
make package/luci-app-amneziawg/compile V=s
|
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}
|
# Build amneziawg-tools (userspace tools)
|
||||||
make V=s package/amneziawg-tools/compile
|
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 "*.?pk" | grep -E "(amneziawg|luci-proto-amneziawg|luci-i18n-amneziawg)" | head -10
|
||||||
|
|
||||||
- name: Prepare artifacts
|
- name: Prepare artifacts
|
||||||
run: |
|
run: |
|
||||||
tag_name=${{ github.ref_name }}
|
# Find SDK directory
|
||||||
|
SDK_DIR=$(find . -maxdepth 1 -name "openwrt-sdk-*" -type d | head -n1)
|
||||||
|
|
||||||
mkdir -p awgrelease
|
mkdir -p awgrelease
|
||||||
postfix="v${{ matrix.build_env.tag }}_${{ matrix.build_env.pkgarch}}_${{ matrix.build_env.target}}_${{ matrix.build_env.subtarget}}"
|
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
|
# Copy built packages
|
||||||
cp bin/targets/${{ matrix.build_env.target}}/${{ matrix.build_env.subtarget}}/packages/kmod-amneziawg_*.ipk awgrelease/kmod-amneziawg_${postfix}.ipk
|
find "$SDK_DIR/bin/packages" -name "amneziawg-tools*.?pk" -exec sh -c 'file="$1"; postfix="$2"; ext="${file##*.}"; cp "$file" "awgrelease/amneziawg-tools_${postfix}.${ext}"' _ {} "${postfix}" \; || echo "amneziawg-tools package not found"
|
||||||
|
find "$SDK_DIR/bin/packages" -name "luci-proto-amneziawg*.?pk" -exec sh -c 'file="$1"; postfix="$2"; ext="${file##*.}"; cp "$file" "awgrelease/luci-proto-amneziawg_${postfix}.${ext}"' _ {} "${postfix}" \; || echo "luci-proto-amneziawg package not found"
|
||||||
|
find "$SDK_DIR/bin/packages" -name "luci-i18n-amneziawg-ru*.?pk" -exec sh -c 'file="$1"; postfix="$2"; ext="${file##*.}"; cp "$file" "awgrelease/luci-i18n-amneziawg-ru_${postfix}.${ext}"' _ {} "${postfix}" \; || echo "luci-i18n-amneziawg-ru package not found"
|
||||||
|
find "$SDK_DIR/bin/targets" -name "kmod-amneziawg*.?pk" -exec sh -c 'file="$1"; postfix="$2"; ext="${file##*.}"; cp "$file" "awgrelease/kmod-amneziawg_${postfix}.${ext}"' _ {} "${postfix}" \; || echo "kmod-amneziawg package not found"
|
||||||
|
|
||||||
|
echo "Built packages:"
|
||||||
|
ls -la awgrelease/
|
||||||
|
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
files: awgrelease/*.ipk
|
files: awgrelease/*.?pk
|
||||||
|
tag_name: v${{ matrix.build_env.tag }}
|
||||||
|
|||||||
187
.github/workflows/build-to-all-latest-snapshots.yml
vendored
187
.github/workflows/build-to-all-latest-snapshots.yml
vendored
@@ -1,187 +0,0 @@
|
|||||||
name: Build AmneziaWG for snapshot OpenWRT
|
|
||||||
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- "SNAPSHOT"
|
|
||||||
schedule:
|
|
||||||
- cron: '0 */4 * * *'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
generate-config:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
job-config: ${{ steps.generate-config.outputs.job-config }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: '20.16.0'
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: npm install
|
|
||||||
|
|
||||||
- name: Generate Job Config
|
|
||||||
id: generate-config
|
|
||||||
run: node index.js SNAPSHOT
|
|
||||||
|
|
||||||
build:
|
|
||||||
name: "${{ matrix.build_env.tag }} - ${{ matrix.build_env.pkgarch}} :: ${{ matrix.build_env.target}}/${{ matrix.build_env.subtarget}} build"
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: generate-config
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
build_env: ${{ fromJson(needs.generate-config.outputs.job-config) }}
|
|
||||||
fail-fast: false
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Check if release file exists
|
|
||||||
id: check_release
|
|
||||||
run: |
|
|
||||||
postfix="${{ matrix.build_env.tag }}_${{ matrix.build_env.vermagic }}_${{ matrix.build_env.pkgarch}}_${{ matrix.build_env.target}}_${{ matrix.build_env.subtarget}}"
|
|
||||||
RELEASE_FILE="kmod-amneziawg_${postfix}.ipk"
|
|
||||||
TAG=${{ matrix.build_env.tag }}
|
|
||||||
|
|
||||||
echo "Checking for release file: $RELEASE_FILE in release: $TAG"
|
|
||||||
|
|
||||||
# Используем GitHub CLI для проверки наличия файла в релизе
|
|
||||||
if gh release view "$TAG" --repo Slava-Shchipunov/awg-openwrt --json assets --jq ".assets | .[].name" | grep -q "$RELEASE_FILE"; then
|
|
||||||
echo "Release file $RELEASE_FILE already exists. Skipping job."
|
|
||||||
echo "FILE_EXISTS=true" >> $GITHUB_ENV
|
|
||||||
else
|
|
||||||
echo "FILE_EXISTS=false" >> $GITHUB_ENV
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Прерываем job'у, если файл уже существует
|
|
||||||
- name: Skip job if release file exists
|
|
||||||
if: env.FILE_EXISTS == 'true'
|
|
||||||
run: |
|
|
||||||
echo "Skipping job as release file already exists."
|
|
||||||
exit 0
|
|
||||||
|
|
||||||
- name: Get snapshot commit SHA and device ARCH
|
|
||||||
if: env.FILE_EXISTS == 'false'
|
|
||||||
run: |
|
|
||||||
PROFILE_URL="https://downloads.openwrt.org/snapshots/targets/${{ matrix.build_env.target}}/${{ matrix.build_env.subtarget}}/profiles.json"
|
|
||||||
SNAPSHOT_COMMIT_SHA=$(wget -q $PROFILE_URL -O- | tr ',' '\n' | grep "version_code"| awk -F: '{print $2}' | tr -d '"' | awk -F- '{print $2}')
|
|
||||||
echo "Snapshot commit sha: $SNAPSHOT_COMMIT_SHA"
|
|
||||||
echo "SNAPSHOT_COMMIT_SHA=$SNAPSHOT_COMMIT_SHA" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
DEVICE_ARCH=$(wget -q $PROFILE_URL -O- | tr ',' '\n' | grep "arch_packages"| awk -F: '{print $2}' | tr -d '"')
|
|
||||||
echo "Device ARCH: $DEVICE_ARCH"
|
|
||||||
echo "DEVICE_ARCH=$DEVICE_ARCH" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
if: env.FILE_EXISTS == 'false'
|
|
||||||
with:
|
|
||||||
repository: openwrt/openwrt
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Checkout snapshot commit in openwrt repo
|
|
||||||
if: env.FILE_EXISTS == 'false'
|
|
||||||
run: git checkout ${{ env.SNAPSHOT_COMMIT_SHA}}
|
|
||||||
|
|
||||||
- name: Building kernel and tools
|
|
||||||
if: env.FILE_EXISTS == 'false'
|
|
||||||
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/snapshots/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
|
|
||||||
|
|
||||||
# Setup config with AWG and dependencies
|
|
||||||
wget https://downloads.openwrt.org/snapshots/targets/${{ matrix.build_env.target}}/${{ matrix.build_env.subtarget}}/config.buildinfo -O .config
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
if: env.FILE_EXISTS == 'false'
|
|
||||||
run: |
|
|
||||||
VERMAGIC=`cat ./build_dir/target-*/linux-*/linux-*/.vermagic`
|
|
||||||
echo "Vermagic: $VERMAGIC"
|
|
||||||
|
|
||||||
VERMAGIC_EXPECTED=${{ matrix.build_env.vermagic }}
|
|
||||||
|
|
||||||
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
|
|
||||||
make package/kmod-amneziawg/compile V=s || true
|
|
||||||
|
|
||||||
make package/luci-app-amneziawg/{clean,download,prepare}
|
|
||||||
make package/luci-app-amneziawg/compile V=s
|
|
||||||
|
|
||||||
make V=s package/amneziawg-tools/{clean,download,prepare}
|
|
||||||
make V=s package/amneziawg-tools/compile
|
|
||||||
|
|
||||||
- name: Prepare artifacts
|
|
||||||
if: env.FILE_EXISTS == 'false'
|
|
||||||
run: |
|
|
||||||
tag_name=${{ github.ref_name }}
|
|
||||||
mkdir -p awgrelease
|
|
||||||
postfix="${{ matrix.build_env.tag }}_${{ matrix.build_env.vermagic }}_${{ 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
|
|
||||||
|
|
||||||
- name: Delete old release assets
|
|
||||||
if: env.FILE_EXISTS == 'false'
|
|
||||||
run: |
|
|
||||||
postfix="${{ matrix.build_env.pkgarch }}_${{ matrix.build_env.target }}_${{ matrix.build_env.subtarget }}"
|
|
||||||
echo "Looking for old release files ending with: ${postfix}"
|
|
||||||
|
|
||||||
# Получаем список всех артефактов релиза по имени
|
|
||||||
assets=$(gh release view "${{ matrix.build_env.tag }}" --repo Slava-Shchipunov/awg-openwrt --json assets --jq ".assets | .[] | select(.name | endswith(\"$postfix.ipk\")) | .name")
|
|
||||||
|
|
||||||
# Удаляем найденные артефакты по имени
|
|
||||||
for asset_name in $assets; do
|
|
||||||
echo "Deleting asset with name: $asset_name"
|
|
||||||
gh release delete-asset "${{ matrix.build_env.tag }}" "$asset_name" --repo Slava-Shchipunov/awg-openwrt
|
|
||||||
done
|
|
||||||
|
|
||||||
- name: Release
|
|
||||||
if: env.FILE_EXISTS == 'false'
|
|
||||||
uses: softprops/action-gh-release@v1
|
|
||||||
with:
|
|
||||||
files: awgrelease/*.ipk
|
|
||||||
tag_name: ${{ matrix.build_env.tag }}
|
|
||||||
66
.github/workflows/run-release.yml
vendored
66
.github/workflows/run-release.yml
vendored
@@ -1,66 +0,0 @@
|
|||||||
name: Sync OpenWRT Releases
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '0 0 */3 * *' # Проверка новых релизов раз в три дня
|
|
||||||
workflow_dispatch: # Возможность вручную запустить Action
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
sync-releases:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
release_exists: ${{ steps.check_release.outputs.release_exists }}
|
|
||||||
release_tag: ${{ steps.get_release.outputs.release_tag }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout your repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Get the latest release from OpenWRT
|
|
||||||
id: get_release
|
|
||||||
run: |
|
|
||||||
curl -s https://api.github.com/repos/openwrt/openwrt/releases/latest > latest_release.json
|
|
||||||
RELEASE_TAG=$(jq -r .tag_name latest_release.json)
|
|
||||||
RELEASE_NAME=$(jq -r .name latest_release.json)
|
|
||||||
echo "::set-output name=release_tag::$RELEASE_TAG"
|
|
||||||
echo "::set-output name=release_name::$RELEASE_NAME"
|
|
||||||
|
|
||||||
- name: Check if release exists in your repo
|
|
||||||
id: check_release
|
|
||||||
run: |
|
|
||||||
RELEASE_EXISTS=$(curl -s https://api.github.com/repos/Slava-Shchipunov/awg-openwrt/releases/tags/${{ steps.get_release.outputs.release_tag }} | jq -r .tag_name)
|
|
||||||
if [ "$RELEASE_EXISTS" == "null" ]; then
|
|
||||||
echo "::set-output name=release_exists::false"
|
|
||||||
else
|
|
||||||
echo "::set-output name=release_exists::true"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Create release in your repo
|
|
||||||
if: steps.check_release.outputs.release_exists == 'false'
|
|
||||||
run: |
|
|
||||||
ART="
|
|
||||||
\`\`\`
|
|
||||||
_______ ________ __
|
|
||||||
| |.-----.-----.-----.| | | |.----.| |_
|
|
||||||
| - || _ | -__| || | | || _|| _|
|
|
||||||
|_______|| __|_____|__|__||________||__| |____|
|
|
||||||
|__| A M N E Z I A W I R E G U A R D
|
|
||||||
-----------------------------------------------------
|
|
||||||
OpenWrt ${{ steps.get_release.outputs.release_tag }}
|
|
||||||
-----------------------------------------------------
|
|
||||||
\`\`\`"
|
|
||||||
|
|
||||||
curl -X POST https://api.github.com/repos/Slava-Shchipunov/awg-openwrt/releases \
|
|
||||||
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "$(jq -n --arg tag "${{ steps.get_release.outputs.release_tag }}" \
|
|
||||||
--arg name "Build amnezia wg for all devices with openwrt ${{ steps.get_release.outputs.release_tag }}" \
|
|
||||||
--arg body "$ART" \
|
|
||||||
'{ tag_name: $tag, name: $name, body: $body }')"
|
|
||||||
|
|
||||||
run-build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: sync-releases
|
|
||||||
if: needs.sync-releases.outputs.release_exists == 'false'
|
|
||||||
uses: Slava-Shchipunov/awg-openwrt/.github/workflows/build-module.yml@master
|
|
||||||
with:
|
|
||||||
tag_name: ${{ needs.sync-releases.outputs.release_tag }}
|
|
||||||
91
README.md
91
README.md
@@ -1,13 +1,19 @@
|
|||||||
# Автоматическая настройка AmneziaWG для OpenWRT версии 23.05.0 и более новых
|

|
||||||
Для автоматической настройки рекомендую использовать [скрипт](https://github.com/itdoginfo/domain-routing-openwrt) от пользователя itdog. Этот скрипт позволяет автоматически скачать нужные пакеты из собранных здесь и настроить [точечный обход блокировок по доменам](https://habr.com/ru/articles/767464/).
|
|
||||||
|
|
||||||
Если же вам нужно только установить пакеты, я добавил скрипт amneziawg-install - он автоматически скачает пакеты из этого репозитория под ваше устройство (только для стабильной версии OpenWRT), а также предложит сразу настроить интерфейс с протоколом AmneziaWG. Если пользователь согласится, нужно будет ввести параметры конфига, которые запросит скрипт. При этом скрипт создаст интерфейс, настроит для него правила фаерволла, а также **включит перенаправление всего траффика через тунель AmneziaWG** (установит в настройках Peer галочку Route Allowed IPs).
|
# Пакеты amneziawg для роутеров с прошивкой OpenWRT
|
||||||
|
|
||||||
|
## Автоматическая настройка AmneziaWG для OpenWRT версии 23.05.0 и более новых
|
||||||
|
1) Если ваш роутер обладает достаточным объмом доступной ROM, рекомендую воспользоваться скриптом, описанным ниже, только для установки нужных пакетов, а для точечной маршрутизации траффика в туннель использовать podkop от пользователя [@itdoginfo](https://github.com/itdoginfo) - тут в [документации](https://podkop.net/docs/tunnels/awg_settings/) описан процесс настройки
|
||||||
|
|
||||||
|
2) Если вам нужно только установить пакеты, я добавил скрипт amneziawg-install - он автоматически скачает пакеты из этого репозитория под ваше устройство (только для стабильной версии OpenWRT), а также предложит сразу настроить интерфейс с протоколом AmneziaWG. Если пользователь согласится, нужно будет ввести параметры конфига, которые запросит скрипт. При этом скрипт создаст интерфейс, настроит для него правила фаерволла, а также **включит перенаправление всего траффика через тунель AmneziaWG** (установит в настройках Peer галочку Route Allowed IPs).
|
||||||
Для запуска скрипта подключитесь к роутеру по SSH, введите команду и следуйте инструкциям на экране:
|
Для запуска скрипта подключитесь к роутеру по SSH, введите команду и следуйте инструкциям на экране:
|
||||||
```
|
```
|
||||||
sh <(wget -O - https://raw.githubusercontent.com/Slava-Shchipunov/awg-openwrt/refs/heads/master/amneziawg-install.sh)
|
sh <(wget -O - https://raw.githubusercontent.com/Slava-Shchipunov/awg-openwrt/refs/heads/master/amneziawg-install.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
# Сборка пакетов для всех устройств, поддерживающих OpenWRT
|
3) Кроме того для автоматической настройки также можно использовать [скрипт](https://github.com/itdoginfo/domain-routing-openwrt) от пользователя [@itdoginfo](https://github.com/itdoginfo). Этот скрипт позволяет автоматически скачать нужные пакеты из собранных здесь и настроить [точечный обход блокировок по доменам](https://habr.com/ru/articles/767464/). Подойдёт, если у вас слабый роутер с недостаточным объёмом ROM для установки podkop-a и зависимостей
|
||||||
|
|
||||||
|
## Сборка пакетов для всех устройств, поддерживающих OpenWRT
|
||||||
В репозиторий добавлен скрипт, который парсит данные о поддерживаемых платформах со страницы OpenWRT и автоматически запускает сборку пакетов AmneziaWG для всех устройств.
|
В репозиторий добавлен скрипт, который парсит данные о поддерживаемых платформах со страницы OpenWRT и автоматически запускает сборку пакетов AmneziaWG для всех устройств.
|
||||||
На данный момент я собрал пакеты для всех устройств для OpenWRT версий:
|
На данный момент я собрал пакеты для всех устройств для OpenWRT версий:
|
||||||
1) [23.05.0](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v23.05.0)
|
1) [23.05.0](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v23.05.0)
|
||||||
@@ -16,19 +22,20 @@ 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)
|
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)
|
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)
|
6) [23.05.5](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v23.05.5)
|
||||||
|
7) AWG-2.0 [23.05.6](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v23.05.6)
|
||||||
И собрал пакеты для популярных устройств для OpenWRT [SNAPSHOT](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/SNAPSHOT)
|
8) [24.10.0](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.0) ([AWG-2.0 для 24.10.0](https://github.com/yanjore/awg-openwrt/releases/tag/v24.10.0) из форка, если кому-то понадобится)
|
||||||
|
9) [24.10.1](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.1) ([AWG-2.0 для 24.10.1](https://github.com/yanjore/awg-openwrt/releases/tag/v24.10.1) из форка)
|
||||||
|
10) [24.10.2](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.2) ([AWG-2.0 для 24.10.2](https://github.com/yanjore/awg-openwrt/releases/tag/v24.10.2) из форка)
|
||||||
|
11) AWG-2.0 [24.10.3](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.3)
|
||||||
|
12) AWG-2.0 [24.10.4](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.4)
|
||||||
|
13) AWG-2.0 [24.10.5](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.5)
|
||||||
|
14) AWG-2.0 [25.12.0](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v25.12.0)
|
||||||
|
|
||||||
Также запускал сборку для версии [22.03.7](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v22.03.7), но там для двух платформ сборка завершилась ошибкой. Так как это достаточно старая версия OpenWRT, я не стал разбираться, в чем проблема.
|
Также запускал сборку для версии [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)
|
В соответствии с пунктом [Указываем переменные для сборки](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`, соответствующие вашему устройству.
|
определить `target` и `subtarget` вашего устройства. Далее перейти на страницу релиза, соответствующего вашей версии OpenWRT, затем поиском по странице (Ctrl+F) найти 3 пакета, название которых оканчивается на `target_subtarget.ipk`, соответствующие вашему устройству. Для версии AWG 2.0 также доступен пакет русификации luci-i18n-amneziawg-ru
|
||||||
|
|
||||||
## Как запустить сборку для всех поддерживаемых устройств
|
## Как запустить сборку для всех поддерживаемых устройств
|
||||||
1) Создать форк этого репозитория
|
1) Создать форк этого репозитория
|
||||||
@@ -39,21 +46,40 @@ sh <(wget -O - https://raw.githubusercontent.com/Slava-Shchipunov/awg-openwrt/re
|
|||||||
6) Ввести Release title
|
6) Ввести Release title
|
||||||
7) Нажать внизу зеленую кнопку Publish release
|
7) Нажать внизу зеленую кнопку Publish release
|
||||||
|
|
||||||
Для публичных репозиториев Github предоставляет неограниченное по времени использование раннеров, у меня запускалось до 20 параллельных джоб. Каждая джоба выполняется около 2 часов, общее время на сборку около 10 часов.
|
Для публичных репозиториев Github предоставляет неограниченное по времени использование раннеров, у меня запускалось до 20 параллельных джоб. Каждая джоба выполняется около 10-15 минут, общее время на сборку около 60 минут.
|
||||||
В случае возникновения ошибок в одной джобе, будут отменены все незавершенные - в этом случае на вкладке Actions можно выбрать неудавшийся запуск и нажать Re-run failed jobs
|
|
||||||
|
|
||||||
## Сборка пакетов под определенную платформу
|
## Сборка пакетов под определенную платформу
|
||||||
Как запустить сборку пакетов для определенной платформы можно посмотреть в [инструкции на вики](https://github.com/itdoginfo/domain-routing-openwrt/wiki/Amnezia-WG-Build). Сборка под одно устройство займет около 2 часов.
|
Как запустить сборку пакетов AWG 1.0 для определенной платформы можно посмотреть в [инструкции на вики](https://github.com/itdoginfo/domain-routing-openwrt/wiki/Amnezia-WG-Build). Сборка под одно устройство займет около 2 часов.
|
||||||
|
|
||||||
# Automatic configuration of AmneziaWG for OpenWRT version 23.05.0 and newer
|
AWG 2.0 можно собрать под определённую платформу следующим образом:
|
||||||
For automatic configuration, I recommend using the [script](https://github.com/itdoginfo/domain-routing-openwrt) from the user itdog. This script allows you to automatically download the necessary packages from those collected here and configure [point-by-point bypass of blocking by domains](https://habr.com/ru/articles/767464/) (instructions in Russian).
|
1) Создать форк этого репозитория
|
||||||
|
2) Переключиться на вкладку Actions и включить Github actions (по умолчанию для форков они выключены)
|
||||||
|
3) Слева в списке экшенов выбрать экшен Create Release on Tag
|
||||||
|
4) Справа нажать кнопку Run workflow
|
||||||
|
5) В открывшемся списке указать версию Openwrt (например, 24.10.3), список target, разделенных запятыми (например, stm32,ramips), список subtarget, разделенных запятыми (например, stm32mp1,mt7621). Сборка будет произведена только для существующих пар target/subtarget
|
||||||
|
6) Нажать зеленую кнопку Run workflow
|
||||||
|
Сборка под одно устройство займет около 10-15 минут. При этом должен создаться релиз с указанной версией OpenWRT
|
||||||
|
|
||||||
If you only need to install packages, I added the amneziawg-install script - it will automatically download packages from this repository for your device (only for the stable version of OpenWRT), and also offer to immediately configure the interface with the AmneziaWG protocol. If the user agrees, you will need to enter the config parameters that the script will request. The script will create an interface, configure firewall rules for it, and also **enable redirection of all traffic through the AmneziaWG tunnel** (check the Route Allowed IPs box in the Peer settings).
|
## 🙏 Благодарности
|
||||||
|
|
||||||
|
Огромное спасибо за помощь в сборке пакетов AWG 2.0:
|
||||||
|
|
||||||
|
- [@kozhini](https://github.com/kozhini) и [@this-username-has-been-taken](https://github.com/this-username-has-been-taken) — ~~у которых я позаимствовал код Makefile-ов~~ чьим примером я вдохновлялся🙃
|
||||||
|
- [@Kot-nikot](https://github.com/Kot-nikot) и [@Onotot](https://github.com/Onotot) — за полезные материалы и подсказки🤝
|
||||||
|
- [@ygurov](https://github.com/ygurov) - за [имплементацию](https://github.com/amnezia-vpn/amneziawg-linux-kernel-module/pull/88) awg 2.0 для модуля ядра 💪
|
||||||
|
- А также всем, кто приносил полезные примеры в личку и в [ишью](https://github.com/Slava-Shchipunov/awg-openwrt/issues/39), отписывались в комменты к PR с имплементацией о возникших багах и проблемах ❤️
|
||||||
|
|
||||||
|
## Automatic configuration of AmneziaWG for OpenWRT version 23.05.0 and newer
|
||||||
|
1) If your router has enough available ROM, I recommend using the script described below only to install the necessary packages, and use podkop from user [@itdoginfo](https://github.com/itdoginfo) for selective traffic routing into the tunnel - the setup process is described in the [documentation](https://podkop.net/docs/tunnels/awg_settings/)
|
||||||
|
|
||||||
|
2) If you only need to install packages, I added the amneziawg-install script - it will automatically download packages from this repository for your device (only for the stable version of OpenWRT), and also offer to immediately configure the interface with the AmneziaWG protocol. If the user agrees, you will need to enter the config parameters that the script will request. The script will create an interface, configure firewall rules for it, and also **enable redirection of all traffic through the AmneziaWG tunnel** (check the Route Allowed IPs box in the Peer settings).
|
||||||
To run the script, connect to the router via SSH, enter the command and follow the instructions on the screen:
|
To run the script, connect to the router via SSH, enter the command and follow the instructions on the screen:
|
||||||
```
|
```
|
||||||
sh <(wget -O - https://raw.githubusercontent.com/Slava-Shchipunov/awg-openwrt/refs/heads/master/amneziawg-install.sh)
|
sh <(wget -O - https://raw.githubusercontent.com/Slava-Shchipunov/awg-openwrt/refs/heads/master/amneziawg-install.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
3) In addition, for automatic configuration you can also use the [script](https://github.com/itdoginfo/domain-routing-openwrt) from user [@itdoginfo](https://github.com/itdoginfo). This script allows you to automatically download the necessary packages from those collected here and configure [point-by-point bypass of blocking by domains](https://habr.com/ru/articles/767464/) (instructions in Russian). Suitable if you have a weak router with insufficient ROM to install podkop and its dependencies
|
||||||
|
|
||||||
# Building packages for all devices that support OpenWRT
|
# Building packages for all devices that support OpenWRT
|
||||||
A script has been added to the repository that parses data on supported platforms from the OpenWRT page and automatically starts building AmneziaWG packages for all devices.
|
A script has been added to the repository that parses data on supported platforms from the OpenWRT page and automatically starts building AmneziaWG packages for all devices.
|
||||||
At the moment I have collected packages for all devices for OpenWRT versions:
|
At the moment I have collected packages for all devices for OpenWRT versions:
|
||||||
@@ -62,18 +88,23 @@ At the moment I have collected packages for all devices for OpenWRT versions:
|
|||||||
3) [23.05.2](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v23.05.2)
|
3) [23.05.2](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v23.05.2)
|
||||||
4) [23.05.3](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v23.05.3)
|
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)
|
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)
|
||||||
And collected packages for popular devices for OpenWRT [SNAPSHOT](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/SNAPSHOT)
|
7) AWG-2.0 [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) ([AWG-2.0 for 24.10.0](https://github.com/yanjore/awg-openwrt/releases/tag/v24.10.0) from fork)
|
||||||
|
9) [24.10.1](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.1) ([AWG-2.0 for 24.10.1](https://github.com/yanjore/awg-openwrt/releases/tag/v24.10.1) from fork)
|
||||||
|
10) [24.10.2](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.2) ([AWG-2.0 for 24.10.2](https://github.com/yanjore/awg-openwrt/releases/tag/v24.10.2) from fork)
|
||||||
|
11) AWG-2.0 [24.10.3](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.3)
|
||||||
|
12) AWG-2.0 [24.10.4](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.4)
|
||||||
|
13) AWG-2.0 [24.10.5](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.5)
|
||||||
|
14) AWG-2.0 [25.12.0](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v25.12.0)
|
||||||
|
|
||||||
I also ran the build for version [22.03.7](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v22.03.7), but the build ended with an error for two platforms. Since this is a fairly old version of OpenWRT, I did not bother to figure out what the problem was.
|
I also ran the build for version [22.03.7](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v22.03.7), but the build ended with an error for two platforms. Since this is a fairly old version of OpenWRT, I did not bother to figure out what the problem was.
|
||||||
|
|
||||||
In the future, when new OpenWRT releases are released, releases with AmneziaWG packages will be automatically created and the package build will be launched for all devices supported by the new version. Github action for checking for a new release is launched automatically every 3 days, and can also be launched manually.
|
|
||||||
|
|
||||||
## Automatic package build for SNAPSHOT version
|
## Automatic package build for SNAPSHOT version
|
||||||
A github action is configured in the repository, which runs every 4 hours and checks the [snapshots page](https://downloads.openwrt.org/snapshots/targets/) of the OpenWRT website. At the same time, if a snapshot with a newer kernel version is found for some platform, the package build for this platform is launched, and the new files replace the old ones. In order to save resources and speed up the build process, packages are built only for popular platforms, which are specified in the `SNAPSHOT_SUBTARGETS_TO_BUILD` array in the index.js file.
|
A github action is configured in the repository, which runs every 4 hours and checks the [snapshots page](https://downloads.openwrt.org/snapshots/targets/) of the OpenWRT website. At the same time, if a snapshot with a newer kernel version is found for some platform, the package build for this platform is launched, and the new files replace the old ones. In order to save resources and speed up the build process, packages are built only for popular platforms, which are specified in the `SNAPSHOT_SUBTARGETS_TO_BUILD` array in the index.js file.
|
||||||
|
|
||||||
## Selecting packages for your device
|
## Selecting packages for your device
|
||||||
In accordance with the paragraph [Specify variables for builds](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) (instructions in Russian) determine `target` and `subtarget` of your device. Then go to the release page corresponding to your OpenWRT version, then search the page (Ctrl+F) to find 3 packages whose names end in `target_subtarget.ipk` corresponding to your device.
|
In accordance with the paragraph [Specify variables for builds](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) (instructions in Russian) determine `target` and `subtarget` of your device. Then go to the release page corresponding to your OpenWRT version, then search the page (Ctrl+F) to find 3 packages whose names end in `target_subtarget.ipk` corresponding to your device. For AWG 2.0 version, Russian localization package luci-i18n-amneziawg-ru is also available
|
||||||
|
|
||||||
## How to run a build for all supported devices
|
## How to run a build for all supported devices
|
||||||
1) Create a fork of this repository
|
1) Create a fork of this repository
|
||||||
@@ -84,8 +115,16 @@ In accordance with the paragraph [Specify variables for builds](https://github.c
|
|||||||
6) Enter Release title
|
6) Enter Release title
|
||||||
7) Click the green Publish release button at the bottom
|
7) Click the green Publish release button at the bottom
|
||||||
|
|
||||||
For public repositories, Github provides unlimited use of runners, I had up to 20 parallel jobs running. Each job takes about 2 hours, the total build time is about 10 hours.
|
For public repositories, Github provides unlimited use of runners, I had up to 20 parallel jobs running. Each job takes about 10-15 minutes, the total build time is about 60 minutes.
|
||||||
If errors occur in one job, all unfinished ones will be canceled - in this case, you can select the failed launch on the Actions tab and click Re-run failed jobs
|
|
||||||
|
|
||||||
## Building packages for a specific platform
|
## Building packages for a specific platform
|
||||||
You can see how to start building packages for a specific platform in the [wiki instructions](https://github.com/itdoginfo/domain-routing-openwrt/wiki/Amnezia-WG-Build) (instructions in Russian). Building for one device will take about 2 hours.
|
You can see how to start building AWG 1.0 packages for a specific platform in the [wiki instructions](https://github.com/itdoginfo/domain-routing-openwrt/wiki/Amnezia-WG-Build) (instructions in Russian). Building for one device will take about 2 hours.
|
||||||
|
|
||||||
|
AWG 2.0 can be built for a specific platform as follows:
|
||||||
|
1) Create a fork of this repository
|
||||||
|
2) Switch to the Actions tab and enable Github actions (they are disabled for forks by default)
|
||||||
|
3) On the left in the list of actions, select the Create Release on Tag action
|
||||||
|
4) On the right, click the Run workflow button
|
||||||
|
5) In the opened list, specify the OpenWRT version (for example, 24.10.3), a list of targets separated by commas (for example, stm32,ramips), a list of subtargets separated by commas (for example, stm32mp1,mt7621). The build will be performed only for existing target/subtarget pairs
|
||||||
|
6) Click the green Run workflow button
|
||||||
|
Building for one device will take about 10-15 minutes. A release with the specified OpenWRT version should be created
|
||||||
|
|||||||
@@ -2,32 +2,154 @@
|
|||||||
|
|
||||||
#set -x
|
#set -x
|
||||||
|
|
||||||
|
PKG_MANAGER=""
|
||||||
|
PKG_EXT=""
|
||||||
|
|
||||||
|
detect_package_manager() {
|
||||||
|
if command -v apk >/dev/null 2>&1; then
|
||||||
|
PKG_MANAGER="apk"
|
||||||
|
PKG_EXT="apk"
|
||||||
|
elif command -v opkg >/dev/null 2>&1; then
|
||||||
|
PKG_MANAGER="opkg"
|
||||||
|
PKG_EXT="ipk"
|
||||||
|
else
|
||||||
|
printf "\033[32;1mNo supported package manager found (apk/opkg).\033[0m\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
pkg_update() {
|
||||||
|
if [ "$PKG_MANAGER" = "apk" ]; then
|
||||||
|
apk update
|
||||||
|
else
|
||||||
|
opkg update
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
is_pkg_installed() {
|
||||||
|
pkg_name="$1"
|
||||||
|
if [ "$PKG_MANAGER" = "apk" ]; then
|
||||||
|
apk info -e "$pkg_name" >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
opkg list-installed 2>/dev/null | grep -q "^${pkg_name} "
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
install_local_pkg() {
|
||||||
|
pkg_file="$1"
|
||||||
|
if [ "$PKG_MANAGER" = "apk" ]; then
|
||||||
|
apk add --allow-untrusted "$pkg_file"
|
||||||
|
else
|
||||||
|
opkg install "$pkg_file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
get_pkgarch() {
|
||||||
|
PKGARCH_UBUS=$(ubus call system board 2>/dev/null | jsonfilter -e '@.release.arch' 2>/dev/null)
|
||||||
|
if [ -n "$PKGARCH_UBUS" ]; then
|
||||||
|
echo "$PKGARCH_UBUS"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v opkg >/dev/null 2>&1; then
|
||||||
|
opkg print-architecture | awk 'BEGIN {max=0} {if ($3 > max) {max = $3; arch = $2}} END {print arch}'
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f /etc/openwrt_release ]; then
|
||||||
|
PKGARCH_RELEASE=$(grep "^DISTRIB_ARCH='" /etc/openwrt_release | cut -d"'" -f2)
|
||||||
|
if [ -n "$PKGARCH_RELEASE" ]; then
|
||||||
|
echo "$PKGARCH_RELEASE"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v apk >/dev/null 2>&1; then
|
||||||
|
apk --print-arch
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
uname -m
|
||||||
|
}
|
||||||
|
|
||||||
|
download_package() {
|
||||||
|
pkg_base_name="$1"
|
||||||
|
pkg_postfix_base="$2"
|
||||||
|
awg_dir="$3"
|
||||||
|
base_url="$4"
|
||||||
|
|
||||||
|
preferred_file="${pkg_base_name}${pkg_postfix_base}.${PKG_EXT}"
|
||||||
|
preferred_url="${base_url}${preferred_file}"
|
||||||
|
if wget -q -O "$awg_dir/$preferred_file" "$preferred_url" && [ -s "$awg_dir/$preferred_file" ]; then
|
||||||
|
echo "$preferred_file"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
rm -f "$awg_dir/$preferred_file"
|
||||||
|
|
||||||
|
if [ "$PKG_EXT" = "apk" ]; then
|
||||||
|
fallback_ext="ipk"
|
||||||
|
else
|
||||||
|
fallback_ext="apk"
|
||||||
|
fi
|
||||||
|
|
||||||
|
fallback_file="${pkg_base_name}${pkg_postfix_base}.${fallback_ext}"
|
||||||
|
fallback_url="${base_url}${fallback_file}"
|
||||||
|
if wget -q -O "$awg_dir/$fallback_file" "$fallback_url" && [ -s "$awg_dir/$fallback_file" ]; then
|
||||||
|
echo "$fallback_file"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
rm -f "$awg_dir/$fallback_file"
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
#Репозиторий OpenWRT должен быть доступен для установки зависимостей пакета kmod-amneziawg
|
#Репозиторий OpenWRT должен быть доступен для установки зависимостей пакета kmod-amneziawg
|
||||||
check_repo() {
|
check_repo() {
|
||||||
printf "\033[32;1mChecking OpenWrt repo availability...\033[0m\n"
|
printf "\033[32;1mChecking OpenWrt repo availability...\033[0m\n"
|
||||||
opkg update | grep -q "Failed to download" && printf "\033[32;1mopkg failed. Check internet or date. Command for force ntp sync: ntpd -p ptbtime1.ptb.de\033[0m\n" && exit 1
|
if [ "$PKG_MANAGER" = "apk" ]; then
|
||||||
|
pkg_update >/dev/null 2>&1 || \
|
||||||
|
{ printf "\033[32;1mapk failed. Check internet or date. Command for force ntp sync: ntpd -p ptbtime1.ptb.de\033[0m\n"; exit 1; }
|
||||||
|
else
|
||||||
|
pkg_update | grep -q "Failed to download" && \
|
||||||
|
printf "\033[32;1mopkg failed. Check internet or date. Command for force ntp sync: ntpd -p ptbtime1.ptb.de\033[0m\n" && exit 1
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
install_awg_packages() {
|
install_awg_packages() {
|
||||||
# Получение pkgarch с наибольшим приоритетом
|
# Получение pkgarch с наибольшим приоритетом
|
||||||
PKGARCH=$(opkg print-architecture | awk 'BEGIN {max=0} {if ($3 > max) {max = $3; arch = $2}} END {print arch}')
|
PKGARCH=$(get_pkgarch)
|
||||||
|
|
||||||
TARGET=$(ubus call system board | jsonfilter -e '@.release.target' | cut -d '/' -f 1)
|
TARGET=$(ubus call system board | jsonfilter -e '@.release.target' | cut -d '/' -f 1)
|
||||||
SUBTARGET=$(ubus call system board | jsonfilter -e '@.release.target' | cut -d '/' -f 2)
|
SUBTARGET=$(ubus call system board | jsonfilter -e '@.release.target' | cut -d '/' -f 2)
|
||||||
VERSION=$(ubus call system board | jsonfilter -e '@.release.version')
|
VERSION=$(ubus call system board | jsonfilter -e '@.release.version')
|
||||||
PKGPOSTFIX="_v${VERSION}_${PKGARCH}_${TARGET}_${SUBTARGET}.ipk"
|
PKGPOSTFIX_BASE="_v${VERSION}_${PKGARCH}_${TARGET}_${SUBTARGET}"
|
||||||
BASE_URL="https://github.com/Slava-Shchipunov/awg-openwrt/releases/download/"
|
BASE_URL="https://github.com/Slava-Shchipunov/awg-openwrt/releases/download/"
|
||||||
|
|
||||||
|
# Определяем версию AWG протокола (2.0 для OpenWRT >= 23.05.6 и >= 24.10.3)
|
||||||
|
AWG_VERSION="1.0"
|
||||||
|
MAJOR_VERSION=$(echo "$VERSION" | cut -d '.' -f 1)
|
||||||
|
MINOR_VERSION=$(echo "$VERSION" | cut -d '.' -f 2)
|
||||||
|
PATCH_VERSION=$(echo "$VERSION" | cut -d '.' -f 3)
|
||||||
|
|
||||||
|
if [ "$MAJOR_VERSION" -gt 24 ] || \
|
||||||
|
[ "$MAJOR_VERSION" -eq 24 -a "$MINOR_VERSION" -gt 10 ] || \
|
||||||
|
[ "$MAJOR_VERSION" -eq 24 -a "$MINOR_VERSION" -eq 10 -a "$PATCH_VERSION" -ge 3 ] || \
|
||||||
|
[ "$MAJOR_VERSION" -eq 23 -a "$MINOR_VERSION" -eq 5 -a "$PATCH_VERSION" -ge 6 ]; then
|
||||||
|
AWG_VERSION="2.0"
|
||||||
|
LUCI_PACKAGE_NAME="luci-proto-amneziawg"
|
||||||
|
else
|
||||||
|
LUCI_PACKAGE_NAME="luci-app-amneziawg"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "\033[32;1mDetected AWG version: $AWG_VERSION\033[0m\n"
|
||||||
|
|
||||||
AWG_DIR="/tmp/amneziawg"
|
AWG_DIR="/tmp/amneziawg"
|
||||||
mkdir -p "$AWG_DIR"
|
mkdir -p "$AWG_DIR"
|
||||||
|
|
||||||
if opkg list-installed | grep -q kmod-amneziawg; then
|
if is_pkg_installed "kmod-amneziawg"; then
|
||||||
echo "kmod-amneziawg already installed"
|
echo "kmod-amneziawg already installed"
|
||||||
else
|
else
|
||||||
KMOD_AMNEZIAWG_FILENAME="kmod-amneziawg${PKGPOSTFIX}"
|
KMOD_AMNEZIAWG_FILENAME=$(download_package "kmod-amneziawg" "$PKGPOSTFIX_BASE" "$AWG_DIR" "${BASE_URL}v${VERSION}/")
|
||||||
DOWNLOAD_URL="${BASE_URL}v${VERSION}/${KMOD_AMNEZIAWG_FILENAME}"
|
|
||||||
wget -O "$AWG_DIR/$KMOD_AMNEZIAWG_FILENAME" "$DOWNLOAD_URL"
|
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo "kmod-amneziawg file downloaded successfully"
|
echo "kmod-amneziawg file downloaded successfully"
|
||||||
else
|
else
|
||||||
@@ -35,23 +157,20 @@ install_awg_packages() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
opkg install "$AWG_DIR/$KMOD_AMNEZIAWG_FILENAME"
|
install_local_pkg "$AWG_DIR/$KMOD_AMNEZIAWG_FILENAME"
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo "kmod-amneziawg file downloaded successfully"
|
echo "kmod-amneziawg installed successfully"
|
||||||
else
|
else
|
||||||
echo "Error installing kmod-amneziawg. Please, install kmod-amneziawg manually and run the script again"
|
echo "Error installing kmod-amneziawg. Please, install kmod-amneziawg manually and run the script again"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if opkg list-installed | grep -q amneziawg-tools; then
|
if is_pkg_installed "amneziawg-tools"; then
|
||||||
echo "amneziawg-tools already installed"
|
echo "amneziawg-tools already installed"
|
||||||
else
|
else
|
||||||
AMNEZIAWG_TOOLS_FILENAME="amneziawg-tools${PKGPOSTFIX}"
|
AMNEZIAWG_TOOLS_FILENAME=$(download_package "amneziawg-tools" "$PKGPOSTFIX_BASE" "$AWG_DIR" "${BASE_URL}v${VERSION}/")
|
||||||
DOWNLOAD_URL="${BASE_URL}v${VERSION}/${AMNEZIAWG_TOOLS_FILENAME}"
|
|
||||||
wget -O "$AWG_DIR/$AMNEZIAWG_TOOLS_FILENAME" "$DOWNLOAD_URL"
|
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo "amneziawg-tools file downloaded successfully"
|
echo "amneziawg-tools file downloaded successfully"
|
||||||
else
|
else
|
||||||
@@ -59,40 +178,66 @@ install_awg_packages() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
opkg install "$AWG_DIR/$AMNEZIAWG_TOOLS_FILENAME"
|
install_local_pkg "$AWG_DIR/$AMNEZIAWG_TOOLS_FILENAME"
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo "amneziawg-tools file downloaded successfully"
|
echo "amneziawg-tools installed successfully"
|
||||||
else
|
else
|
||||||
echo "Error installing amneziawg-tools. Please, install amneziawg-tools manually and run the script again"
|
echo "Error installing amneziawg-tools. Please, install amneziawg-tools manually and run the script again"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if opkg list-installed | grep -q luci-app-amneziawg; then
|
# Проверяем оба возможных названия пакета
|
||||||
echo "luci-app-amneziawg already installed"
|
if is_pkg_installed "luci-proto-amneziawg" || is_pkg_installed "luci-app-amneziawg"; then
|
||||||
|
echo "$LUCI_PACKAGE_NAME already installed"
|
||||||
else
|
else
|
||||||
LUCI_APP_AMNEZIAWG_FILENAME="luci-app-amneziawg${PKGPOSTFIX}"
|
LUCI_AMNEZIAWG_FILENAME=$(download_package "$LUCI_PACKAGE_NAME" "$PKGPOSTFIX_BASE" "$AWG_DIR" "${BASE_URL}v${VERSION}/")
|
||||||
DOWNLOAD_URL="${BASE_URL}v${VERSION}/${LUCI_APP_AMNEZIAWG_FILENAME}"
|
|
||||||
wget -O "$AWG_DIR/$LUCI_APP_AMNEZIAWG_FILENAME" "$DOWNLOAD_URL"
|
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo "luci-app-amneziawg file downloaded successfully"
|
echo "$LUCI_PACKAGE_NAME file downloaded successfully"
|
||||||
else
|
else
|
||||||
echo "Error downloading luci-app-amneziawg. Please, install luci-app-amneziawg manually and run the script again"
|
echo "Error downloading $LUCI_PACKAGE_NAME. Please, install $LUCI_PACKAGE_NAME manually and run the script again"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
opkg install "$AWG_DIR/$LUCI_APP_AMNEZIAWG_FILENAME"
|
install_local_pkg "$AWG_DIR/$LUCI_AMNEZIAWG_FILENAME"
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo "luci-app-amneziawg file downloaded successfully"
|
echo "$LUCI_PACKAGE_NAME installed successfully"
|
||||||
else
|
else
|
||||||
echo "Error installing luci-app-amneziawg. Please, install luci-app-amneziawg manually and run the script again"
|
echo "Error installing $LUCI_PACKAGE_NAME. Please, install $LUCI_PACKAGE_NAME manually and run the script again"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Устанавливаем русскую локализацию только для AWG 2.0
|
||||||
|
if [ "$AWG_VERSION" = "2.0" ]; then
|
||||||
|
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 is_pkg_installed "luci-i18n-amneziawg-ru"; then
|
||||||
|
echo "luci-i18n-amneziawg-ru already installed"
|
||||||
|
else
|
||||||
|
LUCI_I18N_AMNEZIAWG_RU_FILENAME=$(download_package "luci-i18n-amneziawg-ru" "$PKGPOSTFIX_BASE" "$AWG_DIR" "${BASE_URL}v${VERSION}/")
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "luci-i18n-amneziawg-ru file downloaded successfully"
|
||||||
|
install_local_pkg "$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
|
||||||
|
fi
|
||||||
|
|
||||||
rm -rf "$AWG_DIR"
|
rm -rf "$AWG_DIR"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,6 +278,17 @@ configure_amneziawg_interface() {
|
|||||||
read -r -p "Enter H3 value (from [Interface]):"$'\n' AWG_H3
|
read -r -p "Enter H3 value (from [Interface]):"$'\n' AWG_H3
|
||||||
read -r -p "Enter H4 value (from [Interface]):"$'\n' AWG_H4
|
read -r -p "Enter H4 value (from [Interface]):"$'\n' AWG_H4
|
||||||
|
|
||||||
|
# AWG 2.0 новые параметры
|
||||||
|
if [ "$AWG_VERSION" = "2.0" ]; then
|
||||||
|
read -r -p "Enter S3 value (from [Interface]) [optional, leave blank to skip]:"$'\n' AWG_S3
|
||||||
|
read -r -p "Enter S4 value (from [Interface]) [optional, leave blank to skip]:"$'\n' AWG_S4
|
||||||
|
read -r -p "Enter I1 value (from [Interface]) [optional, leave blank to skip]:"$'\n' AWG_I1
|
||||||
|
read -r -p "Enter I2 value (from [Interface]) [optional, leave blank to skip]:"$'\n' AWG_I2
|
||||||
|
read -r -p "Enter I3 value (from [Interface]) [optional, leave blank to skip]:"$'\n' AWG_I3
|
||||||
|
read -r -p "Enter I4 value (from [Interface]) [optional, leave blank to skip]:"$'\n' AWG_I4
|
||||||
|
read -r -p "Enter I5 value (from [Interface]) [optional, leave blank to skip]:"$'\n' AWG_I5
|
||||||
|
fi
|
||||||
|
|
||||||
uci set network.${INTERFACE_NAME}=interface
|
uci set network.${INTERFACE_NAME}=interface
|
||||||
uci set network.${INTERFACE_NAME}.proto=$PROTO
|
uci set network.${INTERFACE_NAME}.proto=$PROTO
|
||||||
uci set network.${INTERFACE_NAME}.private_key=$AWG_PRIVATE_KEY_INT
|
uci set network.${INTERFACE_NAME}.private_key=$AWG_PRIVATE_KEY_INT
|
||||||
@@ -149,6 +305,17 @@ configure_amneziawg_interface() {
|
|||||||
uci set network.${INTERFACE_NAME}.awg_h3=$AWG_H3
|
uci set network.${INTERFACE_NAME}.awg_h3=$AWG_H3
|
||||||
uci set network.${INTERFACE_NAME}.awg_h4=$AWG_H4
|
uci set network.${INTERFACE_NAME}.awg_h4=$AWG_H4
|
||||||
|
|
||||||
|
# Устанавливаем новые параметры для AWG 2.0 (только если они заданы)
|
||||||
|
if [ "$AWG_VERSION" = "2.0" ]; then
|
||||||
|
[ -n "$AWG_S3" ] && uci set network.${INTERFACE_NAME}.awg_s3=$AWG_S3
|
||||||
|
[ -n "$AWG_S4" ] && uci set network.${INTERFACE_NAME}.awg_s4=$AWG_S4
|
||||||
|
[ -n "$AWG_I1" ] && uci set network.${INTERFACE_NAME}.awg_i1=$AWG_I1
|
||||||
|
[ -n "$AWG_I2" ] && uci set network.${INTERFACE_NAME}.awg_i2=$AWG_I2
|
||||||
|
[ -n "$AWG_I3" ] && uci set network.${INTERFACE_NAME}.awg_i3=$AWG_I3
|
||||||
|
[ -n "$AWG_I4" ] && uci set network.${INTERFACE_NAME}.awg_i4=$AWG_I4
|
||||||
|
[ -n "$AWG_I5" ] && uci set network.${INTERFACE_NAME}.awg_i5=$AWG_I5
|
||||||
|
fi
|
||||||
|
|
||||||
if ! uci show network | grep -q ${CONFIG_NAME}; then
|
if ! uci show network | grep -q ${CONFIG_NAME}; then
|
||||||
uci add network ${CONFIG_NAME}
|
uci add network ${CONFIG_NAME}
|
||||||
fi
|
fi
|
||||||
@@ -189,8 +356,11 @@ configure_amneziawg_interface() {
|
|||||||
uci set firewall.@forwarding[-1].family='ipv4'
|
uci set firewall.@forwarding[-1].family='ipv4'
|
||||||
uci commit firewall
|
uci commit firewall
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
service network restart
|
||||||
}
|
}
|
||||||
|
|
||||||
|
detect_package_manager
|
||||||
check_repo
|
check_repo
|
||||||
|
|
||||||
install_awg_packages
|
install_awg_packages
|
||||||
@@ -203,5 +373,3 @@ if [ "$IS_SHOULD_CONFIGURE_AWG_INTERFACE" = "y" ] || [ "$IS_SHOULD_CONFIGURE_AWG
|
|||||||
else
|
else
|
||||||
printf "\033[32;1mSkipping amneziawg interface configuration.\033[0m\n"
|
printf "\033[32;1mSkipping amneziawg interface configuration.\033[0m\n"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
service network restart
|
|
||||||
|
|||||||
@@ -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
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=amneziawg-tools
|
PKG_NAME:=amneziawg-tools
|
||||||
|
PKG_VERSION:=1.0.20260223
|
||||||
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
PKG_VERSION:=1.0.20240213
|
PKG_SOURCE_PROTO:=git
|
||||||
PKG_RELEASE:=$(AUTORELEASE)
|
PKG_SOURCE_URL:=https://github.com/amnezia-vpn/amneziawg-tools.git
|
||||||
|
# Version: latest stable release tag
|
||||||
PKG_SOURCE:=v$(PKG_VERSION).tar.gz
|
PKG_SOURCE_VERSION:=v$(PKG_VERSION)
|
||||||
PKG_SOURCE_URL:=https://github.com/amnezia-vpn/amneziawg-tools/archive/refs/tags/
|
|
||||||
PKG_HASH:=4bde122630c9ddb1ec013c3e958f2c613b9eea56834674dda92fcb423c6f4d10
|
|
||||||
|
|
||||||
PKG_LICENSE:=GPL-2.0
|
PKG_LICENSE:=GPL-2.0
|
||||||
PKG_LICENSE_FILES:=COPYING
|
PKG_LICENSE_FILES:=COPYING
|
||||||
|
|
||||||
|
PKG_BUILD_DIR=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
@@ -28,29 +21,26 @@ MAKE_VARS += PLATFORM=linux
|
|||||||
|
|
||||||
define Package/amneziawg-tools
|
define Package/amneziawg-tools
|
||||||
CATEGORY:=Network
|
CATEGORY:=Network
|
||||||
URL:=https://www.wireguard.com
|
SUBMENU:=VPN
|
||||||
MAINTAINER:=Jason A. Donenfeld <Jason@zx2c4.com>
|
URL:=https://amnezia.org/
|
||||||
TITLE:=WireGuard userspace control program (wg)
|
MAINTAINER:=Amnezia Admin <admin@amnezia.org>
|
||||||
|
TITLE:=AmneziaWG userspace control program (awg)
|
||||||
DEPENDS:= \
|
DEPENDS:= \
|
||||||
+@BUSYBOX_CONFIG_IP \
|
+@BUSYBOX_CONFIG_IP \
|
||||||
+@BUSYBOX_CONFIG_FEATURE_IP_LINK
|
+@BUSYBOX_CONFIG_FEATURE_IP_LINK
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/amneziawg-tools/description
|
define Package/amneziawg-tools/description
|
||||||
WireGuard is a novel VPN that runs inside the Linux Kernel and utilizes
|
Amnezia VPN — simple and free app to run a self-hosted VPN with
|
||||||
state-of-the-art cryptography. It aims to be faster, simpler, leaner, and
|
high privacy requirements.
|
||||||
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.
|
|
||||||
|
|
||||||
This package provides the userspace control program for WireGuard,
|
This package provides the userspace control program for AmneziaWG,
|
||||||
`wg(8)`, a netifd protocol helper, and a re-resolve watchdog script.
|
`awg`, a netifd protocol helper, and a re-resolve watchdog script.
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/amneziawg-tools/install
|
define Package/amneziawg-tools/install
|
||||||
$(INSTALL_DIR) $(1)/usr/bin/
|
$(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_BIN) ./files/amneziawg_watchdog $(1)/usr/bin/
|
||||||
$(INSTALL_DIR) $(1)/lib/netifd/proto/
|
$(INSTALL_DIR) $(1)/lib/netifd/proto/
|
||||||
$(INSTALL_BIN) ./files/amneziawg.sh $(1)/lib/netifd/proto/
|
$(INSTALL_BIN) ./files/amneziawg.sh $(1)/lib/netifd/proto/
|
||||||
|
|||||||
@@ -2,9 +2,11 @@
|
|||||||
# Copyright 2016-2017 Dan Luedtke <mail@danrl.com>
|
# Copyright 2016-2017 Dan Luedtke <mail@danrl.com>
|
||||||
# Licensed to the public under the Apache License 2.0.
|
# Licensed to the public under the Apache License 2.0.
|
||||||
|
|
||||||
WG=/usr/bin/amneziawg
|
# shellcheck disable=SC1091,SC3003,SC3043
|
||||||
if [ ! -x $WG ]; then
|
|
||||||
logger -t "amnezia-wg" "error: missing amneziawg-tools (${WG})"
|
AWG=/usr/bin/awg
|
||||||
|
if [ ! -x $AWG ]; then
|
||||||
|
logger -t "amneziawg" "error: missing amneziawg-tools (${AWG})"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -24,25 +26,34 @@ proto_amneziawg_init_config() {
|
|||||||
proto_config_add_int "awg_jmax"
|
proto_config_add_int "awg_jmax"
|
||||||
proto_config_add_int "awg_s1"
|
proto_config_add_int "awg_s1"
|
||||||
proto_config_add_int "awg_s2"
|
proto_config_add_int "awg_s2"
|
||||||
proto_config_add_int "awg_h1"
|
proto_config_add_int "awg_s3"
|
||||||
proto_config_add_int "awg_h2"
|
proto_config_add_int "awg_s4"
|
||||||
proto_config_add_int "awg_h3"
|
proto_config_add_string "awg_h1"
|
||||||
proto_config_add_int "awg_h4"
|
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
|
available=1
|
||||||
|
# shellcheck disable=SC2034
|
||||||
no_proto_task=1
|
no_proto_task=1
|
||||||
}
|
}
|
||||||
|
|
||||||
proto_amneziawg_is_kernel_mode() {
|
proto_amneziawg_is_kernel_mode() {
|
||||||
if [ ! -e /sys/module/amneziawg ]; then
|
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
|
if [ -e /sys/module/amneziawg ]; then
|
||||||
return 0
|
return 0
|
||||||
else
|
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=$?
|
ret=$?
|
||||||
echo "Please install either kernel module (kmod-amneziawg package) or user-space implementation in /usr/bin/amneziawg-go."
|
echo "Please install either kernel module (kmod-amneziawg package) or user-space implementation in /usr/bin/amneziawg-go."
|
||||||
exit $?
|
exit $ret
|
||||||
else
|
else
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@@ -83,13 +94,13 @@ proto_amneziawg_setup_peer() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "[Peer]" >> "${wg_cfg}"
|
echo "[Peer]" >> "${awg_cfg}"
|
||||||
echo "PublicKey=${public_key}" >> "${wg_cfg}"
|
echo "PublicKey=${public_key}" >> "${awg_cfg}"
|
||||||
if [ "${preshared_key}" ]; then
|
if [ "${preshared_key}" ]; then
|
||||||
echo "PresharedKey=${preshared_key}" >> "${wg_cfg}"
|
echo "PresharedKey=${preshared_key}" >> "${awg_cfg}"
|
||||||
fi
|
fi
|
||||||
for allowed_ip in $allowed_ips; do
|
for allowed_ip in ${allowed_ips}; do
|
||||||
echo "AllowedIPs=${allowed_ip}" >> "${wg_cfg}"
|
echo "AllowedIPs=${allowed_ip}" >> "${awg_cfg}"
|
||||||
done
|
done
|
||||||
if [ "${endpoint_host}" ]; then
|
if [ "${endpoint_host}" ]; then
|
||||||
case "${endpoint_host}" in
|
case "${endpoint_host}" in
|
||||||
@@ -105,10 +116,10 @@ proto_amneziawg_setup_peer() {
|
|||||||
else
|
else
|
||||||
endpoint="${endpoint}:51820"
|
endpoint="${endpoint}:51820"
|
||||||
fi
|
fi
|
||||||
echo "Endpoint=${endpoint}" >> "${wg_cfg}"
|
echo "Endpoint=${endpoint}" >> "${awg_cfg}"
|
||||||
fi
|
fi
|
||||||
if [ "${persistent_keepalive}" ]; then
|
if [ "${persistent_keepalive}" ]; then
|
||||||
echo "PersistentKeepalive=${persistent_keepalive}" >> "${wg_cfg}"
|
echo "PersistentKeepalive=${persistent_keepalive}" >> "${awg_cfg}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ${route_allowed_ips} -ne 0 ]; then
|
if [ ${route_allowed_ips} -ne 0 ]; then
|
||||||
@@ -140,7 +151,7 @@ ensure_key_is_generated() {
|
|||||||
oldmask="$(umask)"
|
oldmask="$(umask)"
|
||||||
umask 077
|
umask 077
|
||||||
ucitmp="$(mktemp -d)"
|
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" set network."$1".private_key="$private_key" && \
|
||||||
uci -q -t "$ucitmp" commit network
|
uci -q -t "$ucitmp" commit network
|
||||||
rm -rf "$ucitmp"
|
rm -rf "$ucitmp"
|
||||||
@@ -150,23 +161,35 @@ ensure_key_is_generated() {
|
|||||||
|
|
||||||
proto_amneziawg_setup() {
|
proto_amneziawg_setup() {
|
||||||
local config="$1"
|
local config="$1"
|
||||||
local wg_dir="/tmp/wireguard"
|
local awg_dir="/tmp/amneziawg"
|
||||||
local wg_cfg="${wg_dir}/${config}"
|
local awg_cfg="${awg_dir}/${config}"
|
||||||
|
|
||||||
local private_key
|
local private_key
|
||||||
local listen_port
|
local listen_port
|
||||||
|
local addresses
|
||||||
local mtu
|
local mtu
|
||||||
|
local fwmark
|
||||||
|
local ip6prefix
|
||||||
|
local nohostroute
|
||||||
|
local tunlink
|
||||||
|
|
||||||
# Amnezia WG specific parameters
|
# AmneziaWG specific parameters
|
||||||
local awg_jc
|
local awg_jc
|
||||||
local awg_jmin
|
local awg_jmin
|
||||||
local awg_jmax
|
local awg_jmax
|
||||||
local awg_s1
|
local awg_s1
|
||||||
local awg_s2
|
local awg_s2
|
||||||
|
local awg_s3
|
||||||
|
local awg_s4
|
||||||
local awg_h1
|
local awg_h1
|
||||||
local awg_h2
|
local awg_h2
|
||||||
local awg_h3
|
local awg_h3
|
||||||
local awg_h4
|
local awg_h4
|
||||||
|
local awg_i1
|
||||||
|
local awg_i2
|
||||||
|
local awg_i3
|
||||||
|
local awg_i4
|
||||||
|
local awg_i5
|
||||||
|
|
||||||
ensure_key_is_generated "${config}"
|
ensure_key_is_generated "${config}"
|
||||||
|
|
||||||
@@ -185,18 +208,25 @@ proto_amneziawg_setup() {
|
|||||||
config_get awg_jmax "${config}" "awg_jmax"
|
config_get awg_jmax "${config}" "awg_jmax"
|
||||||
config_get awg_s1 "${config}" "awg_s1"
|
config_get awg_s1 "${config}" "awg_s1"
|
||||||
config_get awg_s2 "${config}" "awg_s2"
|
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_h1 "${config}" "awg_h1"
|
||||||
config_get awg_h2 "${config}" "awg_h2"
|
config_get awg_h2 "${config}" "awg_h2"
|
||||||
config_get awg_h3 "${config}" "awg_h3"
|
config_get awg_h3 "${config}" "awg_h3"
|
||||||
config_get awg_h4 "${config}" "awg_h4"
|
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
|
if proto_amneziawg_is_kernel_mode; then
|
||||||
logger -t "amneziawg" "info: using kernel-space kmod-amneziawg for ${WG}"
|
logger -t "amneziawg" "info: using kernel-space kmod-amneziawg for ${AWG}"
|
||||||
ip link del dev "${config}" 2>/dev/null
|
ip link del dev "${config}" 2>/dev/null
|
||||||
ip link add dev "${config}" type amneziawg
|
ip link add dev "${config}" type amneziawg
|
||||||
else
|
else
|
||||||
logger -t "amneziawg" "info: using user-space amneziawg-go for ${WG}"
|
logger -t "amneziawg" "info: using user-space amneziawg-go for ${AWG}"
|
||||||
rm -f "/var/run/wireguard/${config}.sock"
|
rm -f "/var/run/amneziawg/${config}.sock"
|
||||||
amneziawg-go "${config}"
|
amneziawg-go "${config}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -207,53 +237,73 @@ proto_amneziawg_setup() {
|
|||||||
proto_init_update "${config}" 1
|
proto_init_update "${config}" 1
|
||||||
|
|
||||||
umask 077
|
umask 077
|
||||||
mkdir -p "${wg_dir}"
|
mkdir -p "${awg_dir}"
|
||||||
echo "[Interface]" > "${wg_cfg}"
|
echo "[Interface]" > "${awg_cfg}"
|
||||||
echo "PrivateKey=${private_key}" >> "${wg_cfg}"
|
echo "PrivateKey=${private_key}" >> "${awg_cfg}"
|
||||||
if [ "${listen_port}" ]; then
|
if [ "${listen_port}" ]; then
|
||||||
echo "ListenPort=${listen_port}" >> "${wg_cfg}"
|
echo "ListenPort=${listen_port}" >> "${awg_cfg}"
|
||||||
fi
|
fi
|
||||||
if [ "${fwmark}" ]; then
|
if [ "${fwmark}" ]; then
|
||||||
echo "FwMark=${fwmark}" >> "${wg_cfg}"
|
echo "FwMark=${fwmark}" >> "${awg_cfg}"
|
||||||
fi
|
fi
|
||||||
# AWG
|
# AmneziaWG parameters
|
||||||
if [ "${awg_jc}" ]; then
|
if [ "${awg_jc}" ]; then
|
||||||
echo "Jc = ${awg_jc}" >> "${wg_cfg}"
|
echo "Jc=${awg_jc}" >> "${awg_cfg}"
|
||||||
fi
|
fi
|
||||||
if [ "${awg_jmin}" ]; then
|
if [ "${awg_jmin}" ]; then
|
||||||
echo "Jmin = ${awg_jmin}" >> "${wg_cfg}"
|
echo "Jmin=${awg_jmin}" >> "${awg_cfg}"
|
||||||
fi
|
fi
|
||||||
if [ "${awg_jmax}" ]; then
|
if [ "${awg_jmax}" ]; then
|
||||||
echo "Jmax = ${awg_jmax}" >> "${wg_cfg}"
|
echo "Jmax=${awg_jmax}" >> "${awg_cfg}"
|
||||||
fi
|
fi
|
||||||
if [ "${awg_s1}" ]; then
|
if [ "${awg_s1}" ]; then
|
||||||
echo "S1 = ${awg_s1}" >> "${wg_cfg}"
|
echo "S1=${awg_s1}" >> "${awg_cfg}"
|
||||||
fi
|
fi
|
||||||
if [ "${awg_s2}" ]; then
|
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
|
fi
|
||||||
if [ "${awg_h1}" ]; then
|
if [ "${awg_h1}" ]; then
|
||||||
echo "H1 = ${awg_h1}" >> "${wg_cfg}"
|
echo "H1=${awg_h1}" >> "${awg_cfg}"
|
||||||
fi
|
fi
|
||||||
if [ "${awg_h2}" ]; then
|
if [ "${awg_h2}" ]; then
|
||||||
echo "H2 = ${awg_h2}" >> "${wg_cfg}"
|
echo "H2=${awg_h2}" >> "${awg_cfg}"
|
||||||
fi
|
fi
|
||||||
if [ "${awg_h3}" ]; then
|
if [ "${awg_h3}" ]; then
|
||||||
echo "H3 = ${awg_h3}" >> "${wg_cfg}"
|
echo "H3=${awg_h3}" >> "${awg_cfg}"
|
||||||
fi
|
fi
|
||||||
if [ "${awg_h4}" ]; then
|
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
|
fi
|
||||||
|
|
||||||
config_foreach proto_amneziawg_setup_peer "amneziawg_${config}"
|
config_foreach proto_amneziawg_setup_peer "amneziawg_${config}"
|
||||||
|
|
||||||
# apply configuration file
|
# Apply configuration file
|
||||||
${WG} setconf ${config} "${wg_cfg}"
|
${AWG} setconf "${config}" "${awg_cfg}"
|
||||||
WG_RETURN=$?
|
AWG_RETURN=$?
|
||||||
|
|
||||||
rm -f "${wg_cfg}"
|
rm -f "${awg_cfg}"
|
||||||
|
|
||||||
if [ ${WG_RETURN} -ne 0 ]; then
|
if [ ${AWG_RETURN} -ne 0 ]; then
|
||||||
sleep 5
|
sleep 5
|
||||||
proto_setup_failed "${config}"
|
proto_setup_failed "${config}"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -282,7 +332,8 @@ proto_amneziawg_setup() {
|
|||||||
|
|
||||||
# endpoint dependency
|
# endpoint dependency
|
||||||
if [ "${nohostroute}" != "1" ]; then
|
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/' | \
|
sed -E 's/\[?([0-9.:a-f]+)\]?:([0-9]+)/\1 \2/' | \
|
||||||
while IFS=$'\t ' read -r key address port; do
|
while IFS=$'\t ' read -r key address port; do
|
||||||
[ -n "${port}" ] || continue
|
[ -n "${port}" ] || continue
|
||||||
@@ -295,11 +346,10 @@ proto_amneziawg_setup() {
|
|||||||
|
|
||||||
proto_amneziawg_teardown() {
|
proto_amneziawg_teardown() {
|
||||||
local config="$1"
|
local config="$1"
|
||||||
proto_amneziawg_check_installed
|
|
||||||
if proto_amneziawg_is_kernel_mode; then
|
if proto_amneziawg_is_kernel_mode; then
|
||||||
ip link del dev "${config}" >/dev/null 2>&1
|
ip link del dev "${config}" >/dev/null 2>&1
|
||||||
else
|
else
|
||||||
rm -f /var/run/wireguard/${config}.sock
|
rm -f "/var/run/amneziawg/${config}.sock"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,12 +11,13 @@
|
|||||||
# Run this script from cron every minute:
|
# Run this script from cron every minute:
|
||||||
# echo '* * * * * /usr/bin/wireguard_watchdog' >> /etc/crontabs/root
|
# echo '* * * * * /usr/bin/wireguard_watchdog' >> /etc/crontabs/root
|
||||||
|
|
||||||
|
# shellcheck disable=SC1091,SC3043
|
||||||
|
|
||||||
. /lib/functions.sh
|
. /lib/functions.sh
|
||||||
|
|
||||||
check_peer_activity() {
|
check_peer_activity() {
|
||||||
local cfg=$1
|
local cfg="$1"
|
||||||
local iface=$2
|
local iface="$2"
|
||||||
local disabled
|
local disabled
|
||||||
local public_key
|
local public_key
|
||||||
local endpoint_host
|
local endpoint_host
|
||||||
@@ -26,7 +27,7 @@ check_peer_activity() {
|
|||||||
local idle_seconds
|
local idle_seconds
|
||||||
|
|
||||||
config_get_bool disabled "${cfg}" "disabled" 0
|
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_host "${cfg}" "endpoint_host"
|
||||||
config_get endpoint_port "${cfg}" "endpoint_port"
|
config_get endpoint_port "${cfg}" "endpoint_port"
|
||||||
|
|
||||||
@@ -35,34 +36,35 @@ check_peer_activity() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
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
|
# only process peers with endpoints and keepalive set
|
||||||
[ -z ${endpoint_host} ] && return 0;
|
[ -z "${endpoint_host}" ] && return 0;
|
||||||
[ -z ${persistent_keepalive} -o ${persistent_keepalive} = "off" ] && return 0;
|
if [ -z "${persistent_keepalive}" ] || [ "${persistent_keepalive}" = "off" ]; then return 0; fi
|
||||||
|
|
||||||
# skip IP addresses
|
# skip IP addresses
|
||||||
# check taken from packages/net/ddns-scripts/files/dynamic_dns_functions.sh
|
# 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 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 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 IPV4 IPV6
|
||||||
local IPV6=$(echo ${endpoint_host} | grep -m 1 -o "$IPV6_REGEX")
|
IPV4="$(echo "${endpoint_host}" | grep -m 1 -o "$IPV4_REGEX$")" # do not detect ip in 0.0.0.0.example.com
|
||||||
[ -n "${IPV4}" -o -n "${IPV6}" ] && return 0;
|
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
|
# re-resolve endpoint hostname if not responding for too long
|
||||||
last_handshake=$(wg show ${iface} latest-handshakes | grep ${public_key} | awk '{print $2}')
|
last_handshake=$(awg show "${iface}" latest-handshakes | grep "${public_key}" | awk '{print $2}')
|
||||||
[ -z ${last_handshake} ] && return 0;
|
[ -z "${last_handshake}" ] && return 0;
|
||||||
idle_seconds=$(($(date +%s)-${last_handshake}))
|
idle_seconds=$(($(date +%s)-${last_handshake}))
|
||||||
[ ${idle_seconds} -lt 150 ] && return 0;
|
[ ${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"
|
logger -t "amneziawg_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}"
|
awg set "${iface}" peer "${public_key}" endpoint "${endpoint_host}:${endpoint_port}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# query ubus for all active wireguard interfaces
|
# 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
|
# check every peer in every active wireguard interface
|
||||||
config_load network
|
config_load network
|
||||||
for iface in $wg_ifaces; do
|
for iface in $awg_ifaces; do
|
||||||
config_foreach check_peer_activity "wireguard_${iface}" "${iface}"
|
config_foreach check_peer_activity "amneziawg_${iface}" "${iface}"
|
||||||
done
|
done
|
||||||
76
index.js
76
index.js
@@ -3,16 +3,19 @@ const cheerio = require('cheerio');
|
|||||||
const core = require('@actions/core');
|
const core = require('@actions/core');
|
||||||
|
|
||||||
const version = process.argv[2]; // Получение версии OpenWRT из аргумента командной строки
|
const version = process.argv[2]; // Получение версии OpenWRT из аргумента командной строки
|
||||||
|
const filterTargetsStr = process.argv[3] || ''; // Фильтр по targets (опционально, через запятую)
|
||||||
|
const filterSubtargetsStr = process.argv[4] || ''; // Фильтр по subtargets (опционально, через запятую)
|
||||||
|
|
||||||
const SNAPSHOT_TARGETS_TO_BUILD = ['mediatek', 'ramips', 'x86', 'armsr'];
|
// Преобразуем строки с запятыми в массивы
|
||||||
const SNAPSHOT_SUBTARGETS_TO_BUILD = ['filogic', 'mt7622', 'mt7623', 'mt7629', 'mt7620', 'mt7621', 'mt76x8', '64', 'generic', 'armv8'];
|
const filterTargets = filterTargetsStr ? filterTargetsStr.split(',').map(t => t.trim()).filter(t => t) : [];
|
||||||
|
const filterSubtargets = filterSubtargetsStr ? filterSubtargetsStr.split(',').map(s => s.trim()).filter(s => s) : [];
|
||||||
|
|
||||||
if (!version) {
|
if (!version) {
|
||||||
core.setFailed('Version argument is required');
|
core.setFailed('Version argument is required');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = version === 'SNAPSHOT' ? 'https://downloads.openwrt.org/snapshots/targets/' : `https://downloads.openwrt.org/releases/${version}/targets/`;
|
const url = `https://downloads.openwrt.org/releases/${version}/targets/`;
|
||||||
|
|
||||||
async function fetchHTML(url) {
|
async function fetchHTML(url) {
|
||||||
try {
|
try {
|
||||||
@@ -49,19 +52,27 @@ async function getSubtargets(target) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getDetails(target, subtarget) {
|
async function getDetails(target, subtarget) {
|
||||||
const packagesUrl = `${url}${target}/${subtarget}/packages/`;
|
// pkgarch from packages/index.json
|
||||||
const $ = await fetchHTML(packagesUrl);
|
// for apk-based is required change (should work also for ipk-based)
|
||||||
let vermagic = '';
|
const indexUrl = `${url}${target}/${subtarget}/packages/index.json`;
|
||||||
let pkgarch = '';
|
let pkgarch = '';
|
||||||
|
try {
|
||||||
|
const { data } = await axios.get(indexUrl, { responseType: 'json' });
|
||||||
|
pkgarch = data.architecture || '';
|
||||||
|
} catch (e) {
|
||||||
|
// keep pkgarch empty
|
||||||
|
}
|
||||||
|
|
||||||
$('a').each((index, element) => {
|
// vermagic from kmods directory name (more reliable than parsing kernel filename)
|
||||||
const name = $(element).attr('href');
|
const kmodsUrl = `${url}${target}/${subtarget}/kmods/`;
|
||||||
if (name && name.startsWith('kernel_')) {
|
const $ = await fetchHTML(kmodsUrl);
|
||||||
const vermagicMatch = name.match(/kernel_\d+\.\d+\.\d+(?:-\d+)?[-~]([a-f0-9]+)(?:-r\d+)?_([a-zA-Z0-9_-]+)\.ipk$/);
|
let vermagic = '';
|
||||||
if (vermagicMatch) {
|
|
||||||
vermagic = vermagicMatch[1];
|
$('table tr td.n a').each((_, el) => {
|
||||||
pkgarch = vermagicMatch[2];
|
const name = $(el).attr('href');
|
||||||
}
|
if (name && name.endsWith('/')) {
|
||||||
|
vermagic = name.slice(0, -1);
|
||||||
|
return false; // break
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -74,19 +85,38 @@ async function main() {
|
|||||||
const jobConfig = [];
|
const jobConfig = [];
|
||||||
|
|
||||||
for (const target of targets) {
|
for (const target of targets) {
|
||||||
|
// Пропускаем target, если указан массив фильтров и target не входит в него
|
||||||
|
if (filterTargets.length > 0 && !filterTargets.includes(target)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const subtargets = await getSubtargets(target);
|
const subtargets = await getSubtargets(target);
|
||||||
for (const subtarget of subtargets) {
|
for (const subtarget of subtargets) {
|
||||||
|
// Пропускаем subtarget, если указан массив фильтров и subtarget не входит в него
|
||||||
|
if (filterSubtargets.length > 0 && !filterSubtargets.includes(subtarget)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Добавляем в конфигурацию только если:
|
||||||
|
// 1. Оба массива пустые (автоматическая сборка по тегу) - собираем всё
|
||||||
|
// 2. Оба массива НЕ пустые (ручной запуск) - target И subtarget должны быть в своих массивах
|
||||||
|
const isAutomatic = filterTargets.length === 0 && filterSubtargets.length === 0;
|
||||||
|
const isManualMatch = filterTargets.length > 0 && filterSubtargets.length > 0 &&
|
||||||
|
filterTargets.includes(target) && filterSubtargets.includes(subtarget);
|
||||||
|
|
||||||
|
if (!isAutomatic && !isManualMatch) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const { vermagic, pkgarch } = await getDetails(target, subtarget);
|
const { vermagic, pkgarch } = await getDetails(target, subtarget);
|
||||||
|
|
||||||
if (version !== 'SNAPSHOT' || (SNAPSHOT_SUBTARGETS_TO_BUILD.includes(subtarget) && SNAPSHOT_TARGETS_TO_BUILD.includes(target))) {
|
jobConfig.push({
|
||||||
jobConfig.push({
|
tag: version,
|
||||||
tag: version,
|
target,
|
||||||
target,
|
subtarget,
|
||||||
subtarget,
|
vermagic,
|
||||||
vermagic,
|
pkgarch,
|
||||||
pkgarch,
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/kernel.mk
|
include $(INCLUDE_DIR)/kernel.mk
|
||||||
|
|
||||||
PKG_NAME:=kmod-amneziawg
|
PKG_NAME:=kmod-amneziawg
|
||||||
|
PKG_VERSION:=1.0.20260210
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
|
PKG_SOURCE_PROTO:=git
|
||||||
|
PKG_SOURCE_URL:=https://github.com/amnezia-vpn/amneziawg-linux-kernel-module.git
|
||||||
|
# Version: latest stable release tag
|
||||||
|
PKG_SOURCE_VERSION:=v$(PKG_VERSION)
|
||||||
|
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||||
|
MAKE_PATH:=src
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
define KernelPackage/amneziawg
|
define KernelPackage/amneziawg
|
||||||
@@ -12,7 +19,7 @@ define KernelPackage/amneziawg
|
|||||||
CATEGORY:=Kernel modules
|
CATEGORY:=Kernel modules
|
||||||
SUBMENU:=Network Support
|
SUBMENU:=Network Support
|
||||||
TITLE:=AmneziaWG VPN Kernel Module
|
TITLE:=AmneziaWG VPN Kernel Module
|
||||||
FILES:=$(PKG_BUILD_DIR)/amneziawg.ko
|
FILES:=$(PKG_BUILD_DIR)/$(MAKE_PATH)/amneziawg.ko
|
||||||
DEPENDS:= \
|
DEPENDS:= \
|
||||||
+kmod-udptunnel4 \
|
+kmod-udptunnel4 \
|
||||||
+kmod-udptunnel6 \
|
+kmod-udptunnel6 \
|
||||||
@@ -21,19 +28,17 @@ define KernelPackage/amneziawg
|
|||||||
endef
|
endef
|
||||||
|
|
||||||
define Build/Prepare
|
define Build/Prepare
|
||||||
cp -fr $(LINUX_DIR)/drivers/net/wireguard/{*.c,*.h,selftest/} $(PKG_BUILD_DIR)
|
$(call Build/Prepare/Default)
|
||||||
mkdir -p $(PKG_BUILD_DIR)/uapi
|
mkdir -p $(PKG_BUILD_DIR)/$(MAKE_PATH)/kernel
|
||||||
cp -f $(LINUX_DIR)/include/uapi/linux/wireguard.h $(PKG_BUILD_DIR)/uapi/
|
$(CP) $(LINUX_DIR)/* $(PKG_BUILD_DIR)/$(MAKE_PATH)/kernel/
|
||||||
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)
|
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Build/Compile
|
define Build/Compile
|
||||||
$(MAKE) -C "$(LINUX_DIR)" \
|
$(MAKE_VARS) $(MAKE) -C "$(LINUX_DIR)" \
|
||||||
$(KERNEL_MAKE_FLAGS) \
|
$(KERNEL_MAKE_FLAGS) \
|
||||||
M="$(PKG_BUILD_DIR)" \
|
M="$(PKG_BUILD_DIR)/$(MAKE_PATH)" \
|
||||||
EXTRA_CFLAGS="$(BUILDFLAGS)" \
|
EXTRA_CFLAGS="$(BUILDFLAGS)" \
|
||||||
|
WIREGUARD_VERSION="$(WIREGUARD_VERSION)" \
|
||||||
modules
|
modules
|
||||||
endef
|
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
|
|
||||||
LUCI_PKGARCH:=all
|
|
||||||
|
|
||||||
PKG_PROVIDES:=luci-app-amneziawg
|
|
||||||
|
|
||||||
include $(TOPDIR)/feeds/luci/luci.mk
|
|
||||||
|
|
||||||
# call BuildPackage - OpenWrt buildroot signature
|
|
||||||
14
luci-proto-amneziawg/Makefile
Normal file
14
luci-proto-amneziawg/Makefile
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
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
|
||||||
|
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 form';
|
||||||
'require network';
|
'require network';
|
||||||
'require validation';
|
'require validation';
|
||||||
|
'require uqr';
|
||||||
|
|
||||||
var generateKey = rpc.declare({
|
var generateKey = rpc.declare({
|
||||||
object: 'luci.amneziawg',
|
object: 'luci.amneziawg',
|
||||||
@@ -64,28 +65,16 @@ function generateDescription(name, texts) {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function invokeQREncode(data, code) {
|
function buildSVGQRCode(data, code) {
|
||||||
return fs.exec_direct('/usr/bin/qrencode', [
|
// pixel size 3 for mobile browser
|
||||||
'--inline', '--8bit', '--type=SVG',
|
const options = {
|
||||||
'--output=-', '--', data
|
pixelSize: 3,
|
||||||
]).then(function(svg) {
|
whiteColor: 'white',
|
||||||
code.style.opacity = '';
|
blackColor: 'black'
|
||||||
dom.content(code, Object.assign(E(svg), { style: 'width:100%;height:auto' }));
|
};
|
||||||
}).catch(function(error) {
|
const svg = uqr.renderSVG(data, options);
|
||||||
code.style.opacity = '';
|
code.style.opacity = '';
|
||||||
|
dom.content(code, Object.assign(E(svg), { style: 'width:100%;height:auto' }));
|
||||||
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)
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var cbiKeyPairGenerate = form.DummyValue.extend({
|
var cbiKeyPairGenerate = form.DummyValue.extend({
|
||||||
@@ -97,9 +86,6 @@ var cbiKeyPairGenerate = form.DummyValue.extend({
|
|||||||
pub = this.section.getUIElement(section_id, 'public_key'),
|
pub = this.section.getUIElement(section_id, 'public_key'),
|
||||||
map = this.map;
|
map = this.map;
|
||||||
|
|
||||||
if ((prv.getValue() || pub.getValue()) && !confirm(_('Do you want to replace the current keys?')))
|
|
||||||
return;
|
|
||||||
|
|
||||||
return generateKey().then(function(keypair) {
|
return generateKey().then(function(keypair) {
|
||||||
prv.setValue(keypair.priv);
|
prv.setValue(keypair.priv);
|
||||||
pub.setValue(keypair.pub);
|
pub.setValue(keypair.pub);
|
||||||
@@ -123,7 +109,7 @@ return network.registerProtocol('amneziawg', {
|
|||||||
return this._ubus('l3_device') || this.sid;
|
return this._ubus('l3_device') || this.sid;
|
||||||
},
|
},
|
||||||
|
|
||||||
getOpkgPackage: function() {
|
getPackageName: function() {
|
||||||
return 'amneziawg-tools';
|
return 'amneziawg-tools';
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -198,7 +184,7 @@ return network.registerProtocol('amneziawg', {
|
|||||||
o.placeholder = '1420';
|
o.placeholder = '1420';
|
||||||
o.optional = true;
|
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.optional = true;
|
||||||
o.validate = function(section_id, value) {
|
o.validate = function(section_id, value) {
|
||||||
if (value.length > 0 && !value.match(/^0x[a-fA-F0-9]{1,8}$/))
|
if (value.length > 0 && !value.match(/^0x[a-fA-F0-9]{1,8}$/))
|
||||||
@@ -210,62 +196,102 @@ return network.registerProtocol('amneziawg', {
|
|||||||
// AmneziaWG
|
// AmneziaWG
|
||||||
|
|
||||||
try {
|
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) {}
|
catch(e) {}
|
||||||
|
|
||||||
o = s.taboption('amneziawg', form.Value, 'awg_jc', _('Jc'), _('Junk packet count.'));
|
o = s.taboption('amneziawg', form.Value, 'awg_jc', _('Jc'), _('Junk packet count.'));
|
||||||
o.datatype = 'uinteger';
|
o.datatype = 'uinteger';
|
||||||
|
o.placeholder = '0';
|
||||||
o.optional = true;
|
o.optional = true;
|
||||||
|
|
||||||
o = s.taboption('amneziawg', form.Value, 'awg_jmin', _('Jmin'), _('Junk packet minimum size.'));
|
o = s.taboption('amneziawg', form.Value, 'awg_jmin', _('Jmin'), _('Junk packet minimum size.'));
|
||||||
o.datatype = 'uinteger';
|
o.datatype = 'uinteger';
|
||||||
|
o.placeholder = '0';
|
||||||
o.optional = true;
|
o.optional = true;
|
||||||
|
|
||||||
o = s.taboption('amneziawg', form.Value, 'awg_jmax', _('Jmax'), _('Junk packet maximum size.'));
|
o = s.taboption('amneziawg', form.Value, 'awg_jmax', _('Jmax'), _('Junk packet maximum size.'));
|
||||||
o.datatype = 'uinteger';
|
o.datatype = 'uinteger';
|
||||||
|
o.placeholder = '0';
|
||||||
o.optional = true;
|
o.optional = true;
|
||||||
|
|
||||||
o = s.taboption('amneziawg', form.Value, 'awg_s1', _('S1'), _('Handshake initiation packet junk header size.'));
|
o = s.taboption('amneziawg', form.Value, 'awg_s1', _('S1'), _('Handshake initiation packet junk header size.'));
|
||||||
o.datatype = 'uinteger';
|
o.datatype = 'uinteger';
|
||||||
|
o.placeholder = '0';
|
||||||
o.optional = true;
|
o.optional = true;
|
||||||
|
|
||||||
o = s.taboption('amneziawg', form.Value, 'awg_s2', _('S2'), _('Handshake response packet junk header size.'));
|
o = s.taboption('amneziawg', form.Value, 'awg_s2', _('S2'), _('Handshake response packet junk header size.'));
|
||||||
o.datatype = 'uinteger';
|
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.optional = true;
|
||||||
|
|
||||||
o = s.taboption('amneziawg', form.Value, 'awg_h1', _('H1'), _('Handshake initiation packet type header.'));
|
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.optional = true;
|
||||||
|
|
||||||
o = s.taboption('amneziawg', form.Value, 'awg_h2', _('H2'), _('Handshake response packet type header.'));
|
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.optional = true;
|
||||||
|
|
||||||
o = s.taboption('amneziawg', form.Value, 'awg_h3', _('H3'), _('Handshake cookie packet type header.'));
|
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.optional = true;
|
||||||
|
|
||||||
o = s.taboption('amneziawg', form.Value, 'awg_h4', _('H4'), _('Transport packet type header.'));
|
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;
|
o.optional = true;
|
||||||
|
|
||||||
// -- peers -----------------------------------------------------------------------
|
// -- peers -----------------------------------------------------------------------
|
||||||
|
|
||||||
try {
|
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) {}
|
catch(e) {}
|
||||||
|
|
||||||
o = s.taboption('peers', form.SectionValue, '_peers', form.GridSection, 'amneziawg_%s'.format(s.section));
|
o = s.taboption('peers', form.SectionValue, '_peers', form.GridSection, 'amneziawg_%s'.format(s.section));
|
||||||
o.depends('proto', 'amneziawg');
|
o.depends('proto', 'amneziawg');
|
||||||
|
|
||||||
ss = o.subsection;
|
ss = o.subsection;
|
||||||
ss.anonymous = true;
|
ss.anonymous = true;
|
||||||
ss.addremove = true;
|
ss.addremove = true;
|
||||||
ss.addbtntitle = _('Add peer');
|
ss.addbtntitle = _('Add peer');
|
||||||
ss.nodescriptions = true;
|
ss.nodescriptions = true;
|
||||||
ss.modaltitle = _('Edit peer');
|
ss.modaltitle = _('Edit peer');
|
||||||
|
ss.sortable = true;
|
||||||
|
|
||||||
ss.handleDragConfig = function(ev) {
|
ss.handleDragConfig = function(ev) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
@@ -402,15 +428,22 @@ return network.registerProtocol('amneziawg', {
|
|||||||
s.getOption('public_key').getUIElement(s.section).setValue(keypair.pub);
|
s.getOption('public_key').getUIElement(s.section).setValue(keypair.pub);
|
||||||
s.getOption('listen_port').getUIElement(s.section).setValue(config.interface_listenport || '');
|
s.getOption('listen_port').getUIElement(s.section).setValue(config.interface_listenport || '');
|
||||||
s.getOption('addresses').getUIElement(s.section).setValue(config.interface_address);
|
s.getOption('addresses').getUIElement(s.section).setValue(config.interface_address);
|
||||||
s.getOption('awg_jc').getUIElement(s.section).setValue(config.awg_jc);
|
s.getOption('awg_jc').getUIElement(s.section).setValue(config.interface_jc || '');
|
||||||
s.getOption('awg_jmin').getUIElement(s.section).setValue(config.awg_jmin);
|
s.getOption('awg_jmin').getUIElement(s.section).setValue(config.interface_jmin || '');
|
||||||
s.getOption('awg_jmax').getUIElement(s.section).setValue(config.awg_jmax);
|
s.getOption('awg_jmax').getUIElement(s.section).setValue(config.interface_jmax || '');
|
||||||
s.getOption('awg_s1').getUIElement(s.section).setValue(config.awg_s1);
|
s.getOption('awg_s1').getUIElement(s.section).setValue(config.interface_s1 || '');
|
||||||
s.getOption('awg_s2').getUIElement(s.section).setValue(config.awg_s2);
|
s.getOption('awg_s2').getUIElement(s.section).setValue(config.interface_s2 || '');
|
||||||
s.getOption('awg_h1').getUIElement(s.section).setValue(config.awg_h1);
|
s.getOption('awg_s3').getUIElement(s.section).setValue(config.interface_s3 || '');
|
||||||
s.getOption('awg_h2').getUIElement(s.section).setValue(config.awg_h2);
|
s.getOption('awg_s4').getUIElement(s.section).setValue(config.interface_s4 || '');
|
||||||
s.getOption('awg_h3').getUIElement(s.section).setValue(config.awg_h3);
|
s.getOption('awg_h1').getUIElement(s.section).setValue(config.interface_h1 || '');
|
||||||
s.getOption('awg_h4').getUIElement(s.section).setValue(config.awg_h4);
|
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)
|
if (config.interface_dns)
|
||||||
s.getOption('dns').getUIElement(s.section).setValue(config.interface_dns);
|
s.getOption('dns').getUIElement(s.section).setValue(config.interface_dns);
|
||||||
@@ -486,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', _('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', _('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('p', [
|
||||||
E('textarea', {
|
E('textarea', {
|
||||||
@@ -561,9 +594,10 @@ return network.registerProtocol('amneziawg', {
|
|||||||
return E('em', _('No peers defined yet.'));
|
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 = ss.option(form.Flag, 'disabled', _('Disabled'), _('Enable / Disable peer. Restart amneziawg interface to apply changes.'));
|
||||||
o.modalonly = true;
|
o.editable = true;
|
||||||
o.optional = true;
|
o.optional = true;
|
||||||
|
o.width = '5%';
|
||||||
|
|
||||||
o = ss.option(form.Value, 'description', _('Description'), _('Optional. Description of peer.'));
|
o = ss.option(form.Value, 'description', _('Description'), _('Optional. Description of peer.'));
|
||||||
o.placeholder = 'My Peer';
|
o.placeholder = 'My Peer';
|
||||||
@@ -661,9 +695,6 @@ return network.registerProtocol('amneziawg', {
|
|||||||
var psk = this.section.getUIElement(section_id, 'preshared_key'),
|
var psk = this.section.getUIElement(section_id, 'preshared_key'),
|
||||||
map = this.map;
|
map = this.map;
|
||||||
|
|
||||||
if (psk.getValue() && !confirm(_('Do you want to replace the current PSK?')))
|
|
||||||
return;
|
|
||||||
|
|
||||||
return generatePsk().then(function(key) {
|
return generatePsk().then(function(key) {
|
||||||
psk.setValue(key);
|
psk.setValue(key);
|
||||||
map.save(null, true);
|
map.save(null, true);
|
||||||
@@ -743,10 +774,25 @@ return network.registerProtocol('amneziawg', {
|
|||||||
|
|
||||||
o.modalonly = true;
|
o.modalonly = true;
|
||||||
|
|
||||||
o.createPeerConfig = function(section_id, endpoint, ips) {
|
o.createPeerConfig = function(section_id, endpoint, ips, eips, dns) {
|
||||||
var pub = s.formvalue(s.section, 'public_key'),
|
var pub = s.formvalue(s.section, 'public_key'),
|
||||||
port = s.formvalue(s.section, 'listen_port') || '51820',
|
port = s.formvalue(s.section, 'listen_port') || '51820',
|
||||||
jc = s.formvalue
|
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'),
|
prv = this.section.formvalue(section_id, 'private_key'),
|
||||||
psk = this.section.formvalue(section_id, 'preshared_key'),
|
psk = this.section.formvalue(section_id, 'preshared_key'),
|
||||||
eport = this.section.formvalue(section_id, 'endpoint_port'),
|
eport = this.section.formvalue(section_id, 'endpoint_port'),
|
||||||
@@ -760,7 +806,25 @@ return network.registerProtocol('amneziawg', {
|
|||||||
return [
|
return [
|
||||||
'[Interface]',
|
'[Interface]',
|
||||||
'PrivateKey = ' + prv,
|
'PrivateKey = ' + prv,
|
||||||
|
eips && eips.length ? 'Address = ' + eips.join(', ') : '# Address not defined',
|
||||||
eport ? 'ListenPort = ' + eport : '# ListenPort not defined',
|
eport ? 'ListenPort = ' + eport : '# ListenPort not defined',
|
||||||
|
dns && dns.length ? 'DNS = ' + dns.join(', ') : '# DNS not defined',
|
||||||
|
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]',
|
'[Peer]',
|
||||||
'PublicKey = ' + pub,
|
'PublicKey = ' + pub,
|
||||||
@@ -775,11 +839,13 @@ return network.registerProtocol('amneziawg', {
|
|||||||
var mapNode = ss.getActiveModalMap(),
|
var mapNode = ss.getActiveModalMap(),
|
||||||
headNode = mapNode.parentNode.querySelector('h4'),
|
headNode = mapNode.parentNode.querySelector('h4'),
|
||||||
configGenerator = this.createPeerConfig.bind(this, section_id),
|
configGenerator = this.createPeerConfig.bind(this, section_id),
|
||||||
parent = this.map;
|
parent = this.map,
|
||||||
|
eips = this.section.formvalue(section_id, 'allowed_ips');
|
||||||
|
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
network.getWANNetworks(),
|
network.getWANNetworks(),
|
||||||
network.getWAN6Networks(),
|
network.getWAN6Networks(),
|
||||||
|
network.getNetwork('lan'),
|
||||||
L.resolveDefault(uci.load('ddns')),
|
L.resolveDefault(uci.load('ddns')),
|
||||||
L.resolveDefault(uci.load('system')),
|
L.resolveDefault(uci.load('system')),
|
||||||
parent.save(null, true)
|
parent.save(null, true)
|
||||||
@@ -787,12 +853,12 @@ return network.registerProtocol('amneziawg', {
|
|||||||
var hostnames = [];
|
var hostnames = [];
|
||||||
|
|
||||||
uci.sections('ddns', 'service', function(s) {
|
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);
|
hostnames.push(s.lookup_host);
|
||||||
});
|
});
|
||||||
|
|
||||||
uci.sections('system', 'system', function(s) {
|
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);
|
hostnames.push(s.hostname);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -804,9 +870,19 @@ return network.registerProtocol('amneziawg', {
|
|||||||
|
|
||||||
var ips = [ '0.0.0.0/0', '::/0' ];
|
var ips = [ '0.0.0.0/0', '::/0' ];
|
||||||
|
|
||||||
|
var dns = [];
|
||||||
|
|
||||||
|
var lan = data[2];
|
||||||
|
if (lan) {
|
||||||
|
var lanIp = lan.getIPAddr();
|
||||||
|
if (lanIp) {
|
||||||
|
dns.unshift(lanIp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var qrm, qrs, qro;
|
var qrm, qrs, qro;
|
||||||
|
|
||||||
qrm = new form.JSONMap({ config: { endpoint: hostnames[0], allowed_ips: ips } }, 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;
|
qrm.parent = parent;
|
||||||
|
|
||||||
qrs = qrm.section(form.NamedSection, 'config');
|
qrs = qrm.section(form.NamedSection, 'config');
|
||||||
@@ -816,12 +892,14 @@ return network.registerProtocol('amneziawg', {
|
|||||||
conf = this.map.findElement('.client-config'),
|
conf = this.map.findElement('.client-config'),
|
||||||
endpoint = this.section.getUIElement(section_id, 'endpoint'),
|
endpoint = this.section.getUIElement(section_id, 'endpoint'),
|
||||||
ips = this.section.getUIElement(section_id, 'allowed_ips');
|
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)) {
|
if (this.isValid(section_id)) {
|
||||||
conf.firstChild.data = configGenerator(endpoint.getValue(), ips.getValue());
|
conf.firstChild.data = configGenerator(endpoint.getValue(), ips.getValue(), eips.getValue(), dns.getValue());
|
||||||
code.style.opacity = '.5';
|
code.style.opacity = '.5';
|
||||||
|
|
||||||
invokeQREncode(conf.firstChild.data, code);
|
buildSVGQRCode(conf.firstChild.data, code);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -836,16 +914,27 @@ return network.registerProtocol('amneziawg', {
|
|||||||
ips.forEach(function(ip) { qro.value(ip) });
|
ips.forEach(function(ip) { qro.value(ip) });
|
||||||
qro.onchange = handleConfigChange;
|
qro.onchange = handleConfigChange;
|
||||||
|
|
||||||
|
qro = qrs.option(form.DynamicList, 'dns_servers', _('DNS Servers'), _('DNS servers for the remote clients using this tunnel to your openwrt device. Some wireguard clients require this to be set.'));
|
||||||
|
qro.datatype = 'ipaddr';
|
||||||
|
qro.default = dns;
|
||||||
|
qro.onchange = handleConfigChange;
|
||||||
|
|
||||||
|
qro = qrs.option(form.DynamicList, 'addresses', _('Addresses'), _('IP addresses for the peer to use inside the tunnel. Some clients require this setting.'));
|
||||||
|
qro.datatype = 'ipaddr';
|
||||||
|
qro.default = eips;
|
||||||
|
eips.forEach(function(eip) { qro.value(eip) });
|
||||||
|
qro.onchange = handleConfigChange;
|
||||||
|
|
||||||
qro = qrs.option(form.DummyValue, 'output');
|
qro = qrs.option(form.DummyValue, 'output');
|
||||||
qro.renderWidget = function() {
|
qro.renderWidget = function() {
|
||||||
var peer_config = configGenerator(hostnames[0], ips);
|
var peer_config = configGenerator(hostnames[0], ips, eips, dns);
|
||||||
|
|
||||||
var node = E('div', {
|
var node = E('div', {
|
||||||
'style': 'display:flex;flex-wrap:wrap;align-items:center;gap:.5em;width:100%'
|
'style': 'display:flex;flex-wrap:wrap;align-items:center;gap:.5em;width:100%'
|
||||||
}, [
|
}, [
|
||||||
E('div', {
|
E('div', {
|
||||||
'class': 'qr-code',
|
'class': 'qr-code',
|
||||||
'style': 'width:320px;flex:0 1 320px;text-align:center'
|
'style': 'text-align:center'
|
||||||
}, [
|
}, [
|
||||||
E('em', { 'class': 'spinning' }, [ _('Generating QR code…') ])
|
E('em', { 'class': 'spinning' }, [ _('Generating QR code…') ])
|
||||||
]),
|
]),
|
||||||
@@ -864,7 +953,7 @@ return network.registerProtocol('amneziawg', {
|
|||||||
}, [ peer_config ])
|
}, [ peer_config ])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
invokeQREncode(peer_config, node.firstChild);
|
buildSVGQRCode(peer_config, node.firstChild);
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
};
|
};
|
||||||
@@ -6,9 +6,9 @@
|
|||||||
'require ui';
|
'require ui';
|
||||||
|
|
||||||
|
|
||||||
var callGetWgInstances = rpc.declare({
|
var callgetAwgInstances = rpc.declare({
|
||||||
object: 'luci.amneziawg',
|
object: 'luci.amneziawg',
|
||||||
method: 'getWgInstances'
|
method: 'getAwgInstances'
|
||||||
});
|
});
|
||||||
|
|
||||||
function timestampToStr(timestamp) {
|
function timestampToStr(timestamp) {
|
||||||
@@ -128,7 +128,7 @@ return view.extend({
|
|||||||
'click': ui.createHandlerFn(this, handleInterfaceDetails, ifaces[instanceName])
|
'click': ui.createHandlerFn(this, handleInterfaceDetails, ifaces[instanceName])
|
||||||
}, [
|
}, [
|
||||||
E('span', { 'class': 'ifacebadge' }, [
|
E('span', { 'class': 'ifacebadge' }, [
|
||||||
E('img', { 'src': L.resource('icons', 'tunnel.png') }),
|
E('img', { 'src': L.resource('icons', 'amneziawg.svg') }),
|
||||||
'\xa0',
|
'\xa0',
|
||||||
instanceName
|
instanceName
|
||||||
]),
|
]),
|
||||||
@@ -153,7 +153,7 @@ return view.extend({
|
|||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
poll.add(L.bind(function () {
|
poll.add(L.bind(function () {
|
||||||
return callGetWgInstances().then(L.bind(function(ifaces) {
|
return callgetAwgInstances().then(L.bind(function(ifaces) {
|
||||||
dom.content(
|
dom.content(
|
||||||
document.querySelector('#view'),
|
document.querySelector('#view'),
|
||||||
this.renderIfaces(ifaces)
|
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": {
|
"luci-proto-amneziawg": {
|
||||||
"description": "Grant access to LuCI AmneziaWG procedures",
|
"description": "Grant access to LuCI AmneziaWG procedures",
|
||||||
"read": {
|
"read": {
|
||||||
"file": {
|
|
||||||
"/usr/bin/qrencode --inline --8bit --type=SVG --output=- -- *": [ "exec" ]
|
|
||||||
},
|
|
||||||
"ubus": {
|
"ubus": {
|
||||||
"luci.amneziawg": [
|
"luci.amneziawg": [
|
||||||
"getWgInstances"
|
"getAwgInstances"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"uci": [ "ddns", "system" ]
|
"uci": [ "ddns", "system", "network" ]
|
||||||
},
|
},
|
||||||
"write": {
|
"write": {
|
||||||
"ubus": {
|
"ubus": {
|
||||||
@@ -15,18 +15,33 @@ function command(cmd) {
|
|||||||
return trim(popen(cmd)?.read?.('all'));
|
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 = {
|
const methods = {
|
||||||
generatePsk: {
|
generatePsk: {
|
||||||
call: function() {
|
call: function() {
|
||||||
return { psk: command('amneziawg genpsk 2>/dev/null') };
|
return { psk: command('awg genpsk 2>/dev/null') };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
generateKeyPair: {
|
generateKeyPair: {
|
||||||
call: function() {
|
call: function() {
|
||||||
const priv = command('amneziawg genkey 2>/dev/null');
|
const priv = command('awg genkey 2>/dev/null');
|
||||||
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 } };
|
return { keys: { priv, pub } };
|
||||||
}
|
}
|
||||||
@@ -36,20 +51,20 @@ const methods = {
|
|||||||
args: { privkey: "privkey" },
|
args: { privkey: "privkey" },
|
||||||
call: function(req) {
|
call: function(req) {
|
||||||
const priv = req.args?.privkey;
|
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 } };
|
return { keys: { priv, pub } };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getWgInstances: {
|
getAwgInstances: {
|
||||||
call: function() {
|
call: function() {
|
||||||
const data = {};
|
const data = {};
|
||||||
let last_device;
|
let last_device;
|
||||||
let qr_pubkey = {};
|
let qr_pubkey = {};
|
||||||
|
|
||||||
const uci = cursor();
|
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) {
|
if (wg_dump) {
|
||||||
uci.load("network");
|
uci.load("network");
|
||||||
@@ -74,12 +89,17 @@ const methods = {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let peer_name;
|
let peer_name;
|
||||||
|
let peer_name_legacy;
|
||||||
|
|
||||||
uci.foreach('network', `amneziawg_${last_device}`, (s) => {
|
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;
|
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 = {
|
const peer = {
|
||||||
name: peer_name,
|
name: peer_name,
|
||||||
public_key: record[1],
|
public_key: record[1],
|
||||||
Reference in New Issue
Block a user