{"id":25461,"date":"2025-10-20T07:57:52","date_gmt":"2025-10-20T05:57:52","guid":{"rendered":"https:\/\/contabo.com\/blog\/?p=25461"},"modified":"2025-10-20T07:57:58","modified_gmt":"2025-10-20T05:57:58","slug":"hardening-your-wireguard-security-a-comprehensive-guide","status":"publish","type":"post","link":"https:\/\/contabo.com\/blog\/hardening-your-wireguard-security-a-comprehensive-guide\/","title":{"rendered":"Hardening Your WireGuard Security: A Comprehensive Guide"},"content":{"rendered":"\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"630\" src=\"https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/blog-head_hardening-your-wireguard-security-guide_EN.webp\" alt=\"Hardening Your WireGuard Security: A Comprehensive Guide (Header image)\" class=\"wp-image-25466\" srcset=\"https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/blog-head_hardening-your-wireguard-security-guide_EN.webp 1200w, https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/blog-head_hardening-your-wireguard-security-guide_EN-600x315.webp 600w, https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/blog-head_hardening-your-wireguard-security-guide_EN-768x403.webp 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/figure>\n\n\n\n<p>WireGuard performance and security don\u2019t have to compete. This guide shows how to harden a WireGuard VPS &#8211; understanding what the protocol secures (and what it doesn\u2019t), locking down the host, adding a pre-shared key, preventing private-key leaks, and enforcing practical, interface-aware firewall rules &#8211; all while preserving speed. Each step is minimal, measured, and easy to verify so your tunnels stay fast and safe.&nbsp;<\/p>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-005ed9a8\"><h2 class=\"uagb-heading-text\">Understanding WireGuard&#8217;s Inherent Security&nbsp;<\/h2><\/div>\n\n\n\n<p>WireGuard security is strong by design: a small, opinionated protocol that fixes its cryptography and minimizes complexity. Instead of configurable cipher suites, WireGuard uses a modern, audited cryptographic stack &#8211; a Noise-based handshake with Curve25519, ChaCha20-Poly1305, BLAKE2s, SipHash24 and HKDF. On Linux, it runs in kernel space, keeping the data path efficient and predictable.&nbsp;<\/p>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-62c3fdaa\"><h3 class=\"uagb-heading-text\">What WireGuard Protects by Default&nbsp;<\/h3><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Strong peer authentication<\/strong>: Each peer is identified by a public key. Packets from unknown keys are dropped immediately &#8211; no usernames, certificate chains, or complex negotiations.&nbsp;<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Complete data protection<\/strong>: All traffic is encrypted and authenticated using modern AEAD cryptography. Tampered or corrupted packets never reach your applications.&nbsp;<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Perfect forward secrecy<\/strong>: Session keys rotate automatically during brief handshakes, limiting damage if a session key is later compromised. Past communications remain secure even if current keys leak.&nbsp;<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Network mobility support<\/strong>: Endpoints can change IP addresses (mobile networks, failover scenarios) without reconfiguring peers. The cryptographic identity remains constant while network details adapt.&nbsp;<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Minimal attack surface<\/strong>: Approximately 4,000 lines of code reduce parsing complexity, configuration errors, and edge cases that attackers typically exploit.&nbsp;<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-89a37968\"><h3 class=\"uagb-heading-text\">What WireGuard Cannot Solve Alone&nbsp;<\/h3><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Traffic pattern visibility<\/strong>: WireGuard doesn&#8217;t hide its traffic characteristics. Network monitors can identify WireGuard connections by their UDP packet patterns and timing analysis.&nbsp;<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Identity exposure in handshakes<\/strong>: While data packets have forward secrecy, handshakes can reveal connection initiators if private keys are later compromised along with traffic logs.&nbsp;<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Host-level security<\/strong>: If your server or client is compromised, the tunnel security is also compromised. Operating system hardening and proper key management remain essential.&nbsp;<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Post-quantum cryptography<\/strong>: WireGuard&#8217;s current cryptography isn&#8217;t quantum-resistant by default, though pre-shared keys can provide additional post-quantum protection.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>For additional technical limitations and potential mitigations, see the <a href=\"https:\/\/www.wireguard.com\/known-limitations\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">official WireGuard known limitations documentation<\/a>.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"980\" height=\"451\" src=\"https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/wireguard-security-setup_EN.webp\" alt=\"Your WireGuard security setup\" class=\"wp-image-25538\" srcset=\"https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/wireguard-security-setup_EN.webp 980w, https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/wireguard-security-setup_EN-600x276.webp 600w, https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/wireguard-security-setup_EN-768x353.webp 768w\" sizes=\"auto, (max-width: 980px) 100vw, 980px\" \/><\/figure>\n\n\n\n<p>In general, you can think of WireGuard as a secure tunnel guard: it authenticates peers and protects packets with modern cryptography while remaining simple enough for thorough security auditing. Your responsibility is pairing it with a hardened host system, disciplined key management practices, and precise firewall policies. This combination preserves WireGuard&#8217;s performance advantages while closing the practical security gaps that real-world attackers actually exploit.&nbsp;<\/p>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-a6c23621\"><h2 class=\"uagb-heading-text\">The Crucial Step: Securing Your WireGuard VPS Host&nbsp;<\/h2><\/div>\n\n\n\n<p>To secure WireGuard effectively, start with the underlying host system. Even the strongest VPN protocol fails if the server itself is compromised.&nbsp;<\/p>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-a895d5ef\"><h3 class=\"uagb-heading-text\">Essential System Security<\/h3><\/div>\n\n\n\n<p>Keep your system updated and minimal:&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update &amp;&amp; sudo apt upgrade -y&nbsp;\n\nsudo apt autoremove -y&nbsp;\n\nsudo apt install unattended-upgrades -y&nbsp; # Enables automatic security updates&nbsp;<\/code><\/pre>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-e9e93405\"><h3 class=\"uagb-heading-text\">SSH Hardening&nbsp;<\/h3><\/div>\n\n\n\n<p>Secure your primary attack surface before installing WireGuard:&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Backup the initial SSH configuration&nbsp;\nsudo cp \/etc\/ssh\/sshd_config \/etc\/ssh\/sshd_config.backup&nbsp;\n\n# Edit the SSH configuration&nbsp;\nSudo nano \/etc\/ssh\/sshd_config&nbsp;\n\n# Disable root login, password authentication (use keys only) and change default port&nbsp;\nPermitRootLogin no&nbsp;\nPasswordAuthentication no&nbsp;\nPubkeyAuthentication yes&nbsp;\nChallengeResponseAuthentication no&nbsp;\n\n# Limit the users who can access the SSH&nbsp;\nAllowUsers yourusername&nbsp;\n\n# Test SSH configuration syntax&nbsp;\nsudo sshd -t&nbsp;\n\n# If no errors, restart SSH&nbsp;\nsudo systemctl restart sshd&nbsp;<\/code><\/pre>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-97a145b8\"><h3 class=\"uagb-heading-text\">WireGuard Key Security&nbsp;<\/h3><\/div>\n\n\n\n<p>Generate keys with proper permissions:&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>umask 077&nbsp;<br><br>wg genkey | sudo tee \/etc\/wireguard\/privatekey | wg pubkey | sudo tee \/etc\/wireguard\/publickey&nbsp;<br><br>sudo chmod 600 \/etc\/wireguard\/privatekey&nbsp;<\/code><\/pre>\n\n\n\n<p>Critical: Never store private keys in repositories or share via insecure channels.<\/p>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-9333bdec\"><h3 class=\"uagb-heading-text\"><strong>Basic Firewall Protection<\/strong>&nbsp;<\/h3><\/div>\n\n\n\n<p><strong>Recommended (portable, iptables)<\/strong>&nbsp;<\/p>\n\n\n\n<p>Add allows first; set default-deny last. Always have a second SSH session open when configuring firewall rules to avod complete lockout from your server. If you make a mistake, you can use the backup session to fix the rules.&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Allow loopback + established:&nbsp;<br><br>sudo iptables -A INPUT -i lo -j ACCEPT&nbsp;<br>sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT&nbsp;<br>&nbsp;<br># Allow SSH and WireGuard:&nbsp;<br><br>sudo iptables -A INPUT -p tcp --dport 2222 -m conntrack --ctstate NEW -j ACCEPT&nbsp;<br>sudo iptables -A INPUT -p udp --dport 51820 -m conntrack --ctstate NEW -j ACCEPT&nbsp;<\/code><\/pre>\n\n\n\n<p><em>Note: Using port 2222 for SSH instead of the default port 22 significantly reduces log noise from automated scanning attacks, making it easier to identify legitimate security events in your logs.<\/em>&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Default policies\nsudo iptables -P INPUT DROP&nbsp;\nsudo iptables -P FORWARD DROP&nbsp;\nsudo iptables -P OUTPUT ACCEPT&nbsp;<\/code><\/pre>\n\n\n\n<p>IPv6: repeat with ip6tables if IPv6 is enabled.&nbsp;<\/p>\n\n\n\n<p>Debian\/Ubuntu persistence:&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt install -y iptables-persistent &amp;&amp; sudo netfilter-persistent save&nbsp;<\/code><\/pre>\n\n\n\n<p><strong>Easy (Ubuntu \/ UFW)<\/strong>&nbsp;<\/p>\n\n\n\n<p>UFW is Ubuntu-centric and designed for ease of use. Other distributions would need to install and enable UFW or use the more portable iptables approach above.&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update &amp;&amp; sudo apt install -y ufw&nbsp;<br><br>sudo ufw default deny incoming&nbsp;<br><br>sudo ufw default allow outgoing&nbsp;<br><br>sudo ufw allow 2222\/tcp&nbsp;<br><br>sudo ufw allow 51820\/udp&nbsp;<br><br>sudo ufw enable&nbsp;<\/code><\/pre>\n\n\n\n<p><em>Remember: Changing SSH to port 2222 reduces automated attack attempts and keeps your authentication logs cleaner, though it&#8217;s not a substitute for proper SSH hardening practices.<\/em>&nbsp;<\/p>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-4c171fbe\"><h3 class=\"uagb-heading-text\"><strong>Automated Protection<\/strong>&nbsp;<\/h3><\/div>\n\n\n\n<p>Use SSH keys only and keep a second SSH session open while changing settings to avoid lockout.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Enforce keys-only auth (OpenSSH with sshd_config.d\/)\nsudo tee \/etc\/ssh\/sshd_config.d\/99-keys-only.conf &gt;\/dev\/null &lt;&lt;'EOF'\nPermitRootLogin no\nPasswordAuthentication no\nPubkeyAuthentication yes\nEOF\n\n# Reload without dropping current sessions (service name varies by distro)\nsudo systemctl reload ssh || sudo systemctl reload sshd\n\n# Quick test from another terminal (adjust user\/host\/port)\nssh -p 2222 youruser@your.server -- true<\/code><\/pre>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-e6246347\"><h2 class=\"uagb-heading-text\">Adding an Extra Layer: WireGuard Pre-Shared Key (PSK)&nbsp;<\/h2><\/div>\n\n\n\n<p>A WireGuard pre-shared key (PSK) is an optional symmetric secret mixed into the standard public key handshake. It adds defense-in-depth: even if an attacker later obtained a private key or recorded traffic, the PSK raises the cryptographic barrier significantly.&nbsp;<\/p>\n\n\n\n<p><strong>When to Use PSKs<\/strong>: Use PSKs for site-to-site links or environments with compliance requirements. The <a href=\"https:\/\/www.wireguard.com\/protocol\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">official WireGuard documentation<\/a> states PSKs provide &#8220;post-quantum resistance&#8221; against future quantum computer attacks.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1060\" height=\"451\" src=\"https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/wireguard-key-system_EN.webp\" alt=\"WireGuard private\/public\/pre-shared key system explained\" class=\"wp-image-25532\" srcset=\"https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/wireguard-key-system_EN.webp 1060w, https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/wireguard-key-system_EN-600x255.webp 600w, https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/wireguard-key-system_EN-768x327.webp 768w\" sizes=\"auto, (max-width: 1060px) 100vw, 1060px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-d776c640\"><h3 class=\"uagb-heading-text\">Setup and Configuration&nbsp;<\/h3><\/div>\n\n\n\n<p>Generate unique PSKs per server-client pair:&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Generate and store PSK with proper permissions&nbsp;<br><br>wg genpsk | pass insert \u2013e wireguard\/psk-client1&nbsp;<br>sudo chmod 600 \/etc\/wireguard\/psk-client1&nbsp;<br><br># Add to both peers' &#91;Peer] sections&nbsp;<br><br>PresharedKey = &lt;contents of \/etc\/wireguard\/psk-client1&gt;&nbsp;<\/code><\/pre>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-94e6bc4e\"><h3 class=\"uagb-heading-text\">Security Best Practices&nbsp;<\/h3><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use unique PSKs per connection &#8211; never share one PSK across multiple peers.&nbsp;<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Rotate PSKs periodically during planned maintenance windows.&nbsp;<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Store securely &#8211; never commit PSKs to repositories or share via insecure channels.&nbsp;<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-e6b70bad\"><h3 class=\"uagb-heading-text\">Verification&nbsp;<\/h3><\/div>\n\n\n\n<p>After configuration, run <code>wg show<\/code>. You should see pre-shared key: (hidden) under each peer, confirming the PSK is active.&nbsp;<\/p>\n\n\n\n<p>WireGuard&#8217;s pre-shared keys provide substantial security enhancement with minimal operational overhead &#8211; a small change that significantly strengthens your WireGuard deployment against both current and future cryptographic threats.&nbsp;<\/p>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-66e3e3c7\"><h2 class=\"uagb-heading-text\">Preventing WireGuard Private Key Leaks&nbsp;<\/h2><\/div>\n\n\n\n<p>The WireGuard private key is the single most sensitive item in your setup. Treat it like a root password: never transmit it, never paste it into chats or tickets, and keep it readable only by root. Leaks, not cryptography, are the most common real-world failure.&nbsp;<\/p>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-c01d1325\"><h3 class=\"uagb-heading-text\">1) Generate Locally &amp; Lock It Down<\/h3><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Create keys on the host that will use them and store under <code>\/etc\/wireguard\/<\/code>. Use <code>sudoedit<\/code> for config changes so secrets don\u2019t land in shell history.<\/li>\n\n\n\n<li>Set strict ownership and permissions before\/after key creation.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code># Create directory with correct perms (if needed)\nsudo install -d -m 700 -o root -g root \/etc\/wireguard\n\n# Generate keys without printing them to the terminal\numask 077\nwg genkey | sudo tee \/etc\/wireguard\/privatekey &gt;\/dev\/null\nsudo wg pubkey &lt; \/etc\/wireguard\/privatekey | sudo tee \/etc\/wireguard\/publickey &gt;\/dev\/null\n\n# Enforce ownership &amp; permissions\nsudo chown root:root \/etc\/wireguard \/etc\/wireguard\/*key\nsudo chmod 700 \/etc\/wireguard\nsudo chmod 600 \/etc\/wireguard\/*key<\/code><\/pre>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-bd22e9d1\"><h3 class=\"uagb-heading-text\">2) Eliminate Side Channels<\/h3><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li>No CLI args\/screenshots\/tickets\/chats for private keys; they can surface in <code>ps<\/code>, logs, scrollback, or clipboards.<\/li>\n\n\n\n<li>Disable editor swap\/backup files when touching key material (avoid <code>*.swp<\/code>, <code>*~<\/code>).<\/li>\n\n\n\n<li>Never commit private keys to Git &#8211; even private repos. If using config management, keep secrets in a proper secrets manager and template only public keys.<\/li>\n\n\n\n<li>Backups: either exclude <code>\/etc\/wireguard\/*key<\/code> from plaintext backups or encrypt backups at rest. On restore, preserve owners\/permissions; many leaks happen during sloppy restores.<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-5f6f2858\"><h3 class=\"uagb-heading-text\">3) Rotation &amp; Lightweight Monitoring<\/h3><\/div>\n\n\n\n<p><strong>Minimal-downtime rotation:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>On the rotating peer, generate a new keypair and update the local <code>PrivateKey<\/code> (edit with <code>sudoedit<\/code>).<\/li>\n\n\n\n<li>On the remote peer, update the matching <code>[Peer] PublicKey<\/code>.<\/li>\n\n\n\n<li>Restart both interfaces and verify a fresh handshake:<br><code>sudo systemctl restart wg-quick@wg0<br>wg show # check latest handshake + counters<\/code><\/li>\n\n\n\n<li>Delete old private keys and any temporary files; rotate snapshots that captured old keys.<\/li>\n<\/ol>\n\n\n\n<p>Optional defense-in-depth: add a per-peer PSK and rotate periodically.<\/p>\n\n\n\n<p>Optional monitoring: add simple file-integrity\/audit rules to watch <code>\/etc\/wireguard\/*key<\/code> for unexpected reads\/writes.<\/p>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-a16d709c\"><h2 class=\"uagb-heading-text\"><strong>Advanced Firewall Hardening<\/strong>&nbsp;<\/h2><\/div>\n\n\n\n<p>A good WireGuard firewall lets only the traffic you intend, supports roaming clients, and won\u2019t tank performance. Keep rules stateful, interface-aware, and placed in the right plane (cloud security group first, then OS firewall). Avoid mixing frameworks &#8211; choose UFW, nftables, or iptables and stick to it.&nbsp;<\/p>\n\n\n\n<p><strong>Principles that won\u2019t slow you down: <\/strong>Use default-deny on <code>INPUT <\/code>with an explicit allow for your WireGuard UDP port (51820 by default) and <code>ESTABLISHED,RELATED<\/code> traffic. Scope rules to interfaces when possible (match <code>iif wg0 \/ oif wg0<\/code>) to keep policies readable. If your server is a gateway (it routes a subnet through the tunnel), you must open <code>FORWARD <\/code>and add<code> NAT (MASQUERADE)<\/code> on the WAN interface; for a host-only tunnel, leave <code>FORWARD <\/code>closed.&nbsp;<\/p>\n\n\n\n<p><strong>nftables (compact, OS firewall):<\/strong>&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># INPUT (stateful allow + WireGuard UDP)&nbsp;\nnft add table inet filter&nbsp;\nnft add chain inet filter input '{ type filter hook input priority 0; policy drop; }'&nbsp;\nnft add rule&nbsp; inet filter input ct state established,related accept&nbsp;\nnft add rule&nbsp; inet filter input udp dport 51820 ct state new accept&nbsp;<\/code><\/pre>\n\n\n\n<p><strong>iptables (gateway additions):<\/strong>&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># FORWARD and NAT if the server routes a subnet&nbsp;\niptables -A FORWARD -i wg0 -o &lt;WAN_IFACE&gt; -j ACCEPT&nbsp;\niptables -A FORWARD -i &lt;WAN_IFACE&gt; -o wg0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT&nbsp;\niptables -t nat -A POSTROUTING -o &lt;WAN_IFACE&gt; -j MASQUERADE&nbsp;<\/code><\/pre>\n\n\n\n<p><strong>MSS and PMTU: <\/strong>When routing subnets, clamp TCP MSS so packets don\u2019t exceed path MTU and get dropped mid-path:&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>iptables -t mangle -A FORWARD -o wg0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu&nbsp;<\/code><\/pre>\n\n\n\n<p>(For host-to-host tunnels that don\u2019t forward subnets, this is usually unnecessary.)&nbsp;<\/p>\n\n\n\n<p><strong>Rate limiting without self-sabotage: <\/strong>You can add gentle UDP rate limits or bursts to blunt scan noise, but keep them conservative &#8211; over-tight limits will cap peak throughput or break handshakes on busy links. Test after any limiter.&nbsp;<\/p>\n\n\n\n<p><strong>\u201ciptables as a VPN\u201d: <\/strong>Forwarding and NAT can bridge networks and \u201cfeel like a VPN,\u201d but they don\u2019t encrypt or authenticate traffic. Use the firewall for policy and routing, and WireGuard for identity and encryption. Together they form a real, secure site-to-site link.&nbsp;<\/p>\n\n\n\n<p><strong>Troubleshooting fast-path.<\/strong>&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>No handshake:<\/strong> UDP\/51820 blocked in the cloud security group or OS firewall; confirm the listener with ss -uapn | grep 51820.&nbsp;<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Handshake OK, no traffic:<\/strong> FORWARD or MASQUERADE missing on a gateway. Add the rules above and re-test.&nbsp;<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Works one way only:<\/strong> reverse path rules missing. Run iperf3 -R through the tunnel and fix the opposite direction.&nbsp;<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Stalls\/frag needed:<\/strong> enable MSS clamping (when routing) and verify MTU choices.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>Keep rules minimal, measured, and documented. A small, stateful, interface-aware policy gives you reliable security and preserves WireGuard\u2019s performance edge.&nbsp;<\/p>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-5f5e17ff\"><h2 class=\"uagb-heading-text\">WireGuard Security FAQ&nbsp;<\/h2><\/div>\n\n\n\n<p><strong>What is WireGuard? How does the WireGuard VPN protocol work?<\/strong>&nbsp;<br>WireGuard is a modern, open-source VPN protocol that creates encrypted tunnels between peers using public keys. On Linux it runs in-kernel for speed; peers allow traffic via AllowedIPs and communicate over UDP.&nbsp;<\/p>\n\n\n\n<p><strong>Is WireGuard secure?<\/strong>&nbsp;<br>Yes. Its fixed, audited crypto (Noise framework: Curve25519, ChaCha20-Poly1305, BLAKE2s, HKDF) and small codebase reduce attack surface. Real security still depends on host hardening, correct firewalling, and strict private-key hygiene.&nbsp;<\/p>\n\n\n\n<p><strong>Is WireGuard free to use?<\/strong>&nbsp;<br>Yes. WireGuard is free and open source (GPLv2 in Linux; permissive userspace ports exist). There are no licensing fees to deploy it on your VPS or devices.&nbsp;<\/p>\n\n\n\n<p><strong>What security vulnerabilities does WireGuard have?<\/strong>&nbsp;<br>No widely exploited protocol flaws are known. Risks are operational: private-key leaks, weak host security, metadata exposure (UDP, timing), and non-PQC primitives. Handshakes can reveal initiators if keys and logs are later compromised.&nbsp;<\/p>\n\n\n\n<p><strong>What WireGuard firewall rules should I use?<\/strong>&nbsp;<br>Allow your UDP port (51820 by default) and ESTABLISHED\/RELATED traffic. If acting as a gateway, add FORWARD accepts and NAT (MASQUERADE) on the WAN interface; when routing subnets, clamp TCP MSS to PMTU.&nbsp;<\/p>\n\n\n\n<p><strong>What is the best port to use for WireGuard?<\/strong>&nbsp;<br>Any UDP port works. 51820\/udp is standard. For stealth, choose a high random UDP port. If networks block UDP broadly, expect issues &#8211; tunneling over TCP\/HTTPS is possible but hurts performance.&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>WordPress security starts at the server layer. This guide shows how to lock down SSH with keys only, use a minimal iptables firewall, and (optionally) put wp-admin behind WireGuard. Copy the commands, apply them in minutes, and get a fast, low-overhead baseline that blocks common attacks.<\/p>\n","protected":false},"author":65,"featured_media":25466,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[18],"tags":[],"ppma_author":[1489],"class_list":["post-25461","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials"],"uagb_featured_image_src":{"full":["https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/blog-head_hardening-your-wireguard-security-guide_EN.webp",1200,630,false],"thumbnail":["https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/blog-head_hardening-your-wireguard-security-guide_EN-150x150.webp",150,150,true],"medium":["https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/blog-head_hardening-your-wireguard-security-guide_EN-600x315.webp",600,315,true],"medium_large":["https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/blog-head_hardening-your-wireguard-security-guide_EN-768x403.webp",768,403,true],"large":["https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/blog-head_hardening-your-wireguard-security-guide_EN.webp",1200,630,false],"1536x1536":["https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/blog-head_hardening-your-wireguard-security-guide_EN.webp",1200,630,false],"2048x2048":["https:\/\/contabo.com\/blog\/wp-content\/uploads\/2025\/10\/blog-head_hardening-your-wireguard-security-guide_EN.webp",1200,630,false]},"uagb_author_info":{"display_name":"Julia Mink","author_link":"https:\/\/contabo.com\/blog\/author\/julia-mink\/"},"uagb_comment_info":0,"uagb_excerpt":"WordPress security starts at the server layer. This guide shows how to lock down SSH with keys only, use a minimal iptables firewall, and (optionally) put wp-admin behind WireGuard. Copy the commands, apply them in minutes, and get a fast, low-overhead baseline that blocks common attacks.","authors":[{"term_id":1489,"user_id":65,"is_guest":0,"slug":"julia-mink","display_name":"Julia Mink","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/26ce5d4ae17d160425d842da4ea00c56716ffb5d4c58ee0cfb73de57b1de5272?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/posts\/25461","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/users\/65"}],"replies":[{"embeddable":true,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/comments?post=25461"}],"version-history":[{"count":17,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/posts\/25461\/revisions"}],"predecessor-version":[{"id":26164,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/posts\/25461\/revisions\/26164"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/media\/25466"}],"wp:attachment":[{"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/media?parent=25461"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/categories?post=25461"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/tags?post=25461"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/contabo.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=25461"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}