Installing WireGuard on Amazon Linux

Lots of folks who use AWS like to use the Amazon Linux distribution that Amazon provides. But since Amazon Linux does not include a WireGuard package in its supported package repositories, if you want to use WireGuard with Amazon Linux, you must build and install WireGuard yourself. Fortunately, it’s easy (especially with newer Linux kernels). Here’s how you do it:

Amazon Linux 2

Amazon Linux 2 is based on RHEL (Red Hat Enterprise Linux) version 7, but with a number of updates and AWS-specific customizations. Originally, Amazon Linux 2 was released with the Linux kernel version 4.14, but recently (since late 2021), Amazon added a second kernel version: 5.10.

WireGuard has been part of the Linux kernel since version 5.6, so the WireGuard installation process is easier under the newer kernel (5.10) than the old (4.14). You can use either, however. Amazon is expected to support both kernels until the Amazon Linux 2 EOL (End of Life), June 2023.

Older Kernel

With the old kernel (like any kernel version before 5.6), you have to build and install the WireGuard kernel module first (which provides the wireguard network device type), and then you can build and install the userspace wg and wg-quick tools.

You can check your kernel version by running the following command:

$ uname -r
4.14.275-207.503.amzn2.aarch64

In the above example, we’re running the old 4.14 kernel version on an ARM (aka aarch64) processor.

To install the WireGuard kernel module, first install the @Development Tools package group, which will install the kernel headers and build tools needed to build the WireGuard module:

$ sudo yum install "@Development Tools"
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Resolving Dependencies
...
Install  25 Packages (+43 Dependent packages)
Upgrade              (  6 Dependent packages)

Total download size: 62 M
Is this ok [y/d/N]: y
...
Complete!

Then download the source code for the WireGuard kernel module on older kernels:

$ git clone https://git.zx2c4.com/wireguard-linux-compat
Cloning into 'wireguard-linux-compat'...
...
Resolving deltas: 100% (6786/6786), done.

On ARM, you have to apply a small patch to the source code: Since the cpu_have_named_feature function the WireGuard source code attempts to define is already defined in arch/arm64/include/asm/cpufeature.h under the Amazon Linux 2 version of the kernel source tree, you have to patch the code to skip this redefinition. Create a cpu_have_named_feature.patch file with the following content:

diff --git a/src/compat/compat.h b/src/compat/compat.h
index 36e902b..4bd782f 100644
--- a/src/compat/compat.h
+++ b/src/compat/compat.h
@@ -864,7 +864,7 @@ static inline void skb_mark_not_on_list(struct sk_buff *skb)
 #define COMPAT_CANNOT_INDIVIDUAL_NETLINK_OPS_POLICY
 #endif

-#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) && defined(__aarch64__)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) && defined(__aarch64__) && !defined(cpu_have_named_feature)
 #define cpu_have_named_feature(name) (elf_hwcap & (HWCAP_ ## name))
 #endif

And then apply this patch to the WireGuard source code with the following command:

$ patch -d wireguard-linux-compat -p 1 < cpu_have_named_feature.patch
patching file src/compat/compat.h

Once you’ve applied this patch, run the following command to build the WireGuard kernel module:

$ make -C wireguard-linux-compat/src -j$(nproc)
make: Entering directory `/home/ec2-user/wireguard-linux-compat/src'
  CC [M]  /home/ec2-user/wireguard-linux-compat/src/main.o
  ...
  LD [M]  /home/ec2-user/wireguard-linux-compat/src/wireguard.ko
make: Leaving directory `/home/ec2-user/wireguard-linux-compat/src'
Tip

If you see an error like the following, you didn’t apply the above patch correctly:

In file included from <command-line>:0:0:
/home/ec2-user/wireguard-linux-compat/src/compat/compat.h:868:0: warning: "cpu_have_named_feature" redefined
 #define cpu_have_named_feature(name) (elf_hwcap & (HWCAP_ ## name))

In file included from ./arch/arm64/include/asm/archrandom.h:8:0,
                 from ./include/linux/random.h:118,
                 from /home/ec2-user/wireguard-linux-compat/src/compat/compat.h:327,
                 from <command-line>:0:
./arch/arm64/include/asm/cpufeature.h:346:0: note: this is the location of the previous definition
 #define cpu_have_named_feature(name) cpu_have_feature(cpu_feature(name))

In file included from <command-line>:0:0:
/home/ec2-user/wireguard-linux-compat/src/crypto/zinc/poly1305/poly1305-arm-glue.c: In function ‘poly1305_fpu_init’:
/home/ec2-user/wireguard-linux-compat/src/compat/compat.h:868:39: error: ‘elf_hwcap’ undeclared (first use in this function); did you mean ‘cpu_hwcaps’?
 #define cpu_have_named_feature(name) (elf_hwcap & (HWCAP_ ## name))
                                       ^
/home/ec2-user/wireguard-linux-compat/src/crypto/zinc/poly1305/poly1305-arm-glue.c:23:22: note: in expansion of macro ‘cpu_have_named_feature’
  poly1305_use_neon = cpu_have_named_feature(ASIMD);
                      ^~~~~~~~~~~~~~~~~~~~~~
/home/ec2-user/wireguard-linux-compat/src/compat/compat.h:868:39: note: each undeclared identifier is reported only once for each function it appears in
 #define cpu_have_named_feature(name) (elf_hwcap & (HWCAP_ ## name))
                                       ^
/home/ec2-user/wireguard-linux-compat/src/crypto/zinc/poly1305/poly1305-arm-glue.c:23:22: note: in expansion of macro ‘cpu_have_named_feature’
  poly1305_use_neon = cpu_have_named_feature(ASIMD);
Tip

If you see an error like the following, your kernel source code (installed via the @Development Tools package group above) doesn’t match the version of the kernel you’re currently running:

make: Entering an unknown directory
make: *** /lib/modules/4.14.273-207.502.amzn2.aarch64/build: No such file or directory.  Stop.
make: Leaving an unknown directory
make: *** [module] Error 2

Usually the solution to this is simply to install the available package updates (which should include the kernel package), reboot the system, and try building the WireGuard kernel module again:

$ uname -r
4.14.273-207.502.amzn2.aarch64

$ sudo yum upgrade
Loaded plugins: priorities, update-motd
Resolving Dependencies
...
Install   5 Packages
Upgrade  21 Packages

Total download size: 48 M
Is this ok [y/d/N]: y
...
Complete!

$ sudo reboot
Shared connection to 203.0.113.2 closed.
...

$ uname -r
4.14.275-207.503.amzn2.aarch64

$ make -C wireguard-linux-compat/src -j$(nproc)
make: Entering directory `/home/ec2-user/wireguard-linux-compat/src'
  CC [M]  /home/ec2-user/wireguard-linux-compat/src/main.o
  ...
  LD [M]  /home/ec2-user/wireguard-linux-compat/src/wireguard.ko
make: Leaving directory `/home/ec2-user/wireguard-linux-compat/src'

If you don’t see any errors, install the newly-built WireGuard kernel module with the following command:

$ sudo make -C wireguard-linux-compat/src install
make: Entering directory `/home/ec2-user/wireguard-linux-compat/src'
  INSTALL /home/ec2-user/wireguard-linux-compat/src/wireguard.ko
At main.c:160:
- SSL error:02001002:system library:fopen:No such file or directory: bss_file.c:175
- SSL error:2006D080:BIO routines:BIO_new_file:no such file: bss_file.c:182
sign-file: certs/signing_key.pem: No such file or directory
  DEPMOD  4.14.275-207.503.amzn2.aarch64
depmod -b "/" -a 4.14.275-207.503.amzn2.aarch64
make: Leaving directory `/home/ec2-user/wireguard-linux-compat/src'

The module has been installed correctly if you can run the following command without errors:

$ sudo modprobe wireguard

With the WireGuard kernel module installed, you can now install the userspace WireGuard tools. Download the source code for it:

$ git clone https://git.zx2c4.com/wireguard-tools
Cloning into 'wireguard-tools'...
...
Resolving deltas: 100% (2088/2088), done.

Then build the userspace WireGuard tools:

$ make -C wireguard-tools/src -j$(nproc)
make: Entering directory `/home/ec2-user/wireguard-tools/src'
  CC      wg.o
  ...
  LD      wg
make: Leaving directory `/home/ec2-user/wireguard-tools/src'

And install the tools:

$ sudo make -C wireguard-tools/src install
make: Entering directory `/home/ec2-user/wireguard-tools/src'
‘wg’ -> ‘/usr/bin/wg’
...
‘systemd/wg-quick.target’ -> ‘/usr/lib/systemd/system/wg-quick.target’
make: Leaving directory `/home/ec2-user/wireguard-tools/src'

The tools have been installed correctly if you can run the following command without errors:

$ sudo wg

At this point, WireGuard has been fully installed on your system, and is ready to go!

Note

You will have to re-run the WireGuard kernel module build and installation steps every time you upgrade your Linux kernel:

$ uname -r
4.14.273-207.502.amzn2.aarch64

$ sudo yum update kernel
Loaded plugins: priorities, update-motd, upgrade-helper
Resolving Dependencies
...
Install  1 Package

Total download size: 21 M
Installed size: 102 M
Is this ok [y/d/N]: y
...
Installed:
  kernel.x86_64 0:4.14.275-207.503.amzn2

Complete!

$ sudo reboot
Shared connection to 203.0.113.2 closed.
...

$ uname -r
4.14.275-207.503.amzn2.aarch64

$ make -C wireguard-linux-compat/src -j$(nproc)
make: Entering directory `/home/ec2-user/wireguard-linux-compat/src'
  CC [M]  /home/ec2-user/wireguard-linux-compat/src/main.o
  ...
  LD [M]  /home/ec2-user/wireguard-linux-compat/src/wireguard.ko
make: Leaving directory `/home/ec2-user/wireguard-linux-compat/src'

$ sudo make -C wireguard-linux-compat/src install
make: Entering directory `/home/ec2-user/wireguard-linux-compat/src'
  INSTALL /home/ec2-user/wireguard-linux-compat/src/wireguard.ko
  ...
  DEPMOD  4.14.275-207.503.amzn2.aarch64
depmod -b "/" -a 4.14.275-207.503.amzn2.aarch64
make: Leaving directory `/home/ec2-user/wireguard-linux-compat/src'

If you upgrade your kernel routinely, you may want to set this up to run under DKMS.

Newer Kernel

With the new kernel (like any kernel version 5.6 or newer), you only have to build and install the userspace wg and wg-quick tools.

You can check your kernel version by running the following command:

$ uname -r
5.10.109-104.500.amzn2.aarch64

In the above example, we’re running the new 5.10 kernel version on an ARM (aka aarch64) processor.

To install the WireGuard userspace tools, first install the basic tools needed to get the source code and build it:

$ sudo yum install gcc git make
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Package 1:make-3.82-24.amzn2.aarch64 already installed and latest version
Resolving Dependencies
...
Install  2 Packages (+18 Dependent packages)
Upgrade             (  2 Dependent packages)

Total download size: 44 M
Is this ok [y/d/N]: y
...
Complete!

Then download the source code for the userspace WireGuard tools:

$ git clone https://git.zx2c4.com/wireguard-tools
Cloning into 'wireguard-tools'...
...
Resolving deltas: 100% (2088/2088), done.

And build the userspace WireGuard tools:

$ make -C wireguard-tools/src -j$(nproc)
make: Entering directory `/home/ec2-user/wireguard-tools/src'
  CC      wg.o
  ...
  LD      wg
make: Leaving directory `/home/ec2-user/wireguard-tools/src'

Then install them:

$ sudo make -C wireguard-tools/src install
make: Entering directory `/home/ec2-user/wireguard-tools/src'
‘wg’ -> ‘/usr/bin/wg’
...
‘systemd/wg-quick.target’ -> ‘/usr/lib/systemd/system/wg-quick.target’
make: Leaving directory `/home/ec2-user/wireguard-tools/src'

The tools have been installed correctly if you can run the following command without errors:

$ sudo wg

At this point, WireGuard has been fully installed on your system, and is ready to go!

Amazon Linux 2022

Amazon Linux 2022 is based on Fedora 35 (Fedora 34 for the preview release), plus it includes a number of updates and AWS-specific customizations. Since the earliest versions of Amazon Linux 2022 use the Linux kernel version 5.10, you can safely expect that all versions of Amazon Linux 2022 will natively include the WireGuard kernel module.

So with Amazon Linux 2022, you only have to build and install the userspace wg and wg-quick tools. To install these WireGuard userspace tools, first install the basic tools needed to get the source code and build it:

$ sudo dnf install gcc git make
Last metadata expiration check: 0:00:56 ago on Thu 28 Apr 2022 10:30:54 PM UTC.
Dependencies resolved.
...
Install  6 Packages

Total download size: 6.1 M
Installed size: 32 M
Is this ok [y/N]: y
...
Complete!

Then download the source code for the userspace WireGuard tools:

$ git clone https://git.zx2c4.com/wireguard-tools
Cloning into 'wireguard-tools'...
...
Resolving deltas: 100% (2088/2088), done.

And build the userspace WireGuard tools:

$ make -C wireguard-tools/src -j$(nproc)
make: Entering directory `/home/ec2-user/wireguard-tools/src'
  CC      wg.o
  ...
  LD      wg
make: Leaving directory `/home/ec2-user/wireguard-tools/src'

Then install them:

$ sudo make -C wireguard-tools/src install
make: Entering directory `/home/ec2-user/wireguard-tools/src'
‘wg’ -> ‘/usr/bin/wg’
...
‘systemd/wg-quick.target’ -> ‘/usr/lib/systemd/system/wg-quick.target’
make: Leaving directory `/home/ec2-user/wireguard-tools/src'

The tools have been installed correctly if you can run the following command without errors:

$ sudo wg

At this point, WireGuard has been fully installed on your system, and is ready to go!