This tutorial will use the latest build of Monero to create a pruned node service. A pruned node stores the blockchain in approximately one-third of the space as compared to a full node. More details about Monero blockchain pruning is available here: https://www.getmonero.org/2019/02/01/pruning.html.
Installation Overview
- Connect to server with SSH
- Create restricted service account
- Install Monero files
- Create Monero configuration
- Create Monero directories
- Configure Firewall entries
- Create Monero service
- Validating the Monero service
1. Connect to server with SSH
All of the configuration in this tutorial is performed on a headless Odroid N2+ so configuration will be performed within an SSH connection. Connect to the headless server with ssh <username>@<headless server ip>
. Enter the correct password to connect to an SSH session.
ssh <username>@<headless server ip>
2. Create Restricted Service Accounts
The Monero service will configured to run under a restricted account to reduce the vulnerability surface of the headless server. A monero
group and monero
user will be created. The user and group accounts will be defined as system accounts. A system user account has no home directory and no shell. As a final step the ownership of the monero files previously copied to /usr/local/bin will be changed to the monero user and group and permissions will be restricted.
# Create monero group
sudo groupadd --system monero
# Create monero user and add to monero group
sudo useradd --system -g monero monero
3. Install Monero Files
The required files to run a pruned node on ARM architecture have previously been compiled and are available as binary files from the Monero Github repo which is located at: https://github.com/monero-project/monero. Within the Github repo open the latest Release and scroll to Official Download Links. The link used in this tutorial is Linux, armv8 which will need to be downloaded from within the SSH session. The direct link is: https://downloads.getmonero.org/cli/monero-android-armv8-v0.17.3.0.tar.bz2. Downloading the file from within an SSH session requires installation of wget. After the file is downloaded the contents will be extracted and moved to the /usr/local/bin
directory.
# Move to home folder
cd ~
# Install wget
sudo pacman -S wget
# Download the latest version of Monero
wget https://downloads.getmonero.org/cli/monero-android-armv8-v0.17.3.0.tar.bz2
# Extract files
tar -xf monero-android-armv8-v0.17.3.0.tar.bz2
# Move files to /usr/local/bin
cd monero-android-armv8-v0.17.3.0
sudo mv monero* /usr/local/bin
# Change ownership of Monero files to monero user and group
sudo chown monero:monero /usr/local/bin/monero*
# Change permissions of Monero files (user = read, write, execute; group/other = read, execute)
sudo chmod 755 /usr/local/bin/monero*
4. Create Monero Configuration
The Monero file that runs as a node can be configured with command line arguments or it can be configured using a dedicated configuration file. Using a dedicated configuration file allows for easier configuration of the Monero service. A directory will be created for the Monero configuration file and a blank configuration file will be created. Then permissions will be set for the configuration file. The configuration file should be completed using the example at the end of this tutorial. There are many ways to accomplish this but the easiest way is to edit the blank configuration file using nano
and copy / paste the contents of the example configuration file.
# Create Monero configuration directory
sudo mkdir /etc/monero
# Create a configuration file
sudo touch /etc/monero/monerod.conf
# Configure permissions of the configuration file
sudo chown monero:monero /etc/monero/monerod.conf
sudo chmod 644 /etc/monero/monerod.conf
# Edit the configuration file
sudo nano /etc/monero/monerod.conf
## copy / paste the example monerod.conf contents
## save the file using <ctrl><x>
5. Create Monero Directories
This section creates a directory to store the Monero blockchain (/var/lib/monero/.bitmonero/lmdb), a directory to store logs (/var/log/monero), and a directory to store the Linux process file associated with the Monero service (/var/run/monero).
# Create Monero database directory
sudo mkdir -p /var/lib/monero/.bitmonero/lmdb
# Change ownership of the Monero database directory
sudo chown -R monero:monero /var/lib/monero/
# Change permission for the Monero database directory
sudo chmod -R 755 /var/lib/monero/
# Create Monero log directory
sudo mkdir /var/log/monero
# Change ownership of the Monero log directory
sudo chown monero:monero /var/log/monero
# Change permissions for the Monero log directory
sudo chmod 740 /var/log/monero
# Create Monero process directory
sudo mkdir /var/run/monero
# Change ownership of the Monero process directory
sudo chown monero:monero /var/run/monero
# Change permissions for the Monero process directory
sudo chmod 710 /var/run/monero
6. Configure Firewall Entries
Two firewall entries are required to allow the Monero service to function correctly. Port 18080 allows Monero to connect to peers to receive blockchain data and pool transactions. Port 18089 allows wallets to connect to the Monero service. If the headless server is located in behind a firewall then only wallets within the local network will be able to connect to the Monero service for wallet updates.
# Configure the firewall to allow Monero peers for blockchain updates
sudo ufw allow 18080/tcp
# Configure the firewall to allow Monero restricted RPC calls
sudo ufw allow 18089/tcp
7. Create Monero Service
This section details the core of the Monero service. All of the sections above support this section and this is where the service file will be created and the service started. Create a service file from the example included in this tutorial and then force systemctl to reload so that it recognizes the Monero service. Lastly the Monero daemon can be started so that the blockchain can be synced.
# Create a Monero service file
sudo nano /etc/systemd/system/monero.service
## copy / paste the example monerod.service contents
## save the file using <ctrl><x>
# Reload systemctl so that the Monero service is recognized
sudo systemctl daemon-reload
# Start the Monero service (syncing the blockchain will take a few days)
sudo systemctl start monerod
8. Validating the Monero Service
There are multiple ways to validate the Monero service but the easiest two are: (1) run the command monerod status
, and (2) run the command sudo systemctl status monerod
.
Example Files
monerod.conf
# /etc/monero/monerod.conf
# Data directory (blockchain db and indices)
data-dir=/var/lib/monero/.bitmonero # Remember to create the monero user first
# Log file
log-file=/var/log/monero/monerod.log
max-log-file-size=0 # Prevent monerod from managing the log files; we want logrotate to take care of that
# Pruning configuration (THIS IS REQUIRED FOR STORAGE SIZE)
prune-blockchain=1
# Slow but reliable db writes (THIS ENSURES POWER FAILURES DO NOT CORRUPT THE DATABASE)
db-sync-mode=safe:sync
# P2P configuration
p2p-bind-ip=0.0.0.0 # Bind to all interfaces (the default)
p2p-bind-port=18080 # Bind to default port
# RPC configuration
rpc-restricted-bind-ip=0.0.0.0 # Bind restricted RPC to all interfaces
rpc-restricted-bind-port=18089 # Bind restricted RPC on custom port to differentiate from default unrestricted RPC (18081)
# no-igd=1 # Disable UPnP port mapping, add if not behind NAT or connecting through TOR
# ZMQ configuration
zmq-pub=tcp://127.0.0.1:18083 # Used for p2pool
# Block known-malicious nodes from a DNSBL
enable-dns-blocklist=1
# Included in p2pool config
disable-dns-checkpoints=1
# Peer list configuration
out-peers=64 # This will enable much faster sync and tx awareness; the default 8 is suboptimal nowadays
in-peers=1024 # The default is unlimited; we prefer to put a cap on this
# Set download and upload limits, if desired
limit-rate-up=50 # 128000 kB/s == 125MB/s == 1GBit/s; a raise from default 2048 kB/s; contribute more to p2p network
limit-rate-down=12800 # 128000 kB/s == 125MB/s == 1GBit/s; a raise from default 2048 kB/s; contribute more to p2p network
# Hide port
hide-my-port=1 # Do not advertise IP across the network
monerod.service
[Unit]
Description=Monero Full Node (Mainnet)
After=network.target
[Service]
# Process management
####################
Type=forking
PIDFile=/run/monero/monerod.pid
ExecStart=/usr/local/bin/monerod --config-file=/etc/monero/monerod.conf --pidfile /run/monero/monerod.pid --detach
Restart=on-failure
RestartSec=30
# Directory creation and permissions
####################################
# Run as monero:monero
User=monero
Group=monero
# /run/monero
RuntimeDirectory=monero
RuntimeDirectoryMode=0710
# /var/lib/monero
StateDirectory=monero
StateDirectoryMode=0710
# /var/log/monero
LogsDirectory=monero
LogsDirectoryMode=0710
# /etc/monero
ConfigurationDirectory=monero
ConfigurationDirectoryMode=0710
# Hardening measures
####################
# Provide a private /tmp and /var/tmp.
PrivateTmp=true
# Mount /usr, /boot/ and /etc read-only for the process.
ProtectSystem=full
# Deny access to /home, /root and /run/user
ProtectHome=true
# Disallow the process and all of its children to gain
# new privileges through execve().
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target