<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ivan Bondarev</title>
    <description>The latest articles on DEV Community by Ivan Bondarev (@bivlked).</description>
    <link>https://dev.to/bivlked</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3816233%2F20163664-3650-4603-801a-13f5a56a32e8.png</url>
      <title>DEV Community: Ivan Bondarev</title>
      <link>https://dev.to/bivlked</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bivlked"/>
    <language>en</language>
    <item>
      <title>How to install AmneziaWG 3.1 on your own VPS (Ubuntu and Debian)</title>
      <dc:creator>Ivan Bondarev</dc:creator>
      <pubDate>Thu, 22 Oct 2026 21:24:42 +0000</pubDate>
      <link>https://dev.to/bivlked/how-to-install-amneziawg-31-on-your-own-vps-ubuntu-and-debian-3mho</link>
      <guid>https://dev.to/bivlked/how-to-install-amneziawg-31-on-your-own-vps-ubuntu-and-debian-3mho</guid>
      <description>&lt;p&gt;Here's how I set up an AmneziaWG 3.1 server on a plain Ubuntu or Debian VPS: one bash script, the kernel module, no Docker and no web panel. It takes 15 to 25 minutes, mostly &lt;code&gt;apt&lt;/code&gt; and building the kernel module.&lt;/p&gt;

&lt;p&gt;AmneziaWG is the WireGuard fork built to get past DPI, and 3.1 is its newest generation. The official way to get a 3.1 server is the Amnezia VPN app, which logs into your server over SSH and runs AmneziaWG there in Docker. I wrote and maintain &lt;a href="https://github.com/bivlked/amneziawg-installer" rel="noopener noreferrer"&gt;amneziawg-installer&lt;/a&gt;, the script I use below. Since v6.0.0 a fresh install sets up 3.1 by default.&lt;/p&gt;

&lt;h2&gt;
  
  
  What 3.1 changes
&lt;/h2&gt;

&lt;p&gt;The big one is header encryption. Every install gets its own &lt;code&gt;HeaderProtectionKey&lt;/code&gt;, so the header no longer tells an observer what kind of packet it's looking at. Data packets also get extra padding (&lt;code&gt;ContentPaddingAddition&lt;/code&gt;). The obfuscation you may know from 2.0 is still there: junk packets (&lt;code&gt;Jc&lt;/code&gt;), random padding on protocol messages (&lt;code&gt;S1&lt;/code&gt;-&lt;code&gt;S4&lt;/code&gt;) and the &lt;code&gt;I1&lt;/code&gt; packet sent before the handshake.&lt;/p&gt;

&lt;p&gt;The Amnezia team now tells people to move even if 2.0 still works for them, because "AmneziaWG 2.0, like AmneziaWG 1.5, has become vulnerable to blocking" (&lt;a href="https://docs.amnezia.org/documentation/instructions/new-amneziawg-selfhosted/" rel="noopener noreferrer"&gt;Amnezia docs&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;One thing before you start. If your carrier blocks the server's IP, or the whole hosting provider, a new protocol generation won't help. 3.1 changes how the packets look, but they still go to the same address.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A full virtual machine (KVM or similar) on x86_64. Containers (OpenVZ, LXC, Docker) can't load a kernel module, and the installer stops there.&lt;/li&gt;
&lt;li&gt;Ubuntu 24.04 LTS, Ubuntu 26.04 LTS or Debian 13. 3.1 needs kernel 6.7 or newer, and all three have it.&lt;/li&gt;
&lt;li&gt;At least 512 MB of RAM and 2 GB of disk. 1 GB of RAM is comfortable, and one vCPU is plenty for a personal VPN.&lt;/li&gt;
&lt;li&gt;Root over SSH, ideally on a clean minimal install. The script assumes the server does nothing else: it tunes the kernel and network for a VPN and offers to remove packages like snapd.&lt;/li&gt;
&lt;li&gt;An emergency console in your provider's panel. Make sure it works before you start. If SSH ever stops answering, that's how you get back in.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since v6.2.0 ARM64 gets 3.1 too: Hetzner CAX, Oracle Ampere, AWS Graviton, a Raspberry Pi on a 64-bit system. For the Pi I checked that the module builds against the Raspberry Pi OS kernels, but I have not run it on a Pi itself yet. 32-bit ARM stays on AmneziaWG 2.0, and so does a stock Debian 12: its kernel is 6.1, older than 6.7. Either way, the final report tells you why.&lt;/p&gt;

&lt;p&gt;If you plan to route traffic from Russian mobile networks, avoid Hetzner. Russian carriers block its subnets widely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;

&lt;p&gt;Log in as root and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget &lt;span class="nt"&gt;-O&lt;/span&gt; install_amneziawg_en.sh https://github.com/bivlked/amneziawg-installer/releases/latest/download/install_amneziawg_en.sh
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x install_amneziawg_en.sh
&lt;span class="nb"&gt;sudo &lt;/span&gt;bash ./install_amneziawg_en.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If SSH listens on a non-standard port, add &lt;code&gt;--ssh-port=YOUR_PORT&lt;/code&gt; so the firewall doesn't lock you out.&lt;/p&gt;

&lt;p&gt;The first run asks for the VPN port, the tunnel subnet, IPv6, the routing mode, client isolation and the server name shown in the Amnezia app. Enter takes the value in brackets, and the defaults are fine for most people. It also lists the packages it wants to remove and asks before touching them. Answer &lt;code&gt;n&lt;/code&gt; if you want to keep them.&lt;/p&gt;

&lt;p&gt;Two prompts trip people up:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;"Reboot now? [y/N]"&lt;/strong&gt;. Answer &lt;code&gt;y&lt;/code&gt;. Enter means no, and then you have to reboot by hand. Your SSH session drops. Wait a minute or two, log in again and run the same command with the same flags. The script remembers where it stopped.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Enable UFW? [y/N]"&lt;/strong&gt; on the third run. Answer &lt;code&gt;y&lt;/code&gt; here too. Enter leaves the server without a firewall.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So a normal install has two reboots: one after system prep, one after the kernel module is built. After the second one the script sets up the firewall, starts the service and creates two clients, &lt;code&gt;my_phone&lt;/code&gt; and &lt;code&gt;my_laptop&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you don't want to answer anything, add &lt;code&gt;--yes&lt;/code&gt;. It takes the defaults, removes the packages, enables the firewall and reboots on its own. You still have to log in after each reboot and run the same command again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connect your devices
&lt;/h2&gt;

&lt;p&gt;Each client gets four files in &lt;code&gt;/root/awg/&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name.conf&lt;/code&gt;, the text config for AmneziaWG apps, Linux &lt;code&gt;awg-quick&lt;/code&gt; and routers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;name.png&lt;/code&gt;, a QR code of that same config&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;name.vpnuri&lt;/code&gt; and &lt;code&gt;name.vpnuri.png&lt;/code&gt;, a &lt;code&gt;vpn://&lt;/code&gt; link for the Amnezia VPN app&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The two QR codes look the same, and it's easy to scan the wrong one. The Amnezia VPN app wants &lt;code&gt;name.vpnuri.png&lt;/code&gt;. The AmneziaWG apps want &lt;code&gt;name.png&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Copy them to your computer. Run this on your own machine, not in the SSH session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp root@SERVER_IP:/root/awg/my_phone.png &lt;span class="nb"&gt;.&lt;/span&gt;
scp root@SERVER_IP:/root/awg/my_laptop.conf &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If SSH is on another port, &lt;code&gt;scp&lt;/code&gt; wants it as &lt;code&gt;-P&lt;/code&gt; (capital P): &lt;code&gt;scp -P YOUR_PORT root@SERVER_IP:/root/awg/my_phone.png .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Which app to use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android: WG Tunnel or AmneziaWG, scan &lt;code&gt;my_phone.png&lt;/code&gt; off your screen&lt;/li&gt;
&lt;li&gt;iPhone, iPad and Mac: AmneziaWG&lt;/li&gt;
&lt;li&gt;Windows: AmneziaWG, import the &lt;code&gt;.conf&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Linux: &lt;code&gt;awg-quick&lt;/code&gt; with the &lt;code&gt;.conf&lt;/code&gt;, or the nm-amneziawg plugin for NetworkManager&lt;/li&gt;
&lt;li&gt;Any platform: Amnezia VPN, scan &lt;code&gt;name.vpnuri.png&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whatever you pick, it has to be a version that understands 3.1. An older app may fail to connect, sometimes without showing any error. I keep a &lt;a href="https://github.com/bivlked/amneziawg-installer/blob/main/ADVANCED.en.md#client-gen-adv" rel="noopener noreferrer"&gt;table of clients&lt;/a&gt; with the versions that work and recheck it when something changes.&lt;/p&gt;

&lt;p&gt;On 13 October I connected to a fresh 3.1 server from Android (AmneziaWG and WG Tunnel) and from Windows. When the phone switched from Wi-Fi to mobile data, both Android apps reconnected in under a second. I didn't test iPhone or Mac that day.&lt;/p&gt;

&lt;p&gt;To add a client later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;bash /root/awg/manage_amneziawg.sh add my_tablet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Check that it works
&lt;/h2&gt;

&lt;p&gt;Connect a device, then run this on the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;awg show awg0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You want a &lt;code&gt;latest handshake&lt;/code&gt; from the last two or three minutes. On the device, any "what is my IP" site should show the server's address (with the default routing mode, which sends all traffic through the tunnel).&lt;/p&gt;

&lt;p&gt;To see the server's health and which generation it runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;bash /root/awg/manage_amneziawg.sh check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for the line "Installation protocol generation".&lt;/p&gt;

&lt;h2&gt;
  
  
  When to stay on 2.0
&lt;/h2&gt;

&lt;p&gt;A client without 3.1 support can't connect to a 3.1 server. If any of your devices is a router on stock firmware (stable KeeneticOS, GL.iNet, OpenWrt with an older amneziawg package), uses Hiddify or runs an app that hasn't been updated, install the server on 2.0 from the start:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;bash ./install_amneziawg_en.sh &lt;span class="nt"&gt;--protocol&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better to decide before you install: switching generations later means a reinstall and a new profile for every client.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optional: your own I1 packet
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;I1&lt;/code&gt; is a packet the client sends before the handshake, so the start of the connection looks like some other protocol. By default my installer puts a packet shaped like a DNS response there. Since v6.1.0 you can set your own at install time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;bash ./install_amneziawg_en.sh &lt;span class="nt"&gt;--i1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'&amp;lt;your I1 string&amp;gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A popular choice is a QUIC-shaped packet from &lt;a href="https://sageptr.github.io/mini_quic_generator/" rel="noopener noreferrer"&gt;Mini QUIC Generator&lt;/a&gt;: enter an SNI and copy the "AmneziaWG 1.5+ (I1 = )" field. I tried it with several SNIs, and the strings it gave me (53 to 99 bytes) passed the installer's check as is.&lt;/p&gt;

&lt;p&gt;That check runs before anything gets installed. It only allows the tags that both the kernel module and amneziawg-go understand: &lt;code&gt;&amp;lt;b 0xHEX&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;r N&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;rc N&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;rd N&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;t&amp;gt;&lt;/code&gt;, written back to back, with the whole packet at most 1024 bytes. It refuses &lt;code&gt;&amp;lt;c&amp;gt;&lt;/code&gt;, because amneziawg-go, which the Android, iPhone, Mac and Windows apps run on, won't load a profile with it.&lt;/p&gt;

&lt;p&gt;The installer remembers your value, so a later reinstall keeps it. &lt;code&gt;--no-cps&lt;/code&gt;, &lt;code&gt;--preset&lt;/code&gt;, &lt;code&gt;--mobile&lt;/code&gt;, &lt;code&gt;--jc&lt;/code&gt;, &lt;code&gt;--jmin&lt;/code&gt; and &lt;code&gt;--jmax&lt;/code&gt; drop it, with a warning.&lt;/p&gt;

&lt;p&gt;On a server that's already running, use &lt;code&gt;--force --i1='...'&lt;/code&gt;. That's a full reinstall pass with the same two reboots, so expect a few minutes of downtime. Keys, clients and the other parameters stay as they were, only &lt;code&gt;I1&lt;/code&gt; changes. When it's done, reissue the client profiles with &lt;code&gt;sudo bash /root/awg/manage_amneziawg.sh regen&lt;/code&gt; and import them on your devices again. The client is the one sending &lt;code&gt;I1&lt;/code&gt;, so the new value only kicks in once it's in their profiles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions I get often
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can I upgrade my 2.0 server to 3.1 in place?&lt;/strong&gt; No. Updating the scripts keeps the generation. To move over, you run &lt;code&gt;--uninstall&lt;/code&gt; and then a fresh install, and every client needs a new profile. Before that, run &lt;code&gt;sudo bash /root/awg/manage_amneziawg.sh backup&lt;/code&gt; and copy the archive to your own machine, because &lt;code&gt;--uninstall&lt;/code&gt; deletes &lt;code&gt;/root/awg/&lt;/code&gt; along with the backups folder inside it. That backup is also your way back to 2.0 if you need it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why does the profile leave out &lt;code&gt;RandomTrailers&lt;/code&gt; and &lt;code&gt;DisableCookies&lt;/code&gt;?&lt;/strong&gt; &lt;code&gt;RandomTrailers&lt;/code&gt; has to be on at both ends, so a server with it cuts off every client that doesn't have it. In my tests it also cut throughput 85 to 133 times when combined with the rest of the obfuscation. &lt;code&gt;DisableCookies&lt;/code&gt; removes the protection against handshake floods. 3.1 works fine without either, so the installer doesn't write these lines at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will it get through my ISP?&lt;/strong&gt; I can't promise that. It depends on the network and on the parameters. If the handshake shows up but traffic dies after a few kilobytes, read the &lt;a href="https://github.com/bivlked/amneziawg-installer/blob/main/ADVANCED.en.md#as-blocking-adv" rel="noopener noreferrer"&gt;section on AS-level blocking&lt;/a&gt; before you reinstall anything.&lt;/p&gt;

&lt;p&gt;The full guide, with every flag, updates and uninstall, is &lt;a href="https://github.com/bivlked/amneziawg-installer/blob/main/INSTALL_VPS.md" rel="noopener noreferrer"&gt;INSTALL_VPS&lt;/a&gt;. If something here doesn't match what you see on your server, open an issue in the &lt;a href="https://github.com/bivlked/amneziawg-installer" rel="noopener noreferrer"&gt;repository&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>vpn</category>
      <category>selfhosted</category>
      <category>linux</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>amneziawg-installer v5.34.0: full tunnel by default, and a signing key you can check outside GitHub</title>
      <dc:creator>Ivan Bondarev</dc:creator>
      <pubDate>Sun, 13 Sep 2026 19:01:46 +0000</pubDate>
      <link>https://dev.to/bivlked/amneziawg-installer-v5340-full-tunnel-by-default-and-a-signing-key-you-can-check-outside-github-2nha</link>
      <guid>https://dev.to/bivlked/amneziawg-installer-v5340-full-tunnel-by-default-and-a-signing-key-you-can-check-outside-github-2nha</guid>
      <description>&lt;p&gt;Two things in this post. The first is the public key that signs my installer releases, published here on purpose, away from the GitHub repository. The second is v5.34.0, which changes what a fresh install hands to clients by default.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the signing key is on dev.to
&lt;/h2&gt;

&lt;p&gt;Since v5.29.0 every release of &lt;a href="https://github.com/bivlked/amneziawg-installer" rel="noopener noreferrer"&gt;amneziawg-installer&lt;/a&gt; ships detached &lt;a href="https://jedisct1.github.io/minisign/" rel="noopener noreferrer"&gt;minisign&lt;/a&gt; signatures for the six scripts, plus &lt;code&gt;KEYS.txt&lt;/code&gt; with the public key. The private key stays offline on my machine and never reaches GitHub Actions; the release workflow only verifies, and it refuses to publish a release whose signatures do not check out.&lt;/p&gt;

&lt;p&gt;That protects the download on its way to you. It does not protect you from a compromise of the GitHub account itself: whoever can replace the script can replace &lt;code&gt;KEYS.txt&lt;/code&gt; next to it, and a check against a key taken from the same place will pass. A signature starts to mean something when the key comes from somewhere else, or when you saved it earlier.&lt;/p&gt;

&lt;p&gt;So here it is, outside the repository. A copy here only helps if whoever takes over the GitHub account cannot also edit this post, so save the key somewhere of your own:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;untrusted comment: minisign public key 3E598A1C01907E17
RWQXfpABHIpZPttqrwYrQNHRTk/iLIz4cVh9KkRwAElHP+CoW/NPEysN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key ID &lt;code&gt;3E598A1C01907E17&lt;/code&gt;. The same ID is printed in &lt;code&gt;SECURITY.md&lt;/code&gt; and in the README, and the full key is &lt;code&gt;KEYS.txt&lt;/code&gt; in the repository. If any of them ever disagrees with this post, do not run the script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verifying a release with the key from this post
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;minisign

&lt;span class="nv"&gt;TAG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;v5.34.0
&lt;span class="nv"&gt;BASE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/bivlked/amneziawg-installer/releases/download/&lt;/span&gt;&lt;span class="nv"&gt;$TAG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
curl &lt;span class="nt"&gt;-LO&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BASE&lt;/span&gt;&lt;span class="s2"&gt;/install_amneziawg_en.sh"&lt;/span&gt;
curl &lt;span class="nt"&gt;-LO&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BASE&lt;/span&gt;&lt;span class="s2"&gt;/install_amneziawg_en.sh.minisig"&lt;/span&gt;

minisign &lt;span class="nt"&gt;-Vm&lt;/span&gt; install_amneziawg_en.sh &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-P&lt;/span&gt; RWQXfpABHIpZPttqrwYrQNHRTk/iLIz4cVh9KkRwAElHP+CoW/NPEysN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the &lt;code&gt;-P&lt;/code&gt;: the key is passed on the command line, so &lt;code&gt;KEYS.txt&lt;/code&gt; from the repository is not involved at all.&lt;/p&gt;

&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Signature and comment signature verified
Trusted comment: amneziawg-installer v5.34.0 install_amneziawg_en.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read the second line, not only the first. The trusted comment is signed along with the file, so it cannot be edited, but minisign does not compare it with what you expected: an older script with its own older signature verifies just as well and simply prints an older tag. Accept the download only if that line says exactly &lt;code&gt;amneziawg-installer v5.34.0 install_amneziawg_en.sh&lt;/code&gt;; otherwise stop.&lt;/p&gt;

&lt;p&gt;A changed byte gives &lt;code&gt;Signature verification failed&lt;/code&gt; and a non-zero exit code. Releases before v5.29.0 have no signatures, so there is nothing to check there.&lt;/p&gt;

&lt;h2&gt;
  
  
  v5.34.0: the default is now the full tunnel
&lt;/h2&gt;

&lt;p&gt;A fresh install used to give clients a list of 34 IPv4 subnets ("Amnezia List + DNS"): all public IPv4, minus private and a few reserved ranges. Starting with v5.34.0 the default is &lt;code&gt;AllowedIPs = 0.0.0.0/0, ::/0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Why the change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Amnezia app shows its own split-tunneling page only when it sees &lt;code&gt;0.0.0.0/0&lt;/code&gt; among the client routes. Given a subnet list, it decides that the server already splits traffic, says the server does not support split tunneling, and hides the toggle.&lt;/li&gt;
&lt;li&gt;On Linux, &lt;code&gt;awg-quick&lt;/code&gt; turns on its fwmark handling only for a &lt;code&gt;/0&lt;/code&gt; route. A list-shaped IPv4 config has none, and on my test bench that ended in a routing loop: packets to the server itself went back into the tunnel.&lt;/li&gt;
&lt;li&gt;The Amnezia app's own server template emits the same &lt;code&gt;0.0.0.0/0, ::/0&lt;/code&gt; pair, which is the form its split-tunneling page recognises.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cost, plainly: the default profile no longer keeps private networks out of the tunnel, so whether your LAN stays reachable while the VPN is on depends on the client, not on the config. If you need home devices over IPv4, install with &lt;code&gt;--route-amnezia&lt;/code&gt; to keep the previous mode. That mode does not bring back LAN access over IPv6: it also sends &lt;code&gt;::/0&lt;/code&gt; into the tunnel.&lt;/p&gt;

&lt;p&gt;A running server keeps its mode. The new default applies to new installs only; a reinstall takes the mode saved in the server settings, and existing client profiles do not change by themselves. To move a running server to another mode, rerun the installer with &lt;code&gt;--force&lt;/code&gt; and the mode you want (without &lt;code&gt;--force&lt;/code&gt; it refuses to touch a configured server), then reissue the profiles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;bash ./install_amneziawg_en.sh &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--route-all&lt;/span&gt;      &lt;span class="c"&gt;# or --route-amnezia&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;bash /root/awg/manage_amneziawg.sh regen &lt;span class="nt"&gt;--reset-routes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;--reset-routes&lt;/code&gt; replaces every client's own route list with the server-wide mode, including lists you edited by hand. The regenerated profiles have to be imported on the devices again.&lt;/p&gt;

&lt;p&gt;The release also tidies up the routing menu and its edge cases: every mode now names both its benefit and its price, an unrecognised answer no longer falls back to the default silently, and a reinstall no longer changes the mode of a working server.&lt;/p&gt;

&lt;p&gt;Full notes: &lt;a href="https://github.com/bivlked/amneziawg-installer/releases/tag/v5.34.0" rel="noopener noreferrer"&gt;v5.34.0 on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;

&lt;p&gt;The installer is meant for a clean Ubuntu or Debian VPS (Ubuntu 24.04 or Debian 13 for a new server, Ubuntu 26.04 works too). If you verified the script above, run that same file instead of downloading it again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;bash ./install_amneziawg_en.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without verification, the quick path from the README is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget &lt;span class="nt"&gt;-O&lt;/span&gt; install_amneziawg_en.sh https://github.com/bivlked/amneziawg-installer/releases/latest/download/install_amneziawg_en.sh
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x install_amneziawg_en.sh
&lt;span class="nb"&gt;sudo &lt;/span&gt;bash ./install_amneziawg_en.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;About 20 minutes and two reboots; after each reboot, run the same command again and it picks up where it stopped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/bivlked/amneziawg-installer" rel="noopener noreferrer"&gt;amneziawg-installer on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/bivlked/amneziawg-installer#verifying-a-release" rel="noopener noreferrer"&gt;Verifying a release&lt;/a&gt; in the README&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/bivlked/amneziawg-installer/blob/main/docs/SIGNING_DESIGN.md" rel="noopener noreferrer"&gt;Release signing design and threat model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/bivlked/amneziawg-installer/blob/main/CHANGELOG.en.md" rel="noopener noreferrer"&gt;Changelog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Questions or problems? Open an issue on &lt;a href="https://github.com/bivlked/amneziawg-installer/issues" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; or leave a comment here.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>vpn</category>
      <category>selfhosted</category>
      <category>security</category>
      <category>linux</category>
    </item>
    <item>
      <title>AmneziaWG 3.1 on Oracle Cloud Always Free ARM: a Self-Hosted DPI-Bypass VPN</title>
      <dc:creator>Ivan Bondarev</dc:creator>
      <pubDate>Thu, 16 Apr 2026 16:48:49 +0000</pubDate>
      <link>https://dev.to/bivlked/self-hosted-dpi-bypass-vpn-on-oracle-cloud-always-free-arm-2mek</link>
      <guid>https://dev.to/bivlked/self-hosted-dpi-bypass-vpn-on-oracle-cloud-always-free-arm-2mek</guid>
      <description>&lt;p&gt;&lt;em&gt;Updated in November 2026 for installer v6.2.2.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;AmneziaWG 3.1 runs on Oracle Cloud's Always Free ARM instances (Ampere A1), so you can have your own DPI-resistant VPN server for $0 a month. I maintain &lt;a href="https://github.com/bivlked/amneziawg-installer" rel="noopener noreferrer"&gt;amneziawg-installer&lt;/a&gt;, and since v6.2.0 it sets up the 3.1 generation on ARM64 too. This is a rewrite of my guide from April.&lt;/p&gt;

&lt;p&gt;Why not plain WireGuard? In Russia, Iran and a few other places DPI recognizes the WireGuard handshake and drops it. AmneziaWG is a WireGuard fork that disguises those packets. It sends a few junk packets first, pads the handshake to random sizes and adds a packet that looks like ordinary traffic (my installer makes it look like a DNS reply). In 3.1 the packet headers are also encrypted with a per-server key, &lt;code&gt;HeaderProtectionKey&lt;/code&gt;, so the type field that gives WireGuard away is hidden.&lt;/p&gt;

&lt;p&gt;The installer does the server side: kernel module, firewall, sysctl, client configs. On Oracle it comes down to running one command three times.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;An Oracle Cloud account on the &lt;a href="https://www.oracle.com/cloud/free/" rel="noopener noreferrer"&gt;Always Free tier&lt;/a&gt;. Oracle asks for a card to verify you, but Always Free resources are not charged.&lt;/li&gt;
&lt;li&gt;An SSH key. If you have none, run &lt;code&gt;ssh-keygen -t ed25519&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A client app that supports AmneziaWG 3.1: AmneziaWG for Android or iOS 3.1.4+, AmneziaWG for Windows 3.1.0+, Amnezia VPN 5.0.1.5+, or WG Tunnel 5.6.0+ on Android. Routers and other clients are in the &lt;a href="https://github.com/bivlked/amneziawg-installer/blob/main/ADVANCED.en.md#client-gen-adv" rel="noopener noreferrer"&gt;client table&lt;/a&gt;. The stock WireGuard app cannot import these configs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Oracle gives for free now
&lt;/h2&gt;

&lt;p&gt;Oracle has cut the Always Free allowance for Ampere A1. It is now 1,500 OCPU hours and 9,000 GB hours a month, which Oracle itself counts as &lt;strong&gt;2 OCPUs and 12 GB of RAM&lt;/strong&gt; around the clock. Older guides, my own included, said 4 and 24. A personal VPN uses a small part of that, since the tunnel runs inside the kernel.&lt;/p&gt;

&lt;p&gt;Outbound traffic is free up to 10 TB a month, and both AmneziaWG and the installer are open source (the installer is MIT). Inside the allowance the whole setup costs nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create the instance
&lt;/h2&gt;

&lt;p&gt;In the OCI console: &lt;strong&gt;Compute → Instances → Create instance&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Image: Canonical Ubuntu 24.04. The installer is tested on it the most. Ubuntu 26.04 and Debian 13 work too. Skip Debian 12. Its kernel is 6.1, and on kernels older than 6.7 the installer falls back to AmneziaWG 2.0.&lt;/li&gt;
&lt;li&gt;Shape: &lt;code&gt;VM.Standard.A1.Flex&lt;/code&gt; with 2 OCPUs and 12 GB, the whole free allowance. A smaller shape is fine as well.&lt;/li&gt;
&lt;li&gt;Networking: a VCN with a public IPv4 address.&lt;/li&gt;
&lt;li&gt;SSH keys: paste your &lt;code&gt;~/.ssh/id_ed25519.pub&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ampere capacity in the free regions is hit and miss. If you get "Out of capacity", try another availability domain or come back later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open the VPN port
&lt;/h2&gt;

&lt;p&gt;The default security list of a new VCN lets in SSH and not much else. The installer listens on &lt;strong&gt;UDP 39743&lt;/strong&gt; by default (&lt;code&gt;--port=N&lt;/code&gt; sets your own). Go to &lt;strong&gt;Networking → Virtual Cloud Networks → your VCN → Security Lists → Default Security List → Add Ingress Rules&lt;/strong&gt; and add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Source CIDR: &lt;code&gt;0.0.0.0/0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;IP Protocol: UDP&lt;/li&gt;
&lt;li&gt;Destination Port Range: &lt;code&gt;39743&lt;/code&gt;, or the port you pass with &lt;code&gt;--port&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your mobile carrier drops unfamiliar UDP ports, install with &lt;code&gt;--mobile&lt;/code&gt;: the server then uses 443/udp with a mobile preset, so open 443/udp instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh ubuntu@&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;your-public-ip&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
wget -O install_amneziawg_en.sh https://github.com/bivlked/amneziawg-installer/releases/latest/download/install_amneziawg_en.sh
chmod +x install_amneziawg_en.sh
sudo bash ./install_amneziawg_en.sh --yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The script comes from the latest release rather than the main branch, so you get a version that went through the release checks. &lt;code&gt;--yes&lt;/code&gt; accepts the defaults: full tunnel, UFW on, and the packages the installer considers unneeded on a VPN-only box removed, snapd and unattended-upgrades among them. Without unattended-upgrades nobody installs security updates for you, so run &lt;code&gt;sudo apt upgrade&lt;/code&gt; from time to time, or add &lt;code&gt;--keep-packages&lt;/code&gt; to keep those packages. Leave out &lt;code&gt;--yes&lt;/code&gt; if you would rather answer the questions yourself.&lt;/p&gt;

&lt;p&gt;What follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First run: system update and preparation. With &lt;code&gt;--yes&lt;/code&gt; the server reboots by itself and SSH drops. Wait a minute, log back in and run the same command.&lt;/li&gt;
&lt;li&gt;Second run: the kernel module. On ARM64 it is built with DKMS from the Amnezia PPA for whatever kernel the instance runs, and it rebuilds itself after kernel updates. Oracle instances use Oracle's own kernel, 7.0 on Ubuntu 24.04 at the moment; I checked that the module builds for it. Then another automatic reboot.&lt;/li&gt;
&lt;li&gt;Third run: firewall, configs, the service. The VPN works right away, no extra reboot needed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It takes about 10 to 15 minutes, most of it the first system update. Progress is saved on disk, so an interrupted run continues where it stopped. If apt fails to download a package on a flaky network, the installer stops instead of retrying (since v6.2.1, because of the apt vulnerability CVE-2026-109518); just run it again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Oracle's own firewall rules
&lt;/h3&gt;

&lt;p&gt;Oracle's Ubuntu images ship their own iptables rules in &lt;code&gt;/etc/iptables/rules.v4&lt;/code&gt;, loaded at boot by &lt;code&gt;netfilter-persistent&lt;/code&gt;. They end with a &lt;code&gt;REJECT&lt;/code&gt; in INPUT and FORWARD, so the VPN port would stay closed even after you open it in the security list. Installing UFW removes &lt;code&gt;netfilter-persistent&lt;/code&gt;, but the rules already loaded stay in memory above UFW's rules until the next boot. Earlier versions of this guide had you reboot once more by hand because of that.&lt;/p&gt;

&lt;p&gt;Since v6.2.2 the installer handles it: after setting up UFW it removes exactly that &lt;code&gt;REJECT&lt;/code&gt; if it sits above UFW and is listed in &lt;code&gt;rules.v4&lt;/code&gt;, and notes it in the log. A &lt;code&gt;REJECT&lt;/code&gt; that is not in that file may be your own, so the installer leaves it, warns you and prints the &lt;code&gt;iptables -D&lt;/code&gt; command to delete it.&lt;/p&gt;

&lt;p&gt;I checked this on an Ubuntu 24.04 ARM64 server with a real &lt;code&gt;rules.v4&lt;/code&gt; and Oracle's rules reproduced, not on a real Oracle instance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check the result
&lt;/h2&gt;

&lt;p&gt;The installer finishes with a report. Find the line "Protocol generation", it should say 3.1. If it says 2.0, the report gives the reason, an old kernel for example. Later on, &lt;code&gt;sudo bash /root/awg/manage_amneziawg.sh check&lt;/code&gt; shows the same plus the server's health.&lt;/p&gt;

&lt;p&gt;Then check the address your clients will connect to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sudo grep Endpoint /root/awg/my_phone.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The instance sits behind Oracle's NAT, and its network interface has a private 10.x address. The installer asks an outside service for the public one, so normally you see your Oracle public IP here and do not need &lt;code&gt;--endpoint&lt;/code&gt;. If you see a 10.x address, run the installer again with &lt;code&gt;--endpoint=&amp;lt;your-public-ip&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connect your phone
&lt;/h2&gt;

&lt;p&gt;The install creates two clients, &lt;code&gt;my_phone&lt;/code&gt; and &lt;code&gt;my_laptop&lt;/code&gt;. To add another one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sudo bash /root/awg/manage_amneziawg.sh add tablet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each client gets four files in &lt;code&gt;/root/awg/&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;my_phone.conf&lt;/code&gt;: the config for AmneziaWG desktop apps, Linux &lt;code&gt;awg-quick&lt;/code&gt; and routers;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;my_phone.png&lt;/code&gt;: a QR code of that config, for the AmneziaWG mobile apps;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;my_phone.vpnuri&lt;/code&gt; and &lt;code&gt;my_phone.vpnuri.png&lt;/code&gt;: a &lt;code&gt;vpn://&lt;/code&gt; link and its QR code, for the Amnezia VPN app.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The two QR codes are different, and Amnezia VPN only takes the &lt;code&gt;vpnuri&lt;/code&gt; one.&lt;/p&gt;

&lt;p&gt;The quickest way onto a phone is to print the QR code right in the terminal and scan it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sudo bash /root/awg/manage_amneziawg.sh qr my_phone
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add &lt;code&gt;--vpn&lt;/code&gt; at the end to get the one for Amnezia VPN.&lt;/p&gt;

&lt;p&gt;If you want the files on your computer instead: &lt;code&gt;/root/awg&lt;/code&gt; is readable by root only, and on Oracle you log in as &lt;code&gt;ubuntu&lt;/code&gt;. So first copy them to your home directory on the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sudo install -m 600 -o ubuntu -g ubuntu /root/awg/my_phone.conf /root/awg/my_phone.png ~/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, on your computer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp ubuntu@&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;your-public-ip&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;:my_phone.conf ubuntu@&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;your-public-ip&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;:my_phone.png .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Afterwards delete the copies on the server with &lt;code&gt;rm ~/my_phone.*&lt;/code&gt;, since the config holds the client's private key.&lt;/p&gt;

&lt;p&gt;Once the phone is connected, &lt;code&gt;sudo awg show awg0&lt;/code&gt; on the server should show a &lt;code&gt;latest handshake&lt;/code&gt; from the last minute or two, and a "what is my IP" site on the phone should show the Oracle address.&lt;/p&gt;

&lt;h2&gt;
  
  
  No handshake?
&lt;/h2&gt;

&lt;p&gt;Before changing settings, look at what reaches the server. Run these on the server while the phone tries to connect (put in your own port, or 443 with &lt;code&gt;--mobile&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sudo tcpdump -ni any udp port 39743
sudo awg show awg0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;tcpdump shows nothing from the phone: the port is closed in the security list, or the traffic is blocked on the way to Oracle.&lt;/li&gt;
&lt;li&gt;Packets arrive, but the peer's &lt;code&gt;endpoint&lt;/code&gt; in &lt;code&gt;awg show&lt;/code&gt; does not change: run &lt;code&gt;sudo iptables -S INPUT&lt;/code&gt; and look for a &lt;code&gt;-j REJECT&lt;/code&gt; line above the &lt;code&gt;ufw-&lt;/code&gt; lines. If there is one, it is dropping them (tcpdump sees packets before the firewall does). The installer removes Oracle's own rule by itself and warns about any other such rule, on screen and in &lt;code&gt;/root/awg/install_amneziawg.log&lt;/code&gt;. Otherwise the client does not support 3.1, or its config does not match the server.&lt;/li&gt;
&lt;li&gt;Packets arrive, the peer's &lt;code&gt;endpoint&lt;/code&gt; switches to the phone's address and its received bytes grow, but &lt;code&gt;latest handshake&lt;/code&gt; stays empty: the network filters the burst of packets sent before the handshake. When I measured this in September on one Russian mobile carrier, the shape of the &lt;code&gt;I1&lt;/code&gt; packet decided it, not the number of junk packets: lowering &lt;code&gt;Jc&lt;/code&gt; did not help, a DNS-shaped &lt;code&gt;I1&lt;/code&gt; did. New installs already get a DNS-shaped &lt;code&gt;I1&lt;/code&gt;. Other carriers behave differently, and some need &lt;code&gt;I1&lt;/code&gt; removed entirely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full walk-through is in &lt;a href="https://github.com/bivlked/amneziawg-installer/blob/main/ADVANCED.en.md#no-connection-adv" rel="noopener noreferrer"&gt;ADVANCED: no connection&lt;/a&gt;, and the cellular case in &lt;a href="https://github.com/bivlked/amneziawg-installer/blob/main/ADVANCED.en.md#no-hs-mobile-adv" rel="noopener noreferrer"&gt;handshake fails on mobile data&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Worth knowing before you rely on it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Oracle reclaims idle Always Free instances. Idle means that over 7 days the 95th percentile of CPU use stayed under 20 %, and network and memory use were under 20 % too. A personal VPN often fits that, and a cron job that loads the CPU twice a week does not move a 95th percentile. Oracle's own advice is to upgrade the account to Pay As You Go. Reclaiming applies only to Always Free accounts, and Always Free resources stay free after the upgrade. A stopped instance can be started again if the shape is available in your region.&lt;/li&gt;
&lt;li&gt;Host IPv6 is off by default. &lt;code&gt;--allow-ipv6&lt;/code&gt; keeps it on, and &lt;code&gt;--allow-ipv6-tunnel&lt;/code&gt; also gives clients IPv6 inside the tunnel.&lt;/li&gt;
&lt;li&gt;An ARM64 server set up before v6.2.0 stays on 2.0. A newer installer does not change the generation of a running server; moving to 3.1 means a reinstall and new configs on every device, see &lt;a href="https://github.com/bivlked/amneziawg-installer/blob/main/INSTALL_VPS.md#update-flow" rel="noopener noreferrer"&gt;the update flow&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;No VPN is guaranteed to get through. AmneziaWG makes the tunnel much harder to recognize, but networks also block by address and by packet shape, and results differ from one network to another. Known cases and workarounds are collected in &lt;a href="https://github.com/bivlked/amneziawg-installer/blob/main/ADVANCED.en.md#no-connection-adv" rel="noopener noreferrer"&gt;ADVANCED&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I have tested
&lt;/h2&gt;

&lt;p&gt;On 3 and 4 November I ran ARM64 with 3.1 on an Ampere server at another provider: clean installs of Ubuntu 24.04, Debian 13 and Ubuntu 26.04, traffic through the tunnel, and a kernel update with the module rebuilt automatically. On 9 November I checked v6.2.2 with a clean install on Ubuntu 24.04 ARM64 with Oracle's firewall rules reproduced. I have not run this release on an actual Oracle instance. If Oracle behaves differently for you, tell me in the comments or in the repo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not on Oracle?
&lt;/h2&gt;

&lt;p&gt;The same installer works on any full VM or bare-metal server with Ubuntu 24.04 / 26.04 or Debian 13, x86_64 or ARM64 (AWS Graviton, Hetzner CAX and others). It does not work in containers such as OpenVZ or LXC, because they cannot load a kernel module. On a Raspberry Pi with a 64-bit OS the 3.1 module builds against the Raspberry Pi OS kernels, but I have not run it on a Pi yet.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;General install guide: &lt;a href="https://github.com/bivlked/amneziawg-installer/blob/main/INSTALL_VPS.md" rel="noopener noreferrer"&gt;INSTALL_VPS.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ARM details: &lt;a href="https://github.com/bivlked/amneziawg-installer/blob/main/ADVANCED.en.md#arm-support-adv" rel="noopener noreferrer"&gt;Raspberry Pi and ARM64 support&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Releases: &lt;a href="https://github.com/bivlked/amneziawg-installer/releases" rel="noopener noreferrer"&gt;github.com/bivlked/amneziawg-installer/releases&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The AmneziaWG protocol: &lt;a href="https://docs.amnezia.org/documentation/amnezia-wg/" rel="noopener noreferrer"&gt;docs.amnezia.org&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you hit a problem with a particular carrier, open an issue or a discussion in the &lt;a href="https://github.com/bivlked/amneziawg-installer" rel="noopener noreferrer"&gt;repo&lt;/a&gt; and mention the carrier and the region. A good part of the mobile fixes in the installer started from reports like that.&lt;/p&gt;

</description>
      <category>vpn</category>
      <category>selfhosted</category>
      <category>oraclecloud</category>
      <category>wireguard</category>
    </item>
    <item>
      <title>AmneziaWG 2.0 in 5 Minutes: DPI-Resistant VPN That WireGuard Can't Match</title>
      <dc:creator>Ivan Bondarev</dc:creator>
      <pubDate>Mon, 06 Apr 2026 16:56:11 +0000</pubDate>
      <link>https://dev.to/bivlked/your-wireguard-got-blocked-deploy-amneziawg-20-in-5-minutes-2k7h</link>
      <guid>https://dev.to/bivlked/your-wireguard-got-blocked-deploy-amneziawg-20-in-5-minutes-2k7h</guid>
      <description>&lt;p&gt;WireGuard is blocked or throttled in Russia, China, Iran, UAE, Turkmenistan, and a bunch of other countries. If yours stopped working - you can replace it with AmneziaWG 2.0 in about 5 minutes. Same WireGuard speed, same crypto, but the traffic looks like random noise to DPI.&lt;/p&gt;

&lt;p&gt;No Linux skills needed. Three commands and you're done.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You Need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;clean VPS&lt;/strong&gt; - any $3-5/month server works (1 GB RAM is plenty)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ubuntu 24.04 / 25.10&lt;/strong&gt; or &lt;strong&gt;Debian 12 / 13&lt;/strong&gt; on that server&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSH access&lt;/strong&gt; - your provider gives you an IP, login, and password&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't have a VPS yet? Grab one from DigitalOcean, Vultr, or wherever - just make sure the datacenter is outside your country. Cheapest tier is fine. One 2026 caveat for readers in Russia: traffic to some datacenter networks (Hetzner AS24940 is the loudest example) is now cut at the AS level - the handshake completes, then data flow dies. There is a workaround via an I1 packet that mimics QUIC with an allowlisted SNI; see the &lt;a href="https://github.com/bivlked/amneziawg-installer/blob/main/ADVANCED.en.md#as-blocking-adv" rel="noopener noreferrer"&gt;AS-blocking section in ADVANCED&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 - Install (3 commands)
&lt;/h2&gt;

&lt;p&gt;SSH into your server and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget &lt;span class="nt"&gt;-O&lt;/span&gt; install_amneziawg_en.sh https://raw.githubusercontent.com/bivlked/amneziawg-installer/main/install_amneziawg_en.sh
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x install_amneziawg_en.sh
&lt;span class="nb"&gt;sudo &lt;/span&gt;bash ./install_amneziawg_en.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The installer asks a few questions (port, subnet, number of clients) - defaults work for most setups. Hit Enter through them or use &lt;code&gt;--yes&lt;/code&gt; for fully automatic mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;bash ./install_amneziawg_en.sh &lt;span class="nt"&gt;--yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It reboots twice (kernel updates). Just re-run the same script after each reboot - it picks up where it left off. Whole thing takes about 5 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 - Connect Your Devices
&lt;/h2&gt;

&lt;p&gt;After installation, you'll find client config files in &lt;code&gt;/root/awg/&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.conf&lt;/code&gt; files - import into any AmneziaWG client&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.png&lt;/code&gt; files - QR codes, scan from your phone&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.vpnuri&lt;/code&gt; files - one-tap import for Amnezia VPN app&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Which client to use:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Client&lt;/th&gt;
&lt;th&gt;Link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;All platforms&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Amnezia VPN&lt;/strong&gt; (recommended)&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/amnezia-vpn/amnezia-client/releases" rel="noopener noreferrer"&gt;Download&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows&lt;/td&gt;
&lt;td&gt;AmneziaWG&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/amnezia-vpn/amneziawg-windows-client/releases" rel="noopener noreferrer"&gt;Download&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Android&lt;/td&gt;
&lt;td&gt;AmneziaWG&lt;/td&gt;
&lt;td&gt;&lt;a href="https://play.google.com/store/apps/details?id=org.amnezia.awg" rel="noopener noreferrer"&gt;Google Play&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;iOS&lt;/td&gt;
&lt;td&gt;AmneziaWG&lt;/td&gt;
&lt;td&gt;&lt;a href="https://apps.apple.com/app/amneziawg/id6478942365" rel="noopener noreferrer"&gt;App Store&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Android (FOSS)&lt;/td&gt;
&lt;td&gt;WG Tunnel&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/wgtunnel/android" rel="noopener noreferrer"&gt;F-Droid / GitHub&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Quickest way:&lt;/strong&gt; Install Amnezia VPN on your phone, scan the QR code. Done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 - Verify
&lt;/h2&gt;

&lt;p&gt;Open a browser and go to &lt;a href="https://ifconfig.me" rel="noopener noreferrer"&gt;ifconfig.me&lt;/a&gt;. If you see your &lt;strong&gt;server's IP&lt;/strong&gt; instead of your home IP - you're on the VPN.&lt;/p&gt;

&lt;p&gt;On the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;awg show awg0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for &lt;code&gt;latest handshake&lt;/code&gt; under your peer - if it shows a recent timestamp, you're good.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing Clients
&lt;/h2&gt;

&lt;p&gt;Need to add a phone, laptop, or share access with someone?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Add a new client&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;bash /root/awg/manage_amneziawg.sh add my_laptop

&lt;span class="c"&gt;# Give someone temporary access (auto-expires)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;bash /root/awg/manage_amneziawg.sh add guest &lt;span class="nt"&gt;--expires&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;7d

&lt;span class="c"&gt;# See who's connected and how much traffic they used&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;bash /root/awg/manage_amneziawg.sh stats

&lt;span class="c"&gt;# Remove a client&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;bash /root/awg/manage_amneziawg.sh remove guest

&lt;span class="c"&gt;# List all clients&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;bash /root/awg/manage_amneziawg.sh list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each &lt;code&gt;add&lt;/code&gt; generates a new &lt;code&gt;.conf&lt;/code&gt; + QR code + &lt;code&gt;vpn://&lt;/code&gt; URI.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Running Under the Hood
&lt;/h2&gt;

&lt;p&gt;The installer sets up &lt;a href="https://docs.amnezia.org/documentation/amnezia-wg/" rel="noopener noreferrer"&gt;AmneziaWG 2.0&lt;/a&gt; - a WireGuard fork that randomizes packet headers, adds padding, and sends decoy packets before the handshake. DPI can't fingerprint it because every server speaks its own "dialect" of the protocol.&lt;/p&gt;

&lt;p&gt;It runs as a &lt;strong&gt;kernel module&lt;/strong&gt; (not the slower userspace Go implementation), so you get near-WireGuard speeds. The crypto is identical - Curve25519, ChaCha20-Poly1305, same as stock WireGuard.&lt;/p&gt;

&lt;p&gt;The installer also hardens the server - UFW firewall with deny-all policy, Fail2Ban, and some kernel/network tuning.&lt;/p&gt;

&lt;p&gt;I wrote a detailed breakdown of how the obfuscation works &lt;a href="https://dev.to/bivlked/amneziawg-20-self-host-an-obfuscated-wireguard-vpn-that-bypasses-dpi-4692"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want a more detailed guide?
&lt;/h2&gt;

&lt;p&gt;The full VPS deployment walkthrough lives at &lt;a href="https://github.com/bivlked/amneziawg-installer/blob/main/INSTALL_VPS.md" rel="noopener noreferrer"&gt;INSTALL_VPS.md&lt;/a&gt; on GitHub. It covers provider selection, OS choice, common troubleshooting (PPA fallback, DKMS recovery, mobile carrier patterns), and the full update + uninstall lifecycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's new since publication
&lt;/h2&gt;

&lt;p&gt;The installer keeps moving. v5.15.0 added opt-in dual-stack IPv6 inside the tunnel (&lt;code&gt;--allow-ipv6-tunnel&lt;/code&gt;), and v5.15.4 documented the AS-blocking workaround mentioned above. For what landed since, see the &lt;a href="https://github.com/bivlked/amneziawg-installer/releases" rel="noopener noreferrer"&gt;releases page&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;⭐ &lt;a href="https://github.com/bivlked/amneziawg-installer" rel="noopener noreferrer"&gt;&lt;strong&gt;amneziawg-installer&lt;/strong&gt; on GitHub&lt;/a&gt; - star it if it helped you&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/amnezia-vpn/amnezia-client/releases" rel="noopener noreferrer"&gt;Amnezia VPN Client&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.amnezia.org/documentation/amnezia-wg/" rel="noopener noreferrer"&gt;AmneziaWG 2.0 Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Router firmware with AWG support:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/hoaxisr/awg-manager" rel="noopener noreferrer"&gt;AWG Manager&lt;/a&gt; - Keenetic&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/r0otx/asuswrt-merlin-amneziawg" rel="noopener noreferrer"&gt;AmneziaWG for Merlin&lt;/a&gt; - ASUS&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Hit a problem? &lt;a href="https://github.com/bivlked/amneziawg-installer/issues" rel="noopener noreferrer"&gt;Open an issue&lt;/a&gt; or drop a comment below.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>devops</category>
      <category>selfhosted</category>
      <category>vpn</category>
    </item>
    <item>
      <title>AmneziaWG 2.0: Self-Host an Obfuscated WireGuard VPN That Bypasses DPI</title>
      <dc:creator>Ivan Bondarev</dc:creator>
      <pubDate>Wed, 11 Mar 2026 14:10:22 +0000</pubDate>
      <link>https://dev.to/bivlked/amneziawg-20-self-host-an-obfuscated-wireguard-vpn-that-bypasses-dpi-4692</link>
      <guid>https://dev.to/bivlked/amneziawg-20-self-host-an-obfuscated-wireguard-vpn-that-bypasses-dpi-4692</guid>
      <description>&lt;h2&gt;
  
  
  The Problem: WireGuard Is Easy to Block
&lt;/h2&gt;

&lt;p&gt;WireGuard is a great VPN protocol - fast, lean, well-audited crypto. But it has one glaring weakness: &lt;strong&gt;predictability&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Every WireGuard packet starts with a 4-byte header containing a message type: &lt;code&gt;1&lt;/code&gt; for handshake initiation, &lt;code&gt;2&lt;/code&gt; for response, &lt;code&gt;3&lt;/code&gt; for cookie, &lt;code&gt;4&lt;/code&gt; for data. The handshake init is always exactly 148 bytes. These are strong, static signatures that DPI systems fingerprint without breaking a sweat.&lt;/p&gt;

&lt;p&gt;And they do. WireGuard is actively blocked in &lt;strong&gt;10+ countries&lt;/strong&gt; right now. In Russia, standard WireGuard has roughly a 12% success rate. Iran sees 98% packet loss. China's Great Firewall picks it up within seconds. Egypt, Turkmenistan, Myanmar, Pakistan, UAE, Turkey, Belarus, Uzbekistan, Kazakhstan - all confirmed blocking or throttling at the DPI level.&lt;/p&gt;

&lt;p&gt;I'm based in Russia, and I watched this unfold firsthand. Through most of 2024, my WireGuard tunnels worked fine. Then they started dropping - not all at once, but ISP by ISP, week by week. Russia's TSPU (Technical Means of Countering Threats - essentially DPI boxes installed at every major provider) learned to identify WireGuard traffic and silently kill it. Handshakes just stopped completing. No error, no timeout message - the packets simply vanished.&lt;/p&gt;

&lt;p&gt;That's what pushed me to build an open-source installer for AmneziaWG 2.0, a WireGuard fork with protocol-level obfuscation. Here's how the protocol works under the hood, and how to get it running on your own server.&lt;/p&gt;

&lt;h2&gt;
  
  
  How DPI Catches WireGuard
&lt;/h2&gt;

&lt;p&gt;Standard WireGuard uses fixed 32-bit message types for its four packet types. A DPI system needs a trivially simple heuristic:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;UDP packet&lt;/strong&gt; + &lt;strong&gt;known header value (1-4)&lt;/strong&gt; + &lt;strong&gt;predictable packet size&lt;/strong&gt; = WireGuard&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Handshake init is always 148 bytes. Response is always 92 bytes. These invariant sizes are a dead giveaway. Once the DPI box flags a WireGuard session, it can block the IP, throttle the connection, or silently drop every packet.&lt;/p&gt;

&lt;h2&gt;
  
  
  What AmneziaWG 2.0 Does About It
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.amnezia.org/documentation/amnezia-wg/" rel="noopener noreferrer"&gt;AmneziaWG&lt;/a&gt; is a WireGuard fork by the &lt;a href="https://amnezia.org/" rel="noopener noreferrer"&gt;Amnezia VPN&lt;/a&gt; team. It changes the transport layer to resist DPI while leaving the cryptographic core (Curve25519, ChaCha20-Poly1305, Noise IK) untouched.&lt;/p&gt;

&lt;p&gt;The first version (AWG 1.x) replaced standard headers with custom fixed values. Helped for a while, but a patient DPI system could learn the new static values just as well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWG 2.0&lt;/strong&gt; (late 2025) took a different path: randomize everything, every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the Obfuscation Actually Works
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Dynamic Headers (H1-H4)
&lt;/h3&gt;

&lt;p&gt;Instead of fixed header values, AWG 2.0 uses &lt;strong&gt;ranges&lt;/strong&gt;. Every time a packet goes out, a random value is picked from within the configured range:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;H1&lt;/span&gt; = &lt;span class="m"&gt;100000&lt;/span&gt;-&lt;span class="m"&gt;800000&lt;/span&gt;         &lt;span class="c"&gt;# Handshake init
&lt;/span&gt;&lt;span class="n"&gt;H2&lt;/span&gt; = &lt;span class="m"&gt;1000000&lt;/span&gt;-&lt;span class="m"&gt;8000000&lt;/span&gt;       &lt;span class="c"&gt;# Handshake response
&lt;/span&gt;&lt;span class="n"&gt;H3&lt;/span&gt; = &lt;span class="m"&gt;10000000&lt;/span&gt;-&lt;span class="m"&gt;80000000&lt;/span&gt;     &lt;span class="c"&gt;# Cookie
&lt;/span&gt;&lt;span class="n"&gt;H4&lt;/span&gt; = &lt;span class="m"&gt;100000000&lt;/span&gt;-&lt;span class="m"&gt;800000000&lt;/span&gt;   &lt;span class="c"&gt;# Data transport
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ranges must not overlap - the protocol still needs to tell packet types apart. But the result is that &lt;strong&gt;every packet looks different on the wire&lt;/strong&gt;. There's no single header value for DPI to latch onto.&lt;/p&gt;

&lt;h3&gt;
  
  
  Random Padding (S1-S4)
&lt;/h3&gt;

&lt;p&gt;AWG pads packets with random bytes to break the fixed-size signatures:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Packet Type&lt;/th&gt;
&lt;th&gt;What happens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;S1&lt;/td&gt;
&lt;td&gt;Handshake init&lt;/td&gt;
&lt;td&gt;Init becomes 148 + S1 bytes (bye-bye fixed 148)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S2&lt;/td&gt;
&lt;td&gt;Handshake response&lt;/td&gt;
&lt;td&gt;Response becomes 92 + S2 bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;S3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cookie &lt;em&gt;(new in 2.0)&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;Pads cookie packets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;S4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Data transport &lt;em&gt;(new in 2.0)&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;Pads &lt;strong&gt;every&lt;/strong&gt; data packet&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;S3 and S4 are the big additions in 2.0. S4 matters most - it touches every single data packet, which makes traffic analysis across the whole session much harder.&lt;/p&gt;

&lt;p&gt;One gotcha: &lt;code&gt;S1 + 56&lt;/code&gt; must not equal &lt;code&gt;S2&lt;/code&gt;. Why? Because 148 - 92 = 56, so if the padding values differ by exactly 56, the padded init and padded response end up the same size. That's a pattern you don't want.&lt;/p&gt;

&lt;h3&gt;
  
  
  CPS - Custom Protocol Signature (I1-I5)
&lt;/h3&gt;

&lt;p&gt;Before the real WireGuard handshake, the client sends &lt;strong&gt;decoy packets&lt;/strong&gt; that mimic another protocol's signature.&lt;/p&gt;

&lt;p&gt;Parameters I1 through I5 define the content of up to 5 decoy packets using a tag format:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tag&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;b 0xHEX&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Insert specific bytes (hex-encoded)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;r N&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;N cryptographically random bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;rc N&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;N random alphanumeric chars [A-Za-z0-9]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;rd N&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;N random decimal digits [0-9]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;t&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Current UNIX timestamp (4 bytes)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;c&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Packet counter (4 bytes)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Simple version: &lt;code&gt;&amp;lt;r 128&amp;gt;&lt;/code&gt; - blast 128 random bytes. DPI sees a random UDP packet from who-knows-what.&lt;/p&gt;

&lt;p&gt;Sneakier version: &lt;code&gt;&amp;lt;b 0xc000000001&amp;gt;&amp;lt;r 64&amp;gt;&amp;lt;t&amp;gt;&lt;/code&gt; - starts with bytes that look like a QUIC Initial packet header, then random data, then a timestamp. A DPI box might classify this as the start of a normal QUIC session.&lt;/p&gt;

&lt;p&gt;The server ignores CPS packets entirely - it just waits for the real handshake init that comes after.&lt;/p&gt;

&lt;p&gt;In 2026 this stopped being theoretical. When traffic to an entire hosting network is cut at the AS level (Hetzner AS24940 is the best-known case: handshake passes, then data dies), a generic random I1 does not help - but an I1 that mimics a QUIC Initial with an allowlisted SNI inside can break through. Which SNI works turned out to be operator-specific, so expect some trial and error. Symptom, tooling and field results are written up in &lt;a href="https://github.com/bivlked/amneziawg-installer/blob/main/ADVANCED.en.md#as-blocking-adv" rel="noopener noreferrer"&gt;ADVANCED&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Junk Packets (Jc, Jmin, Jmax)
&lt;/h3&gt;

&lt;p&gt;Before each handshake, the client fires off &lt;code&gt;Jc&lt;/code&gt; junk packets with random sizes between &lt;code&gt;Jmin&lt;/code&gt; and &lt;code&gt;Jmax&lt;/code&gt; bytes. Pure noise that makes the connection setup profile less recognizable.&lt;/p&gt;

&lt;h3&gt;
  
  
  What This All Adds Up To
&lt;/h3&gt;

&lt;p&gt;Each AmneziaWG 2.0 server ends up with its own &lt;strong&gt;unique parameter set&lt;/strong&gt;. There's no universal DPI signature that catches all AWG 2.0 traffic - every server is, in effect, speaking its own dialect.&lt;/p&gt;

&lt;p&gt;Here's the 1.x-to-2.0 changelog:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;AWG 1.x&lt;/th&gt;
&lt;th&gt;AWG 2.0&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;H1-H4&lt;/td&gt;
&lt;td&gt;Fixed values&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Ranges&lt;/strong&gt; (random per packet)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S1-S2&lt;/td&gt;
&lt;td&gt;Padding for init/response&lt;/td&gt;
&lt;td&gt;Unchanged&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;New:&lt;/strong&gt; cookie padding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S4&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;New:&lt;/strong&gt; data packet padding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;I1-I5 (CPS)&lt;/td&gt;
&lt;td&gt;Late addition&lt;/td&gt;
&lt;td&gt;Fully supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jc/Jmin/Jmax&lt;/td&gt;
&lt;td&gt;Junk packets&lt;/td&gt;
&lt;td&gt;Unchanged&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Crypto&lt;/td&gt;
&lt;td&gt;WireGuard (untouched)&lt;/td&gt;
&lt;td&gt;WireGuard (untouched)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What About Speed?
&lt;/h2&gt;

&lt;p&gt;People always ask this, so let's get it out of the way.&lt;/p&gt;

&lt;p&gt;You might have seen a "65% overhead" number floating around online. The AmneziaWG developers &lt;a href="https://github.com/amnezia-vpn/amnezia-client/issues/526" rel="noopener noreferrer"&gt;tracked that down&lt;/a&gt; to the &lt;strong&gt;userspace Go implementation&lt;/strong&gt; (amneziawg-go), not the protocol itself. The &lt;strong&gt;kernel module&lt;/strong&gt; (what my installer uses via DKMS) runs at near-WireGuard speeds.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;WireGuard&lt;/th&gt;
&lt;th&gt;AmneziaWG 2.0&lt;/th&gt;
&lt;th&gt;OpenVPN&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Crypto overhead&lt;/td&gt;
&lt;td&gt;~4%&lt;/td&gt;
&lt;td&gt;~4% (same crypto)&lt;/td&gt;
&lt;td&gt;~15-20%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Obfuscation overhead&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;+3-7% (padding/junk)&lt;/td&gt;
&lt;td&gt;+10% (obfs4)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total overhead&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~4%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&amp;lt;12%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~25-28%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Battery drain (4h streaming)&lt;/td&gt;
&lt;td&gt;18%&lt;/td&gt;
&lt;td&gt;19% (+1%)&lt;/td&gt;
&lt;td&gt;~25%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Real-world benchmark on an uncensored network: WireGuard 95 Mbps, AmneziaWG 92 Mbps. That's a 3% difference - you won't notice it.&lt;/p&gt;

&lt;p&gt;And in a censored network? The comparison is "92 Mbps vs 0 Mbps." If WireGuard is blocked, raw speed numbers don't mean much.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Stacks Up Against Alternatives
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;WireGuard&lt;/th&gt;
&lt;th&gt;AmneziaWG 2.0&lt;/th&gt;
&lt;th&gt;OpenVPN+obfs4&lt;/th&gt;
&lt;th&gt;Shadowsocks&lt;/th&gt;
&lt;th&gt;VLESS+Reality&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DPI resistance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Low (detectable)&lt;/td&gt;
&lt;td&gt;Very High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Speed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fastest&lt;/td&gt;
&lt;td&gt;Near-WG (&amp;lt;12% OH)&lt;/td&gt;
&lt;td&gt;Slow (~25% OH)&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Medium-Fast&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Full VPN tunnel&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No (proxy)&lt;/td&gt;
&lt;td&gt;No (proxy)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Runs in kernel&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (DKMS)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Setup complexity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Simple&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Simple (installer)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Complex&lt;/td&gt;
&lt;td&gt;Simple (Outline)&lt;/td&gt;
&lt;td&gt;Complex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Transport&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;UDP&lt;/td&gt;
&lt;td&gt;UDP (obfuscated)&lt;/td&gt;
&lt;td&gt;TCP/UDP + TLS&lt;/td&gt;
&lt;td&gt;TCP&lt;/td&gt;
&lt;td&gt;TCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Audited crypto&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Inherits WG audit&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;No DPI in your country? Plain WireGuard is simpler, just use that. Need the absolute maximum DPI resistance and OK with a proxy? VLESS+Reality is worth a look, but it's a proxy, not a VPN tunnel. AmneziaWG 2.0 fills the gap between them: WireGuard-grade performance with real obfuscation in a full tunnel.&lt;/p&gt;

&lt;h2&gt;
  
  
  One-Command Setup
&lt;/h2&gt;

&lt;p&gt;Setting up AmneziaWG 2.0 by hand means building a kernel module, generating 10+ obfuscation parameters with the right constraints, writing server and client configs, configuring firewall rules. Lots of moving parts, lots of places to get something wrong.&lt;/p&gt;

&lt;p&gt;I automated all of it in &lt;a href="https://github.com/bivlked/amneziawg-installer" rel="noopener noreferrer"&gt;&lt;strong&gt;amneziawg-installer&lt;/strong&gt;&lt;/a&gt;. It builds the &lt;strong&gt;kernel module&lt;/strong&gt; via DKMS (not the slower Go userspace implementation), so you get the speed numbers from the table above.&lt;/p&gt;

&lt;h3&gt;
  
  
  What You Need
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;clean&lt;/strong&gt; Ubuntu 24.04 / 25.10 or Debian 12 / 13 server&lt;/li&gt;
&lt;li&gt;Root SSH access&lt;/li&gt;
&lt;li&gt;~1 GB RAM (any $2-4/month VPS is enough)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Install
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget &lt;span class="nt"&gt;-O&lt;/span&gt; install_amneziawg_en.sh https://raw.githubusercontent.com/bivlked/amneziawg-installer/main/install_amneziawg_en.sh
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x install_amneziawg_en.sh
&lt;span class="nb"&gt;sudo &lt;/span&gt;bash ./install_amneziawg_en.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The script walks through 8 steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;System hardening&lt;/strong&gt; - strips bloat (snapd, modemmanager), tunes kernel params (BBR, network buffers), sets up swap&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DKMS build&lt;/strong&gt; - installs the AmneziaWG kernel module from &lt;a href="https://launchpad.net/~amnezia/+archive/ubuntu/ppa" rel="noopener noreferrer"&gt;Amnezia PPA&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Firewall&lt;/strong&gt; - UFW with deny-all default, SSH rate-limiting, VPN port only&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Config generation&lt;/strong&gt; - all AWG 2.0 parameters auto-generated with proper constraints, server + client configs + QR codes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service start&lt;/strong&gt; - Fail2Ban, awg-quick@awg0 enabled and running&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Two reboots happen along the way (kernel updates + module loading). The script saves its state, so you just re-run it after each reboot and it picks up where it left off.&lt;/p&gt;

&lt;h3&gt;
  
  
  Non-Interactive Mode
&lt;/h3&gt;

&lt;p&gt;For scripted or automated deployments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;bash ./install_amneziawg_en.sh &lt;span class="nt"&gt;--port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;51820 &lt;span class="nt"&gt;--disallow-ipv6&lt;/span&gt; &lt;span class="nt"&gt;--route-amnezia&lt;/span&gt; &lt;span class="nt"&gt;--yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since v5.15.0 you can also enable dual-stack IPv6 inside the tunnel with &lt;code&gt;--allow-ipv6-tunnel&lt;/code&gt; (off by default). Clients then get a ULA IPv6 address next to IPv4, and with native IPv6 on the server the client routes &lt;code&gt;::/0&lt;/code&gt; through the tunnel. Existing IPv4-only clients keep working; recreate a client (&lt;code&gt;remove&lt;/code&gt; + &lt;code&gt;add&lt;/code&gt;) to make it dual-stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing Clients
&lt;/h2&gt;

&lt;p&gt;After installation, use the management script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Add a client (generates .conf + QR code + vpn:// URI)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;bash /root/awg/manage_amneziawg.sh add my_phone

&lt;span class="c"&gt;# List all clients&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;bash /root/awg/manage_amneziawg.sh list

&lt;span class="c"&gt;# Remove a client&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;bash /root/awg/manage_amneziawg.sh remove my_phone

&lt;span class="c"&gt;# Check server status&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;bash /root/awg/manage_amneziawg.sh check

&lt;span class="c"&gt;# Temporary client - auto-removed after 7 days&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;bash /root/awg/manage_amneziawg.sh add guest &lt;span class="nt"&gt;--expires&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;7d

&lt;span class="c"&gt;# Traffic stats per client&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;bash /root/awg/manage_amneziawg.sh stats

&lt;span class="c"&gt;# Backup all configs&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;bash /root/awg/manage_amneziawg.sh backup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Connect using any client with AWG 2.0 support:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/amnezia-vpn/amnezia-client/releases" rel="noopener noreferrer"&gt;&lt;strong&gt;Amnezia VPN&lt;/strong&gt;&lt;/a&gt; - full-featured, all platforms (&amp;gt;= 4.8.12.7)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/amnezia-vpn/amneziawg-windows-client/releases" rel="noopener noreferrer"&gt;&lt;strong&gt;AmneziaWG&lt;/strong&gt;&lt;/a&gt; - lightweight tunnel manager, Windows (&amp;gt;= 2.0.0)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/artem4150/VeilBox" rel="noopener noreferrer"&gt;&lt;strong&gt;VeilBox&lt;/strong&gt;&lt;/a&gt; - open-source, Windows/macOS&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Checking That It Works
&lt;/h2&gt;

&lt;p&gt;On the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;awg show awg0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for &lt;code&gt;latest handshake&lt;/code&gt; under your peer. If it's there, the AWG 2.0 handshake went through.&lt;/p&gt;

&lt;p&gt;From the client side:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl ifconfig.me
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see your server's IP instead of your home IP - you're connected through the VPN.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;I've been running this on my own servers for several months now. From Russia, through ISPs with active TSPU filtering, AWG 2.0 connections hold where stock WireGuard has been dead since mid-2025. The crypto hasn't changed, so every WireGuard audit still applies. The overhead? Under 12% on paper, closer to 3% in my testing. And since the installer uses the kernel module, you skip the userspace performance hit entirely.&lt;/p&gt;

&lt;p&gt;If you're in a country where WireGuard stopped working, give it a shot. And if you run into issues or have suggestions, I'd genuinely like to hear about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full deployment walkthrough
&lt;/h2&gt;

&lt;p&gt;For a step-by-step VPS-side walkthrough covering provider selection (Hetzner CAX, Oracle Free Tier ARM, generic), OS choice, install flow, first client setup, update flow, uninstall, and troubleshooting common issues - see the canonical install guide on GitHub: &lt;a href="https://github.com/bivlked/amneziawg-installer/blob/main/INSTALL_VPS.md" rel="noopener noreferrer"&gt;INSTALL_VPS.md&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/bivlked/amneziawg-installer" rel="noopener noreferrer"&gt;amneziawg-installer on GitHub&lt;/a&gt; - star it if it's useful to you&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.amnezia.org/documentation/amnezia-wg/" rel="noopener noreferrer"&gt;AmneziaWG 2.0 Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/amnezia-vpn/amnezia-client/releases" rel="noopener noreferrer"&gt;Amnezia VPN Client&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://spatiumstas.github.io/junker/" rel="noopener noreferrer"&gt;Junker - AmneziaWG Signature Generator&lt;/a&gt; (for manual setup)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Router firmware with AWG support:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/hoaxisr/awg-manager" rel="noopener noreferrer"&gt;AWG Manager&lt;/a&gt; - Keenetic routers&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/r0otx/asuswrt-merlin-amneziawg" rel="noopener noreferrer"&gt;AmneziaWG for Merlin&lt;/a&gt; - ASUS routers with GeoIP/GeoSite routing&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Questions, bugs, feature requests? Open an issue on &lt;a href="https://github.com/bivlked/amneziawg-installer/issues" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; or leave a comment here.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>vpn</category>
      <category>opensource</category>
      <category>linux</category>
      <category>selfhosted</category>
    </item>
  </channel>
</rss>
