Skip to content

Running Monerod via Systemd

The end goal

You will publicly offer the following services, where xxx.yyy.zzz.vvv is your server IP address.

  • xxx.yyy.zzz.vvv:18080 - clearnet P2P service (for other nodes)
  • xxx.yyy.zzz.vvv:18089 - clearnet RPC service (for wallets)

Why run this specific setup?

You will be able to connect your desktop and mobile Monero wallets to your own trusted Monero node, in a secure and private way over Tor.

Running as a systemd service will allow your node to always remain synced, as opposed to intermittently running node.

Public RPC service - The public-node config option will broadcast your RPC port to your peers, providing a service for anyone to use your node to connect their wallets to the Monero network. This is useful to users who don't run their own nodes. You may enable it by removing the # from #public-node in the config.

Public RPC may be resource intensive

Providing Public RPC via the flag public-node=1 may use a sizeable amount of resources on your PC.

Assumptions

You possess:

  • Basic understanding of Linux administration
  • Root access to a Linux server
  • Recommended 4 GB+ RAM
  • Recommended available SSD storage of
    • 550.0 GB+ for the full node
    • 200.0 GB+ for the pruned

Current blockchain size as of 2024-09-19

The current blockchain sizes are approximately:
Full node: 220 GB
Pruned node: 80 GB

Some commands assume Ubuntu but you will easily translate them to your distribution.

Install Monero

  1. Create monero user and group:

    useradd --system monero
    
  2. Create monero config, data and log directories:

    mkdir -p /etc/monero     # config
    mkdir -p /var/lib/monero # blockchain
    mkdir -p /var/log/monero # logs
    chown monero:monero /etc/monero
    chown monero:monero /var/lib/monero
    chown monero:monero /var/log/monero
    

    Feel free to adjust above to your preferred conventions, just remember to adjust the paths in the systemd and monerod config files accordingly.

  3. Download and verify the archive.

  4. Extract the binaries (adjust filename if necessary):

    tar -xvf monero-linux-x64-v0.18.3.4.tar.bz2
    rm monero-linux-x64-v0.18.3.4.tar.bz2
    
  5. Move binaries to /usr/local/bin/:

    mv monero-x86_64-linux-gnu-v0.18.3.4/* /usr/local/bin/.
    chown monero:monero /usr/local/bin/monero*
    

Monerod Config

  1. Create /etc/monero/monerod.conf as shown below:

    # /etc/monero/monerod.conf
    #
    # Configuration file for monerod. For all available options see the MoneroDocs:
    # https://docs.getmonero.org/interacting/monerod-reference/
    
    # Data directory (blockchain db and indices)
    data-dir=/var/lib/monero/bitmonero   # Blockchain storage location
    
    # Optional pruning
    #prune-blockchain=1           # Pruning saves 2/3 of disk space w/o degrading functionality but contributes less to the network
    #sync-pruned-blocks=1         # Allow downloading pruned blocks instead of prunning them yourself
    
    # Centralized services
    check-updates=disabled         # Do not check DNS TXT records for a new version
    enable-dns-blocklist=1           # Block known malicious nodes
    
    # Log file
    log-file=/var/log/monero/monero.log
    log-level=0                    # Minimal logs, WILL NOT log peers or wallets connecting
    max-log-file-size=2147483648   # Set to 2GB to mitigate log trimming by monerod; configure logrotate instead
    
    # P2P full node
    #p2p-bind-ip=0.0.0.0            # Bind to all interfaces (the default)
    #p2p-bind-port=18080            # Bind to default port
    #no-igd=1                       # Disable UPnP port mapping
    
    # RPC open node
    #public-node=1                  # Advertise to other users they can use this node for connecting their wallets
    rpc-restricted-bind-ip=0.0.0.0 # Bind to all interfaces (the Open Node)
    rpc-restricted-bind-port=18089 # Bind to a new RESTICTED port (the Open Node)
    
    # RPC TLS
    rpc-ssl=autodetect             # Use TLS if client wallet supports it (Default); A new certificate will be regenerated every restart
    
    # ZMQ
    #zmq-rpc-bind-ip=127.0.0.1      # Default 127.0.0.1
    #zmq-rpc-bind-port=18082        # Default 18082
    zmq-pub=tcp://127.0.0.1:18083  # ZMQ pub
    #no-zmq=1                       # Disable ZMQ RPC server
    
    # Mempool size
    max-txpool-weight=2684354560   # Maximum unconfirmed transactions pool size in bytes (here ~2.5GB, default ~618MB)
    
    # Database sync mode
    #db-sync-mode=safe:sync        # Slow but reliable db writes
    
    # Network limits
    out-peers=24              # This will enable much faster sync and tx awareness; the default 8 is suboptimal nowadays
    in-peers=48               # The default is unlimited; we prefer to put a cap on this
    
    limit-rate-up=1048576     # 1048576 kB/s == 1GB/s; a raise from default 2048 kB/s; contribute more to p2p network
    limit-rate-down=1048576   # 1048576 kB/s == 1GB/s; a raise from default 8192 kB/s; allow for faster initial sync
    
    # Tor/I2P: broadcast transactions originating from connected wallets over Tor/I2P (does not concern relayed transactions)
    #tx-proxy=i2p,127.0.0.1:4447,16.disable_noise  # I2P
    #tx-proxy=tor,127.0.0.1:9050,16,disable_noise  # Tor
    
    # Tor/I2P: tell monerod your onion address so it can be advertised on P2P network
    #anonymous-inbound=PASTE_YOUR_I2P_HOSTNAME,127.0.0.1:18085,64         # I2P
    #anonymous-inbound=PASTE_YOUR_ONION_HOSTNAME:18084,127.0.0.1:18084,64 # Tor
    
    # Tor: be forgiving to connecting wallets
    disable-rpc-ban=1
    

Systemd

  1. Create /etc/systemd/system/monerod.service as shown below.

    # /etc/systemd/system/monerod.service
    
    [Unit]
    Description=Monero Daemon
    After=network-online.target
    
    [Service]
    ExecStart=/usr/local/bin/monerod --detach --config-file /etc/monero/monerod.conf --pidfile /run/monero/monerod.pid
    ExecStartPost=/bin/sleep 0.1
    PIDFile=/run/monero/monerod.pid
    Type=forking
    
    Restart=on-failure
    RestartSec=30
    
    User=monero
    Group=monero
    RuntimeDirectory=monero
    
    StandardOutput=journal
    StandardError=journal
    
    [Install]
    WantedBy=multi-user.target
    
  2. Enable the monerod service:

    systemctl daemon-reload
    systemctl enable monerod
    systemctl restart monerod
    
  3. Verify it is up:

    systemctl status monerod
    
  4. Verify it is working as intended:

    tail -n100 /var/log/monero/monero.log
    

Open firewall ports

If you use a firewall (and you should), open 18080 and 18089 ports for incoming TCP connections. These are for the incoming clearnet connections, P2P and RPC respectively.

You do not need to open any ports for Tor.

For example, for popular ufw firewall, that would be:

ufw allow 18080/tcp
ufw allow 18089/tcp

To verify, use ufw status. The output should be similar to the following (the 22 being default SSH port, unrelated to Monero):

To                         Action      From
--                         ------      ----
22/tcp                     LIMIT       Anywhere
18080/tcp                  ALLOW       Anywhere
18089/tcp                  ALLOW       Anywhere
22/tcp (v6)                LIMIT       Anywhere (v6)
18080/tcp (v6)             ALLOW       Anywhere (v6)
18089/tcp (v6)             ALLOW       Anywhere (v6)

Tor & I2P

Tor Setup

The end goal

To enable the following services:

  • yourlongv3onionaddress.onion:18084 - onion P2P service (for other onion nodes)
  • yourlongv3onionaddress.onion:18089 - onion RPC service (for wallets connecting over Tor)

Onion service for P2P network is useful for other full node users as it allows them to broadcast transactions over Tor (using --tx-proxy option).

Onion service for wallet interface is useful for wallet users connecting over Tor because it mitigates Clearnet and Tor exit node MiTM risks (which are very real). By connecting wallet to an onion service, no MiTM attack is realistic because onion connections are end-to-end encrypted.

Why different P2P ports for clearnet and onion?

A: The data served by the Onion p2p port differs from clearnet P2P. A different port is required.

  1. Elevate to root:
    sudo su -
    
  2. 🔗 Install Tor

  3. Add the following lines to /etc/tor/torrc:

    HiddenServiceDir /var/lib/tor/monerod
    HiddenServicePort 18089 127.0.0.1:18089    # interface for wallet ("RPC")
    HiddenServicePort 18084 127.0.0.1:18084    # interface for P2P network
    

  4. Enable Tor service:
    systemctl enable tor
    systemctl restart tor
    
  5. View/Copy your new Onion Address:
    cat /var/lib/tor/monerod/hostname
    
  6. Copy the result into your Monero config file 🔗, enabling these options:
    anonymous-inbound=yourlongv3onionaddress.onion:18084,127.0.0.1:18084
    tx-proxy=tor,127.0.0.1:9050,disable_noise
    
    Replace yourlongv3onionaddress.onion with your onion address.
  7. The node is now available on Tor. You can check that the service is working by using curl:
    curl -x socks5h://127.0.0.1:9050 http://yourlongv3onionaddress.onion:18089/get_info
    
Backup Onion keys

You may want to backup your keys folder (/var/lib/tor/monerod) to secure control over your onion address.

How Tor onion services work?

A fresh onion address and corresponding key pair were created for you in /var/lib/tor/monero/.
This happens on restart whenever you add a new HiddenServiceDir to the /etc/tor/torrc config file.
The tor daemon will forward traffic from a virtual onion port to an actual localhost port, where some service is listening (in our case, this will be monerod).
A single onion address can offer multiple services at various virtual ports.

I2P Setup

The end goal

To enable the following services:

  • yourlongb32i2paddress.b32.i2p:18085 - i2p P2P service (for other i2p nodes)
  • yourlongb32i2paddress.b32.i2p:18089 - i2p RPC service (for wallets connecting over i2p)

I2P service for P2P network is useful for other full node users as it allows them to broadcast transactions over I2P (using --tx-proxy option).

I2P service for wallet interface is useful for wallet users connecting over I2P because it mitigates Clearnet and Tor exit node MiTM risks (which are very real). By connecting wallet to an I2P service, no MiTM attack is realistic because I2P connections are end-to-end encrypted.

Why different P2P ports for clearnet and i2p?

A: The data served by the i2p p2p port differs from clearnet P2P. A different port is required

  1. Elevate to root:
    sudo su -
    
  2. Install i2pd:
    apt install apt-transport-https
    wget -q -O - https://repo.i2pd.xyz/.help/add_repo | bash -s -
    apt update
    apt install i2pd
    
  3. Create a server tunnel for the Monero P2P and RPC ports:
    cat << EOF > /etc/i2pd/tunnels.conf.d/monero-mainnet.conf
    [monero-node]
    type = server
    host = 127.0.0.1
    # Anonymous inbound port
    port = 18085
    inport = 0
    keys = monero-mainnet.dat
    
    [monero-rpc]
    type = server
    host = 127.0.0.1
    # Restricted RPC port
    port = 18089
    keys = monero-mainnet.dat
    EOF
    
  4. Restart i2pd:
    systemctl restart i2pd
    
  5. Find the new b32 address of the node:

    curl -s http://127.0.0.1:7070/?page=i2p_tunnels | grep -Eo "[a-zA-Z0-9./?=_%:-]*" | grep "18085"`
    

    Go to the web console at 127.0.0.1:7070 -> I2P tunnels page.
    Look for Server tunnels and you will see an address like yourlongb32i2paddress.b32.i2p next to monero-node.

  6. Copy the result into your Monero config file 🔗, enabling these options:

    anonymous-inbound=yourlongb32i2paddress.b32.i2p,127.0.0.1:18085
    tx-proxy=i2p,127.0.0.1:4447,disable_noise
    

    Replace yourlongb32i2paddress.b32.i2p with your b32 address.

  7. The node is now available on i2p. You can check that the service is working by using curl:

    curl -x socks5h://127.0.0.1:4447 http://yourlongb32i2paddress.b32.i2p:18089/get_info
    

(Optional) Register short and memorable .i2p domain on reg.i2p

Testing

Testing

On server

List all services listening on ports and make sure it is what you expect:

sudo netstat -lntpu

The output should include these (in any order); obviously the PID values will differ.

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
...
tcp        0      0 0.0.0.0:18080           0.0.0.0:*               LISTEN      259255/monerod
tcp        0      0 0.0.0.0:18089           0.0.0.0:*               LISTEN      259255/monerod
tcp        0      0 127.0.0.1:18084         0.0.0.0:*               LISTEN      259255/monerod
tcp        0      0 127.0.0.1:9050          0.0.0.0:*               LISTEN      258786/tor

On client machine

Finally, we want to test connections from your client machine.

Install tor and torsocks on your laptop, you will want them anyway for Monero wallet.

Just for testing, you will also need nmap and proxychains.

Test clearnet P2P connection:

nmap -Pn -p 18080 YOUR_IP_ADDRESS_HERE

Test clearnet RPC connection:

curl --digest -X POST http://YOUR_IP_ADDRESS_HERE:18089/json_rpc -d '{"jsonrpc":"2.0","id":"0","method":"get_info"}' -H 'Content-Type: application/json'

Test onion P2P connection (skip if you don't have proxychains):

proxychains nmap -Pn -p 18084 YOUR_ONION_ADDRESS_HERE.onion

Test onion RPC connection:

curl -x socks5h://127.0.0.1:9050 --digest -X POST http://YOUR_ONION_ADDRESS_HERE.onion:18089/json_rpc -d '{"jsonrpc":"2.0","id":"0","method":"get_info"}' -H 'Content-Type: application/json'`

Debugging

Debugging

Tor:

  • Status: systemctl status tor@default
  • Logs: journalctl -xe --unit tor@default

Monerod:

  • Status: systemctl status monero
  • Logs: tail -n100 /var/log/monero/monero.log
  • Logs more info: change log-level=0 to log-level=1 in monero.conf (remember to revert once solved)