- Rust 95.2%
- Shell 4.8%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .forgejo/workflows | ||
| assets | ||
| scripts | ||
| src | ||
| .gitignore | ||
| build.rs | ||
| Cargo.lock | ||
| Cargo.toml | ||
| LICENSE | ||
| README.md | ||
Servimari
A small Linux GUI (FLTK) for choosing which Overwatch 2 server region you play
on. Check the regions you want to play in; Servimari blocks the rest with
iptables so the matchmaker can only place you in an allowed region.
Building
Requires Rust (edition 2021) and the FLTK system dependencies (libx11, libxext, libxft, libxrender, libxcursor, libxfixes, libxinerama, libxi, libfontconfig1, libfreetype6, mesa).
cargo build --release
# or, for the portable AppImage:
bash scripts/build-appimage.sh
pkexec (polkit) is used to run the iptables commands, so a working polkit
agent is required at runtime.
How it works
- On startup Servimari downloads Google's public cloud IP ranges
(
https://www.gstatic.com/ipranges/cloud.json) in the background; if that fails it falls back to the bundledassets/gcp_snapshot.jsonand retries twice more (30 s apart). - Applying a block creates a user chain
SERVIMARI, jumps to it from theINPUTandOUTPUTchains, and for every blocked CIDR adds:- 4
RETURNrules that let the Overwatch login port through, then - 2
DROPrules covering the whole CIDR in both directions.
- 4
- The selected regions are persisted to
$XDG_CONFIG_HOME/servimari/state.json— only after the firewall confirms the rules installed — together with the current boot id, so after a reboot Servimari can suggest re-applying.
Design trade-offs (read before you rely on it)
- Cloud ranges are broad. GCP-backed regions block the whole public GCP range for that region, not just Blizzard's servers. Any unrelated service you use that happens to be hosted in a blocked region's range will also be cut off. This is what makes region blocking effective, and it is intentional.
- IPv4 only. IPv6 prefixes are not fetched, so a blocked region may still be reachable over IPv6.
- Firewall rules are not persistent by default. If your distro runs
iptables-persistent/firewalldthe rules may survive a reboot; otherwise you must re-apply after booting (Servimari will suggest it). - "Blocked N regions" counts regions with loaded ranges. If the live fetch failed and a region's ranges are missing, it is skipped and reported rather than silently claimed as blocked.
Refreshing the bundled GCP snapshot
assets/gcp_snapshot.json is a point-in-time copy of the GCP ranges for just
the regions Servimari can block. Unlike the live fetch (which filters to the
relevant scopes at runtime), the bundled file is a JSON object that maps each
GCP scope directly to its list of ipv4Prefix CIDR strings, e.g.
{"us-east4": ["...", ...], ...}. snapshot_gcp() loads it straight into that
shape, so the file must not be wrapped in a {"prefixes": [...]} envelope.
The scope values are exactly the GoogleCloud(...) entries in
src/region.rs (currently us-east4, southamerica-east1, europe-north1,
me-central2, asia-northeast1, asia-southeast1); the app ignores any other
scopes. Regenerate it with:
curl -s https://www.gstatic.com/ipranges/cloud.json \
| jq 'reduce (.prefixes[] | select(.ipv4Prefix and .scope and (.scope | IN(
"us-east4","southamerica-east1","europe-north1",
"me-central2","asia-northeast1","asia-southeast1")))
)) as $p ({}; .[$p.scope] += [$p.ipv4Prefix])' \
> assets/gcp_snapshot.json
Because the live fetch succeeds in almost all cases, the snapshot only matters for offline-first launches; keeping it roughly up to date is a nice-to-have.
Development
cargo test # unit tests for CIDR validation, ping parsing, batch building,
# the shell marker protocol and state-file round-trips
cargo check # fast compile check
Releases are built by the .forgejo/workflows/release.yml workflow (tag v*).
License
GPL-3.0-or-later — see LICENSE.