Restore Privacy — Code & Policy Audit
~every 4h automated security pass (node probes, package confidence, privacy checks). Countdown from last written audit timestamp.
| Field | Value |
|---|---|
| Product | Restore Privacy Tunnel (RPT / RPT2) |
| Repository | restore-privacy (private source; installers only via paid status host) |
| Public catalog version | 0.3.7 |
| Production node | 82.221.101.241:44044 (UDP); status UI TCP 8080 — Iceland, host FlokiNET |
| Audit generated | 22 July 2026 (2026-07-22T13:00:14Z) |
| Cadence | Automated security pass (~every 4 hours + jitter on privacy-hardened node timer) |
| Audit type | Static suite + live node status probe + per-installer AUDIT STATE + section B privacy probes + multihop node structure |
| Auditor method | scripts/run_security_audit.py — unittest privacy/security modules + TCP/HTTP/UDP probes + no-.priv scan + catalog package RAG + section B + multihop structure (no firewall scan) |
Installer package AUDIT STATE (catalog v0.3.7)
Reader confidence for each current paid catalog installer after this security-audit pass. The STATE column shows a solid colour only (not the words Green/Amber/Red). Platform includes an OS-relative icon. On the status host, long Package / Notes text scrolls inside the cell (not by widening the full page). Regenerated by scripts/run_security_audit.py --write (4-hour timer).
| Platform | Package | STATE | Notes |
|---|---|---|---|
| Windows | restore-privacy-client-0.3.7-windows-x64-setup.exe | node_elgamal.pub embedded (raw product pin match); PE/MZ magic OK; multihop residual prep markers present (exit_node_elgamal; residual-via-exit when RPT_MULTIHOP_ENABLED=1); exit_node_elgamal.pub raw bytes present (Romania exit pin) | |
| Android | restore-privacy-client-0.3.7-android.apk | node_elgamal.pub pin matches product monopin; Android residual wire (PFS + outer obfs) present; exit_node_elgamal.pub present (multihop exit pin) | |
| macOS | restore-privacy-client-0.3.7-macos.zip | node_elgamal.pub pin matches product monopin; archive present (structural residual gates N/A in this pass); exit_node_elgamal.pub present (multihop exit pin) | |
| iOS | restore-privacy-client-0.3.7-ios.zip | node_elgamal.pub pin matches product monopin; archive present (structural residual gates N/A in this pass); exit_node_elgamal.pub present (multihop exit pin) | |
| Linux | restore-privacy-client-0.3.7-linux-x64.tar.gz | node_elgamal.pub pin matches product monopin; archive present (structural residual gates N/A in this pass); exit_node_elgamal.pub present (multihop exit pin) |
Catalog overall (worst package):
| State colour | Meaning |
|---|---|
| Green | Present, no *.priv, product node pub pin match, platform structural gate pass (Windows multihop markers when PE) |
| Amber | Present but pin/structural check incomplete or soft warning |
| Red | Missing from local releases/assets tree, embeds *.priv, pin mismatch, or failed structural gate |
Privacy probes (section B — audit timer)
Structured privacy checks run with the security audit (status-only; no LUKS format, no live ephemeral rebuild, no firewall/expose-surface scan).
| Probe | State | Notes |
|---|---|---|
| nolog_journald | rpt-node.json/conf not present (non-node host); rpt-node.service unit not on this host | |
| no_priv_public_trees | scanned_roots=6; hits=0 | |
| kill_switch_default_off | default_empty_env_enabled=False; current_env_enabled=False; kill-switch default off (product residual) | |
| title_only_status | title_only=True; body={'title': 'RESTORE PRIVACY'} | |
| host_privacy_drift | journald drop-in 99-rpt-privacy.conf absent; rpt-node.service unit not on this host; install_host_privacy.sh recipe present in tree | |
| disk_wipe_readiness | cryptsetup not found (FDE tooling absent); install_disk_encryption.sh present; install_zram_luks.sh present (node-only ram volume) | |
| ephemeral_dry_run | ephemeral_node.py present (C:\Users\rgsne\restore_privacy\scripts\ephemeral_node.py); dry-run mode available; dry-run exit=0 | |
| firewall_expose_surface | intentionally excluded (OBJECTIVE: no firewall/expose-surface probe) |
Section B overall: PASS (firewall probe excluded by design)
In-scope probes: not all PASS (timer host should seed client/node scripts + fixtures).
Multihop node structure (audit timer)
Structural product-layout checks for multi-hop residual (entry → exit). Honesty: residual-via-exit when multi-hop enabled; not full intermediate onion encapsulation; default single-hop Iceland entry.
| Probe | State | Notes |
|---|---|---|
| multihop_module_flags | MULTI_HOP_ROUTING_IMPLEMENTED=True (residual-via-exit); entry host 82.221.101.241:44044 (Iceland monopin); exit host 185.146.232.107:44044 (Romania monopin) | |
| multihop_product_pubs | entry pub present (C:\Users\rgsne\restore_privacy\product\node_elgamal.pub) sha=1b126abfae737c66…; exit pub present (C:\Users\rgsne\restore_privacy\product\exit_node_elgamal.pub... | |
| multihop_residual_via_exit | is_multihop_active=True for entry→exit path; residual_endpoint dials exit 185.146.232.107:44044 (residual-via-exit); multi-hop disabled residual stays entry 82.221.101.241 (defa... | |
| multihop_node_host_layout | present: C:\Users\rgsne\restore_privacy\node\install_zram_luks.sh; present: C:\Users\rgsne\restore_privacy\node\install_host_privacy.sh; node-only: clients never install LUKS/zram |
Multihop structure overall: PASS
| Role | Host | Public key |
|---|---|---|
| Entry (Iceland) | 82.221.101.241:44044 | product/node_elgamal.pub |
| Exit (Romania) | 185.146.232.107:44044 | product/exit_node_elgamal.pub |
1. Executive summary
Latest automated security audit for production node 82.221.101.241 and the in-repo privacy/security gates.
Core privacy thesis (unchanged): no user-info logs, minimal public status (title + downloads — no live client count), honest Connected only when residual full tunnel is active (residual_ip_capture), device Ed25519 keys (no shared client private key in packages), no third-party geo on Connect, session PFS + outer obfs as mitigations (traffic-analysis resistance only — not a claim of full protocol camouflage).
This pass (automated):
| Check | Result |
|---|---|
| Security unit suite | PASS (11 modules) |
| Node status TCP :8080 | reachable |
Node /status HTTP | OK — title-only=True |
| UDP product port :44044 | probe sent |
No *.priv under public trees | OK |
| Privacy probes (section B) | PASS (firewall excluded) |
| Multihop node structure | PASS (residual-via-exit honesty) |
| Live node healthy (TCP+HTTP) | YES |
| Catalog installers AUDIT STATE | (see top package table) |
Overall posture: Strong for residual honesty (residual_ip_capture), no public live count, no-phones-home Connect, packaging strip of *.priv, tunnel DNS + DoT, Settings transparency. Multi-hop residual is opt-in (RPT_MULTIHOP_ENABLED=1): residual-via-exit (Romania); default single-hop Iceland entry — not full intermediate encapsulation. Windows 0.3.6 PE is rebuilt with multihop prep. Product kill-switch is off by default (opt-in `RPT_KILL_SWITCH=1` only). Installer package confidence is the RAG table at the top of this audit.
Primary residual risks (open by design / environment):
- Operational — Product node is on FlokiNET in Iceland (strict Icelandic privacy / free-expression hosting norms). As far as we can be assured from FlokiNET’s public statements (“No invasive logs”; resource-usage monitoring only; no third-party tenant traffic/pattern sharing — https://flokinet.is/privacy/, https://flokinet.is/vps/), the host does not retain invasive logs of users connecting to the node. That is host-published posture, not a product forensic audit. Separate CDN/status hosts and home-ISP paths may still log. Node OS compromise (live RAM) remains residual.
- Apple — residual IP requires signed Packet Tunnel / NE.
- Linux privilege floor — residual needs root + TUN/
ip. - Traffic analysis — padding/jitter/cover/outer obfs are mitigations only.
- FDE / wipe / rebuild — at-rest only; unlocked root still sees secrets.
2. Scope and method
2.1 In scope
| Area | Paths |
|---|---|
| Shared client | client/connect.py, client/endpoint.py, client/full_tunnel.py, client/multihop.py, client/secrets_loader.py, client/legal_links.py, residual honesty / residual_ip_capture |
| Multi-hop residual | Opt-in residual-via-exit (RPT_MULTIHOP_ENABLED=1); entry Iceland + exit Romania pubs under product/ |
| Windows / Linux | client/windows/ (multihop PE via scripts/build_windows_multihop.py), client/linux/ |
| Mobile / Apple | client_app/ Flutter + NativePrep residual engines (exit pub inject) |
| Node | node/* (handshake, pfs, traffic_shape, crypto_session, nolog); node-only zram+LUKS2 |
| Paid packages | status_page/downloads.py monopin 0.3.7; assets under status_page/assets/0.3.7/ + VPS paid_assets |
| Public web | status_page/* catalog 0.3.7 |
| Policies | PRIVACY_POLICY.md, LICENSE, CREDITS.md, README.md, AUDIT.md |
2.2 Method notes
- Public audit is served on the status host as
/AUDIT.mdand/audit.md(source repo is private). - Product default host 82.221.101.241.
- Product node ElGamal pub pin:
product/NODE_ELGAMAL_PUB.sha256(SHA-2561b126abf…). - Did not paste secret material into this document.
3. Live node probe results
| Probe | Detail |
|---|---|
TCP 82.221.101.241:8080 | ok=True error=None |
HTTP http://82.221.101.241:8080/status | code=200 body={'title': 'RESTORE PRIVACY'} |
UDP 82.221.101.241:44044 | sent=True error=None |
Expectation: /status returns title-only JSON (e.g. {"title":"RESTORE PRIVACY"}) — never a live client count.
4. Threat model scenarios
4.6 Threat model scenarios
Scenario A — VPS compromise
Production node placement: Iceland, hypervisor host FlokiNET. As far as we can be assured from FlokiNET’s public statements, the host does not retain invasive connection logs of users connecting to the node (“No invasive logs”; no third-party traffic/pattern sharing; overall resource usage only). If the VPS guest OS / root (production node) is fully compromised while sessions are active, in-memory session material may still be exposed. Product no-log / nolog composition reduces durable user-info logs on disk but does not erase live RAM. Residual risk: compromise of the node OS (distinct from FlokiNET’s published no-invasive-logs posture for tenant connection logging).
Scenario B — Traffic analysis by ISP
An ISP performing traffic analysis may still observe connection timing and volume. Outer obfuscation and traffic shaping mitigate fingerprinting; this is traffic-analysis resistance only, not a claim of full protocol camouflage. Residual risk: sophisticated network observers.
Scenario C — Client device seizure
Device seizure of a user machine may expose the local device key and residual config stored on disk. Packages never ship a shared client private key; keys are generated per device. Restore Internet executable (shipped with your download) will erase everything relating to this VPN from your device. Residual risk: local disk / unlocked endpoint compromise (if the failsafe was not run before seizure, residual product material may still be recoverable).
5. Findings (automated this pass)
| Severity | Finding | Status |
|---|---|---|
| Info | Automated pass at 2026-07-22T13:00:14Z | Recorded |
| High | Public client count on status | Closed (title-only) |
| Medium | Shared client priv in packages | Closed (no .priv hits) |
| Low | Unit suite failure | N/A |
| Info | Multi-hop residual | Opt-in residual-via-exit (Romania); Windows PE multihop rebuild shipped in catalog when package present |
6. Automated checks (this pass — 22 July 2026)
Modules: tests.test_legal_links, tests.test_legal_docs, tests.test_no_public_client_count, tests.test_connect_no_phones_home, tests.test_obfuscation, tests.test_kill_switch_leaks, tests.test_product_node_key, tests.test_pfs_product_require, tests.test_downloads, tests.test_multihop, tests.test_audit_package_rag
| Result | Detail |
|---|---|
| Unit suite | PASS (11 modules) |
| Return code | 0 |
| Log | operator SCRATCH / security_audit.log / node journal rpt-security-audit.service |
| Generator | scripts/run_security_audit.py |
6.1 Package host credibility
| Expectation | Notes |
|---|---|
| Product host | 82.221.101.241 |
| Public catalog | 0.3.7 paid installers on status host (£2.45; no free GitHub release downloads) |
| Node pub pin | 1b126abf… |
No .priv in public package trees | OK |
7. Secrets & packaging checklist
| Control | Status |
|---|---|
secrets/ gitignored | Yes |
Installer strip *.priv | Yes |
Product node_elgamal.pub tracked | Yes (product/) |
| This audit embeds no keys | Confirmed |
8. Recommendations (non-binding)
- Keep 4-hour timer enabled on the production node (
install_security_audit_timer.sh). - Redeploy VPN APP Shop after audit link / catalog changes.
- Keep multi-hop residual honesty: residual-via-exit when enabled; do not claim full intermediate encapsulation.
- Ops: keep Unbound tunnel-only; no public :53; provider log awareness; zram+LUKS2 node-only on multi-hop hosts.
9. Conclusion
Automated security audit at 2026-07-22T13:00:14Z against node 82.221.101.241 and in-repo privacy gates. Public SECURITY AUDIT links must resolve on the status host (/AUDIT.md / /audit.md). Source repository is private; paid catalog installers are fulfilled on the status host only. Core privacy promises hold when the suite passes and status remains title-only.
Re-run: python3 scripts/run_security_audit.py --write
10. Follow-ups status
| Rec | Status |
|---|---|
| Public audit on private GitHub blob | Fixed — clients use status-origin /AUDIT.md |
| Periodic node audit | In tree — 4h systemd timer |
| Multi-hop residual | In tree — opt-in residual-via-exit (Romania); Windows multihop PE via build_windows_multihop.py; Linux/Android/Apple ship exit pub |
| Kill-switch + DoT + outer obfs | In tree |
| Ephemeral node rebuild | In tree (dry-run default) |
11. Document control
| Item | |
|---|---|
| Output | AUDIT.md (repo root); served as /AUDIT.md and /audit.md on VPN APP Shop |
| Related | PRIVACY_POLICY.md, README.md, scripts/run_security_audit.py |
| Code baseline | Catalog 0.3.7 + node 82.221.101.241 |
| Pass date | 22 July 2026 |
| Machine JSON | status_page/static/security_audit_latest.json (when --write) |