title: Introducing ChainLock, A Linux Tool for Locking Down Important Files

What’s the problem?

Let’s say you have a valuable file on your computer, such as a bitcoin wallet.dat file. You want to keep the wallet secure, so you put a password on it. But it’s a short password, so you can type it in more easily. Or it’s a reused password, so you can remember it. Or maybe you only keep a small amount of currency there, so you don’t bother with a password.

Maybe you’ve taken steps to protect yourself from clipboard hijacking malware, and now you’re wondering what to do next. Or maybe you haven’t. Either way, you still have a problem. It is common for malware to target and steal your wallet.dat file. The attacker only needs to exfiltrate the file so they can crack your password offline, then they can transfer your funds to an account they control.

In addition, in July we discovered clipboard hijacking malware that now targets our CCW tool. Clearly we need to step our game up a bit.

Since the original CCW tool was for Windows, we wanted to create something for Linux users. We wanted the tool to be accessible, so it could be used to protect sensitive files without doing things like recompiling the kernel or configuring SELinux. We ended up with a new tool, dubbed ChainLock, which can lock any file on your Linux computer such that it can only be opened by a specific application. For example, it can ensure your wallet.dat file can only be accessed by your bitcoin core application and can’t be opened or copied by malware.

How do I install it?

You can find the .deb for 64 bit systems here and the Android .apk here. Note that you need tor and python3 installed on Linux and Orbot installed on Android. You will also need a kernel with fanotify support, check /boot/config for CONFIG_FANOTIFY=y and CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y.

$ wget https://chainlock.e-paths.com/static/chainlock-1.0.0_amd64.deb
$ sudo dpkg -i chainlock-1.0.0_amd64.deb

You can verify your download with the following hashes:

$ sha256sum chainlock-1.0.0_amd64.deb
72be011da373273f87675ba18389be269122205833b496c4e827ea302c1db582  chainlock-1.0.0_amd64.deb
$ sha256sum ChainlockCompanion.apk
2fa1ee1e1ac9873098d2a1f55204c098dae1970d9f7753f8b86a8713b60b675d  ChainlockCompanion.apk

How does it work?

Here’s how it works, with example commands so you can follow along. We’re going to use an empty wallet.dat file in a user’s ~/.bitcoin folder.

$ chainlock --help
usage: chainlock [-h] [-l | -u | -i INITIALIZE INITIALIZE] [-t]

optional arguments:
  -h, --help            show this help message and exit
  -l, --lock            Lock all unlocked files.
  -u, --unlock          unlock the protected file
  -i INITIALIZE INITIALIZE, --initialize INITIALIZE INITIALIZE
                        Start protecting the target file (first argument),
                        allowing access with the specified binary (second
                        argument). Use the full path.
  -p UPGRADE, --upgrade UPGRADE
                        Change the authorized binary for a file.
  -t, --testing

First, we onboard a file with the CLI program. This encrypts the target file with a strong password (under the hood it’s using gocryptfs), moves the encrypted file to a special folder, and replaces the original with a symlink to the encrypted file. Then a QR code pops up on screen which we can scan with the companion application. This QR code contains the key to decrypt the encrypted file, a code to identify the file being protected, and the hash of the binary allowed to access the protected file.

$ mkdir -p ~/.bitcoin
$ cd ~/.bitcoin/
$ echo "Test Wallet." > wallet.txt
$ chainlock -i /home/user/.bitcoin/wallet.txt /usr/bin/cat
Please scan the QR code that pops up in your companion app.

Now the key to unlock the protected file is only stored on your phone and can’t be found on your computer. An attacker must compromise both devices to unlock your file without permission.

$ ll wallet.txt 
lrwxrwxrwx 1 root root 93 Aug 31 15:47 wallet.txt -> /opt/chainlock/dfs/9c14786eb41fd5edd2f834dbb0f39b57a95081d6f64ad07052270e5f67b6b765/protected

That takes care of protecting the file at rest, but locked files aren’t very helpful when you’re trying to use them. We need a way to decrypt the file but still only allow a single application to access it. Enter fanotify. Fanotify lets us insert ourselves between an application and a file. When the application requests to read that file, we get to decide whether or not the request is allowed.

We can use the CLI tool to unlock the file. Note that we don’t need to specify anything other than that we are unlocking a file. In the background, a tor instance and hidden service is launched. Then QR code pops up, which contains information on how to reach the hidden service such as it’s onion address and the public key that can be used to submit information. With the companion app we can select the file we want to unlock, then scan the QR code. The app will send the information necessary to unlock the file to the hidden service.

$ chainlock -u
Please open the Chainlock Android app, select the file you wish 
to unlock, and scan the QR code. You may need to scan a few times.
You may now close the QR code popup.
Reading Password from stdin
Decrypting master key
$ The option "-allow_other" is set. Make sure the file permissions protect your data from unwanted access.
Filesystem mounted and ready.

ChainLock now starts a daemon to watch over the file and only allow access from the allowed binary, and then decrypts the file so it can be used. Now the wallet can only be used with the specified application. Nothing else works!

$ cat wallet.txt 
Test Wallet.
$ tac wallet.txt 
tac: failed to open 'wallet.txt' for reading: Operation not permitted
$ sudo su
# cat wallet.txt 
Test Wallet.
# tac wallet.txt 
tac: failed to open 'wallet.txt' for reading: Operation not permitted
# exit
exit
$

“But,” you ask, “what if the authorized binary changes or upgrades?” Not a problem. Simply select the file in the companion app, run the upgrade CLI command with the path to the upgraded or new binary, and scan the QR code. Now when you unlock the file you selected your phone will tell ChainLock to allow the new binary.

$ chainlock -p /usr/bin/less
$ chainlock -u
Please open the Chainlock Android app, select the file you wish 
to unlock, and scan the QR code. You may need to scan a few times.
You may now close the QR code popup.
Reading Password from stdin
Decrypting master key
The option "-allow_other" is set. Make sure the file permissions protect your data from unwanted access.
Filesystem mounted and ready.
$ cat wallet.txt 
cat: wallet.txt: Operation not permitted
$ tac wallet.txt 
tac: failed to open 'wallet.txt' for reading: Operation not permitted
$ less wallet.txt 
Test Wallet.
wallet.txt (END)
$ 

Can you show me?

Don’t take my word for it, here’s a video: