Skip to content

Add Anti-Censorship features support and udp over tcp obfuscator on Linux and Android#11275

Open
encrypt94 wants to merge 20 commits into
mainfrom
marco/add-obfuscators
Open

Add Anti-Censorship features support and udp over tcp obfuscator on Linux and Android#11275
encrypt94 wants to merge 20 commits into
mainfrom
marco/add-obfuscators

Conversation

@encrypt94
Copy link
Copy Markdown
Collaborator

@encrypt94 encrypt94 commented May 13, 2026

Description

This PR adds support for anti-censorship features / obfuscators.
A new menu similar to "Privacy Features" , allows users to configure the following anti-censorship features when available on the platform (the menu item will be hidden if a feature is not available.)

  • Connect using port 53 - not an obfuscation method, simply exposes an existing feature and allows the user to always use port 53 (compatible with LWO)
  • Udp over Tcp - the only obfuscator implemented in this pr, uses udp over tcp crate to tunnel WireGuard traffic over TCP
  • Lighweight obfuscation - lighweight WireGuard scrambler, planned as the next obfuscator
  • MASQUE - tunnel WireGuard traffic over CONNECT-UDP
  • Shadowsocks - tunnel WireGuard traffic over shadowsocks
    obfuscators description strings and anti-censorship help text can be improved, help is super appreciated :)

Obfuscators are implemented in a Rust crate located under the obfuscators/ directory.
An obfuscator acts as a local UDP proxy running on a local UDP port, the outbound sockets must be protected to avoid traffic loops.

On Linux (and Windows in the future except for the marking part):

  • The crate produces a standalone binary (mozilla-obfuscator) installed alongside the daemon.
  • When the VPN is turned on or a server switch occurs, the obfuscator is launched.
  • The obfuscator requires CAP_NET_ADMIN privileges to set SO_MARK.
  • The obfuscator listens on a free port and writes the port to stdout.
  • The MozillaVPN daemon parses the port from stdout and rewrites the server/port in WireGuard's peer config (alternatively, we can probe a free port in the daemon and send it to the obfuscator but this approach may be prone to race contitions)

On Android (and likely iOS in a similar way):

  • The crate is accessed via FFI using JNA.
  • VPNActivity starts the obfuscator.
  • VPNActivity calls protect on the obfuscator's sockets.
  • VPNActivity rewrites the local port in the configuration.

This architecture was chosen because most of the libraries required to implement obfuscation protocols are available in the Rust ecosystem: UDP-over-TCP, Shadowsocks, and QUIC stacks.

Impacts on the rust build bits:

  • added add_rust_binary in rustlang.cmake and refactored add_rust_library to split out shared parts
  • updated rust to 1.91 because:
    • udp-over-tcp requires rust >= 1.87
    • only rust 1.89 and 1.91 are available in Ubuntu repost
    • i hit a weird bug with cargo 1.8x installed from ubuntu repos being unable to install crates from git (solved in 1.91)
  • rust 1.91 is not available in debian:bookworm so is now installed using rustup in linux-qt6-build

UI

When Anti-Censorship features are enabled, a “Anti-Censorship is on” label appears below the timer.
Screenshot from 2026-05-13 14-26-54
A new Anti-Censorship Features menu is available in Settings.
Screenshot from 2026-05-13 14-27-00
When Anti-Censorship features are available on the platform, a toggle switch will be displayed in the menu with name and brief description.
Enabling one feature will automatically disable any previously enabled feature, except for the “Use Port 53” feature, which is compatible with LWO.
Screenshot from 2026-05-13 14-27-09
Screenshot from 2026-05-13 14-27-12
Help text
Screenshot from 2026-05-13 14-27-19

Reference

VPN-7588 - Create generic obfuscation interface for anti censorship features
VPN-7566 - Create anti censorship features menu
VPN-7582 - Implement UDP over TCP on Linux
VPN-7583 - Implement UDP over TCP on Android

Checklist

  • My code follows the style guidelines for this project
  • I have not added any packages that contain high risk or unknown licenses (GPL, LGPL, MPL, etc. consult with DevOps if in question)
  • I have performed a self review of my own code
  • I have commented my code PARTICULARLY in hard to understand areas
  • I have added thorough tests where needed

@encrypt94 encrypt94 changed the title Add obfuscators and udp over tcp obfuscator on Linux DRAFT Add obfuscators and udp over tcp obfuscator on Linux May 13, 2026
@encrypt94 encrypt94 changed the title DRAFT Add obfuscators and udp over tcp obfuscator on Linux DRAFT Add Anti-Censorship features support and udp over tcp obfuscator (Linux only) May 13, 2026
@encrypt94 encrypt94 force-pushed the marco/add-obfuscators branch 3 times, most recently from cbd6d7e to ba41012 Compare May 13, 2026 22:48
@oskirby
Copy link
Copy Markdown
Collaborator

oskirby commented May 13, 2026

I've had kind of a love/hate relationship with building rust binaries over the years, but this might be a good case for splitting the obfuscator into a standalone binary that can be invoked by the daemon as needed rather than baking it into the client.

The obfuscator should only ever operate on unprivileged information, should require no root permissions, and it probably has a pretty heavy workload given that it needs to live in the packet processing loop.

QProcess * obfuscator = new QProcess(this);
QStringList args;
args << "--method" << "lwo";
args << "--pubkey" << config.m_serverPublicKey;
args << "--server" << config.m_serverIpv4AddrIn;
obfuscator->start("/usr/bin/mozillavpn-obfuscator", args);

connect(obfuscator, &QProcess::started, this, &Example::handleObfuscatorStarted);
connect(obfuscator, &QProcess::finished, this, &Example::handleObfuscatorFinished);

@encrypt94 encrypt94 force-pushed the marco/add-obfuscators branch from ba41012 to 6b6f676 Compare May 13, 2026 23:09
@encrypt94 encrypt94 changed the title DRAFT Add Anti-Censorship features support and udp over tcp obfuscator (Linux only) DRAFT Add Anti-Censorship features support and udp over tcp obfuscator (Linux and Android only) Jun 1, 2026
@encrypt94 encrypt94 changed the title DRAFT Add Anti-Censorship features support and udp over tcp obfuscator (Linux and Android only) DRAFT Add Anti-Censorship features support and udp over tcp obfuscator on Linux and Android Jun 1, 2026
@encrypt94 encrypt94 force-pushed the marco/add-obfuscators branch 3 times, most recently from 4386cc2 to 7c124ff Compare June 1, 2026 13:06
encrypt94 added 11 commits June 1, 2026 16:55
…ndgen, with an the udp2tcp implementation.

Wire the obfuscator into the controller and daemon so the daemon can spin up a local obfuscation tunnel and the WireGuard peer is pointed at the obfuscator'slocal UDP port.
…update daemon.cpp, drop ffi calls and use QProcess to call the obfuscator
… library build helpers into smaller reusable functions shared with the binaries helpers
…fuscator ffi interface and instantiate the obfuscator and protect the sockets
…roxy_options; class=Invalid (3)' bug when installing crates from git
…untu only provides 1.85 and 1.89 in its repos.
@encrypt94 encrypt94 force-pushed the marco/add-obfuscators branch 2 times, most recently from 4f85b01 to 5eb093d Compare June 1, 2026 15:07
@encrypt94 encrypt94 force-pushed the marco/add-obfuscators branch from 5eb093d to dbfe054 Compare June 1, 2026 15:17
encrypt94 added 3 commits June 1, 2026 17:24
…was generating a cyle (only when called by dpkg-buildpackage) use a custom target that sets sets ${TARGET_NAME}_EXECUTABLE
@encrypt94 encrypt94 force-pushed the marco/add-obfuscators branch 3 times, most recently from 2ce192f to 5005e81 Compare June 2, 2026 14:31
…op obfuscator for wasm and ios, on desktop platform use qprocessobfusctator on wasm use the dummy one
@encrypt94 encrypt94 force-pushed the marco/add-obfuscators branch from 5005e81 to ef8ab9b Compare June 2, 2026 15:04
@encrypt94 encrypt94 changed the title DRAFT Add Anti-Censorship features support and udp over tcp obfuscator on Linux and Android Add Anti-Censorship features support and udp over tcp obfuscator on Linux and Android Jun 2, 2026
@encrypt94 encrypt94 marked this pull request as ready for review June 2, 2026 19:30
@encrypt94 encrypt94 requested review from a team and flodolo as code owners June 2, 2026 19:30
@encrypt94 encrypt94 requested review from abhishekmadan30 and removed request for a team June 2, 2026 19:30

settings:
privacySettings: Privacy features
antiCensorshipSettings: Anti-Censorship features
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this coming from the Content Team? Is this terminology approved by Legal?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar question - I'm curious if you'd be open to working on wordsmithing a bunch of these. "What can xxxx do for me?", for instance, feels like a different voice than most of our product copy.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this coming from the Content Team? Is this terminology approved by Legal?
Thanks for raising this. It’s not coming from the Content Team and hasn’t been approved by Legal yet. Legal is currently reviewing the language.

Similar question - I'm curious if you'd be open to working on wordsmithing a bunch of these. "What can xxxx do for me?", for instance, feels like a different voice than most of our product copy.

Sure i'm totally open to change the descriptions! i'll try to come up with something that feels more aligned with the rest of our product copy :) suggestions are super appreciated!

antiCensorshipSettingsWarning: These options may cause connection stability issues.
antiCensorshipPort53Title: Connect using port 53
antiCensorshipPort53Body: This may help on networks that block ports or UDP traffic.
antiCensorshipMasqueTitle: MASQUE
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this uppercase? Should it be translated? Same question for SHADOWSOCKS later.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shadowsocks casing is an error. MASQUE is an acronym, so it should be kept uppercase. Both of them are proper nouns and should not be translated

Comment on lines +67 to +72
onClicked: {
if(MZSettings.obfuscationMethod == modelData.settingValue) {
MZSettings.obfuscationMethod = MZSettings.NoObfuscation;
} else {
MZSettings.obfuscationMethod = modelData.settingValue;
// Maybe automatically disable alwaysPort53 when enabling an obfuscation method
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If these options are mutually exclusive, we should not use switches here - we should use radio buttons, like in the DNS settings screen.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Obfuscators are mutually exclusive, and "Always use port 53" only works with LWO. What do you think about using a toggle switch for "Always use port 53" and radio buttons for the obfuscators, and then disabling the switch when anything other than LWO is selected?

Copy link
Copy Markdown
Collaborator

@mcleinman mcleinman Jun 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about splitting it into two radio buttons? Something like "LWO via typical ports" and "LWO using port 53"? We don't need to touch the settings structure in code - under the hood, we just set those settings as appropriate.

@mcleinman
Copy link
Copy Markdown
Collaborator

This is amazing, thank you! I'm focusing on UI right now, will let others handle the underlying code who are better positioned to review that piece.


settings:
privacySettings: Privacy features
antiCensorshipSettings: Anti-Censorship features
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to be done in conjunction with legal, but I'm wondering if "anti-censorship features" is immediately understandable by the average person.

Maybe something like "Advanced networking features" or "restricted network settings" or "alternative connection methods" or "hostile network defense" or "censorship resistance" or "network workaround" or... maybe this is something we can talk out in a meeting next week?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And of course, if we rename this we'll need to update many of these strings.

settings:
privacySettings: Privacy features
antiCensorshipSettings: Anti-Censorship features
antiCensorshipSettingsWarning: These options may cause connection stability issues.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
antiCensorshipSettingsWarning: These options may cause connection stability issues.
antiCensorshipSettingsWarning: These options should be used when a network operator is blocking connection to VPN servers. They may cause stability issues.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also include something about how this will not help with a website blocking VPN connections? This seems important for setting user expectations.

antiCensorshipSettings: Anti-Censorship features
antiCensorshipSettingsWarning: These options may cause connection stability issues.
antiCensorshipPort53Title: Connect using port 53
antiCensorshipPort53Body: This may help on networks that block ports or UDP traffic.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
antiCensorshipPort53Body: This may help on networks that block ports or UDP traffic.
antiCensorshipPort53Body: This may help on networks that block specific ports or UDP traffic.

antiCensorshipPort53Title: Connect using port 53
antiCensorshipPort53Body: This may help on networks that block ports or UDP traffic.
antiCensorshipMasqueTitle: MASQUE
antiCensorshipMasqueBody: This may help on networks that block VPN protocols by disguising VPN traffic as regular HTTPS traffic.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
antiCensorshipMasqueBody: This may help on networks that block VPN protocols by disguising VPN traffic as regular HTTPS traffic.
antiCensorshipMasqueBody: This disguises VPN traffic as regular HTTPS traffic, and may help on networks that block VPN protocols by .

privacySettings: Privacy features
antiCensorshipSettings: Anti-Censorship features
antiCensorshipSettingsWarning: These options may cause connection stability issues.
antiCensorshipPort53Title: Connect using port 53
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
antiCensorshipPort53Title: Connect using port 53
antiCensorshipPort53Title: Always connect using port 53

antiCensorshipShadowsocksTitle: SHADOWSOCKS
antiCensorshipShadowsocksBody: A reliable censorship circumvention protocol that may help bypass restrictive or heavily filtered networks.
antiCensorshipUdpOverTcpTitle: UDP over TCP
antiCensorshipUdpOverTcpBody: This may help on networks that block UDP traffic by tunneling it over TCP.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
antiCensorshipUdpOverTcpBody: This may help on networks that block UDP traffic by tunneling it over TCP.
antiCensorshipUdpOverTcpBody: This tunnels UDP traffic over TCP, and may help on networks that block UDP traffic.

antiCensorshipMasqueTitle: MASQUE
antiCensorshipMasqueBody: This may help on networks that block VPN protocols by disguising VPN traffic as regular HTTPS traffic.
antiCensorshipLwoTitle: Lightweight obfuscation
antiCensorshipLwoBody: The fastest obfuscation method. May help on networks that detect or block WireGuard traffic without adding significant overhead.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we give a little bit more here? We give a minor technical explanation for the others, and this once we just call "lightweight" with no detail.

antiCensorshipLwoTitle: Lightweight obfuscation
antiCensorshipLwoBody: The fastest obfuscation method. May help on networks that detect or block WireGuard traffic without adding significant overhead.
antiCensorshipShadowsocksTitle: SHADOWSOCKS
antiCensorshipShadowsocksBody: A reliable censorship circumvention protocol that may help bypass restrictive or heavily filtered networks.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
antiCensorshipShadowsocksBody: A reliable censorship circumvention protocol that may help bypass restrictive or heavily filtered networks.
antiCensorshipShadowsocksBody: [Insert a phrase of technical detail.] This may help bypass restrictive or heavily filtered networks, and sometimes works when all other ones do not.

Are there tradeoffs to this, like in speed? Is this the first one folks should try, or the last?

value: Anti-Censorship features can help when your provider or network blocks VPN or UDP traffic.
comment: Body label for the Anti-Censorship features help sheet
antiCensorshipBody2:
value: These features may slow down your connection, so turn them off when you no longer need them.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
value: These features may slow down your connection, so turn them off when you no longer need them.
value: These features may slow down the connection, so turn them off when they are not needed.

value: Anti-Censorship features
comment: Title label for the Anti-Censorship features help sheet
antiCensorshipHeader:
value: What can Anti-Censorship features do for me?
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe remove this header? I'm not sure it adds anything, given that we have the title as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants