From e882483f87f320f8a3a9e95bcf07bd5eb05cc39b Mon Sep 17 00:00:00 2001 From: Iurii Egorov Date: Wed, 23 Oct 2024 13:08:30 +0300 Subject: [PATCH] Add parameter to obfuscate endpoints in netlink get device response --- amneziawg-dkms.spec | 5 +- kernel-tree-scripts/prepare-sources.sh | 12 ++- src/Kbuild | 1 + src/Makefile | 23 ++---- src/main.c | 1 + src/netlink.c | 28 +++++-- src/netlink.h | 2 + .../005-bogus-endpoints-parameter.patch | 75 +++++++++++++++++++ 8 files changed, 120 insertions(+), 27 deletions(-) create mode 100644 src/patches/005-bogus-endpoints-parameter.patch diff --git a/amneziawg-dkms.spec b/amneziawg-dkms.spec index fa7613a..3f75db8 100644 --- a/amneziawg-dkms.spec +++ b/amneziawg-dkms.spec @@ -1,7 +1,7 @@ %global debug_package %{nil} Name: amneziawg-dkms -Version: 1.0.20241022 +Version: 1.0.20241023 Release: 1%{?dist} Epoch: 1 URL: https://www.wireguard.com/ @@ -89,6 +89,9 @@ exit 0 %{_usrsrc}/amneziawg-%{version} %changelog +* Thu Oct 23 2024 Yuri Egorov - 1.0.20241023-1 +- Update to 1.0.20241023 + * Thu Oct 22 2024 Yuri Egorov - 1.0.20241022-1 - Update to 1.0.20241022 diff --git a/kernel-tree-scripts/prepare-sources.sh b/kernel-tree-scripts/prepare-sources.sh index 29b841a..3d0a67e 100755 --- a/kernel-tree-scripts/prepare-sources.sh +++ b/kernel-tree-scripts/prepare-sources.sh @@ -17,6 +17,12 @@ is_modern_kernel() { fi } +cd_first () { + local prefix=$1 + local first=$(find ./${prefix}* -maxdepth 0 -type d 2>/dev/null | sort | head -n 1) + [ "${first}" != "" ] && cd "${first}" || exit 255 +} + if ! is_modern_kernel; then echo "Legacy kernel - using the compat sources" exit 0 @@ -72,7 +78,7 @@ if [[ "${DISTRO_FLAVOR}" =~ debian ]]; then PACKAGE_VERSION=$(apt-cache madison "${PACKAGE_NAME}"|grep Sources|head -n 1|awk '{ print $3; }') echo "Downloading as $(whoami)" apt-get -yq -o APT::Sandbox::User="$(whoami)" source "${PACKAGE_NAME}=${PACKAGE_VERSION}" - cd "$(ls -d */)" || exit 255 + cd_first else yumdownloader --source kernel [ -f "${HOME}/.rpmmacros" ] && mv "${HOME}/.rpmmacros" "${HOME}/.rpmmacros.orig" @@ -83,8 +89,8 @@ else rm -rf "${HOME}/.rpmmacros" [ -f "${HOME}/.rpmmacros.orig" ] && mv "${HOME}/.rpmmacros.orig" "${HOME}/.rpmmacros" cd ../BUILD || exit 255 - cd "$(find ./* -maxdepth 0 -type d | sort | head -n 1)" || exit 255 - cd "$(ls -d linux*/)" || exit 255 + cd_first + cd_first linux fi KERNEL_PATH="$(pwd)" diff --git a/src/Kbuild b/src/Kbuild index 93e46f6..f618152 100644 --- a/src/Kbuild +++ b/src/Kbuild @@ -8,6 +8,7 @@ ccflags-y := -D'pr_fmt(fmt)=KBUILD_MODNAME ": " fmt' ccflags-y += -Wframe-larger-than=2048 ccflags-$(CONFIG_AMNEZIAWG_DEBUG) += -DDEBUG -g ccflags-$(if $(WIREGUARD_VERSION),y,) += -D'WIREGUARD_VERSION="$(WIREGUARD_VERSION)"' +ccflags-$(if $(OMIT_ENDPOINTS),y,) += -D'OMIT_ENDPOINTS="$(OMIT_ENDPOINTS)"' amneziawg-y := main.o noise.o device.o peer.o timers.o queueing.o send.o receive.o socket.o peerlookup.o allowedips.o ratelimiter.o cookie.o netlink.o diff --git a/src/Makefile b/src/Makefile index 8d4dad4..f88d805 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3,6 +3,7 @@ # Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. WIREGUARD_VERSION = 1.0.0 +OMIT_ENDPOINTS ?= KERNELRELEASE ?= $(shell uname -r) KERNELDIR ?= /lib/modules/$(KERNELRELEASE)/build @@ -90,25 +91,19 @@ MAKEFLAGS += --no-print-directory endif module: - @$(MAKE) -C $(KERNELDIR) M=$(TARGET_BUILD_DIR) WIREGUARD_VERSION="$(WIREGUARD_VERSION)" modules - if [ "$(TARGET_BUILD_DIR)" != "$(PWD)" ]; then \ - cp $(TARGET_BUILD_DIR)/amneziawg.ko $(PWD)/amneziawg.ko; \ - fi + @$(MAKE) -C $(KERNELDIR) M=$(TARGET_BUILD_DIR) WIREGUARD_VERSION="$(WIREGUARD_VERSION)" OMIT_ENDPOINTS="$(OMIT_ENDPOINTS)" modules + [ "$(TARGET_BUILD_DIR)" != "$(PWD)" ] && cp $(TARGET_BUILD_DIR)/amneziawg.ko $(PWD)/amneziawg.ko module-debug: - @$(MAKE) -C $(KERNELDIR) M=$(TARGET_BUILD_DIR) V=1 CONFIG_AMNEZIAWG_DEBUG=y WIREGUARD_VERSION="$(WIREGUARD_VERSION)" modules - if [ "$(TARGET_BUILD_DIR)" != "$(PWD)" ]; then \ - cp $(TARGET_BUILD_DIR)/amneziawg.ko $(PWD)/amneziawg.ko; \ - fi + @$(MAKE) -C $(KERNELDIR) M=$(TARGET_BUILD_DIR) V=1 CONFIG_AMNEZIAWG_DEBUG=y WIREGUARD_VERSION="$(WIREGUARD_VERSION)" OMIT_ENDPOINTS="$(OMIT_ENDPOINTS)" modules + [ "$(TARGET_BUILD_DIR)" != "$(PWD)" ] && cp $(TARGET_BUILD_DIR)/amneziawg.ko $(PWD)/amneziawg.ko clean: @$(MAKE) -C $(KERNELDIR) M=$(PWD) clean - if [ "$(TARGET_BUILD_DIR)" != "$(PWD)" ]; then \ - rm -rf $(TARGET_BUILD_DIR); \ - fi + [ "$(TARGET_BUILD_DIR)" != "$(PWD)" ] && rm -rf $(TARGET_BUILD_DIR) module-install: - @$(MAKE) -C $(KERNELDIR) M=$(TARGET_BUILD_DIR) WIREGUARD_VERSION="$(WIREGUARD_VERSION)" modules_install + @$(MAKE) -C $(KERNELDIR) M=$(TARGET_BUILD_DIR) WIREGUARD_VERSION="$(WIREGUARD_VERSION)" OMIT_ENDPOINTS="$(OMIT_ENDPOINTS)" modules_install $(DEPMOD) -b "$(DEPMODBASEDIR)" -a $(KERNELRELEASE) install: module-install @@ -118,9 +113,7 @@ dkms-install: $(DKMS_SOURCES) @$(foreach f,$(DKMS_SOURCES),install -v -m0644 -D $(f) $(DESTDIR)$(DKMSDIR)/$(f);) @install -v -m 0755 ../kernel-tree-scripts/prepare-sources.sh "$(DESTDIR)$(DKMSDIR)/prepare-sources.sh" @install -v -m 0755 ../kernel-tree-scripts/cleanup-sources.sh "$(DESTDIR)$(DKMSDIR)/cleanup-sources.sh" - if [ "$(realpath $(WG_SOURCE_DIR))" != "" ]; then \ - ln -s "$(KERNEL_SOURCE_DIR)" "$(DESTDIR)$(DKMSDIR)/kernel"; \ - fi + [ "$(realpath $(WG_SOURCE_DIR))" != "" ] && ln -s "$(KERNEL_SOURCE_DIR)" "$(DESTDIR)$(DKMSDIR)/kernel" style: $(KERNELDIR)/scripts/checkpatch.pl -f --max-line-length=4000 --codespell --color=always $(filter-out wireguard.mod.c,$(wildcard *.c)) $(wildcard *.h) $(wildcard selftest/*.c) diff --git a/src/main.c b/src/main.c index 8e5affd..4c321d4 100644 --- a/src/main.c +++ b/src/main.c @@ -75,6 +75,7 @@ static void __exit wg_mod_exit(void) wg_allowedips_slab_uninit(); } +module_param(bogus_endpoints, int, 0600); module_init(wg_mod_init); module_exit(wg_mod_exit); MODULE_LICENSE("GPL v2"); diff --git a/src/netlink.c b/src/netlink.c index af0ba3a..7d9f3d1 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -14,6 +14,9 @@ #include #include #include +#include + +int bogus_endpoints = 0; static struct genl_family genl_family; @@ -164,18 +167,27 @@ get_peer(struct wg_peer *peer, struct sk_buff *skb, struct dump_ctx *ctx) nla_put_u32(skb, WGPEER_A_PROTOCOL_VERSION, 1)) goto err; +#ifndef OMIT_ENDPOINTS read_lock_bh(&peer->endpoint_lock); - if (peer->endpoint.addr.sa_family == AF_INET) - fail = nla_put(skb, WGPEER_A_ENDPOINT, - sizeof(peer->endpoint.addr4), - &peer->endpoint.addr4); - else if (peer->endpoint.addr.sa_family == AF_INET6) - fail = nla_put(skb, WGPEER_A_ENDPOINT, - sizeof(peer->endpoint.addr6), - &peer->endpoint.addr6); + if (peer->endpoint.addr.sa_family == AF_INET) { + struct sockaddr_in addr4 = peer->endpoint.addr4; + + if (bogus_endpoints) + addr4.sin_addr.s_addr = get_random_u32(); + + fail = nla_put(skb, WGPEER_A_ENDPOINT, sizeof(addr4), &addr4); + } else if (peer->endpoint.addr.sa_family == AF_INET6) { + struct sockaddr_in6 addr6 = peer->endpoint.addr6; + + if (bogus_endpoints) + get_random_bytes(&addr6.sin6_addr.s6_addr, sizeof(addr6.sin6_addr.s6_addr)); + + fail = nla_put(skb, WGPEER_A_ENDPOINT, sizeof(addr6), &addr6); + } read_unlock_bh(&peer->endpoint_lock); if (fail) goto err; +#endif allowedips_node = list_first_entry_or_null(&peer->allowedips_list, struct allowedips_node, peer_list); diff --git a/src/netlink.h b/src/netlink.h index c1ea75a..0fcc344 100644 --- a/src/netlink.h +++ b/src/netlink.h @@ -9,6 +9,8 @@ #include "peer.h" #include "noise.h" +extern int bogus_endpoints; + int wg_genl_mcast_peer_unknown(struct wg_device *wg, const u8 pubkey[NOISE_PUBLIC_KEY_LEN], struct endpoint *endpoint, bool advanced_security); int wg_genetlink_init(void); diff --git a/src/patches/005-bogus-endpoints-parameter.patch b/src/patches/005-bogus-endpoints-parameter.patch new file mode 100644 index 0000000..df7f31f --- /dev/null +++ b/src/patches/005-bogus-endpoints-parameter.patch @@ -0,0 +1,75 @@ +diff --git main.c main.c +index 8e5affd..4c321d4 100644 +--- main.c ++++ main.c +@@ -75,6 +75,7 @@ static void __exit wg_mod_exit(void) + wg_allowedips_slab_uninit(); + } + ++module_param(bogus_endpoints, int, 0600); + module_init(wg_mod_init); + module_exit(wg_mod_exit); + MODULE_LICENSE("GPL v2"); +diff --git netlink.c netlink.c +index af0ba3a..7d9f3d1 100644 +--- netlink.c ++++ netlink.c +@@ -14,6 +14,9 @@ + #include + #include + #include ++#include ++ ++int bogus_endpoints = 0; + + static struct genl_family genl_family; + +@@ -164,18 +167,27 @@ get_peer(struct wg_peer *peer, struct sk_buff *skb, struct dump_ctx *ctx) + nla_put_u32(skb, WGPEER_A_PROTOCOL_VERSION, 1)) + goto err; + ++#ifndef OMIT_ENDPOINTS + read_lock_bh(&peer->endpoint_lock); +- if (peer->endpoint.addr.sa_family == AF_INET) +- fail = nla_put(skb, WGPEER_A_ENDPOINT, +- sizeof(peer->endpoint.addr4), +- &peer->endpoint.addr4); +- else if (peer->endpoint.addr.sa_family == AF_INET6) +- fail = nla_put(skb, WGPEER_A_ENDPOINT, +- sizeof(peer->endpoint.addr6), +- &peer->endpoint.addr6); ++ if (peer->endpoint.addr.sa_family == AF_INET) { ++ struct sockaddr_in addr4 = peer->endpoint.addr4; ++ ++ if (bogus_endpoints) ++ addr4.sin_addr.s_addr = get_random_u32(); ++ ++ fail = nla_put(skb, WGPEER_A_ENDPOINT, sizeof(addr4), &addr4); ++ } else if (peer->endpoint.addr.sa_family == AF_INET6) { ++ struct sockaddr_in6 addr6 = peer->endpoint.addr6; ++ ++ if (bogus_endpoints) ++ get_random_bytes(&addr6.sin6_addr.s6_addr, sizeof(addr6.sin6_addr.s6_addr)); ++ ++ fail = nla_put(skb, WGPEER_A_ENDPOINT, sizeof(addr6), &addr6); ++ } + read_unlock_bh(&peer->endpoint_lock); + if (fail) + goto err; ++#endif + allowedips_node = + list_first_entry_or_null(&peer->allowedips_list, + struct allowedips_node, peer_list); +diff --git netlink.h netlink.h +index c1ea75a..0fcc344 100644 +--- netlink.h ++++ netlink.h +@@ -9,6 +9,8 @@ + #include "peer.h" + #include "noise.h" + ++extern int bogus_endpoints; ++ + int wg_genl_mcast_peer_unknown(struct wg_device *wg, const u8 pubkey[NOISE_PUBLIC_KEY_LEN], + struct endpoint *endpoint, bool advanced_security); + int wg_genetlink_init(void);