Advisory: ProxyMark deanonymization paper (2026-07)
In July 2026, researchers published "Deanonymizing Monero Transactions in Tor Network" (Shi et al., arxiv.org/abs/2607.07062). The attack is network-layer, not on-chain — ring signatures, stealth addresses, and RingCT are unaffected. It targets Monero nodes that broadcast transactions through Tor using a specific two-outgoing-hidden-service pattern; an attacker who controls both outgoing connections can watermark traffic to link the .onion address to the machine's real IP. Reported effectiveness: 100% precision on onion-ID identification, 91–93% recall on watermark-based IP correlation.
Status as of 2026-08-08. The paper was discussed at the 2026-07-29 MRL meeting. The three-part attack breaks down as follows:
- Onion-address leak (heuristic 1) — partially patched. monero#9632 (vtnerd, merged 2025) shuffles the node's own onion address inside the 250-peer list returned during Timed Sync Request. syntheticbird noted at the meeting the shuffle is imperfect — the address still ships in every TSR, so correlation is slower but not eliminated. tevador proposed the correct fix as "insert own address before truncating to 250 peers with randomized insertion" — no PR yet.
- Proxy-selection bias / unbounded self-reported block height (heuristic 2) — unpatched.
process_payload_sync_data()incryptonote_protocol_handler.inlaccepts any block-height claim without an upper bound, letting an attacker bias the proxy-selection lottery. Discussion identified sanity checks (reject peerlists composed entirely of unknown onions when own peerlist is full) but no PR merged. - Timed sync/ping messages defeating noise protocol (heuristic 3) — unpatched. rucknium at the meeting: "the noise protocol wasn't intended to defeat an active adversary. It was designed to hide info from a passive ISP-level observer." No PR merged.
No monerod release has shipped since the paper disclosure (last release: v0.18.5.1, 2026-07-08). Full linkability mitigation is expected at the FCMP++ hard fork (~February 2027) — vtnerd at the meeting: "the biggest issue with linking tx to identity is that you can effectively 'break' the ring. this closes with fcmp++." FCMP++ replaces ring signatures with full-chain membership proofs, removing the primitive the attack chains from.
Operational implication. If you run a Monero node behind Tor in the two-outgoing-hidden-service configuration this guide describes below, be aware the attack is real, network-layer, and not currently mitigated at the P2P level. It does not affect ring signatures, stealth addresses, or RingCT; it also does not affect Tor Browser sessions or wallets connecting to your node. Watch github.com/monero-project/meta for the next MRL meeting for mitigation PR announcements. The rest of this guide is unchanged.
Why personal nodes matter (and when they don't)
- Privacy: the remote-node operator sees your IP and which subaddresses you scan for. Your own node makes that information local-only.
- Trust: you verify every block. The chain you see is the chain consensus rules say is valid — not what a public-node operator chose to show you.
- Availability: public nodes go down or get rate-limited. Your node is always there.
- When not worth it: low-balance hot wallet, mobile-only user, transient setup. Then a vetted Tor-hosted remote node from /nodes is the pragmatic option.
Hardware floor
- CPU: any 64-bit CPU made in the last 10 years. Sync is single-threaded-ish + RandomX validation; nothing fancy.
- RAM: 4 GB minimum, 8 GB comfortable.
- Disk: ~250 GB SSD as of mid-2026 (pruned: ~80 GB). NVMe is faster but SATA SSD works. Spinning rust is painful.
- Bandwidth: ~5–10 GB initial sync, then a few hundred MB/day. Unlimited or generous-cap connection.
- OS: Linux (Debian / Ubuntu / Arch) is the path of least resistance. Windows + macOS work; raspi 4 works for pruned-only.
Setup — Linux (recommended)
- Get a verified binary. Download from getmonero.org → verify GPG signature (see verify guide) → extract.
- Pick a config:
(dropmonerod \ --data-dir /var/lib/monero \ --no-igd \ --restricted-rpc \ --rpc-bind-ip 127.0.0.1 \ --rpc-bind-port 18081 \ --confirm-external-bind \ --enable-dns-blocklist \ --out-peers 32 \ --in-peers 64--restricted-rpcif this node is for your own wallet only; keep it if you'll share) - Run as a service: systemd unit, restart on failure, user
monero. - Wait. Initial sync: 12–48 hours depending on disk + CPU. Use
--fast-block-sync 1for less verification (faster but trusts the network more on old blocks). - Open the wallet RPC port only to localhost (or your LAN with a firewall). Never expose 18081 to the public internet without RPC restrictions.
Connect your wallet
- Feather / Monero GUI / Cake on same machine: point at
http://127.0.0.1:18081. Done. - Same LAN: point at the LAN IP. Make sure RPC is bound to the LAN interface, firewalled to your subnet.
- Remote (recommended Tor): see below.
Expose over Tor (recommended for remote access)
- Install Tor on the same machine.
apt install tor. - Add a hidden service to
/etc/tor/torrc:HiddenServiceDir /var/lib/tor/monero-rpc/ HiddenServicePort 18081 127.0.0.1:18081 - Restart Tor, read
/var/lib/tor/monero-rpc/hostname— that's your .onion address. - Wallet config: point at
http://<your-onion>:18081. Use--proxy 127.0.0.1:9050on the wallet's CLI or the wallet's "use Tor" toggle. - Optional: add the
--rpc-restricted-bindport to a second hidden service so you can share with friends without exposing internal-only RPC.
Share back to the network
If you have bandwidth to spare, the Monero P2P port (18080) can be exposed publicly to relay blocks and transactions for others. Doing so helps decentralization. Run a clear-net peer + an onion peer for max impact; xmr.club lists working public nodes at /nodes — yours can join.
Common failure modes
- Disk fills up during sync. Provision 300+ GB. Use a separate volume so the OS root doesn't crash.
- "Connection refused" from wallet. RPC isn't bound to where the wallet's connecting. Check
--rpc-bind-ip+ firewall. - Slow first sync. CPU is RandomX-bottlenecked or disk is the bottleneck. SSD non-negotiable.
- Node falls behind. Often clock skew. Run
chrony/systemd-timesyncd. - Wallet syncs forever. Wallet's restore height is too low. Set it to the height your wallet was created — wallet skips earlier blocks.