Skip to content

Architecture

Next1971 edited this page Oct 17, 2026 · 5 revisions

Architecture

MASQUE VPN is an experimental, self-hosted IP VPN. You run a Linux server on your VPS, maintain a private certificate authority, and issue a separate client profile for each device.

This page describes the v2.1.0 architecture. Exact commands and configuration formats belong in the versioned documentation beside the code.

1. High-level design

The clients capture IP packets through the operating system's VPN interface and pass them to a shared Go core. The core carries those packets to the server using CONNECT-IP.

The server forwards tunnel traffic through its Linux networking stack and out through the VPS.

Applications
    |
OS routing / VPN interface
    |
Shared Go client core
    |
    +-- HTTP/3 CONNECT-IP over QUIC / UDP --+
    |                                      |
    +-- HTTP/2 CONNECT-IP over TLS / TCP ---+
                                           |
                                  MASQUE server
                                           |
                                    Linux TUN
                                           |
                                  Forwarding / NAT
                                           |
                                  VPS WAN / Internet

Traffic exits at the VPS. This is not a public VPN service, an anonymity network, or a multi-hop system.

2. Two transports, one VPN model

The v2.1.0 server listens on UDP and TCP using the same port number.

Transport Role VPN authentication
HTTP/3 over QUIC / UDP Normal tunnel transport Client certificate signed by the private CA
HTTP/2 over TLS / TCP Alternative tunnel transport Valid client certificate plus an HTTP/2 CONNECT-IP request

UDP and TCP are separate network transports. Allowing a port for UDP in a firewall does not automatically allow the same port for TCP. Enable both in the host firewall and cloud security group when both are required.

TCP support does not turn the project into a general-purpose HTTP proxy. The VPN still carries IP traffic through CONNECT-IP.

Client transport selection

Android phone, Android TV, and Windows v2.1.0 expose:

  • Automatic
  • UDP only
  • TCP only

Automatic is a connectivity mode, not a guarantee that the client continuously benchmarks both transports or chooses the fastest one.

The older v2.0.0 experiment had no manual transport selector and started TCP only after an unanswered UDP probe. Do not use that older interface description for v2.1.0.

iOS 2.0 on TestFlight supports UDP and TCP with this server. Transport compatibility does not imply that every platform has identical UI controls.

3. TCP website versus VPN access

The TCP listener has two distinct outcomes:

Incoming TCP / TLS connection
    |
    +-- Valid client certificate
    |   + HTTP/2 CONNECT-IP request
    |       |
    |       +--> Authenticated VPN tunnel
    |
    +-- Browser / probe / no valid client certificate
            |
            +--> HTML page, not VPN access

On TCP, the TLS handshake requests a client certificate but does not require one merely to establish the connection. The server still requires a valid client certificate before opening the VPN tunnel.

A browser, a missing certificate, or an invalid client certificate receives an HTML page rather than tunnel access.

The server certificate remains signed by the project's private CA. A normal browser therefore shows a certificate warning before the page. This is not a publicly trusted HTTPS website.

UDP does not serve a website.

Seeing the TCP page proves neither that client authentication succeeds nor that forwarding, NAT, DNS, or the VPN tunnel works.

4. Trust and credentials

A private certificate authority signs:

  • The server certificate.
  • A separate client certificate for each device.

Clients verify the server using the private CA and the configured server identity. The server verifies client credentials before granting VPN access.

A real profile.masque contains sensitive credentials, including a client private key. Treat the complete profile as a secret.

Operational rules:

  • Issue one bundle per device.
  • Do not share one active profile between multiple devices.
  • Keep CA, server, and client private keys out of Git.
  • Transfer profiles through a secure channel.
  • Back up ca.key securely.
  • Keep insecure = false.

The experimental Windows VPS installer can issue and revoke client configurations. Server-side CN blocking is a denylist mechanism, not a certificate revocation list.

See the security policy and client configuration guide.

5. Shared core and platform integration

The server and shared Go client core live under:

android/go-src/masque-vpn/

Despite that directory name, the Go module is not Android-only.

Platform Native integration
Android / Android TV Kotlin UI, Android VpnService, Go core through gomobile
Windows Windows service, GUI, MSI installer, Wintun
iOS Swift app, Packet Tunnel Network Extension, Go core through gomobile
Linux server Go server, Linux TUN, forwarding and NAT

Native code handles platform-specific lifecycle, permissions, profile import, and VPN-interface integration. The shared Go core handles tunnel connectivity and packet forwarding.

On iOS, the Go core runs inside the Packet Tunnel extension rather than the host application.

6. Address assignment and reconnect

Tunnel addresses are assigned by the server.

The server maintains stable address assignments by client certificate Common Name (CN). This allows a reconnecting device to retain its tunnel identity instead of receiving a different address on every connection.

The server also demultiplexes return traffic to the appropriate client session.

Android uses a two-phase setup: establish the tunnel session, receive the assigned address, then create the VPN interface and start forwarding packets.

Android reconnect handling can retain the TUN interface while rebuilding the transport session after a network change. This is reconnect behavior, not a guarantee of uninterrupted connectivity on every device or network.

The underlying server connection must stay outside the VPN route to avoid routing the tunnel into itself. How this is implemented depends on the platform.

7. IPv4 and IPv6

Two different features must be distinguished:

  1. Transport addressing: reaching the VPS over IPv4 or IPv6.
  2. Inner tunnel addressing: carrying IPv4 or IPv6 packets inside the VPN.

Support for one does not automatically configure the other.

The project supports IPv6 QUIC transport and dual-stack server binding. Optional IPv6 tunnel addressing uses the configured IPv6 pool and requires appropriate forwarding and WAN connectivity on the VPS.

For IPv6 inside the tunnel, configure the server, client routes, forwarding, and NAT rules consistently. A reachable IPv6 server address alone is not sufficient.

Use documentation matching the deployed release, especially when older clients are still in use.

8. MTU, statistics, and ping

Android phone, Android TV, and Windows v2.1.0 expose a configurable tunnel MTU with a default of 1340.

This is the client tunnel MTU, not a claim that every physical network has an MTU of 1340. The server TUN configuration is a separate setting.

The default followed testing on particular network paths. It is not a universal optimum, and results from one mobile connection do not establish that UDP or TCP is always faster.

These clients also provide:

  • An optional kill switch, off by default.
  • Day/month traffic statistics.
  • Ping during TCP sessions.

On QUIC connections, ping is the smoothed QUIC round-trip time to the server. TCP-session ping must not be described as QUIC RTT.

Kill-switch guarantees depend on the operating system and application lifecycle. In particular, Android's application-level kill switch should not be confused with the OS-level Always-on VPN / Block connections without VPN settings.

9. Server deployment

The same server architecture can be deployed through:

  • Manual Linux installation.
  • install.sh for a fresh installation.
  • Experimental Docker Compose packaging.
  • The experimental Windows VPS Setup Helper.

Docker requires host networking, NET_ADMIN, and /dev/net/tun. Certificates and configuration are supplied separately; they are not embedded in the server binary.

The v2.1.0 Windows Setup Helper deploys UDP and TCP, supports an optional second port, and displays a profile QR code.

install.sh verifies release checksums and refuses to overwrite an existing CA, configuration, or service. Do not treat it as an in-place upgrade command.

Updating the server does not require replacing the existing CA or issuing new profiles merely because the binary changed.

See the server installation guide.

10. Version compatibility

Client Server Available transport
Older UDP client, including v1.7.1 v2.1.0 UDP
v2.0.0 / v2.1.0 v2.1.0 UDP and TCP
v2.1.0 Older UDP-only server UDP
iOS 2.0 TestFlight v2.1.0 UDP and TCP
Older iOS 1.7 TestFlight v2.1.0 UDP

TCP requires a server with the HTTP/2 CONNECT-IP implementation: v2.0.0 or v2.1.0.

The v2.0.0 TCP listener required a client certificate during the handshake and did not serve a website. The browser-facing HTML behavior described on this page belongs to v2.1.0.

Existing profiles and certificates remain compatible with v2.1.0.

11. Security boundaries and limitations

  • Encryption protects the client-to-VPS tunnel. It does not make the VPS operator unable to inspect traffic leaving the tunnel.
  • Application-level end-to-end encryption, such as HTTPS, remains separate from VPN encryption.
  • Tunnel DNS currently uses plaintext DNS inside the tunnel; this is not built-in DoH or DoT.
  • The TCP HTML page does not make the server publicly trusted, indistinguishable from every ordinary website, or guaranteed to evade filtering.
  • Availability and performance depend on the client network, VPS, firewall rules, MTU, and platform behavior.
  • The project is experimental and has not undergone an independent security audit.

Further reading