User Tools

Site Tools


howtos:mail_crypt_-_decrypt_encrypt_mails

Intro

mailcow compress and encrypt mail stored inside the “mailcowdockerized_vmail-vol-1” docker volume.

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
howtos/mail_crypt_-_decrypt_encrypt_mails.txt · Last modified: 13/08/2023 15:18 by domingo