/u/settleddown posted some excellent instructions on how to create your own BloxStaking KeyVault instance in AWS and keep it updated yourself.
I've adjusted these instructions to "take over" the existing instance, without needing to spin up an entirely new one. The Python script now prompts the user for the password.
NB: pip3 is very slow on WSL2. This can be resolved by running pip3 install -U keyring
, and then mkdir -p ~/.config/python_keyring/
and edit vi ~/.config/python_keyring/keyringrc.cfg
and paste into it:
[backend]
default-keyring=keyring.backends.null.Keyring
After installing KeyVault via Blox Staking app, on the machine that Blox Staking app runs on, you can get the SSH key for the KeyVault, which is in your AWS account, us-west-1 region.
Copy paste the contents of the script into a file extract-blox-key.py
import base64
import binascii
import json
import hashlib
import getpass
import sys
from Crypto.Cipher import AES
def get_json_value(json,key,file,abort):
try:
value=json[key]
return value
except Exception as e:
print("Could not find",key,"in file",file)
print("Exception:",e)
if abort:
exit()
def main():
blox_ip=None
blox_port=None
if len(sys.argv) != 2:
print("Please give the path to the blox-github-ID.json file as a parameter:")
print(" python3 extract-blox-key.py /path/to/blox-github-ID.json")
print("If in WSL2, the path would be /mnt/c/Users/USER/AppData/Roaming/blox-live-desktop-app/blox-github-ID.json")
exit()
try:
blox_file = open(sys.argv[1],"r")
except Exception as e:
print("Unable to open file",sys.argv[1])
print("Exception:",e)
exit()
try:
blox_json=json.load(blox_file)
except Exception as e:
print("Unable to parse file",sys.argv[1])
print("Was it the right file?")
print("Exception:",e)
exit()
blox_key=get_json_value(blox_json,'keyPair',sys.argv[1],True)
blox_ip=get_json_value(blox_json,'publicIp',sys.argv[1],False)
blox_port=get_json_value(blox_json,'port',sys.argv[1],False)
blox_password=getpass.getpass(prompt="Please enter your Blox password: ")
encodedpass=base64.b64encode(hashlib.sha256(blox_password.encode()).digest())[:32]
try:
unhexed = binascii.unhexlify(blox_key.strip())
except Exception as e:
print("The keyPair value wasn't formatted as expected - please check the input file")
print("Exception:",e)
exit()
try:
keydict = json.loads(base64.b64decode(AES.new(encodedpass,AES.MODE_ECB).decrypt(unhexed)))
except Exception as e:
print("Unable to decrypt the private key. Was the password correct?")
print("Exception:",e)
exit()
print()
print(keydict['privateKey'])
print()
print("Next, paste this private key into ~/.ssh/blox-key")
print("Then give it a strong passphrase with 'ssh-keygen -f ~/.ssh/blox-key -p'")
print("Change its permissions with 'chmod 600 ~/.ssh/blox-key'")
if blox_ip and blox_port:
print("And finally, connect to your KeyVault server with 'ssh -i ~/.ssh/blox-key -p ",blox_port," ec2-user@",blox_ip,"'",sep='')
else:
print("And finally, connect to your KeyVault server with 'ssh -i ~/.ssh/blox-key -p 2200 ec2-user@KEYVAULT_IP'")
if __name__ == "__main__":
main()
Install the pycryptodome Python library: pip3 install pycryptodome
Then run the script to extract the key: python3 extract-blox-key.py /path/to/blox-LOGINMETHOD-ID.json
LOGINMETHOD
would be github
, google-oauth2
or windowslive
; and ID
is your specific ID assigned to you.
On WSL2 for example, with Github login, this would be python3 extract-blox-key.py /mnt/c/Users/USER/AppData/Roaming/blox-live-desktop-app/blox-github-ID.json
On MacOS with Google login, this would be python3 extract-blox-key.py "/Users/USER/Library/Application Support/blox-live-desktop-app/blox-google-oauth2-ID.json"
Take the resulting RSA PRIVATE KEY text and put it into a file ~/.ssh/blox-key
, and set file permissions for the user only - file explorer in Windows or chmod 600 ~/.ssh/blox-key
in WSL2. Set a strong passphrase for the key: ssh-keygen -f ~/.ssh/blox-key -p
Then connect to your blox instance via ssh -i ~/.ssh/blox-key -p 2200 ec2-user@VAULT-IP
If you'd like to make updating KeyVault seamless, you can create a docker-compose for it. The following instructions are inside the KeyVault, using your SSH session.
First install docker-compose, paste these one line at a time:
sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose version
Create a keyvault.env
file in ~
that contains your actual public IP (AWS instance elastic IP) instead of x.x.x.x:
VAULT_EXTERNAL_ADDRESS=x.x.x.x
Create a docker-compose.yml
file in ~
containing this:
version: "3"
services:
key_vault:
restart: unless-stopped
container_name: key_vault
image: bloxstaking/key-vault:latest
environment:
- UNSEAL=true
- VAULT_CLIENT_TIMEOUT=30s
env_file: keyvault.env
volumes:
- ~/data:/data
- ~/policies:/policies
ports:
- 8200:8200/tcp
cap_add:
- IPC_LOCK
Lastly, test that this is working with the following steps:
Stop running container:
docker stop key_vault
docker container rm key_vault
Start with docker-compose: docker-compose up -d
Followed by: docker ps
Check the logs: docker-compose logs -f key_vault
Check https://beaconcha.in/ . You may miss one attestation, but expect the next one to be successful.
Updating the vault is then as easy as: docker-compose pull
and docker-compose down && docker-compose up -d
Blox Live keeps an encrypted copy of your seed on your desktop machine. That's only necessary for creating validators and recreating KeyVault through Blox Live. It can be very desirable to remove this seed from your desktop so that it can't be compromised.
Find the blox-LOGINMETHOD-ID.json
, which on Windows is in C:\Users\USER\AppData\Roaming\blox-live-desktop-app
and on MacOS in /Users/USER/Library/Application Support/blox-live-desktop-app/
. You could make a copy of it on an encrypted USB key, or if you prefer, not do that, and just set up Blox Live from scratch if you ever want to add another validator. LOGINMETHOD
can be one of github
, google-oauth2
or windowslive
, depending on how you log in.
Edit this file and remove the value for seed
so it looks like this:
"seed": "",
Save the file. That's it. Blox Live will now be able to monitor your vault, but won't be able to add new validators or recreate the KeyVault, without being given that seed again.
Merci pour le code