BitCanna validator security: Introducing TMKMS in BitCanna

Tuesday, June 22, 2021

BitCanna advanced validator security: Tendermint Key Management System (TMKMS)

Managing validator private keys is certainly the most critical aspect in validating tendermint-based networks. These validator keys are responsible for signing and validating every block produced in the network, representing all the stake delegated to the node. If an attacker were capable to gain access to the server and steal the keys, it may use these keys to attack the network and the validator stake and reputation.

A proper Tendermint key-management system is also required to reduce double-signing accidents, which leads to the feared slashing and the death of the validator. These fatal incidents occur when a Tendermint-based validator signs a proposed block twice, which the network detects as an attack. This can be caused by running two Tendemint-based validators at the same time with the same private keys.

Introducing: Tendermint Key Management System (TMKMS)

TMKMS is the solution for managing validator keys in Tendermint-based networks. It was initially developed by the Cosmos team and it is currently maintained by Iqlusioninc.

This key management system separates the signing process from the validator, allowing to perform the signing process in different hosts. It also provides double-signing protection.

TMKMS is compatible with two signing backends:

  • Soft-sign: the common software signing with a plain private key. The advantages between this and not using TMKMS are the double-signing protection and having the keys and the validator in separated servers.
  • Hardware security modules (HSM): provided by devices like Ledger Nano S and YubiHSM, that signs without exposing the private keys. These methods are more secure but you need to have physical access to the server.

In this article, we explain how to configure a TMKMS service for a BitCanna validator using soft-sign in a different host.

How to configure TMKMS in Bitcanna validators

We need two servers to configure TMKMS on a Tendermint-based validator:

  • TMKMS server
  • Validator server

The TMKMS server should have a firewall with all the ports closed except the SSH port. The recommendation is to use a different SSH port than the default port 22, but we will use it as an example.

sudo ufw allow 22 ssh
sudo ufw enable

It would be best to allow SSH connections just from the authorized machines, so the command would look like this:

sudo ufw allow from <remote host> to any port 22

Once this is configured, we proceed to install Cargo and TMKMS:

sudo apt update  
sudo apt install build-essential git  
curl [https://sh.rustup.rs](https://sh.rustup.rs/) -sSf | sh  
# Select the default instalation
git clone [https://github.com/iqlusioninc/tmkms.git](https://github.com/iqlusioninc/tmkms.git) && cd tmkms

In this example, we are going to configure it to use software signature (Soft-sign) on a cloud server. If we have a local server, the most secure solution is to use Yubikey HSM signing.

cargo build --release --features=softsign

Once this is done, we need to go back to the validator server and check the Tendermint version that is running. We do this by using the following command:

bcnad tendermint version

It is important to check the Tendermint version because it will be configured later on the TMKMS server.

The next step is to allow access to port 26658 of the validator by just the IP of the TMKMS server:

sudo ufw allow from <ip tmkms> to any port 26658

Then, edit the validator configuration:

nano $HOME/.bcna/config/config.toml
priv_validator_laddr = "tcp://<validator ip>:26658"

Note that we need to place the validator IP instead of the TMKMS IP, this is correct.

As an alternative, we can add the NodeID as a prefix:

priv_validator_laddr = "tcp://<nodeid>@<validator ip>:26658"

In the TMKMS server, we can create new keys or import already existing keys. In this example, we are going to use the existing keys from a BitCanna validator. Thanks to that, we including TMKMS security in an already existing validator.

We will take the file from $HOME/.bcna/config/priv_validator_key.json and move it to the TMKMS machine.

In the TMKMS server, init a new service:

$HOME/tmkms/target/release/tmkms init $HOME/kms/bcna

Create the folders $HOME/kms/bcna in the TMKMS server and copy the priv_validator_key.json there. Then, execute these commands:

$HOME/tmkms/target/release/tmkms softsign import $HOME/kms/bcna/priv_validator_key.json $HOME/kms/bcna/secrets/cosmoshub-3-consensus.key

rm $HOME/kms/bcna/priv_validator_key.json

After that, edit the TMKMS Toml config file and place the correct chain-id, validator IP, and Tendermint version:

nano $HOME/kms/bcna/tmkms.toml

id = "bitcanna-testnet-3"
chain_ids= ["bitcanna-testnet-3"]  
chain_id= "bitcanna-testnet-3"  
key_format = { type = "bech32", account_key_prefix = "bcnpub", consensus_key_prefix = "bcnvalconspub" }  
addr = "tcp://Validator_IP:26658"  
protocol_version = "v0.34"

Start the TMKMS service by pointing to the config file we have just edited:

$HOME/tmkms/target/release/tmkms start -c $HOME/kms/bcna/tmkms.toml

Start the BitCanna validator. If the validator and TMKMS process return no errors, we can configure TMKMS as a service:

sudo tee <<EOF >/dev/null /etc/systemd/system/tmkmsbcna.service

[Unit]  
Description=tmkms bcna service  
After=network.target  
StartLimitIntervalSec=0

[Service]
Type=simple  
Restart=always  
RestartSec=10  
User=XXXXX  
ExecStart=$(echo $HOME)/tmkms/target/release/tmkms start -c $(echo $HOME)/kms/bcna/tmkms.toml  
LimitNOFILE=1024

[Install]  
WantedBy=multi-user.target
EOF

Enable the service:

sudo systemctl enable tmkmsbcna

Start the service:

sudo systemctl start tmkmsbcna

Check the logs:

journalctl -u tmkmsbcna -f

Thanks for reading this tutorial, we hope it helps to improve the overall security of the BitCanna network and other Tendermint chains. If you have any questions, you can reach us by email or on Telegram.

Written by