Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .kres.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ spec:
targets:
- amazon-ena
- amdgpu
- amneziawg
- amd-ucode
- binfmt-misc
- bird2
Expand Down
99 changes: 99 additions & 0 deletions network/amneziawg/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# AmneziaWG

Adds [AmneziaWG](https://docs.amnezia.org/documentation/amnezia-wg/) VPN interfaces as system extensions.
AmneziaWG is a WireGuard-based VPN protocol with DPI bypass capabilities through traffic obfuscation (header randomization, packet padding, jitter).

## Installation

See [Installing Extensions](https://github.com/siderolabs/extensions#installing-extensions).

## Usage

Configure the extension via `ExtensionServiceConfig` document.

```yaml
---
apiVersion: v1alpha1
kind: ExtensionServiceConfig
name: amneziawg
configFiles:
- content: |
[Interface]
PrivateKey = <your-private-key>
ListenPort = 51820
Address = 10.0.0.1/24
Jc = 5
Jmin = 50
Jmax = 1000
S1 = 52
S2 = 52
H1 = 12345678
H2 = 87654321
H3 = 11223344
H4 = 44332211

[Peer]
PublicKey = <peer-public-key>
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
mountPath: /etc/amneziawg/awg0.conf
```

Then apply the patch to your node's MachineConfigs
```bash
talosctl patch mc -p @amneziawg-config.yaml
```

You will then be able to verify that it is in place with the following command
```bash
talosctl get extensionserviceconfigs

NODE NAMESPACE TYPE ID VERSION
mynode runtime ExtensionServiceConfig amneziawg 1
```

## Configuration

The config file follows the standard WireGuard format with additional AmneziaWG-specific parameters for DPI obfuscation:

| Parameter | Description |
|-----------|-------------|
| `Jc` | Junk packet count |
| `Jmin` | Minimum junk packet size |
| `Jmax` | Maximum junk packet size |
| `S1` | Init packet padding size |
| `S2` | Response packet padding size |
| `H1` | Init packet header value |
| `H2` | Response packet header value |
| `H3` | Cookie packet header value |
| `H4` | Transport packet header value |

All standard WireGuard fields (`PrivateKey`, `ListenPort`, `Address`, `PublicKey`, `Endpoint`, `AllowedIPs`, `PersistentKeepalive`, `MTU`, `PostUp`, `PostDown`) are also supported.

### Environment overrides

Environment variables can be set via `ExtensionServiceConfig`:

```yaml
---
apiVersion: v1alpha1
kind: ExtensionServiceConfig
name: amneziawg
environment:
- AWG_INTERFACE=awg0
- AWG_CONFIG=/etc/amneziawg/awg0.conf
- AWG_LOG_LEVEL=verbose
configFiles:
- content: |
...
mountPath: /etc/amneziawg/awg0.conf
```

| Variable | Default | Description |
|----------|---------|-------------|
| `AWG_INTERFACE` | `awg0` | Network interface name |
| `AWG_CONFIG` | `/etc/amneziawg/awg0.conf` | Path to config file |
| `AWG_LOG_LEVEL` | `info` | Log level (`info` or `verbose`) |

For more information see https://docs.amnezia.org/documentation/amnezia-wg/
31 changes: 31 additions & 0 deletions network/amneziawg/amneziawg.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: amneziawg
depends:
- network:
- addresses
- connectivity
- configuration: true
container:
entrypoint: /usr/local/bin/entrypoint.sh
environment:
- PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/sbin:/bin
- WG_SOCKET_DIR=/run/amneziawg
- AWG_INTERFACE=awg0
- AWG_CONFIG=/etc/amneziawg/awg0.conf
- AWG_LOG_LEVEL=info
security:
writeableRootfs: false
writeableSysfs: true
mounts:
- source: /dev/net/tun
destination: /dev/net/tun
type: bind
options:
- bind
- rw
- source: /run/amneziawg
destination: /run/amneziawg
type: bind
options:
- bind
- rw
restart: always
114 changes: 114 additions & 0 deletions network/amneziawg/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#!/bin/sh
set -e

AWG_INTERFACE="${AWG_INTERFACE:-awg0}"
AWG_CONFIG="${AWG_CONFIG:-/etc/amneziawg/${AWG_INTERFACE}.conf}"
AWG_LOG_LEVEL="${AWG_LOG_LEVEL:-info}"

export WG_SOCKET_DIR=/run/amneziawg

log() { echo "[amneziawg] $*"; }

if [ ! -f "$AWG_CONFIG" ]; then
log "ERROR: config file not found: $AWG_CONFIG"
log "Provide config via ExtensionServiceConfig:"
log ""
log " apiVersion: v1alpha1"
log " kind: ExtensionServiceConfig"
log " name: amneziawg"
log " configFiles:"
log " - content: |"
log " [Interface]"
log " PrivateKey = <key>"
log " ListenPort = 51820"
log " Address = 10.0.0.1/24"
log " Jc = 5"
log " Jmin = 50"
log " Jmax = 1000"
log " S1 = 0"
log " S2 = 0"
log " H1 = 1"
log " H2 = 2"
log " H3 = 3"
log " H4 = 4"
log " [Peer]"
log " PublicKey = <key>"
log " Endpoint = <host>:51820"
log " AllowedIPs = 0.0.0.0/0"
log " mountPath: /etc/amneziawg/awg0.conf"
exit 1
fi

parse_field() {
grep -i "^${1} *=" "$2" | head -1 | sed "s/^[^ ]* *= *//"
}

collect_field() {
grep -i "^${1} *=" "$2" | sed "s/^[^ ]* *= *//" | tr '\n' ' '
}

ADDRESSES=$(collect_field Address "$AWG_CONFIG")
MTU=$(parse_field MTU "$AWG_CONFIG")

STRIPPED_CONF=$(mktemp)
grep -iv "^\(Address\|DNS\|MTU\|Table\|PreUp\|PostUp\|PreDown\|PostDown\|SaveConfig\) *=" "$AWG_CONFIG" > "$STRIPPED_CONF"

log "Starting amneziawg-go on interface $AWG_INTERFACE"
export LOG_LEVEL="$AWG_LOG_LEVEL"

mkdir -p /run/amneziawg
amneziawg-go "$AWG_INTERFACE" &
AWG_PID=$!

SOCK="/run/amneziawg/${AWG_INTERFACE}.sock"
for i in $(seq 1 50); do
[ -S "$SOCK" ] && break
sleep 0.1
done

if [ ! -S "$SOCK" ]; then
log "ERROR: UAPI socket did not appear at $SOCK"
kill $AWG_PID 2>/dev/null
exit 1
fi

awg setconf "$AWG_INTERFACE" "$STRIPPED_CONF"
rm -f "$STRIPPED_CONF"
log "Configuration applied from $AWG_CONFIG"

for addr in $ADDRESSES; do
ip addr add "$addr" dev "$AWG_INTERFACE" 2>/dev/null || true
log "Address $addr added"
done

if [ -n "$MTU" ]; then
ip link set mtu "$MTU" dev "$AWG_INTERFACE"
log "MTU set to $MTU"
fi

ip link set "$AWG_INTERFACE" up
log "Interface $AWG_INTERFACE is UP"

POST_UP=$(grep -i "^PostUp *=" "$AWG_CONFIG" | sed "s/^[^ ]* *= *//" || true)
if [ -n "$POST_UP" ]; then
log "Running PostUp"
eval "$POST_UP" || true
fi

cleanup() {
log "Shutting down $AWG_INTERFACE"
POST_DOWN=$(grep -i "^PostDown *=" "$AWG_CONFIG" | sed "s/^[^ ]* *= *//" || true)
if [ -n "$POST_DOWN" ]; then
log "Running PostDown"
eval "$POST_DOWN" || true
fi
ip link set "$AWG_INTERFACE" down 2>/dev/null || true
ip link delete "$AWG_INTERFACE" 2>/dev/null || true
kill $AWG_PID 2>/dev/null
}
trap cleanup TERM INT

log "AmneziaWG is running:"
awg show "$AWG_INTERFACE"

wait $AWG_PID
10 changes: 10 additions & 0 deletions network/amneziawg/manifest.yaml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: v1alpha1
metadata:
name: amneziawg
version: "{{ .VERSION }}"
author: masterbpro
description: |
[{{ .TIER }}] AmneziaWG is a WireGuard-based VPN protocol with DPI bypass capabilities through traffic obfuscation.
compatibility:
talos:
version: ">= v1.7.0"
72 changes: 72 additions & 0 deletions network/amneziawg/pkg.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: amneziawg
variant: scratch
shell: /bin/bash
dependencies:
- stage: base
- image: "{{ .BUILD_ARG_PKGS_PREFIX }}/fhs:{{ .BUILD_ARG_PKGS }}"
from: /
to: /rootfs/usr/local/lib/containers/amneziawg
steps:
- env:
GOPATH: /tmp/go
CGO_ENABLED: 0
- cachePaths:
- /.cache/go-build
- /tmp/go/pkg
sources:
- url: https://github.com/amnezia-vpn/amneziawg-go/archive/refs/tags/v{{ .AMNEZIAWG_GO_VERSION }}.tar.gz
destination: amneziawg-go.tar.gz
sha256: {{ .AMNEZIAWG_GO_SHA256 }}
sha512: {{ .AMNEZIAWG_GO_SHA512 }}
- url: https://github.com/amnezia-vpn/amneziawg-tools/archive/refs/tags/v{{ .AMNEZIAWG_TOOLS_VERSION }}.tar.gz
destination: amneziawg-tools.tar.gz
sha256: {{ .AMNEZIAWG_TOOLS_SHA256 }}
sha512: {{ .AMNEZIAWG_TOOLS_SHA512 }}
- network: default
prepare:
- |
mkdir amneziawg-go amneziawg-tools
tar -xzf amneziawg-go.tar.gz --strip-components=1 -C amneziawg-go
tar -xzf amneziawg-tools.tar.gz --strip-components=1 -C amneziawg-tools
- |
cd amneziawg-go
go mod download
- network: none
build:
- |
cd amneziawg-go
CGO_ENABLED=0 go build -v -o ../amneziawg-go-bin .
- |
cd amneziawg-tools/src
make CC="gcc -static" WITH_WGQUICK=yes
install:
- |
mkdir -p /rootfs/usr/local/lib/containers/amneziawg/usr/local/bin/
cp -p amneziawg-go-bin /rootfs/usr/local/lib/containers/amneziawg/usr/local/bin/amneziawg-go
cp -p amneziawg-tools/src/wg /rootfs/usr/local/lib/containers/amneziawg/usr/local/bin/awg
cp -p amneziawg-tools/src/wg-quick/linux.bash /rootfs/usr/local/lib/containers/amneziawg/usr/local/bin/awg-quick
chmod +x /rootfs/usr/local/lib/containers/amneziawg/usr/local/bin/*
- |
cp -p /pkg/entrypoint.sh /rootfs/usr/local/lib/containers/amneziawg/usr/local/bin/entrypoint.sh
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see where the shell is coming from? It should inside the container rootfs for the script to work

chmod +x /rootfs/usr/local/lib/containers/amneziawg/usr/local/bin/entrypoint.sh
- |
mkdir -p /rootfs/usr/local/lib/containers/amneziawg/sbin
cp /sbin/ip /rootfs/usr/local/lib/containers/amneziawg/sbin/ip 2>/dev/null || true
- |
mkdir -p /rootfs/usr/local/etc/containers
cp /pkg/amneziawg.yaml /rootfs/usr/local/etc/containers/
- |
mkdir -p /rootfs/usr/local/bin
cp -p amneziawg-go-bin /rootfs/usr/local/bin/amneziawg-go
cp -p amneziawg-tools/src/wg /rootfs/usr/local/bin/awg
test:
- |
mkdir -p /extensions-validator-rootfs
cp -r /rootfs/ /extensions-validator-rootfs/rootfs
cp /pkg/manifest.yaml /extensions-validator-rootfs/manifest.yaml
/extensions-validator validate --rootfs=/extensions-validator-rootfs --pkg-name="${PKG_NAME}"
finalize:
- from: /rootfs
to: /rootfs
- from: /pkg/manifest.yaml
to: /
2 changes: 2 additions & 0 deletions network/amneziawg/vars.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VERSION: "{{ .AMNEZIAWG_GO_VERSION }}"
TIER: "contrib"
8 changes: 8 additions & 0 deletions network/vars.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# renovate: datasource=github-releases extractVersion=^v(?<version>.*)$ depName=amnezia-vpn/amneziawg-go
AMNEZIAWG_GO_VERSION: 0.2.16
AMNEZIAWG_GO_SHA256: 8327a22c7bcf4f6b05585d4b9536759c1e11fcc1e6830e5186fd55a14255eae1
AMNEZIAWG_GO_SHA512: 40f438307bbdc760c58a0a692c08a64bdbdbd4468ccaf67f687a08f6ef3a3b102b8fe2103da61475074a472758db68c2d6e73786206c6deb355da0ee6dce6409
# renovate: datasource=github-releases extractVersion=^v(?<version>.*)$ depName=amnezia-vpn/amneziawg-tools
AMNEZIAWG_TOOLS_VERSION: 1.0.20260223
AMNEZIAWG_TOOLS_SHA256: ab09cfafe6c1e9a6260964a8ba5cb2d657cc23862eb0c29253305e532ac40a16
AMNEZIAWG_TOOLS_SHA512: 591afaef659e26be16c8d883da8d8ff026f855f60c9887440b566ef18b9948ca57754673d833f27e77d8c05f7e354f37b49adc9f5467334eeb7eda7165960c54
# renovate: datasource=github-releases extractVersion=^v(?<version>.*)$ depName=tailscale/tailscale
TAILSCALE_VERSION: 1.94.2
TAILSCALE_SHA256: c45975beb4cb7bab8047cfba77ec8b170570d184f3c806258844f3e49c60d7aa
Expand Down