Tools: How To Set Up WireGuard on Rocky Linux 8

Tools: How To Set Up WireGuard on Rocky Linux 8

Source: DigitalOcean

By Jamon Camisso and Vinayak Baranwal WireGuard is a lightweight Virtual Private Network (VPN) that supports IPv4 and IPv6 connections. A VPN allows you to traverse untrusted networks as if you were on a private network. It gives you the freedom to access the internet safely and securely from your smartphone or laptop when connected to an untrusted network, like the WiFi at a hotel or coffee shop. WireGuard’s encryption relies on public and private keys for peers to establish an encrypted tunnel between themselves. Each version of WireGuard uses a specific cryptographic cipher suite to ensure simplicity, security, and compatibility with peers. In comparison, other VPN software such as OpenVPN and IPSec use Transport Layer Security (TLS) and certificates to authenticate and establish encrypted tunnels between systems. Different versions of TLS include support for hundreds of different cryptographic suites and algorithms, and while this allows for great flexibility to support different clients, it also makes configuring a VPN that uses TLS more time consuming, complex, and error prone. This tutorial sets up WireGuard on a Rocky Linux 8 server and configures another machine as a peer using both IPv4 and IPv6 (a dual stack connection). You will also route the peer’s internet traffic through the WireGuard server in a gateway configuration, in addition to using the VPN for an encrypted peer-to-peer tunnel. For the purposes of this tutorial, we configure another Rocky Linux 8 system as the peer (also referred to as client) to the WireGuard Server. Subsequent tutorials in this series explain how to install and run WireGuard on Windows, macOS, Android, and iOS. Note: If you plan to set up WireGuard on a DigitalOcean Droplet, be aware that we, like many hosting providers, charge for bandwidth overages. For this reason, please be mindful of how much traffic your server is handling.
See Bandwidth Billing Documentation for more info. To follow this tutorial, you will need: SELinux: Rocky Linux 8 runs with SELinux in enforcing mode by default. If WireGuard fails after a correct config, see Troubleshooting WireGuard on Rocky Linux 8 (SELinux section). This tutorial configures a road-warrior (client-to-server) setup: one or more mobile or remote clients connect to a single WireGuard server. Traffic is encrypted between each peer and the server; the server can act as a gateway for peer internet traffic (NAT masquerading). In a site-to-site setup, two or more fixed sites (e.g., office and datacenter) connect as peers. Each side has a WireGuard interface and knows the other’s public key and endpoint. Use site-to-site when you need direct, encrypted links between networks rather than remote users connecting to one server. Configuration differences: each peer’s AllowedIPs includes the other site’s LAN ranges (not 0.0.0.0/0 for default routing), you typically do not enable NAT masquerading on the peer side for that tunnel, and peers behind NAT often need PersistentKeepalive so the connection stays discoverable. The steps in this guide (keys, firewall, IP forwarding, systemd) still apply; only the peer configuration and firewall rules differ. WireGuard must be installed from ELRepo and EPEL before the kernel module and tools are available, because Rocky Linux 8 does not ship WireGuard in its base repositories. Add the repositories and install the packages. You may be prompted for your sudo password: Install the WireGuard kernel module (kmod-wireguard from ELRepo) and the configuration tools (wireguard-tools from EPEL): You’ll use the built-in wg genkey and wg pubkey commands to create the keys, and then add the private key to WireGuard’s configuration file. You will also need to change the permissions on the key that you just created using the chmod command, since by default the file is readable by any user on your server. Create the private key for WireGuard and change its permissions using the following commands: Your key will be a different 44-character base64 string. If the output is blank or shows an error, do not proceed — the key file was not written correctly. Restricting the private key with chmod go= matters because any process that can read the key can impersonate the server or peer; keeping it root-only limits exposure if another service is compromised. The next step is to create the corresponding public key, which is derived from the private key. Use the following command to create the public key file: Your public key will be a different 44-character base64 string. If the output is blank or shows an error, do not proceed — the key file was not written correctly. This command consists of three individual commands that are chained together using the | (pipe) operator: Private IPv4 and IPv6 ranges must be chosen for the tunnel interfaces before you create the server config, because each peer and the server need unique addresses in a dedicated range. If you plan to use both IPv4 and IPv6, follow both sub-sections below. Otherwise, follow the instructions in the appropriate section for your VPN’s network needs. The server needs a private IPv4 range for its tunnel interface and for peers, because WireGuard assigns one address from this range to each side. You can choose any range of IP addresses from the following reserved blocks of addresses (if you would like to learn more about how these blocks are allocated visit the RFC 1918 specification): For the purposes of this tutorial we’ll use 10.8.0.0/24 as a block of IP addresses from the first range of reserved IPs. This range will allow up to 255 different peer connections, and generally should not have overlapping or conflicting addresses with other private IP ranges. Feel free to choose a range of addresses that works with your network configuration if this example range isn’t compatible with your networks. The WireGuard Server will use a single IP address from the range for its private tunnel IPv4 address. We’ll use 10.8.0.1/24 here, but any address in the range of 10.8.0.1 to 10.8.0.255 can be used. Make a note of the IP address that you choose if you use something different from 10.8.0.1/24. You will add this IPv4 address to the configuration file that you define in Step 3: Creating a WireGuard Server Configuration. A unique local IPv6 prefix must be generated for the tunnel when using IPv6, because addresses must be in the reserved fd00::/8 block and should not collide with other networks. Use the algorithm in RFC 4193 to generate a random prefix. According to the RFC, the recommended way to obtain a unique IPv6 prefix is to combine the time of day with a unique identifying value from a system like a serial number or device ID. Those values are then hashed and truncated resulting in a set of bits that can be used as a unique address within the reserved private fd00::/8 block of IPs. To get started generating an IPv6 range for your WireGuard Server, collect a 64-bit timestamp using the date utility with the following command: You will receive a number like the following, which is the number of seconds (the %s in the date command), and nanoseconds (the %N) since 1970-01-01 00:00:00 UTC combined together: Record the value somewhere for use later in this section. Next, copy the machine-id value for your server from the /var/lib/dbus/machine-id file. This identifier is unique to your system and should not change for as long as the server exists. You will receive output like the following: Now you need to combine the timestamp with the machine-id and hash the resulting value using the SHA-1 algorithm. The command will use the following format: Run the command substituting in your timestamp and machine identity values: You will receive a hash value like the following: Note that the output of the sha1sum command is in hexadecimal, so the output uses two characters to represent a single byte of data. For example 4f and 26 in the example output are the first two bytes of the hashed data. The algorithm in the RFC only requires the least significant (trailing) 40 bits, or 5 bytes, of the hashed output. Use the cut command to print the last 5 hexadecimal encoded bytes from the hash: The -c argument tells the cut command to select only a specified set of characters. The 31- argument tells cut to print all the characters from position 31 to the end of the input line. You should receive output like the following: In this example output, the set of bytes is: 0d 86 fa c3 bc. Now you can construct your unique IPv6 network prefix by appending the 5 bytes you have generated with the fd prefix, separating every 2 bytes with a : colon for readability. Because each subnet in your unique prefix can hold a total of 18,446,744,073,709,551,616 possible IPv6 addresses, you can restrict the subnet to a standard size of /64 for simplicity. Using the bytes previously generated with the /64 subnet size the resulting prefix will be the following: This fd0d:86fa:c3bc::/64 range is what you will use to assign individual IP addresses to your WireGuard tunnel interfaces on the server and peers. To allocate an IP for the server, add a 1 after the final :: characters. The resulting address will be fd0d:86fa:c3bc::1/64. Peers can use any IP in the range, but typically you’ll increment the value by one each time you add a peer e.g. fd0d:86fa:c3bc::2/64. Make a note of the IP and proceed configuring the WireGuard Server in the next section of this tutorial. A server config file must exist before the WireGuard interface can start, because it defines the private key, tunnel addresses, and listen port. Gather the private key from Step 1, the server IPv4 address from Step 2(a) (e.g. 10.8.0.1/24), and if using IPv6 the server address from Step 2(b) (e.g. fd0d:86fa:c3bc::1/64). Then create the config file: Add the following lines to the file, substituting your private key in place of the highlighted base64_encoded_private_key_goes_here value, and the IP address(es) on the Address line. You can also change the ListenPort line if you would like WireGuard to be available on a different port. Press i to put vi into insertion mode and then add the following lines: SaveConfig = true writes any runtime changes (peers added with wg set, wg addconf, or similar) back to wg0.conf when the interface is brought down. This means that if you manually edit wg0.conf while the interface is running and then bring it down, your edits will be overwritten by the in-memory state. To safely edit the config file with SaveConfig = true in use: bring the interface down first (sudo wg-quick down wg0), make your edits, then bring it back up (sudo wg-quick up wg0). When you are finished making changes, press ESC and then :wq to write the changes to the file and quit. You now have an initial server configuration that you can build upon depending on how you plan to use your WireGuard VPN server. IP forwarding must be enabled on the server when the peer will route internet or other subnet traffic through the VPN, because the kernel otherwise drops forwarded packets. Skip this step if you only need peer-to-server or peer-to-peer access within the VPN. Enable forwarding so the server can route traffic between the WireGuard interface and other interfaces (and the internet). You can add the settings to /etc/sysctl.conf or, preferably, to a drop-in file under /etc/sysctl.d/ (e.g., /etc/sysctl.d/99-wireguard.conf) so they persist across reboots and stay separate from other tuning. Create or edit a sysctl drop-in: If you are using IPv6 with WireGuard, append the IPv6 setting: If you prefer to use /etc/sysctl.conf, add the same lines at the bottom of that file instead. If you use both IPv4 and IPv6, set both parameters. Load the new values for the current session: Firewall rules must allow UDP 51820 and permit forwarding and masquerade for the VPN interface, because otherwise incoming WireGuard traffic or outbound traffic from peers will be dropped. Skip this step if you only need machine-to-machine access within the VPN. This tutorial uses firewall-cmd rather than PostUp and PreDown hooks in the WireGuard config because Rocky Linux 8 uses firewalld as its default firewall manager; firewall-cmd integrates with firewalld zones and persists rules correctly on this system. If you are not using firewalld, you can achieve the same result using PostUp = iptables -A FORWARD -i wg0 -j ACCEPT and matching PreDown rules. Add firewall rules so the WireGuard Server accepts VPN traffic and can forward and masquerade it. Use permanent rules (--permanent) so they persist across reboots; rules without --permanent apply only at runtime and are lost on reload or reboot. For full firewalld setup, see How To Set Up a Firewall Using firewalld on Rocky Linux 8. Run the following to allow access to the WireGuard service on UDP port 51820: Next you will need to add the wg0 device to the internal zone, which will allow traffic on the VPN interface to reach other interfaces on the WireGuard Server. This setting is particularly important if you are using the Server as a VPN gateway for all the Peer’s Internet traffic. If you add more WireGuard tunnels to your server in the future, be sure to add their devices to the internal or trusted zone as well. Run the following to add the wg0 interface to the internal zone: Finally, if you are using the WireGuard Server as a VPN gateway, you will need to add a masquerade rule to the public zone. Masquerading is used to rewrite traffic that comes in on an internal interface (in this case wg0) to make it appear like it originates directly from the WireGuard Server’s public IPv4 or IPv6 addresses. Run the following commands to enable masquerading, substituting in your IPv4 and IPv6 network ranges in place of the highlighted values: Now reload the firewall to make the changes take effect, and to ensure that they are permanent: Note (permanent vs. runtime): Rules added with --permanent are written to disk and apply after firewall-cmd --reload or reboot. Without --permanent, rules apply only in the current session and are lost on reload. If you use a different firewall or custom firewalld zones, you may need additional rules (e.g., port 53 for DNS, 80 and 443 for HTTP/HTTPS when tunneling all traffic). You can now examine the status of the entire public, internal, or other firewall zones to confirm that the rules are in place by running the following command. Substitute in the zone that you would like to examine in place of the highlighted public name: You will receive output like the following: The highlighted values indicate the rule to allow UDP traffic on port 51820 is present, and that masquerading is enabled for any of the listed networks. You can also verify that the internal forwarding rule is in place using the following command: You will receive output like the following if the rule is present: Your WireGuard Server is now configured to correctly handle the VPN’s traffic, including forwarding and masquerading for peers. With the firewall rules in place, you can start the WireGuard service itself to listen for peer connections. The WireGuard interface must be brought up and optionally enabled at boot, because the config file alone does not create the tunnel. Enable the wg-quick@wg0 systemd unit so the WireGuard interface starts at boot. The unit name includes the tunnel name wg0, which corresponds to /etc/wireguard/wg0.conf; you can run multiple tunnels (e.g., wg-quick@wg1) with different configs. The service starts after the network is up; if you need it to wait for full connectivity, add After=network-online.target and Wants=network-online.target in a drop-in (see systemd.unit(5)). The service name wg0 maps to the config file /etc/wireguard/wg0.conf. You can create additional tunnels (e.g., wg1.conf) and enable them with systemctl enable [email protected]. Each tunnel can have different IPv4, IPv6, and firewall settings. Double check that the WireGuard service is active with the following command. You should see active (running) or active (exited) in the output: Notice how the output shows the ip commands that are used to create the virtual wg0 device and assign it the IPv4 and IPv6 addresses that you added to the configuration file. With the server configured and running, the next step is to configure your client machine as a WireGuard Peer and connect to the WireGuard Server. The peer must have WireGuard installed, a key pair, a config file with the server’s public key and endpoint, and a unique tunnel IP, because without these the peer cannot authenticate or route traffic over the VPN. On the WireGuard peer machine, install the package and then create keys and config: The peer must have its own key pair, because the server uses the peer’s public key to authenticate it. Generate the private key and restrict permissions, then derive the public key: Again you will receive a single line of base64 encoded output, which is the private key. A copy of the output is also stored in the /etc/wireguard/private.key. Carefully make a note of the private key that is output since you’ll need to add it to WireGuard’s configuration file later in this section. Next use the following command to create the public key file: You will again receive a single line of base64 encoded output, which is the public key for your WireGuard Peer. Copy it somewhere for reference, since you will need to distribute the public key to the WireGuard Server in order to establish an encrypted connection. A peer config file must specify the peer’s private key, its tunnel address(es), the server’s public key and endpoint, and AllowedIPs, because the peer uses these to connect and to decide which traffic goes over the VPN. Open /etc/wireguard/wg0.conf on the peer: Add the following lines to the file, substituting in the various data into the highlighted sections as required: Notice how the first Address line uses an IPv4 address from the 10.8.0.0/24 subnet that you chose earlier. This IP address can be anything in the subnet as long as it is different from the server’s IP. Incrementing addresses by 1 each time you add a peer is generally the easiest way to allocate IPs. Likewise, notice how the second Address line uses an IPv6 address from the subnet that you generated earlier, and increments the server’s address by one. Again, any IP in the range is valid if you decide to use a different address. The other notable part of the file is the last AllowedIPs line. These two IPv4 and IPv6 ranges instruct the peer to only send traffic over the VPN if the destination system has an IP address in either range. Using the AllowedIPs directive, you can restrict the VPN on the peer to only connect to other peers and services on the VPN, or you can configure the setting to tunnel all traffic over the VPN and use the WireGuard Server as a gateway. Warning: If you set AllowedIPs = 0.0.0.0/0 or ::/0 on a remote peer you access via SSH and skip the steps in this section, the tunnel will route your SSH session through wg0 the moment it comes up. Your existing SSH connection will drop and the server will become unreachable until you access it via an out-of-band method (console, recovery mode). Complete this section before starting the tunnel on any remote peer that uses full-tunnel routing. If you have opted to route all of the peer’s traffic over the tunnel using the 0.0.0.0/0 or ::/0 routes and the peer is a remote system, then you will need to complete the steps in this section. If your peer is a local system then it is best to skip this section. For remote peers that you access via SSH or some other protocol using a public IP address, you will need to add some extra rules to the peer’s wg0.conf file. These rules will ensure that you can still connect to the system from outside of the tunnel when it is connected. Otherwise, when the tunnel is established, all traffic that would normally be handled on the public network interface will not be routed correctly to bypass the wg0 tunnel interface, leading to an inaccessible remote system. First, you’ll need to determine the IP address that the system uses as its default gateway. Run the following ip route command: You will receive output like the following: Note the gateway’s highlighted IP address 203.0.113.1 for later use, and device eth0. Your device name may be different. If so, substitute it in place of eth0 in the following commands. Next find the public IP for the system by examining the device with the ip address show command: You will receive output like the following: In this example output, the highlighted 203.0.113.5 IP (without the trailing /20) is the public address that is assigned to the eth0 device that you’ll need to add to the WireGuard configuration. Now open the WireGuard Peer’s /etc/wireguard/wg0.conf file with vi or your preferred editor. Before the [Peer] line, add the following 4 lines: The PostUp and PreDown hooks run when the tunnel is brought up or down. They create a custom routing rule and route so that traffic from the peer’s public IP (e.g., SSH from the internet) still uses the default gateway instead of the VPN, preventing lockout when the tunnel is active. The PreDown lines remove the custom rule and route when the tunnel is shutdown. Note: The table number 200 is arbitrary when constructing these rules. You can use a value between 2 and 252, or you can use a custom name by adding a label to the /etc/iproute2/rt_tables file and then referring to the name instead of the numeric value. For more information about how routing tables work in Linux visit the Routing Tables Section of the Guide to IP Layer Network Administration with Linux. If you are routing all the peer’s traffic over the VPN, ensure that you have configured the correct sysctl and firewall-cmd rules on the WireGuard Server in Step 4: Adjusting the WireGuard Server’s Network Configuration and Step 5: Configuring the WireGuard Server’s Firewall. If you are using the WireGuard Server as a VPN gateway for all your peer’s traffic, you will need to add a line to the [Interface] section that specifies DNS resolvers. If you do not add this setting, then your DNS requests may not be secured by the VPN, or they might be revealed to your Internet Service Provider or other third parties. If you are only using WireGuard to access resources on the VPN network or in a peer-to-peer configuration then you can skip this section. To add DNS resolvers to your peer’s configuration, first determine which DNS servers your WireGuard Server is using. Run the following command on the WireGuard Server, substituting in your ethernet device name in place of eth0 if it is different from this example: You should receive output like the following: The IP addresses that are output are the DNS resolvers that the server is using. You can choose to use any or all of them, or only IPv4 or IPv6 depending on your needs. Make a note of the resolvers that you will use. Next you will need to add your chosen resolvers to the WireGuard Peer’s configuration file. Back on the WireGuard Peer, open /etc/wireguard/wg0.conf file using vi or your preferred editor: Before the [Peer] line, add the following: Again, depending on your preference or requirements for IPv4 and IPv6, you can edit the list according to your needs. Next, enable and start the systemd-resolved service on the Peer so that when the tunnel is established, the Peer’s DNS resolvers get updated: Reboot the WireGuard Peer now. On Rocky Linux 8 and other RHEL-derived distributions, the /etc/resolv.conf file must be in the correct state before the tunnel starts, and a reboot ensures systemd-resolved and the network stack are fully initialised. Once you are connected to the VPN in the following step, you can check that you are sending DNS queries over the VPN by using a site like DNS leak test.com. You can also check that your peer is using the configured resolvers with the resolvectl dns command like you ran on the server. You should receive output like the following, showing the DNS resolvers that you configured for the VPN tunnel: With all of these DNS resolver settings in place and the peer rebooted, you are now ready to add the peer’s public key to the server, and then start the WireGuard tunnel on the peer. Before connecting the peer to the server, it is important to add the peer’s public key to the WireGuard Server. This step ensures that you will be able to connect to and route traffic over the VPN. Without completing this step the WireGuard server will not allow the peer to send or receive any traffic over the tunnel. Ensure that you have a copy of the base64 encoded public key for the WireGuard Peer by running: Now log into the WireGuard server, and run the following command: Note that the allowed-ips portion of the command takes a comma separated list of IPv4 and IPv6 addresses. You can specify individual IPs if you would like to restrict the IP address that a peer can assign itself, or a range like in the example if your peers can use any IP address in the VPN range. Also note that no two peers can have the same allowed-ips setting. If you would like to update the allowed-ips for an existing peer, you can run the same command again, but change the IP addresses. Multiple IP addresses are supported. For example, to change the WireGuard Peer that you just added to add an IP like 10.8.0.100 to the existing 10.8.0.2 and fd0d:86fa:c3bc::2 IPs, you would run the following: Check the status of the tunnel on the server using the wg command: Notice how the peer line shows the WireGuard Peer’s public key, and the IP addresses, or ranges of addresses that it is allowed to use to assign itself an IP. The peer must bring the tunnel up with wg-quick up wg0 (or start the systemd unit) so that encrypted traffic can flow, because the config file does not start the interface by itself. To connect manually on the peer, run the following. To automate at boot instead, use the same systemd enable/start steps as on the server (see Step 6: Starting the WireGuard Server). You will receive output like the following: Notice the highlighted IPv4 and IPv6 addresses that you assigned to the peer. If you set the AllowedIPs on the peer to 0.0.0.0/0 and ::/0 (or to use ranges other than the ones that you chose for the VPN), then your output will resemble the following: In this example, notice the highlighted routes that the command added, which correspond to the AllowedIPs in the peer configuration. Next, generate some traffic on the tunnel interface by using ping to send a single ICMP packet (indicated by the -c 1 argument in the following commands) to the WireGuard Server: If you are routing all traffic over the VPN, you can use one of CloudFlare’s servers instead: Now check the status of the tunnel on the peer using the wg command: You can also check the status on the server again, and you will receive similar output. Verify that your peer is using the VPN by using the ip route and ip -6 route commands. If you are using the VPN as a gateway for all your Internet traffic, check which interface will be used for traffic destined to CloudFlare’s 1.1.1.1 and 2606:4700:4700::1111 DNS resolvers. If you are only using WireGuard to access resources on the VPN, substitute a valid IPv4 or IPv6 address like the gateway itself into these commands. For example 10.8.0.1 or fd0d:86fa:c3bc::1. Notice the wg0 device is used and the IPv4 address 10.8.0.2 that you assigned to the peer. Likewise, if you are using IPv6, run the following: Again note the wg0 interface, and the IPv6 address fd0d:86fa:c3bc::2 that you assigned to the peer. If your peer has a browser installed, you can also visit ipleak.net to confirm that your peer is routing its traffic over the VPN. Once you are ready to disconnect from the VPN on the peer, use the wg-quick command: You will receive output like the following indicating that the VPN tunnel is shut down: If you set the AllowedIPs on the peer to 0.0.0.0/0 and ::/0 (or to use ranges other than the ones that you chose for the VPN), then your output will resemble the following: To reconnect to the VPN, run the wg-quick up wg0 command again on the peer. If you would like to completely remove a peer’s configuration from the WireGuard Server, you can run the following command, being sure to substitute the correct public key for the peer that you want to remove: Typically you will only need to remove a peer configuration if the peer no longer exists, or if its encryption keys are compromised or changed. Otherwise it is better to leave the configuration in place so that the peer can reconnect to the VPN without requiring that you add its key and allowed-ips each time. Each additional peer needs its own key pair and a unique tunnel IP in your VPN range. Add one [Peer] block per peer on the WireGuard Server. Config file method: Append a new [Peer] block to /etc/wireguard/wg0.conf on the server. Use the peer’s public key and assign a unique AllowedIPs (e.g., 10.8.0.3/32, fd0d:86fa:c3bc::3/128 for the second peer). No two peers may share the same AllowedIPs. Example: Then reload the interface so the new peer is applied: sudo wg-quick down wg0 && sudo wg-quick up wg0, or add the peer at runtime with wg set (below). Live-add method: To add a peer without restarting the interface, use wg set: If SaveConfig = true is set in the server’s [Interface] section, run sudo wg-quick save wg0 (or bring the interface down and up) to write the new peer to the config file. On the second peer machine, create its own /etc/wireguard/wg0.conf with a unique Address (e.g., 10.8.0.3/24, fd0d:86fa:c3bc::3/64) and the server’s PublicKey and Endpoint. Check the server interface: On the server run sudo wg show. You should see the peer’s public key and its allowed ips. If the peer is missing, add it (see Step 8 and Adding Multiple Peers). Handshake successful: Handshake never completed: If latest handshake is missing entirely, the peer has never successfully completed a handshake. This means packets are not reaching the server or the server is not responding. Check the firewall, the peer’s Endpoint address, and the AllowedIPs on both sides. If latest handshake shows a time older than 3 minutes and is not updating, the tunnel was established but has since gone silent — check for routing issues or a NAT timeout. Verify UDP 51820 is reachable: From the peer (or another host), test with nc -vzu <server_public_ip> 51820. If the port is closed, check firewalld: sudo firewall-cmd --zone=public --list-ports should include 51820/udp, and rules must be permanent and reloaded. Check AllowedIPs: The peer’s tunnel IP must fall within the server’s allowed-ips for that peer. Mismatches prevent the handshake from completing. Rocky Linux 8 runs SELinux in enforcing mode by default. If WireGuard starts and the config looks correct but traffic is being silently dropped, check for SELinux denials: If denials appear, the fastest correct fix is to generate a local policy module from the audit log: To verify the module was loaded: To test whether SELinux is the cause without permanently changing policy, temporarily switch to permissive mode, confirm the tunnel works, then return to enforcing and apply the policy module: Do not leave the system in permissive mode in production. Forwarding must be enabled for gateway mode. Check at runtime: If values are 0, load your sysctl config (e.g., sudo sysctl -p /etc/sysctl.d/99-wireguard.conf) or add the settings to /etc/sysctl.d/ and reload. Check the service and logs: If the service fails, common causes are missing or incorrect config (/etc/wireguard/wg0.conf), wrong key or path, or the network not ready. Ensure the unit is enabled: sudo systemctl enable [email protected]. Is WireGuard included by default in Rocky Linux 8?
No. You must install the kernel module and tools from ELRepo and EPEL (kmod-wireguard, wireguard-tools) after adding the elrepo-release and epel-release repositories. What port does WireGuard use?
WireGuard uses UDP. The default port is 51820. You can set a different port with ListenPort in the server’s [Interface] section. Does WireGuard work with firewalld?
Yes. Open UDP 51820 (or your chosen port) in the appropriate zone, add the wg0 interface to an internal or trusted zone, and add masquerade rules if the server is a gateway. Use --permanent and firewall-cmd --reload so rules persist. How do I add multiple peers to WireGuard?
Add a separate [Peer] block for each peer in the server’s config (or use wg set wg0 peer <pubkey> allowed-ips <ips>). Each peer must have a unique key pair and a unique tunnel IP (in AllowedIPs on the server and Address on the peer). How do I restart WireGuard safely?
Run sudo wg-quick down wg0 then sudo wg-quick up wg0 on the server. Or use systemd: sudo systemctl restart [email protected]. Restarting drops active peer sessions until they reconnect. Why is my WireGuard peer not connecting?
Common causes: UDP port 51820 not open on the server firewall, peer not added on the server or wrong allowed-ips, wrong peer Endpoint or PublicKey, or SELinux blocking. Check wg show, firewall rules, and ausearch for SELinux denials. How do I enable WireGuard at boot?
Run sudo systemctl enable [email protected]. The service starts after boot; ensure the config file and keys are in place before the first boot where you rely on it. How do I check WireGuard status?
Run sudo wg show (or sudo wg) to see interfaces and peers, handshakes, and traffic. Use sudo systemctl status [email protected] to see whether the service is active. Can I use WireGuard for site-to-site VPN?
Yes. Configure each site with a WireGuard interface, the other site’s public key and endpoint, and set AllowedIPs to the other site’s LAN ranges. Do not use NAT masquerading for that tunnel on the peer side; use PersistentKeepalive if a peer is behind NAT. Does SELinux block WireGuard traffic?
It can. Rocky Linux 8 has SELinux enforcing by default. If WireGuard fails, check with ausearch -c wg-quick -m avc. Fix by adjusting SELinux booleans or policy; avoid leaving the system in permissive mode. In this tutorial you installed WireGuard (kernel module and tools) on Rocky Linux 8, configured a dual-stack road-warrior server and peer, set up firewall rules and IP forwarding, and enabled the service at boot. You generated key pairs, restricted private key permissions, and optionally used the server as a VPN gateway. A production-ready deployment goes beyond this guide: rotate keys periodically, monitor peers with wg show, and consider restricting peer access (e.g., by source IP or firewall rules). For automation, you can use How To Install and Configure Ansible on Rocky Linux 8 to manage configs and keys across servers. For more on WireGuard (advanced tunnels, containers), see the official WireGuard documentation. Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases. Learn more about our products Building future-ready infrastructure with Linux, Cloud, and DevOps. Full Stack Developer & System Administrator. Technical Writer @ DigitalOcean | GitHub Contributor | Passionate about Docker, PostgreSQL, and Open Source | Exploring NLP & AI-TensorFlow | Nailed over 50+ deployments across production environments. This textbox defaults to using Markdown to format your answer. You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link! Please complete your information! Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation. Full documentation for every DigitalOcean product. The Wave has everything you need to know about building a business, from raising funding to marketing your product. Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter. New accounts only. By submitting your email you agree to our Privacy Policy Scale up as you grow — whether you're running one virtual machine or ten thousand. Sign up and get $200 in credit for your first 60 days with DigitalOcean.* *This promotional offer applies to new accounts only.