This is just a note to myself. Posting here in case the thought bubbles and code snippets are useful for anyone else. I removed the article about the updated bootstrap script as I believe the version I created may no longer be current and don't want anyone to get stuck. If anyone really wants it, its still in the XDC Library on https://xdcoutpost.xyz/.
Lay and Secure the Server Foundations
Update the OS
To Install a New Node we first update and secure the OS:
sudo apt update
sudo apt upgrade
sudo apt autoremove
sudo apt clean
Prerequisites
Then to install prerequisites, there is an appendix at the bottom of this article but if thinking of using anything in there, please read the appendix first as I have not rechecked it since having slow peer pickup on another node installed using the instructions in the Appendix. For the moment, if unsure, they just check the XinFin Github repo for official prerequisites installation.
Create the Client's User
After updating the OS, we'll add a specific user to install the node under.
For the specific user's username, use up to 32 characters. Mix of numbers and lower case letters. First character must be a lower case letter.
For the specific users password, use up to 40 characters. Mix of numbers, upper and lower case letters, and symbols. Be careful with using $ as a character in the password in the useradd command below as it can be interpreted as a string variable even if its in the middle of the password.
sudo groupadd my_new_user
sudo useradd -p $(openssl passwd -6 my_new_password) my_new_user -m -s /bin/bash -g my_new_user -G sudo
sudo reboot
SSH-Key Authentication
If you've not already done so and plan on using SSH key authentication to login to the server, remember to do these from your local terminal you'll be connecting to the VPS from:
ssh-keygen
AND THEN
ssh-copy-id -p<yourcustomSSHport> login@serverip
Lock Down SSH Access
Then secure the ssh access to the server:
sudo nano /etc/ssh/sshd_config
You'll want to uncomment the line "#Port 22", and change the port number to something custom.
Also set:
PermitRootLogin no
PasswordAuthentication yes
PubkeyAuthentication yes
The "root" user is a weakness on the server as it is an easy username for hackers to "guess". If they have the username, they only need to guess the password. However if we take away the easy "root" username as an option, we create another whole level of pain for hackers. That's why the "PermitRootLogin no" is set.
For the above settings, you also need to determine whether password logins are even required for any user (or if you'll just manage with SSH key authentication).
Then restart the SSH service:
sudo service ssh restart
If SSH changes are failing, you can check if your VPS provider has additional override setings and where they are. For example:
sudo grep -rE '^\s*PermitRootLogin' /etc/ssh/
And then modify what you need to.
Firewall
Then we establish the firewall:
sudo apt install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 30303
sudo ufw allow <yourSSHport>
sudo ufw enable
reboot
Make sure you allow your SSH port before you reboot, otherwise you won't be able to connect to your VPS by SSH after rebooting. You may still be able to get in through a virtual terminal in your VPS provider's dashboard in that case and can then hopefully allow the port that way so you can get back in via SSH.
Fail2Ban Intrusion Protection System
Then to protect against repetitive automated brute-force intrusion attempts we set up fail2ban:
sudo apt install fail2ban
sudo cp -p /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
Then put these lines in the sshd section:
enabled = true
filter = sshd
port = ssh
banaction = iptables-multiport
findtime = 86400
# 86400 seconds = 1 day
bantime = -1
# -1 = ban forever
maxretry = 3
# 3 attempts in 1 day = ban
logpath = %(sshd_log)s
backend = %(sshd_backend)s
Then complete the fail2ban process:
sudo systemctl restart fail2ban
sudo systemctl enable fail2ban
To check who is banned:
sudo fail2ban-client status sshd
To unban an IP address:
sudo fail2ban-client set sshd unban <ip address>
Download the Chain Tarball
Now we download the chain tarball to avoid the slow sync from genesis. Make sure you're SSH'd in as the specific user, not root. We'll use a "screen" session to avoid broken pipes and will use "aria2c" to optimise a multiconnection download and ensure we can "resume" the download if it is broken for whatever reason.
sudo apt install screen
sudo apt install aria2
Run a screen session with:
screen
To detach a screen session but keep it running in the background, use:
Ctrl+A
and then press
D
To see a list of available screen sessions:
screen -ls
To reattach a screen session:
screen -r <sessionname>
To permanently close/exit a screen session just use:
exit
So.. Now that we're in our screen session, lets download the XDC chain tarball:
mkdir ~/chaindl
cd ~/chaindl
aria2c -x 8 -s 8 -k 1M https://download.xinfin.network/xdcchain.tar
If for whatever reason it is interrupted and needs to resume, we can add the --continue flag to the aria2c command.
Detach the screen session and come back later. You can peek in on it every now and then with the commands above. When it is finished, we need to decompress it. Once again, we can do this via a screen session and then detach it to protect the whole process from interruption.
To decompress it in the screen session:
sudo tar -xvf xdcchain.tar # Creates XDC directory
Then clean it up:
cd XDC
sudo rm -rf nodekey # Remove old node key
sudo rm -rf transactions.rlp # Clean up pending transactions
Install the XDC Node Client
Now to install the node using method 3 (from here https://github.com/XinFinOrg/XinFin-Node) and customise it:
cd ~
git clone https://github.com/XinFinOrg/XinFin-Node.git
cd XinFin-Node/mainnet
sudo nano .env
In the .env file, set your node name, email and set gcmode to "full" instead of "archive".
Then save and exit.
Note: there is also a gcmode setting in start_node.sh but this is a backup/default if the environment variable isn't already set. It defaults to "archive" if not set.
Then start the node briefly for 10 seconds or so and then shut it down again.. This creates some of the directories we need:
sudo bash docker-up.sh
sudo bash docker-down.sh
Now clean up the new directories by removing the chain files we dont need etc:
cd ~/XinFin-Node/mainnet/xdcchain
sudo rm -rf XDC
sudo rm -rf *.log
Now we move the earlier decompressed chain files into the new node:
sudo mv ~/chaindl/XDC .
Now we restart the node:
cd ~/XinFin-Node/mainnet
sudo bash docker-up.sh
Troubleshoot Peer Issues
Let the node sync.
If you're not picking up peers, then you can run the peer.sh script (while the node is running):
cd ~/XinFin-Node/mainnet
sudo bash peer.sh
If you get an error, then check the container name. I have noted that the docker containers have had different names at different stages or perhaps with different methods I'm not sure. To check the container name use:
sudo docker ps
Then edit the peer.sh script and update the hard-coded container name in there:
sudo nano peer.sh
If you had to do the container-name update in the script then run the peer.sh script again:
sudo bash peer.sh
The node should now pick up peers relatively quickly (ie it should be up to perhaps 15-20 peers within 10-15 minutes).
Residual "Open" Ports
The Docker port bindings will not be affected by ufw. This means that you will still see ports 8888 and 8989 showing as open if you scan the VPS ports with nmap from a terminal external to the VPS:
nmap -Pn -p 8888 Your.VPS.IP.ADDRESS
nmap -Pn -p 8989 Your.VPS.IP.ADDRESS
However, by default in the .env file, the environment variable "ENABLE_RPC=false" is set and this makes the start_node.sh script not expose the RPC/WS in the docker container. The ports 8888 and 8989 still show as open however as the docker proxy answers the handshake. So, even if someone tries to access those "open" ports, sorry nobody is home.
To actually decrease the attack surface even further we can simply disable to docker port bindings by editing the docker-compose.yml file:
cd ~/XinFin-Node/mainnet
sudo nano docker-compose.yml
Once you've opened the file, just use # to comment out the 2 port lines that handle the container port bindings for 8888 and 8989 as show here:
ports:
- "30303:30303"
# - "8989:8545"
# - "8888:8546"
Now just stop and restart the node. Then try the nmap scans again and those ports will now show as closed.
Node Migrations
If this is a node migration, once syncing has completed, remember to docker-down.sh the old and new nodes. Then delete the keystore file on the new node. Then scp the keystore file across from the old node to put it in the keystore directory on the new node. Then just docker-up.sh the new node.
Voila. New node!
Android/iOs Push Notifications
To receive Android/iOs push-notifications if your client/node goes offline, set up the free open-source XDC Sentinel tool.
To receive Android/iOs push-notifications of changes in Governance status of staked nodes + arrival alerts for Masternode Educational Rewards, set up the free open-source XDC Tycoon tool.
Appendix details just for me
Installing the XDC client on machines that have Intel CPUs, there are some considerations with one of the new Docker packages (docker-ce-rootless-extras) that must be removed.
The following code is not to be used. Something in the new customised bootstrap script I wrote (not the official XinFin version) resulted in a node I just installed not picking up peers so all the below steps when installing prerequisites etc need to be double checked to see if they may have been related. This section is a mental note to me just until I've finished playing next time I install a new node:
sudo apt-get update
sudo apt-get install \
apt-transport-https ca-certificates curl git jq \
software-properties-common -y
echo "Setting up Docker repository and installing Docker"
# Remove any old Docker installations
sudo apt remove docker docker-engine docker.io containerd runc docker-compose -y
sudo rm -f /usr/local/bin/docker-compose
# Add Docker's official GPG key and repository
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
# Handle Intel compatibility issue by removing and holding the problematic package
sudo apt remove docker-ce-rootless-extras -y
sudo apt-mark hold docker-ce-rootless-extras
sudo systemctl restart docker
Discussion (0)