====== Intro ====== mailcow compress and encrypt mail stored inside the "mailcowdockerized_vmail-vol-1" docker volume. [[https://docs.mailcow.email/manual-guides/Dovecot/u_e-dovecot-mail-crypt/|The documentation]] has a description on how you decrypt or re-encrypt the mail files inside the volume. This requires that you enter the dovecot container and paste the logic. That is rather cumbersome, so here is a bash script which you can run from anywhere which takes care of that. ===== Script Which Takes It All ===== It take two flags "-d" for decryption and "-e" for encryption, which needs to be supplied when you run it. #!/bin/bash # Define the path inside the container CONTAINER_PATH="/tmp/mail_crypt_tool.sh" DOCKER_COMPOSE_FILE="/opt/mailcow-dockerized/docker-compose.yml" # Function to decrypt files decrypt_files() { find /var/vmail/ -type f -regextype egrep -regex '.*S=.*W=.*' | while read -r file; do if [[ $(head -c7 "$file") == "CRYPTED" ]]; then doveadm fs get compress lz4:1:crypt:private_key_path=/mail_crypt/ecprivkey.pem:public_key_path=/mail_crypt/ecpubkey.pem:posix:prefix=/ \ "$file" > "/tmp/$(basename "$file")" if [[ -s "/tmp/$(basename "$file")" ]]; then chmod 600 "/tmp/$(basename "$file")" chown 5000:5000 "/tmp/$(basename "$file")" mv "/tmp/$(basename "$file")" "$file" else rm "/tmp/$(basename "$file")" fi fi done } # Function to encrypt files encrypt_files() { find /var/vmail/ -type f -regextype egrep -regex '.*S=.*W=.*' | while read -r file; do if [[ $(head -c7 "$file") != "CRYPTED" ]]; then doveadm fs put crypt private_key_path=/mail_crypt/ecprivkey.pem:public_key_path=/mail_crypt/ecpubkey.pem:posix:prefix=/ \ "$file" "$file" chmod 600 "$file" chown 5000:5000 "$file" fi done } # Function to print help print_help() { echo "Usage: $0 [OPTIONS]" echo "Options:" echo " -d Decrypt files in /var/vmail" echo " -e Encrypt files in /var/vmail" echo " -h Display this help message" } # Check if we're inside a Docker container if [ -f /.dockerenv ]; then # We are inside a container, proceed with the main logic main() { case "$1" in -d) decrypt_files ;; -e) encrypt_files ;; *) print_help ;; esac } main "$@" else # We are outside a container, so let's copy and execute the script inside the container docker compose -f $DOCKER_COMPOSE_FILE cp $0 dovecot-mailcow:$CONTAINER_PATH docker compose -f $DOCKER_COMPOSE_FILE exec -T dovecot-mailcow chmod +x $CONTAINER_PATH docker compose -f $DOCKER_COMPOSE_FILE exec -T dovecot-mailcow $CONTAINER_PATH "$@" fi ===== Script Which Takes One Mailbox At a Time ===== #!/bin/bash # Define the path inside the container CONTAINER_PATH="/tmp/mail_crypt_tool.sh" DOCKER_COMPOSE_FILE="/opt/mailcow-dockerized/docker-compose.yml" decrypt_files() { local mailbox_path="$1" find "$mailbox_path" -type f -regextype egrep -regex '.*S=.*W=.*' | while read -r file; do if [[ $(head -c7 "$file") == "CRYPTED" ]]; then doveadm fs get compress lz4:1:crypt:private_key_path=/mail_crypt/ecprivkey.pem:public_key_path=/mail_crypt/ecpubkey.pem:posix:prefix=/ \ "$file" > "/tmp/$(basename "$file")" if [[ -s "/tmp/$(basename "$file")" ]]; then chmod 600 "/tmp/$(basename "$file")" chown 5000:5000 "/tmp/$(basename "$file")" mv "/tmp/$(basename "$file")" "$file" else rm "/tmp/$(basename "$file")" fi fi done } encrypt_files() { local mailbox_path="$1" find "$mailbox_path" -type f -regextype egrep -regex '.*S=.*W=.*' | while read -r file; do if [[ $(head -c7 "$file") != "CRYPTED" ]]; then doveadm fs put crypt private_key_path=/mail_crypt/ecprivkey.pem:public_key_path=/mail_crypt/ecpubkey.pem:posix:prefix=/ \ "$file" "$file" chmod 600 "$file" chown 5000:5000 "$file" fi done } print_help() { echo "Usage: $0 [OPTIONS] [MAILBOX_PATH]" echo "Options:" echo " -d Decrypt specified mailbox or all mailboxes if no path is provided" echo " -e Encrypt specified mailbox or all mailboxes if no path is provided" echo " -h Display this help message" echo "MAILBOX_PATH: Path to the mailbox, format: /var/vmail/domain/user" } # Function to list and select user mailboxes select_mailbox() { local paths=($(find /var/vmail/ -mindepth 2 -maxdepth 2 -type d ! -name ".*")) local mailboxes=() # Convert paths to email format for path in "${paths[@]}"; do local user=$(basename "$path") local domain=$(basename $(dirname "$path")) mailboxes+=("$user@$domain") done select mailbox in "${mailboxes[@]}"; do if [[ -n $mailbox ]]; then # Convert back to path format and return local user=$(echo "$mailbox" | cut -d'@' -f1) local domain=$(echo "$mailbox" | cut -d'@' -f2) echo "/var/vmail/$domain/$user" return else echo "Invalid selection" fi done } # Check if we're inside a Docker container if [ -f /.dockerenv ]; then # We are inside a container, proceed with the main logic main() { local mailbox_path="" if [[ -z "$2" ]]; then echo "Select a mailbox:" mailbox_path=$(select_mailbox) else mailbox_path="$2" fi case "$1" in -d) decrypt_files "$mailbox_path" ;; -e) encrypt_files "$mailbox_path" ;; *) print_help ;; esac } main "$@" else # We are outside a container, so let's copy and execute the script inside the container docker compose -f $DOCKER_COMPOSE_FILE cp $0 dovecot-mailcow:$CONTAINER_PATH docker compose -f $DOCKER_COMPOSE_FILE exec -T dovecot-mailcow chmod +x $CONTAINER_PATH docker compose -f $DOCKER_COMPOSE_FILE exec -T dovecot-mailcow $CONTAINER_PATH "$@" fi