import { Callout } from 'nextra/components'; import { Steps } from 'nextra/components'; import { Tabs } from 'nextra/components'; import { MyTab } from 'components/generic-tabs.tsx'; import { AccordionTemplate } from 'components/accordion-template.tsx'; import NTMExplanation from 'components/operators/snippets/ntm-accordion-explanation.mdx'; ## Security Patch: `CopyFail` & `DirtyFrag` In spring 2026 two critical Linux kernel vulnerabilities had been disclosed. Both allow any local user or process to gain root access on the machine - no special permissions needed. **What is exposed?** An attacker (or any compromised process) can take full control of the machine: read or exfiltrate everything, modify files, install backdoors, or escape containers onto the host. **Security patch required! Follow these steps to patch the vulnerability as soon as possible!** **CVEs covered** | CVE | Name | Affected module | |---|---|---| | `CVE-2026-31431` | `CopyFail` | `algif_aead` | | `CVE-2026-43284` | `DirtyFrag` | `esp4`, `esp6` | | `CVE-2026-43500` | `DirtyFrag` | `rxrpc` |
Directly on the hosting server, Using Ansible, ]} defaultIndex="0"> **This guide is written from root perspective, please add `sudo` to your commands if you are non-root user.** ###### 1. Check if mitigations are already applied Many hosting providers already applied these mitigations automatically via `unattended-upgrades`. Run these checks first: ```sh cat /etc/modprobe.d/disable-algif_aead.conf 2>/dev/null && echo "Already mitigated" || echo "Not yet mitigated" cat /etc/modprobe.d/dirtyfrag.conf 2>/dev/null && echo "Already mitigated" || echo "Not yet mitigated" ``` Compare your output to this table: | Check | Safe output | Action if not safe | |---|---|---| | `disable-algif_aead.conf` | `Already mitigated` | Go to [Step 2](#2-apply-the-interim-mitigation---disable-algif_aead) | | `dirtyfrag.conf` | `Already mitigated` | Go to [Step 3](#3-apply-the-interim-mitigation---disable-esp4-esp6-and-rxrpc) | If both checks are `Already mitigated` - **you are done, no further action needed.** ###### 2. Apply the interim mitigation - disable `algif_aead` The fastest fix on Debian/Ubuntu is to update the `kmod` package - this is how [providers applied it](https://ubuntu.com/blog/copy-fail-vulnerability-fixes-available) automatically and avoids a reboot: ```sh apt update && apt install --only-upgrade kmod rmmod algif_aead 2>/dev/null || true ``` - Alternatively, apply manually: ```sh echo "install algif_aead /bin/false" | tee /etc/modprobe.d/disable-algif_aead.conf rmmod algif_aead 2>/dev/null || true ``` - Drop page cache to clear any contamination: ```sh echo 3 > /proc/sys/vm/drop_caches ``` No reboot is required unless the module was already in active use by a running process. The `rmmod` command above unloads it live. **RHEL, AlmaLinux, Rocky, CentOS** only: this module is baked into the kernel on these distros - the command above does nothing. You must wait for a patched kernel from your distro and apply it when available. Continue to [Step 4](#4-restore-gateway-egress-routing--wireguard-functionality). ###### 3. Apply the interim mitigation - disable `esp4`, `esp6`, and `rxrpc` ```sh sh -c "printf 'install esp4 /bin/false\ninstall esp6 /bin/false\ninstall rxrpc /bin/false\n' > /etc/modprobe.d/dirtyfrag.conf" rmmod esp4 esp6 rxrpc 2>/dev/null || true ``` - Drop page cache to clear any contamination: ```sh echo 3 > /proc/sys/vm/drop_caches ``` Continue to [Step 4](#4-restore-gateway-egress-routing--wireguard-functionality). ###### 4. Restore Gateway egress routing & WireGuard functionality This step applies only to Gateway nodes. Skip this step for Mixnodes. If your server was rebooted for any reason, all iptables rules including NAT, forwarding rules, and the `NYM-EXIT` chain are dropped. Unless `iptables-persistent` was already configured, these rules are gone. - Run the [Nym network tunnel manager](https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/network-tunnel-manager.sh) (NTM) to restore and persist everything. NTM will also install `iptables-persistent` if not already present, ensuring rules survive future reboots: ```sh curl -L "https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/network-tunnel-manager.sh" -o network-tunnel-manager.sh ``` - Run NTM (Standard SSH on port 22 (default)): ```sh chmod +x ./network-tunnel-manager.sh && ./network-tunnel-manager.sh complete_networking_configuration ``` - NTM on non-standart SSH port (replace `2222` with your actual port): ```sh chmod +x ./network-tunnel-manager.sh && HOST_SSH_PORT=2222 ./network-tunnel-manager.sh complete_networking_configuration ``` ###### 5. Verify egress routing & WireGuard functionality There are a few ways to check that your WireGuard is working correctly: - Connect to your node in NymVPN as an exit node in the *Fast* mode, if you rebooted it may take up to one hour for the node to be working properly again - Verify WireGuard handshakes are resuming inside the node: ```sh watch -n 5 'wg show all | grep -E "peer|latest handshake|transfer"' ``` Within 60–90 seconds you should see `latest handshake: X seconds ago` timestamps appearing next to active peers and transfer bytes incrementing. Press `Ctrl+C` to exit the watch loop. If you are using Ansible you can use this playbook [mitigate_kernel_CVE.yml](https://github.com/nymtech/nym/tree/develop/ansible/nym-node/playbooks/mitigate_kernel_CVE.yml). ###### 1. Create new playbook - Navigate to your Nym node Ansible directory with all playbooks (`/playbooks`) - You can double check that you are in the right place, running `ls` command and checking this output: ``` ansible.cfg bond.yml deploy.yml group_vars inventory system-maintenance.yml upgrade.yml ``` - Download the playbook ```sh curl -o mitigate_kernel_CVE.yml -L https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/ansible/nym-node/playbooks/mitigate_kernel_CVE.yml ``` - To control, run `ls` again ``` ansible.cfg bond.yml deploy.yml group_vars inventory mitigate_kernel_CVE.yml system-maintenance.yml upgrade.yml ``` ###### 2. Run playbook `mitigate_kernel_CVE.yml` - For safety start only with one node: ```sh ansible-playbook mitigate_kernel_CVE.yml -l node1 ``` - Check if everything worked smooth on the node machine - Run on all machines in your inventory ```sh ansible-playbook mitigate_kernel_CVE.yml ``` ###### 3. Ensure routing & WireGuard functionality This step applies only to Gateway nodes. Skip this step for Mixnodes. In case your hosting servers rebooted all iptables rules including NAT, forwarding rules, and the `NYM-EXIT` chain, are dropped. Unless `iptables-persistent` was already configured before the reboot, these rules are gone. - Run the [Nym network tunnel manager](https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/network-tunnel-manager.sh) (NTM) to restore and persist everything, using Ansible playbook `deploy.yml` pointing to the correct role: - For safety start only with one node: ```sh ansible-playbook deploy.yml -t ntm -l node1 ``` - Check if everything worked smooth on the node machine - Run on all machines in your inventory ```sh ansible-playbook deploy.yml -t ntm ``` ###### 4. Verify egress routing & WireGuard functionality - Connect to your node in NymVPN as an exit node in the *Fast* mode, it may take up to one hour for the node to be working properly again In case something doesn't work fine, please check the manual steps and [troubleshooting steps](#troubleshooting-wireguard-handshake-fails-after-patching) below
### Troubleshooting: WireGuard handshake fails after patching If after completing all steps above WireGuard peers are still not handshaking and you can't connect to your node via NymVPN, work through this checklist: ###### 1. Confirm blacklists are in place ```sh cat /etc/modprobe.d/disable-algif_aead.conf 2>/dev/null && echo "algif_aead: mitigated" || echo "algif_aead: NOT mitigated" cat /etc/modprobe.d/dirtyfrag.conf 2>/dev/null && echo "dirtyfrag: mitigated" || echo "dirtyfrag: NOT mitigated" ``` - Both files must exist - these are what prevent the modules from loading on demand or after reboot - If either is missing, return to [Step 2](#2-apply-the-interim-mitigation---disable-algif_aead) or [Step 3](#3-apply-the-interim-mitigation---disable-esp4-esp6-and-rxrpc) and apply the missing mitigation ###### 2. Check for stale xfrm state ```sh ip xfrm policy list && ip xfrm state list ``` - If either returns entries, flush them — WireGuard does not use xfrm and stale entries can intercept handshake packets: ```sh ip xfrm state flush && ip xfrm policy flush ``` ###### 3. Confirm the `nymwg` interface is up ```sh ip addr show type wireguard ``` - If absent, restart the `nym-node service`: ```sh systemctl restart nym-node ``` ###### 4. Check iptables forwarding rules are present ```sh iptables -L FORWARD -n -v | grep -E 'nymwg|nymtun' iptables -L NYM-EXIT -n | head -10 ``` - If the `NYM-EXIT` chain is missing or `FORWARD` has no entries for `nymwg`, re-run [Step 4](#4-restore-gateway-egress-routing--wireguard-functionality). ###### 5. Confirm IP forwarding is enabled ```sh sysctl net.ipv4.ip_forward net.ipv6.conf.all.forwarding ``` - Both should return `= 1`. If not: `sysctl -w net.ipv4.ip_forward=1 && sysctl -w net.ipv6.conf.all.forwarding=1` ###### 6. Watch for live handshake packets - Install tcpdump if missing ```sh apt install tcpdump -y # Debian/Ubuntu dnf install tcpdump -y # RHEL family # replace with your actual WG port from: ss -ulnp | grep nym-node tcpdump -ni any udp port 51264 ``` Trigger a connection attempt from a client. If you see packets arriving but WireGuard is not responding, check `journalctl -u nym-node -n 100` for errors from the binary itself.