key-manager Script Implementation
CommunityEnterpriseBelow are examples of the protocol used by the key-manager.py script,
if you want to write your own Key Manager.
These details can be seen when increasing the debug level of the Storage Daemon to 200
or enabling the debug on the key-manager.py script with option -d.
$ OPERATION=LABEL VOLUME_NAME=Volume0001 ./key-manager.py getkey --cipher AES_128_XTS --key-dir /opt/bacula/keys
cipher: AES_128_XTS
cipher_key: G6HksAYDnNGr67AAx2Lb/vecTVjZoYAqSLZ7lGMyDVE=
volume_name: Volume0001
$ OPERATION=READ VOLUME_NAME=Volume0001 ./key-manager.py getkey --cipher AES_128_XTS --key-dir /opt/bacula/keys
cipher: AES_128_XTS
cipher_key: G6HksAYDnNGr67AAx2Lb/vecTVjZoYAqSLZ7lGMyDVE=
volume_name: Volume0001
$ cat /opt/bacula/etc/keydir/Volume0001
cipher: AES_128_XTS
cipher_key: G6HksAYDnNGr67AAx2Lb/vecTVjZoYAqSLZ7lGMyDVE=
volume_name: Volume0001
$ OPERATION=READ VOLUME_NAME=DontExist ./key-manager.py getkey --cipher AES_128_XTS --key-dir /opt/bacula/keys 2>/dev/null
error: no cipher key nor encrypted cipher key for volume "DontExist"
$ echo $?
0
$ OPERATION=BAD_CMD VOLUME_NAME=Volume0002 ./key-manager.py getkey --cipher AES_128_XTS --key-dir /opt/bacula/keys 2>/dev/null
error: environment variable OPERATION invalid "BAD_CMD" for volume "Volume0002"
$ echo $?
0
In the commands above, notice that the keys are stored in a single directory
- /opt/bacula/keys - by using the --key-dir option to modify
the default value /opt/bacula/etc/keydir. Arguments are conveyed through
the use of environment variables and the output is written to STDOUT.
Master Key Protocol
When using a Master Key, the protocol is slightly different. In the examples below, calls to the script have been removed to highlight only the input and output structures.
< OPERATION=LABEL
< VOLUME_NAME=TestVolume001
> volume_name: TestVolume001
> cipher: AES_128_XTS
> cipher_key: TdxS7l/6rL3XEE29Mx2kngZcojFQbJFh7sjMEWbPMgE=
> master_keyid: OTg1NTBBMTRENzk2RjAwNDNEQjZFRTg5NjQ1ODgxN0RBRjQ2QzRBNg==
> enc_cipher_key: hQEMA21+h/2GRPB5AQgAyqs31NNV+ej5NnviqRo51yvASV46YUHeViOFizZe2K/MR9jxwpAiv9HsEFsRxp3XTj1E4Lhyp8kY9FQw4xdDtxO1h5ak5rRWagW+ErdMg2Y6pJWGynjCakDmHSe/YA7wFUV2m26UC9FSQN38UmOSJf6HMDpkWaJZpenNGx7FbBjg8ffhXl6c0/91g0fZHI1jsvIpYdd787YFaxH8q2R6Eu6NRdQ0+NqhSw8TEGj6OMwQHW8MfnKfS37E/s/KNF2HdoZEKjkPaMUn+HwVuaBYBu+cw4bmlowMjsL4ZUvFRK5Zh4vQVOsMxHSuThO7miotJe12nJOFMm+yCZzw6rn57dRoAQkCENuIAUjUcGYQBZM/F/VSEIrND6LY9Nh/xcksd7IMV9B/4X9R2LNw5Z4aSCSj4eLTjeYO06/d0FOV6z1dhAwvRaz3EQPaQ6MPQ9MjhPnrbypQw7y42+dfSJTENoiDDqOa38ay6jo=
< OPERATION=READ
< VOLUME_NAME=TestVolume001
< ENC_CIPHER_KEY=hQEMA21+h/2GRPB5AQgAyqs31NNV+ej5NnviqRo51yvASV46YUHeViOFizZe2K/MR9jxwpAiv9HsEFsRxp3XTj1E4Lhyp8kY9FQw4xdDtxO1h5ak5rRWagW+ErdMg2Y6pJWGynjCakDmHSe/YA7wFUV2m26UC9FSQN38UmOSJf6HMDpkWaJZpenNGx7FbBjg8ffhXl6c0/91g0fZHI1jsvIpYdd787YFaxH8q2R6Eu6NRdQ0+NqhSw8TEGj6OMwQHW8MfnKfS37E/s/KNF2HdoZEKjkPaMUn+HwVuaBYBu+cw4bmlowMjsL4ZUvFRK5Zh4vQVOsMxHSuThO7miotJe12nJOFMm+yCZzw6rn57dRoAQkCENuIAUjUcGYQBZM/F/VSEIrND6LY9Nh/xcksd7IMV9B/4X9R2LNw5Z4aSCSj4eLTjeYO06/d0FOV6z1dhAwvRaz3EQPaQ6MPQ9MjhPnrbypQw7y42+dfSJTENoiDDqOa38ay6jo=
< MASTER_KEYID=OTg1NTBBMTRENzk2RjAwNDNEQjZFRTg5NjQ1ODgxN0RBRjQ2QzRBNg==
> volume_name: TestVolume001
> cipher: AES_128_XTS
> cipher_key: TdxS7l/6rL3XEE29Mx2kngZcojFQbJFh7sjMEWbPMgE=
When the script requests the user to introduce the passphrase:
< OPERATION=READ
< VOLUME_NAME=TestVolume001
< ENC_CIPHER_KEY=hQEMA21+h/2GRPB5AQgAg2XAvs5JpvZrICXGVhO57pGSbDtz4XiNOygxjk44G+p+nSHYzRTC21XjjO5E86yZHS3QxtlMt9C5jGDMOHYkWrez810q8xnXCtWWzirigrpfwW6QR+EnxFNLnM2mUNk3fjMyotfa/oN47ZeRcFAwLRjShHkHLz/m9DhDqQ5GJXC73fmrN+92vHsAKsvfnQ3esSxRF5uqTlh/bpvaqoZpd1VY6DJp0RmInDTpH52elTYiOlrWtxHvLB92UNR0GRRGCOTkCIAz+YN5rJ7jPMMehWJZmDgb5L8bMGdasB01PM6uGWe+jWpaqYz2mm+NMGRuBaroCWwkdPngWp8aXlZXsNRoAQkCEOuei1kDUuTEIJM2vlUMj1ffWgivHvEbn9t6CQoXUALvFxcsn9WxiJOKaXZNp9EyZlT1yy/Ep2Ieu3xWKUQvirpJGXXKnoT/k8KOFlTcs50HSRqImRHo7xDj9/yjrHz+NHLTMqE=
< MASTER_KEYID=OTg1NTBBMTRENzk2RjAwNDNEQjZFRTg5NjQ1ODgxN0RBRjQ2QzRBNg==
> volume_name: TestVolume001
> need_passphrase: 6D7E87FD8644F079 Bacula <bacula@localhost> 6D7E87FD8644F079 6458817DAF46C4A6 1 0
> key_grip: 03FB203FC97003A4D7BA540E32F9714E6775422E
Environment Variables
Bacula passes the following variables via the environment:
OPERATION This is set to LABEL when the Volume is being labeled. In this case the script is expected to generate a new key. Alternatively, it may be set to READ when the Volume already has a label, necessitating the Storage Daemon to use the existing key to read or append data to the Volume.
VOLUME_NAME This is the name of the Volume.
ENC_CIPHER_KEY When the volume holds master key information, this is the encrypted version of the cipher key that is base64-encoded.
MASTER_KEYID When the volume holds master key information, this is the ID of the master Master Key that was used to encrypt CIPHER_KEY into ENC_CIPHER_KEY. The MASTER_KEYID is also the name of a section in
key-manager.conffile. The value is base64 encoded.
Both the MASTER_KEYID and the ENC_CIPHER_KEY are store unencoded in the Volume.
Expected Output Fields
Bacula expects the following fields in the response:
volume_name This is a repetition of the name of the Volume that is given to the script. This field is optional and ignored by Bacula.
cipher This is the cipher that Bacula must use. Bacula knows the following ciphers: AES_128_XTS and AES_256_XTS. The key lengths will vary based on the cipher selected.
cipher_key This is a symmetric key in base64 format.
enc_cipher_key When a Master Key is used, this is an encrypted version of the cipher_key that the Volume must hold in the Label.
master_keyid When a Master Key is used, this is the Id of the Master Key that has been used to encrypt cipher_key into
enc_cipher_key.comment This is a single line of text that is optional and ignored by Bacula.
error This is a single line error message. This is optional, but when provided, Bacula considers that the script returned an error and displays this error in the job log.
Script Exit Codes
Bacula expects an exit code of 0. Should the script terminate with any other error code, all output will be disregarded and Bacula will log a generic message along with the exit code.
To signal an error to Bacula, the script must use the error field and return an error code of 0.
See also
Previous articles:
Next articles:
Go back to: key-manager Script and Using Master Key.