LifeFarmer IronGuard

v0.3.2 March 27, 2026 GPL-3.0-or-later macOS and Linux

A WireGuard tunnel, built again in Rust.

IronGuard is a from-scratch WireGuard implementation. Homebrew installs the tunnel and a manager. You describe the interface in wg.json, then bring it up.

Cross-section of the tunnel. The ruler is the 16-byte v2 frame header. The block on the wire is one frame.

  • type 1
  • flags 1
  • reserved 2
  • receiver 4
  • counter 8
brew tap dickwu/tap
brew install ironguard

Same formula, one command. brew install dickwu/tap/ironguard

Bring a tunnel up

Do these in order. The commands are the ones in the repository README and the Homebrew tap.

  1. Install both binaries

    Tap dickwu/tap, then install ironguard. The formula puts ironguard and ironguard-tui on your PATH.

    brew tap dickwu/tap
    brew install ironguard
  2. Make a key pair

    genkey prints a private key. pubkey reads a private key on stdin and prints the public key. genpsk prints a pre-shared key.

    ironguard genkey > private.key
    ironguard pubkey < private.key
  3. Write wg.json

    Point private_key_file at the key, set an address, and add peers. The file has to be JSON. Comments are not allowed. A full example is below. Validate it before you open a device.

    ironguard validate wg.json
  4. Bring the interface up

    This is the command from the tap README. utun9 is the interface name in that example, and it has to be a key in your wg.json. On Linux the key is whatever you named the interface, such as wg0 in the TUI setup example. Creating the TUN device needs root. If you are not root, ironguard up re-runs itself with sudo. ironguard down utun9 stops that interface. ironguard status lists what the file configures.

    sudo ironguard up utun9 --config wg.json --foreground

Or let the manager build the server

Run ironguard-tui with no arguments for the dashboard. The README's non-interactive example is the three commands below. setup detects Linux or macOS, writes /etc/ironguard/wg.json, generates keys under /etc/ironguard/keys/, and registers systemd or launchd. client create makes a key pair, picks the next address from 10.0.0.2, and adds the peer. Run restart after you add or remove a client.

sudo ironguard-tui setup
sudo ironguard-tui client create laptop --endpoint=vpn.example.com:51820
sudo ironguard-tui start

On the wire

Taken from the v0.3.2 sources, the repository README, and the Homebrew formula. The schema tables live in the README.

Frame
16-byte v2 header: type, flags, reserved, receiver id, counter. In the source the type byte starts at 0x04 for data, then 0x05 keepalive, 0x06 control, and 0x07 batch, so the header can share the wire with older handshake messages.
AEAD
AES-256-GCM through ring. The project README reports 2.5 to 3.6 times the speed of ChaCha20-Poly1305 on AES-NI hardware.
Keys
X25519 for key exchange. HKDF-SHA256 derives epoch keys. Private key material is zeroed on drop.
Routing
Crypto-key routing with longest-prefix match tables for IPv4 and IPv6. Anti-replay is an RFC 6479 window of 2048 bits. Each peer has five timers.
QUIC
A Cargo feature, compiled into the release binaries. The README says tunnel packets can ride inside QUIC on networks that block UDP: unreliable datagrams first, length-prefixed streams if datagrams are unavailable. quic.mode is handshake_only (the schema default) or full_transport. The handshake port is quic.port, or the listen port plus one. ironguard gen-quic-cert writes an mTLS certificate.
Pipeline
Tokio workers batch TUN and UDP I/O. A batch flushes on count, size, or timeout. The buffer pool has two tiers: 8192 buffers of 2 KB and 128 of 64 KB. Each peer has a reorder buffer.
Systems
macOS uses utun, sendmsg_x / recvmsg_x, and kernel buffer tuning. Linux uses a TUN device, sendmmsg / recvmmsg, and GSO/GRO. The formula publishes archives for macOS Apple Silicon, macOS Intel, Linux x86_64, and Linux ARM64.
NAT
The README’s connectivity crate does STUN binding requests, coordinated UDP hole punching, a birthday-paradox spray for symmetric NAT, UPnP port mapping, mDNS on the LAN, and a QUIC relay.
Config
wg.json holds interfaces, addresses, peers, DNS names in endpoints, masquerade, and post_up / post_down hooks. A peer can carry allowed IPs, a keepalive, a pre-shared key file, and an ACL of destination CIDRs. ironguard import and ironguard export convert standard WireGuard .conf files.
Post-quantum
The schema has post_quantum set to false, true, or strict, and a per-peer pq_public_key documented as an ML-KEM-768 public key. The Homebrew tap describes that cryptography as optional and feature-gated.

A wg.json file

The example from the repository README. The public key there is a placeholder. Secrets stay in private.key, not in the JSON.

wg.json

{
  "$schema": "ironguard/v1",
  "interfaces": {
    "utun9": {
      "private_key_file": "./private.key",
      "listen_port": 51820,
      "address": ["10.0.0.1/24"],
      "mtu": 1420,
      "quic": {
        "port": 51821,
        "sni": "vpn.example.com"
      },
      "peers": [
        {
          "public_key": "abc123...",
          "endpoint": "vpn.example.com:51820",
          "allowed_ips": ["10.0.0.2/32"],
          "persistent_keepalive": 25
        }
      ]
    }
  }
}

Keys load from a file or an environment variable, hex or base64. More fields, including DNS, fwmark, and per-peer ACLs, are in the README. Sample files are in configs/.

Without Homebrew

The formula installs the v0.3.2 archives. You can fetch those same files, or build the workspace.

Each archive contains ironguard and ironguard-tui. After it unpacks, move both binaries onto your PATH: sudo mv ironguard ironguard-tui /usr/local/bin/.

macOS Apple Silicon curl -sL https://github.com/dickwu/ironguard/releases/download/v0.3.2/ironguard-macos-aarch64.tar.gz | tar xz
macOS Intel curl -sL https://github.com/dickwu/ironguard/releases/download/v0.3.2/ironguard-macos-x86_64.tar.gz | tar xz
Linux x86_64 curl -sL https://github.com/dickwu/ironguard/releases/download/v0.3.2/ironguard-linux-x86_64.tar.gz | tar xz
Linux ARM64 curl -sL https://github.com/dickwu/ironguard/releases/download/v0.3.2/ironguard-linux-aarch64.tar.gz | tar xz

v0.3.2 release · All releases · Formula ironguard.rb

Questions

Something missing belongs in the issue tracker.

What is IronGuard?

IronGuard is a from-scratch WireGuard implementation in Rust. The tunnel binary is ironguard. The manager is ironguard-tui. Configuration is a JSON file named wg.json. It runs on macOS and Linux.

How do I install it with Homebrew?

Run brew tap dickwu/tap, then brew install ironguard. The formula installs both ironguard and ironguard-tui. brew install dickwu/tap/ironguard is the same formula in one command.

Which systems have prebuilt binaries?

The Homebrew formula ships macOS Apple Silicon, macOS Intel, Linux x86_64, and Linux ARM64. The formula version is 0.3.2, released March 27, 2026. The license is GPL-3.0-or-later.

How do I bring a tunnel up?

Write a private key with ironguard genkey, derive the public key with ironguard pubkey, and put the path to the private key in wg.json. Then run sudo ironguard up utun9 --config wg.json --foreground. Creating the TUN device needs root. If you are not root, ironguard up re-runs itself with sudo.

Can it read a standard WireGuard conf file?

Yes. ironguard import reads a .conf file and writes wg.json. ironguard export writes one interface from wg.json back to .conf.

How does QUIC use ports?

QUIC is a Cargo feature, and the release builds include it. The handshake port is quic.port when that field is set, otherwise the listen port plus one. The client connects to the peer endpoint port plus one, and both ports have to be reachable. The README says QUIC prefers unreliable datagrams and falls back to streams.

What does ironguard-tui do?

With no arguments it opens a dashboard of status, peers, and logs. Subcommands cover setup, client create, start, stop, restart, status, logs, peers, and server-key. setup registers systemd on Linux or launchd on macOS, writes /etc/ironguard/wg.json, and generates keys under /etc/ironguard/keys/.

Where is the source?

The formula homepage and the source repository are https://github.com/dickwu/ironguard. This page is part of the LifeFarmer catalog at https://lifefarmer.ca.

Install IronGuard

Two commands. Both binaries. Then a JSON file and an interface name.

brew tap dickwu/tap
brew install ironguard