summaryrefslogtreecommitdiff
path: root/net/amnezia-tools
diff options
context:
space:
mode:
Diffstat (limited to 'net/amnezia-tools')
-rw-r--r--net/amnezia-tools/Makefile41
-rw-r--r--net/amnezia-tools/distinfo3
-rw-r--r--net/amnezia-tools/files/amnezia.in82
-rw-r--r--net/amnezia-tools/files/patch-config.c50
-rw-r--r--net/amnezia-tools/files/patch-containers.h21
-rw-r--r--net/amnezia-tools/files/patch-ipc-freebsd.h27
-rw-r--r--net/amnezia-tools/files/patch-ipc-uapi.h11
-rw-r--r--net/amnezia-tools/files/patch-man_wg-quick.8204
-rw-r--r--net/amnezia-tools/files/patch-man_wg.8158
-rw-r--r--net/amnezia-tools/files/patch-set.c11
-rw-r--r--net/amnezia-tools/files/patch-version.h7
-rw-r--r--net/amnezia-tools/files/patch-wg-quick_freebsd.bash316
-rw-r--r--net/amnezia-tools/pkg-descr2
-rw-r--r--net/amnezia-tools/pkg-plist7
14 files changed, 940 insertions, 0 deletions
diff --git a/net/amnezia-tools/Makefile b/net/amnezia-tools/Makefile
new file mode 100644
index 000000000000..ead229b31481
--- /dev/null
+++ b/net/amnezia-tools/Makefile
@@ -0,0 +1,41 @@
+PORTNAME= amnezia
+DISTVERSIONPREFIX= v
+DISTVERSION= 1.0.20241018
+PORTREVISION= 2
+CATEGORIES= net net-vpn
+PKGNAMESUFFIX= -tools
+
+MAINTAINER= vova@zote.me
+COMMENT= Fast, modern and secure VPN Tunnel with AmneziaVPN anti-detection
+WWW= https://github.com/amnezia-vpn/amneziawg-tools/
+
+LICENSE= GPLv2
+
+RUN_DEPENDS= bash:shells/bash
+
+USES= gmake shebangfix
+USE_GITHUB= yes
+GH_ACCOUNT= amnezia-vpn
+GH_PROJECT= amneziawg-tools
+USE_RC_SUBR= ${PORTNAME}
+
+SHEBANG_FILES= wg-quick/freebsd.bash
+
+MAKE_ARGS+= DEBUG=no WITH_BASHCOMPLETION=yes WITH_SYSTEMDUNITS=no
+MAKE_ENV+= MANDIR="${PREFIX}/share/man" \
+ SYSCONFDIR="${PREFIX}/etc"
+
+WRKSRC_SUBDIR= src
+
+post-patch:
+ @${REINPLACE_CMD} -e 's|wg s|awg s|g; \
+ s|/usr/local/etc/wireguard|${ETCDIR}|' \
+ ${WRKSRC}/completion/wg-quick.bash-completion
+ @${REINPLACE_CMD} -e 's|%%ETCDIR%%|${ETCDIR}|' \
+ ${WRKSRC}/wg-quick/freebsd.bash
+
+post-install:
+ @${RMDIR} ${STAGEDIR}${ETCDIR}/amneziawg
+ ${STRIP_CMD} ${STAGEDIR}${PREFIX}/bin/awg
+
+.include <bsd.port.mk>
diff --git a/net/amnezia-tools/distinfo b/net/amnezia-tools/distinfo
new file mode 100644
index 000000000000..4121ea84aa23
--- /dev/null
+++ b/net/amnezia-tools/distinfo
@@ -0,0 +1,3 @@
+TIMESTAMP = 1754646104
+SHA256 (amnezia-vpn-amneziawg-tools-v1.0.20241018_GH0.tar.gz) = 60f1cec1774fb871a2d8dc24e4f731625516d90f663d6e0d2c77d9247222f2f9
+SIZE (amnezia-vpn-amneziawg-tools-v1.0.20241018_GH0.tar.gz) = 156259
diff --git a/net/amnezia-tools/files/amnezia.in b/net/amnezia-tools/files/amnezia.in
new file mode 100644
index 000000000000..98010c013bdb
--- /dev/null
+++ b/net/amnezia-tools/files/amnezia.in
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+# PROVIDE: amnezia
+# REQUIRE: NETWORKING
+# KEYWORD: shutdown
+#
+# amnezia_enable (bool): Set to "YES" to enable amnezia.
+# (default: "NO")
+#
+# amnezia_interfaces (str): List of interfaces to bring up/down
+# on start/stop. (eg: "amn0 amn1")
+# (default: "")
+# amnezia_env (str): Environment variables for the userspace
+# implementation. (eg: "LOG_LEVEL=debug")
+#
+# amnezia_kmod (str): Kernel module to load.
+# (default: "if_amn", "" - no module)
+#
+# amnezia_confdirs (str): Directory to store the configuration files.
+# (default: "%%ETCDIR%%")
+
+. /etc/rc.subr
+
+name=amnezia
+rcvar=amnezia_enable
+extra_commands="reload status"
+
+start_cmd="${name}_start"
+stop_cmd="${name}_stop"
+reload_cmd="${name}_reload"
+status_cmd="${name}_status"
+
+amnezia_start()
+{
+ kmod=${amnezia_kmod:-if_amn}
+ ${amnezia_env:+eval export $amnezia_env}
+ [ -n "${kmod}" ] && kldstat -q -n ${kmod} || kldload -n ${kmod}
+
+ for interface in ${amnezia_interfaces}; do
+ %%PREFIX%%/bin/awg-quick up ${interface}
+ done
+}
+
+amnezia_stop()
+{
+ for interface in ${amnezia_interfaces}; do
+ %%PREFIX%%/bin/awg-quick down ${interface}
+ done
+}
+
+amnezia_reload()
+{
+ ${amnezia_env:+eval export $amnezia_env}
+
+ for interface in ${amnezia_interfaces}; do
+ %%PREFIX%%/bin/awg-quick reload ${interface}
+ done
+}
+
+amnezia_status()
+{
+ ${amnezia_env:+eval export $amnezia_env}
+ amnezia_status="0"
+
+ for interface in ${amnezia_interfaces}; do
+ %%PREFIX%%/bin/awg show ${interface} || amnezia_status="1"
+ done
+
+ return ${amnezia_status}
+}
+
+load_rc_config $name
+
+: ${amnezia_enable="NO"}
+: ${amnezia_interfaces=""}
+: ${amnezia_env=""}
+: ${amnezia_kmod="if_amn"}
+: ${amnezia_confdirs="%%ETCDIR%%"}
+
+${amnezia_confdirs:+eval export AWG_QUICK_CONFIG_SEARCH_PATHS="$amnezia_confdirs"}
+
+run_rc_command "$1"
diff --git a/net/amnezia-tools/files/patch-config.c b/net/amnezia-tools/files/patch-config.c
new file mode 100644
index 000000000000..4e07d978251a
--- /dev/null
+++ b/net/amnezia-tools/files/patch-config.c
@@ -0,0 +1,50 @@
+--- config.c.orig 2024-10-01 13:02:42 UTC
++++ config.c
+@@ -337,6 +337,20 @@ static bool validate_netmask(struct wgallowedip *allow
+ return true;
+ }
+
++static inline void parse_ip_prefix(struct wgpeer *peer, uint32_t *flags, char **mask)
++{
++ /* If the IP is prefixed with either '+' or '-' consider this an
++ * incremental change. Disable WGPEER_REPLACE_ALLOWEDIPS. */
++ switch ((*mask)[0]) {
++ case '-':
++ *flags |= WGALLOWEDIP_REMOVE_ME;
++ /* fall through */
++ case '+':
++ peer->flags &= ~WGPEER_REPLACE_ALLOWEDIPS;
++ ++(*mask);
++ }
++}
++
+ static inline bool parse_allowedips(struct wgpeer *peer, struct wgallowedip **last_allowedip, const char *value)
+ {
+ struct wgallowedip *allowedip = *last_allowedip, *new_allowedip;
+@@ -353,10 +367,18 @@ static inline bool parse_allowedips(struct wgpeer *pee
+ }
+ sep = mutable;
+ while ((mask = strsep(&sep, ","))) {
++ uint32_t flags = 0;
+ unsigned long cidr;
+ char *end, *ip;
+
++ parse_ip_prefix(peer, &flags, &mask);
++
+ saved_entry = strdup(mask);
++ if (!saved_entry) {
++ perror("strdup");
++ free(mutable);
++ return false;
++ }
+ ip = strsep(&mask, "/");
+
+ new_allowedip = calloc(1, sizeof(*new_allowedip));
+@@ -387,6 +409,7 @@ static inline bool parse_allowedips(struct wgpeer *pee
+ else
+ goto err;
+ new_allowedip->cidr = cidr;
++ new_allowedip->flags = flags;
+
+ if (!validate_netmask(new_allowedip))
+ fprintf(stderr, "Warning: AllowedIP has nonzero host part: %s/%s\n", ip, mask);
diff --git a/net/amnezia-tools/files/patch-containers.h b/net/amnezia-tools/files/patch-containers.h
new file mode 100644
index 000000000000..88563f74058a
--- /dev/null
+++ b/net/amnezia-tools/files/patch-containers.h
@@ -0,0 +1,21 @@
+--- containers.h.orig 2024-10-01 13:02:42 UTC
++++ containers.h
+@@ -29,6 +29,10 @@ struct timespec64 {
+ int64_t tv_nsec;
+ };
+
++enum {
++ WGALLOWEDIP_REMOVE_ME = 1U << 0,
++};
++
+ struct wgallowedip {
+ uint16_t family;
+ union {
+@@ -36,6 +40,7 @@ struct wgallowedip {
+ struct in6_addr ip6;
+ };
+ uint8_t cidr;
++ uint32_t flags;
+ struct wgallowedip *next_allowedip;
+ };
+
diff --git a/net/amnezia-tools/files/patch-ipc-freebsd.h b/net/amnezia-tools/files/patch-ipc-freebsd.h
new file mode 100644
index 000000000000..22255c0bcca3
--- /dev/null
+++ b/net/amnezia-tools/files/patch-ipc-freebsd.h
@@ -0,0 +1,27 @@
+--- ipc-freebsd.h.orig 2024-10-01 13:02:42 UTC
++++ ipc-freebsd.h
+@@ -15,13 +15,13 @@ static int get_dgram_socket(void)
+ {
+ static int sock = -1;
+ if (sock < 0)
+- sock = socket(AF_INET, SOCK_DGRAM, 0);
++ sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
+ return sock;
+ }
+
+ static int kernel_get_wireguard_interfaces(struct string_list *list)
+ {
+- struct ifgroupreq ifgr = { .ifgr_name = "wg" };
++ struct ifgroupreq ifgr = { .ifgr_name = "amn" };
+ struct ifg_req *ifg;
+ int s = get_dgram_socket(), ret = 0;
+
+@@ -389,6 +389,8 @@ static int kernel_set_device(struct wgdevice *dev)
+ nvl_aips[j] = nvlist_create(0);
+ if (!nvl_aips[j])
+ goto err_peer;
++ if (aip->flags)
++ nvlist_add_number(nvl_aips[j], "flags", aip->flags);
+ nvlist_add_number(nvl_aips[j], "cidr", aip->cidr);
+ if (aip->family == AF_INET)
+ nvlist_add_binary(nvl_aips[j], "ipv4", &aip->ip4, sizeof(aip->ip4));
diff --git a/net/amnezia-tools/files/patch-ipc-uapi.h b/net/amnezia-tools/files/patch-ipc-uapi.h
new file mode 100644
index 000000000000..61df9f69e784
--- /dev/null
+++ b/net/amnezia-tools/files/patch-ipc-uapi.h
@@ -0,0 +1,11 @@
+--- ipc-uapi.h.orig 2024-10-01 13:02:42 UTC
++++ ipc-uapi.h
+@@ -111,7 +111,7 @@ static int userspace_set_device(struct wgdevice *dev)
+ continue;
+ } else
+ continue;
+- fprintf(f, "allowed_ip=%s/%d\n", ip, allowedip->cidr);
++ fprintf(f, "allowed_ip=%s%s/%d\n", (allowedip->flags & WGALLOWEDIP_REMOVE_ME) ? "-" : "", ip, allowedip->cidr);
+ }
+ }
+ fprintf(f, "\n");
diff --git a/net/amnezia-tools/files/patch-man_wg-quick.8 b/net/amnezia-tools/files/patch-man_wg-quick.8
new file mode 100644
index 000000000000..96d988cf7162
--- /dev/null
+++ b/net/amnezia-tools/files/patch-man_wg-quick.8
@@ -0,0 +1,204 @@
+--- man/wg-quick.8.orig 2024-10-01 13:02:42 UTC
++++ man/wg-quick.8
+@@ -1,10 +1,10 @@
+-.TH WG-QUICK 8 "2016 January 1" ZX2C4 "WireGuard"
++.TH AWG-QUICK 8 "2025 August 8" AWG "AmneziaWG"
+
+ .SH NAME
+-wg-quick - set up a WireGuard interface simply
++awg-quick - set up a WireGuard interface simply
+
+ .SH SYNOPSIS
+-.B wg-quick
++.B awg-quick
+ [
+ .I up
+ |
+@@ -13,6 +13,8 @@ wg-quick - set up a WireGuard interface simply
+ .I save
+ |
+ .I strip
++|
++.I reload
+ ] [
+ .I CONFIG_FILE
+ |
+@@ -31,9 +33,9 @@ with all
+ runs pre/post down scripts. Running \fIsave\fP saves the configuration of an existing
+ interface without bringing the interface down. Use \fIstrip\fP to output a configuration file
+ with all
+-.BR wg-quick (8)-specific
++.BR awg-quick (8)-specific
+ options removed, suitable for use with
+-.BR wg (8).
++.BR awg (8).
+
+ \fICONFIG_FILE\fP is a configuration file, whose filename is the interface name
+ followed by `.conf'. Otherwise, \fIINTERFACE\fP is an interface name, with configuration
+@@ -41,24 +43,24 @@ Generally speaking, this utility is just a simple scri
+ search paths.
+
+ Generally speaking, this utility is just a simple script that wraps invocations to
+-.BR wg (8)
++.BR awg (8)
+ and
+-.BR ip (8)
+-in order to set up a WireGuard interface. It is designed for users with simple
++.BR ifconfig (8)
++in order to set up a AmneziaWG interface. It is designed for users with simple
+ needs, and users with more advanced needs are highly encouraged to use a more
+ specific tool, a more complete network manager, or otherwise just use
+-.BR wg (8)
++.BR awg (8)
+ and
+-.BR ip (8),
++.BR route (8),
+ as usual.
+
+ .SH CONFIGURATION
+
+ The configuration file adds a few extra configuration values to the format understood by
+-.BR wg (8)
++.BR awg (8)
+ in order to configure additional attributes of an interface. It handles the
+ values that it understands, and then it passes the remaining ones directly to
+-.BR wg (8)
++.BR awg (8)
+ for further processing.
+
+ It infers all routes from the list of peers' allowed IPs, and automatically adds
+@@ -67,7 +69,7 @@ to handle overriding of the default gateway.
+ .BR ip-rule (8)
+ to handle overriding of the default gateway.
+
+-The configuration file will be passed directly to \fBwg\fP(8)'s `setconf'
++The configuration file will be passed directly to \fBawg\fP(8)'s `setconf'
+ sub-command, with the exception of the following additions to the \fIInterface\fP section,
+ which are handled by this tool:
+
+@@ -102,9 +104,29 @@ interface is removed will therefore be overwritten.
+ SaveConfig \(em if set to `true', the configuration is saved from the current state of the
+ interface upon shutdown. Any changes made to the configuration file before the
+ interface is removed will therefore be overwritten.
++.IP \(bu
++Description \(em will setup interface description visible in ifconfig and SNMP.
++.IP \(bu
++UserLand \(em enforce to use amnezia-go instead of kernel driver, you can use
++\fBamnezia-wireguard-go\fP to install it.
++.IP \(bu
++Routes \(em list of routes for the peer to be installed into FIB - that option provides a way to have AllowedIPs list wider then routes installed. Empty list is allowed.
++That is useful if routing protocol will work over the link.
++But remember that internal wireguard routing will happen according to AllowedIPs anyway.
++Suggested use in case dynamic route - one interface -> one link.
++.IP \(bu
++Monitor default route change \(em do not run `route monitor` when there is no need to do anything on default
++change. That will help to avoid keeping two bashes and one route binaries
++per interface always.
++Default value is true.
++.IP \(bu
++Track DNS Changes \(em if peer endpoint defined as a hostname - periodically (timeout in seconds)
++check if hostname was changed, and if changed update peer endpoint according
++to new hostname. Quite useful in case of DDNS configurations.
++Default values is 0, disabled.
+
+ .P
+-Recommended \fIINTERFACE\fP names include `wg0' or `wgvpn0' or even `wgmgmtlan0'.
++Recommended \fIINTERFACE\fP names include `amn0' or `awg0'.
+ However, the number at the end is in fact optional, and really
+ any free-form string [a-zA-Z0-9_=+.-]{1,15} will work. So even interface names corresponding
+ to geographic locations would suffice, such as `cincinnati', `nyc', or `paris', if that's
+@@ -113,9 +135,9 @@ These examples draw on the same syntax found for
+ .SH EXAMPLES
+
+ These examples draw on the same syntax found for
+-.BR wg (8),
++.BR awg (8),
+ and a more complete description may be found there. Bold lines below are for options that extend
+-.BR wg (8).
++.BR awg (8).
+
+ The following might be used for connecting as a client to a VPN gateway for tunneling all
+ traffic:
+@@ -151,15 +173,15 @@ two lines `PostUp` and `PreDown` lines to the `[Interf
+ to prevent the flow of unencrypted packets through the non-WireGuard interfaces, by adding the following
+ two lines `PostUp` and `PreDown` lines to the `[Interface]` section:
+
+- \fBPostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT\fP
++ \fBPostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(awg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT\fP
+ .br
+- \fBPreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT\fP
++ \fBPreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(awg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT\fP
+ .br
+
+ The `PostUp' and `PreDown' fields have been added to specify an
+ .BR iptables (8)
+ command which, when used with interfaces that have a peer that specifies 0.0.0.0/0 as part of the
+-`AllowedIPs', works together with wg-quick's fwmark usage in order to drop all packets that
++`AllowedIPs', works together with awg-quick's fwmark usage in order to drop all packets that
+ are either not coming out of the tunnel encrypted or not going through the tunnel itself. (Note
+ that this continues to allow most DHCP traffic through, since most DHCP clients make use of PF_PACKET
+ sockets, which bypass Netfilter.) When IPv6 is in use, additional similar lines could be added using
+@@ -168,7 +190,7 @@ Or, perhaps it is desirable to store private keys in e
+ Or, perhaps it is desirable to store private keys in encrypted form, such as through use of
+ .BR pass (1):
+
+- \fBPreUp = wg set %i private-key <(pass WireGuard/private-keys/%i)\fP
++ \fBPreUp = awg set %i private-key <(pass WireGuard/private-keys/%i)\fP
+ .br
+
+ For use on a server, the following is a more complicated example involving multiple peers:
+@@ -242,36 +264,43 @@ in the filename:
+ These configuration files may be placed in any directory, putting the desired interface name
+ in the filename:
+
+-\fB # wg-quick up /path/to/wgnet0.conf\fP
++\fB # awg-quick up amn0\fP
+
++or
++
++\fB # awg-quick up /path/to/amn0.conf\fP
++
+ For convenience, if only an interface name is supplied, it automatically chooses a path in
+ `/etc/wireguard/':
+
+-\fB # wg-quick up wgnet0\fP
++\fB # awg-quick up amn0\fP
+
+ This will load the configuration file `/etc/wireguard/wgnet0.conf'.
+
+ The \fIstrip\fP command is useful for reloading configuration files without disrupting active
+ sessions:
+
+-\fB # wg syncconf wgnet0 <(wg-quick strip wgnet0)\fP
++\fB # awg syncconf amn0 <(awg-quick strip amn)\fP
+
++or
++
++\fB # awg-quick reload amn0\fP
++
++
+ .SH SEE ALSO
+-.BR wg (8),
+-.BR ip (8),
+-.BR ip-link (8),
+-.BR ip-address (8),
+-.BR ip-route (8),
+-.BR ip-rule (8),
+-.BR resolvconf (8).
++.BR awg (8),
++.BR ifconfig (8),
++.BR route (8),
+
+ .SH AUTHOR
++.B awg-quick
++based on
+ .B wg-quick
+ was written by
+ .MT Jason@zx2c4.com
+ Jason A. Donenfeld
+ .ME .
+ For updates and more information, a project page is available on the
+-.UR https://\:www.wireguard.com/
++.UR https://\:github.com/amnezia-vpn/amneziawg-tools/
+ World Wide Web
+ .UE .
diff --git a/net/amnezia-tools/files/patch-man_wg.8 b/net/amnezia-tools/files/patch-man_wg.8
new file mode 100644
index 000000000000..87e018ff2856
--- /dev/null
+++ b/net/amnezia-tools/files/patch-man_wg.8
@@ -0,0 +1,158 @@
+--- man/wg.8.orig 2024-10-01 13:02:42 UTC
++++ man/wg.8
+@@ -1,10 +1,10 @@
+-.TH WG 8 "2015 August 13" ZX2C4 "WireGuard"
++.TH AWG 8 "2025 August 8" AWG "AmneziaWG"
+
+ .SH NAME
+-wg - set and retrieve configuration of WireGuard interfaces
++awg - set and retrieve configuration of WireGuard interfaces
+
+ .SH SYNOPSIS
+-.B wg
++.B awg
+ [
+ .I COMMAND
+ ] [
+@@ -15,17 +15,15 @@ wg - set and retrieve configuration of WireGuard inter
+
+ .SH DESCRIPTION
+
+-.B wg
++.B awg
+ is the configuration utility for getting and setting the configuration of
+ WireGuard tunnel interfaces. The interfaces themselves can be added and removed
+ using
+-.BR ip-link (8)
++.BR ifconfig (8)
+ and their IP addresses and routing tables can be set using
+-.BR ip-address (8)
+-and
+-.BR ip-route (8).
++.BR route (8).
+ The
+-.B wg
++.B awg
+ utility provides a series of sub-commands for changing WireGuard-specific
+ aspects of WireGuard interfaces.
+
+@@ -36,7 +34,7 @@ Sub-commands that take an INTERFACE must be passed a W
+ .SH COMMANDS
+
+ .TP
+-\fBshow\fP { \fI<interface>\fP | \fIall\fP | \fIinterfaces\fP } [\fIpublic-key\fP | \fIprivate-key\fP | \fIlisten-port\fP | \fIfwmark\fP | \fIpeers\fP | \fIpreshared-keys\fP | \fIendpoints\fP | \fIallowed-ips\fP | \fIlatest-handshakes\fP | \fIpersistent-keepalive\fP | \fItransfer\fP | \fIdump\fP]
++\fBshow\fP { \fI<interface>\fP | \fIall\fP | \fIinterfaces\fP } [\fIpublic-key\fP | \fIprivate-key\fP | \fIlisten-port\fP | \fIfwmark\fP | \fIpeers\fP | \fIpreshared-keys\fP | \fIendpoints\fP | \fIallowed-ips\fP | \fIlatest-handshakes\fP | \fIpersistent-keepalive\fP | \fItransfer\fP | \fIdump\fP | \fIjc\fP | \fIjmin\fP | \fIjmax\fP | \fIs1\fP | \fIs2\fP | \fIh1\fP | \fIh2\fP | \fIh3\fP | \fIh4\fP]
+ Shows current WireGuard configuration and runtime information of specified \fI<interface>\fP.
+ If no \fI<interface>\fP is specified, \fI<interface>\fP defaults to \fIall\fP.
+ If \fIinterfaces\fP is specified, prints a list of all WireGuard interfaces,
+@@ -55,7 +53,7 @@ by \fICONFIGURATION FILE FORMAT\fP below.
+ Shows the current configuration of \fI<interface>\fP in the format described
+ by \fICONFIGURATION FILE FORMAT\fP below.
+ .TP
+-\fBset\fP \fI<interface>\fP [\fIlisten-port\fP \fI<port>\fP] [\fIfwmark\fP \fI<fwmark>\fP] [\fIprivate-key\fP \fI<file-path>\fP] [\fIpeer\fP \fI<base64-public-key>\fP [\fIremove\fP] [\fIpreshared-key\fP \fI<file-path>\fP] [\fIendpoint\fP \fI<ip>:<port>\fP] [\fIpersistent-keepalive\fP \fI<interval seconds>\fP] [\fIallowed-ips\fP \fI<ip1>/<cidr1>\fP[,\fI<ip2>/<cidr2>\fP]...] ]...
++\fBset\fP \fI<interface>\fP [\fIlisten-port\fP \fI<port>\fP] [\fIfwmark\fP \fI<fwmark>\fP] [\fIprivate-key\fP \fI<file-path>\fP] [\fIjc <jc>]\fP [\fI<jmin <jmin>]\fP [\fIjmax <jmax>\fP] [\fIs1 <s1>\fP] [\fIs2 <s2>\fP] [\fIh1\fP] [\fIh2 <h2>\fP] [\fIh3 <h3>\fP] [\fIh4 <h4>\fP] [\fIpeer\fP \fI<base64-public-key>\fP [\fIremove\fP] [\fIpreshared-key\fP \fI<file-path>\fP] [\fIendpoint\fP \fI<ip>:<port>\fP] [\fIpersistent-keepalive\fP \fI<interval seconds>\fP] [\fIallowed-ips\fP \fI[+|-]<ip1>/<cidr1>\fP[,\fI[+|-]<ip2>/<cidr2>\fP]...] ]...
+ Sets configuration values for the specified \fI<interface>\fP. Multiple
+ \fIpeer\fPs may be specified, and if the \fIremove\fP argument is given
+ for a peer, that peer is removed, not configured. If \fIlisten-port\fP
+@@ -72,7 +70,11 @@ If \fIallowed-ips\fP is specified, but the value is th
+ it adds an additional layer of symmetric-key cryptography to be mixed into
+ the already existing public-key cryptography, for post-quantum resistance.
+ If \fIallowed-ips\fP is specified, but the value is the empty string, all
+-allowed ips are removed from the peer. The use of \fIpersistent-keepalive\fP
++allowed ips are removed from the peer. By default, \fIallowed-ips\fP replaces
++a peer's allowed ips. If + or - is prepended to any of the ips then
++the update is incremental; ips prefixed with '+' or '' are added to the peer's
++allowed ips if not present while ips prefixed with '-' are removed if present.
++The use of \fIpersistent-keepalive\fP
+ is optional and is by default off; setting it to 0 or "off" disables it.
+ Otherwise it represents, in seconds, between 1 and 65535 inclusive, how often
+ to send an authenticated empty packet to the peer, for the purpose of keeping
+@@ -119,11 +121,52 @@ A private key and a corresponding public key may be ge
+ .br
+ $ umask 077
+ .br
+- $ wg genkey | tee private.key | wg pubkey > public.key
++ $ awg genkey | tee private.key | awg pubkey > public.key
+ .TP
+ \fBhelp\fP
+ Shows usage message.
+
++.SH AMNEZIA OPTIONS
++Configuration options to be use in order to bypass DPI filters, these options appears in
++\fBshow\fP, \fBset\fP, \fBsetconf\fP, \fBaddconf\fP commands.
++
++.TP
++\fBjc\fP
++Number of junk packets before handshake.
++.br
++1–128 (recomended 3–10)
++
++.TP
++\fBjmin\fP
++Minimum size of junk packets.
++.br
++jmin: < jmax (recomended ~ 8)
++
++.TP
++\fBjmax\fP
++Maximum size of junk packets.
++.br
++jmax: ≤ 1280 (recomended ~ 80)
++
++.TP
++\fBs1\fP
++Size of handshake initiation packet prepend junk. Should be the same on both ends.
++.br
++0–1132 (recomended 15–150), s1 + 56 ≠ s2
++
++.TP
++\fBs2\fP
++Size of handshake response packet prepend junk. Should be the same on both ends.
++.br
++0–1188 (recomended 15–150), s1 + 56 ≠ s2
++
++.TP
++\fBh1-h4\fP
++Custom identifiers for initiation/response/cookie/data packets. Should be the same on both ends.
++.br
++The unique value in range of 5 - 4,294,967,295 (0x5 - 0xFFFFFFFF), h1 != h2 != h3 != h4
++
++
+ .SH CONFIGURATION FILE FORMAT
+ The configuration file format is based on \fIINI\fP. There are two top level sections
+ -- \fIInterface\fP and \fIPeer\fP. Multiple \fIPeer\fP sections may be specified, but
+@@ -224,7 +267,7 @@ on a per-interface basis by using
+ on a per-interface basis by using
+ .BR ifconfig (1):
+
+-\fB # ifconfig wg0 debug
++\fB # ifconfig amn0 debug\fP
+
+ On userspace implementations, it is customary to set the \fILOG_LEVEL\fP environment variable to \fIverbose\fP.
+
+@@ -240,19 +283,18 @@ If set to an integer or to \fIinfinity\fP, DNS resolut
+ If set to an integer or to \fIinfinity\fP, DNS resolution for each peer's endpoint will be retried that many times for non-permanent errors, with an increasing delay between retries. If unset, the default is 15 retries.
+
+ .SH SEE ALSO
+-.BR wg-quick (8),
+-.BR ip (8),
+-.BR ip-link (8),
+-.BR ip-address (8),
+-.BR ip-route (8).
++.BR awg-quick (8),
++.BR ifconfig (8),
++.BR route (8).
+
+ .SH AUTHOR
++awg based on
+ .B wg
+-was written by
++that was written by
+ .MT Jason@zx2c4.com
+ Jason A. Donenfeld
+ .ME .
+ For updates and more information, a project page is available on the
+-.UR https://\:www.wireguard.com/
++.UR https://\:github.com/amnezia-vpn/amneziawg-tools/
+ World Wide Web
+ .UE .
diff --git a/net/amnezia-tools/files/patch-set.c b/net/amnezia-tools/files/patch-set.c
new file mode 100644
index 000000000000..61e1ec5314d0
--- /dev/null
+++ b/net/amnezia-tools/files/patch-set.c
@@ -0,0 +1,11 @@
+--- set.c.orig 2024-10-01 13:02:42 UTC
++++ set.c
+@@ -18,7 +18,7 @@ int set_main(int argc, const char *argv[])
+ int ret = 1;
+
+ if (argc < 3) {
+- fprintf(stderr, "Usage: %s %s <interface> [listen-port <port>] [fwmark <mark>] [private-key <file path>] [peer <base64 public key> [remove] [preshared-key <file path>] [endpoint <ip>:<port>] [persistent-keepalive <interval seconds>] [allowed-ips <ip1>/<cidr1>[,<ip2>/<cidr2>] [advanced-security <on|off>]...] ]...\n", PROG_NAME, argv[0]);
++ fprintf(stderr, "Usage: %s %s <interface> [listen-port <port>] [fwmark <mark>] [private-key <file path>] [peer <base64 public key> [remove] [preshared-key <file path>] [endpoint <ip>:<port>] [persistent-keepalive <interval seconds>] [allowed-ips [+|-]<ip1>/<cidr1>[,[+|-]<ip2>/<cidr2>] [advanced-security <on|off>]...] ]...\n", PROG_NAME, argv[0]);
+ return 1;
+ }
+
diff --git a/net/amnezia-tools/files/patch-version.h b/net/amnezia-tools/files/patch-version.h
new file mode 100644
index 000000000000..02ae2a096e8a
--- /dev/null
+++ b/net/amnezia-tools/files/patch-version.h
@@ -0,0 +1,7 @@
+--- version.h.orig 2024-10-01 13:02:42 UTC
++++ version.h
+@@ -1,3 +1,3 @@
+ #ifndef WIREGUARD_TOOLS_VERSION
+-#define WIREGUARD_TOOLS_VERSION "1.0.20210914"
++#define WIREGUARD_TOOLS_VERSION "1.0.20250521"
+ #endif
diff --git a/net/amnezia-tools/files/patch-wg-quick_freebsd.bash b/net/amnezia-tools/files/patch-wg-quick_freebsd.bash
new file mode 100644
index 000000000000..6d218f256182
--- /dev/null
+++ b/net/amnezia-tools/files/patch-wg-quick_freebsd.bash
@@ -0,0 +1,316 @@
+--- wg-quick/freebsd.bash.orig 2024-10-01 13:02:42 UTC
++++ wg-quick/freebsd.bash
+@@ -25,11 +25,20 @@ CONFIG_FILE=""
+ POST_DOWN=( )
+ SAVE_CONFIG=0
+ CONFIG_FILE=""
++DESCRIPTION=""
++USERLAND=0
++MONITOR=1
++TRACK_DNS_CHANGES=0
+ PROGRAM="${0##*/}"
+ ARGS=( "$@" )
+
+ IS_ASESCURITY_ON=0
+
++
++declare -A ROUTES
++declare -A ENDPOINTS
++
++
+ cmd() {
+ echo "[#] $*" >&3
+ "$@"
+@@ -40,7 +49,7 @@ die() {
+ exit 1
+ }
+
+-CONFIG_SEARCH_PATHS=( /etc/amnezia/amneziawg /usr/local/etc/amnezia/amneziawg )
++CONFIG_SEARCH_PATHS=( ${AWG_QUICK_CONFIG_SEARCH_PATHS:-%%ETCDIR%%} )
+
+ unset ORIGINAL_TMPDIR
+ make_temp() {
+@@ -64,7 +73,7 @@ parse_options() {
+ }
+
+ parse_options() {
+- local interface_section=0 line key value stripped path v
++ local interface_section=0 line key value stripped path v last_public_key
+ CONFIG_FILE="$1"
+ if [[ $CONFIG_FILE =~ ^[a-zA-Z0-9_=+.-]{1,15}$ ]]; then
+ for path in "${CONFIG_SEARCH_PATHS[@]}"; do
+@@ -82,7 +91,7 @@ parse_options() {
+ stripped="${line%%\#*}"
+ key="${stripped%%=*}"; key="${key##*([[:space:]])}"; key="${key%%*([[:space:]])}"
+ value="${stripped#*=}"; value="${value##*([[:space:]])}"; value="${value%%*([[:space:]])}"
+- [[ $key == "["* ]] && interface_section=0
++ [[ $key == "["* ]] && interface_section=0 && last_public_key=""
+ [[ $key == "[Interface]" ]] && interface_section=1
+ if [[ $interface_section -eq 1 ]]; then
+ case "$key" in
+@@ -96,9 +105,14 @@ parse_options() {
+ PreDown) PRE_DOWN+=( "$value" ); continue ;;
+ PostUp) POST_UP+=( "$value" ); continue ;;
+ PostDown) POST_DOWN+=( "$value" ); continue ;;
++ Description) DESCRIPTION="$value"; continue ;;
+ SaveConfig) read_bool SAVE_CONFIG "$value"; continue ;;
++ UserLand) read_bool USERLAND "$value"; continue ;;
++ Monitor) read_bool MONITOR "$value"; continue ;;
++ TrackDNSChanges) TRACK_DNS_CHANGES="$value"; continue ;;
+ esac
+ case "$key" in
++
+ Jc);&
+ Jmin);&
+ Jmax);&
+@@ -109,6 +123,17 @@ parse_options() {
+ H3);&
+ H4) IS_ASESCURITY_ON=1;;
+ esac
++ else
++ case "$key" in
++ PublicKey) last_public_key="$value" ;;
++ Routes) ROUTES["$last_public_key"]="$value"; continue ;;
++ Endpoint)
++ endpoint_host="${value%%:*}"
++ if ! [[ "$endpoint_host" =~ ^[0-9]+ ]]; then
++ ENDPOINTS["$last_public_key"]="$endpoint_host"
++ fi
++ ;;
++ esac
+ fi
+ WG_CONFIG+="$line"$'\n'
+ done < "$CONFIG_FILE"
+@@ -129,12 +154,15 @@ add_if() {
+
+ add_if() {
+ local ret rc
+- local cmd="ifconfig wg create name "$INTERFACE""
+- if [[ $IS_ASESCURITY_ON == 1 ]]; then
++ local cmd="ifconfig amn create name "$INTERFACE""
++ if [[ $USERLAND == 1 ]]; then
+ cmd="amneziawg-go "$INTERFACE"";
+ fi
+- if ret="$(cmd $cmd 2>&1 >/dev/null)"; then
+- return 0
++ if [ -n "$DESCRIPTION" ]; then
++ ret="$(cmd $cmd description "$DESCRIPTION" 2>&1 >/dev/null)" && return 0
++ else
++
++ ret="$(cmd $cmd 2>&1 >/dev/null)" && return 0
+ fi
+ rc=$?
+ if [[ $ret == *"ifconfig: ioctl SIOCSIFNAME (set name): File exists"* ]]; then
+@@ -209,7 +237,7 @@ set_mtu() {
+ [[ ${BASH_REMATCH[1]} == *:* ]] && family=inet6
+ output="$(route -n get "-$family" "${BASH_REMATCH[1]}" || true)"
+ [[ $output =~ interface:\ ([^ ]+)$'\n' && $(ifconfig "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) && ${BASH_REMATCH[1]} -gt $mtu ]] && mtu="${BASH_REMATCH[1]}"
+- done < <(wg show "$INTERFACE" endpoints)
++ done < <(awg show "$INTERFACE" endpoints)
+ if [[ $mtu -eq 0 ]]; then
+ read -r output < <(route -n get default || true) || true
+ [[ $output =~ interface:\ ([^ ]+)$'\n' && $(ifconfig "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) && ${BASH_REMATCH[1]} -gt $mtu ]] && mtu="${BASH_REMATCH[1]}"
+@@ -242,7 +270,7 @@ collect_endpoints() {
+ while read -r _ endpoint; do
+ [[ $endpoint =~ ^\[?([a-z0-9:.]+)\]?:[0-9]+$ ]] || continue
+ ENDPOINTS+=( "${BASH_REMATCH[1]}" )
+- done < <(wg show "$INTERFACE" endpoints)
++ done < <(awg show "$INTERFACE" endpoints)
+ }
+
+ set_endpoint_direct_route() {
+@@ -297,18 +325,18 @@ monitor_daemon() {
+ }
+
+ monitor_daemon() {
++ [[ $MONITOR -eq 0 ]] && return 0
+ echo "[+] Backgrounding route monitor" >&2
+ (make_temp
+ trap 'del_routes; clean_temp; exit 0' INT TERM EXIT
+ exec >/dev/null 2>&1
+- exec 19< <(exec route -n monitor)
++ exec 19< <(exec stdbuf -oL route -n monitor)
+ local event pid=$!
+ # TODO: this should also check to see if the endpoint actually changes
+ # in response to incoming packets, and then call set_endpoint_direct_route
+ # then too. That function should be able to gracefully cleanup if the
+ # endpoints change.
+ while read -u 19 -r event; do
+- [[ $event == RTM_* ]] || continue
+ ifconfig "$INTERFACE" >/dev/null 2>&1 || break
+ [[ $AUTO_ROUTE4 -eq 1 || $AUTO_ROUTE6 -eq 1 ]] && set_endpoint_direct_route
+ # TODO: set the mtu as well, but only if up
+@@ -316,6 +344,77 @@ monitor_daemon() {
+ kill $pid) & disown
+ }
+
++wg_endpoints() {
++ awk '
++ BEGIN { RS=""; FS="\n" }
++ /Peer/ {
++ pk=""; ep=""
++ for (i = 1; i <= NF; i++) {
++ if ($i ~ /^PublicKey[ \t]*=/) {
++ pk = $i
++ sub(/^PublicKey[ \t]*=[ \t]*/, "", pk)
++ }
++ if ($i ~ /^Endpoint[ \t]*=/) {
++ ep = $i
++ sub(/^Endpoint[ \t]*=[ \t]*/, "", ep)
++ split(ep, parts, ":")
++ host = parts[1]
++ port = parts[2]
++ }
++ }
++ if (pk != "" && host != "" && port != "") {
++ print pk, host, port
++ }
++ }
++ '
++}
++
++tracker_pid_file() {
++ echo "/var/run/awg-quick.dns-tracker.${INTERFACE}.pid"
++}
++
++monitor_dns_changes() {
++ local pk peer_ip port peer_host host_ip
++ [[ $TRACK_DNS_CHANGES -eq 0 ]] && return 0
++
++ echo "[+] Backgrounding DNS tracker" >&2
++ exec >/dev/null 2>&1
++
++ pid_file="$(tracker_pid_file)"
++ [[ -f "$pid_file" ]] && kill $(cat "$pid_file") 2>/dev/null || true
++
++ (
++ trap 'rm -f "$pid_file"; exit 0' INT TERM EXIT
++
++ set -e
++ while true; do
++ sleep $TRACK_DNS_CHANGES &
++ wait $!
++
++ $cmd awg showconf "$INTERFACE" 2> /dev/null | wg_endpoints | \
++ while read -r pk peer_ip port; do
++ peer_host="${ENDPOINTS[$pk]}"
++ if [[ -n "$peer_host" ]]; then
++ host_ip=$(host "$peer_host" 2>/dev/null | awk '/has address/ { print $4; exit; }') || continue
++
++ if [[ "$host_ip" = "$peer_ip" ]]; then
++ #echo "$pk matches ${peer_ip} <=> ${host_ip}"
++ :
++ else
++ logger -t awg-quick -p local0.notice \
++ "$INTERFACE/$pk host $peer_host:" \
++ "IP missmatch: $host_ip != $peer_ip, configuring endpoint" || true
++ $cmd awg set "$INTERFACE" peer "$pk" endpoint "$peer_host:$port" || true
++ fi
++ fi
++ done
++
++ done
++ ) & disown
++ echo "$!" > "$pid_file"
++}
++
++
+ HAVE_SET_DNS=0
+ set_dns() {
+ [[ ${#DNS[@]} -gt 0 ]] || return 0
+@@ -354,7 +453,7 @@ set_config() {
+ }
+
+ set_config() {
+- echo "$WG_CONFIG" | cmd wg setconf "$INTERFACE" /dev/stdin
++ echo "$WG_CONFIG" | cmd awg setconf "$INTERFACE" /dev/stdin
+ }
+
+ save_config() {
+@@ -386,7 +485,7 @@ save_config() {
+ done
+ old_umask="$(umask)"
+ umask 077
+- current_config="$(cmd wg showconf "$INTERFACE")"
++ current_config="$(cmd awg showconf "$INTERFACE")"
+ trap 'rm -f "$CONFIG_FILE.tmp"; clean_temp; exit' INT TERM EXIT
+ echo "${current_config/\[Interface\]$'\n'/$new_config}" > "$CONFIG_FILE.tmp" || die "Could not write configuration file"
+ sync "$CONFIG_FILE.tmp"
+@@ -433,6 +532,20 @@ cmd_usage() {
+ _EOF
+ }
+
++get_routes() {
++ while read -r pub_key i; do
++ if [[ -v "ROUTES[$pub_key]" ]]; then
++ for route in ${ROUTES[$pub_key]//,/ }; do
++ echo "$route"
++ done
++ else
++ for j in $i; do
++ [[ $j =~ ^[0-9a-z:.]+/[0-9]+$ ]] && echo "$j"
++ done
++ fi
++ done < <(awg show "$INTERFACE" allowed-ips) | sort -nr -k 2 -t /
++}
++
+ cmd_up() {
+ local i
+ [[ -z $(ifconfig "$INTERFACE" 2>/dev/null) ]] || die "\`$INTERFACE' already exists"
+@@ -446,26 +559,31 @@ cmd_up() {
+ set_mtu
+ up_if
+ set_dns
+- for i in $(while read -r _ i; do for i in $i; do [[ $i =~ ^[0-9a-z:.]+/[0-9]+$ ]] && echo "$i"; done; done < <(wg show "$INTERFACE" allowed-ips) | sort -nr -k 2 -t /); do
++ for i in $(get_routes); do
+ add_route "$i"
+ done
+ [[ $AUTO_ROUTE4 -eq 1 || $AUTO_ROUTE6 -eq 1 ]] && set_endpoint_direct_route
+ monitor_daemon
++ monitor_dns_changes
+ execute_hooks "${POST_UP[@]}"
+ trap 'clean_temp; exit' INT TERM EXIT
+ }
+
+ cmd_down() {
+- [[ " $(wg show interfaces) " == *" $INTERFACE "* ]] || die "\`$INTERFACE' is not a WireGuard interface"
++ [[ " $(awg show interfaces) " == *" $INTERFACE "* ]] || die "\`$INTERFACE' is not a WireGuard interface"
+ execute_hooks "${PRE_DOWN[@]}"
+ [[ $SAVE_CONFIG -eq 0 ]] || save_config
+ del_if
+ unset_dns
++ if [[ -f "$(tracker_pid_file)" ]]; then
++ kill $(cat "$(tracker_pid_file)") 2>/dev/null
++ rm -f "$(tracker_pid_file)"
++ fi
+ execute_hooks "${POST_DOWN[@]}"
+ }
+
+ cmd_save() {
+- [[ " $(wg show interfaces) " == *" $INTERFACE "* ]] || die "\`$INTERFACE' is not a WireGuard interface"
++ [[ " $(awg show interfaces) " == *" $INTERFACE "* ]] || die "\`$INTERFACE' is not a WireGuard interface"
+ save_config
+ }
+
+@@ -473,6 +591,10 @@ cmd_strip() {
+ echo "$WG_CONFIG"
+ }
+
++cmd_reload() {
++ cmd awg setconf "$INTERFACE" <(cmd_strip)
++}
++
+ # ~~ function override insertion point ~~
+
+ make_temp
+@@ -496,6 +618,10 @@ elif [[ $# -eq 2 && $1 == strip ]]; then
+ auto_su
+ parse_options "$2"
+ cmd_strip
++elif [[ $# -eq 2 && $1 == reload ]]; then
++ auto_su
++ parse_options "$2"
++ cmd_reload
+ else
+ cmd_usage
+ exit 1
diff --git a/net/amnezia-tools/pkg-descr b/net/amnezia-tools/pkg-descr
new file mode 100644
index 000000000000..0b238af17b73
--- /dev/null
+++ b/net/amnezia-tools/pkg-descr
@@ -0,0 +1,2 @@
+This supplies the main userspace tooling for using and configuring
+WireGuard tunnels, including the awg(8) and awg-quick(8) utilities.
diff --git a/net/amnezia-tools/pkg-plist b/net/amnezia-tools/pkg-plist
new file mode 100644
index 000000000000..8a2c3db16065
--- /dev/null
+++ b/net/amnezia-tools/pkg-plist
@@ -0,0 +1,7 @@
+bin/awg
+bin/awg-quick
+share/bash-completion/completions/awg
+share/bash-completion/completions/awg-quick
+share/man/man8/awg.8.gz
+share/man/man8/awg-quick.8.gz
+@dir etc/amnezia