diff --git a/net/amnezia-kmod/Makefile b/net/amnezia-kmod/Makefile index 8e6d734dd4ed..523c32e5834e 100644 --- a/net/amnezia-kmod/Makefile +++ b/net/amnezia-kmod/Makefile @@ -1,23 +1,23 @@ PORTNAME= amnezia -PORTVERSION= 1.0.8 +PORTVERSION= 2.0.8 DISTVERSIONPREFIX= v CATEGORIES= net net-vpn PKGNAMESUFFIX= -kmod MAINTAINER= vova@zote.me COMMENT= Amnezia VPN FreeBSD kernel module implementation WWW= https://docs.amnezia.org/documentation/amnezia-wg LICENSE= MIT LICENSE_FILE= ${WRKSRC}/COPYING BROKEN_FreeBSD_13= depends on kernel sources of recent FreeBSD 14 or newer USES= kmod uidfix USE_GITHUB= yes GH_ACCOUNT= vgrebenschikov GH_PROJECT= wireguard-amnezia-kmod PLIST_FILES= ${KMODDIR}/if_amn.ko .include diff --git a/net/amnezia-kmod/distinfo b/net/amnezia-kmod/distinfo index 1e206f9cefcc..318fbb887373 100644 --- a/net/amnezia-kmod/distinfo +++ b/net/amnezia-kmod/distinfo @@ -1,3 +1,3 @@ -TIMESTAMP = 1753648668 -SHA256 (vgrebenschikov-wireguard-amnezia-kmod-v1.0.8_GH0.tar.gz) = 5045cfe0f0f6d58c2c6f5103f2f5b4238b7f59f33ca6f0a8b516762ead7ba7eb -SIZE (vgrebenschikov-wireguard-amnezia-kmod-v1.0.8_GH0.tar.gz) = 57959 +TIMESTAMP = 1765569800 +SHA256 (vgrebenschikov-wireguard-amnezia-kmod-v2.0.8_GH0.tar.gz) = 3e8eef841d8249f9406c1d06c666aa2f902524c965c388fac489543043764a9b +SIZE (vgrebenschikov-wireguard-amnezia-kmod-v2.0.8_GH0.tar.gz) = 69102 diff --git a/net/amnezia-kmod/files/patch-if__wg.c b/net/amnezia-kmod/files/patch-if__wg.c index 9dd13ffb9054..c5fce996ad63 100644 --- a/net/amnezia-kmod/files/patch-if__wg.c +++ b/net/amnezia-kmod/files/patch-if__wg.c @@ -1,173 +1,173 @@ ---- if_wg.c.orig 2025-07-22 17:38:01 UTC +--- if_wg.c.orig 2025-12-10 17:55:03 UTC +++ if_wg.c -@@ -278,21 +278,21 @@ static volatile unsigned long peer_counter = 0; +@@ -305,21 +305,21 @@ static volatile unsigned long peer_counter = 0; static int clone_count; static uma_zone_t wg_packet_zone; static volatile unsigned long peer_counter = 0; -static const char wgname[] = "wg"; +static const char wgname[] = "amn"; static unsigned wg_osd_jail_slot; static struct sx wg_sx; -SX_SYSINIT(wg_sx, &wg_sx, "wg_sx"); +SX_SYSINIT(wg_sx, &wg_sx, "amn_sx"); static LIST_HEAD(, wg_softc) wg_list = LIST_HEAD_INITIALIZER(wg_list); static TASKQGROUP_DEFINE(wg_tqg, mp_ncpus, 1); -MALLOC_DEFINE(M_WG, "WG", "wireguard"); +MALLOC_DEFINE(M_WG, "amn", "amnezia"); -VNET_DEFINE_STATIC(struct if_clone *, wg_cloner); +VNET_DEFINE_STATIC(struct if_clone *, amn_cloner); -#define V_wg_cloner VNET(wg_cloner) +#define V_amn_cloner VNET(amn_cloner) #define WG_CAPS IFCAP_LINKSTATE struct wg_timespec64 { -@@ -386,10 +386,10 @@ static int wg_ioctl(if_t, u_long, caddr_t); +@@ -418,10 +418,10 @@ static int wg_ioctl(if_t, u_long, caddr_t); static void wg_reassign(if_t, struct vnet *, char *unused); static void wg_init(void *); static int wg_ioctl(if_t, u_long, caddr_t); -static void vnet_wg_init(const void *); -static void vnet_wg_uninit(const void *); -static int wg_module_init(void); -static void wg_module_deinit(void); +static void vnet_amn_init(const void *); +static void vnet_amn_uninit(const void *); +static int amn_module_init(void); +static void amn_module_deinit(void); /* TODO Peer */ static struct wg_peer * -@@ -408,7 +408,7 @@ wg_peer_alloc(struct wg_softc *sc, const uint8_t pub_k +@@ -448,7 +448,7 @@ wg_peer_create(struct wg_softc *sc, const uint8_t pub_ cookie_maker_init(&peer->p_cookie, pub_key); - rw_init(&peer->p_endpoint_lock, "wg_peer_endpoint"); + rw_init(&peer->p_endpoint_lock, "amn_peer_endpoint"); wg_queue_init(&peer->p_stage_queue, "stageq"); wg_queue_init(&peer->p_encrypt_serial, "txq"); -@@ -428,9 +428,9 @@ wg_peer_alloc(struct wg_softc *sc, const uint8_t pub_k +@@ -468,9 +468,9 @@ wg_peer_create(struct wg_softc *sc, const uint8_t pub_ peer->p_handshake_retries = 0; GROUPTASK_INIT(&peer->p_send, 0, (gtask_fn_t *)wg_deliver_out, peer); - taskqgroup_attach(qgroup_wg_tqg, &peer->p_send, peer, NULL, NULL, "wg send"); + taskqgroup_attach(qgroup_wg_tqg, &peer->p_send, peer, NULL, NULL, "amn send"); GROUPTASK_INIT(&peer->p_recv, 0, (gtask_fn_t *)wg_deliver_in, peer); - taskqgroup_attach(qgroup_wg_tqg, &peer->p_recv, peer, NULL, NULL, "wg recv"); + taskqgroup_attach(qgroup_wg_tqg, &peer->p_recv, peer, NULL, NULL, "amn recv"); LIST_INIT(&peer->p_aips); peer->p_aips_num = 0; -@@ -3286,26 +3286,26 @@ static void +@@ -3720,26 +3720,26 @@ static void } static void -vnet_wg_init(const void *unused __unused) +vnet_amn_init(const void *unused __unused) { struct if_clone_addreq req = { .create_f = wg_clone_create, .destroy_f = wg_clone_destroy, .flags = IFC_F_AUTOUNIT, }; - V_wg_cloner = ifc_attach_cloner(wgname, &req); + V_amn_cloner = ifc_attach_cloner(wgname, &req); } -VNET_SYSINIT(vnet_wg_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, -- vnet_wg_init, NULL); +- vnet_wg_init, NULL); +VNET_SYSINIT(vnet_amn_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, -+ vnet_amn_init, NULL); ++ vnet_amn_init, NULL); static void -vnet_wg_uninit(const void *unused __unused) +vnet_amn_uninit(const void *unused __unused) { - if (V_wg_cloner) - ifc_detach_cloner(V_wg_cloner); + if (V_amn_cloner) + ifc_detach_cloner(V_amn_cloner); } -VNET_SYSUNINIT(vnet_wg_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, -- vnet_wg_uninit, NULL); +- vnet_wg_uninit, NULL); +VNET_SYSUNINIT(vnet_amn_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, -+ vnet_amn_uninit, NULL); ++ vnet_amn_uninit, NULL); static int wg_prison_remove(void *obj, void *data __unused) -@@ -3352,14 +3352,14 @@ static int +@@ -3786,14 +3786,14 @@ static int #endif static int -wg_module_init(void) +amn_module_init(void) { int ret; osd_method_t methods[PR_MAXMETHOD] = { [PR_METHOD_REMOVE] = wg_prison_remove, }; - wg_packet_zone = uma_zcreate("wg packet", sizeof(struct wg_packet), + wg_packet_zone = uma_zcreate("amn packet", sizeof(struct wg_packet), - NULL, NULL, NULL, NULL, 0, 0); + NULL, NULL, NULL, NULL, 0, 0); ret = crypto_init(); -@@ -3378,15 +3378,15 @@ static void +@@ -3812,15 +3812,15 @@ static void } static void -wg_module_deinit(void) +amn_module_deinit(void) { VNET_ITERATOR_DECL(vnet_iter); VNET_LIST_RLOCK(); VNET_FOREACH(vnet_iter) { - struct if_clone *clone = VNET_VNET(vnet_iter, wg_cloner); + struct if_clone *clone = VNET_VNET(vnet_iter, amn_cloner); if (clone) { ifc_detach_cloner(clone); - VNET_VNET(vnet_iter, wg_cloner) = NULL; + VNET_VNET(vnet_iter, amn_cloner) = NULL; } } VNET_LIST_RUNLOCK(); -@@ -3401,13 +3401,13 @@ static int +@@ -3835,13 +3835,13 @@ static int } static int -wg_module_event_handler(module_t mod, int what, void *arg) +amn_module_event_handler(module_t mod, int what, void *arg) { switch (what) { case MOD_LOAD: - return wg_module_init(); + return amn_module_init(); case MOD_UNLOAD: - wg_module_deinit(); + amn_module_deinit(); break; default: return (EOPNOTSUPP); -@@ -3415,12 +3415,12 @@ wg_module_event_handler(module_t mod, int what, void * +@@ -3849,12 +3849,12 @@ wg_module_event_handler(module_t mod, int what, void * return (0); } -static moduledata_t wg_moduledata = { - "if_wg", - wg_module_event_handler, +static moduledata_t amn_moduledata = { + "if_amn", + amn_module_event_handler, NULL }; -DECLARE_MODULE(if_wg, wg_moduledata, SI_SUB_PSEUDO, SI_ORDER_ANY); -MODULE_VERSION(if_wg, WIREGUARD_VERSION); -MODULE_DEPEND(if_wg, crypto, 1, 1, 1); +DECLARE_MODULE(if_amn, amn_moduledata, SI_SUB_PSEUDO, SI_ORDER_ANY); +MODULE_VERSION(if_amn, WIREGUARD_VERSION); +MODULE_DEPEND(if_amn, crypto, 1, 1, 1); diff --git a/net/amnezia-kmod/pkg-descr b/net/amnezia-kmod/pkg-descr index 00d5e020f365..07b78e9e5464 100644 --- a/net/amnezia-kmod/pkg-descr +++ b/net/amnezia-kmod/pkg-descr @@ -1,15 +1,17 @@ FreeBSD kernel module for Amnezia VPN protocol. Amnezia VPN is a VPN protocol that is backward compatible with the WireGuard VPN protocol. It offers protection against detection by Deep Packet Inspection (DPI) systems. At the same time, it retains the simplified architecture and high performance. The Amnezia VPN protocol has issues with detection due to distinctive packet signatures. Amnezia addresses this problem by employing advanced obfuscation methods, allowing its traffic to blend seamlessly with regular internet traffic. This package provides the FreeBSD kernel module (if_amn.ko) implementation for Amnezia VPN, enabling kernel-level support for the protocol. + +Partial support of AWG2 protocol added - 2.0 S3/S4 parameters. diff --git a/net/amnezia-tools/Makefile b/net/amnezia-tools/Makefile index f48a8948fd1f..0167f3c2172f 100644 --- a/net/amnezia-tools/Makefile +++ b/net/amnezia-tools/Makefile @@ -1,43 +1,44 @@ PORTNAME= amnezia DISTVERSIONPREFIX= v -DISTVERSION= 1.0.20241018 -PORTREVISION= 4 +DISTVERSION= 1.0.20250903 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 \ +DEBUG?= no + +MAKE_ARGS+= DEBUG=${DEBUG} \ 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 diff --git a/net/amnezia-tools/distinfo b/net/amnezia-tools/distinfo index 4121ea84aa23..33f5d4d3fc37 100644 --- a/net/amnezia-tools/distinfo +++ b/net/amnezia-tools/distinfo @@ -1,3 +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 +TIMESTAMP = 1761344729 +SHA256 (amnezia-vpn-amneziawg-tools-v1.0.20250903_GH0.tar.gz) = d729a6f54aafcd55b2cbb7324f09ca8f0d2536772970652bf822a271d0c907d7 +SIZE (amnezia-vpn-amneziawg-tools-v1.0.20250903_GH0.tar.gz) = 160214 diff --git a/net/amnezia-tools/files/patch-config.c b/net/amnezia-tools/files/patch-config.c index 68d939b8e675..0b87c28f2ac3 100644 --- a/net/amnezia-tools/files/patch-config.c +++ b/net/amnezia-tools/files/patch-config.c @@ -1,59 +1,59 @@ ---- config.c.orig 2024-10-01 13:02:42 UTC +--- config.c.orig 2025-09-03 14:11:13 UTC +++ config.c -@@ -252,7 +252,7 @@ static inline bool parse_endpoint(struct sockaddr *end +@@ -259,7 +259,7 @@ static inline bool parse_endpoint(struct sockaddr *end * * So this is what we do, except FreeBSD removed EAI_NODATA some time ago, so that's conditional. */ - if (ret == EAI_NONAME || ret == EAI_FAIL || + if (ret == EAI_FAIL || #ifdef EAI_NODATA ret == EAI_NODATA || #endif -@@ -337,6 +337,20 @@ static bool validate_netmask(struct wgallowedip *allow +@@ -344,6 +344,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 +@@ -360,10 +374,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 +@@ -394,6 +416,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 index 88563f74058a..233c2465854b 100644 --- a/net/amnezia-tools/files/patch-containers.h +++ b/net/amnezia-tools/files/patch-containers.h @@ -1,21 +1,21 @@ ---- containers.h.orig 2024-10-01 13:02:42 UTC +--- containers.h.orig 2025-09-03 14:11:13 UTC +++ containers.h -@@ -29,6 +29,10 @@ struct timespec64 { +@@ -34,6 +34,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 { +@@ -41,6 +45,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 index 22255c0bcca3..2737729233b5 100644 --- a/net/amnezia-tools/files/patch-ipc-freebsd.h +++ b/net/amnezia-tools/files/patch-ipc-freebsd.h @@ -1,27 +1,48 @@ ---- ipc-freebsd.h.orig 2024-10-01 13:02:42 UTC +--- ipc-freebsd.h.orig 2025-09-03 14:11:13 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) +@@ -458,15 +458,15 @@ static int kernel_set_device(struct wgdevice *dev) + if (dev->flags & WGDEVICE_HAS_H4) + nvlist_add_binary(nvl_device, "h4", dev->transport_packet_magic_header, strlen(dev->transport_packet_magic_header) + 1); + if (dev->flags & WGDEVICE_HAS_I1) +- nvlist_add_binary(nvl_device, "i1", dev->i1, strlen(dev->i1) + 1); ++ nvlist_add_binary(nvl_device, "i1", dev->i1 ? dev->i1 : "", strlen(dev->i1 ? dev->i1 : "") + 1); + if (dev->flags & WGDEVICE_HAS_I2) +- nvlist_add_binary(nvl_device, "i2", dev->i2, strlen(dev->i2) + 1); ++ nvlist_add_binary(nvl_device, "i2", dev->i2 ? dev->i2 : "", strlen(dev->i2 ? dev->i2 : "") + 1); + if (dev->flags & WGDEVICE_HAS_I3) +- nvlist_add_binary(nvl_device, "i3", dev->i3, strlen(dev->i3) + 1); ++ nvlist_add_binary(nvl_device, "i3", dev->i3 ? dev->i3 : "", strlen(dev->i3 ? dev->i3 : "") + 1); + if (dev->flags & WGDEVICE_HAS_I4) +- nvlist_add_binary(nvl_device, "i4", dev->i4, strlen(dev->i4) + 1); ++ nvlist_add_binary(nvl_device, "i4", dev->i4 ? dev->i4 : "", strlen(dev->i4 ? dev->i4 : "") + 1); + if (dev->flags & WGDEVICE_HAS_I5) +- nvlist_add_binary(nvl_device, "i5", dev->i5, strlen(dev->i5) + 1); ++ nvlist_add_binary(nvl_device, "i5", dev->i5 ? dev->i5 : "", strlen(dev->i5 ? dev->i5 : "") + 1); + if (dev->flags & WGDEVICE_HAS_FWMARK) + nvlist_add_number(nvl_device, "user-cookie", dev->fwmark); + if (dev->flags & WGDEVICE_REPLACE_PEERS) +@@ -502,6 +502,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 index 61df9f69e784..cbf4811ca8a7 100644 --- a/net/amnezia-tools/files/patch-ipc-uapi.h +++ b/net/amnezia-tools/files/patch-ipc-uapi.h @@ -1,11 +1,11 @@ ---- ipc-uapi.h.orig 2024-10-01 13:02:42 UTC +--- ipc-uapi.h.orig 2025-09-03 14:11:13 UTC +++ ipc-uapi.h -@@ -111,7 +111,7 @@ static int userspace_set_device(struct wgdevice *dev) +@@ -126,7 +126,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.8 b/net/amnezia-tools/files/patch-man_wg.8 index 87e018ff2856..5356f8d2069c 100644 --- a/net/amnezia-tools/files/patch-man_wg.8 +++ b/net/amnezia-tools/files/patch-man_wg.8 @@ -1,158 +1,200 @@ ---- man/wg.8.orig 2024-10-01 13:02:42 UTC +--- man/wg.8.orig 2025-09-03 14:11:13 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\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\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\fP. If no \fI\fP is specified, \fI\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\fP in the format described by \fICONFIGURATION FILE FORMAT\fP below. .TP -\fBset\fP \fI\fP [\fIlisten-port\fP \fI\fP] [\fIfwmark\fP \fI\fP] [\fIprivate-key\fP \fI\fP] [\fIpeer\fP \fI\fP [\fIremove\fP] [\fIpreshared-key\fP \fI\fP] [\fIendpoint\fP \fI:\fP] [\fIpersistent-keepalive\fP \fI\fP] [\fIallowed-ips\fP \fI/\fP[,\fI/\fP]...] ]... +\fBset\fP \fI\fP [\fIlisten-port\fP \fI\fP] [\fIfwmark\fP \fI\fP] [\fIprivate-key\fP \fI\fP] [\fIjc ]\fP [\fI]\fP [\fIjmax \fP] [\fIs1 \fP] [\fIs2 \fP] [\fIh1\fP] [\fIh2

\fP] [\fIh3

\fP] [\fIh4

\fP] [\fIpeer\fP \fI\fP [\fIremove\fP] [\fIpreshared-key\fP \fI\fP] [\fIendpoint\fP \fI:\fP] [\fIpersistent-keepalive\fP \fI\fP] [\fIallowed-ips\fP \fI[+|-]/\fP[,\fI[+|-]/\fP]...] ]... Sets configuration values for the specified \fI\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 +@@ -119,11 +121,94 @@ 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 ++0–1304 (recomended 15–150) + +.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 ++0–1360 (recomended 15–150) ++ ++.TP ++\fBs3\fP ++Size of handshake cookie packet prepend junk. Should be the same on both ends. ++.br ++0–1388 (recomended 15–150) ++ ++.TP ++\fBs4\fP ++Size of data transport packet prepend junk. Should be the same on both ends. ++Will effectively decrease maximum possible MTU of interface. ++.br ++0–160 (recomended 15-32) + +.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 ++Should be either the unique value in range of 5 - 4294967295 (0x5 - 0xFFFFFFFF) ++.br ++Or should be either the range of two such values, via '-', like 2294967295-4294970000, when range is used a random number from the range selected for each packet. ++For range, first value should be less then second. ++.br ++Such ranges or values should not intersect/match each other. ++ ++.TP ++\fBi1-i5\fP ++Pre-crafted custom signature packets to be send before hadshake. May be configured on either side and may be different between sides. ++These packets are being send prior to every handshake, in the same way as Junk packets do. The sending order is i1, i2, i3, i4, i5. If there is no value specified, the packet is skipped. ++.br ++Value is a sequence of tags specified below: + ++.br ++\fB\fP - static bytes tag. Dumps [seq] as-is to the packet. [seq] is hex-encoded sequence which represents bytes sequence (2 hex numbers per byte) and is always even-sized ++ ++.br ++\fB\fP - random bytes tag. Dumps [size] amount of randomly-generated bytes to the packet ++ ++.br ++\fB\fP - random digits tag. Dumps [size] amount of randomly-generated bytes from [0-9] set to the packet ++ ++.br ++\fB\fP - random chars tag. Dumps [size] amount of randomly-generated bytes from [a-zA-Z] set to the packet ++ ++.br ++\fB\fP - timestamp tag. Dumps 4-bytes long current system time in UNIX format ++ ++.br ++\fB\fP - packet counter tag. Dumps 4-bytes long amount of packets sent by AWG + .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 +@@ -224,7 +309,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 +@@ -240,19 +325,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 index 61e1ec5314d0..060312414f44 100644 --- a/net/amnezia-tools/files/patch-set.c +++ b/net/amnezia-tools/files/patch-set.c @@ -1,11 +1,11 @@ ---- set.c.orig 2024-10-01 13:02:42 UTC +--- set.c.orig 2025-09-03 14:11:13 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 [listen-port ] [fwmark ] [private-key ] [peer [remove] [preshared-key ] [endpoint :] [persistent-keepalive ] [allowed-ips /[,/] [advanced-security ]...] ]...\n", PROG_NAME, argv[0]); -+ fprintf(stderr, "Usage: %s %s [listen-port ] [fwmark ] [private-key ] [peer [remove] [preshared-key ] [endpoint :] [persistent-keepalive ] [allowed-ips [+|-]/[,[+|-]/] [advanced-security ]...] ]...\n", PROG_NAME, argv[0]); +- fprintf(stderr, "Usage: %s %s [listen-port ] [fwmark ] [private-key ] [jc ] [jmin ] [jmax ] [s1 ] [s2 ] [s3 ] [s4 ] [h1 ] [h2 ] [h3 ] [h4 ] [i1 \"\"] [i2 \"\"] [i3 \"\"] [i4 \"\"] [i5 \"\"] [peer [remove] [preshared-key ] [endpoint :] [persistent-keepalive ] [allowed-ips /[,/] [advanced-security ]...] ]...\n", PROG_NAME, argv[0]); ++ fprintf(stderr, "Usage: %s %s [listen-port ] [fwmark ] [private-key ] [jc ] [jmin ] [jmax ] [s1 ] [s2 ] [s3 ] [s4 ] [h1 ] [h2 ] [h3 ] [h4 ] [i1 \"\"] [i2 \"\"] [i3 \"\"] [i4 \"\"] [i5 \"\"] [peer [remove] [preshared-key ] [endpoint :] [persistent-keepalive ] [allowed-ips [+|-]/[,[+|-]/] [advanced-security ]...] ]...\n", PROG_NAME, argv[0]); return 1; } diff --git a/net/amnezia-tools/files/patch-show.c b/net/amnezia-tools/files/patch-show.c new file mode 100644 index 000000000000..fb6f765c71dc --- /dev/null +++ b/net/amnezia-tools/files/patch-show.c @@ -0,0 +1,51 @@ +--- show.c.orig 2025-09-03 14:11:13 UTC ++++ show.c +@@ -401,39 +401,39 @@ static bool ugly_print(struct wgdevice *device, const + } else if (!strcmp(param, "h1")) { + if (with_interface) + printf("%s\t", device->name); +- printf("%s\n", device->init_packet_magic_header); ++ printf("%s\n", device->init_packet_magic_header?:"0"); + } else if (!strcmp(param, "h2")) { + if (with_interface) + printf("%s\t", device->name); +- printf("%s\n", device->response_packet_magic_header); ++ printf("%s\n", device->response_packet_magic_header?:"0"); + } else if (!strcmp(param, "h3")) { + if (with_interface) + printf("%s\t", device->name); +- printf("%s\n", device->underload_packet_magic_header); ++ printf("%s\n", device->underload_packet_magic_header?:"0"); + } else if (!strcmp(param, "h4")) { + if (with_interface) + printf("%s\t", device->name); +- printf("%s\n", device->transport_packet_magic_header); ++ printf("%s\n", device->transport_packet_magic_header?:"0"); + } else if (!strcmp(param, "i1")) { + if (with_interface) + printf("%s\t", device->name); +- printf("%s\n", device->i1); ++ printf("%s\n", device->i1?:""); + } else if (!strcmp(param, "i2")) { + if (with_interface) + printf("%s\t", device->name); +- printf("%s\n", device->i2); ++ printf("%s\n", device->i2?:""); + } else if (!strcmp(param, "i3")) { + if (with_interface) + printf("%s\t", device->name); +- printf("%s\n", device->i3); ++ printf("%s\n", device->i3?:""); + } else if (!strcmp(param, "i4")) { + if (with_interface) + printf("%s\t", device->name); +- printf("%s\n", device->i4); ++ printf("%s\n", device->i4?:""); + } else if (!strcmp(param, "i5")) { + if (with_interface) + printf("%s\t", device->name); +- printf("%s\n", device->i5); ++ printf("%s\n", device->i5?:""); + } else if (!strcmp(param, "endpoints")) { + for_each_wgpeer(device, peer) { + if (with_interface) diff --git a/net/amnezia-tools/files/patch-wg-quick_freebsd.bash b/net/amnezia-tools/files/patch-wg-quick_freebsd.bash index e4f2cfe40c0a..cc582319c260 100644 --- a/net/amnezia-tools/files/patch-wg-quick_freebsd.bash +++ b/net/amnezia-tools/files/patch-wg-quick_freebsd.bash @@ -1,360 +1,424 @@ ---- wg-quick/freebsd.bash.orig 2025-12-03 19:32:16 UTC +--- wg-quick/freebsd.bash.orig 2025-12-12 22:28:42 UTC +++ wg-quick/freebsd.bash -@@ -25,11 +25,20 @@ CONFIG_FILE="" +@@ -25,11 +25,18 @@ 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 + IS_AWG_ON=0 -+ +declare -A ROUTES +declare -A ENDPOINTS_MAP -+ + cmd() { echo "[#] $*" >&3 "$@" -@@ -40,7 +49,7 @@ die() { +@@ -40,7 +47,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() { +@@ -64,7 +71,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() { +@@ -82,7 +89,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() { +@@ -96,9 +103,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;; +@@ -116,6 +128,17 @@ parse_options() { + I4);& + I5) IS_AWG_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_MAP["$last_public_key"]="$endpoint_host" + fi + ;; + esac fi WG_CONFIG+="$line"$'\n' done < "$CONFIG_FILE" -@@ -129,19 +154,22 @@ add_if() { +@@ -136,20 +159,24 @@ 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 [[ $IS_AWG_ON == 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 - echo "$ret" >&3 - return $rc - fi +- fi +- rc=$? +- if [[ $ret == *"ifconfig: ioctl SIOCSIFNAME (set name): File exists"* ]]; then +- echo "$ret" >&3 +- return $rc +- fi - echo "[!] Missing WireGuard kernel support ($ret). Falling back to slow userspace implementation." >&3 ++ local cmd="ifconfig amn create name "$INTERFACE"" ++ if [[ $USERLAND == 0 ]]; then ++ 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 ++ echo "$ret" >&3 ++ return $rc ++ fi ++ fi + echo "[!] Missing Amnezia kernel support ($ret). Falling back to slow userspace implementation." >&3 cmd "${WG_QUICK_USERSPACE_IMPLEMENTATION:-amneziawg-go}" "$INTERFACE" ++ if [ -n "$DESCRIPTION" ]; then ++ cmd ifconfig $INTERFACE description "$DESCRIPTION" ++ fi + } + + del_routes() { +@@ -181,9 +208,9 @@ del_if() { + if [[ -S /var/run/amneziawg/$INTERFACE.sock ]]; then + cmd rm -f "/var/run/amneziawg/$INTERFACE.sock" + else +- cmd ifconfig "$INTERFACE" destroy ++ cmd ifconfig -n "$INTERFACE" destroy + fi +- while ifconfig "$INTERFACE" >/dev/null 2>&1; do ++ while ifconfig -n "$INTERFACE" >/dev/null 2>&1; do + # HACK: it would be nice to `route monitor` here and wait for RTM_IFANNOUNCE + # but it turns out that the announcement is made before the interface + # disappears so we sometimes get a hang. So, we're instead left with polling +@@ -193,21 +220,21 @@ up_if() { } -@@ -209,7 +237,7 @@ set_mtu() { + up_if() { +- cmd ifconfig "$INTERFACE" up ++ cmd ifconfig -n "$INTERFACE" up + } + + add_addr() { + if [[ $1 == *:* ]]; then +- cmd ifconfig "$INTERFACE" inet6 "$1" alias ++ cmd ifconfig -n "$INTERFACE" inet6 "$1" alias + else +- cmd ifconfig "$INTERFACE" inet "$1" alias ++ cmd ifconfig -n "$INTERFACE" inet "$1" alias + fi + } + + set_mtu() { + local mtu=0 endpoint output family + if [[ -n $MTU ]]; then +- cmd ifconfig "$INTERFACE" mtu "$MTU" ++ cmd ifconfig -n "$INTERFACE" mtu "$MTU" + return + fi + while read -r _ endpoint; do +@@ -215,14 +242,16 @@ set_mtu() { + family=inet [[ ${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]}" +- [[ $output =~ interface:\ ([^ ]+)$'\n' && $(ifconfig "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) && ${BASH_REMATCH[1]} -gt $mtu ]] && mtu="${BASH_REMATCH[1]}" - done < <(wg show "$INTERFACE" endpoints) ++ [[ $output =~ interface:\ ([^ ]+)$'\n' && $(ifconfig -n "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) && ${BASH_REMATCH[1]} -gt $mtu ]] && mtu="${BASH_REMATCH[1]}" + 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() { +- [[ $output =~ interface:\ ([^ ]+)$'\n' && $(ifconfig "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) && ${BASH_REMATCH[1]} -gt $mtu ]] && mtu="${BASH_REMATCH[1]}" ++ [[ $output =~ interface:\ ([^ ]+)$'\n' && $(ifconfig -n "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) && ${BASH_REMATCH[1]} -gt $mtu ]] && mtu="${BASH_REMATCH[1]}" + fi +- [[ $mtu -gt 0 ]] || mtu=1500 +- cmd ifconfig "$INTERFACE" mtu $(( mtu - 80 )) ++ if [[ $mtu -gt 0 && $mtu -lt 1420 ]]; then ++ # setup MTU only if discovered MTU is less then default ++ cmd ifconfig -n "$INTERFACE" mtu $(( mtu - 80 )) || true ++ fi + } + + +@@ -249,7 +278,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,25 @@ monitor_daemon() { +@@ -304,25 +333,108 @@ monitor_daemon() { } monitor_daemon() { - echo "[+] Backgrounding route monitor" >&2 + [[ $MONITOR -eq 0 ]] && return 0 + + if [[ $1 == "spawn" ]]; then + # re-run this function over daemon to detach from session + echo "[+] Backgrounding route monitor" >&2 + env TMPDIR="${ORIGINAL_TMPDIR}" daemon $0 monitor-daemon ${INTERFACE} + return 0 + fi + (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 +- ifconfig "$INTERFACE" >/dev/null 2>&1 || break ++ ifconfig -n "$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 +351,82 @@ monitor_daemon() { + done 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 + + if [[ $1 == "spawn" ]]; then + # re-run this function over daemon to detach from session + echo "[+] Backgrounding DNS tracker" >&2 + env TMPDIR="${ORIGINAL_TMPDIR}" daemon $0 monitor-dns-changes ${INTERFACE} + return 0 + fi + + 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_MAP[$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 + ) /dev/null 2>&1 3>&- & disown + echo "$!" > "$pid_file" +} + + HAVE_SET_DNS=0 set_dns() { [[ ${#DNS[@]} -gt 0 ]] || return 0 -@@ -354,7 +465,7 @@ set_config() { +@@ -361,7 +473,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 +497,7 @@ save_config() { +@@ -393,7 +505,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" -@@ -412,7 +523,7 @@ cmd_usage() { +@@ -419,7 +531,7 @@ cmd_usage() { followed by \`.conf'. Otherwise, INTERFACE is an interface name, with configuration found at: ${CONFIG_SEARCH_PATHS[@]/%//INTERFACE.conf}. - It is to be readable by wg(8)'s \`setconf' sub-command, with the exception + It is to be readable by awg(8)'s \`setconf' sub-command, with the exception of the following additions to the [Interface] section, which are handled by $PROGRAM: -@@ -429,10 +540,24 @@ cmd_usage() { +@@ -436,13 +548,27 @@ cmd_usage() { - SaveConfig: if set to \`true', the configuration is saved from the current state of the interface upon shutdown. - See wg-quick(8) for more info and examples. + See awg-quick(8) for more info and examples. _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 +571,31 @@ cmd_up() { +- [[ -z $(ifconfig "$INTERFACE" 2>/dev/null) ]] || die "\`$INTERFACE' already exists" ++ [[ -z $(ifconfig -n "$INTERFACE" 2>/dev/null) ]] || die "\`$INTERFACE' already exists" + trap 'del_if; del_routes; clean_temp; exit' INT TERM EXIT + add_if + execute_hooks "${PRE_UP[@]}" +@@ -453,26 +579,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_daemon spawn + monitor_dns_changes spawn 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 Amnezia 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 Amnezia interface" save_config } -@@ -473,6 +603,10 @@ cmd_strip() { +@@ -480,6 +611,10 @@ cmd_strip() { echo "$WG_CONFIG" } +cmd_reload() { + cmd awg setconf "$INTERFACE" <(cmd_strip) +} + # ~~ function override insertion point ~~ make_temp -@@ -496,6 +630,18 @@ elif [[ $# -eq 2 && $1 == strip ]]; then +@@ -503,6 +638,18 @@ 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 +elif [[ $# -eq 2 && $1 == "monitor-daemon" ]]; then + auto_su + parse_options "$2" + monitor_daemon +elif [[ $# -eq 2 && $1 == "monitor-dns-changes" ]]; then + auto_su + parse_options "$2" + monitor_dns_changes else cmd_usage exit 1