Last active
July 8, 2026 14:58
-
-
Save nerun/cc053edec6715421c2ddd2aec77c6580 to your computer and use it in GitHub Desktop.
Keeper of Mythos, a graphical frontend for the basic commands of cryptsetup / dm-crypt / LUKS for creating encrypted containers in files.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # | |
| # keeper.sh - version 6 - July 8, 2026 | |
| # Copyright (c) 2025 Daniel Dias Rodrigues. No rights reserved. | |
| # | |
| # This program is free software; you can redistribute it and/or modify it under | |
| # the terms of the Creative Commons Zero 1.0 Universal (CC0 1.0) Public Domain | |
| # Dedication (https://creativecommons.org/publicdomain/zero/1.0/). | |
| # | |
| lang="${LC_ALL:-${LC_MESSAGES:-$LANG}}" | |
| if [[ "$lang" == pt* ]]; then | |
| str_programname="Guardião dos Mythos" | |
| str_super="Privilégios de Superusuário Necessários" | |
| str_super_authcancel="Autenticação cancelada." | |
| str_super_authsuccess="Autenticação bem-sucedida!" | |
| str_super_wrongpwd="Senha incorreta. Tentativas restantes:" | |
| str_super_attemptsexceed="Número máximo de tentativas excedido." | |
| str_progress="Inscrevendo selos arcanos... Por favor, aguarde." | |
| str_createimg="Inscrever Tomo" | |
| str_createimg_size="Tamanho do Tomo" | |
| str_createimg_entersize="Digite o tamanho do tomo (ex: 50M, 2G):" | |
| str_createimg_pwd="Inscreva um Feitiço Secreto" | |
| str_createimg_success="Tomo criado com sucesso." | |
| str_authmethod="Método de autenticação:" | |
| str_authmethod_pass="Feitiço Secreto (senha)" | |
| str_authmethod_keyfile="Item Mágico (arquivo-chave)" | |
| str_keyfile_select="Selecione o $str_authmethod_keyfile" | |
| str_keyfile_invalid="Arquivo-chave inválido ou sem permissão de leitura." | |
| str_createkey="Criar Item Mágico" | |
| str_magicitem_succ="Item Mágico criado em:" | |
| str_magicitem_fail="Falha ao criar Item Mágico. Verifique permissões." | |
| str_mount="Abrir Tomo" | |
| str_mount_pwd="Conjure o Feitiço Secreto" | |
| str_mount_success_1="Tomo aberto como:" | |
| str_mount_success_2="e montado como:" | |
| str_mount_fail="Falha ao abrir o tomo. Feitiço errado?" | |
| str_umount_nonemounted="Não há tomos abertos." | |
| str_umount="Selar Tomo" | |
| str_umount_select="Selecione um tomo para fechar:" | |
| str_umount_listmounted="Tomos Abertos" | |
| str_umount_umounted="Tomo selado." | |
| str_menu="Escolha uma ação:" | |
| str_menu_action="Ação" | |
| readme=$(cat <<'EOF' | |
| # Guardião dos Mythos | |
| # Copyright (c) 2025 Daniel Dias Rodrigues. Nenhum direito reservado. | |
| # | |
| # Este programa é software livre; você pode redistribuí-lo e/ou modificá-lo sob | |
| # os termos da Creative Commons Zero 1.0 Universal (CC0 1.0) Public Domain | |
| # Dedication (https://creativecommons.org/publicdomain/zero/1.0/). | |
| Bem-vindo ao seu Tomo de Conhecimento Arcano! | |
| Este espaço de armazenamento seguro foi criado usando o Guardião dos Mythos, uma | |
| interface gráfica para gerenciar contêineres criptografados no Linux. | |
| ## O que é isto? | |
| Este é um arquivo de imagem de disco criptografado e regravável que funciona | |
| como um cofre digital seguro. Você pode armazenar arquivos confidenciais, | |
| documentos ou quaisquer dados que deseje manter em segredo. | |
| ## Detalhes Técnicos | |
| - **Criptografia**: LUKS2 (Linux Unified Key Setup) | |
| - **Sistema de Arquivos**: ext4 | |
| - **Método de Acesso**: Criptografia baseada em senha | |
| ## Como Usar | |
| 1. Use o Guardião dos Mythos ou as ferramentas do cryptsetup para abrir este | |
| contêiner. | |
| 2. Lembre-se de fechar/selar corretamente o contêiner após o uso. | |
| ## Notas de Segurança | |
| - Mantenha sua senha protegida. A segurança dos seus dados depende de manter sua | |
| senha em sigilo. | |
| - Sempre feche/sele o contêiner quando não estiver em uso. | |
| - Considere fazer cópias de segurança dos arquivos importantes armazenados aqui. | |
| - O próprio arquivo do contêiner deve ser armazenado em um local seguro. | |
| ## Sobre | |
| Criei esta interface gráfica apenas como um exercício divertido para simplificar | |
| o básico da criação e do gerenciamento de contêineres criptografados. | |
| Ela abrange os comandos essenciais de criação, abertura e fechamento presentes | |
| no cryptsetup. Se você precisar de uma interface mais completa, recomendo o | |
| "Tomb, the Crypto Undertaker" <https://www.dyne.org/software/tomb>. | |
| Como esta é uma interface para o cryptsetup, você pode utilizar todos os | |
| comandos do cryptsetup para gerenciar este contêiner, incluindo aqueles não | |
| abrangidos por esta ferramenta, como "luksAddKey" e outros. | |
| A extensão ".tome" é arbitrária e poderia ser substituída por ".img" ou qualquer | |
| outra extensão. | |
| ## Explicando a Piada | |
| Os nomes seguem um tema inspirado em Cthulhu e Lovecraft: | |
| - "Guardião dos Mythos" faz alusão tanto ao Mestre de Jogo quanto aos Mythos de | |
| Cthulhu no RPG Chamado de Cthulhu da Chaosium. | |
| - Um "tomo" é um antigo livro de feitiços e conhecimento arcano. | |
| - A senha é um "feitiço secreto". | |
| - O arquivo-chave é um "item mágico". | |
| - Digitar a senha é "conjurar o feitiço" para abrir o tomo selado magicamente. | |
| - "Selar" o tomo significa desmontá-lo e fechá-lo (criptografando-o novamente). | |
| Que seus segredos permaneçam para sempre ocultos de olhos curiosos! | |
| EOF | |
| ) | |
| else | |
| str_programname="Keeper of Mythos" | |
| str_super="Superuser Privileges Required" | |
| str_super_authcancel="Authentication canceled." | |
| str_super_authsuccess="Authentication successful!" | |
| str_super_wrongpwd="Incorrect password. Remaining attempts:" | |
| str_super_attemptsexceed="Maximum attempts exceeded." | |
| str_progress="Inscribing arcane seals... Please wait." | |
| str_createimg="Scribe Tome" | |
| str_createimg_size="Tome Size" | |
| str_createimg_entersize="Enter tome size (e.g. 50M, 2G):" | |
| str_createimg_pwd="Inscribe a Secret Spell" | |
| str_createimg_success="Tome created successfully." | |
| str_authmethod="Authentication method:" | |
| str_authmethod_pass="Secret Spell (password)" | |
| str_authmethod_keyfile="Magic Item (key file)" | |
| str_keyfile_select="Select the $str_authmethod_keyfile" | |
| str_keyfile_invalid="Invalid key file or no read permission." | |
| str_createkey="Craft Magic Item" | |
| str_magicitem_succ="Magic Item created in:" | |
| str_magicitem_fail="Failed to create Magic Item. Check permissions." | |
| str_mount="Open Tome" | |
| str_mount_pwd="Cast Secret Spell" | |
| str_mount_success_1="Tome opened as:" | |
| str_mount_success_2="and mounted as:" | |
| str_mount_fail="Failed to open tome. Wrong spell?" | |
| str_umount_nonemounted="There are no open tomes." | |
| str_umount="Seal Tome" | |
| str_umount_select="Select a tome to close:" | |
| str_umount_listmounted="Open Tomes" | |
| str_umount_umounted="Tome sealed." | |
| str_menu="Choose an action:" | |
| str_menu_action="Action" | |
| readme=$(cat <<'EOF' | |
| # Keeper of Mythos | |
| # Copyright (c) 2025 Daniel Dias Rodrigues. No rights reserved. | |
| # | |
| # This program is free software; you can redistribute it and/or modify it under | |
| # the terms of the Creative Commons Zero 1.0 Universal (CC0 1.0) Public Domain | |
| # Dedication (https://creativecommons.org/publicdomain/zero/1.0/). | |
| Welcome to your Tome of Arcane Lore! | |
| This secure storage space was created using Keeper of Mythos, a graphical | |
| frontend for managing encrypted containers on Linux. | |
| ## What is this? | |
| This is an encrypted, rewritable disk image file that functions as a secure | |
| digital vault. You can store confidential files, documents, or any data you wish | |
| to keep secret. | |
| ## Technical Details | |
| - **Encryption**: LUKS2 (Linux Unified Key Setup) | |
| - **File System**: ext4 | |
| - **Access Method**: Password-based encryption | |
| ## How to Use | |
| 1. Use Keeper of Mythos or cryptsetup tools to open this container | |
| 2. Remember to properly close/seal the container after use | |
| ## Security Notes | |
| - Keep your password safe and secure. The security of your data depends on | |
| keeping your password confidential. | |
| - Always close/seal the container when not in use. | |
| - Consider backing up important files stored here. | |
| - The container file itself should be stored in a safe location. | |
| ## About | |
| I created this frontend purely as a fun exercise to simplify the basics of | |
| creating and managing encrypted containers. | |
| It covers the essential creation, opening, and closing commands present in | |
| cryptsetup. If you need a more capable frontend, I recommend "Tomb, the Crypto | |
| Undertaker" <https://www.dyne.org/software/tomb>. | |
| Since this is a frontend for cryptsetup, you can use all cryptsetup commands to | |
| manage this container, including those not covered in this tool, such as | |
| "luksAddKey" and others. | |
| The ".tome" extension is arbitrary and could be replaced with \".img\" or any | |
| other extension. | |
| ## The Joke Explained | |
| The names follow a Cthulhu/Lovecraftian theme: | |
| - "Keeper of Mythos" alludes both to the Game Master and to Cthulhu Mythos in | |
| Chaosium's Call of Cthulhu RPG. | |
| - A "tome" is an ancient book of spells and arcane knowledge. | |
| - The password is a "secret spell". | |
| - The key file is a "magic item". | |
| - Entering the password is "casting the spell" to open the magically sealed | |
| tome. | |
| - "Sealing" the tome means unmounting and closing (re-encrypting) it. | |
| May your secrets remain forever hidden from prying eyes! | |
| EOF | |
| ) | |
| fi | |
| authenticate_sudo() { | |
| local password attempts=0 max_attempts=3 | |
| while [ $attempts -lt $max_attempts ]; do | |
| password=$(zenity --password --title="$str_super") || { zenity --error --text="$str_super_authcancel"; exit 1; } | |
| [ -z "$password" ] && { zenity --error --text="$str_super_authcancel"; exit 1; } | |
| if echo "$password" | sudo -S -v 2>/dev/null; then | |
| ( while true; do sleep 60; sudo -n true 2>/dev/null || break; done ) & | |
| zenity --info --text="$str_super_authsuccess" --timeout=2 | |
| return 0 | |
| else | |
| attempts=$((attempts + 1)) | |
| remaining=$((max_attempts - attempts)) | |
| if [ "$remaining" -gt 0 ]; then | |
| zenity --error --text="$str_super_wrongpwd $remaining" | |
| else | |
| zenity --error --text="$str_super_attemptsexceed" | |
| exit 1 | |
| fi | |
| fi | |
| done | |
| } | |
| show_progress() { | |
| PROGRESS_FIFO=$(mktemp -u) | |
| mkfifo "$PROGRESS_FIFO" | |
| zenity --progress --title="$str_programname" \ | |
| --text="$str_progress" \ | |
| --pulsate --auto-close --no-cancel < "$PROGRESS_FIFO" & | |
| PROGRESS_PID=$! | |
| exec 3>"$PROGRESS_FIFO" | |
| sleep 0.2 | |
| } | |
| kill_progress() { | |
| exec 3>&- | |
| wait "$PROGRESS_PID" 2>/dev/null | |
| rm -f "$PROGRESS_FIFO" | |
| } | |
| generate_mapper_name() { | |
| local base mapper n | |
| base=$(basename "$1") | |
| base="${base%.*}" | |
| base=$(echo "$base" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g') | |
| mapper="tome-$base" | |
| n=1 | |
| while [ -e "/dev/mapper/$mapper" ]; do | |
| mapper="tome-$base-$n" | |
| n=$((n+1)) | |
| done | |
| echo "$mapper" | |
| } | |
| scribe_tome() { | |
| local file size auth_method pass keyfile key_arg | |
| file=$(zenity --file-selection --save --title="$str_createimg") | |
| [ -z "$file" ] && return | |
| size=$(zenity --entry --title="$str_createimg_size" --text="$str_createimg_entersize") | |
| [ -z "$size" ] && return | |
| auth_method=$(zenity --list --title="$str_createimg" \ | |
| --text="$str_authmethod" \ | |
| --radiolist --column="" --column="" \ | |
| TRUE "$str_authmethod_pass" \ | |
| FALSE "$str_authmethod_keyfile") | |
| [ -z "$auth_method" ] && return | |
| if [ "$auth_method" = "$str_authmethod_pass" ]; then | |
| pass=$(zenity --password --title="$str_createimg_pwd") | |
| [ -z "$pass" ] && return | |
| else | |
| keyfile=$(zenity --file-selection --title="$str_keyfile_select") | |
| [ -z "$keyfile" ] && return | |
| [ -r "$keyfile" ] || { zenity --error --text="$str_keyfile_invalid"; return; } | |
| fi | |
| show_progress | |
| truncate -s "$size" "$file" | |
| if [ "$auth_method" = "$str_authmethod_pass" ]; then | |
| echo -n "$pass" | sudo -S cryptsetup --batch-mode --key-file=- luksFormat --type luks2 "$file" | |
| echo -n "$pass" | sudo -S cryptsetup --batch-mode --key-file=- open "$file" tome_tmp | |
| else | |
| sudo cryptsetup --batch-mode --key-file="$keyfile" luksFormat --type luks2 "$file" | |
| sudo cryptsetup --batch-mode --key-file="$keyfile" open "$file" tome_tmp | |
| fi | |
| sudo mkfs.ext4 /dev/mapper/tome_tmp | |
| sudo mkdir -p /mnt/tome_tmp | |
| sudo mount /dev/mapper/tome_tmp /mnt/tome_tmp | |
| sudo chown "$USER": /mnt/tome_tmp | |
| echo "$readme" > /mnt/tome_tmp/README.txt | |
| sudo umount /mnt/tome_tmp | |
| sudo rm -rf /mnt/tome_tmp | |
| sudo cryptsetup close tome_tmp | |
| kill_progress | |
| zenity --info --title="$str_programname" --text="$str_createimg_success" | |
| } | |
| magic_item(){ | |
| local file success test1 | |
| file=$(zenity --file-selection --save --title="$str_createkey") | |
| [ -z "$file" ] && return | |
| dd if=/dev/urandom of="$file" bs=512 count=4 | |
| success=$? | |
| if [ $success -eq 0 ] && [ -n "$file" ]; then | |
| chmod 400 "$file" | |
| zenity --info --title="$str_createkey" --text="$str_magicitem_succ\n$file" | |
| else | |
| zenity --info --title="$str_createkey" --text="$str_magicitem_fail" | |
| fi | |
| } | |
| open_tome() { | |
| local file mapper auth_method pass keyfile success | |
| file=$(zenity --file-selection --title="$str_mount") | |
| [ -z "$file" ] && return | |
| mapper=$(generate_mapper_name "$file") | |
| auth_method=$(zenity --list --title="$str_mount" \ | |
| --text="$str_authmethod" \ | |
| --radiolist --column="" --column="" \ | |
| TRUE "$str_authmethod_pass" \ | |
| FALSE "$str_authmethod_keyfile") | |
| [ -z "$auth_method" ] && return | |
| if [ "$auth_method" = "$str_authmethod_pass" ]; then | |
| pass=$(zenity --password --title="$str_mount_pwd") | |
| [ -z "$pass" ] && return | |
| echo -n "$pass" | sudo cryptsetup --batch-mode --key-file=- open "$file" "$mapper" | |
| else | |
| keyfile=$(zenity --file-selection --title="$str_keyfile_select") | |
| [ -z "$keyfile" ] && return | |
| [ -r "$keyfile" ] || { zenity --error --text="$str_keyfile_invalid"; return; } | |
| sudo cryptsetup --batch-mode --key-file="$keyfile" open "$file" "$mapper" | |
| fi | |
| success=$? | |
| if [ $success -eq 0 ]; then | |
| sudo mkdir -p /mnt/"$mapper" | |
| sudo mount /dev/mapper/"$mapper" /mnt/"$mapper" | |
| zenity --info --title="$str_programname" --text="$str_mount_success_1\n /dev/mapper/$mapper\n$str_mount_success_2\n /mnt/$mapper" | |
| else | |
| zenity --error --title="$str_programname" --text="$str_mount_fail" | |
| fi | |
| } | |
| seal_tome() { | |
| local list=() choice f | |
| for f in /dev/mapper/tome-*; do | |
| [ -e "$f" ] && list+=("$(basename "$f")") | |
| done | |
| [ ${#list[@]} -eq 0 ] && { zenity --info --title="$str_programname" --text="$str_umount_nonemounted"; return; } | |
| choice=$(zenity --list --title="$str_umount" --text="$str_umount_select" --column="$str_umount_listmounted" "${list[@]}") | |
| [ -z "$choice" ] && return | |
| sudo umount /mnt/"$choice" | |
| sudo rm -rf /mnt/"$choice" | |
| sudo cryptsetup close "$choice" | |
| zenity --info --title="$str_programname" --text="$str_umount_umounted" | |
| } | |
| main_menu() { | |
| local choice | |
| while true; do | |
| choice=$(zenity --list --height="332" --title="$str_programname" --text="$str_menu" \ | |
| --column="$str_menu_action" "$str_createimg" "$str_createkey" "$str_mount" "$str_umount") | |
| [ -z "$choice" ] && exit 0 | |
| case "$choice" in | |
| "$str_createimg") scribe_tome ;; | |
| "$str_createkey") magic_item ;; | |
| "$str_mount") open_tome ;; | |
| "$str_umount") seal_tome ;; | |
| esac | |
| done | |
| } | |
| authenticate_sudo | |
| main_menu |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Suggestion of
keeper.desktop. ReplaceYOUR_USERby your user's path. Save in~/.local/share/applications.Choose any icon you wish. I use this one:
