Table of Contents
- Step 0 Purchase Equipment and Assemble NUC
- Step 1 Generate Staking Data
- Step 2 Install Linux Server
- Step 3 Secure the Server
- Step 4 Configure Port Forwarding
- Step 5 Configure Timekeeping
- Step 6 Generate Client Auth Secret
- Step 7 Install Reth
- Step 8 Install Prysm
- Step 9 Configure the Beacon Node Service
- Step 10 Configure the Validator Service
- Step 11 Import Validator Keys
- Step 12 Fund the Validators
Step 0 Purchase Equipment and Assemble NUC
First, you’ll need hardware to run the validator software on. Requirements can be found here as of 1/27/25, suggested hardware are as follows:- Asus NUC 14+ Pro
- 32GB RAM (64GB preferred)
- NVMe M.2 4TB
- Ethernet connection with 100 Mbps symmetrical (300 Mbps preferred)
- USB drive (used to install Linux) 4GB+
- HDMI (or USB) cord and connectable monitor for initial set up
- USB keyboard and mouse (mouse is only required if using Ubuntu desktop to generate new validator keys)
Step 1 Generate Staking Data
Only if setting up a new validator: If setting up a new validator (and haven’t already generated deposit data and validator key(s)), you’ll need to run the deposit tool CLI, and should do so from an air-gapped machine. If you are not generating new keys, skip to step 2. In order to have a machine ready to go, we will need to install an OS on your new validator hardware built in step 0. We’ll be using Ubuntu Desktop. On your laptop, navigate to ubuntu.com, download the latest LTS copy of Ubuntu Desktop (as of 2025, 24.04.1 LTS). In addition, download and install the Etcher tool which will allow you to flash the operating system onto the USB drive. Lastly, download the latest version of the deposit CLI tool - you want the AMD64 version - unzip the executable file. With all the software and data assembled, run the Etcher tool to flash the USB drive with Ubuntu Desktop using your laptop. Insert the USB into your air gapped machine (built in step 0), connect the machine to a monitor via HDMI (or USB), keyboard, and mouse, and go through the installation process (which should occur automatically). Make sure to choose the minimum settings allowed so things go quickly. Once the installation is complete, remove the USB drive, and reformat the disk to exFAT so you can move the deposit CLI tool onto the USB drive. You may also want to drop a text file into the USB drive with your withdrawal address to make the next step easier. Finally, re-insert the USB drive into the NUC and move the deposit CLI tool to your desktop. Now, run the binary file in a terminal window on your Linux desktop by using the below command (easier if you have your withdrawal address handy for a copy/paste!){#_Validators} with the number of validators you want to run (32ETH per), and {YourWithdrawalAddress} with an Ethereum address you control.
NOTE: Once set, the withdrawal address CANNOT be changed, so be ABSOLUTELY SURE that it is an address you control the private keys for (or it’s a multisig and you control the private keys to the underlying wallets) and correctly specified. For example: —eth1_withdrawal_address 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
DO NOT set the withdrawal address to a central exchange wallet or account. This MUST be an EOA or smart contract wallet, as ETH is not “transferred” but rather “generated” in the wallet via a state change, and that doesn’t play nicely with Coinbase/Kraken/etc.
Once you execute the above steps, confirm your withdrawal address within the generated files, and provide your language preferences. You will then be asked to create the validator keystore password. Note this password on the variables document. You will need this later to import the validator(s) into the Consensus Client. Please note that this document will be referenced a number of times below, and is meant to serve as an example for a way to keep a secure paper record of your passwords, file locations, etc.
Next, a seed phrase (mnemonic) will be generated. Back it up somewhere safe. This is CRITICAL. You will need this to add additional validators or to regenerate keys if lost. IF YOU LOSE THIS MNEMONIC, YOU MAY LOSE ACCESS TO THE VALIDATOR! Not your keys, not your coins.
Once you have confirmed your mnemonic your validator(s) will be created. The following files will be generated and placed on your desktop.
- The deposit_data-[timestamp].json file contains the public key(s) for the validator(s) and information about the staking deposit. This file will be used to complete the ETH staking deposit process later in this guide. This is where you can triple check the withdrawal address
- The keystore-[..].json files contain the encrypted validator signing key. There is one keystore file per validator that you are funding. These will be imported into the Consensus Client for use during validation operations.
- If you lose or accidentally delete the files it is possible to regenerate them using the Staking Deposit CLI tool and your mnemonic via the existing-mnemonic command (see here).
Step 2 Install Linux Server
Navigate to ubuntu.com, download the latest LTS copy of Ubuntu Server (as of 2025, 24.04.1 LTS). In addition, download and install the Etcher tool which will allow you to flash the operating system onto the USB drive. Then, run the Etcher tool to flash the USB drive with Ubuntu Server. Once that’s complete, pop the USB drive into your NUC, and restart it - also connect it to Ethernet if you haven’t already. Upon restart, hold fn+F10 in order to boot from USB. Follow the installation instructions, making sure to select the following settings:- When setting up hard drive settings, uncheck the LVM box else the full HD cannot be used
- You should make sure no software is downloaded or installed aside from OpenSSH
- Do not select “minimum” when installing the software, you will need the items downloaded and installed in the normal process
- Name your device whatever you like - and note this on your variable document
- Create a user when prompted to do so, and set a password for that user that’s sufficiently complex - note this on your variable document
ccze provides colorized log output, and jq is a JSON parser useful for formatting RPC responses.
After rebooting:
Step 3 Secure the Server
After the updates and restart complete, it’s time to change some security settings.Modify the Default SSH Port
Port 22 is the default SSH port and a common attack vector. Change the SSH port to avoid this. Choose a port number between 1024–49151 and run the following command to check is not already in use:Configure the Firewall
Install UFW:::1 localhost line, create a new line, and add the local IP of your node (see: variables), then a few spaces so you’re aligned with the localhost text, and then enter the name of the Node you used above (see: variables).
Now, let’s test to see if you can SSH into your Node. Simply open a new terminal window, and enter the following command, subbing in the name of the Node, user, and the SSH port (see: variables).
{user}@{node_name}, you’re set! Once you see this, you can disconnect the Node from the monitor and keyboard, and can perform the remainder of tasks from any laptop or computer on the same LAN using the command above to SSH in. The Node only needs to remain connected to power and ethernet (powered via UPS if possible).
Configure Fail2Ban
Fail2Ban is an intrusion-prevention program that scans log files and bans IPs that show malicious activity. If a certain number of failed logins are detected from a specific IP address (within a specified amount of time), that IP address is blocked. This service provides basic protection against brute-force attacks, and can be configured to ignore local IPs. Install fail2ban, and enable and start the service:Disable Root Access
It is best practice to not log in as root in order to maintain security and follow the principle of least-privilege. First, check to ensure another user besides root can run the sudo command (if you’ve gotten this far, this is just a double check step). Let’s first check sudo access:{your-username} may run the following commands on {device-name}: (ALL:ALL) ALL” you have sudo privileges with your current user.
Now, lock the root account:
Step 4 Configure Port Forwarding
From your laptop (or whichever device on the local network you plan on accessing the Node from), log into your router to edit the port forwarding settings. While access is different for each network set up and router, usually you can access your router at 192.168.1.1 or a similar local IP address. Occasionally, instructions can be found on the router itself. Once you’ve logged in to your router, edit the port forwarding settings for your Node to forward the following ports: Reth (Execution Client):- Port 30303 - TCP and UDP - P2P networking and Discovery v4
- Port 30305 - UDP only - Discovery v5 (improved peer discovery)
- Port 13000 - TCP and UDP - P2P networking
- Port 12000 - UDP only - QUIC discovery
Step 5 Configure Timekeeping
Running validators against a blockchain requires accurate timekeeping in order to ensure proper synchronization with the network. Validators need time accuracy within 0.5 seconds for proper attestations. While Ubuntu has time synchronization built in usingsystemd-timesyncd, we’ll use chrony instead, which provides more accurate time synchronization - critical for validators.
Install chrony (this will replace systemd-timesyncd):
- Leap status: Should say “Normal” (after a few minutes)
- System time: Should show offset in milliseconds (< 100ms is good, < 10ms is excellent)
- Stratum: Should be 2-4 (lower is better)
Step 6 Generate Client Auth Secret
On the server, communication between the Execution and Consensus clients is secured using a JSON Web Token (JWT) authentication scheme. The JWT is represented by a file that contains a randomly generated 32-byte hex string. The Execution and Consensus clients each make use of the file for message authentication. First, create a directory to store this file:Step 7 Install Reth
Time to install Reth! All commands provided below are based on the v1.9.3 version of Reth (current as of Nov 2025), but should be adjusted based on whatever the latest version of Reth is here - simply expand the Assets section and copy the URL for the ‘reth-v…-x86_64-unknown-linux-gnu.tar.gz’ file. Note that MANY commands below will need to update if this version is updated. Full Node vs Archive Node: This guide configures Reth as a full node (using the--full flag), which is the optimal configuration for validators:
- Full Node: Stores recent state and enough history to validate the chain. Syncs in hours (especially with snapshots), requires ~1-2TB storage, and is sufficient for all validation operations.
- Archive Node: Stores complete historical state since genesis. Takes weeks to sync, requires 3-4TB+ storage, and is only needed for specialized applications like block explorers or historical data analysis.
--fullflag: Runs Reth as a full node (not archive). For validators, you only need a full node which stores recent state. Archive nodes store all historical state since genesis and are unnecessary for validation, taking significantly longer to sync (weeks vs hours) and requiring much more disk space.TimeoutStopSec=900: Allows the Reth service 15 minutes to write cached data to disk on clean shutdown (important for large databases).KillSignal=SIGINT: Explicitly tells systemd to use SIGINT for graceful shutdown (same as Ctrl+C).- Port configuration: Explicitly sets P2P networking ports to 30303 (default) for better peer discovery. This is the default, but better to make explicit.
- Discovery v5: Enables the newer, more resilient peer discovery protocol on port 30305 UDP. Improves peer finding and network connectivity.
- Peer limits: Limits connections to 35 outbound + 35 inbound (70 total) to reduce bandwidth and resource usage while maintaining excellent connectivity. For gigabit home validators, this balances network contribution with efficiency.
--prune.accounthistory.full, --prune.storagehistory.full, etc.) as they will conflict with the --full flag’s configuration and cause the pruner to fail. The --full flag handles all pruning automatically.
Optional: Use Merkle Snapshot for Faster Initial Sync
Why use a snapshot? Syncing Reth from genesis can take days even with a full node. Using a recent snapshot from Merkle.io can reduce initial sync time to just a few hours. Merkle.io publishes Reth snapshots every Monday and Thursday atdownloads.merkle.io. Using a snapshot is particularly recommended for new installations or after database corruption.
To use a Merkle snapshot:
First, install required dependencies:
tmux to run the download to prevent it from being killed if your SSH connection drops.
Start a tmux session:
YYYY-MM-DD with the latest snapshot date (most recent Monday or Thursday). Check Merkle’s snapshot page for the current available dates.
Example for January 1, 2026:
- Detach from session (leaves download running): Press
Ctrl+BthenD - Reattach to session:
tmux attach -t reth-download - Monitor progress in another terminal:
watch -n 30 'df -h /var/lib/reth'ortail -f /var/lib/reth/wget-logorwatch -n 60 'du -sh /var/lib/reth'
- Download the Merkle snapshot
- Extract it directly into your data directory (streaming, no temp file)
- Set proper ownership as the reth user
--full flag, which takes 1-3 days but results in a smaller database (~1TB). Skip the snapshot download and proceed directly to starting the service. This is a valid approach if you have time and want to minimize storage usage, though the Merkle snapshot approach is faster and Reth’s upcoming pruning improvements will eventually make the difference negligible.
Start Reth Service
Reload systemd to reflect the changes and start the service. Check the status to make sure it’s running correctly:Step 8 Install Prysm
The Prysm Consensus Client is made up of two binaries that provide the functionality of the beacon node and validator, respectively. This step will download and prepare the Prysm binaries. Time to install Prysm! All commands provided below are based on the 7.1.2 version of Prysm (current as of 1/7/26), but should be adjusted based on whatever the latest version of Prysm is here. Note that many commands below will need to update if this version is updated. In the Assets section (expand if necessary) copy the download links to the beacon-chain-v…-linux-amd64 file and the validator-v…-linux-amd64 file. Be sure to copy the correct links. Download the binaries using the commands below. Modify the URL to match the copied download links:Step 9 Configure the Beacon Node Service
Set up an account for the services to run under (note: this type of account cannot log into the server):{FeeRecipientAddress} with the address you’d like to receive the validator tip fees.
Make sure to replace {CheckpointSyncURL} (x2) with a valid checkpoint sync URL see here for more information - be sure to select a Mainnet endpoint.
Press CTRL + X then Y then ENTER to save and exit.
Reload systemd to reflect the changes and start the service. Check the status to make sure it’s running correctly:
Step 10 Configure the Validator Service
Set up an account for the services to run under (note: this type of account cannot log into the server):{FeeRecipientAddress} with the address you’d like to receive the validator tip fees.
Press CTRL + X then Y then ENTER to save and exit.
Reload systemd to reflect the changes and start the service. Check the status to make sure it’s running correctly:
Step 11 Import Validator Keys
To import the keys into Prysm, we’ll need to get them onto the same machine.Copy Validator Keystore File(s) to Server
Before we transfer over the Validator Keystore file(s), we’ll need to create a place to store them:deposit_data-1682896118.json keystore-m_12381_3600_0_0_0-1682896115.jsonNote that while you will only ever have 1 deposit file (regardless of the amount of validators), you will have 1 keystore file for each validator you are setting up on the Node. You only need to move the keystore file(s) to the validator_keys folder. Now that we have the file names, we issue a command to copy those files from /mnt/usb to $HOME/staking-deposit-cli/validator_keys:
Import the Validator Keystore Files into Prysm
REMEMBER: If you import the same keystore twice OR run the same keystore on multiple nodes at the same time YOU WILL GET SLASHED! Now we will run the validator import process. You will need to provide the directory where the generated keystore-[..].json files are located. E.g. $HOME/staking-deposit-cli/validator_keys (as determined above in this step)Create a Wallet Password File
Create a file to store the wallet password so the Prysm validator service (set up below) can access the wallet without you having to supply the password:Step 12 Fund the Validators
Now that the Consensus Client is up and running, to actually begin staking on the Ethereum network you will need to deposit ETH to fund your validators. Note: DO NOT continue until your execution and consensus clients are fully synced. If they have not and your validator(s) become active on the network, you would be subject to inactivity penalties. You can determine sync status by checking the status of the Beacon Chain or through JSON-RPC calls to Reth, both methods are described above. With the deposit file in hand and an EOA with 32ETH per validator + some spare ETH for gas, head to the Ethereum Launchpad Click on Become a Validator, click through the warning steps and continue through the screens until you get to the Generate Key Pairs section. Select the number of validators you are going to run. Choose a value that matches the number of validators you created in Step 1. Scroll down, check the box if you agree, and click Continue. You will be asked to upload the deposit_data-[timestamp].json file. You generated this file in Step 1. (Note: There are no security concerns copying the file or having access to it on a public computer). Double check that inside the file the withdrawal address is set correctly. When satisfied, browse or drag the file to upload and click continue. Connect your wallet. Choose MetaMask (or one of the other supported wallets), log in, select the account where you have your ETH and click Continue. Your MetaMask balance will be displayed. The site will allow you to continue only if you have selected Mainnet and you have a sufficient ETH balance. A summary shows the number of validators and total amount of ETH required. Tick the boxes if you agree and click continue. If you are ready to deposit click onInitiate All Transactions.
This will pop open MetaMask (or one of the other supported wallets) where you can confirm and broadcast each transaction.
Once all the transactions have successfully completed you are done! WOOOOOOO! Congratulations you have deposited your stake!
Check the Status of Your Validator Deposits
Newly added validators can take a while to activate. You can check the status of your keys with these steps:- Copy your wallet address used to make the deposit
- Go to Beaconcha.in
- Search for your key(s) using your wallet address
Status section that provides an activation estimate time for each validator.
That’s it. You now have a functioning Execution and Consensus client and the staking deposit done. Once your deposit is active you will automatically begin staking and earning rewards.
Probably a good time to touch grass.
Clean Up validator_keys
While not essential as you can always regenerate them using your mnemonic, it’s good practice to back up the validator_keys directory (typically $HOME/staking-deposit-cli/validator_keys) on a USB for emergencies.
After ensuring you have a backup of these files as described in Step 1 Generate Staking Data, you can safely remove the validator_keys directory. Note that this will not impact your existing validators, as in Step 11 Import Validator Keys the validator_keys are imported into the validator instance. The copies referenced above are “extra”:

