Skip to content
atori.tech

2.1 Monero node (monerod)

monerod is the Monero daemon from the Monero Project. It downloads and validates the whole blockchain, relays blocks and transactions to its peers, and serves your wallets.

Requirements

  • 1. System done
  • At least 120 GB free for a pruned node, or 300 GB+ for a full node

Preparations

Create a dedicated monero user that runs the daemon, and let nodeadmin read its files:

sudo adduser --disabled-password --comment "" monero
sudo adduser nodeadmin monero

On Ubuntu 26.04, the first command may print usermod: no changes. That's harmless: the user was created. The new group membership only applies to new logins, so nodeadmin can read monerod's log file once you log in again (you open a second SSH session for that in Run).

Create the data directory:

sudo mkdir /data/monero
sudo chown monero:monero /data/monero
sudo chmod 750 /data/monero

Installation

Work in a temporary directory, and pin the version you want. Check the latest release at https://www.getmonero.org/downloads/.

cd /tmp
VERSION=0.18.5.4

Always use the latest release

The signed hash list, hashes.txt, only covers the current release. If a newer version came out after this guide was written, set VERSION to that one, or the hash check in Verify fails.

Download

wget https://downloads.getmonero.org/cli/monero-linux-x64-v$VERSION.tar.bz2
wget https://www.getmonero.org/downloads/hashes.txt
wget -O binaryfate.asc https://raw.githubusercontent.com/monero-project/monero/master/utils/gpg_keys/binaryfate.asc

Verify

The release hashes are signed by binaryFate, a Monero core maintainer. First check that the key you downloaded is the right one:

gpg --show-keys binaryfate.asc

The fingerprint, on the line below pub, must be exactly:

81AC591FE9C4B65C5806AFC3F0AF4D462A0BDF92

Danger

If the fingerprint doesn't match, stop. Delete the files and ask for help in the community. Don't continue.

Import the key and check the signature on the hash list:

gpg --import binaryfate.asc
gpg --verify hashes.txt

Look for Good signature from "binaryFate <binaryfate@getmonero.org>". You'll also see a warning that the key isn't certified with a trusted signature. That's expected, because you haven't signed binaryFate's key yourself.

Now check the archive against the signed hash list:

grep "monero-linux-x64-v$VERSION.tar.bz2" hashes.txt | sha256sum --check

Expected output: monero-linux-x64-v0.18.5.4.tar.bz2: OK

Install

tar -xjf monero-linux-x64-v$VERSION.tar.bz2
sudo install -m 0755 -o root -g root -t /usr/local/bin monero-*-linux-gnu-v$VERSION/monero*
monerod --version
Monero 'Fluorine Fermi' (v0.18.5.4-release)

Check that all the tools landed in place:

ls /usr/local/bin/monero*

You should see monerod, monero-wallet-cli, monero-wallet-rpc, and several monero-blockchain-* utilities.

Clean up:

rm -rf /tmp/monero-* /tmp/hashes.txt /tmp/binaryfate.asc

Configuration

Switch to the monero user and create the config file:

sudo su - monero
nano /data/monero/monerod.conf
# MoneroBox: monerod configuration
# All options: monerod --help

## Data
data-dir=/data/monero
log-file=/data/monero/monerod.log
log-level=0
max-log-file-size=104850000
max-log-files=5

## Pruning
# Uncomment both lines for a pruned node (~1/3 of the disk space).
# Pruned nodes still fully validate every block and transaction.
#prune-blockchain=1
#sync-pruned-blocks=1

## P2P network
# No incoming connections: listen on localhost only, and ask peers
# not to share our address. The node syncs over outgoing connections.
p2p-bind-ip=127.0.0.1
p2p-bind-port=18080
hide-my-port=1
out-peers=32
# Never open ports on the router with UPnP
no-igd=1
# Skip peers on the Monero Project's DNS blocklist
enable-dns-blocklist=1

## RPC
# Unrestricted RPC: localhost only, never expose it
rpc-bind-ip=127.0.0.1
rpc-bind-port=18081
# Restricted RPC for wallets: safe to reach from your LAN
rpc-restricted-bind-ip=0.0.0.0
rpc-restricted-bind-port=18089
confirm-external-bind=1

## ZMQ (needed by P2Pool, see 3.1)
zmq-pub=tcp://127.0.0.1:18083

## Misc
check-updates=disabled

Save and exit. Make a ~/.bitmonero link so monerod commands run by monero find the data directory, then go back to nodeadmin:

ln -s /data/monero /home/monero/.bitmonero
exit

Full or pruned?

Full (the default) keeps everything and can help other nodes sync from scratch. Pruned keeps only 1/8 of the old prunable data (mostly signatures) plus everything recent, which brings the size down to about a third. It's just as secure for you and your wallets. If you're short on disk space, prune. You can't "un-prune" later without a fresh sync.

Autostart on boot

Create a systemd service:

sudo nano /etc/systemd/system/monerod.service
# MoneroBox: systemd unit for monerod
# /etc/systemd/system/monerod.service

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

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

# Hardening
PrivateTmp=true
ProtectSystem=full
ProtectHome=read-only
NoNewPrivileges=true
PrivateDevices=true

[Install]
WantedBy=multi-user.target

Enable it:

sudo systemctl daemon-reload
sudo systemctl enable monerod

Firewall

Allow the restricted RPC, so your wallets can reach the node:

sudo ufw allow 18089/tcp comment 'monerod restricted RPC'

The P2P port 18080 needs no rule: monerod only listens on 127.0.0.1 for it, and syncs and relays over its own outgoing connections to other nodes.

Hide all Monero traffic in Tor (optional)

By default monerod syncs and relays over the clearnet, so your ISP, and every peer your node connects to, can see that your IP runs a Monero node. tx-proxy from 2.2 only hides your own transactions. The proxy option goes further: it sends all of monerod's peer-to-peer traffic through Tor, the initial blockchain download (IBD) included. Your ISP then only sees Tor traffic, and peers only see Tor exit relays.

Before you turn it on, know the trade-offs:

  • Slower. Downloading the whole chain through Tor takes several times longer than over the clearnet. Once synced, keeping up with new blocks over Tor works fine.
  • No DNS. With proxy set, monerod makes no DNS lookups at all: it finds peers through its built-in seed list, and DNS checkpoints and enable-dns-blocklist stop working. A file-based ban list still works.
  • Exit relays. Your node still talks to ordinary Monero nodes, through Tor exit relays. An exit relay sees that traffic, though not your IP. Your node validates every block itself, so nobody can feed it fake blocks.

You can turn it on in two ways:

The most private option: your ISP never sees Monero traffic at all. Do this before you start monerod for the first time in Run.

In /data/monero/monerod.conf, add this line under ## P2P network:

# Send all P2P traffic, including the initial sync, through Tor
proxy=127.0.0.1:9050

Then continue with Run. Expect the initial sync to take considerably longer than the 1โ€“3 days mentioned there.

The faster option: sync over the clearnet first, then hide everything from then on. Your ISP sees Monero traffic during the initial sync, but not afterwards.

Wait until monerod status shows 100%. Then, in /data/monero/monerod.conf, add this line under ## P2P network:

# Send all P2P traffic through Tor
proxy=127.0.0.1:9050

Restart monerod:

sudo systemctl restart monerod

Check that everything goes through Tor

monerod should have no direct connections to peers on port 18080, and all its peer connections should go to Tor's SOCKS port, 9050:

sudo ss -tnp state established '( dport = :18080 )' | grep -c monerod
sudo ss -tnp state established '( dport = :9050 )' | grep -c monerod
0
14

The first number must be 0. The second is how many peers your node reaches through Tor; it grows over the first minutes. monerod sync_info shows the peers' clearnet addresses as usual: those are the nodes at the other end of each Tor circuit.

To turn it off again, remove the proxy line and restart monerod.

Run

Start monerod and follow the log:

sudo systemctl start monerod
journalctl -fu monerod

Open a second SSH session to follow the detailed log:

tail -f /data/monero/monerod.log

You'll see lines like:

Synced 1234567/3456789 (35%, 2222222 left)

Check sync status at any time:

monerod status
Height: 3456789/3456789 (100.0%) on mainnet, not mining, net hash 5.12 GH/s, v16, 32(out)+0(in) connections, uptime 1d 4h 12m 3s

(in) stays at 0: your node accepts no incoming connections (see Firewall). The (out) count goes up and down while it syncs; anything above zero is fine.

How long does the initial sync take?

With an NVMe SSD and a decent connection, 1โ€“3 days. On a SATA SSD or slower CPU, longer. On a hard drive, possibly weeks. Through Tor (see above), considerably longer. While it syncs, carry on with 2.2 Anonymous networking. Your node is ready for wallets when monerod status shows 100%.

Validation

Check that the service is running and listening on the right ports:

systemctl is-active monerod
sudo ss -tlnp | grep monerod
active
LISTEN 0  128  127.0.0.1:18081  0.0.0.0:*  users:(("monerod",pid=2345,fd=14))
LISTEN 0  128  127.0.0.1:18080  0.0.0.0:*  users:(("monerod",pid=2345,fd=10))
LISTEN 0  100  127.0.0.1:18083  0.0.0.0:*  users:(("monerod",pid=2345,fd=28))
LISTEN 0  100  127.0.0.1:18082  0.0.0.0:*  users:(("monerod",pid=2345,fd=25))
LISTEN 0  128    0.0.0.0:18089  0.0.0.0:*  users:(("monerod",pid=2345,fd=18))
  • Only 18089 (restricted RPC, for your wallets) listens on all interfaces.
  • 18080 (P2P), 18081 (unrestricted RPC), 18082 (ZMQ RPC) and 18083 (ZMQ pub) listen on 127.0.0.1 only. If 18081 shows 0.0.0.0, check rpc-bind-ip in the config right away.

Useful commands

All of these talk to the local unrestricted RPC on 127.0.0.1:18081:

monerod status          # height, sync %, connections
monerod sync_info       # sync details and peers you're downloading from
monerod print_net_stats # bandwidth used
monerod print_cn        # list peer connections
monerod diff            # current network difficulty
monerod print_pl        # known peers (white = recently seen, gray = unverified)
monerod bans            # currently banned peers
monerod hard_fork_info  # network upgrade status
monerod set_log 1       # more detailed log for a while; set_log 0 to go back
monerod version         # running version

Check the restricted RPC from your regular computer:

curl -s http://NODE_IP:18089/get_info | jq '.height, .synchronized'

Extras (optional)

Limit bandwidth

By default monerod allows up to 8192 kB/s upload and 32768 kB/s download. On a capped or slow connection, lower them in monerod.conf (values in kB/s):

limit-rate-up=1024
limit-rate-down=8192

Restart monerod afterwards. To try values without a restart, change them on the fly (they reset at the next restart):

monerod limit_up 1024
monerod limit_down 8192

Fewer peers also means less traffic: lower out-peers in the config.

Prune an existing full node

Changed your mind about disk space? There are two ways to prune a node that already synced in full:

  • In place: run monerod prune_blockchain and confirm. Quick to start, but the database file doesn't shrink: freed space is only reused for new blocks.
  • Pruned copy (frees the space): stop monerod, then run the pruning tool. It writes a pruned copy, swaps it in, and leaves the old database next to it:
    sudo systemctl stop monerod
    sudo -u monero monero-blockchain-prune --data-dir /data/monero
    sudo -u monero du -sh /data/monero/lmdb /data/monero/lmdb-old
    
    It needs free space for the copy (about a third of the full size). When monerod runs fine on the pruned database, delete /data/monero/lmdb-old.

Then add prune-blockchain=1 and sync-pruned-blocks=1 to the config, so the node stays pruned.

Build monerod from source

Prefer compiling over trusting release binaries? The release tags are signed by luigi1111, whose key is in the Monero repository:

sudo apt install -y build-essential cmake pkg-config git libssl-dev libzmq3-dev libunbound-dev \
  libsodium-dev libunwind-dev liblzma-dev libreadline-dev libexpat1-dev libpgm-dev \
  libhidapi-dev libusb-1.0-0-dev libprotobuf-dev protobuf-compiler libudev-dev libboost-all-dev
cd /tmp
git clone --recursive --branch v$VERSION https://github.com/monero-project/monero.git
cd monero
wget -O luigi1111.asc https://raw.githubusercontent.com/monero-project/monero/master/utils/gpg_keys/luigi1111.asc
gpg --show-keys luigi1111.asc      # must be 8777AB8F778EE89487A2F8E7F4ACA0183641E010
gpg --import luigi1111.asc
git verify-tag v$VERSION           # look for: Good signature from "luigi1111"
USE_SINGLE_BUILDDIR=1 make release -j$(nproc)
sudo install -m 0755 -o root -g root -t /usr/local/bin build/release/bin/monero*
The build takes 30โ€“90 minutes and needs about 4 GB of RAM. Then continue with Configuration as normal.

Troubleshooting

sha256sum: 'standard input': no properly formatted checksum lines found

hashes.txt has no line for the version you downloaded. It only lists the current release, so this happens as soon as a newer version is out than the one in VERSION. See which version it covers:

grep monero-linux-x64 hashes.txt
Set VERSION to that version, delete the old archive (rm monero-linux-x64-v*.tar.bz2), and repeat Download and Verify.

monerod doesn't start, or keeps restarting

Read the last lines of both logs:

sudo journalctl -u monerod -n 50 --no-pager
tail -50 /data/monero/monerod.log
Common causes:

  • A typo in monerod.conf: the log names the option it doesn't recognise. Fix the line and restart.
  • Wrong permissions: /data/monero must belong to monero. Fix with sudo chown -R monero:monero /data/monero.
  • Port already in use: something else listens on 18080/18081/18089. Find it with sudo ss -tlnp | grep 180.
The sync is stuck, or there are 0 connections

Run monerod sync_info and monerod print_cn.

  • 0 connections: check the node's internet connection, and that the firewall allows outgoing traffic (sudo ufw status verbose should show allow (outgoing)).
  • Connections, but the height doesn't move: usually a slow disk or a busy CPU. Check with htop: if monerod uses little CPU and the disk is busy, the disk is the bottleneck.
  • Restarting monerod (sudo systemctl restart monerod) often helps with a stalled sync.
Database errors after a power cut (MDB_CORRUPTED, Error opening database)

The database was damaged. Delete only the database folder, lmdb, and let monerod sync again. Your monerod.conf and logs in /data/monero stay.

sudo systemctl stop monerod
sudo rm -rf /data/monero/lmdb
sudo systemctl start monerod

The disk is full

df -h /data shows how much is left. Either move to a bigger SSD, or prune the node (see Extras). Log files are capped by max-log-file-size and max-log-files, so they won't fill the disk.

My wallet can't connect to NODE_IP:18089
  • The node must be fully synced first: monerod status shows 100%.
  • Check that 18089 listens on 0.0.0.0 (see Validation).
  • Check that the firewall has a rule for it: sudo ufw status | grep 18089.
  • From your regular computer: curl -s http://NODE_IP:18089/get_info | jq .status should print "OK".

Port reference

Port Protocol Use
18080 TCP P2P network (localhost only; the node connects out)
18081 TCP Unrestricted RPC (localhost only)
18082 TCP ZMQ RPC (localhost only)
18083 TCP ZMQ pub, used by P2Pool and monero-lws (localhost only)
18089 TCP Restricted RPC, for wallets

Upgrade

Watch for new releases on the Monero downloads page or the GitHub releases. Network upgrades (hard forks) require you to update before the fork height.

  1. Repeat Download, Verify and Install with the new VERSION.
  2. Restart the service:
sudo systemctl restart monerod
monerod --version

Uninstall

sudo systemctl disable --now monerod
sudo rm /etc/systemd/system/monerod.service /usr/local/bin/monero*
sudo ufw delete allow 18089/tcp
sudo rm -rf /data/monero          # deletes the blockchain!
sudo deluser --remove-home monero