From 1b5963c15555b8286b90722148d5af26f13dcb03 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Mon, 25 Nov 2019 21:05:24 -0500 Subject: [PATCH 01/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index fab0502..dbfdd23 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -33,15 +33,33 @@ def request(resource, method='GET', data=None): return {'ok': r.ok, 'status_code': r.status_code, 'response': r.text} raise ValueError(r) -POOLS = request('storage/volume/', 'GET') -for pool in POOLS['response']: - if pool['is_decrypted'] == False: - logging.info('Pool {} is locked'.format(pool['name'])) - response = request('storage/volume/{}/unlock/'.format(pool['name']), 'POST', {'passphrase': '{}'.format(config.ENCRYPTION_PASSPHRASES[pool['name']])}) - if response['ok']: - logging.info('Pool {} was unlocked successfully'.format(pool['name'])) +#if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Unlock FreeNAS Pools') + group = parser.add_mutually_exclusive_group() + group.add_argument('-s', '--server', action='store_true', help='server (Usually runs on another system where passwords are stored)') + group.add_argument('-c', '--client', action='store_true', help='client (Usually runs on the FreeNAS server)') + parser.add_argument('-ip', '--host', type=str, help='Hostname/IP of the host running the unlock script (Required for client)') + parser.add_argument('-f', '--filePath', type=str, help='Absolute path to the script on the host (Required for client)') + args = parser.parse_args() + if args.client and (args.host is None or args.filePath is None): + parser.error("--client requires --host and --filePath.") + + +if args.server or True: + POOLS = request('storage/volume/', 'GET') + for pool in POOLS['response']: + if pool['is_decrypted'] == False: + logging.info('Pool {} is locked'.format(pool['name'])) + response = request('storage/volume/{}/unlock/'.format(pool['name']), 'POST', {'passphrase': '{}'.format(config.ENCRYPTION_PASSPHRASES[pool['name']])}) + if response['ok']: + logging.info('Pool {} was unlocked successfully'.format(pool['name'])) + else: + logging.error('Pool {} was NOT unlocked successfully'.format(pool['name'])) else: - logging.error('Pool {} was NOT unlocked successfully'.format(pool['name'])) - else: - logging.debug('Pool {} is already unlocked'.format(pool['name'])) \ No newline at end of file + logging.debug('Pool {} is already unlocked'.format(pool['name'])) +elif args.client and False: + host = args.host + filePath = args.filePath +else: + print(parser.print_help()) \ No newline at end of file -- 2.39.5 From 89c9043423fb1da2448c91192f0a9dd8b82a21c0 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 11:32:33 -0500 Subject: [PATCH 02/30] Update 'config.py' --- config.py | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/config.py b/config.py index cf4cf08..33d1caf 100644 --- a/config.py +++ b/config.py @@ -1,23 +1,11 @@ #!/usr/bin/env python -# Descriptive name for the host -HOST_SHORTNAME = 'freenas' -# FQDN for the host, can use IP too -HOSTNAME = 'freenas.local' +# FQDN for the host containing the luks volume with the recovery keys, can use IP too +KEY_HOST = 'pi.local' # Root password for the system, api is only able to use basic auth with the root account -ROOT_PASSWORD = 'my super secret password' -# path to the CA certificate to verify the ssl cert. If you don't wish to verify, make this False -CA_CERT_PATH = '/root/ca.crt' -# pool names and their encryption keys, the index is the pool name and the value is the encryption passphrase for the pool -# Ex: ENCRYPTION_PASSPHRASES = {'zroot': 'super secret password goes here'} this would be the zroot pool and password to unlock it -ENCRYPTION_PASSPHRASES = { - 'POOL_NAME': 'ENCRYPTION_PASSPHRASE', - 'POOL_NAME2': 'ENCRYPTION_PASSPHRASE2' -} - -# STMP Settings -SMTP_SERVER = 'smtp.gmail.com' -SMTP_PORT = 587 -SMTP_SSL = True -SMTP_FROM = 'admin@gmail.com' -SMTP_USERNAME = 'admin@gmail.com' -SMTP_PASSWORD = 'super secret password goes here' \ No newline at end of file +FREENAS_ROOT_PASSWORD = 'my super secret password' +# path to the CA certificate to verify the ssl cert on FreeNAS. If you don't wish to verify, make this False +CA_CERT_PATH = 'False' +# pool names, this makes things easy when looking for the keys in the Luks volume +POOL_NAMES = {'POOL_NAME','POOL_NAME2'} +# Luks encryption password +LUKS_PASSWORD = "" \ No newline at end of file -- 2.39.5 From 147ef3667e1db97142583c350b8d0d3d2b0a76eb Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 11:39:03 -0500 Subject: [PATCH 03/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 60 +++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index dbfdd23..2c2cc84 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -import requests, platform, subprocess, config, logging, simplejson as json, argparse +import requests, platform, subprocess, config, logging, simplejson as json, argparse, from subprocess import call # You must initialize logging, otherwise you'll not see debug output. logging.basicConfig(level=logging.INFO,format='%(asctime)s - [%(levelname)s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S') @@ -35,31 +35,37 @@ def request(resource, method='GET', data=None): #if __name__ == "__main__": - parser = argparse.ArgumentParser(description='Unlock FreeNAS Pools') - group = parser.add_mutually_exclusive_group() - group.add_argument('-s', '--server', action='store_true', help='server (Usually runs on another system where passwords are stored)') - group.add_argument('-c', '--client', action='store_true', help='client (Usually runs on the FreeNAS server)') - parser.add_argument('-ip', '--host', type=str, help='Hostname/IP of the host running the unlock script (Required for client)') - parser.add_argument('-f', '--filePath', type=str, help='Absolute path to the script on the host (Required for client)') - args = parser.parse_args() - if args.client and (args.host is None or args.filePath is None): - parser.error("--client requires --host and --filePath.") +# parser = argparse.ArgumentParser(description='Unlock FreeNAS Pools') +# group = parser.add_mutually_exclusive_group() +# group.add_argument('-s', '--server', action='store_true', help='server (Usually runs on another system where passwords are stored)') +# group.add_argument('-c', '--client', action='store_true', help='client (Usually runs on the FreeNAS server)') +# parser.add_argument('-ip', '--host', type=str, help='Hostname/IP of the host running the unlock script (Required for client)') +# parser.add_argument('-f', '--filePath', type=str, help='Absolute path to the script on the host (Required for client)') +# args = parser.parse_args() +# if args.client and (args.host is None or args.filePath is None): +# parser.error("--client requires --host and --filePath.") + + +#POOLS = request('storage/volume/', 'GET') +#for pool in POOLS['response']: +# if pool['is_decrypted'] == False: +# logging.info('Pool {} is locked'.format(pool['name'])) +# response = request('storage/volume/{}/unlock/'.format(pool['name']), 'POST', {'passphrase': '{}'.format(config.ENCRYPTION_PASSPHRASES[pool['name']])}) +# if response['ok']: +# logging.info('Pool {} was unlocked successfully'.format(pool['name'])) +# else: +# logging.error('Pool {} was NOT unlocked successfully'.format(pool['name'])) +# else: +# logging.debug('Pool {} is already unlocked'.format(pool['name'])) + + + +# Create a small ramdrive to store our recovery keys temporarily +rc = call("mkdir /mnt/ramfs", shell=True) +rc = call("mdmfs -s 1m md /mnt/ramfs", shell=True) + +# Send our unlock/mount script to the pi and execute it on the pi using ssh +rc = call("ssh root@ 'bash -s'", shell=True) + -if args.server or True: - POOLS = request('storage/volume/', 'GET') - for pool in POOLS['response']: - if pool['is_decrypted'] == False: - logging.info('Pool {} is locked'.format(pool['name'])) - response = request('storage/volume/{}/unlock/'.format(pool['name']), 'POST', {'passphrase': '{}'.format(config.ENCRYPTION_PASSPHRASES[pool['name']])}) - if response['ok']: - logging.info('Pool {} was unlocked successfully'.format(pool['name'])) - else: - logging.error('Pool {} was NOT unlocked successfully'.format(pool['name'])) - else: - logging.debug('Pool {} is already unlocked'.format(pool['name'])) -elif args.client and False: - host = args.host - filePath = args.filePath -else: - print(parser.print_help()) \ No newline at end of file -- 2.39.5 From ce7d1934c510f71a8726b65916ec5dabfa98c8bc Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 11:39:29 -0500 Subject: [PATCH 04/30] Update 'config.py' --- config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/config.py b/config.py index 33d1caf..1c01adb 100644 --- a/config.py +++ b/config.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # FQDN for the host containing the luks volume with the recovery keys, can use IP too KEY_HOST = 'pi.local' +KEY_HOST_USER = 'root' # Root password for the system, api is only able to use basic auth with the root account FREENAS_ROOT_PASSWORD = 'my super secret password' # path to the CA certificate to verify the ssl cert on FreeNAS. If you don't wish to verify, make this False -- 2.39.5 From d0093d798e0507516afaed23e23c0c105c33175b Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 11:42:56 -0500 Subject: [PATCH 05/30] Update 'config.py' --- config.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config.py b/config.py index 1c01adb..454e090 100644 --- a/config.py +++ b/config.py @@ -1,7 +1,10 @@ #!/usr/bin/env python # FQDN for the host containing the luks volume with the recovery keys, can use IP too KEY_HOST = 'pi.local' +# Username to use to login to the key host KEY_HOST_USER = 'root' +# Location of the luks volume file +LUKS_VOLUME = '/root/secure.luks' # Root password for the system, api is only able to use basic auth with the root account FREENAS_ROOT_PASSWORD = 'my super secret password' # path to the CA certificate to verify the ssl cert on FreeNAS. If you don't wish to verify, make this False -- 2.39.5 From 4cf0acbdda2a453eb26c0524c71a9cc0edb6ef9b Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 11:43:46 -0500 Subject: [PATCH 06/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index 2c2cc84..07426af 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -65,7 +65,7 @@ rc = call("mkdir /mnt/ramfs", shell=True) rc = call("mdmfs -s 1m md /mnt/ramfs", shell=True) # Send our unlock/mount script to the pi and execute it on the pi using ssh -rc = call("ssh root@ 'bash -s'", shell=True) +rc = call("ssh config.KEY_HOST_USER@config.KEY_HOST_USER 'echo -n config.LUKS_PASSWORD | cryptsetup luksOpen config.LUKS_VOLUME FreeNASRecoveryKeys -d - && mount /dev/mapper/FreeNASRecoveryKeys /mnt/FreeNASRecoveryKeys'", shell=True) -- 2.39.5 From d3502d345e159230918b37e27639cf7a10dc6579 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 11:44:37 -0500 Subject: [PATCH 07/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index 07426af..3c8aac5 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -1,5 +1,6 @@ #!/usr/bin/env python -import requests, platform, subprocess, config, logging, simplejson as json, argparse, from subprocess import call +import requests, platform, subprocess, config, logging, simplejson as json, argparse +from subprocess import call # You must initialize logging, otherwise you'll not see debug output. logging.basicConfig(level=logging.INFO,format='%(asctime)s - [%(levelname)s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S') -- 2.39.5 From 09f00dc8dd3a09f84fe5550aa91945a618073aeb Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 11:45:15 -0500 Subject: [PATCH 08/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index 3c8aac5..416bcb8 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -66,7 +66,7 @@ rc = call("mkdir /mnt/ramfs", shell=True) rc = call("mdmfs -s 1m md /mnt/ramfs", shell=True) # Send our unlock/mount script to the pi and execute it on the pi using ssh -rc = call("ssh config.KEY_HOST_USER@config.KEY_HOST_USER 'echo -n config.LUKS_PASSWORD | cryptsetup luksOpen config.LUKS_VOLUME FreeNASRecoveryKeys -d - && mount /dev/mapper/FreeNASRecoveryKeys /mnt/FreeNASRecoveryKeys'", shell=True) +rc = call("ssh config.KEY_HOST_USER@config.KEY_HOST 'echo -n config.LUKS_PASSWORD | cryptsetup luksOpen config.LUKS_VOLUME FreeNASRecoveryKeys -d - && mount /dev/mapper/FreeNASRecoveryKeys /mnt/FreeNASRecoveryKeys'", shell=True) -- 2.39.5 From 4cdc7dcdc58fed0162552ca2d9ce489f98ebcaf9 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 11:47:18 -0500 Subject: [PATCH 09/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index 416bcb8..85b6021 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -66,7 +66,7 @@ rc = call("mkdir /mnt/ramfs", shell=True) rc = call("mdmfs -s 1m md /mnt/ramfs", shell=True) # Send our unlock/mount script to the pi and execute it on the pi using ssh -rc = call("ssh config.KEY_HOST_USER@config.KEY_HOST 'echo -n config.LUKS_PASSWORD | cryptsetup luksOpen config.LUKS_VOLUME FreeNASRecoveryKeys -d - && mount /dev/mapper/FreeNASRecoveryKeys /mnt/FreeNASRecoveryKeys'", shell=True) +rc = call("ssh {}@{} 'echo -n {} | cryptsetup luksOpen {} FreeNASRecoveryKeys -d - && mount /dev/mapper/FreeNASRecoveryKeys /mnt/FreeNASRecoveryKeys'".format(config.KEY_HOST_USER, config.KEY_HOST, config.LUKS_PASSWORD, config.LUKS_VOLUME), shell=True) -- 2.39.5 From d1d7a3c91ca3502fd329f3302db2d5544da5ac19 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 11:48:03 -0500 Subject: [PATCH 10/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index 85b6021..593ef56 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -66,7 +66,7 @@ rc = call("mkdir /mnt/ramfs", shell=True) rc = call("mdmfs -s 1m md /mnt/ramfs", shell=True) # Send our unlock/mount script to the pi and execute it on the pi using ssh -rc = call("ssh {}@{} 'echo -n {} | cryptsetup luksOpen {} FreeNASRecoveryKeys -d - && mount /dev/mapper/FreeNASRecoveryKeys /mnt/FreeNASRecoveryKeys'".format(config.KEY_HOST_USER, config.KEY_HOST, config.LUKS_PASSWORD, config.LUKS_VOLUME), shell=True) +rc = call("ssh {}@{} 'mkdir /mnt/FreeNASRecoveryKeys && echo -n {} | cryptsetup luksOpen {} FreeNASRecoveryKeys -d - && mount /dev/mapper/FreeNASRecoveryKeys /mnt/FreeNASRecoveryKeys'".format(config.KEY_HOST_USER, config.KEY_HOST, config.LUKS_PASSWORD, config.LUKS_VOLUME), shell=True) -- 2.39.5 From 9d32d02a785acde6fe8eadc54731e0236285cf52 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 11:52:28 -0500 Subject: [PATCH 11/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index 593ef56..1aa4503 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -66,7 +66,7 @@ rc = call("mkdir /mnt/ramfs", shell=True) rc = call("mdmfs -s 1m md /mnt/ramfs", shell=True) # Send our unlock/mount script to the pi and execute it on the pi using ssh -rc = call("ssh {}@{} 'mkdir /mnt/FreeNASRecoveryKeys && echo -n {} | cryptsetup luksOpen {} FreeNASRecoveryKeys -d - && mount /dev/mapper/FreeNASRecoveryKeys /mnt/FreeNASRecoveryKeys'".format(config.KEY_HOST_USER, config.KEY_HOST, config.LUKS_PASSWORD, config.LUKS_VOLUME), shell=True) +rc = call("ssh {}@{} 'mkdir /mnt/FreeNASRecoveryKeys; echo -n {} | cryptsetup luksOpen {} FreeNASRecoveryKeys -d - && mount /dev/mapper/FreeNASRecoveryKeys /mnt/FreeNASRecoveryKeys'".format(config.KEY_HOST_USER, config.KEY_HOST, config.LUKS_PASSWORD, config.LUKS_VOLUME), shell=True) -- 2.39.5 From a1e55758892f990b20c4c11cdf5cc5982289b5f7 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 11:54:11 -0500 Subject: [PATCH 12/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index 1aa4503..db9f410 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -66,7 +66,7 @@ rc = call("mkdir /mnt/ramfs", shell=True) rc = call("mdmfs -s 1m md /mnt/ramfs", shell=True) # Send our unlock/mount script to the pi and execute it on the pi using ssh -rc = call("ssh {}@{} 'mkdir /mnt/FreeNASRecoveryKeys; echo -n {} | cryptsetup luksOpen {} FreeNASRecoveryKeys -d - && mount /dev/mapper/FreeNASRecoveryKeys /mnt/FreeNASRecoveryKeys'".format(config.KEY_HOST_USER, config.KEY_HOST, config.LUKS_PASSWORD, config.LUKS_VOLUME), shell=True) +rc = call("ssh {}@{} 'mkdir /mnt/FreeNASRecoveryKeys; echo -n {} | cryptsetup luksOpen {} FreeNASRecoveryKeys -v -d - && mount /dev/mapper/FreeNASRecoveryKeys /mnt/FreeNASRecoveryKeys'".format(config.KEY_HOST_USER, config.KEY_HOST, config.LUKS_PASSWORD, config.LUKS_VOLUME), shell=True) -- 2.39.5 From c1b168817e7f5f995a0f4d43b5da8285ed737a58 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 11:56:06 -0500 Subject: [PATCH 13/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index db9f410..1aa4503 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -66,7 +66,7 @@ rc = call("mkdir /mnt/ramfs", shell=True) rc = call("mdmfs -s 1m md /mnt/ramfs", shell=True) # Send our unlock/mount script to the pi and execute it on the pi using ssh -rc = call("ssh {}@{} 'mkdir /mnt/FreeNASRecoveryKeys; echo -n {} | cryptsetup luksOpen {} FreeNASRecoveryKeys -v -d - && mount /dev/mapper/FreeNASRecoveryKeys /mnt/FreeNASRecoveryKeys'".format(config.KEY_HOST_USER, config.KEY_HOST, config.LUKS_PASSWORD, config.LUKS_VOLUME), shell=True) +rc = call("ssh {}@{} 'mkdir /mnt/FreeNASRecoveryKeys; echo -n {} | cryptsetup luksOpen {} FreeNASRecoveryKeys -d - && mount /dev/mapper/FreeNASRecoveryKeys /mnt/FreeNASRecoveryKeys'".format(config.KEY_HOST_USER, config.KEY_HOST, config.LUKS_PASSWORD, config.LUKS_VOLUME), shell=True) -- 2.39.5 From c5029006068f5bae0ed716e430317d80da74ee56 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 12:03:19 -0500 Subject: [PATCH 14/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index 1aa4503..d5e96a5 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -68,5 +68,12 @@ rc = call("mdmfs -s 1m md /mnt/ramfs", shell=True) # Send our unlock/mount script to the pi and execute it on the pi using ssh rc = call("ssh {}@{} 'mkdir /mnt/FreeNASRecoveryKeys; echo -n {} | cryptsetup luksOpen {} FreeNASRecoveryKeys -d - && mount /dev/mapper/FreeNASRecoveryKeys /mnt/FreeNASRecoveryKeys'".format(config.KEY_HOST_USER, config.KEY_HOST, config.LUKS_PASSWORD, config.LUKS_VOLUME), shell=True) +# Now we can copy the keys to the ramfs +for keyName in config.POOL_NAMES: + rc= call("scp {}@{}:/mnt/FreeNASRecoveryKeys/{}.recoveryKey /mnt/ramfs".format(config.KEY_HOST_USER, config.KEY_HOST, keyName), shell=True) + +# We can close the luks volume now +rc = call("ssh {}@{} 'umount /mnt/FreeNASRecoveryKeys; cryptsetup luksClose FreeNASRecoveryKeys'".format(config.KEY_HOST_USER, config.KEY_HOST), shell=True) + -- 2.39.5 From 922a72fb718002704d838baff97a0882ca25b885 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 12:08:59 -0500 Subject: [PATCH 15/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index d5e96a5..d09d646 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -import requests, platform, subprocess, config, logging, simplejson as json, argparse +import requests, platform, subprocess, config, logging, simplejson as json, argparse, base64 from subprocess import call # You must initialize logging, otherwise you'll not see debug output. @@ -69,11 +69,19 @@ rc = call("mdmfs -s 1m md /mnt/ramfs", shell=True) rc = call("ssh {}@{} 'mkdir /mnt/FreeNASRecoveryKeys; echo -n {} | cryptsetup luksOpen {} FreeNASRecoveryKeys -d - && mount /dev/mapper/FreeNASRecoveryKeys /mnt/FreeNASRecoveryKeys'".format(config.KEY_HOST_USER, config.KEY_HOST, config.LUKS_PASSWORD, config.LUKS_VOLUME), shell=True) # Now we can copy the keys to the ramfs -for keyName in config.POOL_NAMES: - rc= call("scp {}@{}:/mnt/FreeNASRecoveryKeys/{}.recoveryKey /mnt/ramfs".format(config.KEY_HOST_USER, config.KEY_HOST, keyName), shell=True) +for poolName in config.POOL_NAMES: + rc= call("scp {}@{}:/mnt/FreeNASRecoveryKeys/{}.recoveryKey /mnt/ramfs".format(config.KEY_HOST_USER, config.KEY_HOST, poolName), shell=True) # We can close the luks volume now rc = call("ssh {}@{} 'umount /mnt/FreeNASRecoveryKeys; cryptsetup luksClose FreeNASRecoveryKeys'".format(config.KEY_HOST_USER, config.KEY_HOST), shell=True) +for poolName in config.POOL_NAMES: + recovery_key = open('/mnt/ramfs/{}.recoveryKey'.format(poolName),'rb') + recovery_key_binary = recovery_key.read() + recovery_key_string = (base64.b64encode(recovery_key_binary)).decode('ascii') + response = request('storage/volume/{}/unlock/'.format(poolName), 'POST', {'recovery_key': '{}'.format(recovery_key_string)}) + + + -- 2.39.5 From ec45ec11d37c719935de145d034874c81d696ed4 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 12:10:43 -0500 Subject: [PATCH 16/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index d09d646..58e03fc 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -47,19 +47,6 @@ def request(resource, method='GET', data=None): # parser.error("--client requires --host and --filePath.") -#POOLS = request('storage/volume/', 'GET') -#for pool in POOLS['response']: -# if pool['is_decrypted'] == False: -# logging.info('Pool {} is locked'.format(pool['name'])) -# response = request('storage/volume/{}/unlock/'.format(pool['name']), 'POST', {'passphrase': '{}'.format(config.ENCRYPTION_PASSPHRASES[pool['name']])}) -# if response['ok']: -# logging.info('Pool {} was unlocked successfully'.format(pool['name'])) -# else: -# logging.error('Pool {} was NOT unlocked successfully'.format(pool['name'])) -# else: -# logging.debug('Pool {} is already unlocked'.format(pool['name'])) - - # Create a small ramdrive to store our recovery keys temporarily rc = call("mkdir /mnt/ramfs", shell=True) @@ -75,11 +62,20 @@ for poolName in config.POOL_NAMES: # We can close the luks volume now rc = call("ssh {}@{} 'umount /mnt/FreeNASRecoveryKeys; cryptsetup luksClose FreeNASRecoveryKeys'".format(config.KEY_HOST_USER, config.KEY_HOST), shell=True) -for poolName in config.POOL_NAMES: - recovery_key = open('/mnt/ramfs/{}.recoveryKey'.format(poolName),'rb') - recovery_key_binary = recovery_key.read() - recovery_key_string = (base64.b64encode(recovery_key_binary)).decode('ascii') - response = request('storage/volume/{}/unlock/'.format(poolName), 'POST', {'recovery_key': '{}'.format(recovery_key_string)}) +#Loop through the pools and only unlock the locked ones +POOLS = request('storage/volume/', 'GET') +for pool in POOLS['response']: + if pool['is_decrypted'] == False: + recovery_key = open('/mnt/ramfs/{}.recoveryKey'.format(pool['name']),'rb') + recovery_key_binary = recovery_key.read() + recovery_key_string = (base64.b64encode(recovery_key_binary)).decode('ascii') + response = request('storage/volume/{}/unlock/'.format(pool['name']), 'POST', {'recovery_key': '{}'.format(recovery_key_string)}) + if response['ok']: + logging.info('Pool {} was unlocked successfully'.format(pool['name'])) + else: + logging.error('Pool {} was NOT unlocked successfully'.format(pool['name'])) + else: + logging.debug('Pool {} is already unlocked'.format(pool['name'])) -- 2.39.5 From 161920785aca3227e5e97b1c58682684f6b06bc3 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 12:12:13 -0500 Subject: [PATCH 17/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index 58e03fc..f70a1f9 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -21,7 +21,7 @@ def request(resource, method='GET', data=None): url, data=json.dumps(data), headers={'Content-Type': "application/json"}, - auth=('root', '{}'.format(config.ROOT_PASSWORD)), + auth=('root', '{}'.format(config.FREENAS_ROOT_PASSWORD)), verify='{}'.format(config.CA_CERT_PATH) ) logging.debug('Request Status Code: {}'.format(r.status_code)) -- 2.39.5 From e0b5884028f5514c615127500df9bdeae4f01e58 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 12:12:54 -0500 Subject: [PATCH 18/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index f70a1f9..0aa55a2 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -66,10 +66,10 @@ rc = call("ssh {}@{} 'umount /mnt/FreeNASRecoveryKeys; cryptsetup luksClose Free POOLS = request('storage/volume/', 'GET') for pool in POOLS['response']: if pool['is_decrypted'] == False: - recovery_key = open('/mnt/ramfs/{}.recoveryKey'.format(pool['name']),'rb') + recovery_key = open('/mnt/ramfs/{}.recoveryKey'.format(pool['name']),'rb') recovery_key_binary = recovery_key.read() recovery_key_string = (base64.b64encode(recovery_key_binary)).decode('ascii') - response = request('storage/volume/{}/unlock/'.format(pool['name']), 'POST', {'recovery_key': '{}'.format(recovery_key_string)}) + response = request('storage/volume/{}/unlock/'.format(pool['name']), 'POST', {'recovery_key': '{}'.format(recovery_key_string)}) if response['ok']: logging.info('Pool {} was unlocked successfully'.format(pool['name'])) else: -- 2.39.5 From 31c4520940531613cfd782a028a811e723a697d3 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 12:13:09 -0500 Subject: [PATCH 19/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index 0aa55a2..ff96443 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -65,7 +65,7 @@ rc = call("ssh {}@{} 'umount /mnt/FreeNASRecoveryKeys; cryptsetup luksClose Free #Loop through the pools and only unlock the locked ones POOLS = request('storage/volume/', 'GET') for pool in POOLS['response']: - if pool['is_decrypted'] == False: + if pool['is_decrypted'] == False: recovery_key = open('/mnt/ramfs/{}.recoveryKey'.format(pool['name']),'rb') recovery_key_binary = recovery_key.read() recovery_key_string = (base64.b64encode(recovery_key_binary)).decode('ascii') -- 2.39.5 From d76148739c9fbee4119743122d7060fdac2aad30 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 12:13:41 -0500 Subject: [PATCH 20/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index ff96443..cc4aa50 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -70,12 +70,12 @@ for pool in POOLS['response']: recovery_key_binary = recovery_key.read() recovery_key_string = (base64.b64encode(recovery_key_binary)).decode('ascii') response = request('storage/volume/{}/unlock/'.format(pool['name']), 'POST', {'recovery_key': '{}'.format(recovery_key_string)}) - if response['ok']: - logging.info('Pool {} was unlocked successfully'.format(pool['name'])) - else: - logging.error('Pool {} was NOT unlocked successfully'.format(pool['name'])) - else: - logging.debug('Pool {} is already unlocked'.format(pool['name'])) + if response['ok']: + logging.info('Pool {} was unlocked successfully'.format(pool['name'])) + else: + logging.error('Pool {} was NOT unlocked successfully'.format(pool['name'])) + else: + logging.debug('Pool {} is already unlocked'.format(pool['name'])) -- 2.39.5 From 6f23ab5617245001cfe084bff565fa3710187dfa Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 12:14:26 -0500 Subject: [PATCH 21/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index cc4aa50..4ca4a34 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -12,7 +12,7 @@ logging.basicConfig(level=logging.INFO,format='%(asctime)s - [%(levelname)s] %(m def request(resource, method='GET', data=None): if data is None: data = '' - url = 'https://{}/api/v1.0/{}'.format(config.HOSTNAME, resource) + url = 'https://127.0.0.1/api/v1.0/{}'.format(resource) logging.debug('Request URL: {}'.format(url)) logging.debug('Request Data: {}'.format(data)) logging.debug('CA Certificate Path: {}'.format(config.CA_CERT_PATH)) -- 2.39.5 From da26134c66019058cbbbb8a8afa7aad7543fcc99 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 12:16:06 -0500 Subject: [PATCH 22/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index 4ca4a34..6a4a14d 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -22,7 +22,7 @@ def request(resource, method='GET', data=None): data=json.dumps(data), headers={'Content-Type': "application/json"}, auth=('root', '{}'.format(config.FREENAS_ROOT_PASSWORD)), - verify='{}'.format(config.CA_CERT_PATH) + verify={}.format(config.CA_CERT_PATH) ) logging.debug('Request Status Code: {}'.format(r.status_code)) if r.ok: -- 2.39.5 From 1d3b6f6922ab8915b6f3f77f4dca73fa8a6effeb Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 12:17:55 -0500 Subject: [PATCH 23/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index 6a4a14d..4ca4a34 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -22,7 +22,7 @@ def request(resource, method='GET', data=None): data=json.dumps(data), headers={'Content-Type': "application/json"}, auth=('root', '{}'.format(config.FREENAS_ROOT_PASSWORD)), - verify={}.format(config.CA_CERT_PATH) + verify='{}'.format(config.CA_CERT_PATH) ) logging.debug('Request Status Code: {}'.format(r.status_code)) if r.ok: -- 2.39.5 From c17636f3171c78df48ca53f8439e3c79f9fa25b1 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 12:18:25 -0500 Subject: [PATCH 24/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index 4ca4a34..06647cd 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -22,7 +22,7 @@ def request(resource, method='GET', data=None): data=json.dumps(data), headers={'Content-Type': "application/json"}, auth=('root', '{}'.format(config.FREENAS_ROOT_PASSWORD)), - verify='{}'.format(config.CA_CERT_PATH) + verify="{}".format(config.CA_CERT_PATH) ) logging.debug('Request Status Code: {}'.format(r.status_code)) if r.ok: -- 2.39.5 From 79d95018049835de3624041a717b91c8244107b6 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 12:18:42 -0500 Subject: [PATCH 25/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index 06647cd..6a4a14d 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -22,7 +22,7 @@ def request(resource, method='GET', data=None): data=json.dumps(data), headers={'Content-Type': "application/json"}, auth=('root', '{}'.format(config.FREENAS_ROOT_PASSWORD)), - verify="{}".format(config.CA_CERT_PATH) + verify={}.format(config.CA_CERT_PATH) ) logging.debug('Request Status Code: {}'.format(r.status_code)) if r.ok: -- 2.39.5 From f73127c0c588b6a145bf5bfd242dd0b41298be4f Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 12:19:15 -0500 Subject: [PATCH 26/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index 6a4a14d..8fc5072 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -22,7 +22,7 @@ def request(resource, method='GET', data=None): data=json.dumps(data), headers={'Content-Type': "application/json"}, auth=('root', '{}'.format(config.FREENAS_ROOT_PASSWORD)), - verify={}.format(config.CA_CERT_PATH) + verify=config.CA_CERT_PATH ) logging.debug('Request Status Code: {}'.format(r.status_code)) if r.ok: -- 2.39.5 From 61093fa8323bfb13e554d2ea9d94cd3c2a9f0406 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Wed, 27 Nov 2019 12:20:56 -0500 Subject: [PATCH 27/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index 8fc5072..8d1ff07 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -76,7 +76,9 @@ for pool in POOLS['response']: logging.error('Pool {} was NOT unlocked successfully'.format(pool['name'])) else: logging.debug('Pool {} is already unlocked'.format(pool['name'])) - + +# unmount the ramfs and destory the keys +rc = call("umount /mnt/ramfs", shell=True) -- 2.39.5 From 684493ed33e0d951f8b0687c41337be4ca7ab21f Mon Sep 17 00:00:00 2001 From: jgaunt Date: Thu, 28 Nov 2019 12:14:04 -0500 Subject: [PATCH 28/30] Update 'freenas_network_unlock.py' --- freenas_network_unlock.py | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/freenas_network_unlock.py b/freenas_network_unlock.py index 8d1ff07..22bed4f 100644 --- a/freenas_network_unlock.py +++ b/freenas_network_unlock.py @@ -4,10 +4,6 @@ from subprocess import call # You must initialize logging, otherwise you'll not see debug output. logging.basicConfig(level=logging.INFO,format='%(asctime)s - [%(levelname)s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S') -#logging.getLogger().setLevel(logging.DEBUG) -#requests_log = logging.getLogger("requests.packages.urllib3") -#requests_log.setLevel(logging.DEBUG) -#requests_log.propagate = True def request(resource, method='GET', data=None): if data is None: @@ -16,6 +12,10 @@ def request(resource, method='GET', data=None): logging.debug('Request URL: {}'.format(url)) logging.debug('Request Data: {}'.format(data)) logging.debug('CA Certificate Path: {}'.format(config.CA_CERT_PATH)) + if config.CA_CERT_PATH == 'False': + config.CA_CERT_PATH = False + else: + config.CA_CERT_PATH = '{}'.format(config.CA_CERT_PATH) r = requests.request( method, url, @@ -34,20 +34,6 @@ def request(resource, method='GET', data=None): return {'ok': r.ok, 'status_code': r.status_code, 'response': r.text} raise ValueError(r) - -#if __name__ == "__main__": -# parser = argparse.ArgumentParser(description='Unlock FreeNAS Pools') -# group = parser.add_mutually_exclusive_group() -# group.add_argument('-s', '--server', action='store_true', help='server (Usually runs on another system where passwords are stored)') -# group.add_argument('-c', '--client', action='store_true', help='client (Usually runs on the FreeNAS server)') -# parser.add_argument('-ip', '--host', type=str, help='Hostname/IP of the host running the unlock script (Required for client)') -# parser.add_argument('-f', '--filePath', type=str, help='Absolute path to the script on the host (Required for client)') -# args = parser.parse_args() -# if args.client and (args.host is None or args.filePath is None): -# parser.error("--client requires --host and --filePath.") - - - # Create a small ramdrive to store our recovery keys temporarily rc = call("mkdir /mnt/ramfs", shell=True) rc = call("mdmfs -s 1m md /mnt/ramfs", shell=True) @@ -60,15 +46,15 @@ for poolName in config.POOL_NAMES: rc= call("scp {}@{}:/mnt/FreeNASRecoveryKeys/{}.recoveryKey /mnt/ramfs".format(config.KEY_HOST_USER, config.KEY_HOST, poolName), shell=True) # We can close the luks volume now -rc = call("ssh {}@{} 'umount /mnt/FreeNASRecoveryKeys; cryptsetup luksClose FreeNASRecoveryKeys'".format(config.KEY_HOST_USER, config.KEY_HOST), shell=True) +rc = call("ssh {}@{} 'umount /mnt/FreeNASRecoveryKeys; cryptsetup luksClose FreeNASRecoveryKeys; rm -rf /mnt/FreeNASRecoveryKeys'".format(config.KEY_HOST_USER, config.KEY_HOST), shell=True) -#Loop through the pools and only unlock the locked ones +# Loop through the pools and only unlock the locked ones POOLS = request('storage/volume/', 'GET') for pool in POOLS['response']: if pool['is_decrypted'] == False: recovery_key = open('/mnt/ramfs/{}.recoveryKey'.format(pool['name']),'rb') - recovery_key_binary = recovery_key.read() - recovery_key_string = (base64.b64encode(recovery_key_binary)).decode('ascii') + recovery_key_binary = recovery_key.read() + recovery_key_string = (base64.b64encode(recovery_key_binary)).decode('ascii') response = request('storage/volume/{}/unlock/'.format(pool['name']), 'POST', {'recovery_key': '{}'.format(recovery_key_string)}) if response['ok']: logging.info('Pool {} was unlocked successfully'.format(pool['name'])) @@ -77,8 +63,8 @@ for pool in POOLS['response']: else: logging.debug('Pool {} is already unlocked'.format(pool['name'])) -# unmount the ramfs and destory the keys -rc = call("umount /mnt/ramfs", shell=True) +# wipe the files, unmount the ramfs, and remove the folder +rc = call("rm -fP /mnt/ramfs/*; umount /mnt/ramfs; rmdir /mnt/ramfs", shell=True) -- 2.39.5 From 104452c084f65348569d7b2048091c63897df949 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Fri, 29 Nov 2019 21:29:23 -0500 Subject: [PATCH 29/30] Update 'README.md' --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index 6403076..9bf3c11 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,19 @@ # FreeNAS-Network-Unlock +Configuration variables are changed within the c[onfig.py](config.py) file. + +#### Setup password-less SSH connection +You are responsible for setting up the password-less ssh connection from freenas to the other computer. You can use the following as a base. +``` +# Run ssh-keygen to create the default ~/.ssh/id_rsa ssh key (no passphrase) +ssh-keygen + +# Add the public key of this ssh key to the authorized keys of the PI +# We will be prompted to enter the password of the Pi use in order to access the Pi on this occasion, but once the keys are installed on the Pi we won't need to use the password again +cat ~/.ssh/id_rsa.pub | ssh @ 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys' + +# Check that password-less access is working by running +ssh @ +# You should be dumped straight to the terminal of the Pi without being prompted for a password. You can now logout of the Pi using: +exit +``` \ No newline at end of file -- 2.39.5 From 55f59b393a094536f5035abe95eaab72f0b10b58 Mon Sep 17 00:00:00 2001 From: jgaunt Date: Fri, 29 Nov 2019 21:41:08 -0500 Subject: [PATCH 30/30] Update 'README.md' --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9bf3c11..6c8ccf2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # FreeNAS-Network-Unlock -Configuration variables are changed within the c[onfig.py](config.py) file. +Configuration variables are changed within the [config.py](config.py) file. #### Setup password-less SSH connection -- 2.39.5