larry1chan@qq.com vor 10 Monaten
Commit
314db4abbf
9 geänderte Dateien mit 476 neuen und 0 gelöschten Zeilen
  1. 2 0
      .gitignore
  2. 189 0
      automount_luks.py
  3. 161 0
      crypt_tools.py
  4. 13 0
      luks_mount.conf
  5. 1 0
      master_passkey
  6. 28 0
      private_key.pem
  7. 9 0
      public_key.pem
  8. 14 0
      random_pass.py
  9. 59 0
      readme.md

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+__pycache__/
+venv/:x

+ 189 - 0
automount_luks.py

@@ -0,0 +1,189 @@
+import os
+import subprocess
+from crypt_tools import decrypt_passphrase, create_luks_mount_config
+import argparse
+
+
+# Configuration file containing encrypted LUKS passphrases
+CONFIG_FILE = "luks_mount.conf"
+
+
+
+
+def get_device_uuid(device):
+    """
+    Get the UUID of a device using blkid.
+    """
+    try:
+        output = subprocess.check_output(["blkid", "-o", "value", "-s", "UUID", device])
+        return output.decode().strip()
+    except subprocess.CalledProcessError as e:
+        print(f"Failed to get UUID for {device}: {e}")
+        return None
+
+def get_mount_point(device_id):
+    """
+    Get the mount point for a given device ID from the configuration file.
+    """
+    if not os.path.exists(CONFIG_FILE):
+        print(f"Configuration file '{CONFIG_FILE}' not found!")
+        return None
+
+    with open(CONFIG_FILE, "r") as f:
+        for line in f:
+            if line.startswith("#") or len(line) == 0:
+                continue            
+            parts = line.strip().split()
+            if len(parts) != 3:
+                continue
+
+            uuid, mount_point, _ = parts
+            if uuid == device_id:
+                return mount_point
+
+    return None
+
+
+def mount_luks_filesystems():
+    """
+    Read the configuration file, decrypt the LUKS passphrases, and mount the filesystems.
+    """
+    if not os.path.exists(CONFIG_FILE):
+        print(f"Configuration file '{CONFIG_FILE}' not found!")
+        return
+
+    with open(CONFIG_FILE, "r") as f:
+        for line in f:
+            if line.startswith("#") or len(line) == 0:
+                continue            
+            # Parse the configuration line: uuid mount_point encrypted_passphrase
+            parts = line.strip().split()
+            if len(parts) != 3:
+                print(f"Skipping invalid line: {line}")
+                continue
+
+            uuid, mount_point, encrypted_passphrase = parts
+
+            # Get the device path from the UUID
+            device = f"/dev/disk/by-uuid/{uuid}"
+            if not os.path.exists(device):
+                print(f"Device '{device}' not found!")
+                continue
+
+            # Decrypt the LUKS passphrase using the master passkey
+            try:
+                passphrase = decrypt_passphrase(encrypted_passphrase, private_key_file="private_key.pem")
+            except Exception as e:
+                print(f"Failed to decrypt passphrase for {device}: {e}")
+                continue
+
+            # Unlock the LUKS device
+            try:
+                subprocess.run(
+                    ["cryptsetup", "luksOpen", device, f"{os.path.basename(device)}_crypt"],
+                    input=passphrase.encode(),
+                    check=True
+                )
+                print(f"Unlocked LUKS device: {device}")
+            except subprocess.CalledProcessError as e:
+                print(f"Failed to unlock {device}: {e}")
+                continue
+
+            # Mount the filesystem
+            try:
+                os.makedirs(mount_point, exist_ok=True)
+                subprocess.run(
+                    ["mount", f"/dev/mapper/{os.path.basename(device)}_crypt", mount_point],
+                    check=True
+                )
+                print(f"Mounted {device} at {mount_point}")
+            except subprocess.CalledProcessError as e:
+                print(f"Failed to mount {device} at {mount_point}: {e}")
+                continue
+
+
+def unmount_and_lock_filesystem(device_id):
+    """
+    Unmount and lock a filesystem given the device ID.
+    """
+    device = f"/dev/disk/by-uuid/{device_id}"
+    crypt_device = f"/dev/mapper/{os.path.basename(device)}_crypt"
+
+    # Get the mount point from the configuration file
+    mount_point = get_mount_point(device_id)
+    if not mount_point:
+        print(f"Mount point for device '{device_id}' not found in configuration file.")
+        return
+
+    # Unmount the filesystem
+    try:
+        subprocess.run(["sudo", "umount", crypt_device], check=True)
+        print(f"Unmounted filesystem: {crypt_device}")
+    except subprocess.CalledProcessError as e:
+        print(f"Failed to unmount filesystem {crypt_device}: {e}")
+        return
+    
+
+    # Remove the mount point directory
+    try:
+        os.rmdir(mount_point)
+        print(f"Removed mount point directory: {mount_point}")
+    except OSError as e:
+        print(f"Failed to remove mount point directory {mount_point}: {e}")
+
+    # Lock the LUKS device
+    try:
+        subprocess.run(["sudo", "cryptsetup", "luksClose", f"{os.path.basename(device)}_crypt"], check=True)
+        print(f"Locked LUKS device: {device}")
+    except subprocess.CalledProcessError as e:
+        print(f"Failed to lock LUKS device {device}: {e}")
+
+def close_all_filesystems():
+    """
+    Close all filesystems listed in the configuration file.
+    """
+    if not os.path.exists(CONFIG_FILE):
+        print(f"Configuration file '{CONFIG_FILE}' not found!")
+        return
+
+    with open(CONFIG_FILE, "r") as f:
+        for line in f:
+            parts = line.strip().split()
+            if len(parts) != 3:
+                print(f"Skipping invalid line: {line}")
+                continue
+
+            uuid, _, _ = parts
+            unmount_and_lock_filesystem(uuid)
+
+
+def main():
+    """
+    Main function to read the master passkey and mount LUKS filesystems.
+    """
+    parser = argparse.ArgumentParser(description="Automount LUKS filesystems.")
+    parser.add_argument("-m", "--mount", action="store_true", help="Mount all LUKS devices")
+    parser.add_argument("-c", "--close", help="Close a specific LUKS device", metavar="DEVICE_ID")
+    parser.add_argument("-f", "--config", help="Specify a configuration file", metavar="CONFIG_FILE")
+    parser.add_argument("-k", "--close-all", action="store_true", help="Close all LUKS devices")
+    parser.add_argument("-n", "--new-config", action="store_true", help="Create a new luks_mount.conf file")
+
+
+    args = parser.parse_args()
+    global CONFIG_FILE
+    if args.config:
+
+        CONFIG_FILE = args.config
+    if args.mount:        
+        mount_luks_filesystems()
+    elif args.close:
+        unmount_and_lock_filesystem(args.close)
+    elif args.close_all:
+        close_all_filesystems()
+    elif args.new_config:
+        create_luks_mount_config(config_file=CONFIG_FILE)
+    else:
+        parser.print_help()
+
+if __name__ == "__main__":
+    main()

+ 161 - 0
crypt_tools.py

@@ -0,0 +1,161 @@
+from cryptography.hazmat.primitives.asymmetric import rsa, padding
+from cryptography.hazmat.primitives import serialization, hashes
+from cryptography.hazmat.backends import default_backend
+import os
+import base64
+import getpass
+
+def init_keys(private_key_file="private_key.pem", public_key_file="public_key.pem"):
+    """
+    Generate a new RSA private/public key pair and save them to files.
+    """
+    # Check if keys already exist
+    if os.path.exists(private_key_file) and os.path.exists(public_key_file):
+        print("Keys already exist. Skipping key generation.")
+        return
+
+    # Generate a private key
+    private_key = rsa.generate_private_key(
+        public_exponent=65537,
+        key_size=2048,
+        backend=default_backend()
+    )
+
+    # Generate the public key
+    public_key = private_key.public_key()
+
+    # Serialize and save the private key
+    with open(private_key_file, "wb") as f:
+        f.write(
+            private_key.private_bytes(
+                encoding=serialization.Encoding.PEM,
+                format=serialization.PrivateFormat.PKCS8,
+                encryption_algorithm=serialization.NoEncryption()
+            )
+        )
+
+    # Serialize and save the public key
+    with open(public_key_file, "wb") as f:
+        f.write(
+            public_key.public_bytes(
+                encoding=serialization.Encoding.PEM,
+                format=serialization.PublicFormat.SubjectPublicKeyInfo
+            )
+        )
+
+    print(f"Private key saved to {private_key_file}")
+    print(f"Public key saved to {public_key_file}")
+
+
+def encrypt_passphrase(passphrase, public_key_file="public_key.pem"):
+    """
+    Encrypt a passphrase using the public key.
+    Returns the encrypted passphrase as a base64-encoded string.
+    """
+    # Load the public key
+    with open(public_key_file, "rb") as f:
+        public_key = serialization.load_pem_public_key(
+            f.read(),
+            backend=default_backend()
+        )
+
+    # Encrypt the passphrase
+    encrypted = public_key.encrypt(
+        passphrase.encode(),
+        padding.OAEP(
+            mgf=padding.MGF1(algorithm=hashes.SHA256()),
+            algorithm=hashes.SHA256(),
+            label=None
+        )
+    )
+
+    # Return the encrypted passphrase as a base64-encoded string
+    return base64.b64encode(encrypted).decode()
+
+def decrypt_passphrase(encrypted_passphrase, private_key_file="private_key.pem"):
+    """
+    Decrypt an encrypted passphrase using the private key.
+    Returns the decrypted passphrase as a string.
+    """
+    # Load the private key
+    with open(private_key_file, "rb") as f:
+        private_key = serialization.load_pem_private_key(
+            f.read(),
+            password=None,
+            backend=default_backend()
+        )
+
+    # Decode the base64-encoded encrypted passphrase
+    encrypted = base64.b64decode(encrypted_passphrase.encode())
+
+    # Decrypt the passphrase
+    decrypted = private_key.decrypt(
+        encrypted,
+        padding.OAEP(
+            mgf=padding.MGF1(algorithm=hashes.SHA256()),
+            algorithm=hashes.SHA256(),
+            label=None
+        )
+    )
+
+    # Return the decrypted passphrase
+    return decrypted.decode()
+
+def create_luks_mount_config(config_file="luks_mount.conf", public_key_file="public_key.pem"):
+    """
+    Create a new luks_mount.conf file by interactively prompting for device, mount point, and password.
+    If the configuration file already exists, provide an option to quit or append to the existing file.
+    """
+    mode = "w"
+    if os.path.exists(config_file):
+        print(f"Configuration file '{config_file}' already exists.")
+        choice = input("Do you want to (a)ppend to it or (q)uit? ").strip().lower()
+        if choice == 'q':
+            print("Exiting without making changes.")
+            return
+        elif choice == 'a':
+            mode = "a"
+        else:
+            print("Invalid choice. Exiting without making changes.")
+            return
+
+    with open(config_file, mode) as f:
+        if mode == "w":
+            f.write("# LUKS mount configuration file\n")
+            f.write("# Format: UUID mount_point encrypted_passphrase\n")
+
+        while True:
+            device = input("Enter the device UUID (e.g., UUID): ").strip()
+            mount_point = input("Enter the mount point (e.g., /media/<username>/luks-<UUID>): ").strip()
+            passphrase = getpass.getpass("Enter the passphrase: ").strip()
+
+            encrypted_passphrase = encrypt_passphrase(passphrase, public_key_file)
+            f.write(f"{device} {mount_point} {encrypted_passphrase}\n")
+
+            another = input("Do you want to add another entry? (y/n): ").strip().lower()
+            if another != 'y':
+                break
+
+    print(f"Configuration saved to {config_file}")
+
+
+# Example usage
+if __name__ == "__main__":
+    # Initialize keys (run this once to generate keys)
+    init_keys()
+
+    # Encrypt a passphrase
+    #passphrases = ["5khbS4JFN25tPVrkzv2b2Q==", "kT3vPK09f+KhNWp7LpU1jg==", "3fhbN/Nt1YFPM5AUbJ4ERg=="]
+    passphrases= ["df638b83d86404800bd631cf3ca3a483", "f1c873af36003777dbf7fae275e5f159", "23d828a6cbde48cd826e862da6b3e3e9"]
+    
+    print(decrypt_passphrase('fAqe02nfx1L+YZK/kLFbsd1nVCl5w/LJxxMeSRXLsEm+vq49dRI4eYSzjl3w2YqyPb4JeVXfMDWCTm523k9e/KI+GF8zAPisI1icWM/k+yzMCrW9Ga7rzwW092Uepm7IU4z7LwU4Z9t2wmQkeb6ulso6lcaYzVoCcIHRJ0gCkBZBb0nA1lXQvf2UNFfe9kkzX+DR1MCovY9SAsIndisCh6y0IxEBbfCTASU5VYIcngiKayS6flVtGuLOz/3S6Z+T5GDN7dLC97wf/yVBQJ2lPdgTcawv2qV59OcxDGUeHjwi340+UIramslrxmGpFMyBkmLYqcjKkWsVD6HF2msu6w=='))
+    print(decrypt_passphrase('huZoCnJBUay3XSZt36XoBqckexy5iYB6LT41Wscxx/8KujJQWas/hwn6tdlr7ss8pTs2LNW71CvcRdHx6p8YgBs0aYV5o4z8P5yLahGH0ZgmA/Tc+brQN3+/s1cyFNQ8LZK0D2jizpah5Np469EO5hLT//lx4/WEobX79CS1WRZxetbqmgLqKrFcbBh50BYS/Ka61P63IIlHXCF7GySPZM1m0bRfphmQ/93FPngkyinxK0Sho0i7ddXC+bwXWeZSAi9nPTNZ4tGBa7hVzJBNVmoI4zIdjXtfJeGQ21bSPIPI+KsfE3/3Oe2AFmU1o8axbxNQJGbmee6BqJIhArzAzA=='))
+
+    for passphrase in passphrases:
+         encrypted = encrypt_passphrase(passphrase)
+         print(f"Encrypted passphrase: {encrypted}")
+
+         # Decrypt the passphrase
+         decrypted = decrypt_passphrase(encrypted)
+         print(f"Decrypted passphrase: {decrypted}")
+

+ 13 - 0
luks_mount.conf

@@ -0,0 +1,13 @@
+f48bfd48-e478-4fd1-97b0-5bf66844b584    /media/yazoo/luks-f48bfd48-e478-4fd1-97b0-5bf66844b584  c6jvKUgjvNhImxO2OpndSHRMeO4N7+R2oN2i2eiqsXwSqMCD2juqSXRSUI8QrNOqR/SLRX5vkBZkwZ669Xv8nRXHpeWsSzr7t9qUjz48tIgTH/sfVDkxztyKre247M4hRAHUBevXTFRaa8H81w3x59Loix5/nlZ0EqYgyM/vSZzGv3hZIeIia2tWxE8b7Mbb/BwCj9fjxVgTD5v0TsfHQftf/BwWJcFqIleFDaD84hVfzAyOwNJhn56DanbUiwHnKwgr/HZ7/36UZ/rbB7zBaLt2hFaY3t6012bdkEzOe9/9b0UCXtoMeL9XmNQm5mWEtzOlcoUJUlpNkZSuaaJV+g==
+740cad07-082c-4708-afa6-7c3890b18429    /media/yazoo/luks-740cad07-082c-4708-afa6-7c3890b18429  Lt1vwF2to/SLAe1Wqk+aWqpvaQluJygPfjHrY1c4eZ709cYJ05+Q/X9WUMxPZ4heQS6njA+Z/QSGgbpRsl+ULwZaUkjGFOW6zOJMdYWrFml639gaVz3J5vfso/QMqR2efPgWObcQWRuWGcwgWZmcVV03mqxllNEbrv8jEmd3oZYJszSU1usrxQOHi2x6FqFR5uFCUk1V1AjjudONWC8LAzAEAxYg8yHVHnmuzMS+IekSsLDdtThhhxWBaegyxmOlqc5rwdx5E9f6sYI61yE7iptSWut8srcbWQYsJpIxZWcRnRSivX3zTxVTQwiBZID7SknbLLmu9nsu0jvsVTNw0A==
+89f16553-74b6-4328-932c-876f99e779b8    /media/yazoo/luks-89f16553-74b6-4328-932c-876f99e779b8  mRqh1BcEj9T2Y8uzc0oDdt6RQ6uGScS26YUvVpxZV8EhqOdPWEg0ZlUtg+aEiBMkFRhVtLOFyMOdEr0/6T/T+5BAwz8DEgFPSupPRXsfu7nR3M8r5l11zHgOpcgSZSpIEkMzjAzgzAhRURxiw0BEpTsvw62IIyihCK0n0cydYVlhgBZqd1voTyILeCbvODVMMJMG0P6+wyq0hSgVqdkXmNbSRPqbtppO1JbFxcA8VfzYpAcLc/A6bmh15cu0TqwadCACdzBRS/D5rNLAx62/TaPh7SBEgEweA+d60z6T20Lr12BHAI8P26DGSQ5U75RPdc62iR9bQS1K2ffdD5d9lA==
+# Western Digital USB removable drive 2TB 5955839a-aa5e-40ef-bb39-2721cf531b48 - 
+# 5955839a-aa5e-40ef-bb39-2721cf531b48    /media/yazoo/luks-5955839a-aa5e-40ef-bb39-2721cf531b48  JK+jBVM57nOoQBH/WzJdFc7fzw67R+PmEcAPKZbECkdMSAXkryW4DzD9RRTFVoL4xjKvOxF1Gq8kw0PgeLGlyQASNzTD+cnfjKxxd5E7cHRPcziF7RqZRBe24woTLPFnEVybUgvGDm2U85SbmY/D2tuOfqdIT3YrXP/8USWQcSv3cxU41fjb95LBfWlYlFa9X9/sJC42CN6YoAnDswNy2Ezav36gnE9DvSiedb/Pe3A6ExvuHnog4TDp5FO8sicama4RplJJIdbVGRwDdHGT7RQMRzOY769lntgIz+dIvfM22S/bLamZ8ny8RPlDabF2bOm9suLfgkNGp2EvmoKAqA==
+# Toshiba USB removable drive 8TB 01cf1174-2f42-45d2-b206-c146c4f42f49 - 
+# 01cf1174-2f42-45d2-b206-c146c4f42f49    /media/yazoo/luks-01cf1174-2f42-45d2-b206-c146c4f42f49  F7mZZtnGF8IGzQZfUim74y5nE+AepG51eAv5EeUuxGNe4RsME5PmDr69vBdUiG5FQPoUp7C75Z5g9wxH5z/lJQqCXgH+jWF2+dDs/HEfFvqM/SE1iQRC8c9oCS+ZPGDEyDEDsJIdmU9pKvdK5ObkgY1wlbEofB4taxqSq3UOd2y0CyR3AfvwXFnlBKarlk05AabUhnHVCuhRIBxuTp2WS7hLOmfwlpKFoX3X5MZSMb7gcRf0SMp6cKo4gMqnmbBPCZfNVWv8AtMdbXINCPV6JMfApJte0zlYmzIUhL0FuCKpyYiZKfDX00HSSbYFAm3qllXtZgEVaTE7Z0WMunQrxQ==
+# Seagate USB removable drive 8TB 67672a15-a412-4a17-bb01-c76509e21243 - 
+# 67672a15-a412-4a17-bb01-c76509e21243    /media/yazoo/luks-67672a15-a412-4a17-bb01-c76509e21243  fAqe02nfx1L+YZK/kLFbsd1nVCl5w/LJxxMeSRXLsEm+vq49dRI4eYSzjl3w2YqyPb4JeVXfMDWCTm523k9e/KI+GF8zAPisI1icWM/k+yzMCrW9Ga7rzwW092Uepm7IU4z7LwU4Z9t2wmQkeb6ulso6lcaYzVoCcIHRJ0gCkBZBb0nA1lXQvf2UNFfe9kkzX+DR1MCovY9SAsIndisCh6y0IxEBbfCTASU5VYIcngiKayS6flVtGuLOz/3S6Z+T5GDN7dLC97wf/yVBQJ2lPdgTcawv2qV59OcxDGUeHjwi340+UIramslrxmGpFMyBkmLYqcjKkWsVD6HF2msu6w==
+# CT2000MX500SSD1 (M3CR046) Nextcloud Files 63fdfdf9-4de5-4b11-8ffb-cad337baaad8 - 
+# 63fdfdf9-4de5-4b11-8ffb-cad337baaad8    /media/yazoo/nextcloud_files                            Jtho4K1IqqyJtgrm3IDS9YMsyho4USl7Tok3q80WiLMZZQ/qlt2jnT2OQcImPpdCsOe/P6evw4ZSYVp8kuOBjq1IkZX2GyWR1lW3K6AAOV++yq/0YVcVVBXqWRBTdiS/lQBG6wlaFNOshzArHjDgw324xlxE4cMm0v4ljwlVnuVauSMayeBEoQvmIHzB5evbA1ofa3gukC4YN7h1+xuQ2DQAKvvSsFhSm0YBveiiNTJo+1+W9GX223SQc7vF5TRD+Rq7jvsqDe7s2YubdcRtTA/XRDEwWpCzEHzdWXYID1FfwKMyVG5esHsTx8KbkAq1yXgpvGLaqs1gaAcVgu+pGw==
+# Western Digital USB 1TB 8819b3a5-9cc2-4f3a-8f11-f0acc38d2792 -
+8819b3a5-9cc2-4f3a-8f11-f0acc38d2792 /media/yazoo/wdcrypt NuLozNS5TYrUqrzPeNyqVVt6E3f8FhDYubfcnueV960PtYK1pLVKGeX3imM6zB1TzIzpabDa6vWfTo6sNm3at4woJG6hO+6+lzeZsAdX6DoLw9WqFBrn25YJw8Mb9EJOe28PqG/xGrG421BcfAbIssAhD83Cnn1IzAGqDwuPk7ppFPtDUTY9YqB6pSULY+Rg/f2ww34634rRT4KmWuOgArEcNtQJtn0Bhx+SSt/BqT0P1TpklSzqT1WWfhisHKqgOUY7y0OU9KVegTDUhftqa9tT2p6z8VP6gzZATVJ6UqT46krjtLwib/9+oXA0XlpHF2G50QpQKZ0QNPkDs2ua3A==

+ 1 - 0
master_passkey

@@ -0,0 +1 @@
+somepassphrase

+ 28 - 0
private_key.pem

@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCm8NnJRapG0TZZ
+lk/RXAIC65o8LuFII5Rdw6qKI89LuWscp+FkmZrbEvDz+wuyqtaVMpxHUIZXPAHX
+C5bvi2koEBShDeehLJCmT9QPoSaXZSmib7EJjB83itSKSOOtsHeU+5dzSBnmxOMW
+FTaR6ahjSjGiuLnsRgpa7Lvu5Vkhidorm+Zu2OUAvlFGjl3U/lhinDqTxpY0v7RR
+RhdZ9cmiwo4/uhLMIa4XIGmBK7VTeIBC/ovkLhpknWzG+A6emqRIMObB7qPZUZvY
+pfzvqZOE6Sd0D9ZIuWzqBdMw6BAKEBTc48Wr5z9vGDIW/w1IGZ1oU2OhnlPYfl2t
+Wh89Cq3hAgMBAAECggEADXNYstA1gd7zsHhtTi6p/VL/EnQLA/lU6BCetiJgPodO
+H2kR3p2HNflC13+dz8uWvj7ti0vsRQ1RTyKwirSqeHdCOD9C71AkR/gk240GC1rz
+5bH221ByR/L8QLeSe6E9I1B5oYjYyGiK7PGw28UOI5Db6rLUTRqQFUcfdcY+Hhbo
+QHUDKD0psBLymzzdXiPXOkp8EMSozVClxsDRMB+2PcVzJz++C6OcMLuCHqQFB9Yf
+rxIQN00bVuLdCIk84SzoMp8LrMp+wFRRYFfoWe+e4zixNacKghfWcNiWzGhQcDYQ
+9o6azxUOOSd3nN1SYUIefqvhmyN4ojc9GsAwuFOKyQKBgQDhZ9RELmf+VZFAaXMf
+uKz4JFTDUILAzMZuCGM5sqdW7kfBbX7lJbyYTOTdBmADTjNjN5qfkw0FQlbdty37
+SjiSU9HMeDm2Kdb6t6UG/xQiTZtm6dObsVM+0yJHOMvC3VwninwI4d7INHW9lsdE
+BnxxxUZgcswoHWhkaQnebO9ySQKBgQC9mYu3pOKRutjegbuEXCVJ3NuMEsEmCbwA
+ciz6g9Q2/STgYs09D4mU6nUBokJEPEClaD6VqCsCJEJ0NTW9Fd1Sc5+WNt0NA1F1
+buyBFTsi0S+WgIPEe/Q6mc+6ofjIwKM3fIUo+PIFsALOFBI5t5fvL0iCiVmmqh4S
+n4XkqTxe2QKBgQCCltX6vmwPhOGHUNCa8zJ6/QmCstVeAAWCYCekmOWsTpaR8O8Q
+sUFHd10s1HGx2I+bDu7tPpPPlTSgdW0VZlXKKPemn4zIBgt/6/+XQxcWHKJJCHVJ
+gX26KzZzzur2NasbWXcs6jdZBFOmiIFf3uYgP+vbGwc+wnLloZlPHQvIyQKBgQCk
+nlqHGqx1p2uA1ddANtlRZmdhGS+GnVEUeg2/fRKWo/iOsnpMl9724xKwVnd+02m1
+s+sS+a5N77mbOE/uWruNSUK4o+4NzGG/uo2yDgMIWeQdonvF73HAJ6gK/XMKqueL
+15uuVWedtJLa5uZkIpnSXJVycVrbsDzoIoWYYbA/EQKBgQCDsZ4Hak3b5KUyXmzI
+Yr2sywAxkkCIRQWe7aiZe8AI0fCXKnq80mk5jAdCj2TwtOk3L2EXf4bcp2jttArx
+YaYswf7IeJJTc4DmcCE2SxQoIqGhPTY8WjnfZn0yVDfM8zDjtqhwFsdyHRvi0beN
+d9yktLUklCtNxWgRoObAaq7WbA==
+-----END PRIVATE KEY-----

+ 9 - 0
public_key.pem

@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApvDZyUWqRtE2WZZP0VwC
+AuuaPC7hSCOUXcOqiiPPS7lrHKfhZJma2xLw8/sLsqrWlTKcR1CGVzwB1wuW74tp
+KBAUoQ3noSyQpk/UD6Eml2Upom+xCYwfN4rUikjjrbB3lPuXc0gZ5sTjFhU2kemo
+Y0oxori57EYKWuy77uVZIYnaK5vmbtjlAL5RRo5d1P5YYpw6k8aWNL+0UUYXWfXJ
+osKOP7oSzCGuFyBpgSu1U3iAQv6L5C4aZJ1sxvgOnpqkSDDmwe6j2VGb2KX876mT
+hOkndA/WSLls6gXTMOgQChAU3OPFq+c/bxgyFv8NSBmdaFNjoZ5T2H5drVofPQqt
+4QIDAQAB
+-----END PUBLIC KEY-----

+ 14 - 0
random_pass.py

@@ -0,0 +1,14 @@
+import os
+import base64
+
+def generate_random_passphrase(length=16):
+    """
+    Generate a random passphrase encoded in ASCII.
+    """
+    random_bytes = os.urandom(length)
+    passphrase = base64.b64encode(random_bytes).decode('ascii')
+    return passphrase
+
+# Generate a random passphrase of 32 bytes
+random_passphrase = generate_random_passphrase()
+print(f"Random Passphrase: {random_passphrase}")

+ 59 - 0
readme.md

@@ -0,0 +1,59 @@
+# Automount LUKS Filesystems
+
+## Overview
+
+This script automates the process of mounting and unmounting LUKS-encrypted filesystems. It uses a configuration file to store the device UUIDs, mount points, and encrypted passphrases.
+
+## Requirements
+
+* Python 3.x
+* `argparse` library
+* `cryptography` library
+* `subprocess` library
+
+## Configuration File
+
+The configuration file is expected to be in the following format:
+
+```
+uuid  mount_point  encrypted_passphrase
+```
+
+For example:
+
+```
+f48bfd48-e478-4fd1-97b0-5bf66844b584  /media/yazoo/luks-f48bfd48-e478-4fd1-97b0-5bf66844b584  c6jvKUgjvNhImxO2OpndSHRMeO4N7+R2oN2i2eiqsXwSqMCD2juqSXRSUI8QrNOqR/SLRX5vkBZkwZ669Xv8nRXHpeWsSzr7t9qUjz48tIgTH/sfVDkxztyKre247M4hRAHUBevXTFRaa8H81w3x59Loix5/nlZ0EqYgyM/vSZzGv3hZIeIia2tWxE8b7Mbb/BwCj9fjxVgTD5v0TsfHQftf/BwWJcFqIleFDaD84hVfzAyOwNJhn56DanbUiwHnKwgr/HZ7/36UZ/rbB7zBaLt2hFaY3t6012bdkEzOe9/9b0UCXtoMeL9XmNQm5mWEtzOlcoUJUlpNkZSuaaJV+g==
+```
+
+## Usage
+
+The script can be run with the following options:
+
+```
+$ python automount_luks.py -h
+usage: automount_luks.py [-h] [-m] [-c CLOSE] [-f CONFIG_FILE]
+
+optional arguments:
+  -h, --help            show this help message and exit
+  -m, --mount           Mount the specified device
+  -c CLOSE, --close CLOSE
+                        Close the specified device
+  -f CONFIG_FILE, --config CONFIG_FILE
+                        Specify a configuration file
+```
+
+## Key Generation
+
+The script uses RSA keys to encrypt and decrypt the passphrases. The keys can be generated using the `crypt_tools.py` script:
+
+```
+$ python crypt_tools.py
+```
+
+This will generate a private key file (`private_key.pem`) and a public key file (`public_key.pem`).
+
+## Notes
+
+* The script assumes that the `cryptsetup` and `mount` commands are installed and available on the system.
+* The script uses the `sudo` command to run the `umount` and `cryptsetup` commands with elevated privileges.
+* The script does not handle errors well, and may require additional error handling and logging in a production environment.