NixOS is a Linux distribution which is configured via declarative scripts. The main system configuration is found in /etc/nixos/configuration.nix
which allows one to deploy a wallet either at home or on a remote machine with ease. This is useful when one wishes to host a wallet without giving up control or privacy.
To test the setup NixOS 19.03 on EC2 was used and some grin were withdrawn from an exchange. NixOS is cool because it can be customised using nix scripts.
The assumptions are that you have a domain name somewhere that you can point to your public
IP. You can either setup a NixOS box at home and forward the inbound ports 80 and 443 to
the machine or set up an instance in the cloud provisioned with a NixOS image.
Step 1. Installing basic tools
You’ll need git in order to download grin. The following needs to be added to /etc/nixos/configuration.nix
in order to add git and tmux to your environment.
{ pkgs, ... }:
{
...
environment.systemPackages = with pkgs; [
wget git tmux
];
}
Step 2. Setting up an environment
We can use the rust overlay from mozilla to setup a shell so that the grin wallet and server become buildable.
This script could be improved but I will leave that up to readers. For the sake of simplicity save this file as default.nix
and run nix-shell
in the directory where it is saved.
{ pkgs ? import <nixpkgs> {} }:
let
src = pkgs.fetchFromGitHub {
owner = "mozilla";
repo = "nixpkgs-mozilla";
rev = "9f35c4b09fd44a77227e79ff0c1b4b6a69dff533";
sha256 = "18h0nvh55b5an4gmlgfbvwbyqj91bklf1zymis6lbdh75571qaz0";
};
in
with import "${src.out}/rust-overlay.nix" pkgs pkgs;
let
rustPlatform = pkgs.makeRustPlatform {
cargo = latest.rustChannels.stable.rust;
rustc = latest.rustChannels.stable.rust;
};
in
rustPlatform.buildRustPackage rec {
name = "grin-miner-${version}";
version = "0.1";
src = pkgs.fetchFromGitHub {
owner = "mimblewimble";
repo = "grin-miner";
rev = "143db3b13ce9a2aee5150b41c8691f133f74bc7d";
sha256 = "0gh4hy1cs9l2yq1nnsqv1zv6qc4808g1dx1am27jb8ycqgpbkyhf";
fetchSubmodules = true;
};
RUST_BACKTRACE = 1;
hardeningDisable = [ "format" ];
LIBCLANG_PATH="${pkgs.llvmPackages_5.libclang}/lib";
buildInputs = with pkgs; [
ncurses
zlib
pkgconfig
openssl
cmake
clang
];
cargoSha256 = "053711lsgi6zhgq7a2h4mkrxymws66c8g5y60hpifz5x1sxcgiiw";
meta = with pkgs.stdenv.lib; {
description = "grin-tech";
homepage = https://github.com/mimblewimble/grin-miner;
license = licenses.mit;
};
}
Running nix-shell
brings you into a new prompt with the tools required to build.
In the new shell clone the grin repositories, cd into them and run cargo build --release
.
[nix-shell]$ cd ~/
[nix-shell]$ git clone https://github.com/mimblewimble/grin
[nix-shell]$ git clone https://github.com/mimblewimble/grin-wallet
[nix-shell]$ cd grin && cargo build --release && cd ../
[nix-shell]$ cd grin-wallet && cargo build --release && cd ../
This will build the grin and grin-wallet under target/release
.
Step 3. Setting up tmux
tmux is useful to create a session in the shell that can be re-connected to in case you get disconnected from the remote machine.
To start a tmux session just type tmux
in the shell, use ctrl b c
to create two new tabs and use ctrl b <n>
where n is the tab number to switch between them.
You want to be running grin server in the first tab, grin-wallet in the second and use the third to navigate your machine or perform maintenance.
Switch to the first tab (ctrl b 0
), cd into the grin directory (e.g cd ~/grin
) and run the grin server.
Switch to the second tab (ctrl b 1
), cd into the grin-wallet directory (e.g cd ~/grin-wallet
) and run the grin wallet.
Instructions for running these programs can be found on the github but basically you want the grin server to be started and the grin wallet to be listening (target/release/grin-wallet listen
).
Once both are running, go to the third tab ctrl b 2
in order to continue.
Step 4. Setting up self signed SSL certificates
You need SSL certificates in order for be able to serve HTTPS. Add the following to /etc/nixos/configuration.nix
and do nixos-rebuild switch
where wallet.example.com
is replaced with your real domain / subdomain.
security.acme.certs."wallet.example.com" = {
webroot = "/var/www/challenges";
email = "contact@example.com";
};
Step 5. Setting up a reverse proxy
You need a reverse proxy which will proxy requests to your listening wallet. Uncomment the lines you added previously to /etc/nixos/configuration.nix
and add the nginx configuration below it as shown below. Modify the domain accordingly to your requirements.
# Make sure these lines are uncommented
# security.acme.certs."wallet.example.com" = {
# webroot = "/var/www/challenges";
# email = "contact@example.com";
# };
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
virtualHosts = {
"wallet.example.com" = {
addSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://127.0.0.1:3415/";
};
};
};
};
Once the configuration has been modified, run nixos-rebuild switch
which will start the reverse proxy. If the grin wallet is listening on the default port (3415) this will proxy requests to the listening wallet. You also have to make sure that the domain name that you own points to the public IP address of the machine. This involves adding an A record with the domain host.
You should now be able to send grin to https://wallet.example.com
.