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
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MIT License

Copyright (c) 2019-2023 Franck Nijhof
Copyright (c) 2019-2024 Franck Nijhof

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,36 @@
# AmneziaWG

AmneziaWG (AmneziaWireGuard) is a fork of the regular WireGuard-Go with the addition of functions to bypass blocking and reduce the likelihood of protocol detection. One of the key features of AmneziaWG is backward compatibility with WireGuard. This means that when using AmneziaWG, unless the configuration specifies specific parameters for protocol obfuscation, it will act as a standard WireGuard.

What's special?

Before the session starts, the client sends several packets with random data (the number of such packets Jc and their minimum and maximum size in bytes Jmin, Jmax is set in the config)

The header of the handshake packet (Initiator to Responder) and the response packet (Responder to Initiator) have been changed; these values are also set in the config (H1 and H2)

Init handshake packets additionally have garbage at the beginning of the data,
the dimensions are determined by the values of S1 and S2. (by default, the initial handshake packet has a fixed size (148 bytes), after adding garbage, its size will be 148 + the length of random bytes).

The header of data packages and special “Under Load” packages has been changed - H4 and H3, respectively.
More details about the new custom fields:

- `junk_packet_count` Jc (Junk packet count) - the number of packets with random data that are sent before the start of the session
- `junk_packet_min_size` JMin (Junk packet minimum size) - minimum packet size for Junk packet. That is, all randomly generated packets will have a size no less than Jmin
- `junk_packet_max_size` JMax (Junk packet maximum size) - maximum size for Junk packets
- `init_packet_junk_size` S1 (Init packet junk size) - the size of random data that will be added to the init packet, the size of which is initially fixed
- `response_packet_junk_size` S2 (Response packet junk size) - the size of random data that will be added to the response, the size of which is initially fixed
- `init_packet_magic_header` H1 (Init packet magic header) - header of the first byte of the handshake
- `response_packet_magic_header` H2 (Response packet magic header) - header of the first byte of the handshake response
- `transport_packet_magic_header` H3 (Transport packet magic header) - header of the transmitted data packet
- `uload_packet_magic_header` H4 (Underload packet magic header) - UnderLoad packet header

As you can guess, the headings H1, H2, H3, H4 should be different. If you set Jc, S1 and S2 to zero, then there will be no garbage.

> **_NOTE:_**
A regular WG server can work with the AmneziaWG configuration in which Jc, Jmin, Jmax are set, and the remaining fields are zero. Thus, the AWG client will simply send garbage packets before init packets, which has absolutely no effect on the operation of the WG protocol, but may confuse DPI.

---

# Home Assistant Community Add-on: WireGuard

[![GitHub Release][releases-shield]][releases]
Expand Down
2 changes: 1 addition & 1 deletion wireguard/.README.j2 → amnezia-wireguard/.README.j2
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ If you are more interested in stable releases of our add-ons:
[forum]: https://community.home-assistant.io/t/home-assistant-community-add-on-wireguard/134662?u=frenck
[github-sponsors-shield]: https://frenck.dev/wp-content/uploads/2019/12/github_sponsor.png
[github-sponsors]: https://github.com/sponsors/frenck
[maintenance-shield]: https://img.shields.io/maintenance/yes/2023.svg
[maintenance-shield]: https://img.shields.io/maintenance/yes/2024.svg
[patreon-shield]: https://frenck.dev/wp-content/uploads/2019/12/patreon.png
[patreon]: https://www.patreon.com/frenck
[project-stage-shield]: https://img.shields.io/badge/project%20stage-experimental-yellow.svg
Expand Down
52 changes: 52 additions & 0 deletions wireguard/DOCS.md → amnezia-wireguard/DOCS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,55 @@
# AmneziaWG

AmneziaWG (AmneziaWireGuard) is a fork of the regular WireGuard-Go with the addition of functions to bypass blocking and reduce the likelihood of protocol detection. One of the key features of AmneziaWG is backward compatibility with WireGuard. This means that when using AmneziaWG, unless the configuration specifies specific parameters for protocol obfuscation, it will act as a standard WireGuard.

What's special?

Before the session starts, the client sends several packets with random data (the number of such packets Jc and their minimum and maximum size in bytes Jmin, Jmax is set in the config)

The header of the handshake packet (Initiator to Responder) and the response packet (Responder to Initiator) have been changed; these values are also set in the config (H1 and H2)

Init handshake packets additionally have garbage at the beginning of the data,
the dimensions are determined by the values of S1 and S2. (by default, the initial handshake packet has a fixed size (148 bytes), after adding garbage, its size will be 148 + the length of random bytes).

The header of data packages and special “Under Load” packages has been changed - H4 and H3, respectively.
More details about the new custom fields:

- `junk_packet_count` Jc (Junk packet count) - the number of packets with random data that are sent before the start of the session
- `junk_packet_min_size` JMin (Junk packet minimum size) - minimum packet size for Junk packet. That is, all randomly generated packets will have a size no less than Jmin
- `junk_packet_max_size` JMax (Junk packet maximum size) - maximum size for Junk packets
- `init_packet_junk_size` S1 (Init packet junk size) - the size of random data that will be added to the init packet, the size of which is initially fixed
- `response_packet_junk_size` S2 (Response packet junk size) - the size of random data that will be added to the response, the size of which is initially fixed
- `init_packet_magic_header` H1 (Init packet magic header) - header of the first byte of the handshake
- `response_packet_magic_header` H2 (Response packet magic header) - header of the first byte of the handshake response
- `transport_packet_magic_header` H3 (Transport packet magic header) - header of the transmitted data packet
- `uload_packet_magic_header` H4 (Underload packet magic header) - UnderLoad packet header

As you can guess, the headings H1, H2, H3, H4 should be different. If you set Jc, S1 and S2 to zero, then there will be no garbage.

> **_NOTE:_**
A regular WG server can work with the AmneziaWG configuration in which Jc, Jmin, Jmax are set, and the remaining fields are zero. Thus, the AWG client will simply send garbage packets before init packets, which has absolutely no effect on the operation of the WG protocol, but may confuse DPI.

## WireGuard status API

This add-on provides a simple WireGuard status API. This API is not an
official API, darn simple, and experimental, but does allow you to pull
in data from the add-on into Home Assistant.

With the use of the [Home Assistant RESTful][ha-rest] integration, one should
be able to grab some interesting data from this add-on.

Example:

```yaml
sensor:
- platform: rest
resource: http://53948f79_wireguard
```
This addon features `ping_loss` and `ping_avg` attributes. By default, it is set to `-1`
To enable peer ping "average" and "packet loss" metrics, specify the `ping_address` address of the peer.
---


# Home Assistant Community Add-on: WireGuard

[WireGuard®][wireguard] is an extremely simple yet fast and modern VPN that
Expand Down
27 changes: 19 additions & 8 deletions wireguard/Dockerfile → amnezia-wireguard/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
ARG BUILD_FROM=ghcr.io/hassio-addons/base:14.3.1
ARG BUILD_FROM=ghcr.io/hassio-addons/base:16.3.6
# hadolint ignore=DL3006
FROM ${BUILD_FROM}

# Amnezia Wireguart Tools version
ENV AWG_TOOLS=v1.0.20241018
# Amnezia WG GO version
ENV AWG_GO=v0.2.12

# Set shell
SHELL ["/bin/bash", "-o", "pipefail", "-c"]

Expand All @@ -10,19 +15,24 @@ SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN \
apk add --no-cache --virtual .build-dependencies \
build-base=0.5-r3 \
git=2.40.1-r0 \
linux-headers \
git=2.45.2-r0 \
\
&& apk add --no-cache \
go=1.20.10-r0 \
iptables=1.8.9-r2 \
libqrencode=4.1.1-r1 \
go=1.22.10-r0 \
iptables=1.8.10-r3 \
libqrencode-tools=4.1.1-r2 \
openresolv=3.13.2-r0 \
wireguard-tools=1.0.20210914-r3 \
\
&& ln -sf /sbin/xtables-nft-multi /sbin/ip6tables \
&& ln -sf /sbin/xtables-nft-multi /sbin/iptables \
&& git clone --branch "0.0.20230223" --depth=1 \
"https://git.zx2c4.com/wireguard-go" /tmp/wireguard \
&& git clone --depth=1 --branch $AWG_TOOLS \
"https://github.com/amnezia-vpn/amneziawg-tools.git" /tmp/wg-tools \
&& cd /tmp/wg-tools/src \
&& make \
&& make install \
&& git clone --depth=1 --branch $AWG_GO\
"https://github.com/amnezia-vpn/amneziawg-go.git" /tmp/wireguard \
\
&& cd /tmp/wireguard \
&& make \
Expand Down Expand Up @@ -64,3 +74,4 @@ LABEL \
org.opencontainers.image.created=${BUILD_DATE} \
org.opencontainers.image.revision=${BUILD_REF} \
org.opencontainers.image.version=${BUILD_VERSION}

8 changes: 8 additions & 0 deletions amnezia-wireguard/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
build_from:
aarch64: ghcr.io/hassio-addons/base:16.3.6
amd64: ghcr.io/hassio-addons/base:16.3.6
armv7: ghcr.io/hassio-addons/base:16.3.6
codenotary:
base_image: codenotary@frenck.dev
signer: codenotary@frenck.dev
27 changes: 24 additions & 3 deletions wireguard/config.yaml → amnezia-wireguard/config.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
name: WireGuard
name: AmneziaWG
version: dev
slug: wireguard
description: Fast, modern, secure VPN tunnel
url: https://github.com/hassio-addons/addon-wireguard
description: WireGuard-Go fork with protection against DPI systems.
url: https://github.com/yury-sannikov/addon-amnezia-wireguard
codenotary: codenotary@frenck.dev
arch:
- aarch64
Expand All @@ -13,9 +13,11 @@ init: false
ports:
80/tcp: null
51820/udp: 51820
51821/udp: 51821
ports_description:
80/tcp: WireGuard peers status API
51820/udp: "WireGuard: forward this port in your router"
51821/udp: "Auxiliary port for the peer"
hassio_api: true
privileged:
- NET_ADMIN
Expand All @@ -35,6 +37,11 @@ options:
- 172.27.66.2
allowed_ips: []
client_allowed_ips: []
ping_address: 172.27.66.2
amnezia:
junk_packet_count: 3
junk_packet_min_size: 100
junk_packet_max_size: 1000
schema:
log_level: list(trace|debug|info|notice|warning|error|fatal)?
server:
Expand All @@ -53,6 +60,7 @@ schema:
post_up: str?
post_down: str?
mtu: int?
listen_port: int?
peers:
- name: match(^[a-zA-Z0-9\d](?:[a-zA-Z0-9\d]|-(?=[a-zA-Z0-9\d])){0,32}$)
private_key: str?
Expand All @@ -67,3 +75,16 @@ schema:
endpoint: str?
pre_shared_key: str?
fwmark: str?
ping_address: str?
amnezia:
junk_packet_count: int
junk_packet_min_size: int
junk_packet_max_size: int
init_packet_junk_size: int?
response_packet_junk_size: int?
init_packet_magic_header: int?
response_packet_magic_header: int?
transport_packet_magic_header: int?
uload_packet_magic_header: int?


Binary file added amnezia-wireguard/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added amnezia-wireguard/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ declare pre_up
declare server_private_key
declare server_public_key
declare table
declare junk_packet_count
declare junk_packet_min_size
declare junk_packet_max_size
declare init_packet_junk_size
declare response_packet_junk_size
declare init_packet_magic_header
declare response_packet_magic_header
declare transport_packet_magic_header
declare uload_packet_magic_header
declare listen_port

if ! bashio::fs.directory_exists '/ssl/wireguard'; then
mkdir -p /ssl/wireguard ||
Expand All @@ -39,7 +49,7 @@ interface="wg0"
if bashio::config.has_value "server.interface"; then
interface=$(bashio::config "server.interface")
fi
config="/etc/wireguard/${interface}.conf"
config="/etc/amnezia/amneziawg/${interface}.conf"

# Start creation of configuration
echo "[Interface]" > "${config}"
Expand All @@ -55,6 +65,12 @@ for address in $(bashio::config 'server.addresses'); do
echo "Address = ${address}" >> "${config}"
done

# Get listen port
listen_port="51820"
if bashio::config.has_value "server.listen_port"; then
listen_port=$(bashio::config "server.listen_port")
fi

# Add all server DNS addresses to the configuration
if bashio::config.has_value 'server.dns'; then
for dns in $(bashio::config 'server.dns'); do
Expand All @@ -71,7 +87,7 @@ if bashio::config.has_value 'server.private_key'; then
else
if ! bashio::fs.file_exists '/ssl/wireguard/private_key'; then
umask 077 || bashio::exit.nok "Could not set a proper umask"
wg genkey > /ssl/wireguard/private_key ||
awg genkey > /ssl/wireguard/private_key ||
bashio::exit.nok "Could not generate private key!"
fi
server_private_key=$(</ssl/wireguard/private_key)
Expand All @@ -81,7 +97,7 @@ fi
if bashio::config.has_value 'server.public_key'; then
server_public_key=$(bashio::config 'server.public_key')
else
server_public_key=$(wg pubkey <<< "${server_private_key}")
server_public_key=$(awg pubkey <<< "${server_private_key}")
fi

fwmark=$(bashio::config "server.fwmark")
Expand Down Expand Up @@ -133,12 +149,42 @@ if bashio::config.has_value 'server.post_down'; then
fi
fi

# AmneziaWG specific settings
junk_packet_count=$(bashio::config "amnezia.junk_packet_count")
junk_packet_min_size=$(bashio::config "amnezia.junk_packet_min_size")
junk_packet_max_size=$(bashio::config "amnezia.junk_packet_max_size")
init_packet_junk_size=$(bashio::config "amnezia.init_packet_junk_size")
response_packet_junk_size=$(bashio::config "amnezia.response_packet_junk_size")
init_packet_magic_header=$(bashio::config "amnezia.init_packet_magic_header")
response_packet_magic_header=$(bashio::config "amnezia.response_packet_magic_header")
transport_packet_magic_header=$(bashio::config "amnezia.transport_packet_magic_header")
uload_packet_magic_header=$(bashio::config "amnezia.uload_packet_magic_header")

{
bashio::var.has_value "${junk_packet_count}" && echo "Jc = ${junk_packet_count}"
bashio::var.has_value "${junk_packet_min_size}" && echo "Jmin = ${junk_packet_min_size}"
bashio::var.has_value "${junk_packet_max_size}" && echo "Jmax = ${junk_packet_max_size}"
bashio::var.has_value "${init_packet_junk_size}" && [ ! "${init_packet_junk_size}" = "null" ] \
&& echo "S1 = ${init_packet_junk_size}"
bashio::var.has_value "${response_packet_junk_size}" && [ ! "${response_packet_junk_size}" = "null" ] \
&& echo "S2 = ${response_packet_junk_size}"
bashio::var.has_value "${init_packet_magic_header}" && [ ! "${init_packet_magic_header}" = "null" ] \
&& echo "H1 = ${init_packet_magic_header}"
bashio::var.has_value "${response_packet_magic_header}" && [ ! "${response_packet_magic_header}" = "null" ] \
&& echo "H2 = ${response_packet_magic_header}"
bashio::var.has_value "${transport_packet_magic_header}" && [ ! "${transport_packet_magic_header}" = "null" ] \
&& echo "H3 = ${transport_packet_magic_header}"
bashio::var.has_value "${uload_packet_magic_header}" && [ ! "${uload_packet_magic_header}" = "null" ] \
&& echo "H4 = ${uload_packet_magic_header}"
} >> "${config}"


# Finish up the main server configuration
{
echo "PrivateKey = ${server_private_key}"

# Adds server port to the configuration
echo "ListenPort = 51820"
echo "ListenPort = ${listen_port}"

# Custom routing table
bashio::config.has_value "server.table" && echo "Table = ${table}"
Expand Down Expand Up @@ -202,7 +248,7 @@ for peer in $(bashio::config 'peers|keys'); do
# or generate one if needed.
if ! bashio::fs.file_exists "${config_dir}/private_key"; then
umask 077 || bashio::exit.nok "Could not set a proper umask"
wg genkey > "${config_dir}/private_key" ||
awg genkey > "${config_dir}/private_key" ||
bashio::exit.nok "Could not generate private key for ${name}!"
fi
peer_private_key=$(<"${config_dir}/private_key")
Expand All @@ -213,7 +259,7 @@ for peer in $(bashio::config 'peers|keys'); do
if bashio::config.has_value "peers[${peer}].public_key"; then
peer_public_key=$(bashio::config "peers[${peer}].public_key")
elif bashio::var.has_value "${peer_private_key}"; then
peer_public_key=$(wg pubkey <<< "${peer_private_key}")
peer_public_key=$(awg pubkey <<< "${peer_private_key}")
fi

# Get peer addresses
Expand Down
Loading