Compare commits

...

31 Commits

Author SHA1 Message Date
b32555f66c install_update_dovecot-2.4.sh: fix error writing (mysql) 'auth-sql.conf.ext' file. 2026-01-21 01:43:01 +01:00
e3c2df0f3b README.install: a minor change. 2026-01-11 00:42:08 +01:00
2f3e513f04 Merge branch 'master' of https://git.oopen.de/install/mailsystem 2026-01-10 14:46:44 +01:00
876fae3364 install_postfixadmin.sh: dovecot changed quota: ist now determined directly from filesystem. this isn't supported ba postfixadmin - so disable quota view for mailboxes. 2026-01-10 14:46:11 +01:00
3032337c7d Provide systemd.pc wrapper so pkg-config exposes systemdsystemunitdir. 2026-01-09 21:46:13 +01:00
4240bc3b14 install_amavis.sh: remoce deprecated parameter disable_dns_lookups for transport 'amavisfeed'. 2026-01-08 13:55:22 +01:00
14fc0b0578 Merge branch 'master' of git.oopen.de:install/mailsystem 2026-01-08 13:50:07 +01:00
6a827cba44 install_postfix_advanced.sh,install_postfix_base.sh: comment deprecated parameter 'smtpd_tls_dh1024_param_file'. 2026-01-08 13:49:40 +01:00
0ec563bb3c Merge branch 'master' of https://git.oopen.de/install/mailsystem 2026-01-07 01:59:52 +01:00
027930ae6e install_opendmarc.sh: adjust writing milter directives to postfix's main.cf. 2026-01-07 01:59:36 +01:00
20da412413 install_opendkim.sh: adjust writing milter directives to postfix's main.cf. 2026-01-07 01:59:22 +01:00
e829868645 install_opendkim.sh: move FQHN from '/etc/opendkim/trusted'. 2026-01-07 01:53:46 +01:00
5b853a26cb Backup old (Post-Queue setting) installation scripts. 2026-01-07 00:14:36 +01:00
cd39cb98b8 install_amavis.sh: change to 'Post-Queue' setting. 2026-01-07 00:13:13 +01:00
b09baa144c install_opendmarc.sh: forgot changing also master.cf. 2026-01-07 00:12:17 +01:00
f0921f8669 install_opendkim.sh: forgot changing also master.cf. 2026-01-07 00:12:02 +01:00
548c4015e8 Merge branch 'master' of https://git.oopen.de/install/mailsystem 2026-01-06 23:22:30 +01:00
e91c9f1b04 install_opendmarc.sh: adjust konfiguration. 2026-01-06 23:21:58 +01:00
4bb27992d8 install_opendkim.sh: adjust konfiguration. 2026-01-06 23:21:08 +01:00
4360717cfe install_amavis.sh: forgot 'fi' - fixed. 2026-01-05 01:06:31 +01:00
59488b9065 install_postfix_advanced.sh: add support for debian 13 systems. 2026-01-04 23:16:04 +01:00
fdd17790f6 Do not install DMARC Report support on mail relay systems. 2026-01-04 23:15:23 +01:00
50bc28dc2a install_update_dovecot-2.4.sh: support english language in qota warn messages. 2025-12-20 23:55:57 +01:00
b87793cbad Fis systemd support on debian system version 13 (trixie) or newer. 2025-12-15 01:23:16 +01:00
Christoph
cc155c578a install_amavis.sh: fix error in creating master.cf if aditional port is used. 2025-12-10 02:13:58 +01:00
b28b3a8316 install_update_dovecot-2.4.sh: adjust sieve configuration. 2025-12-09 17:49:41 +01:00
ecfd630612 install_amavis.sh: no warn messages from amavis to admin. 2025-12-09 13:50:52 +01:00
68d2bd18b7 install_amavis.sh: some minor changes. 2025-12-09 00:01:31 +01:00
Christoph
6521b03aa2 install_amavis.sh: adjust printing master.cf. 2025-12-08 23:44:29 +01:00
05723c0514 Merge branch 'master' of https://git.oopen.de/install/mailsystem 2025-12-08 19:26:34 +01:00
32b3c8b01e install_update_dovecot-2.4.sh: some minor changes. 2025-12-08 19:25:46 +01:00
20 changed files with 7701 additions and 362 deletions

5297
BAK/install_amavis.sh.Pre-Queue.00 Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,684 @@
#!/usr/bin/env bash
clear
echo -e "\n \033[32mStart Installation of OpenDKIM..\033[m"
# -------------
# - Settings
# -------------
#_src_base_dir="$(realpath $(dirname $0))"
#conf_file="${_src_base_dir}/conf/install_opendkim.conf"
log_file="$(mktemp)"
backup_date="$(date +%Y-%m-%d-%H%M)"
_opendkim_packages="opendkim opendkim-tools"
opendkim_base_dir="/etc/opendkim"
opendkim_key_dir="${opendkim_base_dir}/keys"
opendkim_conf_file="/etc/opendkim.conf"
postfix_spool_dir="/var/spool/postfix"
opendkim_socket_dir="${postfix_spool_dir}/opendkim"
opendkim_socket_file="${opendkim_socket_dir}/opendkim.sock"
postfix_needs_restart=false
opendkim_needs_restart=false
# -------------
# --- Some functions
# -------------
echononl(){
echo X\\c > /tmp/shprompt$$
if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then
echo -e -n "$*\\c" 1>&2
else
echo -e -n "$*" 1>&2
fi
rm /tmp/shprompt$$
}
fatal(){
echo ""
echo -e "fatal error: $*"
echo ""
echo -e "\t\033[31m\033[1mInstalllation will be interrupted\033[m\033[m"
echo ""
exit 1
}
error(){
echo ""
echo -e "\t[ \033[31m\033[1mFehler\033[m ]: $*"
echo ""
}
warn (){
echo ""
echo -e "\t[ \033[33m\033[1mWarning\033[m ]: $*"
echo ""
}
info (){
echo ""
echo -e "\t[ \033[32m\033[1mInfo\033[m ]: $*"
echo ""
}
echo_done() {
echo -e "\033[80G[ \033[32mdone\033[m ]"
}
echo_ok() {
echo -e "\033[80G[ \033[32mok\033[m ]"
}
echo_warning() {
echo -e "\033[80G[ \033[33m\033[1mwarn\033[m ]"
}
echo_failed(){
echo -e "\033[80G[ \033[1;31mfailed\033[m ]"
}
echo_skipped() {
echo -e "\033[80G[ \033[37mskipped\033[m ]"
}
# -------------
# - Some pre-installation tasks
# -------------
# - Is 'systemd' supported on this system
# -
SYSTEMD_EXISTS=false
systemd=$(which systemd)
systemctl=$(which systemctl)
if [[ -n "$systemd" ]] || [[ -n "$systemctl" ]] ; then
SYSTEMD_EXISTS=true
fi
# =============
# - Start Installation
# =============
echo ""
# - Synchronise package index files with the repository
# -
echononl " Synchronise package index files with the repository.."
apt-get update > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
# - Install OpenDKIM
# -
echononl " Install needed debian packages.."
opendkim_packages=""
packages_installed=false
for _pkg in $_opendkim_packages ; do
if aptitude search "$_pkg" | grep " $_pkg " | grep -e "^i" > /dev/null 2>&1 ; then
continue
else
opendkim_packages="$opendkim_packages $_pkg"
fi
done
if [[ -n "$opendkim_packages" ]]; then
DEBIAN_FRONTEND=noninteractive apt-get -y install $opendkim_packages > /dev/null 2> "$log_file"
packages_installed=true
opendkim_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
fi
# - Add user 'postfix' to group 'opendkim'
# -
echononl " Add user 'postfix' to group 'opendkim'.."
if grep opendkim /etc/group | grep -q postfix 2> /dev/null ; then
echo_skipped
else
adduser postfix opendkim > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
# - Save configuration file from distribution
# -
echononl " Save configuration file from distribution"
if $packages_installed ; then
cp -a $opendkim_conf_file $opendkim_conf_file.ORIG 2> "$log_file"
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
fi
echononl " Backup existing file '${opendkim_conf_file}'.."
if [[ -f "${opendkim_conf_file}" ]] ; then
mv "${opendkim_conf_file}" "${opendkim_conf_file}.${backup_date}"
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
fi
# - Create OpenDKIM configuration
# -
echononl " Create OpenDKIM configuration"
if [[ -f "$opendkim_conf_file" ]] \
&& grep -i -q -E "^\s*Socket\s+local:$opendkim_socket_file" "$opendkim_conf_file" \
&& grep -i -q -E "^\s*SigningTable.*${opendkim_base_dir}/signing.table" "$opendkim_conf_file" \
&& grep -i -q -E "^\s*KeyTable.*${opendkim_base_dir}/key.table" "$opendkim_conf_file" ; then
echo_skipped
warn "OpenDKIM seems already be configured."
else
cat <<EOF > $opendkim_conf_file 2> $log_file
# Datei $opendkim_conf_file
# Sets the "authserv-id" to use when generating the Authentication-Results:
# header field after verifying a message. The default is to use the name of
# the MTA processing the message. If the string "HOSTNAME" is provided, the
# name of the host running the filter (as returned by the gethostname(3)
# function) will be used.
AuthservID "DKIM check $(hostname -f)"
# OpenDKIM agiert als Mail Filter (= Milter) in den
# Modi signer (s) und verifier (v) und verwendet eine
# Socket-Datei zur Kommunikation (alternativ: lokaler Port)
Mode sv
# Socket local:/var/run/opendkim/opendkim.sock
# Socket local:$opendkim_socket_file
# Socket inet:12345@localhost
Socket local:$opendkim_socket_file
# OpenDKIM verwendet diesen Benutzer bzw.
# diese Gruppe
UserID opendkim:opendkim
UMask 002
PidFile /var/run/opendkim/opendkim.pid
# OpenDKIM bei Problemen neustarten,
# aber max. 10 mal pro Stunde
AutoRestart yes
AutoRestartRate 10/1h
# Logging (wenn alles funktioniert eventuell reduzieren)
Syslog yes
SyslogSuccess yes
LogWhy yes
# Verfahren, wie Header und Body durch
# OpenDKIM verarbeitet werden sollen.
Canonicalization relaxed/simple
# interne Mails nicht mit OpenDKIM verarbeiten
ExternalIgnoreList refile:${opendkim_base_dir}/trusted
InternalHosts refile:${opendkim_base_dir}/trusted
# welche Verschlüsselungs-Keys sollen für welche
# Domains verwendet werden
# (refile: für Dateien mit regulären Ausdrücke)
SigningTable refile:${opendkim_base_dir}/signing.table
KeyTable ${opendkim_base_dir}/key.table
# diesen Signatur-Algorithmus verwenden
SignatureAlgorithm rsa-sha256
# Always oversign From (sign using actual From and a null From to prevent
# malicious signatures header fields (From and/or others) between the signer
# and the verifier. From is oversigned by default in the Debian pacakge
# because it is often the identity key used by reputation systems and thus
# somewhat security sensitive.
OversignHeaders From
# Add an "Authentication-Results:" header field even to unsigned messages
# from domains with no "signs all" policy. The reported DKIM result will be
# "none" in such cases. Normally unsigned mail from non-strict domains does
# not cause the results header field to be added.
AlwaysAddARHeader yes
# Causes opendkim to fork and exits immediately, leaving the service running
# in the background. The default is "true".
Background yes
# Sets the DNS timeout in seconds. A value of 0 causes an infinite wait. The
# default is 5. Ignored if not using an asynchronous resolver package. See
# also the NOTES section below.
DNSTimeout 5
EOF
opendkim_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
# - Assign ownership to the opendkim user and restrict tthe
# - file permissions:
# -
echononl " Assign ownership and file permissions.."
chmod u=rw,go=r $opendkim_conf_file 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
# - Create the directories to hold OpenDKIMs data files, assign
# - ownership to the opendkim user, and restrict the file
# - permissions:
# -
echononl " Create directory '$opendkim_base_dir'"
if [[ -d "$opendkim_base_dir" ]] ; then
echo_skipped
else
opendkim_needs_restart=true
mkdir ${opendkim_base_dir} 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
echononl " Create directory '$opendkim_key_dir'"
if [[ -d "$opendkim_key_dir" ]] ; then
echo_skipped
else
opendkim_needs_restart=true
mkdir $opendkim_key_dir 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
echononl " Set ownership on directory '${opendkim_base_dir}' (recursive).."
chown -R opendkim:opendkim ${opendkim_base_dir} 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
echononl " Set file-permission on $opendkim_key_dir"
chmod go-rw $opendkim_key_dir 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
# - Create empty files
# - ${opendkim_base_dir}/signing.table
# - ${opendkim_base_dir}/key.table
# -
echononl " Create empty file '${opendkim_base_dir}/signing.table'.."
if [[ -f "${opendkim_base_dir}/signing.table" ]] ; then
echo_skipped
else
touch ${opendkim_base_dir}/signing.table 2> $log_file
opendkim_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
echononl " Create empty file '${opendkim_base_dir}/key.table'.."
if [[ -f "${opendkim_base_dir}/key.table" ]] ; then
echo_skipped
else
touch ${opendkim_base_dir}/key.table 2> $log_file
opendkim_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
# - Create the trusted hosts file ${opendkim_base_dir}/trusted.hosts.
# -
echononl " Create trusted hosts file '${opendkim_base_dir}/trusted'.."
if [[ -f "${opendkim_base_dir}/trusted" ]] ; then
echo_skipped
else
cat <<EOF > ${opendkim_base_dir}/trusted 2> $log_file
127.0.0.1
::1
localhost
$(hostname -f)
EOF
opendkim_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
# - Create the OpenDKIM socket directory in Postfixs work area
# - and make sure it has the correct ownership:
# -
echononl " Create the OpenDKIM socket directory in Postfixs work area.."
if [[ -d "${postfix_spool_dir}/opendkim" ]] ; then
echo_skipped
else
mkdir ${postfix_spool_dir}/opendkim 2> $log_file
opendkim_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
echononl " Set ownership on directory '${postfix_spool_dir}/opendkim'.."
chown opendkim:postfix ${postfix_spool_dir}/opendkim 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
# - Edit /etc/default/opendkim
# -
# - Set:
# - SOCKET="local:${postfix_spool_dir}/opendkim/opendkim.sock"
# -
echononl " Set 'SOCKET' at file /etc/default/opendkim.."
if grep -q -E "^\s*SOCKET" /etc/default/opendkim 2>/dev/null ; then
if grep -q -E "^\s*SOCKET.*local:$opendkim_socket_file" /etc/default/opendkim 2>/dev/null ; then
echo_skipped
else
perl -i -n -p -e "s#^\s*SOCKET=.*#SOCKET=\"local:$opendkim_socket_file\"#" /etc/default/opendkim 2> $log_file
opendkim_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
else
cat <<EOF >>/etc/default/opendkim 2> $log_file
SOCKET="local:$opendkim_socket_file"
EOF
opendkim_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
# - Edit /etc/postfix/main.cf and add a section to activate
# - processing of e-mail through the OpenDKIM daemon:
# -
backup_date="$(date +%Y-%m-%d-%H%M)"
echononl " Backup existing postfix configuration (main.cf).."
cp -a /etc/postfix/main.cf /etc/postfix/main.cf.$backup_date 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
echononl " Activate processing of e-mail through the OpenDKIM daemon.."
if grep -q -E "milter_default_action\s*=\s*accept" /etc/postfix/main.cf ; then
echo_skipped
warn "Postfix (main.cf) seems already be configured for milters"
echononl " Delete previosly saved Postfix configuration.."
rm /etc/postfix/main.cf.$backup_date 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
cat <<EOF >> /etc/postfix/main.cf 2> $log_file
# ======= Milter configuration =======
# OpenDKIM
milter_default_action = accept
# Postfix ≥ 2.6 milter_protocol = 6, Postfix ≤ 2.5 milter_protocol = 2
milter_protocol = 6
# Note:
# We will sign AFTER sending through AmaVIS, just befor sending out. So
# set 'smtpd_milters =' to an emty string here and add to localhost:10025
# section in master.cf: 'smtpd_milters=local:/opendkim/opendkim.sock'
#
# If you want sign mails before sending through AmaVIS, set
# 'smtpd_milters = local:/opendkim/opendkim.sock' here and add to
# localhost:10025 section in master.cf: 'smtpd_milters='
#
#smtpd_milters = local:/opendkim/opendkim.sock
smtpd_milters =
# Was sind non_smtpd_milters?
#
# non_smtpd_milters gilt für alle Postfix-Prozesse, die Mails verarbeiten, aber NICHT
# der smtpd-Daemon sind.
#
# Das betrifft z. B.:
#
# cleanup Header/Content-Bereinigung
# qmgr Queue-Manager
# lmtp / smtp Auslieferung nach extern
# local lokale Zustellung
#
# Das sind z. B.:
#
# - interne Bounces (MAILER-DAEMON)
#
# - Cron-Mails vom Server
#
# - Weiterleitungen, die Postfix selbst generiert
#
# - Mails, die über sendmail CLI gesendet werden
#
# - Mails, die Amavis über LMTP zurückgibt
#
# - etc.
#
#
# DKIM soll auch die ausgehenden Mails signieren, die nicht über smtpd daemon versendet werden.
non_smtpd_milters = local:/opendkim/opendkim.sock
EOF
postfix_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
# - Prevent Postfix from setting the DKIM Header twice (one befor
# - and one after processing amavis
# -
# - To disable milter processing after amavis, add to your master.cf in
# - the after-amavis section:
# - 127.0.0.1:10025 inet n - - - - smtpd
# - [...]
# - -o smtpd_milters=
# -
# - If you want to run the milter after amavis, set in main.cf
# - smtpd_milters=
# - to an empty string and add the smtpd_milters configuration to master.cf
# - (after-section amavis) instead:
# - -o smtpd_milters=local:/opendkim/opendkim.sock
# -
echononl " Backup file '/etc/postfix/master.cf'.."
cp -a /etc/postfix/master.cf /etc/postfix/master.cf.$backup_date 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
echononl " Adjust /etc/postfix/master.cf. Set DKIM after sending throuh AmaVIS.."
_found=false
_changed=false
tmp_master_file="/tmp/postfix_master.cf"
> $tmp_master_file
while IFS='' read -r _line || [[ -n $_line ]] ; do
if $_found && ! echo "$_line" | grep -i -q -E "^\s*-o" 2> /dev/null ; then
echo " -o smtpd_milters=local:/opendkim/opendkim.sock" >> "$tmp_master_file"
_changed=true
_found=false
fi
if $_found && echo "$_line" | grep -i -q -E "^\s*-o\s+smtpd_milters=\s*" ; then
_found=false
if ! echo "$_line" | grep -i -q -E "^\s*-o\s+smtpd_milters=\s*local:/opendkim/opendkim.sock\s*$" ; then
echo " -o smtpd_milters=local:/opendkim/opendkim.sock" >> "$tmp_master_file"
_changed=true
continue
fi
fi
if echo "$_line" | grep -i -q -E "^\s*(submission|smtps)\s+inet\s+" 2> /dev/null ; then
_found=true
fi
echo "$_line" >> "$tmp_master_file"
done < "/etc/postfix/master.cf"
if $_changed ; then
cp $tmp_master_file /etc/postfix/master.cf 2> $log_file
postfix_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
info "Postfix (master.cf) was not changed - seems already be configured right."
echononl " Delete previosly saved file '/etc/postfix/master.cf'.."
rm /etc/postfix/master.cf.$backup_date 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
rm -f $tmp_master_file
echo ""
# - Restart OpenDKIM
# -
echononl " Restart OpenDKIM.."
if $opendkim_needs_restart ; then
if $SYSTEMD_EXISTS ; then
systemctl restart opendkim > $log_file 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
/etc/init.d/opendkim restart > $log_file 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
else
echo_skipped
fi
# - Restart Postfix so it starts using OpenDKIM when processing mail:
# -
echononl " Restart Postfix.."
if $postfix_needs_restart ; then
if $SYSTEMD_EXISTS ; then
systemctl restart postfix > $log_file 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
/etc/init.d/postfix restart > $log_file 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
else
echo_skipped
fi
echo ""
rm -f "$log_file"
exit 0

View File

@@ -0,0 +1,936 @@
#!/usr/bin/env bash
clear
echo -e "\n \033[32mStart Installation of OpenDMARC..\033[m"
overwrite_config_files=true
# -------------
# - Settings
# -------------
#_src_base_dir="$(realpath $(dirname $0))"
#conf_file="${_src_base_dir}/conf/install_opendmarc.conf"
_opendmarc_packages="opendmarc"
opendmarc_base_dir="/etc/opendmarc"
opendmarc_conf_file="/etc/opendmarc.conf"
postfix_spool_dir="/var/spool/postfix"
opendmarc_socket_dir="${postfix_spool_dir}/opendmarc"
opendmarc_socket_file="${opendmarc_socket_dir}/opendmarc.sock"
config_file_name_value_parameters="
AuthservID|$(hostname -f)
TrustedAuthservIDs|$(hostname -f)
PidFile|/run/opendmarc/opendmarc.pid
RejectFailures|true
Syslog|true
SyslogFacility|mail
IgnoreHosts|${opendmarc_base_dir}/ignore.hosts
IgnoreMailFrom|${opendmarc_base_dir}/ignore.mailfrom
IgnoreAuthenticatedClients|true
RequiredHeaders|false
UMask|002
FailureReports|false
AutoRestart|true
HistoryFile|/run/opendmarc/opendmarc.dat
SPFIgnoreResults|false
SPFSelfValidate|true
Socket|${opendmarc_socket_file}
"
declare -a config_file_name_value_parameter_arr=()
for _conf in $config_file_name_value_parameters ; do
config_file_name_value_parameter_arr+=("$_conf")
done
postfix_needs_restart=false
opendmarc_needs_restart=false
backup_date="$(date +%Y-%m-%d-%H%M)"
log_file="$(mktemp)"
# -------------
# --- Some functions
# -------------
echononl(){
echo X\\c > /tmp/shprompt$$
if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then
echo -e -n "$*\\c" 1>&2
else
echo -e -n "$*" 1>&2
fi
rm /tmp/shprompt$$
}
fatal(){
echo ""
echo -e "fatal error: $*"
echo ""
echo -e "\t\033[31m\033[1mInstalllation will be interrupted\033[m\033[m"
echo ""
exit 1
}
error(){
echo ""
echo -e "\t[ \033[31m\033[1mFehler\033[m ]: $*"
echo ""
}
warn (){
echo ""
echo -e "\t[ \033[33m\033[1mWarning\033[m ]: $*"
echo ""
}
info (){
echo ""
echo -e "\t[ \033[32m\033[1mInfo\033[m ]: $*"
echo ""
}
echo_done() {
echo -e "\033[80G[ \033[32mdone\033[m ]"
}
echo_ok() {
echo -e "\033[80G[ \033[32mok\033[m ]"
}
echo_warning() {
echo -e "\033[80G[ \033[33m\033[1mwarn\033[m ]"
}
echo_failed(){
echo -e "\033[80G[ \033[1;31mfailed\033[m ]"
}
echo_skipped() {
echo -e "\033[80G[ \033[37mskipped\033[m ]"
}
# -------------
# - Some pre-installation tasks
# -------------
# - Is 'systemd' supported on this system
# -
SYSTEMD_EXISTS=false
systemd=$(which systemd)
systemctl=$(which systemctl)
if [[ -n "$systemd" ]] || [[ -n "$systemctl" ]] ; then
SYSTEMD_EXISTS=true
fi
# =============
# - Start Installation
# =============
echo ""
# - Synchronise package index files with the repository
# -
echononl " Synchronise package index files with the repository.."
apt-get update > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
# - Install opendmarc
# -
echononl " Install needed debian packages.."
opendmarc_packages=""
packages_installed=false
for _pkg in $_opendmarc_packages ; do
if aptitude search "$_pkg" | grep " $_pkg " | grep -e "^i" > /dev/null 2>&1 ; then
continue
else
opendmarc_packages="$opendmarc_packages $_pkg"
fi
done
if [[ -n "$opendmarc_packages" ]]; then
DEBIAN_FRONTEND=noninteractive apt-get -y install $opendmarc_packages > /dev/null 2> "$log_file"
packages_installed=true
opendmarc_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
fi
# - Add user 'postfix' to group 'opendmarc'
# -
echononl " Add user 'postfix' to group 'opendmarc'.."
if grep -E "^opendmarc" /etc/group | grep -q postfix 2> /dev/null ; then
echo_skipped
else
usermod -a -G opendmarc postfix > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
# - Add 'IgnoreHosts' with default value to the original opendmarc.conf file
#
echononl " Add 'IgnoreHosts' with default value to the opendmarc.conf file.."
if ! $(grep -q -E "^IgnoreHosts\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
cat << EOF >> ${opendmarc_conf_file}
## Specifies the path to a file that contains a list of hostnames, IP addresses,
## and/or CIDR expressions identifying hosts whose SMTP connections are to be
## ignored by the filter. If not specified, defaults to "127.0.0.1" only.
#
IgnoreHosts 127.0.0.1
# Optional - auch nach Absender-Domain ignorieren:
IgnoreMailFrom ${opendmarc_base_dir}/ignore.mailfrom
EOF
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
fi
# - Add 'IgnoreAuthenticatedClients' with default value to the original opendmarc.conf file
#
_param="IgnoreAuthenticatedClients"
echononl " Add '${_param}' with default value to the opendmarc.conf file.."
if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
cat << EOF >> ${opendmarc_conf_file}
## If set, causes mail from authenticated clients (i.e., those that used
## SMTP AUTH) to be ignored by the filter. The default is "false".
#
IgnoreAuthenticatedClients false
EOF
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
fi
# - Add 'TrustedAuthservIDs' with default value to the original opendmarc.conf file
#
_param="TrustedAuthservIDs"
echononl " Add '${_param}' with default value to the opendmarc.conf file.."
if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
cat << EOF >> ${opendmarc_conf_file}
# Provides a list of authserv-ids that are to be used to identify Authentication-Results
# header fields whose contents are to be assumed as valid input for the DMARC assessment.
# To provide a list, separate values by commas. If the string "HOSTNAME" is provided,
# the name of the host running the filter (as returned by the gethostname(3) function)
# will be used. Matching against this list is case-insensitive. The default is to use the
# value of AuthservID.
#
TrustedAuthservIDs OpenDMARC
EOF
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
fi
# - Add 'RequiredHeaders' with default value to the original opendmarc.conf file
#
_param="IgnoreAuthenticatedClients"
echononl " Add '${_param}' with default value to the opendmarc.conf file.."
if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
cat << EOF >> ${opendmarc_conf_file}
## If set, causes mail from authenticated clients (i.e., those that used
## SMTP AUTH) to be ignored by the filter. The default is "false".
#
IgnoreAuthenticatedClients false
EOF
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
fi
# - Add 'RequiredHeaders' with default value to the original opendmarc.conf file
#
_param="RequiredHeaders"
echononl " Add '${_param}' with default value to the opendmarc.conf file.."
if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
cat << EOF >> ${opendmarc_conf_file}
## If set, the filter will ensure the header of the message conforms to the basic
## header field count restrictions laid out in RFC5322, Section 3.6. Messages
## failing this test are rejected without further processing. A From: field from
## which no domain name could be extracted will also be rejected.
#
RequiredHeaders false
EOF
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
fi
# - Add 'AutoRestart' with default value to the original opendmarc.conf file
#
_param="AutoRestart"
echononl " Add '${_param}' with default value to the opendmarc.conf file.."
if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
cat << EOF >> ${opendmarc_conf_file}
## Automatically re-start on failures. Use with caution; if the filter fails
## instantly after it starts, this can cause a tight fork(2) loop.
#
AutoRestart false
EOF
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
fi
# - Add 'HistoryFile' with default value to the original opendmarc.conf file
#
_param="HistoryFile"
echononl " Add '${_param}' with default value to the opendmarc.conf file.."
if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
cat << EOF >> ${opendmarc_conf_file}
## If set, specifies the location of a text file to which records are written
## that can be used to generate DMARC aggregate reports. Records are batches of
## rows containing information about a single received message, and include all
## relevant information needed to generate a DMARC aggregate report. It is
## expected that this will not be used in its raw form, but rather periodically
## imported into a relational database from which the aggregate reports can be
## extracted using opendmarc-importstats(8).
#
HistoryFile /run/opendmarc/opendmarc.dat
EOF
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
fi
# - Add 'SPFIgnoreResults' with default value to the original opendmarc.conf file
#
_param="SPFIgnoreResults"
echononl " Add '${_param}' with default value to the opendmarc.conf file.."
if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
cat << EOF >> ${opendmarc_conf_file}
## Causes the filter to ignore any SPF results in the header of the message. This
## is useful if you want the filter to perform SPF checks itself, or because you
## don't trust the arriving header. The default is "false".
#
SPFIgnoreResults false
EOF
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
fi
# - Add 'SPFSelfValidate' with default value to the original opendmarc.conf file
#
_param="SPFSelfValidate"
echononl " Add '${_param}' with default value to the opendmarc.conf file.."
if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
cat << EOF >> ${opendmarc_conf_file}
## Causes the filter to perform a fallback SPF check itself when it can find no
## SPF results in the message header. If SPFIgnoreResults is also set, it never
## looks for SPF results in headers and always performs the SPF check itself when
## this is set. The default is "false".
#
SPFSelfValidate false
EOF
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
fi
# - Save configuration file from distribution
# -
echononl " Save configuration file from distribution"
if [[ -f "${opendmarc_conf_file}.ORIG" ]] ; then
echo_skipped
else
cp -a $opendmarc_conf_file $opendmarc_conf_file.ORIG 2> "$log_file"
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
for _val in "${config_file_name_value_parameter_arr[@]}" ; do
IFS='|' read -a _val_arr <<< "${_val}"
echononl " $opendmarc_conf_file: ${_val_arr[0]} -> ${_val_arr[1]}.."
if $(grep -E -q "^\s*${_val_arr[0]}\s+${_val_arr[1]}\s*$" $opendmarc_conf_file 2> /dev/null) ; then
echo_skipped
elif $(grep -E -q "^\s*#\s*${_val_arr[0]}\s+" $opendmarc_conf_file 2> /dev/null); then
perl -i -n -p -e "s&^(\s*#\s*${_val_arr[0]}.*)&\1\n${_val_arr[0]} ${_val_arr[1]}&" $opendmarc_conf_file > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
opendmarc_needs_restart=true
else
echo_failed
error "$(cat $log_file)"
fi
elif $(grep -E -q "^\s*${_val_arr[0]}\s+" $opendmarc_conf_file 2> /dev/null) ; then
perl -i -n -p -e "s#^(\s*${_val_arr[0]}.*)#\#\1\n${_val_arr[0]} ${_val_arr[1]}#" $opendmarc_conf_file > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
opendmarc_needs_restart=true
else
echo_failed
error "$(cat $log_file)"
fi
else
cat <<EOF >> $opendmarc_conf_file 2> "$log_file"
${_val_arr[0]} ${_val_arr[1]}
EOF
if [[ $? -eq 0 ]] ; then
echo_ok
opendmarc_needs_restart=true
else
echo_failed
error "$(cat $log_file)"
fi
fi
done
# - Assign ownership to the opendmarc user and restrict tthe
# - file permissions:
# -
echononl " Assign file permissions to '$opendmarc_conf_file'.."
chmod u=rw,go=r $opendmarc_conf_file 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
# - Create the directories to hold opendmarc's data files, assign
# - ownership to the opendmarc user, and restrict the file
# - permissions:
# -
echononl " Create directory '$opendmarc_base_dir'"
if [[ -d "$opendmarc_base_dir" ]] ; then
echo_skipped
else
opendmarc_needs_restart=true
mkdir ${opendmarc_base_dir} 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
echononl " Set ownership on directory '${opendmarc_base_dir}' (recursive).."
chown -R opendmarc:opendmarc ${opendmarc_base_dir} 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
echononl " Backup existing file '${opendmarc_base_dir}/ignore.hosts'.."
if [[ -f "${opendmarc_base_dir}/ignore.hosts" ]] ; then
mv "${opendmarc_base_dir}/ignore.hosts" "${opendmarc_base_dir}/ignore.hosts.${backup_date}"
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
fi
# - Create the file ${opendmarc_base_dir}/ignore.hosts
# -
echononl " Create file '${opendmarc_base_dir}/ignore.hosts'.."
if [[ -f "${opendmarc_base_dir}/ignore.hosts" ]] ; then
echo_skipped
else
cat <<EOF > ${opendmarc_base_dir}/ignore.hosts 2> $log_file
# /etc/opendmarc/ignore.hosts
#
# Aktuell hat OpenDMARC seinen Milter nur am Dienst
# 'localhost:10025' hängen. Dort ist der Client
# immer 127.0.0.1, nicht die externe Gegenstelle.
#
# Deshalb macht es in diesem Setup keinen Sinn,
# hier IP-Adressen von externen Diensten (CRSend etc.)
# einzutragen sie würden nie matchen.
#
# WICHTIG:
# - KEIN 127.0.0.1
# - KEIN localhost
# - KEIN ::1
#
# Eintrag dieser Adressen würde DMARC komplett deaktivieren.
#
# ==> Datei bleibt absichtlich leer.
EOF
opendmarc_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
# - Create the file ${opendmarc_base_dir}/ignore.hosts
# -
echononl " Backup existing file '${opendmarc_base_dir}/ignore.mailfrom'.."
if [[ -f "${opendmarc_base_dir}/ignore.mailfrom" ]] ; then
mv "${opendmarc_base_dir}/ignore.mailfrom" "${opendmarc_base_dir}/ignore.mailfrom.${backup_date}"
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
fi
echononl " Create file '${opendmarc_base_dir}/ignore.mailfrom'.."
if [[ -f "${opendmarc_base_dir}/ignore.mailfrom" ]] ; then
echo_skipped
else
cat <<EOF > ${opendmarc_base_dir}/ignore.mailfrom 2> $log_file
# /etc/opendmarc/ignore.mailfrom
#
# Hier könnte man Absender-Domains von der DMARC-Prüfung
# ausnehmen (z. B. problematische Partner-Domains).
#
# Aktuell ist das für dein Setup nicht notwendig.
#
# Beispiele (NICHT aktiv!):
# @example.org
# example.org
#
# ==> Datei bleibt absichtlich leer.
EOF
opendmarc_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
# - Edit /etc/default/opendmarc
# -
# - Set:
# - SOCKET="local:${postfix_spool_dir}/opendmarc/opendmarc.sock"
# -
echononl " Set 'SOCKET' at file /etc/default/opendmarc.."
if grep -q -E "^\s*SOCKET" /etc/default/opendmarc 2>/dev/null ; then
if grep -q -E "^\s*SOCKET\s*=\s*\"*local:$opendmarc_socket_file" /etc/default/opendmarc 2>/dev/null ; then
echo_skipped
else
perl -i -n -p -e "s#^\s*SOCKET=.*#SOCKET=\"local:$opendmarc_socket_file\"#" /etc/default/opendmarc 2> $log_file
opendmarc_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
else
cat <<EOF >>/etc/default/opendmarc 2> $log_file
SOCKET="local:$opendmarc_socket_file"
EOF
opendmarc_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
# - Create the opendmarc socket directory in Postfixs work area
# - and make sure it has the correct ownership:
# -
echononl " Create the opendmarc socket directory in Postfix's work area.."
if [[ -d "${postfix_spool_dir}/opendmarc" ]] ; then
echo_skipped
else
mkdir ${postfix_spool_dir}/opendmarc 2> $log_file
opendmarc_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
echononl " Set ownership on directory '${postfix_spool_dir}/opendmarc'.."
chown opendmarc:postfix ${postfix_spool_dir}/opendmarc 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
# - Edit /etc/postfix/main.cf and add a section to activate
# - processing of e-mail through the opendmarc daemon:
# -
echononl " Backup existing postfix configuration (main.cf).."
cp -a /etc/postfix/main.cf /etc/postfix/main.cf.$backup_date 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
echononl " Set Variable non_smtpd_milters at '/etc/postfix/main.cf'.."
if $(grep -q -E "^\s*non_smtpd_milters\s*=\s*.*opendkim.sock" /etc/postfix/main.cf 2> /dev/null) ; then
if $(grep -q -E "^\s*non_smtpd_milters\s*=\s*.*$(basename "${opendmarc_socket_file}")" /etc/postfix/main.cf); then
echo_skipped
else
perl -i -n -p -e "s&^\s*(non_smtpd_milters\s*=.*opendkim.sock)&\1,local:/$(basename "${opendmarc_socket_dir}")/$(basename "${opendmarc_socket_file}")&" \
/etc/postfix/main.cf > $log_file 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
postfix_needs_restart=true
else
echo_failed
error "$(cat $log_file)"
fi
fi
else
echo_skipped
warn "Postfix is not adjusted. Complete Postfix configuration (main.cf) manually\!"
fi
echo ""
# - Edit /etc/postfix/main.cf and add a section to activate
# - processing of e-mail through the OpenDKIM daemon:
# -
backup_date="$(date +%Y-%m-%d-%H%M)"
echononl " Backup existing postfix configuration (main.cf).."
cp -a /etc/postfix/main.cf /etc/postfix/main.cf.$backup_date 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
echononl " Activate processing of e-mail through the OpenDKIM daemon.."
if grep -q -E "milter_default_action\s*=\s*accept" /etc/postfix/main.cf ; then
echo_skipped
info "Postfix (main.cf) was not changed - seems already be configured right."
echononl " Delete previosly saved Postfix configuration.."
rm /etc/postfix/main.cf.$backup_date 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
cat <<EOF >> /etc/postfix/main.cf 2> $log_file
# ======= Milter configuration =======
# OpenDKIM
milter_default_action = accept
# Postfix ≥ 2.6 milter_protocol = 6, Postfix ≤ 2.5 milter_protocol = 2
milter_protocol = 6
# Note:
# We will sign AFTER sending through AmaVIS, just befor sending out. So
# set 'smtpd_milters =' to an emty string here and add to localhost:10025
# section in master.cf: 'smtpd_milters=local:/opendkim/opendkim.sock'
#
# If you want sign mails before sending through AmaVIS, set
# 'smtpd_milters = local:/opendkim/opendkim.sock' here and add to
# localhost:10025 section in master.cf: 'smtpd_milters='
#
#smtpd_milters = local:/opendkim/opendkim.sock
smtpd_milters =
# Was sind non_smtpd_milters?
#
# non_smtpd_milters gilt für alle Postfix-Prozesse, die Mails verarbeiten, aber NICHT
# der smtpd-Daemon sind.
#
# Das betrifft z. B.:
#
# cleanup Header/Content-Bereinigung
# qmgr Queue-Manager
# lmtp / smtp Auslieferung nach extern
# local lokale Zustellung
#
# Das sind z. B.:
#
# - interne Bounces (MAILER-DAEMON)
#
# - Cron-Mails vom Server
#
# - Weiterleitungen, die Postfix selbst generiert
#
# - Mails, die über sendmail CLI gesendet werden
#
# - Mails, die Amavis über LMTP zurückgibt
#
# - etc.
#
#
# DKIM soll auch die ausgehenden Mails signieren, die nicht über smtpd daemon versendet werden.
non_smtpd_milters = local:/opendkim/opendkim.sock
EOF
postfix_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
echo ""
# - Prevent Postfix from setting the DMARC Header twice (one befor
# - and one after processing amavis
# -
# - To disable milter processing after amavis, add to your master.cf in
# - the after-amavis section:
# - 127.0.0.1:10025 inet n - - - - smtpd
# - [...]
# - -o smtpd_milters=
# -
# - If you want to run the milter after amavis, set in main.cf
# - smtpd_milters=
# - to an empty string and add the smtpd_milters configuration to master.cf
# - (after-section amavis) instead:
# - -o smtpd_milters=local:/opendmarc/opendmarc.sock
# -
echononl " Backup file '/etc/postfix/master.cf'.."
cp -a /etc/postfix/master.cf /etc/postfix/master.cf.${backup_date} 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
echononl " Adjust /etc/postfix/master.cf. Set DMARC after sending throuh AmaVIS.."
_found=false
_changed=false
tmp_master_file="/tmp/postfix_master.cf"
> $tmp_master_file
while IFS='' read -r _line || [[ -n $_line ]] ; do
if $_found && ! echo "$_line" | grep -i -q -E "^\s*-o" 2> /dev/null ; then
echo " -o smtpd_milters=local:/opendmarc/opendmarc.sock" >> "$tmp_master_file"
_changed=true
_found=false
fi
if $_found && echo "$_line" | grep -i -q -E "^\s*-o\s+smtpd_milters=\s*" ; then
_found=false
if ! echo "$_line" | grep -i -q -E "^\s*-o\s+smtpd_milters=\s*local:/opendmarc/opendmarc.sock\s*$" ; then
echo " -o smtpd_milters=local:/opendmarc/opendmarc.sock" >> "$tmp_master_file"
_changed=true
continue
fi
fi
if echo "$_line" | grep -i -q -E "^\s*(localhost|127.0.0.1):10025\s+inet\s+" 2> /dev/null ; then
_found=true
fi
echo "$_line" >> "$tmp_master_file"
done < "/etc/postfix/master.cf"
if $_changed ; then
cp $tmp_master_file /etc/postfix/master.cf 2> $log_file
postfix_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
info "Postfix (master.cf) was not changed - seems already be configured right."
echononl " Delete previosly saved file '/etc/postfix/master.cf'.."
rm /etc/postfix/master.cf.$backup_date 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
rm -f $tmp_master_file
echo ""
echononl " Enable OpenDMARC Service"
if $SYSTEMD_EXISTS ; then
systemctl enable opendmarc > $log_file 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
warn "Maybe OpenDMARC Service is not enabled, because its an old non-systemd os.."
fi
# - Restart opendmarc
# -
echononl " Restart opendmarc.."
if $opendmarc_needs_restart ; then
if $SYSTEMD_EXISTS ; then
systemctl restart opendmarc > $log_file 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
/etc/init.d/opendmarc restart > $log_file 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
else
echo_skipped
fi
# - Restart Postfix so it starts using opendmarc when processing mail:
# -
echononl " Restart Postfix.."
if $postfix_needs_restart ; then
if $SYSTEMD_EXISTS ; then
systemctl restart postfix > $log_file 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
/etc/init.d/postfix restart > $log_file 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
else
echo_skipped
fi
echo ""
rm -f "$log_file"
exit 0

View File

@@ -0,0 +1,36 @@
# Analyse und Begründung von DMARC-Rejects
## (Postfix + OpenDMARC 1.4.2)
### 1. Zweck
Diese SOP beschreibt, wie DMARC-Rejects auf dem Mailserver revisionssicher analysiert und begründet werden, ohne die betroffene E-Mail anzunehmen oder erneut senden zu lassen.
### 2. Systemkontext
- MTA: Postfix
- DMARC-Filter: OpenDMARC 1.4.2
- SPF-Prüfung: policyd-spf
- DKIM-Prüfung: OpenDKIM
- Entscheidungspunkt: SMTP END-OF-MESSAGE
### 3. Grundprinzip
OpenDMARC loggt nur das Endergebnis der DMARC-Evaluation, nicht die Detailursachen. Die Ursache eines Rejects wird durch Log-Korrelation ermittelt.
### 4. Relevante Logquellen
- Postfix (SMTP-Rejects)
- policyd-spf (SPF-Ergebnis, identity)
- OpenDMARC (pass/fail/none pro Domain)
### 5. Entscheidungslogik
DMARC besteht nur, wenn mindestens ein Mechanismus DMARC-konform erfolgreich ist:
- SPF(mailfrom) aligned
- DKIM valid + aligned
SPF über HELO ist für DMARC nicht verwertbar.
### 6. Ableitungsregel
Wenn SPF nur über HELO erfolgreich war und DMARC fail meldet, muss DKIM fehlgeschlagen sein.
### 7. Revisionssichere Begründung
Die E-Mail wurde gemäß der DMARC-Policy der Absenderdomain abgelehnt, da keine DMARC-konforme Authentifizierung vorlag.
### 8. Referenzen
RFC 7489 (DMARC), RFC 7208 (SPF), RFC 6376 (DKIM)

Binary file not shown.

View File

@@ -58,7 +58,7 @@
- create configuration file 'install_update_dovecot.conf' - create configuration file 'install_update_dovecot.conf'
cp -a conf install_update_dovecot.conf.sample install_update_dovecot.conf cp -a conf install_update_dovecot.conf.sample install_update_dovecot.conf
- adjust configuration file 'install_update_dovecot.conf' to your needs - adjust configuration file 'install_update_dovecot.conf' to your needs
- run script 'install_update_dovecot.sh' - run script 'install_update_dovecot-2.4.sh' # the old one was: 'install_update_dovecot.sh'
Note: Note:
Maybe you have to finish installing postfixadmin, i.e creating admin account(s). Maybe you have to finish installing postfixadmin, i.e creating admin account(s).

View File

@@ -165,8 +165,16 @@ max_userip_connections=24
#auth_mechanisms="plain login digest-md5 cram-md5" #auth_mechanisms="plain login digest-md5 cram-md5"
auth_mechanisms="plain login" auth_mechanisms="plain login"
# ---
# - Settings for quota warning sript # - Settings for quota warning sript
# - # ---
# msg_language
#
# possible Vallues are 'en' or 'de'
#
msg_language=de
from_address="o.open <oo@oopen.de>" from_address="o.open <oo@oopen.de>"
reply_to="oo@oopen.de" reply_to="oo@oopen.de"
webmailer="https://webmail.oopen.de" webmailer="https://webmail.oopen.de"

View File

@@ -115,9 +115,11 @@ DEFAULT_ADMIN_EMAIL="argus@oopen.de"
# - Is this a systemd system? # - Is this a systemd system?
# - # -
if [[ "X`which systemd`" = "X" ]]; then systemd_exists=false
systemd_exists=false systemd=$(which systemd)
else systemctl=$(which systemctl)
if [[ -n "$systemd" ]] || [[ -n "$systemctl" ]] ; then
systemd_exists=true systemd_exists=true
fi fi

View File

@@ -154,9 +154,11 @@ QUARANTINE_ADMIN=$DEFAULT_QUARANTINE_ADMIN
# - Is this a systemd system? # - Is this a systemd system?
# - # -
if [[ "X`which systemd`" = "X" ]]; then systemd_exists=false
systemd_exists=false systemd=$(which systemd)
else systemctl=$(which systemctl)
if [[ -n "$systemd" ]] || [[ -n "$systemctl" ]] ; then
systemd_exists=true systemd_exists=true
fi fi
@@ -216,6 +218,9 @@ elif [[ "${os_dist,,}" = "debian" ]] && [[ "$os_version" -eq 11 ]] ; then
elif [[ "${os_dist,,}" = "debian" ]] && [[ "$os_version" -eq 12 ]] ; then elif [[ "${os_dist,,}" = "debian" ]] && [[ "$os_version" -eq 12 ]] ; then
_needed_packages_clamav="$_needed_packages_clamav \ _needed_packages_clamav="$_needed_packages_clamav \
libclamunrar11" libclamunrar11"
elif [[ "${os_dist,,}" = "debian" ]] && [[ "$os_version" -eq 13 ]] ; then
_needed_packages_clamav="$_needed_packages_clamav \
libclamunrar12"
else else
_needed_packages_clamav="$_needed_packages_clamav \ _needed_packages_clamav="$_needed_packages_clamav \
libclamunrar13" libclamunrar13"
@@ -231,7 +236,6 @@ _needed_decoders_amavis="
cpio\ cpio\
lhasa \ lhasa \
lzop \ lzop \
liblz4-tool \
lrzip \ lrzip \
melt \ melt \
nomarch \ nomarch \
@@ -248,6 +252,11 @@ _needed_decoders_amavis="
unzip \ unzip \
zip " zip "
if [[ "${os_dist,,}" = "debian" ]] && [[ "$os_version" -lt 12 ]] ; then
_needed_decoders_amavis="$_needed_decoders_amavis \
liblz4-tool"
fi
if [[ "${os_dist,,}" = "debian" ]] && [[ "$os_version" -lt 10 ]] ; then if [[ "${os_dist,,}" = "debian" ]] && [[ "$os_version" -lt 10 ]] ; then
_needed_decoders_amavis="$_needed_decoders_amavis \ _needed_decoders_amavis="$_needed_decoders_amavis \
ripole \ ripole \
@@ -3932,7 +3941,7 @@ installation_failed=false
_needed_cpan_modules=" _needed_cpan_modules="
Digest::SHA1 Digest::SHA1
Digest::SHA2 Digest::SHA2
Digest::SHA256 Digest::SHA
Encode::Detect Encode::Detect
Net::Patricia" Net::Patricia"
for _module in $_needed_cpan_modules ; do for _module in $_needed_cpan_modules ; do
@@ -4315,6 +4324,23 @@ if (-r \$policy_banks_file) {
\$final_bad_header_destiny = D_PASS; \$final_bad_header_destiny = D_PASS;
# ----------------------------------------------------------
# Admin E-Mails / Warnungen direct von AMaViS (nicht DSN- oder Bounce-Mails)
# ----------------------------------------------------------
# Bemerkung:
# *nochmal*: das hat nichts mit den eigentlichen DSN-/Bounce-Mails zu tun.
\$virus_admin = undef;
\$spam_admin = undef;
\$warnvirusrecip = 0;
\$warnbannedrecip = 0;
\$warnbannedsender = 0;
\$warnbadhrecip = 0;
\$warn_offsite = 0;
# Bypass spam checking for trusted networks using mynetworks # Bypass spam checking for trusted networks using mynetworks
# #
@@ -4897,36 +4923,50 @@ else
fi fi
## - Provide an 'After-queue filter' (classic content filter):
## -
## - - The external sender communicates with port 25.
## - - Postfix accepts the email and initially places it in the queue.
## - - Postfix then forwards the email to Amavis (10024).
## - - Amavis returns it to Postfix (typically on 10025).
## -
## - Advantage:
## - Port 25 is 'normal Postfix SMTP'
## - -> Milters (OpenDMARC/OpenDKIM verify) access port 25 cleanly
## - -> DMARC reject happens in the SMTP dialog (if you set it up that way
## - and the checks pass 'pre-queue')
## -
## - Disadvantage:
## - Some types of rejections may no longer happen 'before queue', but only later
## - (depending on the type of check)
## -
## -
## - Set up /etc/postfix/master ## - Set up /etc/postfix/master
## - ## -
## - Forward emails to amavis using "Pre-Queue" Option smtpd_proxy_filter ## - Forward emails to amavis using "After-Queue-Filter" Option content_filter
## - ## -
## - edit /etc/postfix/master.cf and add flags for "smtpd_proxy_filter" (to ## - edit /etc/postfix/master.cf and add flags for "content_filter" (to
## - forward to amavis service on localhost port 10024) and for "content_filter" ## - forward to amavis service on localhost port 10024)
## - (to avoid rechecking by "Post-Queue" content_filter) to smtp service
## - ## -
## - smtp inet n - - - - smtpd ## - smtp inet n - - - - smtpd
## - -o smtpd_proxy_filter=127.0.0.1:10024 ## - -o content_filter=amavisfeed:[127.0.0.1]:10024
## - -o content_filter=
## - ## -
## - take care, that, in case NOT to reject, amavis fowards the mail to the ## - !! Noticw !!
## - MTA (Postfix) for delivering. To avoid loops in checking, install a ## - - take care localhost:10025 has empty 'content_filter'
## - (Postfix) smtpd service on a local Port (10025) without checking anymore
## - ## -
## - to do this edit /etc/postfix/master.cf and add service: ## - localhost:10025 inet n - y - - smtpd
## - ## - -o content_filter=
## - localhost:10025 inet n - - - - smtpd ## - -o smtpd_proxy_filter=
## - -o content_filter= ## - -o smtpd_authorized_xforward_hosts=127.0.0.0/8,[::1]/128
## - -o smtpd_proxy_filter= ## - -o smtpd_client_restrictions=
## - -o smtpd_authorized_xforward_hosts=127.0.0.0/8,[::1]/128 ## - -o smtpd_helo_restrictions=
## - -o smtpd_client_restrictions= ## - -o smtpd_sender_restrictions=
## - -o smtpd_helo_restrictions= ## - -o smtpd_recipient_restrictions=permit_mynetworks,reject
## - -o smtpd_sender_restrictions= ## - -o smtpd_data_restrictions=
## - -o smtpd_recipient_restrictions=permit_mynetworks,reject ## - -o mynetworks=127.0.0.0/8,[::1]/128
## - -o smtpd_data_restrictions= ## - -o receive_override_options=no_unknown_recipient_checks
## - -o mynetworks=127.0.0.0/8,[::1]/128,<$_ipv4_address/32>
## - -o receive_override_options=no_unknown_recipient_checks
## - ## -
## - - take care not to have 'content_filter' set im main.cf
postfix_master_cf="/etc/postfix/master.cf" postfix_master_cf="/etc/postfix/master.cf"
echo "" echo ""
echononl " Backup file \"${postfix_master_cf}\"" echononl " Backup file \"${postfix_master_cf}\""
@@ -4978,10 +5018,7 @@ while IFS='' read -r _line || [[ -n $_line ]] ; do
_found=true _found=true
cat >> $postfix_master_cf << EOF cat >> $postfix_master_cf << EOF
smtp inet n - y - - smtpd smtp inet n - y - - smtpd
-o smtpd_proxy_filter=127.0.0.1:10024 -o content_filter=amavisfeed:[127.0.0.1]:10024
-o content_filter=
-o smtpd_milters=
-o non_smtpd_milters=
EOF EOF
if [[ "$SASL_AUTH_ENABLED" = "no" ]] ; then if [[ "$SASL_AUTH_ENABLED" = "no" ]] ; then
cat >> $postfix_master_cf << EOF cat >> $postfix_master_cf << EOF
@@ -4989,19 +5026,6 @@ EOF
EOF EOF
fi fi
if ${listen_on_additional_smtp_port} ; then
cat >> $postfix_master_cf << EOF
${additional_smtp_port} inet n - y - - smtpd
-o smtpd_proxy_filter=127.0.0.1:10024
-o content_filter=
EOF
if [[ "$SASL_AUTH_ENABLED" = "no" ]] ; then
cat >> $postfix_master_cf << EOF
-o smtpd_sasl_auth_enable=no
EOF
fi
fi
if ! $submission_present && ! $smtps_present && ! $localhost_10025_present ; then if ! $submission_present && ! $smtps_present && ! $localhost_10025_present ; then
cat >> $postfix_master_cf << EOF cat >> $postfix_master_cf << EOF
localhost:10025 inet n - y - - smtpd localhost:10025 inet n - y - - smtpd
@@ -5016,13 +5040,10 @@ localhost:10025 inet n - y - - smtpd
-o mynetworks=127.0.0.0/8,[::1]/128 -o mynetworks=127.0.0.0/8,[::1]/128
-o receive_override_options=no_unknown_recipient_checks -o receive_override_options=no_unknown_recipient_checks
EOF EOF
if [[ -n "$(which opendkim)" && -n "$(which opendmarc)" ]] ; then if [[-n "$(which opendmarc)" ]] ; then
cat >> $postfix_master_cf << EOF cat >> $postfix_master_cf << EOF
-o smtpd_milters=local:/opendkim/opendkim.sock,local:/opendmarc/opendmarc.sock # IMPORTANT: no opendmarc here!
EOF #-o smtpd_milters=local:/opendmarc/opendmarc.sock
elif [[ -n "$(which opendkim)" ]] ; then
cat >> $postfix_master_cf << EOF
-o smtpd_milters=local:/opendkim/opendkim.sock
EOF EOF
fi fi
cat >> $postfix_master_cf << EOF cat >> $postfix_master_cf << EOF
@@ -5033,8 +5054,25 @@ EOF
continue continue
fi fi
if ${listen_on_additional_smtp_port} \
&& echo "$_line" | grep -i -E "^\s*${additional_smtp_port}\s+inet" > /dev/null 2>&1 ; then
_found=true
cat >> $postfix_master_cf << EOF
${additional_smtp_port} inet n - y - - smtpd
-o content_filter=amavisfeed:[127.0.0.1]:10024
EOF
if [[ "$SASL_AUTH_ENABLED" = "no" ]] ; then
cat >> $postfix_master_cf << EOF
-o smtpd_sasl_auth_enable=no
EOF
fi
if $submission_present && echo "$_line" | grep -i -E "^^submission\s+" > /dev/null 2>&1 ; then continue
fi
if $submission_present && echo "$_line" | grep -i -E "^submission\s+" > /dev/null 2>&1 ; then
_found=true _found=true
cat >> $postfix_master_cf << EOF cat >> $postfix_master_cf << EOF
submission inet n - y - 20 smtpd submission inet n - y - 20 smtpd
@@ -5042,8 +5080,13 @@ submission inet n - y - 20 smtpd
-o smtpd_tls_security_level=encrypt -o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes -o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject -o smtpd_client_restrictions=permit_sasl_authenticated,reject
#-o milter_macro_daemon_name=ORIGINATING
EOF EOF
if [[ -n "$(which opendkim)" ]] ; then
cat >> $postfix_master_cf << EOF
-o smtpd_milters=local:/opendkim/opendkim.sock
-o milter_macro_daemon_name=ORIGINATING
EOF
fi
if ! $smtps_present ; then if ! $smtps_present ; then
if ! $localhost_10025_present ; then if ! $localhost_10025_present ; then
cat >> $postfix_master_cf << EOF cat >> $postfix_master_cf << EOF
@@ -5059,26 +5102,19 @@ localhost:10025 inet n - y - - smtpd
-o mynetworks=127.0.0.0/8,[::1]/128 -o mynetworks=127.0.0.0/8,[::1]/128
-o receive_override_options=no_unknown_recipient_checks -o receive_override_options=no_unknown_recipient_checks
EOF EOF
if [[ -n "$(which opendkim)" && -n "$(which opendmarc)" ]] ; then if [[ -n "$(which opendmarc)" ]] ; then
cat >> $postfix_master_cf << EOF cat >> $postfix_master_cf << EOF
-o smtpd_milters=local:/opendkim/opendkim.sock,local:/opendmarc/opendmarc.sock # IMPORTANT: no opendmarc here!
EOF #-o smtpd_milters=local:/opendmarc/opendmarc.sock
elif [[ -n "$(which opendkim)" ]] ; then
cat >> $postfix_master_cf << EOF
-o smtpd_milters=local:/opendkim/opendkim.sock
EOF EOF
fi fi
cat >> $postfix_master_cf << EOF
#-o mynetworks=127.0.0.0/8,[::1]/128,${IPV4}/32
EOF
fi fi
if ! $amavisfeed_present ; then if ! $amavisfeed_present ; then
cat >> $postfix_master_cf << EOF cat >> $postfix_master_cf << EOF
amavisfeed unix - - n - 20 lmtp amavisfeed unix - - n - 20 lmtp
-o smtp_data_done_timeout=1200 -o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes -o smtp_send_xforward_command=yes
-o disable_dns_lookups=yes
EOF EOF
fi fi
fi # if ! $smtps_present fi # if ! $smtps_present
@@ -5092,12 +5128,17 @@ EOF
_found=true _found=true
cat >> $postfix_master_cf << EOF cat >> $postfix_master_cf << EOF
smtps inet n - y - - smtpd smtps inet n - y - - smtpd
-o content_filter=amavisfeed:[127.0.0.1]:10024 -o content_filter=amavisfeed:[127.0.0.1]:10024
-o smtpd_tls_wrappermode=yes -o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes -o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject -o smtpd_client_restrictions=permit_sasl_authenticated,reject
#-o milter_macro_daemon_name=ORIGINATING
EOF EOF
if [[ -n "$(which opendkim)" ]] ; then
cat >> $postfix_master_cf << EOF
-o smtpd_milters=local:/opendkim/opendkim.sock
-o milter_macro_daemon_name=ORIGINATING
EOF
fi
if ! $localhost_10025_present ; then if ! $localhost_10025_present ; then
cat >> $postfix_master_cf << EOF cat >> $postfix_master_cf << EOF
@@ -5113,26 +5154,19 @@ localhost:10025 inet n - y - - smtpd
-o mynetworks=127.0.0.0/8,[::1]/128 -o mynetworks=127.0.0.0/8,[::1]/128
-o receive_override_options=no_unknown_recipient_checks -o receive_override_options=no_unknown_recipient_checks
EOF EOF
if [[ -n "$(which opendkim)" && -n "$(which opendmarc)" ]] ; then if [[ -n "$(which opendmarc)" ]] ; then
cat >> $postfix_master_cf << EOF cat >> $postfix_master_cf << EOF
-o smtpd_milters=local:/opendkim/opendkim.sock,local:/opendmarc/opendmarc.sock # IMPORTANT: no opendmarc here!
EOF #-o smtpd_milters=local:/opendmarc/opendmarc.sock
elif [[ -n "$(which opendkim)" ]] ; then
cat >> $postfix_master_cf << EOF
-o smtpd_milters=local:/opendkim/opendkim.sock
EOF
fi
cat >> $postfix_master_cf << EOF
#-o mynetworks=127.0.0.0/8,[::1]/128,${IPV4}/32
EOF EOF
fi
fi fi
if ! $amavisfeed_present ; then if ! $amavisfeed_present ; then
cat >> $postfix_master_cf << EOF cat >> $postfix_master_cf << EOF
amavisfeed unix - - n - 20 lmtp amavisfeed unix - - n - 20 lmtp
-o smtp_data_done_timeout=1200 -o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes -o smtp_send_xforward_command=yes
-o disable_dns_lookups=yes
EOF EOF
fi fi
@@ -5156,18 +5190,12 @@ localhost:10025 inet n - y - - smtpd
-o mynetworks=127.0.0.0/8,[::1]/128 -o mynetworks=127.0.0.0/8,[::1]/128
-o receive_override_options=no_unknown_recipient_checks -o receive_override_options=no_unknown_recipient_checks
EOF EOF
if [[ -n "$(which opendkim)" && -n "$(which opendmarc)" ]] ; then if [[ -n "$(which opendmarc)" ]] ; then
cat >> $postfix_master_cf << EOF
-o smtpd_milters=local:/opendkim/opendkim.sock,local:/opendmarc/opendmarc.sock
EOF
elif [[ -n "$(which opendkim)" ]] ; then
cat >> $postfix_master_cf << EOF
-o smtpd_milters=local:/opendkim/opendkim.sock
EOF
fi
cat >> $postfix_master_cf << EOF cat >> $postfix_master_cf << EOF
#-o mynetworks=127.0.0.0/8,[::1]/128,${IPV4}/32 # IMPORTANT: no opendmarc here!
#-o smtpd_milters=local:/opendmarc/opendmarc.sock
EOF EOF
fi
continue continue
fi fi
@@ -5175,9 +5203,8 @@ EOF
_found=true _found=true
cat >> $postfix_master_cf << EOF cat >> $postfix_master_cf << EOF
amavisfeed unix - - n - 20 lmtp amavisfeed unix - - n - 20 lmtp
-o smtp_data_done_timeout=1200 -o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes -o smtp_send_xforward_command=yes
-o disable_dns_lookups=yes
EOF EOF
continue continue
fi fi

View File

@@ -94,9 +94,11 @@ echo_skipped() {
# - Is 'systemd' supported on this system # - Is 'systemd' supported on this system
# - # -
if [ "X`which systemd`" = "X" ]; then SYSTEMD_EXISTS=false
SYSTEMD_EXISTS=false systemd=$(which systemd)
else systemctl=$(which systemctl)
if [[ -n "$systemd" ]] || [[ -n "$systemctl" ]] ; then
SYSTEMD_EXISTS=true SYSTEMD_EXISTS=true
fi fi
@@ -204,73 +206,208 @@ else
cat <<EOF > $opendkim_conf_file 2> $log_file cat <<EOF > $opendkim_conf_file 2> $log_file
# Datei $opendkim_conf_file # Datei $opendkim_conf_file
# AuthservID (string)
#
# Sets the "authserv-id" to use when generating the Authentication-Results: # Sets the "authserv-id" to use when generating the Authentication-Results:
# header field after verifying a message. The default is to use the name of # header field after verifying a message. The default is to use the name of
# the MTA processing the message. If the string "HOSTNAME" is provided, the # the MTA processing the message. If the string "HOSTNAME" is provided, the
# name of the host running the filter (as returned by the gethostname(3) # name of the host running the filter (as returned by the gethostname(3)
# function) will be used. # function) will be used.
AuthservID "DKIM check $(hostname -f)" AuthservID HOSTNAME
# Mode (string)
#
# OpenDKIM agiert als Mail Filter (= Milter) in den # OpenDKIM agiert als Mail Filter (= Milter) in den
# Modi signer (s) und verifier (v) und verwendet eine # Modi signer (s) und verifier (v) und verwendet eine
# Socket-Datei zur Kommunikation (alternativ: lokaler Port) # Socket-Datei zur Kommunikation (alternativ: lokaler Port)
Mode sv Mode sv
# Socket (string)
#
# Specifies the socket that should be established by the filter to receive
# connections from sendmail(8) in order to provide service. socketspec is
# in one of two forms: local:path, which creates a UNIX domain socket at
# the specified path, or inet:port[@host] or inet6:port[@host] which
# creates a TCP socket on the specified port and in the specified protocol
# family. If the host is not given as either a hostname or an IP address,
# the socket will be listening on all interfaces. A literal IP address must
# be enclosed in square brackets. This option is mandatory either in the
# configuration file or on the command line.
#
# Socket local:/var/run/opendkim/opendkim.sock # Socket local:/var/run/opendkim/opendkim.sock
# Socket local:$opendkim_socket_file # Socket local:$opendkim_socket_file
# Socket inet:12345@localhost # Socket inet:12345@localhost
Socket local:$opendkim_socket_file Socket local:$opendkim_socket_file
# OpenDKIM verwendet diesen Benutzer bzw. # UserID (string)
# diese Gruppe #
# Attempts to become the specified userid before starting operations. The
# value is of the form userid[:group]. The process will be assigned all of
# the groups and primary group ID of the named userid unless an alternate
# group is specified.
UserID opendkim:opendkim UserID opendkim:opendkim
# UMask (integer)
#
#Requests a specific permissions mask to be used for file creation. This
# only really applies to creation of the socket when Socket specifies a UNIX
# domain socket, and to the PidFile (if any); temporary files are created by
# the mkstemp(3) function that enforces a specific file mode on creation
# regardless of the process umask. See umask(2) for more information.
#
UMask 002 UMask 002
# PidFile (string)
#
# Specifies the path to a file that should be created at process start
# containing the process ID.
PidFile /var/run/opendkim/opendkim.pid PidFile /var/run/opendkim/opendkim.pid
# OpenDKIM bei Problemen neustarten, # AutoRestart (Boolean)
# aber max. 10 mal pro Stunde #
# Automatically re-start on failures. Use with caution; if the filter fails
# instantly after it starts, this can cause a tight fork(2) loop.
AutoRestart yes AutoRestart yes
# AutoRestartRate (string)
#
# Sets the maximum automatic restart rate. If the filter begins restarting
# faster than the rate defined here, it will give up and terminate. This is
# a string of the form n/t[u] where n is an integer limiting the count of
# restarts in the given interval and t[u] defines the time interval through
# which the rate is calculated; t is an integer and u defines the units thus
# represented ("s" or "S" for seconds, the default; "m" or "M" for minutes;
# "h" or "H" for hours; "d" or "D" for days). For example, a value of "10/1h"
# limits the restarts to 10 in one hour. There is no default, meaning restart
# rate is not limited.
AutoRestartRate 10/1h AutoRestartRate 10/1h
# Logging (wenn alles funktioniert eventuell reduzieren) # Syslog (Boolean)
#
# Log via calls to syslog(3) any interesting activity.
Syslog yes Syslog yes
# SyslogSuccess (Boolean)
#
# Log via calls to syslog(3) additional entries indicating successful signing
# or verification of messages.
SyslogSuccess yes SyslogSuccess yes
# LogWhy (boolean)
#
# If logging is enabled (see Syslog below), issues very detailed logging
# about the logic behind the filters decision to either sign a message or
# verify it. The logic behind the decision is non-trivial and can be confusing
# to administrators not familiar with its operation. A description of how the
# decision is made can be found in the OPERATIONS section of the opendkim(8)
# man page. This causes a large increase in the amount of log data generated
# for each message, so it should be limited to debugging use and not enabled
# for general operation.
LogWhy yes LogWhy yes
# Verfahren, wie Header und Body durch # Verfahren, wie Header und Body durch
# OpenDKIM verarbeitet werden sollen. # OpenDKIM verarbeitet werden sollen.
Canonicalization relaxed/simple Canonicalization relaxed/simple
# interne Mails nicht mit OpenDKIM verarbeiten # ExternalIgnoreList (dataset)
#
# Identifies a set of "external" hosts that may send mail through the server
# as one of the signing domains without credentials as such. This has the
# effect of suppressing the "external host (hostname) tried to send mail as
# (domain)" log messages. Entries in the data set should be of the same form
# as those of the PeerList option below. The set is empty by default.
ExternalIgnoreList refile:${opendkim_base_dir}/trusted ExternalIgnoreList refile:${opendkim_base_dir}/trusted
# InternalHosts (dataset)
#
# Identifies a set internal hosts whose mail should be signed rather than
# verified. Entries in this data set follow the same form as those of the
# PeerList option below. If not specified, the default of "127.0.0.1" is applied.
# Naturally, providing a value here overrides the default, so if mail from
# 127.0.0.1 should be signed, the list provided here should include that address
# explicitly.
InternalHosts refile:${opendkim_base_dir}/trusted InternalHosts refile:${opendkim_base_dir}/trusted
# welche Verschlüsselungs-Keys sollen für welche # SigningTable (dataset)
# Domains verwendet werden #
# (refile: für Dateien mit regulären Ausdrücke) # Defines a table used to select one or more signatures to apply to a message
# based on the address found in the From: header field. Keys in this table vary
# depending on the type of table used; values in this data set should include
# one field that contains a name found in the KeyTable (see above) that
# identifies which key should be used in generating the signature, and an
# optional second field naming the signer of the message that will be included
# in the "i=" tag in the generated signature. Note that the "i=" value will not
# be included in the signature if it conflicts with the signing domain
# (the "d=" value).
#
# If the first field contains only a "%" character, it will be replaced by the
# domain found in the From: header field. Similarly, within the optional second
# field, any "%" character will be replaced by the domain found in the From:
# header field.
#
# If this table specifies a regular expression file ("refile"), then the keys are
# wildcard patterns that are matched against the address found in the From:
# header field. Entries are checked in the order in which they appear in the file.
#
# For all other database types, the full user@host is checked first, then simply
# host, then user@.domain (with all superdomains checked in sequence, so
# "foo.example.com" would first check "user@foo.example.com", then "user@.example.com",
# then "user@.com"), then .domain, then user@*, and finally *.
SigningTable refile:${opendkim_base_dir}/signing.table SigningTable refile:${opendkim_base_dir}/signing.table
# KeyTable (dataset)
#
# Gives the location of a file mapping key names to signing keys. If present,
# overrides any KeyFile setting in the configuration file. The data set named here
# maps each key name to three values: (a) the name of the domain to use in the
# signature's "d=" value; (b) the name of the selector to use in the signature's
# "s=" value; and (c) either a private key or a path to a file containing a private
# key. If the first value consists solely of a percent sign ("%") character, it
# will be replaced by the apparent domain of the sender when generating a signature.
# If the third value starts with a slash ("/") character, or "./" or "../", then it
# is presumed to refer to a file from which the private key should be read, otherwise
# it is itself a PEM-encoded private key or a base64-encoded DER private key; a "%"
# in the third value in this case will be replaced by the apparent domain name of
# the sender. The SigningTable (see below) is used to select records from this table
# to be used to add signatures based on the message sender.
KeyTable ${opendkim_base_dir}/key.table KeyTable ${opendkim_base_dir}/key.table
# diesen Signatur-Algorithmus verwenden # SignatureAlgorithm (string)
#
# Selects the signing algorithm to use when generating signatures. Use 'opendkim -V'
# to see the list of supported algorithms. The default is rsa-sha256 if it is
# available, otherwise it will be rsa-sha1.
SignatureAlgorithm rsa-sha256 SignatureAlgorithm rsa-sha256
# Always oversign From (sign using actual From and a null From to prevent # OversignHeaders (dataset)
# malicious signatures header fields (From and/or others) between the signer #
# and the verifier. From is oversigned by default in the Debian pacakge # Specifies a set of header fields that should be included in all signature header
# because it is often the identity key used by reputation systems and thus # lists (the "h=" tag) once more than the number of times they were actually present
# somewhat security sensitive. # in the signed message. The set is empty by default. The purpose of this, and
# especially of listing an absent header field, is to prevent the addition of
# important fields between the signer and the verifier. Since the verifier would
# include that header field when performing verification if it had been added by an
# intermediary, the signed message and the verified message were different and the
# verification would fail. Note that listing a field name here and not listing it in
# the SignHeaders list is likely to generate invalid signatures.
OversignHeaders From OversignHeaders From
# AlwaysAddARHeader (Boolean)
#
# Add an "Authentication-Results:" header field even to unsigned messages # Add an "Authentication-Results:" header field even to unsigned messages
# from domains with no "signs all" policy. The reported DKIM result will be # from domains with no "signs all" policy. The reported DKIM result will be
# "none" in such cases. Normally unsigned mail from non-strict domains does # "none" in such cases. Normally unsigned mail from non-strict domains does
# not cause the results header field to be added. # not cause the results header field to be added.
AlwaysAddARHeader yes AlwaysAddARHeader yes
# Background (Boolean)
#
# Causes opendkim to fork and exits immediately, leaving the service running # Causes opendkim to fork and exits immediately, leaving the service running
# in the background. The default is "true". # in the background. The default is "true".
Background yes Background yes
# DNSTimeout (integer)
#
# Sets the DNS timeout in seconds. A value of 0 causes an infinite wait. The # Sets the DNS timeout in seconds. A value of 0 causes an infinite wait. The
# default is 5. Ignored if not using an asynchronous resolver package. See # default is 5. Ignored if not using an asynchronous resolver package. See
# also the NOTES section below. # also the NOTES section below.
@@ -299,8 +436,8 @@ else
fi fi
# - Create the directories to hold OpenDKIMs data files, assign # - Create the directories to hold OpenDKIMs data files, assign
# - ownership to the opendkim user, and restrict the file # - ownership to the opendkim user, and restrict the file
# - permissions: # - permissions:
# - # -
echononl " Create directory '$opendkim_base_dir'" echononl " Create directory '$opendkim_base_dir'"
@@ -389,7 +526,6 @@ else
127.0.0.1 127.0.0.1
::1 ::1
localhost localhost
$(hostname -f)
EOF EOF
opendkim_needs_restart=true opendkim_needs_restart=true
if [[ $? -eq 0 ]] ; then if [[ $? -eq 0 ]] ; then
@@ -401,7 +537,7 @@ EOF
fi fi
# - Create the OpenDKIM socket directory in Postfixs work area # - Create the OpenDKIM socket directory in Postfixs work area
# - and make sure it has the correct ownership: # - and make sure it has the correct ownership:
# - # -
echononl " Create the OpenDKIM socket directory in Postfixs work area.." echononl " Create the OpenDKIM socket directory in Postfixs work area.."
@@ -460,7 +596,7 @@ EOF
fi fi
# - Edit /etc/postfix/main.cf and add a section to activate # - Edit /etc/postfix/main.cf and add a section to activate
# - processing of e-mail through the OpenDKIM daemon: # - processing of e-mail through the OpenDKIM daemon:
# - # -
backup_date="$(date +%Y-%m-%d-%H%M)" backup_date="$(date +%Y-%m-%d-%H%M)"
@@ -507,7 +643,7 @@ milter_protocol = 6
# localhost:10025 section in master.cf: 'smtpd_milters=' # localhost:10025 section in master.cf: 'smtpd_milters='
# #
#smtpd_milters = local:/opendkim/opendkim.sock #smtpd_milters = local:/opendkim/opendkim.sock
smtpd_milters = smtpd_milters = local:/opendkim/opendkim.sock
# Was sind non_smtpd_milters? # Was sind non_smtpd_milters?
# #
@@ -552,15 +688,15 @@ fi
# - Prevent Postfix from setting the DKIM Header twice (one befor # - Prevent Postfix from setting the DKIM Header twice (one befor
# - and one after processing amavis # - and one after processing amavis
# - # -
# - To disable milter processing after amavis, add to your master.cf in # - To disable milter processing after amavis, add to your master.cf in
# - the after-amavis section: # - the after-amavis section:
# - 127.0.0.1:10025 inet n - - - - smtpd # - 127.0.0.1:10025 inet n - - - - smtpd
# - [...] # - [...]
# - -o smtpd_milters= # - -o smtpd_milters=
# - # -
# - If you want to run the milter after amavis, set in main.cf # - If you want to run the milter after amavis, set in main.cf
# - smtpd_milters= # - smtpd_milters=
# - to an empty string and add the smtpd_milters configuration to master.cf # - to an empty string and add the smtpd_milters configuration to master.cf
# - (after-section amavis) instead: # - (after-section amavis) instead:
# - -o smtpd_milters=local:/opendkim/opendkim.sock # - -o smtpd_milters=local:/opendkim/opendkim.sock
# - # -
@@ -589,6 +725,7 @@ while IFS='' read -r _line || [[ -n $_line ]] ; do
_found=false _found=false
if ! echo "$_line" | grep -i -q -E "^\s*-o\s+smtpd_milters=\s*local:/opendkim/opendkim.sock\s*$" ; then if ! echo "$_line" | grep -i -q -E "^\s*-o\s+smtpd_milters=\s*local:/opendkim/opendkim.sock\s*$" ; then
echo " -o smtpd_milters=local:/opendkim/opendkim.sock" >> "$tmp_master_file" echo " -o smtpd_milters=local:/opendkim/opendkim.sock" >> "$tmp_master_file"
echo " -o milter_macro_daemon_name=ORIGINATING" >> "$tmp_master_file"
_changed=true _changed=true
continue continue
fi fi
@@ -627,7 +764,7 @@ rm -f $tmp_master_file
echo "" echo ""
# - Restart OpenDKIM # - Restart OpenDKIM
# - # -
echononl " Restart OpenDKIM.." echononl " Restart OpenDKIM.."
if $opendkim_needs_restart ; then if $opendkim_needs_restart ; then
if $SYSTEMD_EXISTS ; then if $SYSTEMD_EXISTS ; then

View File

@@ -24,8 +24,8 @@ opendmarc_socket_dir="${postfix_spool_dir}/opendmarc"
opendmarc_socket_file="${opendmarc_socket_dir}/opendmarc.sock" opendmarc_socket_file="${opendmarc_socket_dir}/opendmarc.sock"
config_file_name_value_parameters=" config_file_name_value_parameters="
AuthservID|$(hostname -f) AuthservID|HOSTNAME
TrustedAuthservIDs|$(hostname -f) TrustedAuthservIDs|HOSTNAME
PidFile|/run/opendmarc/opendmarc.pid PidFile|/run/opendmarc/opendmarc.pid
RejectFailures|true RejectFailures|true
Syslog|true Syslog|true
@@ -37,11 +37,13 @@ config_file_name_value_parameters="
UMask|002 UMask|002
FailureReports|false FailureReports|false
AutoRestart|true AutoRestart|true
HistoryFile|/run/opendmarc/opendmarc.dat HistoryFile|/run/opendmarc/opendmarc.dat
SPFIgnoreResults|false SPFIgnoreResults|false
SPFSelfValidate|true SPFSelfValidate|true
Socket|${opendmarc_socket_file} Socket|${opendmarc_socket_file}
" "
declare -a config_file_name_value_parameter_arr=() declare -a config_file_name_value_parameter_arr=()
for _conf in $config_file_name_value_parameters ; do for _conf in $config_file_name_value_parameters ; do
config_file_name_value_parameter_arr+=("$_conf") config_file_name_value_parameter_arr+=("$_conf")
@@ -116,9 +118,11 @@ echo_skipped() {
# - Is 'systemd' supported on this system # - Is 'systemd' supported on this system
# - # -
if [ "X`which systemd`" = "X" ]; then SYSTEMD_EXISTS=false
SYSTEMD_EXISTS=false systemd=$(which systemd)
else systemctl=$(which systemctl)
if [[ -n "$systemd" ]] || [[ -n "$systemctl" ]] ; then
SYSTEMD_EXISTS=true SYSTEMD_EXISTS=true
fi fi
@@ -191,14 +195,39 @@ echononl " Add 'IgnoreHosts' with default value to the opendmarc.conf file.."
if ! $(grep -q -E "^IgnoreHosts\s+" ${opendmarc_conf_file} 2> /dev/null) ; then if ! $(grep -q -E "^IgnoreHosts\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
cat << EOF >> ${opendmarc_conf_file} cat << EOF >> ${opendmarc_conf_file}
## IgnoreHosts (string)
##
## Specifies the path to a file that contains a list of hostnames, IP addresses, ## Specifies the path to a file that contains a list of hostnames, IP addresses,
## and/or CIDR expressions identifying hosts whose SMTP connections are to be ## and/or CIDR expressions identifying hosts whose SMTP connections are to be
## ignored by the filter. If not specified, defaults to "127.0.0.1" only. ## ignored by the filter. If not specified, defaults to "127.0.0.1" only.
# #
IgnoreHosts 127.0.0.1 IgnoreHosts /etc/opendmarc/ignore.hosts
EOF
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
fi
# Optional - auch nach Absender-Domain ignorieren:
IgnoreMailFrom ${opendmarc_base_dir}/ignore.mailfrom # - Add 'IgnoreMailFrom' with default value to the original opendmarc.conf file
#
echononl " Add 'IgnoreMailFrom' with default value to the opendmarc.conf file.."
if ! $(grep -q -E "^IgnoreMailFrom\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
cat << EOF >> ${opendmarc_conf_file}
## IgnoreMailFrom (string)
##
## Gives a list of domain names whose mail (based on the From: domain)
## is to be ignored by the filter. The list should be comma-separated.
## Matching against this list is case-insensitive. The default is an
## empty list, meaning no mail is ignored.
#
IgnoreMailFrom /etc/opendmarc/ignore.mailfrom
EOF EOF
if [[ $? -eq 0 ]] ; then if [[ $? -eq 0 ]] ; then
echo_ok echo_ok
@@ -218,10 +247,12 @@ echononl " Add '${_param}' with default value to the opendmarc.conf file.."
if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
cat << EOF >> ${opendmarc_conf_file} cat << EOF >> ${opendmarc_conf_file}
## IgnoreAuthenticatedClients (Boolean)
##
## If set, causes mail from authenticated clients (i.e., those that used ## If set, causes mail from authenticated clients (i.e., those that used
## SMTP AUTH) to be ignored by the filter. The default is "false". ## SMTP AUTH) to be ignored by the filter. The default is "false".
# #
IgnoreAuthenticatedClients false IgnoreAuthenticatedClients true
EOF EOF
if [[ $? -eq 0 ]] ; then if [[ $? -eq 0 ]] ; then
echo_ok echo_ok
@@ -248,30 +279,7 @@ if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
# will be used. Matching against this list is case-insensitive. The default is to use the # will be used. Matching against this list is case-insensitive. The default is to use the
# value of AuthservID. # value of AuthservID.
# #
TrustedAuthservIDs OpenDMARC TrustedAuthservIDs HOSTNAME
EOF
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
fi
# - Add 'RequiredHeaders' with default value to the original opendmarc.conf file
#
_param="IgnoreAuthenticatedClients"
echononl " Add '${_param}' with default value to the opendmarc.conf file.."
if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
cat << EOF >> ${opendmarc_conf_file}
## If set, causes mail from authenticated clients (i.e., those that used
## SMTP AUTH) to be ignored by the filter. The default is "false".
#
IgnoreAuthenticatedClients false
EOF EOF
if [[ $? -eq 0 ]] ; then if [[ $? -eq 0 ]] ; then
echo_ok echo_ok
@@ -291,6 +299,8 @@ echononl " Add '${_param}' with default value to the opendmarc.conf file.."
if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
cat << EOF >> ${opendmarc_conf_file} cat << EOF >> ${opendmarc_conf_file}
## RequiredHeaders (Boolean)
##
## If set, the filter will ensure the header of the message conforms to the basic ## If set, the filter will ensure the header of the message conforms to the basic
## header field count restrictions laid out in RFC5322, Section 3.6. Messages ## header field count restrictions laid out in RFC5322, Section 3.6. Messages
## failing this test are rejected without further processing. A From: field from ## failing this test are rejected without further processing. A From: field from
@@ -316,10 +326,12 @@ echononl " Add '${_param}' with default value to the opendmarc.conf file.."
if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
cat << EOF >> ${opendmarc_conf_file} cat << EOF >> ${opendmarc_conf_file}
## AutoRestart (Boolean)
##
## Automatically re-start on failures. Use with caution; if the filter fails ## Automatically re-start on failures. Use with caution; if the filter fails
## instantly after it starts, this can cause a tight fork(2) loop. ## instantly after it starts, this can cause a tight fork(2) loop.
# #
AutoRestart false AutoRestart true
EOF EOF
if [[ $? -eq 0 ]] ; then if [[ $? -eq 0 ]] ; then
echo_ok echo_ok
@@ -339,6 +351,8 @@ echononl " Add '${_param}' with default value to the opendmarc.conf file.."
if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
cat << EOF >> ${opendmarc_conf_file} cat << EOF >> ${opendmarc_conf_file}
## HistoryFile (string)
##
## If set, specifies the location of a text file to which records are written ## If set, specifies the location of a text file to which records are written
## that can be used to generate DMARC aggregate reports. Records are batches of ## that can be used to generate DMARC aggregate reports. Records are batches of
## rows containing information about a single received message, and include all ## rows containing information about a single received message, and include all
@@ -347,7 +361,7 @@ if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
## imported into a relational database from which the aggregate reports can be ## imported into a relational database from which the aggregate reports can be
## extracted using opendmarc-importstats(8). ## extracted using opendmarc-importstats(8).
# #
HistoryFile /run/opendmarc/opendmarc.dat #HistoryFile /run/opendmarc/opendmarc.dat
EOF EOF
if [[ $? -eq 0 ]] ; then if [[ $? -eq 0 ]] ; then
echo_ok echo_ok
@@ -396,7 +410,7 @@ if ! $(grep -q -E "^${_param}\s+" ${opendmarc_conf_file} 2> /dev/null) ; then
## looks for SPF results in headers and always performs the SPF check itself when ## looks for SPF results in headers and always performs the SPF check itself when
## this is set. The default is "false". ## this is set. The default is "false".
# #
SPFSelfValidate false SPFSelfValidate true
EOF EOF
if [[ $? -eq 0 ]] ; then if [[ $? -eq 0 ]] ; then
echo_ok echo_ok
@@ -430,15 +444,6 @@ for _val in "${config_file_name_value_parameter_arr[@]}" ; do
echononl " $opendmarc_conf_file: ${_val_arr[0]} -> ${_val_arr[1]}.." echononl " $opendmarc_conf_file: ${_val_arr[0]} -> ${_val_arr[1]}.."
if $(grep -E -q "^\s*${_val_arr[0]}\s+${_val_arr[1]}\s*$" $opendmarc_conf_file 2> /dev/null) ; then if $(grep -E -q "^\s*${_val_arr[0]}\s+${_val_arr[1]}\s*$" $opendmarc_conf_file 2> /dev/null) ; then
echo_skipped echo_skipped
elif $(grep -E -q "^\s*#\s*${_val_arr[0]}\s+" $opendmarc_conf_file 2> /dev/null); then
perl -i -n -p -e "s&^(\s*#\s*${_val_arr[0]}.*)&\1\n${_val_arr[0]} ${_val_arr[1]}&" $opendmarc_conf_file > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
opendmarc_needs_restart=true
else
echo_failed
error "$(cat $log_file)"
fi
elif $(grep -E -q "^\s*${_val_arr[0]}\s+" $opendmarc_conf_file 2> /dev/null) ; then elif $(grep -E -q "^\s*${_val_arr[0]}\s+" $opendmarc_conf_file 2> /dev/null) ; then
perl -i -n -p -e "s#^(\s*${_val_arr[0]}.*)#\#\1\n${_val_arr[0]} ${_val_arr[1]}#" $opendmarc_conf_file > "$log_file" 2>&1 perl -i -n -p -e "s#^(\s*${_val_arr[0]}.*)#\#\1\n${_val_arr[0]} ${_val_arr[1]}#" $opendmarc_conf_file > "$log_file" 2>&1
if [[ $? -eq 0 ]] ; then if [[ $? -eq 0 ]] ; then
@@ -448,11 +453,8 @@ for _val in "${config_file_name_value_parameter_arr[@]}" ; do
echo_failed echo_failed
error "$(cat $log_file)" error "$(cat $log_file)"
fi fi
else elif $(grep -E -q "^\s*#\s*${_val_arr[0]}\s+" $opendmarc_conf_file 2> /dev/null); then
cat <<EOF >> $opendmarc_conf_file 2> "$log_file" perl -i -n -p -e "s&^(\s*#\s*${_val_arr[0]}.*)&\1\n${_val_arr[0]} ${_val_arr[1]}&" $opendmarc_conf_file > "$log_file" 2>&1
${_val_arr[0]} ${_val_arr[1]}
EOF
if [[ $? -eq 0 ]] ; then if [[ $? -eq 0 ]] ; then
echo_ok echo_ok
opendmarc_needs_restart=true opendmarc_needs_restart=true
@@ -460,6 +462,100 @@ EOF
echo_failed echo_failed
error "$(cat $log_file)" error "$(cat $log_file)"
fi fi
else
if [[ "${_val_arr[0]}" == "IgnoreHosts" ]]; then
cat <<EOF >> $opendmarc_conf_file 2> "$log_file"
## IgnoreHosts (string)
##
## Specifies the path to a file that contains a list of hostnames, IP
## addresses, and/or CIDR expressions identifying hosts whose SMTP
## connections are to be ignored by the filter. If not specified,
## defaults to "127.0.0.1" only.
#
${_val_arr[0]} ${_val_arr[1]}
EOF
elif [[ "${_val_arr[0]}" == "IgnoreMailFrom" ]]; then
cat <<EOF >> $opendmarc_conf_file 2> "$log_file"
## IgnoreMailFrom (string)
##
## Gives a list of domain names whose mail (based on the From: domain)
## is to be ignored by the filter. The list should be comma-separated.
## Matching against this list is case-insensitive. The default is an
## empty list, meaning no mail is ignored.
#
${_val_arr[0]} ${_val_arr[1]}
EOF
elif [[ "${_val_arr[0]}" == "IgnoreAuthenticatedClients" ]]; then
cat <<EOF >> $opendmarc_conf_file 2> "$log_file"
## IgnoreAuthenticatedClients (Boolean)
##
## If set, causes mail from authenticated clients (i.e., those that used
## SMTP AUTH) to be ignored by the filter. The default is "false".
#
${_val_arr[0]} ${_val_arr[1]}
EOF
elif [[ "${_val_arr[0]}" == "AutoRestart" ]]; then
cat <<EOF >> $opendmarc_conf_file 2> "$log_file"
## AutoRestart (Boolean)
##
## Automatically re-start on failures. Use with caution; if the filter
## fails instantly after it starts, this can cause a tight fork(2)
## loop.
#
${_val_arr[0]} ${_val_arr[1]}
EOF
elif [[ "${_val_arr[0]}" == "RequiredHeaders" ]]; then
cat <<EOF >> $opendmarc_conf_file 2> "$log_file"
## RequiredHeaders (Boolean)
##
## If set, the filter will ensure the header of the message conforms to
## the basic header field count restrictions laid out in RFC5322,
## Section 3.6. Messages failing this test are rejected without further
## processing. A From: field from which no domain name could be
## extracted will also be rejected.
#
${_val_arr[0]} ${_val_arr[1]}
EOF
elif [[ "${_val_arr[0]}" == "SPFSelfValidate" ]]; then
cat <<EOF >> $opendmarc_conf_file 2> "$log_file"
## SPFSelfValidate (Boolean)
##
## Causes the filter to perform a fallback SPF check itself when it can
## find no SPF results in the message header. If SPFIgnoreResults is
## also set, it never looks for SPF results in headers and always
## performs the SPF check itself when this is set. The default is
## "false".
#
${_val_arr[0]} ${_val_arr[1]}
EOF
elif [[ "${_val_arr[0]}" == "SPFIgnoreResults" ]]; then
cat <<EOF >> $opendmarc_conf_file 2> "$log_file"
## SPFIgnoreResults (Boolean)
##
## Causes the filter to ignore any SPF results in the header of the
## message. This is useful if you want the filter to perform SPF checks
## itself, or because you don't trust the arriving header. The default
## is "false".
#
${_val_arr[0]} ${_val_arr[1]}
EOF
else
cat <<EOF >> $opendmarc_conf_file 2> "$log_file"
${_val_arr[0]} ${_val_arr[1]}
EOF
if [[ $? -eq 0 ]] ; then
echo_ok
opendmarc_needs_restart=true
else
echo_failed
error "$(cat $log_file)"
fi
fi
fi fi
done done
@@ -684,15 +780,37 @@ if $(grep -q -E "^\s*non_smtpd_milters\s*=\s*.*opendkim.sock" /etc/postfix/main.
fi fi
fi fi
else else
echo_skipped echo_skipped
warn "Postfix is not adjusted. Complete Postfix configuration (main.cf) manually\!" warn "non_smtpd_milters is not adjusted. Complete Postfix configuration (main.cf) manually\!"
fi
echononl " Set Variable smtpd_milters at '/etc/postfix/main.cf'.."
if $(grep -q -E "^\s*smtpd_milters\s*=\s*.*opendkim.sock" /etc/postfix/main.cf 2> /dev/null) ; then
if $(grep -q -E "^\s*smtpd_milters\s*=\s*.*$(basename "${opendmarc_socket_file}")" /etc/postfix/main.cf); then
echo_skipped
else
perl -i -n -p -e "s&^\s*(smtpd_milters\s*=.*opendkim.sock)&\1,local:/$(basename "${opendmarc_socket_dir}")/$(basename "${opendmarc_socket_file}")&" \
/etc/postfix/main.cf > $log_file 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
postfix_needs_restart=true
else
echo_failed
error "$(cat $log_file)"
fi
fi
else
echo_skipped
warn "smtpd_milters was not adjusted. Complete Postfix configuration (main.cf) manually\!"
fi fi
echo "" echo ""
# - Edit /etc/postfix/main.cf and add a section to activate # - Edit /etc/postfix/main.cf and add a section to activate
# - processing of e-mail through the OpenDKIM daemon: # - processing of e-mail through the OpenDKIM daemon:
# - # -
backup_date="$(date +%Y-%m-%d-%H%M)" backup_date="$(date +%Y-%m-%d-%H%M)"
@@ -722,7 +840,7 @@ else
# ======= Milter configuration ======= # ======= Milter configuration =======
# OpenDKIM # OpenDKIM, OpenDMARC
milter_default_action = accept milter_default_action = accept
@@ -738,8 +856,7 @@ milter_protocol = 6
# 'smtpd_milters = local:/opendkim/opendkim.sock' here and add to # 'smtpd_milters = local:/opendkim/opendkim.sock' here and add to
# localhost:10025 section in master.cf: 'smtpd_milters=' # localhost:10025 section in master.cf: 'smtpd_milters='
# #
#smtpd_milters = local:/opendkim/opendkim.sock smtpd_milters = local:/opendkim/opendkim.sock, local:/opendmarc/opendmarc.sock
smtpd_milters =
# Was sind non_smtpd_milters? # Was sind non_smtpd_milters?
# #
@@ -769,7 +886,7 @@ smtpd_milters =
# #
# #
# DKIM soll auch die ausgehenden Mails signieren, die nicht über smtpd daemon versendet werden. # DKIM soll auch die ausgehenden Mails signieren, die nicht über smtpd daemon versendet werden.
non_smtpd_milters = local:/opendkim/opendkim.sock non_smtpd_milters = local:/opendkim/opendkim.sock, local:/opendmarc/opendmarc.sock
EOF EOF
postfix_needs_restart=true postfix_needs_restart=true
if [[ $? -eq 0 ]] ; then if [[ $? -eq 0 ]] ; then
@@ -781,87 +898,6 @@ EOF
fi fi
echo ""
# - Prevent Postfix from setting the DMARC Header twice (one befor
# - and one after processing amavis
# -
# - To disable milter processing after amavis, add to your master.cf in
# - the after-amavis section:
# - 127.0.0.1:10025 inet n - - - - smtpd
# - [...]
# - -o smtpd_milters=
# -
# - If you want to run the milter after amavis, set in main.cf
# - smtpd_milters=
# - to an empty string and add the smtpd_milters configuration to master.cf
# - (after-section amavis) instead:
# - -o smtpd_milters=local:/opendmarc/opendmarc.sock
# -
echononl " Backup file '/etc/postfix/master.cf'.."
cp -a /etc/postfix/master.cf /etc/postfix/master.cf.${backup_date} 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
echononl " Adjust /etc/postfix/master.cf. Set DMARC after sending throuh AmaVIS.."
_found=false
_changed=false
tmp_master_file="/tmp/postfix_master.cf"
> $tmp_master_file
while IFS='' read -r _line || [[ -n $_line ]] ; do
if $_found && ! echo "$_line" | grep -i -q -E "^\s*-o" 2> /dev/null ; then
echo " -o smtpd_milters=local:/opendmarc/opendmarc.sock" >> "$tmp_master_file"
_changed=true
_found=false
fi
if $_found && echo "$_line" | grep -i -q -E "^\s*-o\s+smtpd_milters=\s*" ; then
_found=false
if ! echo "$_line" | grep -i -q -E "^\s*-o\s+smtpd_milters=\s*local:/opendmarc/opendmarc.sock\s*$" ; then
echo " -o smtpd_milters=local:/opendmarc/opendmarc.sock" >> "$tmp_master_file"
_changed=true
continue
fi
fi
if echo "$_line" | grep -i -q -E "^\s*(localhost|127.0.0.1):10025\s+inet\s+" 2> /dev/null ; then
_found=true
fi
echo "$_line" >> "$tmp_master_file"
done < "/etc/postfix/master.cf"
if $_changed ; then
cp $tmp_master_file /etc/postfix/master.cf 2> $log_file
postfix_needs_restart=true
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
info "Postfix (master.cf) was not changed - seems already be configured right."
echononl " Delete previosly saved file '/etc/postfix/master.cf'.."
rm /etc/postfix/master.cf.$backup_date 2> $log_file
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
fi
rm -f $tmp_master_file
echo "" echo ""
echononl " Enable OpenDMARC Service" echononl " Enable OpenDMARC Service"

View File

@@ -136,9 +136,11 @@ DEFAULT_INSTALL_DMARC_REPORT_SUPPORT=false
# - Is this a systemd system? # - Is this a systemd system?
# - # -
if [[ "X`which systemd`" = "X" ]]; then systemd_exists=false
systemd_exists=false systemd=$(which systemd)
else systemctl=$(which systemctl)
if [[ -n "$systemd" ]] || [[ -n "$systemctl" ]] ; then
systemd_exists=true systemd_exists=true
fi fi
@@ -450,8 +452,8 @@ else
fi fi
INSTALL_DMARC_REPORT_SUPPORT=false
if ! ${IS_RELAY_HOST} ; then if ! ${IS_RELAY_HOST} ; then
INSTALL_DMARC_REPORT_SUPPORT=false
echo "" echo ""
echo -e "\033[32m--\033[m" echo -e "\033[32m--\033[m"
echo "" echo ""
@@ -578,9 +580,6 @@ fi
[[ "$IPV6" = "disabled" ]] && IPV6="" [[ "$IPV6" = "disabled" ]] && IPV6=""
exit
clean_up 1
# - Synchronise package index files with the repository # - Synchronise package index files with the repository
# - # -
@@ -2124,7 +2123,9 @@ smtpd_tls_key_file = $_TLS_KEY_FILE
#smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_1024.pem #smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_1024.pem
## - also possible to use 2048 key with that parameter ## - also possible to use 2048 key with that parameter
## - ## -
smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_2048.pem ## - DEPRECATED parameter-
## -
#smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_2048.pem
## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. ## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers.
## - ## -
@@ -3825,7 +3826,8 @@ if ${INSTALL_DMARC_REPORT_SUPPORT} ; then
# - ├── processed/ # Originalmails (Archiv) # - ├── processed/ # Originalmails (Archiv)
# - ├── exports/ # CSV- und Top-Auswertungen # - ├── exports/ # CSV- und Top-Auswertungen
# - └── logs/ # Logdateien # - └── logs/ # Logdateien
echononl "Add directory Structure for collecting and analysing DMARC reports.." echo ""
echononl " Add directory Structure for collecting and analysing DMARC reports.."
install -d -o vmail -g vmail -m 750 /var/lib/dmarc/{reports,processed,exports,logs} > /dev/null 2> $log_file install -d -o vmail -g vmail -m 750 /var/lib/dmarc/{reports,processed,exports,logs} > /dev/null 2> $log_file
if [[ $? -eq 0 ]] ; then if [[ $? -eq 0 ]] ; then
echo_ok echo_ok
@@ -3834,7 +3836,7 @@ if ${INSTALL_DMARC_REPORT_SUPPORT} ; then
error "$(cat $log_file)" error "$(cat $log_file)"
fi fi
echononl "Add 'dmarc-pipe' entry to $postfix_master_cf .." echononl " Add 'dmarc-pipe' entry to $postfix_master_cf .."
cat <<EOF >> /etc/postfix/transport 2> $log_file cat <<EOF >> /etc/postfix/transport 2> $log_file
# - Take care your master.cf file ($postfix_master_cf) contains: # - Take care your master.cf file ($postfix_master_cf) contains:
@@ -3852,7 +3854,7 @@ EOF
error "$(cat $log_file)" error "$(cat $log_file)"
fi fi
echononl "Create Postfix lookup table '/etc/postfix/transport'.." echononl " Create Postfix lookup table '/etc/postfix/transport'.."
postmap btree:/etc/postfix/transport > /dev/null 2> $log_file postmap btree:/etc/postfix/transport > /dev/null 2> $log_file
if [[ $? -eq 0 ]] ; then if [[ $? -eq 0 ]] ; then
echo_ok echo_ok
@@ -3861,7 +3863,7 @@ EOF
error "$(cat $log_file)" error "$(cat $log_file)"
fi fi
echononl "Create script '/usr/local/bin/dmarc-collect.sh'.." echononl " Create script '/usr/local/bin/dmarc-collect.sh'.."
tee /usr/local/bin/dmarc-collect.sh > /dev/null 2> $log_file <<'EOF' tee /usr/local/bin/dmarc-collect.sh > /dev/null 2> $log_file <<'EOF'
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
@@ -3919,7 +3921,7 @@ EOF
fi fi
_failed=false _failed=false
echononl "Set permissions for '/usr/local/bin/dmarc-collect.sh'.." echononl " Set permissions for '/usr/local/bin/dmarc-collect.sh'.."
chown vmail:vmail /usr/local/bin/dmarc-collect.sh > /dev/null 2> $log_file chown vmail:vmail /usr/local/bin/dmarc-collect.sh > /dev/null 2> $log_file
if [[ $? -ne 0 ]] ; then if [[ $? -ne 0 ]] ; then
_failed=true _failed=true

View File

@@ -136,9 +136,11 @@ DEFAULT_REWRITE_SENDER_DOMAIN=None
# - Is this a systemd system? # - Is this a systemd system?
# - # -
if [[ "X`which systemd`" = "X" ]]; then systemd_exists=false
systemd_exists=false systemd=$(which systemd)
else systemctl=$(which systemctl)
if [[ -n "$systemd" ]] || [[ -n "$systemctl" ]] ; then
systemd_exists=true systemd_exists=true
fi fi
@@ -927,7 +929,9 @@ smtpd_tls_key_file = $_TLS_KEY_FILE
#smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_1024.pem #smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_1024.pem
## - also possible to use 2048 key with that parameter ## - also possible to use 2048 key with that parameter
## - ## -
smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_2048.pem ## - DEPRECATED parameter-
## -
#smtpd_tls_dh1024_param_file = /etc/postfix/ssl/dh_2048.pem
## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers. ## - File with DH parameters that the Postfix SMTP server should use with EDH ciphers.
## - ## -

View File

@@ -2496,7 +2496,7 @@ fi
## - $CONF['show_undeliverable']='NO'; ## - $CONF['show_undeliverable']='NO';
## - $CONF['show_popimap']='NO'; ## - $CONF['show_popimap']='NO';
## - ## -
## - $CONF['used_quotas'] = 'YES'; ## - $CONF['used_quotas'] = 'NO';
## - $CONF['new_quota_table'] = 'YES'; ## - $CONF['new_quota_table'] = 'YES';
## - ## -
echononl "\tAdjust Postfix Admin's Configuration - Part 5" echononl "\tAdjust Postfix Admin's Configuration - Part 5"
@@ -2528,7 +2528,7 @@ perl -i -n -p -e "s#^(\s*\\\$CONF\['show_undeliverable'\]\s*=.*)#//!\1\n\\\$CONF
$pfa_conf_file >> $log_file 2>&1 || _failed=true $pfa_conf_file >> $log_file 2>&1 || _failed=true
perl -i -n -p -e "s#^(\s*\\\$CONF\['show_popimap'\]\s*=.*)#//!\1\n\\\$CONF['show_popimap'] = 'NO';#" \ perl -i -n -p -e "s#^(\s*\\\$CONF\['show_popimap'\]\s*=.*)#//!\1\n\\\$CONF['show_popimap'] = 'NO';#" \
$pfa_conf_file >> $log_file 2>&1 || _failed=true $pfa_conf_file >> $log_file 2>&1 || _failed=true
perl -i -n -p -e "s#^(\s*\\\$CONF\['used_quotas'\]\s*=.*)#//!\1\n\\\$CONF['used_quotas'] = 'YES';#" \ perl -i -n -p -e "s#^(\s*\\\$CONF\['used_quotas'\]\s*=.*)#//!\1\n\\\$CONF['used_quotas'] = 'NO';#" \
$pfa_conf_file >> $log_file 2>&1 || _failed=true $pfa_conf_file >> $log_file 2>&1 || _failed=true
perl -i -n -p -e "s#^(\s*\\\$CONF\['new_quota_table'\]\s*=.*)#//!\1\n\\\$CONF['new_quota_table'] = 'YES';#" \ perl -i -n -p -e "s#^(\s*\\\$CONF\['new_quota_table'\]\s*=.*)#//!\1\n\\\$CONF['new_quota_table'] = 'YES';#" \
$pfa_conf_file >> $log_file 2>&1 || _failed=true $pfa_conf_file >> $log_file 2>&1 || _failed=true

View File

@@ -65,6 +65,14 @@ echo_skipped() {
echo -e "\033[80G[ \033[33m\033[1mskipped\033[m ]" echo -e "\033[80G[ \033[33m\033[1mskipped\033[m ]"
} }
systemd_exists=false
systemd=$(which systemd)
systemctl=$(which systemctl)
if [[ -n "$systemd" ]] || [[ -n "$systemctl" ]] ; then
systemd_exists=true
fi
## - Install Postfix Firewall Daemon from debian packages system ## - Install Postfix Firewall Daemon from debian packages system
## - ## -
echononl " Install Postfix Firewall Daemon from debian packages system" echononl " Install Postfix Firewall Daemon from debian packages system"

View File

@@ -964,9 +964,11 @@ delete_variable_with_comments() {
# - Support systemd ? # - Support systemd ?
# - # -
if [[ "X$(which systemd)" = "X" ]]; then SYSTEMD_EXISTS=false
SYSTEMD_EXISTS=false systemd=$(which systemd)
else systemctl=$(which systemctl)
if [[ -n "$systemd" ]] || [[ -n "$systemctl" ]] ; then
SYSTEMD_EXISTS=true SYSTEMD_EXISTS=true
fi fi
@@ -1024,6 +1026,13 @@ if [[ "$database" != "postgres" ]] && [[ "$database" != "mysql" ]] ; then
fi fi
[[ -n "$dbpassword" ]] || fatal "Parameter "dbpassword" not set." [[ -n "$dbpassword" ]] || fatal "Parameter "dbpassword" not set."
lang="${msg_language,,}"
if [[ "$lang" =~ ^(en|us|en_us)$ ]]; then
msg_language="en"
else
msg_language="de"
fi
[[ -n "$from_address" ]] || fatal ""Parameter "from_address" not set."" [[ -n "$from_address" ]] || fatal ""Parameter "from_address" not set.""
[[ -n "$reply_to" ]] || fatal ""Parameter "reply_to" not set."" [[ -n "$reply_to" ]] || fatal ""Parameter "reply_to" not set.""
[[ -n "$webmailer" ]] || fatal ""Parameter "webmailer" not set."" [[ -n "$webmailer" ]] || fatal ""Parameter "webmailer" not set.""
@@ -2630,6 +2639,58 @@ if $_new ; then
fi fi
# Dovecot's configure script queries pkg-config for "systemd" and expects
# the variable "systemdsystemunitdir" to be defined.
# On minimal Debian(13)-based systems, only libsystemd.pc is provided and
# no systemd.pc (and often no systemd binary) exists.
# This pkg-config wrapper provides the missing metadata so configure
# can auto-detect the correct systemd unit installation directory.
#
if [[ "${os_dist,,}" = "debian" ]] && [[ "$os_version" -ge 13 ]] ; then
echononl " Create '/usr/lib/x86_64-linux-gnu/pkgconfig/systemd.pc'."
if [[ ! -f "/usr/lib/x86_64-linux-gnu/pkgconfig/systemd.pc" ]] ; then
cat <<'EOF' > /usr/lib/x86_64-linux-gnu/pkgconfig/systemd.pc 2>>${_log_dir}/debian-install.log
prefix=/usr
exec_prefix=${prefix}
libdir=/usr/lib/x86_64-linux-gnu
includedir=/usr/include
# Some build systems (incl. Dovecot's configure) query this to decide where
# to install systemd service/unit files:
systemdsystemunitdir=/usr/lib/systemd/system
Name: systemd
Description: systemd (pkg-config compatibility wrapper)
Version: 0
Requires: libsystemd
EOF
if [[ $? -gt 0 ]] ; then
echo -e "$rc_failed"
error "$(cat $log_file)"
echo ""
echo " command was:"
echo " ln -s libsystemd.pc /usr/lib/x86_64-linux-gnu/pkgconfig/systemd.pc"
echo ""
echononl " continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Abbruch durch User"
else
echo -e "$rc_done"
fi
else
echo -e "$rc_skipped"
fi
fi
## ----------------- ## -----------------
## - Create Users/groups needed for dovecot ## - Create Users/groups needed for dovecot
@@ -2769,6 +2830,11 @@ if $systemd_support ; then
fi fi
#--with-systemdsystemunitdir=/etc/systemd/system/" #--with-systemdsystemunitdir=/etc/systemd/system/"
#if [[ "${os_dist,,}" = "debian" ]] && [[ "$os_version" -ge 13 ]] ; then
# config_params="$config_params systemdsystemunitdir=/lib/systemd/system"
#fi
echononl " Configure Dovecot.." echononl " Configure Dovecot.."
#./configure \ #./configure \
# --prefix=/usr/local/dovecot-${_version} \ # --prefix=/usr/local/dovecot-${_version} \
@@ -2790,11 +2856,12 @@ fi
## - Compile dovecot ## - Compile dovecot
## - ## -
echononl " Compile Dovecot Sources.." echononl " Compile Dovecot Sources.."
make > ${_log_dir}/dovecot-${_version}-make.log 2>&1 || clean_up 1 make > ${_log_dir}/dovecot-${_version}-make.log 2>&1
if [ "$?" = 0 ]; then if [ "$?" = 0 ]; then
echo -e "$rc_done" echo -e "$rc_done"
else else
echo -e "$rc_failed" echo -e "$rc_failed"
echo -e "\n See file \033[1m${_log_dir}/dovecot-${_version}-make.log\033[m for more details."
fatal Compiling dovecot failed fatal Compiling dovecot failed
fi fi
@@ -3141,12 +3208,12 @@ EOF
echononl " Create empty file '$(basename "${_conf_file}")'.." echononl " Create empty file '$(basename "${_conf_file}")'.."
if [[ ! -f "${_conf_file}" ]] ; then if [[ ! -f "${_conf_file}" ]] ; then
_failed=false _failed=false
cat <<'EOF' > "${_conf_file}" 2> "${log_file}" cat <<EOF > "${_conf_file}" 2> "${log_file}"
## ##
## Settings for the Sieve interpreter ## Settings for the Sieve interpreter
## ##
# see also: https://doc.dovecot.org/2.4.1/core/plugins/sieve.html # see also: https://doc.dovecot.org/${_version}/core/plugins/sieve.html
# To use Sieve, you will first need to make sure you are using Dovecot LDA or LMTP Server # To use Sieve, you will first need to make sure you are using Dovecot LDA or LMTP Server
# for delivering incoming mail to users' mailboxes. # for delivering incoming mail to users' mailboxes.
@@ -3211,12 +3278,12 @@ EOF
echononl " Create empty file '$(basename "${_conf_file}")'.." echononl " Create empty file '$(basename "${_conf_file}")'.."
if [[ ! -f "${_conf_file}" ]] ; then if [[ ! -f "${_conf_file}" ]] ; then
_failed=false _failed=false
cat <<'EOF' > "${_conf_file}" 2> "${log_file}" cat <<EOF > "${_conf_file}" 2> "${log_file}"
## ##
## Settings for the Sieve Vacation Extension ## Settings for the Sieve Vacation Extension
## ##
# see also: https://doc.dovecot.org/2.4.1/core/config/sieve/extensions/vacation.html # see also: https://doc.dovecot.org/${_version}/core/config/sieve/extensions/vacation.html
# The Sieve vacation extension (RFC 5230) defines a mechanism to generate automatic # The Sieve vacation extension (RFC 5230) defines a mechanism to generate automatic
# replies to incoming email messages. It takes various precautions to make sure replies # replies to incoming email messages. It takes various precautions to make sure replies
@@ -6281,7 +6348,7 @@ EOF
# same as IMAP's LOGIN command. The LOGIN command is internally handled using PLAIN # same as IMAP's LOGIN command. The LOGIN command is internally handled using PLAIN
# mechanism. # mechanism.
# #
# see https://doc.dovecot.org/2.4.1/core/config/auth/mechanisms/overview.html for # see https://doc.dovecot.org/${_version}/core/config/auth/mechanisms/overview.html for
# further (non-rcCleartext) Authentication. # further (non-rcCleartext) Authentication.
auth_mechanisms = ${auth_mechanisms} auth_mechanisms = ${auth_mechanisms}
EOF EOF
@@ -6407,11 +6474,11 @@ if [[ $dovecot_major_version -gt 2 ]] \
if [[ "$db_driver" = "pgsql" ]]; then if [[ "$db_driver" = "pgsql" ]]; then
read -r -d '' NEW_BLOCK <<'EOF' read -r -d '' NEW_BLOCK <<EOF
passdb sql { passdb sql {
# Load SQL connection data # Load SQL connection data
!include /usr/local/dovecot-2.4.1-4/etc/dovecot/sql-connect.conf.ext !include /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext
query = SELECT username AS user, password \\ query = SELECT username AS user, password \\
FROM mailbox \\ FROM mailbox \\
@@ -6439,18 +6506,18 @@ EOF
# LMTP mail delivery YES YES # LMTP mail delivery YES YES
# doveadm commands YES YES # doveadm commands YES YES
# #
# see also: https://doc.dovecot.org/2.4.1/core/config/auth/passdb.html # see also: https://doc.dovecot.org/${_version}/core/config/auth/passdb.html
# #
$(echo -e "${NEW_BLOCK}") $(echo -e "${NEW_BLOCK}")
EOF EOF
fi fi
read -r -d '' NEW_BLOCK <<'EOF' read -r -d '' NEW_BLOCK <<EOF
userdb sql { userdb sql {
# Load SQL connection data # Load SQL connection data
!include /usr/local/dovecot-2.4.1-4/etc/dovecot/sql-connect.conf.ext !include /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext
query = SELECT '/var/vmail/' || maildir AS home, \\ query = SELECT '/var/vmail/' || maildir AS home, \\
'5000' AS uid, '5000' AS gid \\ '5000' AS uid, '5000' AS gid \\
@@ -6487,7 +6554,7 @@ EOF
# The userdb and passdb may be the same or they may be different depending on your needs. # The userdb and passdb may be the same or they may be different depending on your needs.
# You can also have multiple authentication databases. # You can also have multiple authentication databases.
# #
# see: https://doc.dovecot.org/2.4.1/core/config/auth/userdb.html # see: https://doc.dovecot.org/${_version}/core/config/auth/userdb.html
# #
$(echo -e "${NEW_BLOCK}") $(echo -e "${NEW_BLOCK}")
EOF EOF
@@ -6495,11 +6562,11 @@ EOF
elif [[ "$db_driver" = "mysql" ]]; then elif [[ "$db_driver" = "mysql" ]]; then
read -r -d '' NEW_BLOCK <<'EOF' read -r -d '' NEW_BLOCK <<EOF
passdb sql { passdb sql {
# Load SQL connection data # Load SQL connection data
!include /usr/local/dovecot-2.4.1-4/etc/dovecot/sql-connect.conf.ext !include /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext
query = SELECT username AS user, password \\ query = SELECT username AS user, password \\
FROM mailbox \\ FROM mailbox \\
@@ -6527,17 +6594,17 @@ EOF
# LMTP mail delivery YES YES # LMTP mail delivery YES YES
# doveadm commands YES YES # doveadm commands YES YES
# #
# see also: https://doc.dovecot.org/2.4.1/core/config/auth/passdb.html # see also: https://doc.dovecot.org/${_version}/core/config/auth/passdb.html
# #
$(echo -e "${NEW_BLOCK}") $(echo -e "${NEW_BLOCK}")
EOF EOF
fi fi
read -r -d '' NEW_BLOCK <<'EOF' read -r -d '' NEW_BLOCK <<EOF
userdb sql { userdb sql {
# Load SQL connection data # Load SQL connection data
!include /usr/local/dovecot-2.4.1-4/etc/dovecot/sql-connect.conf.ext !include /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext
query = SELECT CONCAT('/var/vmail/',maildir) AS home, \\ query = SELECT CONCAT('/var/vmail/',maildir) AS home, \\
'5000' AS uid, '5000' AS gid \\ '5000' AS uid, '5000' AS gid \\
@@ -6574,7 +6641,7 @@ EOF
# The userdb and passdb may be the same or they may be different depending on your needs. # The userdb and passdb may be the same or they may be different depending on your needs.
# You can also have multiple authentication databases. # You can also have multiple authentication databases.
# #
# see: https://doc.dovecot.org/2.4.1/core/config/auth/userdb.html # see: https://doc.dovecot.org/${_version}/core/config/auth/userdb.html
# #
$(echo -e "${NEW_BLOCK}") $(echo -e "${NEW_BLOCK}")
EOF EOF
@@ -7071,7 +7138,7 @@ if [[ $dovecot_major_version -gt 2 ]] \
# #
# As used here, %{user | domain} expands to the domain of the local user. Other Mail user # As used here, %{user | domain} expands to the domain of the local user. Other Mail user
# variables can be used as well. # variables can be used as well.
# see: https://doc.dovecot.org/2.4.1/core/settings/variables.html#mail-user-variables # see: https://doc.dovecot.org/${_version}/core/settings/variables.html#mail-user-variables
postmaster_address = ${postmaster_address} postmaster_address = ${postmaster_address}
EOF EOF
fi fi
@@ -7221,7 +7288,7 @@ protocol lmtp {
# #
# As used here, %{user | domain} expands to the domain of the local user. Other Mail user # As used here, %{user | domain} expands to the domain of the local user. Other Mail user
# variables can be used as well. # variables can be used as well.
# see: https://doc.dovecot.org/2.4.1/core/settings/variables.html#mail-user-variables # see: https://doc.dovecot.org/${_version}/core/settings/variables.html#mail-user-variables
postmaster_address = ${postmaster_address} postmaster_address = ${postmaster_address}
mail_plugins { mail_plugins {
@@ -7586,9 +7653,10 @@ if [[ $dovecot_major_version -gt 2 ]] \
read -r -d '' NEW_BLOCK <<EOF read -r -d '' NEW_BLOCK <<EOF
sieve_script personal { sieve_script personal {
driver = file type = personal # kann man schreiben, ist aber Default
path = ~/sieve driver = file
active_path = ~/.dovecot.sieve path = ~/sieve
active_path = ~/.dovecot.sieve
} }
EOF EOF
replace_or_append_code_block "sieve_script personal" "${NEW_BLOCK}" "${_conf_file}" >> "${log_file}" 2>&1 replace_or_append_code_block "sieve_script personal" "${NEW_BLOCK}" "${_conf_file}" >> "${log_file}" 2>&1
@@ -7603,6 +7671,8 @@ EOF
# personal # personal
# -------- # --------
# #
# ** Used by both the Sieve plugin and the ManageSieve protocol **
#
# The personal storage serves as the user's main personal storage. Although more than a single # The personal storage serves as the user's main personal storage. Although more than a single
# personal storage can be defined, only the first one listed in the configuration is used. # personal storage can be defined, only the first one listed in the configuration is used.
# #
@@ -7625,9 +7695,10 @@ EOF
# no default script is executed. # no default script is executed.
sieve_script personal { sieve_script personal {
driver = file type = personal # kann man schreiben, ist aber Default
path = ~/sieve driver = file
active_path = ~/.dovecot.sieve path = ~/sieve
active_path = ~/.dovecot.sieve
} }
EOF EOF
if [[ $? -gt 0 ]]; then if [[ $? -gt 0 ]]; then
@@ -7637,16 +7708,17 @@ EOF
fi fi
if grep -qE "^\s*sieve_script\s+before\s*{" "${_conf_file}"; then if grep -qE "^\s*sieve_script\s+before_spam\s*{" "${_conf_file}"; then
read -r -d '' NEW_BLOCK <<EOF read -r -d '' NEW_BLOCK <<EOF
sieve_script before { sieve_script before_spam {
type = before
driver = file driver = file
path = /usr/local/dovecot/etc/dovecot/sieve/ path = /usr/local/dovecot/etc/dovecot/sieve/
} }
EOF EOF
replace_or_append_code_block "sieve_script before" "${NEW_BLOCK}" "${_conf_file}" >> "${log_file}" 2>&1 replace_or_append_code_block "sieve_script before_spam" "${NEW_BLOCK}" "${_conf_file}" >> "${log_file}" 2>&1
if [[ $? -gt 0 ]]; then if [[ $? -gt 0 ]]; then
_failed=true _failed=true
fi fi
@@ -7675,7 +7747,8 @@ EOF
# A before storage behaves identical to an after storage, except the contained script or # A before storage behaves identical to an after storage, except the contained script or
# scripts are run before user's personal script (instead of after). # scripts are run before user's personal script (instead of after).
sieve_script before { sieve_script before_spam {
type = before
driver = file driver = file
path = /usr/local/dovecot/etc/dovecot/sieve/ path = /usr/local/dovecot/etc/dovecot/sieve/
} }
@@ -7687,16 +7760,17 @@ EOF
fi fi
if grep -qE "^\s*sieve_script\s+global\s*{" "${_conf_file}"; then if grep -qE "^\s*sieve_script\s+global_includes\s*{" "${_conf_file}"; then
read -r -d '' NEW_BLOCK <<EOF read -r -d '' NEW_BLOCK <<EOF
sieve_script global { sieve_script global_includes {
driver = file type = global
path = /usr/local/dovecot/etc/dovecot/sieve/global/ driver = file
path = /usr/local/dovecot/etc/dovecot/sieve/global/
} }
EOF EOF
replace_or_append_code_block "sieve_script global" "${NEW_BLOCK}" "${_conf_file}" >> "${log_file}" 2>&1 replace_or_append_code_block "sieve_script global_includes" "${NEW_BLOCK}" "${_conf_file}" >> "${log_file}" 2>&1
if [[ $? -gt 0 ]]; then if [[ $? -gt 0 ]]; then
_failed=true _failed=true
fi fi
@@ -7745,9 +7819,10 @@ EOF
# storages are defined in the configuration until the script is found. The order can be # storages are defined in the configuration until the script is found. The order can be
# overridden by the sieve_script_precedence setting. # overridden by the sieve_script_precedence setting.
sieve_script global { sieve_script global_includes {
driver = file type = global
path = /usr/local/dovecot/etc/dovecot/sieve/global/ driver = file
path = /usr/local/dovecot/etc/dovecot/sieve/global/
} }
EOF EOF
if [[ $? -gt 0 ]]; then if [[ $? -gt 0 ]]; then
@@ -9162,11 +9237,11 @@ if [[ $dovecot_major_version -gt 2 ]] \
if [[ "$db_driver" = "pgsql" ]]; then if [[ "$db_driver" = "pgsql" ]]; then
read -r -d '' NEW_BLOCK <<'EOF' read -r -d '' NEW_BLOCK <<EOF
userdb sql { userdb sql {
# Load SQL connection data # Load SQL connection data
!include /usr/local/dovecot-2.4.1-4/etc/dovecot/sql-connect.conf.ext !include /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext
query = SELECT '/var/vmail/' || maildir AS home, \\ query = SELECT '/var/vmail/' || maildir AS home, \\
'5000' AS uid, '5000' AS gid, \\ '5000' AS uid, '5000' AS gid, \\
@@ -9204,7 +9279,7 @@ EOF
# The userdb and passdb may be the same or they may be different depending on your needs. # The userdb and passdb may be the same or they may be different depending on your needs.
# You can also have multiple authentication databases. # You can also have multiple authentication databases.
# #
# see: https://doc.dovecot.org/2.4.1/core/config/auth/userdb.html # see: https://doc.dovecot.org/${_version}/core/config/auth/userdb.html
# #
${NEW_BLOCK} ${NEW_BLOCK}
EOF EOF
@@ -9216,11 +9291,11 @@ EOF
elif [[ "$db_driver" = "mysql" ]]; then elif [[ "$db_driver" = "mysql" ]]; then
read -r -d '' NEW_BLOCK <<'EOF' read -r -d '' NEW_BLOCK <<EOF
userdb sql { userdb sql {
# Load SQL connection data # Load SQL connection data
!include /usr/local/dovecot-2.4.1-4/etc/dovecot/sql-connect.conf.ext !include /usr/local/dovecot-${_version}/etc/dovecot/sql-connect.conf.ext
query = SELECT CONCAT('/var/vmail/',maildir) AS home, \ query = SELECT CONCAT('/var/vmail/',maildir) AS home, \
'5000' AS uid, '5000' AS gid, \ '5000' AS uid, '5000' AS gid, \
@@ -9258,7 +9333,7 @@ EOF
# The userdb and passdb may be the same or they may be different depending on your needs. # The userdb and passdb may be the same or they may be different depending on your needs.
# You can also have multiple authentication databases. # You can also have multiple authentication databases.
# #
# see: https://doc.dovecot.org/2.4.1/core/config/auth/userdb.html # see: https://doc.dovecot.org/${_version}/core/config/auth/userdb.html
# #
$(echo -e "${NEW_BLOCK}") $(echo -e "${NEW_BLOCK}")
EOF EOF
@@ -9901,7 +9976,47 @@ if [[ $dovecot_major_version -gt 2 ]] \
echononl " Create quota warning script.." echononl " Create quota warning script.."
## - create the user-warning script ## - create the user-warning script
## - ## -
cat <<EOF >/usr/local/bin/quota-warning.sh if [[ "${msg_language}" == "en" ]] ; then
cat <<EOF >/usr/local/bin/quota-warning.sh
#!/usr/bin/env bash
# author: zhang huangbin <michaelbibby (at) gmail.com>
# purpose: send mail to notify user when his mailbox quota exceeds a
# specified limit.
# project: iredmail (http://www.iredmail.org/)
LANG=en_US.UTF-8
percent=\$1
user=\$2
cat << EOF | /usr/local/dovecot/libexec/dovecot/dovecot-lda -d \${user} -o quota_enforce=no
Date: `date +"%a, %e %b %Y %H:%M:%S %z"`
From: $from_address
Reply-to: $reply_to
To:\${user}
Subject: Quota warning - mailbox is ${percent}% full
content-type: text/plain;
charset=utf-8
Hello!
Your email inbox
\${user}
is over \${percent}% full. To continue receiving emails, please delete emails from your inbox on the server.
You can also use the webmail service:
$webmailer
After deleting emails, please remember to empty the trash folder as well.
Best regards
$salutation
${_EOF:-EOF}
EOF
else
cat <<EOF >/usr/local/bin/quota-warning.sh
#!/usr/bin/env bash #!/usr/bin/env bash
# author: zhang huangbin <michaelbibby (at) gmail.com> # author: zhang huangbin <michaelbibby (at) gmail.com>
@@ -9940,6 +10055,7 @@ Viele Grüße
$salutation $salutation
${_EOF:-EOF} ${_EOF:-EOF}
EOF EOF
fi
if [ "$?" = 0 ]; then if [ "$?" = 0 ]; then
echo -e "$rc_done" echo -e "$rc_done"
else else
@@ -9952,7 +10068,33 @@ EOF
echononl " Create quota warn-under script.." echononl " Create quota warn-under script.."
## - create the user-warning script ## - create the user-warning script
## - ## -
cat <<EOF >/usr/local/bin/quota-warn-under.sh if [[ "${msg_language}" == "en" ]] ; then
cat <<EOF >/usr/local/bin/quota-warn-under.sh
cat << EOF | /usr/local/dovecot/libexec/dovecot/dovecot-lda -d \${user} -o quota_enforce=no
Date: \`date +"%a, %e %b %Y %H:%M:%S %z"\`
From: $from_address
Reply-to: $reply_to
To:\${user}
Subject: Mailbox quota: less than ${percent}% used
content-type: text/plain;
charset=utf-8
Your mailbox
\${user}
can now receive e-mail again.
Please note that, depending on how much space you have freed, your available storage may fill up again quickly.
You can check the current usage in your mail client or via the webmailer here:
$webmailer
Best regards
$salutation
${_EOF:-EOF}
EOF
else
cat <<EOF >/usr/local/bin/quota-warn-under.sh
#!/usr/bin/env bash #!/usr/bin/env bash
percent=\$1 percent=\$1
@@ -9984,6 +10126,7 @@ Viele Grüße
$salutation $salutation
${_EOF:-EOF} ${_EOF:-EOF}
EOF EOF
fi
if [ "$?" = 0 ]; then if [ "$?" = 0 ]; then
echo -e "$rc_done" echo -e "$rc_done"
else else
@@ -10870,24 +11013,27 @@ EOF
replace_or_append_code_block "protocol sieve" "${NEW_BLOCK}" "${_conf_file}" || _failed=true replace_or_append_code_block "protocol sieve" "${NEW_BLOCK}" "${_conf_file}" || _failed=true
read -r -d '' NEW_BLOCK <<'EOF' # read -r -d '' NEW_BLOCK <<'EOF'
sieve_script personal { #sieve_script personal {
path = ~/sieve # type = personal # kann man schreiben, ist aber Default
active_path = ~/.dovecot.sieve # type = personal
} # driver = file
EOF # path = ~/sieve
if grep -qE "^\s*sieve_script\s+personal\s+{" "${_conf_file}"; then # active_path = ~/.dovecot.sieve
#}
replace_code_block "sieve_script personal" "${NEW_BLOCK}" "${_conf_file}" || _failed=true #EOF
# if grep -qE "^\s*sieve_script\s+personal\s+{" "${_conf_file}"; then
else #
# replace_code_block "sieve_script personal" "${NEW_BLOCK}" "${_conf_file}" || _failed=true
cat <<EOF >> "${_conf_file}" || _failed=true #
# else
# Used by both the Sieve plugin and the ManageSieve protocol #
${NEW_BLOCK} # cat <<EOF >> "${_conf_file}" || _failed=true
EOF #
fi ## Used by both the Sieve plugin and the ManageSieve protocol
#${NEW_BLOCK}
#EOF
# fi
if ! $_failed ; then if ! $_failed ; then

View File

@@ -148,9 +148,11 @@ detect_os_1 () {
# - Support systemd ? # - Support systemd ?
# - # -
if [[ "X$(which systemd)" = "X" ]]; then SYSTEMD_EXISTS=false
SYSTEMD_EXISTS=false systemd=$(which systemd)
else systemctl=$(which systemctl)
if [[ -n "$systemd" ]] || [[ -n "$systemctl" ]] ; then
SYSTEMD_EXISTS=true SYSTEMD_EXISTS=true
fi fi

View File

@@ -95,6 +95,16 @@ echo_skipped() {
echo -e "\033[75G[ \033[30m\033[1mskipped\033[m ]" echo -e "\033[75G[ \033[30m\033[1mskipped\033[m ]"
} }
# -Is systemd supported on this system?
# -
systemd_supported=false
systemd=$(which systemd)
systemctl=$(which systemctl)
if [[ -n "$systemd" ]] || [[ -n "$systemctl" ]] ; then
systemd_supported=true
fi
if [ "$POSTFIX_DB_TYPE" = "postgres" -o "$POSTFIX_DB_TYPE" = "postgresql" -o "$POSTFIX_DB_TYPE" = "pgsql" -o "$POSTFIX_DB_TYPE" = "psql" ];then if [ "$POSTFIX_DB_TYPE" = "postgres" -o "$POSTFIX_DB_TYPE" = "postgresql" -o "$POSTFIX_DB_TYPE" = "pgsql" -o "$POSTFIX_DB_TYPE" = "psql" ];then
POSTFIX_DB_TYPE=pgsql POSTFIX_DB_TYPE=pgsql

View File

@@ -182,9 +182,11 @@ fi
# - Is this a systemd system? # - Is this a systemd system?
# - # -
if [[ "X`which systemd`" = "X" ]]; then systemd_exists=false
systemd_exists=false systemd=$(which systemd)
else systemctl=$(which systemctl)
if [[ -n "$systemd" ]] || [[ -n "$systemctl" ]] ; then
systemd_exists=true systemd_exists=true
fi fi

View File

@@ -126,9 +126,11 @@ DEFAULT_SASL_AUTH=false
# - Is this a systemd system? # - Is this a systemd system?
# - # -
if [[ "X`which systemd`" = "X" ]]; then systemd_exists=false
systemd_exists=false systemd=$(which systemd)
else systemctl=$(which systemctl)
if [[ -n "$systemd" ]] || [[ -n "$systemctl" ]] ; then
systemd_exists=true systemd_exists=true
fi fi