The open-source browser extension of Colitu VPN. It protects the browser without installing an app: sign in with your Colitu account, click once, and the browser's traffic leaves through a Colitu server.
| Browsers | Chrome, Edge, Brave, Opera, Yandex Browser (Chrome Web Store) · Firefox 128+ (Firefox Add-ons) |
| Version | 1.1.0 (package.json) |
| Manifest | V3 (Chrome service worker, Firefox event page) |
| Languages | Russian, English, Turkish |
| Dependencies | none at runtime; the build script uses only Node.js |
| License | GPL-3.0 |
Install: Chrome Web Store · Firefox Add-ons · colitu.com/download/browser · Releases
Browsers can only use HTTP, HTTPS and SOCKS proxies, so the extension does not run the app transports (VLESS Reality, XHTTP, Hysteria2). Instead:
- The extension signs in like an app device (
/api/v1/auth/*,/api/v1/devices/register, platformchromeorfirefox) or through the device link (a code you confirm on colitu.com). Accounts with two-step verification (set up on colitu.com) also enter the authenticator-app code or a recovery code (/api/v1/auth/login/mfa); the short-lived challenge is kept in session memory only. Tokens stay in extension storage. - It asks the panel for a proxy ticket and the server list
(
POST /api/v1/webproxy/session). A ticket is a short-lived (≤ 6 h), Ed25519-signed statement "this device of this user may use the proxy until …". It is refreshed in the background and kept in session memory only (storage.session), never on disk; after a browser restart or an update traffic is held back (kill-switch rules: only local addresses and the API go direct) until a new one is fetched. - While connected, the browser talks to an HTTPS proxy (TLS, HTTP/2) on
the chosen node; the ticket is the proxy password. Chrome gets a PAC script
through
chrome.proxy; Firefox answersproxy.onRequestper request. Both use the same routing function (src/lib/routing.js). - The node verifies tickets offline, counts traffic per device and reports it to the panel, which counts it towards the plan (the free plan has 10 GB a month) and tells the node to cut off ended plans and removed devices.
The proxy chain has no DIRECT fallback for websites: if the server
cannot be reached, pages fail instead of leaking around the proxy. Only the
Colitu API itself may fall back to a direct connection, so you can still sign
in and switch servers.
- the Colitu proxy hosts themselves and local network addresses
(
localhost,10/8,172.16/12,192.168/16,169.254/16,100.64/10,fc00::/7,fe80::/10,.local, …); - the sites on your split-tunneling list (“selected sites bypass the proxy”), or every site that is not on it (“only selected sites use the proxy”), see below;
.ru,.su,.рфsites while Russian sites directly is on (default, as in the apps) and the server is not in Russia.
Settings → Split tunneling: Off (default), Selected sites bypass the proxy or Only selected sites use the proxy, with one list of entries:
- a domain matches itself and every subdomain (
example.comcoverswww.example.com;*.example.comis read asexample.com); internationalised names are stored in punycode; - an IPv4 or IPv6 address, or a CIDR range (
203.0.113.0/24,2001:db8::/32), matches sites opened by that address. Host names are not resolved to check address rules: a DNS lookup would happen outside the proxy; - invalid entries are refused with the list of what is wrong; at most 500 entries.
The rule is part of the same routing function as everything else, so it is
applied the same way in both browsers: in Chrome it is compiled into the PAC
script set through chrome.proxy.settings (DIRECT for sites that skip the
proxy), in Firefox proxy.onRequest returns {type: "direct"} for them.
Order of the checks: local addresses and the Colitu proxy hosts (always
direct) → bypass list → Colitu API (proxy with direct fallback) → “only”
list → Russian sites directly → proxy. In “only” mode the user's list wins
over Russian sites directly; “only” with an empty list counts as off. The
popup shows “Split tunneling on: N sites” while a list is in effect, and
saving re-applies the proxy setting at once. Settings from 1.0.0 (“all sites /
only these sites” and the two site lists) are carried over.
While connected (and the setting is on), privacy.network.webRTCIPHandlingPolicy
is set to disable_non_proxied_udp, so WebRTC cannot reveal the real address.
It is cleared when you disconnect.
| Permission | Why |
|---|---|
proxy |
set the browser proxy (Chrome) / answer per-request proxy decisions (Firefox) |
<all_urls> host access |
route every site through the proxy, measure server ping, call the Colitu API |
webRequest, webRequestAuthProvider (Chrome) |
answer the proxy's authentication challenge with the ticket |
privacy |
the WebRTC protection |
storage |
session tokens, settings and the server list |
alarms |
refresh the ticket in the background |
The extension does not read page content, inject scripts into pages, keep a browsing history or use analytics. See PRIVACY.md.
Requires Node.js 20 or newer; there are no npm dependencies.
npm test # routing, PAC, Firefox decisions, translations
npm run build # dist/chrome, dist/firefox, store zips, SHA256SUMS
node scripts/build.mjs chrome builds one browser. Zips are reproducible
(fixed timestamps, sorted entries): building the same tag gives the same
SHA-256 as the release. Load dist/chrome with Load unpacked on
chrome://extensions (Developer mode), or dist/firefox/manifest.json from
about:debugging in Firefox.
--api=<url> points a build at another API for local testing; the output goes
to dist-dev/ and is never published.
| Path | |
|---|---|
src/background.js |
session, proxy setting, authentication, toolbar icon |
src/lib/api.js |
Colitu API client (tokens, device registration, tickets) |
src/lib/routing.js |
what goes through the proxy; PAC generation |
src/lib/proxy.js |
Chrome PAC / Firefox onRequest, WebRTC policy |
src/lib/i18n.js |
UI strings (en, ru, tr) |
src/popup/ |
the popup UI |
scripts/build.mjs |
per-browser manifests and reproducible zips |
store/ |
store listing texts and images |
Security reports: SECURITY.md. Contributions: CONTRIBUTING.md.
Flag images: flag-icons (MIT), see NOTICE.



