diff --git a/.github/workflows/build-module.yml b/.github/workflows/build-module.yml index 526ce45..bc9b0b0 100644 --- a/.github/workflows/build-module.yml +++ b/.github/workflows/build-module.yml @@ -9,6 +9,20 @@ on: tag_name: required: true type: string + workflow_dispatch: + inputs: + version: + description: 'OpenWRT version (e.g., 24.10.3)' + required: true + type: string + targets: + description: 'Targets (comma-separated, e.g., "stm32,ramips")' + required: true + type: string + subtargets: + description: 'Subtargets (comma-separated, e.g., "stm32mp1,mt7621")' + required: true + type: string jobs: generate-config: @@ -27,8 +41,12 @@ jobs: - name: Get OpenWRT version from tag id: get_version run: | - if [ "${{ github.event_name }}" == "workflow_call" ]; then - echo "VERSION=${{ inputs.tag_name }}" >> $GITHUB_ENV + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + echo "VERSION=${{ inputs.version }}" >> $GITHUB_ENV + echo "TARGETS=${{ inputs.targets }}" >> $GITHUB_ENV + echo "SUBTARGETS=${{ inputs.subtargets }}" >> $GITHUB_ENV + elif [ "${{ github.event_name }}" == "workflow_call" ]; then + VERSION="${{ inputs.tag_name }}" echo "VERSION=${VERSION#v}" >> $GITHUB_ENV else echo "VERSION=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_ENV @@ -39,7 +57,7 @@ jobs: - name: Generate Job Config id: generate-config - run: node index.js ${{ env.VERSION }} + run: node index.js ${{ env.VERSION }} "${{ env.TARGETS }}" "${{ env.SUBTARGETS }}" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -53,94 +71,127 @@ jobs: fail-fast: false steps: - - uses: actions/checkout@v4 - with: - repository: openwrt/openwrt - ref: v${{ matrix.build_env.tag }} - fetch-depth: 0 + - name: Checkout AWG source code + uses: actions/checkout@v4 - - name: Cache Tools and Kernel - id: cache-tools-kernel + - name: Install Python dependencies + run: | + sudo apt-get update + sudo apt-get install -y python3-pyelftools + + - name: Cache OpenWrt SDK + id: cache-sdk uses: actions/cache@v4 env: - cache-name: "cache-tools-kernel-${{ matrix.build_env.tag }}-${{ matrix.build_env.pkgarch}}-${{ matrix.build_env.target}}-${{ matrix.build_env.subtarget}}" + cache-name: "cache-sdk-${{ matrix.build_env.tag }}-${{ matrix.build_env.target}}-${{ matrix.build_env.subtarget}}" with: - path: "**" - key: ${{ runner.os }}-build-vm4-${{ env.cache-name }} + path: openwrt-sdk-*/ + key: ${{ runner.os }}-sdk-${{ env.cache-name }} - - name: Building kernel and tools - #if: ${{ steps.cache-tools-kernel.outputs.cache-hit != 'true' }} + - name: Download and extract OpenWrt SDK + if: steps.cache-sdk.outputs.cache-hit != 'true' run: | echo "pkgarch: ${{ matrix.build_env.pkgarch}}, target:${{ matrix.build_env.target}}, subtarget: ${{ matrix.build_env.subtarget}}" - # Setup & install feeds - wget https://downloads.openwrt.org/releases/${{ matrix.build_env.tag }}/targets/${{ matrix.build_env.target}}/${{ matrix.build_env.subtarget}}/feeds.buildinfo -O feeds.conf - echo "src-git awgopenwrt https://github.com/Slava-Shchipunov/awg-openwrt.git" >> ./feeds.conf - ./scripts/feeds update && ./scripts/feeds install -a + # Get the actual SDK filename from the directory listing + SDK_FILE=$(curl -s "https://downloads.openwrt.org/releases/${{ matrix.build_env.tag }}/targets/${{ matrix.build_env.target}}/${{ matrix.build_env.subtarget}}/" | grep -o "openwrt-sdk-${{ matrix.build_env.tag }}-${{ matrix.build_env.target}}-${{ matrix.build_env.subtarget}}_gcc-[^\"]*_musl[^\"]*\.Linux-x86_64\.tar\.[xz|zst]*" | head -n1) + + if [ -z "$SDK_FILE" ]; then + echo "SDK file not found for ${{ matrix.build_env.tag }} ${{ matrix.build_env.target}} ${{ matrix.build_env.subtarget}}" + exit 1 + fi + + SDK_DOWNLOAD_URL="https://downloads.openwrt.org/releases/${{ matrix.build_env.tag }}/targets/${{ matrix.build_env.target}}/${{ matrix.build_env.subtarget}}/${SDK_FILE}" + echo "Downloading SDK: $SDK_DOWNLOAD_URL" + + wget "$SDK_DOWNLOAD_URL" + + # Extract based on file extension + if [[ "$SDK_FILE" == *.tar.zst ]]; then + tar --zstd -xf "$SDK_FILE" + elif [[ "$SDK_FILE" == *.tar.xz ]]; then + tar -xf "$SDK_FILE" + else + echo "Unknown archive format: $SDK_FILE" + exit 1 + fi + + rm "$SDK_FILE" - # Setup config with AWG and dependencies - wget https://downloads.openwrt.org/releases/${{ matrix.build_env.tag }}/targets/${{ matrix.build_env.target}}/${{ matrix.build_env.subtarget}}/config.buildinfo -O .config - echo "CONFIG_PACKAGE_kmod-amneziawg=m" >> .config + - name: Setup SDK and feeds + run: | + # Find SDK directory + SDK_DIR=$(find . -maxdepth 1 -name "openwrt-sdk-*" -type d | head -n1) + + if [ -z "$SDK_DIR" ]; then + echo "SDK directory not found" + exit 1 + fi + + # Get absolute paths + WORKSPACE_DIR=$(pwd) + + cd "$SDK_DIR" + + # Update feeds to include LuCI + ./scripts/feeds update -a + ./scripts/feeds install -a + + # Copy current repository packages directly to package directory + cp -r "$WORKSPACE_DIR/kmod-amneziawg" package/ + cp -r "$WORKSPACE_DIR/amneziawg-tools" package/ + cp -r "$WORKSPACE_DIR/luci-proto-amneziawg" package/ + + # Configure packages to build + echo "CONFIG_PACKAGE_kmod-amneziawg=m" > .config echo "CONFIG_PACKAGE_amneziawg-tools=y" >> .config - echo "CONFIG_PACKAGE_luci-app-amneziawg=y" >> .config - echo "CONFIG_PACKAGE_kmod-crypto-lib-chacha20=m" >> .config - echo "CONFIG_PACKAGE_kmod-crypto-lib-chacha20poly1305=m" >> .config - echo "CONFIG_PACKAGE_kmod-crypto-chacha20poly1305=m" >> .config - + echo "CONFIG_PACKAGE_luci-proto-amneziawg=y" >> .config + echo "CONFIG_PACKAGE_luci-i18n-amneziawg-ru=y" >> .config + make defconfig - echo " > make tools/install" - make tools/install -i -j `nproc` - - cat ./build_dir/target-*/linux-*/linux-*/.vermagic || true - - echo " > make toolchain/install" - make toolchain/install -i -j `nproc` - - cat ./build_dir/target-*/linux-*/linux-*/.vermagic || true - - # compile kernel module - echo " > make target/linux/compile" - make target/linux/compile -i -j `nproc` V=s - - VERMAGIC=`cat ./build_dir/target-*/linux-*/linux-*/.vermagic` - VERMAGIC_EXPECTED=${{ matrix.build_env.vermagic }} - - if [ "$VERMAGIC" != "$VERMAGIC_EXPECTED" ]; then - echo Vermagic mismatch: $VERMAGIC, expected $VERMAGIC_EXPECTED - exit 1 - fi - - - name: Build AmneziaWG + - name: Build AmneziaWG packages run: | - VERMAGIC=`cat ./build_dir/target-*/linux-*/linux-*/.vermagic` - echo "Vermagic: $VERMAGIC" + # Find SDK directory + SDK_DIR=$(find . -maxdepth 1 -name "openwrt-sdk-*" -type d | head -n1) + cd "$SDK_DIR" - VERMAGIC_EXPECTED=${{ matrix.build_env.vermagic }} + echo "Building AmneziaWG packages..." - if [ "$VERMAGIC" != "$VERMAGIC_EXPECTED" ]; then - echo Vermagic mismatch: $VERMAGIC, expected $VERMAGIC_EXPECTED - exit 1 - fi - - # Ignore kmod build for some targets, replace with the awg-go - make package/kmod-amneziawg/{clean,download,prepare} V=s || true + # Build kmod-amneziawg (kernel module) + echo "Building kmod-amneziawg..." + make package/kmod-amneziawg/{download,prepare} V=s || true make package/kmod-amneziawg/compile V=s || true - make package/luci-app-amneziawg/{clean,download,prepare} - make package/luci-app-amneziawg/compile V=s + # Build luci-proto-amneziawg (web interface) + echo "Building luci-proto-amneziawg..." + make package/luci-proto-amneziawg/{download,prepare} V=s + make package/luci-proto-amneziawg/compile V=s - make V=s package/amneziawg-tools/{clean,download,prepare} - make V=s package/amneziawg-tools/compile + # Build amneziawg-tools (userspace tools) + echo "Building amneziawg-tools..." + make package/amneziawg-tools/{download,prepare} V=s + make package/amneziawg-tools/compile V=s + + echo "Build completed. Checking for built packages..." + find bin/ -name "*.ipk" | grep -E "(amneziawg|luci-proto-amneziawg|luci-i18n-amneziawg)" | head -10 - name: Prepare artifacts run: | - tag_name=${{ github.ref_name }} + # Find SDK directory + SDK_DIR=$(find . -maxdepth 1 -name "openwrt-sdk-*" -type d | head -n1) + mkdir -p awgrelease postfix="v${{ matrix.build_env.tag }}_${{ matrix.build_env.pkgarch}}_${{ matrix.build_env.target}}_${{ matrix.build_env.subtarget}}" - cp bin/packages/${{ matrix.build_env.pkgarch }}/awgopenwrt/amneziawg-tools_*.ipk awgrelease/amneziawg-tools_${postfix}.ipk - cp bin/packages/${{ matrix.build_env.pkgarch }}/awgopenwrt/luci-app-amneziawg_*.ipk awgrelease/luci-app-amneziawg_${postfix}.ipk - cp bin/targets/${{ matrix.build_env.target}}/${{ matrix.build_env.subtarget}}/packages/kmod-amneziawg_*.ipk awgrelease/kmod-amneziawg_${postfix}.ipk + + # Copy built packages + find "$SDK_DIR/bin/packages" -name "amneziawg-tools_*.ipk" -exec cp {} awgrelease/amneziawg-tools_${postfix}.ipk \; || echo "amneziawg-tools package not found" + find "$SDK_DIR/bin/packages" -name "luci-proto-amneziawg_*.ipk" -exec cp {} awgrelease/luci-proto-amneziawg_${postfix}.ipk \; || echo "luci-proto-amneziawg package not found" + find "$SDK_DIR/bin/packages" -name "luci-i18n-amneziawg-ru_*.ipk" -exec cp {} awgrelease/luci-i18n-amneziawg-ru_${postfix}.ipk \; || echo "luci-i18n-amneziawg-ru package not found" + find "$SDK_DIR/bin/targets" -name "kmod-amneziawg_*.ipk" -exec cp {} awgrelease/kmod-amneziawg_${postfix}.ipk \; || echo "kmod-amneziawg package not found" + + echo "Built packages:" + ls -la awgrelease/ - name: Release uses: softprops/action-gh-release@v1 diff --git a/.github/workflows/build-to-all-latest-snapshots.yml b/.github/workflows/build-to-all-latest-snapshots.yml deleted file mode 100644 index 09de30b..0000000 --- a/.github/workflows/build-to-all-latest-snapshots.yml +++ /dev/null @@ -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 }} diff --git a/.github/workflows/run-release.yml b/.github/workflows/run-release.yml index bfbc0ff..bfbc00f 100644 --- a/.github/workflows/run-release.yml +++ b/.github/workflows/run-release.yml @@ -3,7 +3,7 @@ name: Sync OpenWRT Releases on: # schedule: # - cron: '0 0 */3 * *' # Проверка новых релизов раз в три дня - workflow_dispatch: # Возможность вручную запустить Action + # workflow_dispatch: # Возможность вручную запустить Action jobs: sync-releases: diff --git a/README.md b/README.md index 8e6ed8b..97ebefe 100644 --- a/README.md +++ b/README.md @@ -26,15 +26,10 @@ sh <(wget -O - https://raw.githubusercontent.com/Slava-Shchipunov/awg-openwrt/re 10) [24.10.2](https://github.com/Slava-Shchipunov/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) -И собрал пакеты для популярных устройств для OpenWRT [SNAPSHOT](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/SNAPSHOT) - Также запускал сборку для версии [22.03.7](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v22.03.7), но там для двух платформ сборка завершилась ошибкой. Так как это достаточно старая версия OpenWRT, я не стал разбираться, в чем проблема. В дальнейшем при выходе новых релизов OpenWRT будут автоматически создаваться релизы с пакетами AmneziaWG и запускаться сборка пакетов под все устройства, поддерживаемые новой версией. Github action для проверки появления нового релиза запускается автоматически раз в 3 дня, а также может быть запущен вручную. -## Автоматическая сборка пакетов для SNAPSHOT версии -В репозитории настроен github action, который запускается каждые 4 часа и проверяет [страницу снапшотов](https://downloads.openwrt.org/snapshots/targets/) сайта OpenWRT. При этом, если для какой-то платформы обнаруживается снапшот с более новой версией ядра, запускается сборка пакетов под эту платформу, а новые файлы заменяют старые. В целях экономии ресурсов и ускорения процесса сборки, пакеты собираются только для популярных платформ, которые указаны в массиве `SNAPSHOT_SUBTARGETS_TO_BUILD` в файле index.js. - ## Выбор пакетов для своего устройства В соответствии с пунктом [Указываем переменные для сборки](https://github.com/itdoginfo/domain-routing-openwrt/wiki/Amnezia-WG-Build#%D1%83%D0%BA%D0%B0%D0%B7%D1%8B%D0%B2%D0%B0%D0%B5%D0%BC-%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5-%D0%B4%D0%BB%D1%8F-%D1%81%D0%B1%D0%BE%D1%80%D0%BA%D0%B8) определить `target` и `subtarget` вашего устройства. Далее перейти на страницу релиза, соответствующего вашей версии OpenWRT, затем поиском по странице (Ctrl+F) найти 3 пакета, название которых оканчивается на `target_subtarget.ipk`, соответствующие вашему устройству. @@ -71,8 +66,12 @@ 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) 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) - -And collected packages for popular devices for OpenWRT [SNAPSHOT](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/SNAPSHOT) +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) +8) [24.10.0](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.0) +9) [24.10.1](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.1) +10) [24.10.2](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.2) +11) AWG-2.0 [24.10.3](https://github.com/Slava-Shchipunov/awg-openwrt/releases/tag/v24.10.3) 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. diff --git a/amneziawg-install.sh b/amneziawg-install.sh index a09a12d..efba7f8 100644 --- a/amneziawg-install.sh +++ b/amneziawg-install.sh @@ -38,7 +38,7 @@ install_awg_packages() { opkg install "$AWG_DIR/$KMOD_AMNEZIAWG_FILENAME" if [ $? -eq 0 ]; then - echo "kmod-amneziawg file downloaded successfully" + echo "kmod-amneziawg installed successfully" else echo "Error installing kmod-amneziawg. Please, install kmod-amneziawg manually and run the script again" exit 1 @@ -62,37 +62,66 @@ install_awg_packages() { opkg install "$AWG_DIR/$AMNEZIAWG_TOOLS_FILENAME" if [ $? -eq 0 ]; then - echo "amneziawg-tools file downloaded successfully" + echo "amneziawg-tools installed successfully" else echo "Error installing amneziawg-tools. Please, install amneziawg-tools manually and run the script again" exit 1 fi fi - if opkg list-installed | grep -q luci-app-amneziawg; then - echo "luci-app-amneziawg already installed" + if opkg list-installed | grep -q luci-proto-amneziawg; then + echo "luci-proto-amneziawg already installed" else - LUCI_APP_AMNEZIAWG_FILENAME="luci-app-amneziawg${PKGPOSTFIX}" + LUCI_APP_AMNEZIAWG_FILENAME="luci-proto-amneziawg${PKGPOSTFIX}" DOWNLOAD_URL="${BASE_URL}v${VERSION}/${LUCI_APP_AMNEZIAWG_FILENAME}" wget -O "$AWG_DIR/$LUCI_APP_AMNEZIAWG_FILENAME" "$DOWNLOAD_URL" if [ $? -eq 0 ]; then - echo "luci-app-amneziawg file downloaded successfully" + echo "luci-proto-amneziawg file downloaded successfully" else - echo "Error downloading luci-app-amneziawg. Please, install luci-app-amneziawg manually and run the script again" + echo "Error downloading luci-proto-amneziawg. Please, install luci-proto-amneziawg manually and run the script again" exit 1 fi opkg install "$AWG_DIR/$LUCI_APP_AMNEZIAWG_FILENAME" if [ $? -eq 0 ]; then - echo "luci-app-amneziawg file downloaded successfully" + echo "luci-proto-amneziawg installed successfully" else - echo "Error installing luci-app-amneziawg. Please, install luci-app-amneziawg manually and run the script again" + echo "Error installing luci-proto-amneziawg. Please, install luci-proto-amneziawg manually and run the script again" exit 1 fi fi + # Ask about Russian localization + printf "\033[32;1mУстанавливаем пакет с русской локализацией? Install Russian language pack? (y/n) [n]: \033[0m\n" + read INSTALL_RU_LANG + INSTALL_RU_LANG=${INSTALL_RU_LANG:-n} + + if [ "$INSTALL_RU_LANG" = "y" ] || [ "$INSTALL_RU_LANG" = "Y" ]; then + if opkg list-installed | grep -q luci-i18n-amneziawg-ru; then + echo "luci-i18n-amneziawg-ru already installed" + else + LUCI_I18N_AMNEZIAWG_RU_FILENAME="luci-i18n-amneziawg-ru${PKGPOSTFIX}" + DOWNLOAD_URL="${BASE_URL}v${VERSION}/${LUCI_I18N_AMNEZIAWG_RU_FILENAME}" + wget -O "$AWG_DIR/$LUCI_I18N_AMNEZIAWG_RU_FILENAME" "$DOWNLOAD_URL" + + if [ $? -eq 0 ]; then + echo "luci-i18n-amneziawg-ru file downloaded successfully" + opkg install "$AWG_DIR/$LUCI_I18N_AMNEZIAWG_RU_FILENAME" + if [ $? -eq 0 ]; then + echo "luci-i18n-amneziawg-ru installed successfully" + else + echo "Warning: Error installing luci-i18n-amneziawg-ru (non-critical)" + fi + else + echo "Warning: Russian localization not available for this version/platform (non-critical)" + fi + fi + else + printf "\033[32;1mSkipping Russian language pack installation.\033[0m\n" + fi + rm -rf "$AWG_DIR" } diff --git a/amneziawg-tools/Makefile b/amneziawg-tools/Makefile index 6408e78..ffcee81 100644 --- a/amneziawg-tools/Makefile +++ b/amneziawg-tools/Makefile @@ -1,25 +1,18 @@ -# -# Copyright (C) 2016-2019 Jason A. Donenfeld -# Copyright (C) 2016 Baptiste Jonglez -# Copyright (C) 2016-2017 Dan Luedtke -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. - include $(TOPDIR)/rules.mk PKG_NAME:=amneziawg-tools +PKG_VERSION:=1.0.20250903 +PKG_RELEASE:=1 -PKG_VERSION:=1.0.20240213 -PKG_RELEASE:=$(AUTORELEASE) - -PKG_SOURCE:=v$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=https://github.com/amnezia-vpn/amneziawg-tools/archive/refs/tags/ -PKG_HASH:=4bde122630c9ddb1ec013c3e958f2c613b9eea56834674dda92fcb423c6f4d10 +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/amnezia-vpn/amneziawg-tools.git +# Version: latest stable release tag +PKG_SOURCE_VERSION:=v$(PKG_VERSION) PKG_LICENSE:=GPL-2.0 PKG_LICENSE_FILES:=COPYING +PKG_BUILD_DIR=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) include $(INCLUDE_DIR)/package.mk @@ -28,32 +21,29 @@ MAKE_VARS += PLATFORM=linux define Package/amneziawg-tools CATEGORY:=Network - URL:=https://www.wireguard.com - MAINTAINER:=Jason A. Donenfeld - TITLE:=WireGuard userspace control program (wg) + SUBMENU:=VPN + URL:=https://amnezia.org/ + MAINTAINER:=Amnezia Admin + TITLE:=AmneziaWG userspace control program (awg) DEPENDS:= \ +@BUSYBOX_CONFIG_IP \ +@BUSYBOX_CONFIG_FEATURE_IP_LINK endef define Package/amneziawg-tools/description - WireGuard is a novel VPN that runs inside the Linux Kernel and utilizes - state-of-the-art cryptography. It aims to be faster, simpler, leaner, and - more useful than IPSec, while avoiding the massive headache. It intends to - be considerably more performant than OpenVPN. WireGuard is designed as a - general purpose VPN for running on embedded interfaces and super computers - alike, fit for many different circumstances. It uses UDP. + Amnezia VPN — simple and free app to run a self-hosted VPN with + high privacy requirements. - This package provides the userspace control program for WireGuard, - `wg(8)`, a netifd protocol helper, and a re-resolve watchdog script. + This package provides the userspace control program for AmneziaWG, + `awg`, a netifd protocol helper, and a re-resolve watchdog script. endef define Package/amneziawg-tools/install $(INSTALL_DIR) $(1)/usr/bin/ - $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/wg $(1)/usr/bin/amneziawg + $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/wg $(1)/usr/bin/awg $(INSTALL_BIN) ./files/amneziawg_watchdog $(1)/usr/bin/ $(INSTALL_DIR) $(1)/lib/netifd/proto/ $(INSTALL_BIN) ./files/amneziawg.sh $(1)/lib/netifd/proto/ endef -$(eval $(call BuildPackage,amneziawg-tools)) \ No newline at end of file +$(eval $(call BuildPackage,amneziawg-tools)) diff --git a/amneziawg-tools/files/amneziawg.sh b/amneziawg-tools/files/amneziawg.sh index cb832af..e0587a8 100755 --- a/amneziawg-tools/files/amneziawg.sh +++ b/amneziawg-tools/files/amneziawg.sh @@ -2,9 +2,11 @@ # Copyright 2016-2017 Dan Luedtke # Licensed to the public under the Apache License 2.0. -WG=/usr/bin/amneziawg -if [ ! -x $WG ]; then - logger -t "amnezia-wg" "error: missing amneziawg-tools (${WG})" +# shellcheck disable=SC1091,SC3003,SC3043 + +AWG=/usr/bin/awg +if [ ! -x $AWG ]; then + logger -t "amneziawg" "error: missing amneziawg-tools (${AWG})" exit 0 fi @@ -24,25 +26,34 @@ proto_amneziawg_init_config() { proto_config_add_int "awg_jmax" proto_config_add_int "awg_s1" proto_config_add_int "awg_s2" - proto_config_add_int "awg_h1" - proto_config_add_int "awg_h2" - proto_config_add_int "awg_h3" - proto_config_add_int "awg_h4" + proto_config_add_int "awg_s3" + proto_config_add_int "awg_s4" + proto_config_add_string "awg_h1" + proto_config_add_string "awg_h2" + proto_config_add_string "awg_h3" + proto_config_add_string "awg_h4" + proto_config_add_string "awg_i1" + proto_config_add_string "awg_i2" + proto_config_add_string "awg_i3" + proto_config_add_string "awg_i4" + proto_config_add_string "awg_i5" +# shellcheck disable=SC2034 available=1 +# shellcheck disable=SC2034 no_proto_task=1 } proto_amneziawg_is_kernel_mode() { if [ ! -e /sys/module/amneziawg ]; then - modprobe amneziawg > /dev/null 2&>1 || true + modprobe amneziawg > /dev/null 2>&1 || true if [ -e /sys/module/amneziawg ]; then return 0 else - if [ ! command -v "${WG_QUICK_USERSPACE_IMPLEMENTATION:-amneziawg-go}" >/dev/null ]; then + if ! command -v "${WG_QUICK_USERSPACE_IMPLEMENTATION:-amneziawg-go}" >/dev/null; then ret=$? echo "Please install either kernel module (kmod-amneziawg package) or user-space implementation in /usr/bin/amneziawg-go." - exit $? + exit $ret else return 1 fi @@ -83,13 +94,13 @@ proto_amneziawg_setup_peer() { return 0 fi - echo "[Peer]" >> "${wg_cfg}" - echo "PublicKey=${public_key}" >> "${wg_cfg}" + echo "[Peer]" >> "${awg_cfg}" + echo "PublicKey=${public_key}" >> "${awg_cfg}" if [ "${preshared_key}" ]; then - echo "PresharedKey=${preshared_key}" >> "${wg_cfg}" + echo "PresharedKey=${preshared_key}" >> "${awg_cfg}" fi - for allowed_ip in $allowed_ips; do - echo "AllowedIPs=${allowed_ip}" >> "${wg_cfg}" + for allowed_ip in ${allowed_ips}; do + echo "AllowedIPs=${allowed_ip}" >> "${awg_cfg}" done if [ "${endpoint_host}" ]; then case "${endpoint_host}" in @@ -105,10 +116,10 @@ proto_amneziawg_setup_peer() { else endpoint="${endpoint}:51820" fi - echo "Endpoint=${endpoint}" >> "${wg_cfg}" + echo "Endpoint=${endpoint}" >> "${awg_cfg}" fi if [ "${persistent_keepalive}" ]; then - echo "PersistentKeepalive=${persistent_keepalive}" >> "${wg_cfg}" + echo "PersistentKeepalive=${persistent_keepalive}" >> "${awg_cfg}" fi if [ ${route_allowed_ips} -ne 0 ]; then @@ -140,7 +151,7 @@ ensure_key_is_generated() { oldmask="$(umask)" umask 077 ucitmp="$(mktemp -d)" - private_key="$("${WG}" genkey)" + private_key="$("${AWG}" genkey)" uci -q -t "$ucitmp" set network."$1".private_key="$private_key" && \ uci -q -t "$ucitmp" commit network rm -rf "$ucitmp" @@ -150,23 +161,35 @@ ensure_key_is_generated() { proto_amneziawg_setup() { local config="$1" - local wg_dir="/tmp/wireguard" - local wg_cfg="${wg_dir}/${config}" + local awg_dir="/tmp/amneziawg" + local awg_cfg="${awg_dir}/${config}" local private_key local listen_port + local addresses local mtu + local fwmark + local ip6prefix + local nohostroute + local tunlink - # Amnezia WG specific parameters + # AmneziaWG specific parameters local awg_jc local awg_jmin local awg_jmax local awg_s1 local awg_s2 + local awg_s3 + local awg_s4 local awg_h1 local awg_h2 local awg_h3 local awg_h4 + local awg_i1 + local awg_i2 + local awg_i3 + local awg_i4 + local awg_i5 ensure_key_is_generated "${config}" @@ -185,18 +208,25 @@ proto_amneziawg_setup() { config_get awg_jmax "${config}" "awg_jmax" config_get awg_s1 "${config}" "awg_s1" config_get awg_s2 "${config}" "awg_s2" + config_get awg_s3 "${config}" "awg_s3" + config_get awg_s4 "${config}" "awg_s4" config_get awg_h1 "${config}" "awg_h1" config_get awg_h2 "${config}" "awg_h2" config_get awg_h3 "${config}" "awg_h3" config_get awg_h4 "${config}" "awg_h4" + config_get awg_i1 "${config}" "awg_i1" + config_get awg_i2 "${config}" "awg_i2" + config_get awg_i3 "${config}" "awg_i3" + config_get awg_i4 "${config}" "awg_i4" + config_get awg_i5 "${config}" "awg_i5" if proto_amneziawg_is_kernel_mode; then - logger -t "amneziawg" "info: using kernel-space kmod-amneziawg for ${WG}" - ip link del dev "${config}" 2>/dev/null + logger -t "amneziawg" "info: using kernel-space kmod-amneziawg for ${AWG}" + ip link del dev "${config}" 2>/dev/null ip link add dev "${config}" type amneziawg else - logger -t "amneziawg" "info: using user-space amneziawg-go for ${WG}" - rm -f "/var/run/wireguard/${config}.sock" + logger -t "amneziawg" "info: using user-space amneziawg-go for ${AWG}" + rm -f "/var/run/amneziawg/${config}.sock" amneziawg-go "${config}" fi @@ -207,53 +237,73 @@ proto_amneziawg_setup() { proto_init_update "${config}" 1 umask 077 - mkdir -p "${wg_dir}" - echo "[Interface]" > "${wg_cfg}" - echo "PrivateKey=${private_key}" >> "${wg_cfg}" + mkdir -p "${awg_dir}" + echo "[Interface]" > "${awg_cfg}" + echo "PrivateKey=${private_key}" >> "${awg_cfg}" if [ "${listen_port}" ]; then - echo "ListenPort=${listen_port}" >> "${wg_cfg}" + echo "ListenPort=${listen_port}" >> "${awg_cfg}" fi if [ "${fwmark}" ]; then - echo "FwMark=${fwmark}" >> "${wg_cfg}" + echo "FwMark=${fwmark}" >> "${awg_cfg}" fi - # AWG + # AmneziaWG parameters if [ "${awg_jc}" ]; then - echo "Jc = ${awg_jc}" >> "${wg_cfg}" + echo "Jc=${awg_jc}" >> "${awg_cfg}" fi if [ "${awg_jmin}" ]; then - echo "Jmin = ${awg_jmin}" >> "${wg_cfg}" + echo "Jmin=${awg_jmin}" >> "${awg_cfg}" fi if [ "${awg_jmax}" ]; then - echo "Jmax = ${awg_jmax}" >> "${wg_cfg}" + echo "Jmax=${awg_jmax}" >> "${awg_cfg}" fi if [ "${awg_s1}" ]; then - echo "S1 = ${awg_s1}" >> "${wg_cfg}" + echo "S1=${awg_s1}" >> "${awg_cfg}" fi if [ "${awg_s2}" ]; then - echo "S2 = ${awg_s2}" >> "${wg_cfg}" + echo "S2=${awg_s2}" >> "${awg_cfg}" + fi + if [ "${awg_s3}" ]; then + echo "S3=${awg_s3}" >> "${awg_cfg}" + fi + if [ "${awg_s4}" ]; then + echo "S4=${awg_s4}" >> "${awg_cfg}" fi if [ "${awg_h1}" ]; then - echo "H1 = ${awg_h1}" >> "${wg_cfg}" + echo "H1=${awg_h1}" >> "${awg_cfg}" fi if [ "${awg_h2}" ]; then - echo "H2 = ${awg_h2}" >> "${wg_cfg}" + echo "H2=${awg_h2}" >> "${awg_cfg}" fi if [ "${awg_h3}" ]; then - echo "H3 = ${awg_h3}" >> "${wg_cfg}" + echo "H3=${awg_h3}" >> "${awg_cfg}" fi if [ "${awg_h4}" ]; then - echo "H4 = ${awg_h4}" >> "${wg_cfg}" + echo "H4=${awg_h4}" >> "${awg_cfg}" + fi + if [ "${awg_i1}" ]; then + echo "I1=${awg_i1}" >> "${awg_cfg}" + fi + if [ "${awg_i2}" ]; then + echo "I2=${awg_i2}" >> "${awg_cfg}" + fi + if [ "${awg_i3}" ]; then + echo "I3=${awg_i3}" >> "${awg_cfg}" + fi + if [ "${awg_i4}" ]; then + echo "I4=${awg_i4}" >> "${awg_cfg}" + fi + if [ "${awg_i5}" ]; then + echo "I5=${awg_i5}" >> "${awg_cfg}" fi - config_foreach proto_amneziawg_setup_peer "amneziawg_${config}" - # apply configuration file - ${WG} setconf ${config} "${wg_cfg}" - WG_RETURN=$? + # Apply configuration file + ${AWG} setconf "${config}" "${awg_cfg}" + AWG_RETURN=$? - rm -f "${wg_cfg}" + rm -f "${awg_cfg}" - if [ ${WG_RETURN} -ne 0 ]; then + if [ ${AWG_RETURN} -ne 0 ]; then sleep 5 proto_setup_failed "${config}" exit 1 @@ -282,7 +332,8 @@ proto_amneziawg_setup() { # endpoint dependency if [ "${nohostroute}" != "1" ]; then - ${WG} show "${config}" endpoints | \ + # shellcheck disable=SC2034 + ${AWG} show "${config}" endpoints | \ sed -E 's/\[?([0-9.:a-f]+)\]?:([0-9]+)/\1 \2/' | \ while IFS=$'\t ' read -r key address port; do [ -n "${port}" ] || continue @@ -295,14 +346,13 @@ proto_amneziawg_setup() { proto_amneziawg_teardown() { local config="$1" - proto_amneziawg_check_installed if proto_amneziawg_is_kernel_mode; then ip link del dev "${config}" >/dev/null 2>&1 else - rm -f /var/run/wireguard/${config}.sock + rm -f "/var/run/amneziawg/${config}.sock" fi } [ -n "$INCLUDE_ONLY" ] || { add_protocol amneziawg -} \ No newline at end of file +} diff --git a/amneziawg-tools/files/amneziawg_watchdog b/amneziawg-tools/files/amneziawg_watchdog index a9b631a..a8e825c 100755 --- a/amneziawg-tools/files/amneziawg_watchdog +++ b/amneziawg-tools/files/amneziawg_watchdog @@ -11,12 +11,13 @@ # Run this script from cron every minute: # echo '* * * * * /usr/bin/wireguard_watchdog' >> /etc/crontabs/root +# shellcheck disable=SC1091,SC3043 . /lib/functions.sh check_peer_activity() { - local cfg=$1 - local iface=$2 + local cfg="$1" + local iface="$2" local disabled local public_key local endpoint_host @@ -26,7 +27,7 @@ check_peer_activity() { local idle_seconds config_get_bool disabled "${cfg}" "disabled" 0 - config_get public_key "${cfg}" "public_key" + config_get public_key "${cfg}" "public_key" config_get endpoint_host "${cfg}" "endpoint_host" config_get endpoint_port "${cfg}" "endpoint_port" @@ -35,34 +36,35 @@ check_peer_activity() { return 0 fi - persistent_keepalive=$(wg show ${iface} persistent-keepalive | grep ${public_key} | awk '{print $2}') + persistent_keepalive=$(awg show "${iface}" persistent-keepalive | grep "${public_key}" | awk '{print $2}') # only process peers with endpoints and keepalive set - [ -z ${endpoint_host} ] && return 0; - [ -z ${persistent_keepalive} -o ${persistent_keepalive} = "off" ] && return 0; + [ -z "${endpoint_host}" ] && return 0; + if [ -z "${persistent_keepalive}" ] || [ "${persistent_keepalive}" = "off" ]; then return 0; fi # skip IP addresses # check taken from packages/net/ddns-scripts/files/dynamic_dns_functions.sh local IPV4_REGEX="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" local IPV6_REGEX="\(\([0-9A-Fa-f]\{1,4\}:\)\{1,\}\)\(\([0-9A-Fa-f]\{1,4\}\)\{0,1\}\)\(\(:[0-9A-Fa-f]\{1,4\}\)\{1,\}\)" - local IPV4=$(echo ${endpoint_host} | grep -m 1 -o "$IPV4_REGEX$") # do not detect ip in 0.0.0.0.example.com - local IPV6=$(echo ${endpoint_host} | grep -m 1 -o "$IPV6_REGEX") - [ -n "${IPV4}" -o -n "${IPV6}" ] && return 0; + local IPV4 IPV6 + IPV4="$(echo "${endpoint_host}" | grep -m 1 -o "$IPV4_REGEX$")" # do not detect ip in 0.0.0.0.example.com + IPV6="$(echo "${endpoint_host}" | grep -m 1 -o "$IPV6_REGEX")" + [ -n "${IPV4}${IPV6}" ] && return 0; # re-resolve endpoint hostname if not responding for too long - last_handshake=$(wg show ${iface} latest-handshakes | grep ${public_key} | awk '{print $2}') - [ -z ${last_handshake} ] && return 0; + last_handshake=$(awg show "${iface}" latest-handshakes | grep "${public_key}" | awk '{print $2}') + [ -z "${last_handshake}" ] && return 0; idle_seconds=$(($(date +%s)-${last_handshake})) [ ${idle_seconds} -lt 150 ] && return 0; - logger -t "wireguard_monitor" "${iface} endpoint ${endpoint_host}:${endpoint_port} is not responding for ${idle_seconds} seconds, trying to re-resolve hostname" - wg set ${iface} peer ${public_key} endpoint "${endpoint_host}:${endpoint_port}" + logger -t "amneziawg_monitor" "${iface} endpoint ${endpoint_host}:${endpoint_port} is not responding for ${idle_seconds} seconds, trying to re-resolve hostname" + awg set "${iface}" peer "${public_key}" endpoint "${endpoint_host}:${endpoint_port}" } # query ubus for all active wireguard interfaces -wg_ifaces=$(ubus -S call network.interface dump | jsonfilter -e '@.interface[@.up=true]' | jsonfilter -a -e '@[@.proto="wireguard"].interface' | tr "\n" " ") +awg_ifaces=$(ubus -S call network.interface dump | jsonfilter -e '@.interface[@.up=true]' | jsonfilter -a -e '@[@.proto="amneziawg"].interface' | tr "\n" " ") # check every peer in every active wireguard interface config_load network -for iface in $wg_ifaces; do - config_foreach check_peer_activity "wireguard_${iface}" "${iface}" -done \ No newline at end of file +for iface in $awg_ifaces; do + config_foreach check_peer_activity "amneziawg_${iface}" "${iface}" +done diff --git a/index.js b/index.js index 8528dae..cc0bdcf 100644 --- a/index.js +++ b/index.js @@ -3,16 +3,19 @@ const cheerio = require('cheerio'); const core = require('@actions/core'); 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) { core.setFailed('Version argument is required'); 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) { try { @@ -74,19 +77,38 @@ async function main() { const jobConfig = []; for (const target of targets) { + // Пропускаем target, если указан массив фильтров и target не входит в него + if (filterTargets.length > 0 && !filterTargets.includes(target)) { + continue; + } + const subtargets = await getSubtargets(target); 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); - if (version !== 'SNAPSHOT' || (SNAPSHOT_SUBTARGETS_TO_BUILD.includes(subtarget) && SNAPSHOT_TARGETS_TO_BUILD.includes(target))) { - jobConfig.push({ - tag: version, - target, - subtarget, - vermagic, - pkgarch, - }); - } + jobConfig.push({ + tag: version, + target, + subtarget, + vermagic, + pkgarch, + }); } } diff --git a/kmod-amneziawg/Makefile b/kmod-amneziawg/Makefile index 6660664..d5e99c5 100644 --- a/kmod-amneziawg/Makefile +++ b/kmod-amneziawg/Makefile @@ -1,10 +1,17 @@ include $(TOPDIR)/rules.mk - include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=kmod-amneziawg +PKG_VERSION:=1.0.20250924 PKG_RELEASE:=1 +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/amnezia-vpn/amneziawg-linux-kernel-module.git +# Latest commit from feature/awg2 branch as of 2025-09-24 +PKG_SOURCE_VERSION:=2a94fcc67c332bbb4b983fcebe03ac31057ead19 +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) +MAKE_PATH:=src + include $(INCLUDE_DIR)/package.mk define KernelPackage/amneziawg @@ -12,7 +19,7 @@ define KernelPackage/amneziawg CATEGORY:=Kernel modules SUBMENU:=Network Support TITLE:=AmneziaWG VPN Kernel Module - FILES:=$(PKG_BUILD_DIR)/amneziawg.ko + FILES:=$(PKG_BUILD_DIR)/$(MAKE_PATH)/amneziawg.ko DEPENDS:= \ +kmod-udptunnel4 \ +kmod-udptunnel6 \ @@ -21,19 +28,17 @@ define KernelPackage/amneziawg endef define Build/Prepare - cp -fr $(LINUX_DIR)/drivers/net/wireguard/{*.c,*.h,selftest/} $(PKG_BUILD_DIR) - mkdir -p $(PKG_BUILD_DIR)/uapi - cp -f $(LINUX_DIR)/include/uapi/linux/wireguard.h $(PKG_BUILD_DIR)/uapi/ - patch -d $(PKG_BUILD_DIR)/ < files/amnezia-sources.patch - patch -d $(PKG_BUILD_DIR)/uapi/ < files/amnezia-uapi.patch - cp -f src/Makefile $(PKG_BUILD_DIR) + $(call Build/Prepare/Default) + mkdir -p $(PKG_BUILD_DIR)/$(MAKE_PATH)/kernel + $(CP) $(LINUX_DIR)/* $(PKG_BUILD_DIR)/$(MAKE_PATH)/kernel/ endef define Build/Compile - $(MAKE) -C "$(LINUX_DIR)" \ + $(MAKE_VARS) $(MAKE) -C "$(LINUX_DIR)" \ $(KERNEL_MAKE_FLAGS) \ - M="$(PKG_BUILD_DIR)" \ + M="$(PKG_BUILD_DIR)/$(MAKE_PATH)" \ EXTRA_CFLAGS="$(BUILDFLAGS)" \ + WIREGUARD_VERSION="$(WIREGUARD_VERSION)" \ modules endef diff --git a/kmod-amneziawg/files/amnezia-sources.patch b/kmod-amneziawg/files/amnezia-sources.patch deleted file mode 100644 index e8f5f62..0000000 --- a/kmod-amneziawg/files/amnezia-sources.patch +++ /dev/null @@ -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 . All Rights Reserved. - */ - --#include "version.h" - #include "device.h" - #include "noise.h" - #include "queueing.h" - #include "ratelimiter.h" - #include "netlink.h" - --#include -+#include "uapi/wireguard.h" - - #include - #include -@@ -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 . 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 "); - 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 -+#include "uapi/wireguard.h" - - #include - #include -@@ -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 - #include - #include -+#include - #include - #include - #include - -+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" diff --git a/kmod-amneziawg/files/amnezia-uapi.patch b/kmod-amneziawg/files/amnezia-uapi.patch deleted file mode 100644 index cbe2193..0000000 --- a/kmod-amneziawg/files/amnezia-uapi.patch +++ /dev/null @@ -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) diff --git a/kmod-amneziawg/src/Makefile b/kmod-amneziawg/src/Makefile deleted file mode 100644 index f0473ba..0000000 --- a/kmod-amneziawg/src/Makefile +++ /dev/null @@ -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 diff --git a/luci-app-amneziawg/Makefile b/luci-app-amneziawg/Makefile deleted file mode 100644 index 037cd50..0000000 --- a/luci-app-amneziawg/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (C) 2016 Dan Luedtke -# -# This is free software, licensed under the Apache License, Version 2.0 . -# - -include $(TOPDIR)/rules.mk - -LUCI_TITLE:=Support for AmneziaWG VPN -LUCI_DEPENDS:=+amneziawg-tools +ucode +qrencode -LUCI_PKGARCH:=all - -PKG_PROVIDES:=luci-app-amneziawg - -include $(TOPDIR)/feeds/luci/luci.mk - -# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-proto-amneziawg/Makefile b/luci-proto-amneziawg/Makefile new file mode 100644 index 0000000..15562da --- /dev/null +++ b/luci-proto-amneziawg/Makefile @@ -0,0 +1,13 @@ +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=Support for AmneziaWG VPN +LUCI_DESCRIPTION:=Provides support and Web UI for AmneziaWG VPN +PKG_VERSION:=2.0.4 +LUCI_DEPENDS:=+amneziawg-tools +ucode +luci-lib-uqr +resolveip +LUCI_PKGARCH:=all + +PKG_LICENSE:=Apache-2.0 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-proto-amneziawg/htdocs/luci-static/resources/icons/amneziawg.svg b/luci-proto-amneziawg/htdocs/luci-static/resources/icons/amneziawg.svg new file mode 100644 index 0000000..5bf7f01 --- /dev/null +++ b/luci-proto-amneziawg/htdocs/luci-static/resources/icons/amneziawg.svg @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/luci-app-amneziawg/htdocs/luci-static/resources/protocol/amneziawg.js b/luci-proto-amneziawg/htdocs/luci-static/resources/protocol/amneziawg.js similarity index 81% rename from luci-app-amneziawg/htdocs/luci-static/resources/protocol/amneziawg.js rename to luci-proto-amneziawg/htdocs/luci-static/resources/protocol/amneziawg.js index b9142b8..d432d8d 100644 --- a/luci-app-amneziawg/htdocs/luci-static/resources/protocol/amneziawg.js +++ b/luci-proto-amneziawg/htdocs/luci-static/resources/protocol/amneziawg.js @@ -7,6 +7,7 @@ 'require form'; 'require network'; 'require validation'; +'require uqr'; var generateKey = rpc.declare({ object: 'luci.amneziawg', @@ -64,42 +65,16 @@ function generateDescription(name, texts) { ]); } -function invokeQREncode(data, div) { - - var code = div.children[0]; - var btn = div.children[1]; - - dom.content(btn, [ - E('a', { - 'class': 'btn cbi-button-action', - 'style': 'text-align: center', - 'href': 'data:text/plain;charset=utf-8,' + encodeURIComponent(data), - 'download': 'amneziawg.conf' - - }, ['Download Configuration']), - ]); - - return fs.exec_direct('/usr/bin/qrencode', [ - '--inline', '--8bit', '--type=SVG', - '--output=-', '--', data - ]).then(function(svg) { - div.style.opacity = ''; - dom.content(code, Object.assign(E(svg), { style: 'width:100%;height:auto' })); - }).catch(function(error) { - div.style.opacity = ''; - - if (L.isObject(error) && error.name == 'NotFoundError') { - dom.content(code, [ - Object.assign(E(qrIcon), { style: 'width:32px;height:32px;opacity:.2' }), - E('p', _('The qrencode package is required for generating an QR code image of the configuration.')) - ]); - } - else { - dom.content(code, [ - _('Unable to generate QR code: %s').format(L.isObject(error) ? error.message : error) - ]); - } - }); +function buildSVGQRCode(data, code) { + // pixel size larger than 4 clips right and bottom edges of complex configs + const options = { + pixelSize: 4, + whiteColor: 'white', + blackColor: 'black' + }; + const svg = uqr.renderSVG(data, options); + code.style.opacity = ''; + dom.content(code, Object.assign(E(svg), { style: 'width:100%;height:auto' })); } var cbiKeyPairGenerate = form.DummyValue.extend({ @@ -111,9 +86,6 @@ var cbiKeyPairGenerate = form.DummyValue.extend({ pub = this.section.getUIElement(section_id, 'public_key'), map = this.map; - if ((prv.getValue() || pub.getValue()) && !confirm(_('Do you want to replace the current keys?'))) - return; - return generateKey().then(function(keypair) { prv.setValue(keypair.priv); pub.setValue(keypair.pub); @@ -137,7 +109,7 @@ return network.registerProtocol('amneziawg', { return this._ubus('l3_device') || this.sid; }, - getOpkgPackage: function() { + getPackageName: function() { return 'amneziawg-tools'; }, @@ -212,7 +184,7 @@ return network.registerProtocol('amneziawg', { o.placeholder = '1420'; o.optional = true; - o = s.taboption('advanced', form.Value, 'fwmark', _('Firewall Mark'), _('Optional. 32-bit mark for outgoing encrypted packets. Enter value in hex, starting with 0x.')); + o = s.taboption('advanced', form.Value, 'fwmark', _('Firewall Mark'), _('Optional. 32-bit mark for packets during firewall processing. Enter value in hex, starting with 0x.')); o.optional = true; o.validate = function(section_id, value) { if (value.length > 0 && !value.match(/^0x[a-fA-F0-9]{1,8}$/)) @@ -224,62 +196,102 @@ return network.registerProtocol('amneziawg', { // AmneziaWG try { - s.tab('amneziawg', _('AmneziaWG Settings'), _('Further information about AmneziaWG interfaces and peers at amnezia.org.')); + s.tab('amneziawg', _('AmneziaWG Settings'), _('Further information about AmneziaWG interfaces and peers at amnezia.org.')); } catch(e) {} o = s.taboption('amneziawg', form.Value, 'awg_jc', _('Jc'), _('Junk packet count.')); o.datatype = 'uinteger'; + o.placeholder = '0'; o.optional = true; o = s.taboption('amneziawg', form.Value, 'awg_jmin', _('Jmin'), _('Junk packet minimum size.')); o.datatype = 'uinteger'; + o.placeholder = '0'; o.optional = true; o = s.taboption('amneziawg', form.Value, 'awg_jmax', _('Jmax'), _('Junk packet maximum size.')); o.datatype = 'uinteger'; + o.placeholder = '0'; o.optional = true; o = s.taboption('amneziawg', form.Value, 'awg_s1', _('S1'), _('Handshake initiation packet junk header size.')); o.datatype = 'uinteger'; + o.placeholder = '0'; o.optional = true; o = s.taboption('amneziawg', form.Value, 'awg_s2', _('S2'), _('Handshake response packet junk header size.')); o.datatype = 'uinteger'; + o.placeholder = '0'; + o.optional = true; + + o = s.taboption('amneziawg', form.Value, 'awg_s3', _('S3'), _('Cookie reply packet junk header size.')); + o.datatype = 'uinteger'; + o.placeholder = '0'; + o.optional = true; + + o = s.taboption('amneziawg', form.Value, 'awg_s4', _('S4'), _('Transport packet junk header size.')); + o.datatype = 'uinteger'; + o.placeholder = '0'; o.optional = true; o = s.taboption('amneziawg', form.Value, 'awg_h1', _('H1'), _('Handshake initiation packet type header.')); - o.datatype = 'uinteger'; + o.datatype = 'string'; + o.placeholder = '1'; o.optional = true; o = s.taboption('amneziawg', form.Value, 'awg_h2', _('H2'), _('Handshake response packet type header.')); - o.datatype = 'uinteger'; + o.datatype = 'string'; + o.placeholder = '2'; o.optional = true; o = s.taboption('amneziawg', form.Value, 'awg_h3', _('H3'), _('Handshake cookie packet type header.')); - o.datatype = 'uinteger'; + o.datatype = 'string'; + o.placeholder = '3'; o.optional = true; o = s.taboption('amneziawg', form.Value, 'awg_h4', _('H4'), _('Transport packet type header.')); - o.datatype = 'uinteger'; + o.datatype = 'string'; + o.placeholder = '4'; + o.optional = true; + + o = s.taboption('amneziawg', form.Value, 'awg_i1', _('I1'), _('First special junk packet signature.')); + o.datatype = 'string'; + o.optional = true; + + o = s.taboption('amneziawg', form.Value, 'awg_i2', _('I2'), _('Second special junk packet signature.')); + o.datatype = 'string'; + o.optional = true; + + o = s.taboption('amneziawg', form.Value, 'awg_i3', _('I3'), _('Third special junk packet signature.')); + o.datatype = 'string'; + o.optional = true; + + o = s.taboption('amneziawg', form.Value, 'awg_i4', _('I4'), _('Fourth special junk packet signature.')); + o.datatype = 'string'; + o.optional = true; + + o = s.taboption('amneziawg', form.Value, 'awg_i5', _('I5'), _('Fifth special junk packet signature.')); + o.datatype = 'string'; o.optional = true; // -- peers ----------------------------------------------------------------------- try { - s.tab('peers', _('Peers'), _('Further information about AmneziaWG interfaces and peers at amneziawg.com.')); + s.tab('peers', _('Peers'), _('Further information about AmneziaWG interfaces and peers at amnezia.org.')); } catch(e) {} o = s.taboption('peers', form.SectionValue, '_peers', form.GridSection, 'amneziawg_%s'.format(s.section)); o.depends('proto', 'amneziawg'); - ss = o.subsection; + ss = o.subsection; ss.anonymous = true; ss.addremove = true; ss.addbtntitle = _('Add peer'); ss.nodescriptions = true; ss.modaltitle = _('Edit peer'); + ss.sortable = true; ss.handleDragConfig = function(ev) { ev.stopPropagation(); @@ -416,15 +428,22 @@ return network.registerProtocol('amneziawg', { s.getOption('public_key').getUIElement(s.section).setValue(keypair.pub); s.getOption('listen_port').getUIElement(s.section).setValue(config.interface_listenport || ''); s.getOption('addresses').getUIElement(s.section).setValue(config.interface_address); - s.getOption('awg_jc').getUIElement(s.section).setValue(config.interface_jc); - s.getOption('awg_jmin').getUIElement(s.section).setValue(config.interface_jmin); - s.getOption('awg_jmax').getUIElement(s.section).setValue(config.interface_jmax); - s.getOption('awg_s1').getUIElement(s.section).setValue(config.interface_s1); - s.getOption('awg_s2').getUIElement(s.section).setValue(config.interface_s2); - s.getOption('awg_h1').getUIElement(s.section).setValue(config.interface_h1); - s.getOption('awg_h2').getUIElement(s.section).setValue(config.interface_h2); - s.getOption('awg_h3').getUIElement(s.section).setValue(config.interface_h3); - s.getOption('awg_h4').getUIElement(s.section).setValue(config.interface_h4); + s.getOption('awg_jc').getUIElement(s.section).setValue(config.interface_jc || ''); + s.getOption('awg_jmin').getUIElement(s.section).setValue(config.interface_jmin || ''); + s.getOption('awg_jmax').getUIElement(s.section).setValue(config.interface_jmax || ''); + s.getOption('awg_s1').getUIElement(s.section).setValue(config.interface_s1 || ''); + s.getOption('awg_s2').getUIElement(s.section).setValue(config.interface_s2 || ''); + s.getOption('awg_s3').getUIElement(s.section).setValue(config.interface_s3 || ''); + s.getOption('awg_s4').getUIElement(s.section).setValue(config.interface_s4 || ''); + s.getOption('awg_h1').getUIElement(s.section).setValue(config.interface_h1 || ''); + s.getOption('awg_h2').getUIElement(s.section).setValue(config.interface_h2 || ''); + s.getOption('awg_h3').getUIElement(s.section).setValue(config.interface_h3 || ''); + s.getOption('awg_h4').getUIElement(s.section).setValue(config.interface_h4 || ''); + s.getOption('awg_i1').getUIElement(s.section).setValue(config.interface_i1 || ''); + s.getOption('awg_i2').getUIElement(s.section).setValue(config.interface_i2 || ''); + s.getOption('awg_i3').getUIElement(s.section).setValue(config.interface_i3 || ''); + s.getOption('awg_i4').getUIElement(s.section).setValue(config.interface_i4 || ''); + s.getOption('awg_i5').getUIElement(s.section).setValue(config.interface_i5 || ''); if (config.interface_dns) s.getOption('dns').getUIElement(s.section).setValue(config.interface_dns); @@ -500,7 +519,7 @@ return network.registerProtocol('amneziawg', { E('p', _('Drag or paste a valid *.conf file below to configure the local AmneziaWG interface.')) ] : [ E('p', _('Paste or drag a AmneziaWG configuration (commonly wg0.conf) 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 configuration import instead.')) + E('p', _('To configure fully the local AmneziaWG interface from an existing (e.g. provider supplied) configuration file, use the configuration import instead.')) ]), E('p', [ E('textarea', { @@ -575,9 +594,10 @@ return network.registerProtocol('amneziawg', { return E('em', _('No peers defined yet.')); }; - o = ss.option(form.Flag, 'disabled', _('Peer disabled'), _('Enable / Disable peer. Restart amneziawg interface to apply changes.')); - o.modalonly = true; + o = ss.option(form.Flag, 'disabled', _('Disabled'), _('Enable / Disable peer. Restart amneziawg interface to apply changes.')); + o.editable = true; o.optional = true; + o.width = '5%'; o = ss.option(form.Value, 'description', _('Description'), _('Optional. Description of peer.')); o.placeholder = 'My Peer'; @@ -675,9 +695,6 @@ return network.registerProtocol('amneziawg', { var psk = this.section.getUIElement(section_id, 'preshared_key'), map = this.map; - if (psk.getValue() && !confirm(_('Do you want to replace the current PSK?'))) - return; - return generatePsk().then(function(key) { psk.setValue(key); map.save(null, true); @@ -757,69 +774,78 @@ return network.registerProtocol('amneziawg', { o.modalonly = true; - o.createPeerConfig = function (section_id, endpoint, ips, eips, dns) { + o.createPeerConfig = function(section_id, endpoint, ips, eips, dns) { var pub = s.formvalue(s.section, 'public_key'), - port = s.formvalue(s.section, 'listen_port') || '51820', - prv = this.section.formvalue(section_id, 'private_key'), - psk = this.section.formvalue(section_id, 'preshared_key'), - eport = this.section.formvalue(section_id, 'endpoint_port'), - keep = this.section.formvalue(section_id, 'persistent_keepalive'), - jc = s.formvalue(s.section, 'awg_jc'), - jmin = s.formvalue(s.section, 'awg_jmin'), - jmax = s.formvalue(s.section, 'awg_jmax'), - s1 = s.formvalue(s.section, 'awg_s1'), - s2 = s.formvalue(s.section, 'awg_s2'), - h1 = s.formvalue(s.section, 'awg_h1'), - h2 = s.formvalue(s.section, 'awg_h2'), - h3 = s.formvalue(s.section, 'awg_h3'), - h4 = s.formvalue(s.section, 'awg_h4'); - + port = s.formvalue(s.section, 'listen_port') || '51820', + jc = s.formvalue(s.section, 'awg_jc'), + jmin = s.formvalue(s.section, 'awg_jmin'), + jmax = s.formvalue(s.section, 'awg_jmax'), + s1 = s.formvalue(s.section, 'awg_s1'), + s2 = s.formvalue(s.section, 'awg_s2'), + s3 = s.formvalue(s.section, 'awg_s3'), + s4 = s.formvalue(s.section, 'awg_s4'), + h1 = s.formvalue(s.section, 'awg_h1'), + h2 = s.formvalue(s.section, 'awg_h2'), + h3 = s.formvalue(s.section, 'awg_h3'), + h4 = s.formvalue(s.section, 'awg_h4'), + i1 = s.formvalue(s.section, 'awg_i1'), + i2 = s.formvalue(s.section, 'awg_i2'), + i3 = s.formvalue(s.section, 'awg_i3'), + i4 = s.formvalue(s.section, 'awg_i4'), + i5 = s.formvalue(s.section, 'awg_i5'), + prv = this.section.formvalue(section_id, 'private_key'), + psk = this.section.formvalue(section_id, 'preshared_key'), + eport = this.section.formvalue(section_id, 'endpoint_port'), + keep = this.section.formvalue(section_id, 'persistent_keepalive'); + + // If endpoint is IPv6 we must escape it with [] if (endpoint.indexOf(':') > 0) { - endpoint = '[' + endpoint + ']'; + endpoint = '['+endpoint+']'; } - var configLines = [ + + return [ '[Interface]', 'PrivateKey = ' + prv, - eport ? 'ListenPort = ' + eport : '# ListenPort not defined', eips && eips.length ? 'Address = ' + eips.join(', ') : '# Address not defined', + eport ? 'ListenPort = ' + eport : '# ListenPort not defined', dns && dns.length ? 'DNS = ' + dns.join(', ') : '# DNS not defined', - '' - ]; - - if (jc) configLines.push('jc = ' + jc); - if (jmin) configLines.push('jmin = ' + jmin); - if (jmax) configLines.push('jmax = ' + jmax); - if (s1) configLines.push('s1 = ' + s1); - if (s2) configLines.push('s2 = ' + s2); - if (h1) configLines.push('h1 = ' + h1); - if (h2) configLines.push('h2 = ' + h2); - if (h3) configLines.push('h3 = ' + h3); - if (h4) configLines.push('h4 = ' + h4); - - configLines.push( + jc ? 'Jc = ' + jc : '# Jc not defined', + jmin ? 'Jmin = ' + jmin : '# Jmin not defined', + jmax ? 'Jmax = ' + jmax : '# Jmax not defined', + s1 ? 'S1 = ' + s1 : '# S1 not defined', + s2 ? 'S2 = ' + s2 : '# S2 not defined', + s3 ? 'S3 = ' + s3 : '# S3 not defined', + s4 ? 'S4 = ' + s4 : '# S4 not defined', + h1 ? 'H1 = ' + h1 : '# H1 not defined', + h2 ? 'H2 = ' + h2 : '# H2 not defined', + h3 ? 'H3 = ' + h3 : '# H3 not defined', + h4 ? 'H4 = ' + h4 : '# H4 not defined', + i1 ? 'I1 = ' + i1 : '# I1 not defined', + i2 ? 'I2 = ' + i2 : '# I2 not defined', + i3 ? 'I3 = ' + i3 : '# I3 not defined', + i4 ? 'I4 = ' + i4 : '# I4 not defined', + i5 ? 'I5 = ' + i5 : '# I5 not defined', '', '[Peer]', 'PublicKey = ' + pub, psk ? 'PresharedKey = ' + psk : '# PresharedKey not used', ips && ips.length ? 'AllowedIPs = ' + ips.join(', ') : '# AllowedIPs not defined', endpoint ? 'Endpoint = ' + endpoint + ':' + port : '# Endpoint not defined', - keep ? 'PersistentKeepAlive = ' + keep : '# PersistentKeepAlive not defined', - '' - ); - - return configLines.join('\n'); - }; + keep ? 'PersistentKeepAlive = ' + keep : '# PersistentKeepAlive not defined' + ].join('\n'); + }; o.handleGenerateQR = function(section_id, ev) { var mapNode = ss.getActiveModalMap(), - headNode = mapNode.parentNode.querySelector('h4'), - configGenerator = this.createPeerConfig.bind(this, section_id), - parent = this.map, + headNode = mapNode.parentNode.querySelector('h4'), + configGenerator = this.createPeerConfig.bind(this, section_id), + parent = this.map, eips = this.section.formvalue(section_id, 'allowed_ips'); return Promise.all([ network.getWANNetworks(), network.getWAN6Networks(), + network.getNetwork('lan'), L.resolveDefault(uci.load('ddns')), L.resolveDefault(uci.load('system')), parent.save(null, true) @@ -827,12 +853,12 @@ return network.registerProtocol('amneziawg', { var hostnames = []; uci.sections('ddns', 'service', function(s) { - if (typeof(s.lookup_host) == 'string' && s.enabled == '1') + if (typeof(s?.lookup_host) == 'string' && s?.enabled == '1') hostnames.push(s.lookup_host); }); uci.sections('system', 'system', function(s) { - if (typeof(s.hostname) == 'string' && s.hostname.indexOf('.') > 0) + if (typeof(s?.hostname) == 'string' && s?.hostname?.indexOf('.') > 0) hostnames.push(s.hostname); }); @@ -846,34 +872,34 @@ return network.registerProtocol('amneziawg', { var dns = []; + var lan = data[2]; + if (lan) { + var lanIp = lan.getIPAddr(); + if (lanIp) { + dns.unshift(lanIp) + } + } + var qrm, qrs, qro; - qrm = new form.JSONMap({ - config: { - endpoint: hostnames[0], - allowed_ips: ips, - addresses: eips, - dns_servers: dns - } - }, null, _('The generated configuration can be imported into a AmneziaWG client application to set up a connection towards this device.')); - + qrm = new form.JSONMap({ config: { endpoint: hostnames[0], allowed_ips: ips, addresses: eips, dns_servers: dns } }, null, _('The generated configuration can be imported into a WireGuard client application to set up a connection towards this device.')); qrm.parent = parent; qrs = qrm.section(form.NamedSection, 'config'); function handleConfigChange(ev, section_id, value) { var code = this.map.findElement('.qr-code'), - conf = this.map.findElement('.client-config'), - endpoint = this.section.getUIElement(section_id, 'endpoint'), - ips = this.section.getUIElement(section_id, 'allowed_ips'); - eips = this.section.getUIElement(section_id, 'addresses'); - dns = this.section.getUIElement(section_id, 'dns_servers'); + conf = this.map.findElement('.client-config'), + endpoint = this.section.getUIElement(section_id, 'endpoint'), + ips = this.section.getUIElement(section_id, 'allowed_ips'); + eips = this.section.getUIElement(section_id, 'addresses'); + dns = this.section.getUIElement(section_id, 'dns_servers'); if (this.isValid(section_id)) { conf.firstChild.data = configGenerator(endpoint.getValue(), ips.getValue(), eips.getValue(), dns.getValue()); code.style.opacity = '.5'; - invokeQREncode(conf.firstChild.data, code); + buildSVGQRCode(conf.firstChild.data, code); } }; @@ -897,7 +923,7 @@ return network.registerProtocol('amneziawg', { qro.datatype = 'ipaddr'; qro.default = eips; eips.forEach(function(eip) { qro.value(eip) }); - qro.onchange = handleConfigChange; + qro.onchange = handleConfigChange; qro = qrs.option(form.DummyValue, 'output'); qro.renderWidget = function() { @@ -908,16 +934,9 @@ return network.registerProtocol('amneziawg', { }, [ E('div', { 'class': 'qr-code', - 'style': 'display:flex; flex-direction: column; text-align: center', + 'style': 'width:320px;flex:0 1 320px;text-align:center' }, [ - E('div', { - 'style': 'width:320px;flex:0 1 320px;text-align:center' - }, [ - E('em', { 'class': 'spinning' }, [ _('Generating QR code…') ]) - ]), - - E('div', { - }, ['Download Configuration']), + E('em', { 'class': 'spinning' }, [ _('Generating QR code…') ]) ]), E('pre', { 'class': 'client-config', @@ -934,7 +953,7 @@ return network.registerProtocol('amneziawg', { }, [ peer_config ]) ]); - invokeQREncode(peer_config, node.firstChild); + buildSVGQRCode(peer_config, node.firstChild); return node; }; diff --git a/luci-app-amneziawg/htdocs/luci-static/resources/view/amneziawg/status.js b/luci-proto-amneziawg/htdocs/luci-static/resources/view/amneziawg/status.js similarity index 95% rename from luci-app-amneziawg/htdocs/luci-static/resources/view/amneziawg/status.js rename to luci-proto-amneziawg/htdocs/luci-static/resources/view/amneziawg/status.js index dc6c89b..716f8b4 100644 --- a/luci-app-amneziawg/htdocs/luci-static/resources/view/amneziawg/status.js +++ b/luci-proto-amneziawg/htdocs/luci-static/resources/view/amneziawg/status.js @@ -6,9 +6,9 @@ 'require ui'; -var callGetWgInstances = rpc.declare({ +var callgetAwgInstances = rpc.declare({ object: 'luci.amneziawg', - method: 'getWgInstances' + method: 'getAwgInstances' }); function timestampToStr(timestamp) { @@ -128,7 +128,7 @@ return view.extend({ 'click': ui.createHandlerFn(this, handleInterfaceDetails, ifaces[instanceName]) }, [ E('span', { 'class': 'ifacebadge' }, [ - E('img', { 'src': L.resource('icons', 'tunnel.svg') }), + E('img', { 'src': L.resource('icons', 'amneziawg.svg') }), '\xa0', instanceName ]), @@ -153,7 +153,7 @@ return view.extend({ render: function() { poll.add(L.bind(function () { - return callGetWgInstances().then(L.bind(function(ifaces) { + return callgetAwgInstances().then(L.bind(function(ifaces) { dom.content( document.querySelector('#view'), this.renderIfaces(ifaces) diff --git a/luci-proto-amneziawg/po/ru/amneziawg.po b/luci-proto-amneziawg/po/ru/amneziawg.po new file mode 100644 index 0000000..d6fdeac --- /dev/null +++ b/luci-proto-amneziawg/po/ru/amneziawg.po @@ -0,0 +1,158 @@ +msgid "Imports settings from an existing AmneziaWG configuration file" +msgstr "Импортирует настройки из существующего файла конфигурации AmneziaWG" + +msgid "" +"Drag or paste a valid *.conf file below to configure the local " +"AmneziaWG interface." +msgstr "" +"Перетащите или вставьте правильный файл *.conf ниже, чтобы " +"настроить локальный интерфейс AmneziaWG." + +msgid "" +"Paste or drag a AmneziaWG configuration (commonly wg0.conf) from " +"another system below to create a matching peer entry allowing that system to " +"connect to the local AmneziaWG interface." +msgstr "" +"Вставьте или перетащите конфигурацию AmneziaWG (обычно wg0.conf) из " +"другой системы ниже, чтобы создать соответствующую запись узла, позволяющую " +"этой системе подключиться к локальному интерфейсу AmneziaWG." + +msgid "" +"To configure fully the local AmneziaWG interface from an existing (e.g. " +"provider supplied) configuration file, use the configuration import instead." +msgstr "" +"Чтобы полностью настроить локальный интерфейс AmneziaWG из существующего " +"(например, предоставленного провайдером) файла конфигурации, используйте " +"вместо этого импорт " +"конфигурации." + +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 amnezia.org." +msgstr "" +"Дополнительная информация об AmneziaWG интерфейсах и узлах приведена по " +"адресу amnezia.org." + +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!" \ No newline at end of file diff --git a/luci-proto-amneziawg/po/ru/status.po b/luci-proto-amneziawg/po/ru/status.po new file mode 100644 index 0000000..a7f743f --- /dev/null +++ b/luci-proto-amneziawg/po/ru/status.po @@ -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 не настроены." \ No newline at end of file diff --git a/luci-app-amneziawg/root/usr/share/luci/menu.d/luci-proto-amneziawg.json b/luci-proto-amneziawg/root/usr/share/luci/menu.d/luci-proto-amneziawg.json similarity index 100% rename from luci-app-amneziawg/root/usr/share/luci/menu.d/luci-proto-amneziawg.json rename to luci-proto-amneziawg/root/usr/share/luci/menu.d/luci-proto-amneziawg.json diff --git a/luci-app-amneziawg/root/usr/share/rpcd/acl.d/luci-amneziawg.json b/luci-proto-amneziawg/root/usr/share/rpcd/acl.d/luci-amneziawg.json similarity index 67% rename from luci-app-amneziawg/root/usr/share/rpcd/acl.d/luci-amneziawg.json rename to luci-proto-amneziawg/root/usr/share/rpcd/acl.d/luci-amneziawg.json index 96a22f8..2e7472f 100644 --- a/luci-app-amneziawg/root/usr/share/rpcd/acl.d/luci-amneziawg.json +++ b/luci-proto-amneziawg/root/usr/share/rpcd/acl.d/luci-amneziawg.json @@ -2,15 +2,12 @@ "luci-proto-amneziawg": { "description": "Grant access to LuCI AmneziaWG procedures", "read": { - "file": { - "/usr/bin/qrencode --inline --8bit --type=SVG --output=- -- *": [ "exec" ] - }, "ubus": { "luci.amneziawg": [ - "getWgInstances" + "getAwgInstances" ] }, - "uci": [ "ddns", "system" ] + "uci": [ "ddns", "system", "network" ] }, "write": { "ubus": { diff --git a/luci-app-amneziawg/root/usr/share/rpcd/ucode/luci.amneziawg b/luci-proto-amneziawg/root/usr/share/rpcd/ucode/luci.amneziawg similarity index 65% rename from luci-app-amneziawg/root/usr/share/rpcd/ucode/luci.amneziawg rename to luci-proto-amneziawg/root/usr/share/rpcd/ucode/luci.amneziawg index 53ce368..453510f 100644 --- a/luci-app-amneziawg/root/usr/share/rpcd/ucode/luci.amneziawg +++ b/luci-proto-amneziawg/root/usr/share/rpcd/ucode/luci.amneziawg @@ -15,18 +15,33 @@ function command(cmd) { return trim(popen(cmd)?.read?.('all')); } +function checkPeerHost(configHost, configPort, wgHost) { + const ips = popen(`resolveip ${shellquote(configHost)} 2>/dev/null`); + const hostIp = replace(wgHost, /\[|\]/g, ""); + if (ips) { + for (let line = ips.read('line'); length(line); line = ips.read('line')) { + const ip = rtrim(line, '\n'); + if (configPort && (ip + ":" + configPort == hostIp)) { + return true; + } else if (ip == substr(hostIp, 0, rindex(hostIp, ":"))) { + return true; + } + } + } + return false; +} const methods = { generatePsk: { call: function() { - return { psk: command('amneziawg genpsk 2>/dev/null') }; + return { psk: command('awg genpsk 2>/dev/null') }; } }, generateKeyPair: { call: function() { - const priv = command('amneziawg genkey 2>/dev/null'); - const pub = command(`echo ${shellquote(priv)} | amneziawg pubkey 2>/dev/null`); + const priv = command('awg genkey 2>/dev/null'); + const pub = command(`echo ${shellquote(priv)} | awg pubkey 2>/dev/null`); return { keys: { priv, pub } }; } @@ -36,20 +51,20 @@ const methods = { args: { privkey: "privkey" }, call: function(req) { const priv = req.args?.privkey; - const pub = command(`echo ${shellquote(priv)} | amneziawg pubkey 2>/dev/null`); + const pub = command(`echo ${shellquote(priv)} | awg pubkey 2>/dev/null`); return { keys: { priv, pub } }; } }, - getWgInstances: { + getAwgInstances: { call: function() { const data = {}; let last_device; let qr_pubkey = {}; const uci = cursor(); - const wg_dump = popen("amneziawg show all dump 2>/dev/null"); + const wg_dump = popen("awg show all dump 2>/dev/null"); if (wg_dump) { uci.load("network"); @@ -74,12 +89,17 @@ const methods = { } else { let peer_name; + let peer_name_legacy; uci.foreach('network', `amneziawg_${last_device}`, (s) => { - if (s.public_key == record[1]) + if (!s.disabled && s.public_key == record[1] && (!s.endpoint_host || checkPeerHost(s.endpoint_host, s.endpoint_port, record[3]))) peer_name = s.description; + if (s.public_key == record[1]) + peer_name_legacy = s.description; }); + if (!peer_name) peer_name = peer_name_legacy; + const peer = { name: peer_name, public_key: record[1],