Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@ This is a note for developers about the recommended tags to keep track of the ch
Dates must be YEAR-MONTH-DAY
-->

## [v1.2.5] - 2025-09-xx-beta

- Added: rsyslog as a dependency on all OS/versions, as some bare metal server deploys don't have it.
- Added: Support for Debian 13 "trixie", easing the way for Ubuntu 16.04 next year.
- Added: Two more tests about the alias routing feature of postfix to verify it's working properly.
- Changed: On Debian 13, the TLS security is more strict now, so you will need to copy the samba CA cert file from the samba server to the mail server host by hand if the samba server use a self signed cert. Other alternatives are 1- use a valid cert 2- use a non secure connection with the LDAP server.
- Changed: Debian 13 updated the dovecot package from 2.3 to 2.4 so some features changed and the dovecot support was rewrited entirely on MailAD, major issues are the removal of the dovecot mailbox replica and the dovecot cache auth, the new dovecot cache auth is based on the new dovecot auth system and is more secure.
- Changed: APT is made less noisy when installing packages
- Changed: Shell [Bash] code standarization on nested and exit command calls to use just one way.
- Changed: Modern distros has changed spamassassin to spamd as a service name and package, we made changes to support that.
- Fixed: When using multi AD DC setups the uri string construction algorithn was slipping a space and spoiling the whole feature; detected and fixed.
- Fixed: When provisioning some times the auto-backup and restore mechanism was failing [if some features was not activated] and dumping noise over the provision log.

## [v1.2.4] - 2025-06-10

- Changed: Added & improved [AI] translations to major doc/features files in the project
Expand Down
24 changes: 12 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ conf: ## Create a configuration file in /etc/
scripts/conf.sh

clean: ## Clean the environment to have a fresh start (preserve SSL/DH certs in /etc/ssl)
-rm deps conf-check install provision all || exit 0
-rm deps conf-check install provision all || true

reset: clean install-purge ## Reset all configurations and remove/purge all softwares & certificates
-rm certs || exit 0
-rm /etc/ssl/private/mail.key /etc/ssl/certs/mail.crt /etc/ssl/certs/cacert.pem || exit 0
-rm -rdf /etc/dovecot || exit 0
-rm -rdf /etc/postfix || exit 0
-rm certs || true
-rm /etc/ssl/private/mail.key /etc/ssl/certs/mail.crt /etc/ssl/certs/cacert.pem || true
-rm -rdf /etc/dovecot || true
-rm -rdf /etc/postfix || true

deps: ## Install all the needed deps to test & build it
scripts/deps.sh
Expand All @@ -41,9 +41,9 @@ install: conf-check deps certs ## Install all the software from the repository

install-purge: deps ## Uninstall software already installed for MailAD (and purge config also)
scripts/install_purge.sh
rm install || exit 0
rm conf-check || exit 0
rm deps || exit 0
rm install || true
rm conf-check || true
rm deps || true

provision: install ## Provision the server, this will copy over the config files and set the vars
# Check for config upgrades
Expand All @@ -58,8 +58,8 @@ all: provision ## Run all targets logically ordered, run this to make it all

force-provision: ## Force a re-provisioning of the system
# removing the targets files
rm provision || exit 0
rm conf-check || exit 0
rm provision || true
rm conf-check || true
# Check for config upgrades
scripts/confupgrade.sh
# configuration checks
Expand Down Expand Up @@ -104,8 +104,8 @@ samba: ## Scaffold a samba AD-DC for testing, just for testing purposes!
utils/samba_scaffold.sh

purge-backups: ## WARNING, DANGEROUS! this command will erase the backup folder
rm -rdf /var/lib/mailad || exit 0
rm -rdf /var/backups/mailad || exit 0
rm -rdf /var/lib/mailad || true
rm -rdf /var/backups/mailad || true

help:
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# MailAD v1.2.4
# MailAD v1.2.5

[![Chat on Telegram](https://img.shields.io/badge/Chat%20on-Telegram-brightgreen?style=flat-square)](https://t.me/MailAD_dev) [![GitHub Issues](https://img.shields.io/github/issues/stdevPavelmc/mailad?style=flat-square)](https://github.com/stdevPavelmc/mailad/issues) [![GitHub Issues Closed](https://img.shields.io/github/issues-closed/stdevPavelmc/mailad?style=flat-square)](https://github.com/stdevPavelmc/mailad/issues?q=is%3Aissue+is%3Aclosed) [![GitHub repo size](https://img.shields.io/github/repo-size/stdevPavelmc/mailad?style=flat-square)](https://github.com/stdevPavelmc/mailad/archive/master.zip) [![GitHub last commit](https://img.shields.io/github/last-commit/stdevPavelmc/mailad?style=flat-square)](https://github.com/stdevPavelmc/mailad/commits/master) [![GitHub commit rate](https://img.shields.io/github/commit-activity/m/stdevPavelmc/mailad?style=flat-square)](https://github.com/stdevPavelmc/mailad/commits/master) [![Financial contributors](https://opencollective.com/mailad/tiers/badge.svg?style=flat-square)](https://opencollective.com/mailad) [![Develop Testing Status](https://img.shields.io/github/actions/workflow/status/stdevPavelmc/mailad/mailad-tests.yml?branch=develop&label=Develop+Testing+Status&style=flat-square)](https://github.com/stdevPavelmc/mailad/actions/workflows/mailad-tests.yml) [![Production Testing Status](https://img.shields.io/github/actions/workflow/status/stdevPavelmc/mailad/mailad-tests.yml?branch=master&label=Production+Testing+Status&style=flat-square)](https://github.com/stdevPavelmc/mailad/actions/workflows/mailad-tests.yml)

Expand Down Expand Up @@ -26,6 +26,7 @@ The recommended OS selection is as follows:

| OS | Active Support | Legacy | Discontinued |
|:--- |:---:|:---:|:---:|
| Debian Trixie 13 | ✅ | | |
| Ubuntu Noble 24.04 LTS | ✅ | | |
| Debian Bookworm 12 | ✅ | | |
| Ubuntu Jammy 22.04 LTS | | ⚠️ | |
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.2.4
v1.2.5
68 changes: 40 additions & 28 deletions common.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,18 @@
#
# Do not change this unless you know what are you doing!!!

# Load OS metadata
source /etc/os-release

# Author Email
[email protected]

# APT options:
# '-y -qq' for automatic and super quiet installs
# '-y' for noisy but detailed installs
APT_OPTS="-y -qq"
export DEBIAN_FRONTEND=noninteractive

# OS support matrix
# Ubuntu
OS_DISCONTINUED_U=("bionic" "focal")
Expand All @@ -15,7 +24,7 @@ OS_SUPPORTED_U=("noble")
# Debian
OS_DISCONTINUED_D=("buster")
OS_LEGACY_D=("bullseye")
OS_SUPPORTED_D=("bookworm")
OS_SUPPORTED_D=("bookworm" "trixie")
# mix
OS_DISCONTINUED=("${OS_DISCONTINUED_U[@]}" "${OS_DISCONTINUED_D[@]}")
OS_LEGACY=("${OS_LEGACY_U[@]}" "${OS_LEGACY_D[@]}")
Expand All @@ -26,16 +35,23 @@ OS_WORKING_D=("${OS_DISCONTINUED_D[@]}" "${OS_LEGACY_D[@]}" "${OS_SUPPORTED_D[@]
OS_WORKING=("${OS_WORKING_U[@]}" "${OS_WORKING_D[@]}")

# Common deps packages
COMMON_DEPS_PKGS="ldap-utils libldap-common dnsutils netcat-traditional openssl ca-certificates wget"
COMMON_DEPS_PKGS="rsyslog ldap-utils libldap-common dnsutils netcat-traditional openssl ca-certificates wget git"

#### Pkgs to install for Debian Buster & Bullseye (10/11)
DEBIAN_BASE_PKGS="postfix postfix-pcre postfix-ldap dovecot-core dovecot-pop3d dovecot-imapd dovecot-ldap dovecot-sieve dovecot-managesieved libnet-ldap-perl rsync dnsutils pflogsumm mailutils amavisd-new p7zip-full unrar-free cabextract cron"

# Pkgs to install for Ubuntu Bionic & Focal (18.04/20.04)
UBUNTU_BASE_PKGS="postfix postfix-pcre postfix-ldap dovecot-core dovecot-pop3d dovecot-imapd dovecot-ldap dovecot-sieve dovecot-managesieved libnet-ldap-perl rsync dnsutils pflogsumm mailutils amavisd-new-postfix p7zip-full p7zip-rar unrar-free cabextract"

### Spamassassin pkgs
### Spamassassin pkgs [olds by default]
DEBIAN_SPAMD_PKGS="spamassassin"
SPAMD_SERVICENAMES="spamassassin"
case "${VERSION_CODENAME}" in
noble|trixie)
DEBIAN_SPAMD_PKGS="spamd"
SPAMD_SERVICENAMES="spamd"
;;
esac

### Clamav pkgs
DEBIAN_AV_PKGS="clamav-freshclam clamav-daemon"
Expand All @@ -55,24 +71,15 @@ SNAPPY_DIR="/var/www/snappymail"
SERVICENAMES="dovecot postfix amavisd-new"

# but for debian 11 and ubuntu 22.04 and onwards amavisd-new is just "amavis"
NEWEROS=`cat /etc/os-release | grep "^VERSION_CODENAME=" | cut -d "=" -f 2`
case "${NEWEROS}" in
bullseye|jammy|noble|bookworm)
case "${VERSION_CODENAME}" in
bullseye|jammy|noble|bookworm|trixie)
SERVICENAMES="dovecot postfix amavis"
;;
esac

### AV service names
AV_SERVICENAMES="clamav-daemon clamav-freshclam"

### SPAMD service name
# SPAMD_SERVICENAMES=$(systemctl list-units --full -all --no-pager | grep spam | awk '{print $1}' | cut -d '.' -f 1)
SPAMD_SERVICENAMES="spamd" # modern version by default
SPAMD_VERSION=$(dpkg -l spamassassin | grep spam | awk '{print $3}' | cut -d '.' -f 1)
if [ "$SPAMD_VERSION" == "3" ] ; then
SPAMD_SERVICENAMES="spamassassin"
fi

# Get the var names from the config file
VARS=`cat mailad.conf | grep -v "#" | sort -r | uniq | cut -d "=" -f 1`

Expand Down Expand Up @@ -137,7 +144,7 @@ function install_debs {

# Do it
export DEBIAN_FRONTEND=noninteractive
apt-get install $PKGS -yq
apt-get install ${APT_OPTS} $PKGS

# Checking for success
R=$?
Expand Down Expand Up @@ -221,15 +228,15 @@ function craft_pkg_list {
# Remove the pkgs in debian-like distros
function debian_remove_pkgs {
# Add an asterisk at the end of the PKGS to wipe al related packages
P=`echo "$PKGS" | tr ' ' '\n' | sort | uniq | xargs | sed s/" "/"* "/g`
P=$(echo "$PKGS" | tr ' ' '\n' | sort | uniq | xargs | sed s/" "/"* "/g)

# Remove all pkgs letting apt build the tree
# two times to fix problems with postfix-amavis-new
env DEBIAN_FRONTEND=noninteractive apt-get purge $P* -y
env DEBIAN_FRONTEND=noninteractive apt-get purge $P* -y
apt-get purge $P* ${APT_OPTS}
apt-get purge $P* ${APT_OPTS}

# Autoremove some of the pkgs left over
env DEBIAN_FRONTEND=noninteractive apt-get autoremove -y
apt-get autoremove ${APT_OPTS}
}

# Craft the list of services to stop/start/restart, etc
Expand Down Expand Up @@ -310,12 +317,13 @@ function extract() {
}

# Warn about a not supported dovecot version
function devecot_version {
function dovecot_version {
# Just one argument, the dovecot version

echo "==========================================================================="
echo "ERROR: Can't locate the dovecot version or it's a not supported one"
echo " detected version is: '$1' and it must be v2.2 or v 2.3"
echo " detected version is: '$1'"
echo " and it must be v2.2, v2.3 or v2.4 "
echo "==========================================================================="
echo " The install process will stop now, please fix that"
echo "==========================================================================="
Expand All @@ -330,17 +338,17 @@ function disable_av() {
ACTIVE=`systemctl is-active clamav-freshclam`
if [ "$ACTIVE" == "active" ] ; then
# disabling
systemctl stop clamav-freshclam || exit 0
systemctl disable clamav-freshclam || exit 0
systemctl mask clamav-freshclam || exit 0
systemctl stop clamav-freshclam || true
systemctl disable clamav-freshclam || true
systemctl mask clamav-freshclam || true
echo "===> Disabing Clamav-freshclam as requested by the config"
fi
ACTIVE=`systemctl is-active clamav-daemon`
if [ "$ACTIVE" == "active" ] ; then
# disabling
systemctl stop clamav-daemon || exit 0
systemctl disable clamav-daemon || exit 0
systemctl mask clamav-daemon || exit 0
systemctl stop clamav-daemon || true
systemctl disable clamav-daemon || true
systemctl mask clamav-daemon || true
echo "===> Disabing clamav-daemon as requested by the config"
fi
}
Expand Down Expand Up @@ -403,7 +411,11 @@ function get_ldap_uri {
SOUT=""
# Fun start here
for DC in `echo "${HOSTAD}"` ; do
SOUT="${SOUT} ${PROTO}://${DC}:${PORT}"
if [ ! "${SOUT}" ] ; then
SOUT="${PROTO}://${DC}:${PORT}"
else
SOUT="${SOUT} ${PROTO}://${DC}:${PORT}"
fi
done

echo "${SOUT}"
Expand Down
14 changes: 7 additions & 7 deletions scripts/backup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,29 @@ LASTWORKINGBACKUPFILE="${LIBFOLDER}/latest_working_backup"
echo "===> Starting a backup of all actual configs to $BKPFOLDER"

# create the backup folder
mkdir -p ${BKPFOLDER} 2> /dev/null || exit 0
mkdir -p ${LIBFOLDER} 2> /dev/null || exit 0
mkdir -p ${BKPFOLDER} 2> /dev/null || true
mkdir -p ${LIBFOLDER} 2> /dev/null || true

# check if a non ideal backup is left behind
if [ -f "$LASTBACKUPFILE" ] ; then
#use cases
if [ -f "$LASTWORKINGBACKUPFILE" ] ; then
# case one: backup & working backup
# erase it only if points to different files
LAST=`cat "$LASTBACKUPFILE"`
WORKING=`cat "$LASTWORKINGBACKUPFILE"`
LAST=$(cat "$LASTBACKUPFILE")
WORKING=$(cat "$LASTWORKINGBACKUPFILE")
if [ "$LAST" != "$WORKING" ] ; then
# erase the file
rm -f "$LAST" || exit 0
rm -f "$LAST" || true
fi
else
# case two: backup & no working backup, erase the file
rm -f `cat "$LASTBACKUPFILE"` || exit 0
rm -f $(cat "$LASTBACKUPFILE") || true
fi
fi

# create the backup
TIMESTAMP=`date +%Y%m%d_%H%M%S`
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BKPFILE="${BKPFOLDER}/${TIMESTAMP}.tar.gz"
tar -cvzf ${BKPFILE} ${FOLDERS}

Expand Down
8 changes: 4 additions & 4 deletions scripts/check_new_version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ UPSTREAM_VERSION_URL="${REPO_URL}/raw/master/VERSION"
UPSTREAM_VERSION_TMP="/tmp/VERSION"
UPSTREAM_VERSION='v1.0.0'
VERSION='v0.1.0'
MAIL=`mktemp`
MAIL=$(mktemp)

# TODO
# - Add the proxy settings if present, data from /etc/mailad/mailad.conf
Expand Down Expand Up @@ -56,7 +56,7 @@ fi
if [ -f "${CHANGELOG}" ] ; then
# sample:
# ## [v1.0.0] - 2022-09-04 v1.0.0
VERSION=`cat "${CHANGELOG}" | grep "##" | head -n 1 | awk '{print $2}' | tr -d "[]"`
VERSION=$(cat "${CHANGELOG}" | grep "##" | head -n 1 | awk '{print $2}' | tr -d "[]")

# DEBUG
if [ "${DEBUG}" ] ; then
Expand All @@ -70,7 +70,7 @@ fi
# Get upstream version
if wget -q "${UPSTREAM_VERSION_URL}" -O "${UPSTREAM_VERSION_TMP}" ; then
# All fine, got file
UPSTREAM_VERSION=`cat "${UPSTREAM_VERSION_TMP}" | head -n 1`
UPSTREAM_VERSION=$(cat "${UPSTREAM_VERSION_TMP}" | head -n 1)

# DEBUG
if [ "${DEBUG}" ] ; then
Expand All @@ -85,7 +85,7 @@ if wget -q "${UPSTREAM_VERSION_URL}" -O "${UPSTREAM_VERSION_TMP}" ; then
TMPCGL="/tmp/CHANGELOG.md"
rm "${TMPCGL}" 2>/dev/null
wget -q "${REPO_URL}/raw/master/CHANGELOG.md" -O ${TMPCGL}
CHANGES=`diff "${TMPCGL}" "${CHANGELOG}" | sed s/"^< "/''/g | egrep -v -E -i '^.{1,3},.{1,3}d.{1,3}'`
CHANGES=$(diff "${TMPCGL}" "${CHANGELOG}" | sed s/"^< "/''/g | egrep -v -E -i '^.{1,3},.{1,3}d.{1,3}')

# output message
echo "Hi there" > ${MAIL}
Expand Down
3 changes: 3 additions & 0 deletions scripts/clamav_handle.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
# - If you pass a 'backup' argument then create a backup file
# - If you pass a 'restore' argument then restore the backup data

# do nothing if no freshclam present
if [ ! -f /etc/clamav/freshclam.conf ] ; then exit 0 ; fi

# vars:
DBDIR=$(grep DatabaseDirectory /etc/clamav/freshclam.conf | awk '{print $2}')
BKPFILE='/tmp/clamavbkp.tar'
Expand Down
2 changes: 1 addition & 1 deletion scripts/conf.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function make_it {

# doit!
cp mailad.conf /etc/mailad/
rm /tmp/conf-already 2>/dev/null || exit 0
rm /tmp/conf-already 2>/dev/null || true
}

# Check if there is a MailAD config there
Expand Down
6 changes: 3 additions & 3 deletions scripts/confupgrade.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# - Warn the user about a new features or config var he need to know

# Get all the vars
CONVARS=`cat /etc/mailad/mailad.conf | grep -v "#" | grep "=" | cut -d "=" -f 1 | tr '\n' ' '`
CONVARS=$(cat /etc/mailad/mailad.conf | grep -v "#" | grep "=" | cut -d "=" -f 1 | tr '\n' ' ')

# load the actual confver
source ./mailad.conf
Expand All @@ -35,14 +35,14 @@ echo "===> Different versions of config file, doing upgrade"
CONFVER=$NCONFVER

# backup the actual config with a timestamp
TS=`date +"%Y%m%d_%H%M%S"`
TS=$(date +"%Y%m%d_%H%M%S")
cp /etc/mailad/mailad.conf /etc/mailad/mailad.conf_$TS

# create a target file to work with
cat mailad.conf > /etc/mailad/mailad.conf

# loop in the options and switch them as needed
for O in `echo $CONVARS | xargs` ; do
for O in $(echo $CONVARS | xargs) ; do
# get the raw content of the var
Vr=${!O}
# excape possibles / in the string
Expand Down
2 changes: 1 addition & 1 deletion scripts/custom_restore.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ echo "===> Starting a selective restore of custom data"
# check if the last backup file exist
if [ -f "${LASTWORKINGBACKUPFILE}" ] ; then
# check if the content exist
BKPFILE=`cat ${LASTWORKINGBACKUPFILE}`
BKPFILE=$(cat ${LASTWORKINGBACKUPFILE})

if [ ! -f "${BKPFILE}" ] ; then
# backup trace there but no backup?
Expand Down
Loading