forked from third-party-mirrors/zfs_autobackup
working on encryption
This commit is contained in:
parent
190a73ec10
commit
7696d8c16d
15
README.md
15
README.md
@ -370,6 +370,21 @@ zfs-autobackup will re-evaluate this on every run: As soon as a snapshot doesn't
|
||||
|
||||
Snapshots on the source that still have to be send to the target wont be destroyed off course. (If the target still wants them, according to the target schedule)
|
||||
|
||||
## How zfs-autobackup handles encryption
|
||||
|
||||
In normal operation datasets are transferred unaltered:
|
||||
|
||||
* Source datasets that are encrypted will be send over as such and stay encrypted at the target side. (In ZFS this is called raw-mode) You dont need keys at the target side if you dont want to access the data.
|
||||
* Source datasets that are plain will stay that way on the target. Even if the specified target-path IS encrypted.
|
||||
|
||||
### Decrypting/encrypting
|
||||
|
||||
If you want to alter the encryption-state of a dataset you have several options:
|
||||
|
||||
* If you want to decrypt encrypted datasets before sending them, you should use the `--decrypt` option. Datasets will then be stored plain at the target.
|
||||
* If you want to encrypt plain datasets when they are received, you should use the `--encrypt` option. Datasets will then be stored encrypted at the target. (Datasets that are already encrypted will still be sent over unaltered!) You are responsible for creating the target-path with encryption enabled.
|
||||
* If you also want re-encrypt encrypted datasets with the target-side encryption you can use both options.
|
||||
|
||||
## Tips
|
||||
|
||||
* Use ```--debug``` if something goes wrong and you want to see the commands that are executed. This will also stop at the first error.
|
||||
|
@ -1,8 +1,116 @@
|
||||
import unittest
|
||||
from zfs_autobackup.CmdPipe import CmdPipe
|
||||
from basetest import *
|
||||
import time
|
||||
|
||||
class MyTestCase(unittest.TestCase):
|
||||
def test_something(self):
|
||||
self.assertEqual(True, False)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
class TestZfsEncryption(unittest2.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
prepare_zpools()
|
||||
|
||||
def prepare_encrypted_dataset(self, key, path, unload_key=False):
|
||||
|
||||
# create encrypted source dataset
|
||||
shelltest("echo {} > /tmp/zfstest.key".format(key))
|
||||
shelltest("zfs create -o keylocation=file:///tmp/zfstest.key -o keyformat=passphrase -o encryption=on {}".format(path))
|
||||
|
||||
if unload_key:
|
||||
shelltest("zfs unmount {}".format(path))
|
||||
shelltest("zfs unload-key {}".format(path))
|
||||
|
||||
# r=shelltest("dd if=/dev/zero of=/test_source1/fs1/enc1/data.txt bs=200000 count=1")
|
||||
|
||||
def test_raw(self):
|
||||
"""send encrypted data unaltered (standard operation)"""
|
||||
|
||||
self.prepare_encrypted_dataset("11111111", "test_source1/fs1/encryptedsource")
|
||||
self.prepare_encrypted_dataset("11111111", "test_source1/fs1/encryptedsourcekeyless", unload_key=True) # raw mode shouldn't need a key
|
||||
self.prepare_encrypted_dataset("22222222", "test_target1/encryptedtarget")
|
||||
|
||||
with patch('time.strftime', return_value="20101111000000"):
|
||||
self.assertFalse(ZfsAutobackup("test test_target1 --verbose --no-progress --allow-empty".split(" ")).run())
|
||||
self.assertFalse(ZfsAutobackup("test test_target1/encryptedtarget --verbose --no-progress --no-snapshot".split(" ")).run())
|
||||
|
||||
with patch('time.strftime', return_value="20101111000001"):
|
||||
self.assertFalse(ZfsAutobackup("test test_target1 --verbose --no-progress --allow-empty".split(" ")).run())
|
||||
self.assertFalse(ZfsAutobackup("test test_target1/encryptedtarget --verbose --no-progress --no-snapshot".split(" ")).run())
|
||||
|
||||
r = shelltest("zfs get -r -t filesystem encryptionroot test_target1")
|
||||
self.assertMultiLineEqual(r,"""
|
||||
NAME PROPERTY VALUE SOURCE
|
||||
test_target1 encryptionroot - -
|
||||
test_target1/encryptedtarget encryptionroot test_target1/encryptedtarget -
|
||||
test_target1/encryptedtarget/test_source1 encryptionroot test_target1/encryptedtarget -
|
||||
test_target1/encryptedtarget/test_source1/fs1 encryptionroot - -
|
||||
test_target1/encryptedtarget/test_source1/fs1/encryptedsource encryptionroot test_target1/encryptedtarget/test_source1/fs1/encryptedsource -
|
||||
test_target1/encryptedtarget/test_source1/fs1/encryptedsourcekeyless encryptionroot test_target1/encryptedtarget/test_source1/fs1/encryptedsourcekeyless -
|
||||
test_target1/encryptedtarget/test_source1/fs1/sub encryptionroot - -
|
||||
test_target1/encryptedtarget/test_source2 encryptionroot test_target1/encryptedtarget -
|
||||
test_target1/encryptedtarget/test_source2/fs2 encryptionroot test_target1/encryptedtarget -
|
||||
test_target1/encryptedtarget/test_source2/fs2/sub encryptionroot - -
|
||||
test_target1/test_source1 encryptionroot - -
|
||||
test_target1/test_source1/fs1 encryptionroot - -
|
||||
test_target1/test_source1/fs1/encryptedsource encryptionroot test_target1/test_source1/fs1/encryptedsource -
|
||||
test_target1/test_source1/fs1/encryptedsourcekeyless encryptionroot test_target1/test_source1/fs1/encryptedsourcekeyless -
|
||||
test_target1/test_source1/fs1/sub encryptionroot - -
|
||||
test_target1/test_source2 encryptionroot - -
|
||||
test_target1/test_source2/fs2 encryptionroot - -
|
||||
test_target1/test_source2/fs2/sub encryptionroot - -
|
||||
""")
|
||||
|
||||
def test_decrypt(self):
|
||||
"""decrypt data and store unencrypted (--decrypt)"""
|
||||
|
||||
self.prepare_encrypted_dataset("11111111", "test_source1/fs1/encryptedsource")
|
||||
self.prepare_encrypted_dataset("22222222", "test_target1/encryptedtarget")
|
||||
|
||||
with patch('time.strftime', return_value="20101111000000"):
|
||||
self.assertFalse(ZfsAutobackup("test test_target1 --verbose --no-progress --decrypt".split(" ")).run())
|
||||
self.assertFalse(ZfsAutobackup("test test_target1/encryptedtarget --verbose --no-progress --decrypt".split(" ")).run())
|
||||
|
||||
r = shelltest("zfs get -r -t filesystem encryptionroot test_target1")
|
||||
self.assertEqual(r, """
|
||||
NAME PROPERTY VALUE SOURCE
|
||||
test_target1 encryptionroot - -
|
||||
test_target1/encryptedtarget encryptionroot test_target1/encryptedtarget -
|
||||
test_target1/encryptedtarget/test_source1 encryptionroot test_target1/encryptedtarget -
|
||||
test_target1/encryptedtarget/test_source1/fs1 encryptionroot - -
|
||||
test_target1/encryptedtarget/test_source1/fs1/encryptedsource encryptionroot - -
|
||||
test_target1/encryptedtarget/test_source1/fs1/sub encryptionroot - -
|
||||
test_target1/encryptedtarget/test_source2 encryptionroot test_target1/encryptedtarget -
|
||||
test_target1/encryptedtarget/test_source2/fs2 encryptionroot test_target1/encryptedtarget -
|
||||
test_target1/encryptedtarget/test_source2/fs2/sub encryptionroot - -
|
||||
test_target1/test_source1 encryptionroot - -
|
||||
test_target1/test_source1/fs1 encryptionroot - -
|
||||
test_target1/test_source1/fs1/encryptedsource encryptionroot - -
|
||||
test_target1/test_source1/fs1/sub encryptionroot - -
|
||||
test_target1/test_source2 encryptionroot - -
|
||||
test_target1/test_source2/fs2 encryptionroot - -
|
||||
test_target1/test_source2/fs2/sub encryptionroot - -
|
||||
""")
|
||||
|
||||
def test_encrypt(self):
|
||||
"""send normal data set and store encrypted on the other side (--encrypt) issue #60 """
|
||||
|
||||
self.prepare_encrypted_dataset("11111111", "test_source1/fs1/encryptedsource")
|
||||
self.prepare_encrypted_dataset("22222222", "test_target1/encryptedtarget")
|
||||
|
||||
with patch('time.strftime', return_value="20101111000000"):
|
||||
self.assertFalse(ZfsAutobackup("test test_target1 --verbose --no-progress --encrypt".split(" ")).run())
|
||||
self.assertFalse(ZfsAutobackup("test test_target1/encryptedtarget --verbose --no-progress --encrypt".split(" ")).run())
|
||||
|
||||
r = shelltest("zfs get encryption -H -o value test_target1/test_source1/fs1/encryptedsource test_target1/encryptedtarget/test_source1/fs1/encryptedsource")
|
||||
self.assertNotIn("off",r)
|
||||
|
||||
|
||||
def test_reencrypt(self):
|
||||
"""decrypt data and reencrypt on the otherside (--decrypt --encrypt) """
|
||||
|
||||
# create encrypted target dataset
|
||||
shelltest("echo 12345678 > /tmp/zfstest.key")
|
||||
shelltest("zfs create -o keylocation=file:///tmp/zfstest.key -o keyformat=passphrase -o encryption=on test_target1/enc1")
|
||||
|
||||
with patch('time.strftime', return_value="20101111000000"):
|
||||
self.assertFalse(ZfsAutobackup("test test_target1/enc1 --allow-empty --verbose --no-progress".split(" ")).run())
|
||||
r = shelltest("zfs get encryption -H -o value test_target1/enc1/test_source1/fs1")
|
||||
self.assertNotIn("off",r)
|
||||
|
@ -880,35 +880,6 @@ test_target1/test_source2/fs2/sub
|
||||
test_target1/test_source2/fs2/sub@test-20101111000003
|
||||
""")
|
||||
|
||||
###########################
|
||||
# TODO:
|
||||
|
||||
def test_encrypted(self):
|
||||
|
||||
# create encrypted dataset
|
||||
shelltest("echo 12345678 > /tmp/zfstest.key")
|
||||
shelltest("zfs create -o keylocation=file:///tmp/zfstest.key -o keyformat=passphrase -o encryption=on test_source1/fs1/enc1")
|
||||
r=shelltest("dd if=/dev/zero of=/test_source1/fs1/enc1/data.txt bs=200000 count=1")
|
||||
|
||||
with patch('time.strftime', return_value="20101111000000"):
|
||||
self.assertFalse(ZfsAutobackup("test test_target1 --allow-empty --verbose --no-progress".split(" ")).run())
|
||||
# self.skipTest("todo: later when travis supports zfs 0.8")
|
||||
r = shelltest("zfs get encryption -H -o value test_target1/test_source1/fs1/enc1")
|
||||
self.assertNotIn("off",r)
|
||||
|
||||
def test_decrypted(self):
|
||||
|
||||
# create encrypted dataset
|
||||
shelltest("echo 12345678 > /tmp/zfstest.key")
|
||||
shelltest("zfs create -o keylocation=file:///tmp/zfstest.key -o keyformat=passphrase -o encryption=on test_source1/fs1/enc1")
|
||||
r=shelltest("dd if=/dev/zero of=/test_source1/fs1/enc1/data.txt bs=200000 count=1")
|
||||
|
||||
with patch('time.strftime', return_value="20101111000000"):
|
||||
self.assertFalse(ZfsAutobackup("test test_target1 --decrypt --allow-empty --no-progress".split(" ")).run())
|
||||
# self.skipTest("todo: later when travis supports zfs 0.8")
|
||||
r = shelltest("zfs get encryption -H -o value test_target1/test_source1/fs1/enc1")
|
||||
self.assertIn("off",r)
|
||||
|
||||
|
||||
def test_progress(self):
|
||||
|
||||
|
@ -93,7 +93,10 @@ class ZfsAutobackup:
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument('--decrypt', action='store_true',
|
||||
help='Decrypt data before sending it over')
|
||||
help='Decrypt data before sending it over.')
|
||||
|
||||
parser.add_argument('--encrypt', action='store_true',
|
||||
help='Encrypt data after receiving it.')
|
||||
|
||||
parser.add_argument('--test', action='store_true',
|
||||
help='dont change anything, just show what would be done (still does all read-only '
|
||||
|
Loading…
x
Reference in New Issue
Block a user