·6 min read·Updated Sep 13, 2026

Run Your Own Monero Node on a VPS: Setup, Firewall and Real Privacy Limits

Deploy monerod on a Linux VPS: install, config, systemd hardening, firewall rules, private wallet access over WireGuard or Tor — and honest privacy limits.

Using someone else's remote Monero node is the single biggest privacy leak in most people's XMR setup. The node operator sees your IP, the exact transactions you submit, and every block range your wallet asks to scan. Running your own node on a VPS fixes part of that problem — but only part, and it introduces trade-offs people rarely mention.

This guide covers a complete monerod deployment on a Linux VPS: resource planning, install and verification, a sane config, systemd hardening, firewall rules, and three ways to reach the node from your wallet without exposing RPC to the internet. It ends with an honest account of what a self-hosted remote node does and does not hide.

The short answer

A pruned Monero node runs comfortably on a VPS with 2 vCPU, 4 GB RAM and roughly 150 GB of SSD space, with the restricted RPC port bound to localhost or a private VPN interface and reached over WireGuard, an SSH tunnel, or a Tor onion service. That setup removes your dependence on third-party node operators and keeps your wallet's scanning activity off other people's logs.

What it does not do is hide from your hosting provider or its upstream network that a Monero node is running at that IP. If your threat model includes network-level observation of the VPS itself, plan accordingly — see the limits section below.

Resource planning: disk, RAM, CPU and bandwidth

Disk. The full Monero blockchain is well over 200 GB and grows continuously; check the current figure on getmonero.org before you size a disk. A pruned node keeps roughly a third of that data by discarding most of the ring signature data it no longer needs to verify new blocks. A pruned node still validates everything going forward and serves wallets fine — it just can't serve historical blocks in full to other peers. For most personal wallet use, pruned is the right default.

RAM. monerod will start on a 2 GB VPS, but initial sync is memory- and I/O-hungry, and LMDB (the database Monero uses) benefits from page cache. 4 GB is a comfortable target. If you're squeezing it onto something smaller, read up on swap, zram and OOM-killer tuning for low-RAM VPS first, because a monerod process killed mid-write is how people end up resyncing from scratch.

Disk speed matters more than CPU. Initial sync is dominated by random writes. On a node with slow or heavily contended storage, sync can take days instead of hours. If you're unsure whether your disk is being throttled by a noisy neighbour, the tests in the guide on spotting an oversold VPS will tell you quickly.

Bandwidth. This is the item people forget. A node with generous peer limits relays blocks and transactions to the whole network and can move hundreds of gigabytes per month. Check your provider's traffic policy, and use the rate limits shown below to keep usage predictable.

Install monerod on Debian or Ubuntu

Use the official static binaries rather than distro packages, which are often outdated.

sudo apt update && sudo apt install -y curl bzip2 gpg jq vnstat
cd /tmp
curl -LO https://downloads.getmonero.org/cli/linux64

Before extracting anything, verify it. The Monero project publishes a signed hashes.txt; download it, verify the signature against the maintainer's GPG key published on getmonero.org, then compare the SHA-256 of your archive:

sha256sum linux64

Skipping this step is how people end up running a tampered daemon with a wallet attached to it. Do not skip it.

Then create a dedicated system user and install the binaries:

tar -xjf linux64
sudo useradd -r -m -d /var/lib/monero -s /usr/sbin/nologin monero
sudo install -m 0755 monero-x86_64-linux-gnu-*/monerod /usr/local/bin/
sudo install -d -o monero -g monero /var/lib/monero /var/log/monero

A sane monerod.conf

Create /etc/monerod.conf:

data-dir=/var/lib/monero
log-file=/var/log/monero/monerod.log
log-level=0
max-log-file-size=10485760

# Keep ~1/3 of chain data; remove this line for a full archival node
prune-blockchain=1

# P2P: reachable inbound is good for the network, optional for you
p2p-bind-ip=0.0.0.0
p2p-bind-port=18080
no-igd=1

# Restricted RPC only, and never on a public interface
rpc-restricted-bind-ip=127.0.0.1
rpc-restricted-bind-port=18089

# ZMQ stays local
zmq-rpc-bind-ip=127.0.0.1
zmq-rpc-bind-port=18083

# Predictable resource use
out-peers=24
in-peers=32
limit-rate-up=2048
limit-rate-down=8192

Two things worth understanding here.

Restricted vs unrestricted RPC. Port 18081 is the unrestricted RPC interface: it exposes administrative and diagnostic calls you do not want strangers touching. Port 18089 is the restricted interface, which is what remote wallets are meant to use. This config never opens 18081 at all. If you later need it for local tooling, bind it to 127.0.0.1 and leave it there.

Sync mode. db-sync-mode=fast:async:250000000bytes (the default) is much faster for the initial sync but risks a corrupted database on an unclean shutdown or host crash. Some operators sync with the default and then switch to db-sync-mode=safe for steady-state operation. On a VPS you don't control the hypervisor of, safe after sync is a reasonable choice.

systemd unit with basic sandboxing

Create /etc/systemd/system/monerod.service:

[Unit]
Description=Monero Node
After=network-online.target
Wants=network-online.target

[Service]
User=monero
Group=monero
Type=simple
ExecStart=/usr/local/bin/monerod --config-file=/etc/monerod.conf --non-interactive
Restart=on-failure
RestartSec=30
TimeoutStopSec=300
LimitNOFILE=16384

NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ProtectKernelTunables=true
ProtectControlGroups=true
RestrictSUIDSGID=true
ReadWritePaths=/var/lib/monero /var/log/monero

[Install]
WantedBy=multi-user.target

--non-interactive keeps the daemon in the foreground so systemd can supervise it properly. TimeoutStopSec=300 matters: monerod needs time to flush LMDB on shutdown, and killing it early is the main cause of database corruption.

Enable and start it:

sudo systemctl daemon-reload
sudo systemctl enable --now monerod

Watch sync progress against the restricted RPC:

curl -s http://127.0.0.1:18089/get_info | jq '{height, target_height, synchronized, incoming_connections_count, outgoing_connections_count}'

When synchronized is true and height matches the network, you're done.

Firewall rules

The node needs exactly one inbound port from the internet, and only if you want to accept incoming peers: TCP 18080. RPC must never be publicly reachable. If you use nftables, the rules fit naturally into the nftables baseline ruleset:

# P2P inbound (optional but good for the network)
tcp dport 18080 accept

# Restricted RPC only over the VPN interface
iifname "wg0" tcp dport 18089 accept

If you skip inbound P2P entirely, your node still syncs and works fine — it just won't serve other peers, and you'll rely purely on outbound connections.

Three ways to reach the node privately

1. SSH tunnel (simplest). Nothing extra to install:

ssh -N -L 18089:127.0.0.1:18089 user@your-vps

Then point your wallet at 127.0.0.1:18089. With monero-wallet-cli:

monero-wallet-cli --daemon-address 127.0.0.1:18089 --trusted-daemon

Only pass --trusted-daemon for a node you actually control — it lets the wallet ask the daemon for information it wouldn't trust a stranger's node with.

2. WireGuard (best for multiple devices). Put the node on a private interface and let phones and laptops reach it as if it were on a LAN. Set rpc-restricted-bind-ip to the VPS's WireGuard address, add confirm-external-bind=1, and restrict the port to the wg0 interface in your firewall. The setup details, including DNS leak handling, are in the self-hosted WireGuard VPN guide.

3. Tor onion service (best for hiding the client side). Map an onion address to the restricted RPC port and connect from wallets that support Tor, such as Feather on desktop or Monerujo on Android. This hides your own IP from the node's network path and means the node doesn't need any clearnet listener for RPC at all. The hardening details and the honest limits

Written by IronBalkans. Last reviewed Sep 13, 2026.