diff --git a/README.md b/README.md index 0deed7b..62df3fe 100644 --- a/README.md +++ b/README.md @@ -5,43 +5,66 @@ Héberger sa boîte mail sur son serveur grâce à [Docker Mail Server](https:// ## PRE REQUIS :paperclip: - Docker + compose plugin +- Certbot - Nom de domaine (ici exemple.com) -- Le port 25 ouvert par son FAI (pas Free !) +- Les ports 25, 143, 465, 587 et 993 ouverts +- Le port 25 ouvert en traffic sortant (Voir avec son FAI) + +:warning: **Les FAIs ferme le port 25 sortant sur les boxs** ## CONFIGURER :wrench: -#### DNS - -- mailserver.env -```env -MAIL_DNS=mail.exemple.com -POSTMASTER_ADDRESS= -``` +#### CREATION DES DNS RECORDS - Créer les DNS suivant: - - A record: + 1. `A` record: ``` # mail.exemple.com point sur mail 10800 IN A ``` - - MX record: + 2. `MX` record: ``` # ne pas oublier le point à la fin !!! @ 10800 IN MX 10 mail.exemple.com. ``` - - TXT record (ancien SPF deprécié): + 3. `TXT` record (ancien SPF deprécié): ``` @ 10800 IN TXT "v=spf1 ip4: ~all" ``` - - TXT record (DMARC) + 4. `TXT` record (DMARC) ``` _dmarc 10800 IN TXT "v=DMARC1; p=quarantine; sp=reject; rua=mailto:reports@exemple.com; ruf=mailto:forensics@xemple.com; fo=1" ``` - - CNAME record (autodiscover conf du server) + 5. `CNAME` record (autodiscover conf du server) ``` autodiscover 10800 IN CNAME mail.exemple.com ``` -#### ENVS + 6. `TXT` record for DKIM (pour mail.example.com après création de clefs DKIM): + ``` + mail._domainkey 10800 IN TXT "v=DKIM1; h=sha256; k=rsa; p=" + ``` +#### ENVS :mag: + +- mailserver.env: +```env +MAIL_DNS=mail.exemple.com +POSTMASTER_ADDRESS=postmaster@exemple.com +``` + +#### CREATION DES CERTIFICATS SSL ::page_with_curl: + +- Création des certifs via certbot: +```bash +sudo certbot certonly -d mail.exemple.com +``` + +- Copie des certificats pour DMS: +```bash +mkdir -p docker-data/certbot/certs/ +sudo cp -r /etc/letsencrypt/live/exemple.com/ docker-data/certbot/certs/ +``` + +#### CREATION BOITE MAIL + CLEFS DKIM :email: :key: - Lancer la stack: ```bash @@ -50,15 +73,20 @@ docker compose up -d - Créer une adresse mail: ```bash - +docker exec -it setup email add user@exemple.com ``` -- Créer les clefs DKIM: +- Créer un alias: ```bash - +docker exec -ti setup alias add postmaster@exemple.com user@exemple.com ``` -- Reporter les datas dans un +- Créer les clefs `DKIM`: +```bash +docker exec -it setup config dkim keysize 1024 +``` + +- Reporter les datas entre () au niveau de `p=""` dans un `TXT` record (**voir étape 6 de la création des DNS records**) Relancer la stack pour valider l'usage des clefs DKIM: ```bash @@ -67,5 +95,8 @@ docker compose down && docker compose up -d ## DOCUMENTATION :books: -- [DNS]() -- [DMS](https://docker-mailserver.github.io/docker-mailserver/latest/usage/) \ No newline at end of file +- [DMS](https://docker-mailserver.github.io/docker-mailserver/latest/usage/) + +## TO DO :bookmark_tabs: + +- [ ] Automate certbot renew \ No newline at end of file diff --git a/setup.sh b/setup.sh deleted file mode 100644 index 6e6168d..0000000 --- a/setup.sh +++ /dev/null @@ -1,201 +0,0 @@ -#!/bin/bash - -# version v1.0.0 -# executed manually / via Make -# task wrapper for various setup scripts - -CONFIG_PATH= -CONTAINER_NAME= -CRI= -DEFAULT_CONFIG_PATH= -DESIRED_CONFIG_PATH= -DIR=$(pwd) -DMS_CONFIG='/tmp/docker-mailserver' -IMAGE_NAME= -DEFAULT_IMAGE_NAME='ghcr.io/docker-mailserver/docker-mailserver:latest' -INFO= -PODMAN_ROOTLESS=false -USE_SELINUX= -USE_TTY= -VOLUME= - -WHITE=$(echo -ne '\e[37m') -ORANGE=$(echo -ne '\e[38;5;214m') -LBLUE=$(echo -ne '\e[94m') -RESET=$(echo -ne '\e[0m') - -set -euEo pipefail -shopt -s inherit_errexit 2>/dev/null || true - -function _show_local_usage() { - # shellcheck disable=SC2059 - printf '%s' "${ORANGE}OPTIONS${RESET} - ${LBLUE}Config path, container or image adjustments${RESET} - -i IMAGE_NAME - Provides the name of the 'docker-mailserver' image. The default value is - '${WHITE}${DEFAULT_IMAGE_NAME}${RESET}' - - -c CONTAINER_NAME - Provides the name of the running container. - - -p PATH - Provides the local path of the config folder to the temporary container instance. - Does not work if an existing a 'docker-mailserver' container is already running. - - ${LBLUE}SELinux${RESET} - -z - Allows container access to the bind mount content that is shared among - multiple containers on a SELinux-enabled host. - - -Z - Allows container access to the bind mount content that is private and - unshared with other containers on a SELinux-enabled host. - - ${LBLUE}Podman${RESET} - -R - Accept running in Podman rootless mode. Ignored when using Docker / Docker Compose. - -" - - [[ ${1:-} == 'no-exit' ]] && return 0 - - # shellcheck disable=SC2059 - printf '%s' "${ORANGE}EXIT STATUS${RESET} - Exit status is 0 if the command was successful. If there was an unexpected error, an error - message is shown describing the error. In case of an error, the script will exit with exit - status 1. - -" -} - -function _get_absolute_script_directory() { - if dirname "$(readlink -f "${0}")" &>/dev/null; then - DIR=$(dirname "$(readlink -f "${0}")") - elif realpath -e -L "${0}" &>/dev/null; then - DIR=$(realpath -e -L "${0}") - DIR="${DIR%/setup.sh}" - fi -} - -function _set_default_config_path() { - if [[ -d "${DIR}/config" ]]; then - # legacy path (pre v10.2.0) - DEFAULT_CONFIG_PATH="${DIR}/config" - else - DEFAULT_CONFIG_PATH="${DIR}/docker-data/dms/config" - fi -} - -function _handle_config_path() { - if [[ -z ${DESIRED_CONFIG_PATH} ]]; then - # no desired config path - if [[ -n ${CONTAINER_NAME} ]]; then - VOLUME=$(${CRI} inspect "${CONTAINER_NAME}" \ - --format="{{range .Mounts}}{{ println .Source .Destination}}{{end}}" | \ - grep "${DMS_CONFIG}$" 2>/dev/null || :) - fi - - if [[ -n ${VOLUME} ]]; then - CONFIG_PATH=$(echo "${VOLUME}" | awk '{print $1}') - fi - - if [[ -z ${CONFIG_PATH} ]]; then - CONFIG_PATH=${DEFAULT_CONFIG_PATH} - fi - else - CONFIG_PATH=${DESIRED_CONFIG_PATH} - fi -} - -function _run_in_new_container() { - # start temporary container with specified image - if ! ${CRI} history -q "${IMAGE_NAME}" &>/dev/null; then - echo "Image '${IMAGE_NAME}' not found. Pulling ..." - ${CRI} pull "${IMAGE_NAME}" - fi - - ${CRI} run --rm "${USE_TTY}" \ - -v "${CONFIG_PATH}:${DMS_CONFIG}${USE_SELINUX}" \ - "${IMAGE_NAME}" "${@}" -} - -function _main() { - _get_absolute_script_directory - _set_default_config_path - - local OPTIND - while getopts ":c:i:p:zZR" OPT; do - case ${OPT} in - ( i ) IMAGE_NAME="${OPTARG}" ;; - ( z | Z ) USE_SELINUX=":${OPT}" ;; - ( c ) CONTAINER_NAME="${OPTARG}" ;; - ( R ) PODMAN_ROOTLESS=true ;; - ( p ) - case "${OPTARG}" in - ( /* ) DESIRED_CONFIG_PATH="${OPTARG}" ;; - ( * ) DESIRED_CONFIG_PATH="${DIR}/${OPTARG}" ;; - esac - - if [[ ! -d ${DESIRED_CONFIG_PATH} ]]; then - echo "Specified directory '${DESIRED_CONFIG_PATH}' doesn't exist" >&2 - exit 1 - fi - ;; - - ( * ) - echo "Invalid option: '-${OPTARG}'" >&2 - echo -e "Use './setup.sh help' to get a complete overview.\n" >&2 - _show_local_usage 'no-exit' - exit 1 - ;; - - esac - done - shift $(( OPTIND - 1 )) - - if command -v docker &>/dev/null; then - CRI=docker - elif command -v podman &>/dev/null; then - CRI=podman - if ! ${PODMAN_ROOTLESS} && [[ ${EUID} -ne 0 ]]; then - read -r -p "You are running Podman in rootless mode. Continue? [Y/n] " - [[ -n ${REPLY} ]] && [[ ${REPLY} =~ (n|N) ]] && exit 0 - fi - else - echo 'No supported Container Runtime Interface detected.' - exit 1 - fi - - INFO=$(${CRI} ps --no-trunc --format "{{.Image}};{{.Names}}" --filter \ - label=org.opencontainers.image.title="docker-mailserver" | tail -1) - - [[ -z ${CONTAINER_NAME} ]] && CONTAINER_NAME=${INFO#*;} - [[ -z ${IMAGE_NAME} ]] && IMAGE_NAME=${INFO%;*} - if [[ -z ${IMAGE_NAME} ]]; then - IMAGE_NAME=${NAME:-${DEFAULT_IMAGE_NAME}} - fi - - if test -t 0; then - USE_TTY="-it" - else - # GitHub Actions will fail (or really anything else - # lacking an interactive tty) if we don't set a - # value here; "-t" alone works for these cases. - USE_TTY="-t" - fi - - _handle_config_path - - if [[ -n ${CONTAINER_NAME} ]]; then - ${CRI} exec "${USE_TTY}" "${CONTAINER_NAME}" setup "${@}" - else - _run_in_new_container setup "${@}" - fi - - [[ ${1:-} == 'help' ]] && _show_local_usage - - return 0 -} - -[[ -z ${1:-} ]] && set 'help' -_main "${@}" \ No newline at end of file