postfwd: install config from files/postfwd, idempotent /etc/default/postfwd handling

- Ship postfwd.cf and list files in files/postfwd; used by install_postfwd.sh
  and install_postfix_advanced.sh (lists only if missing, cf with backup).
- Add update_postfwd_defaults.sh.
- install_amavis.sh: disable smtpd_end_of_data_restrictions on localhost:10025.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-08 10:53:21 +01:00
co-authored by Claude Opus 5.5
parent 450b04134d
commit 39909a5b30
18 changed files with 1264 additions and 849 deletions
+172
View File
@@ -0,0 +1,172 @@
#!/usr/bin/env bash
#
# Update /etc/default/postfwd (idempotent) and reload postfwd.
#
# For every variable below:
# - already set to the wanted value -> nothing to do
# - set to a different value -> comment out the current setting
# and add the new one directly below
# - not set at all -> append the new setting
#
# Quotes around values are ignored when comparing (PORT="10040" == PORT=10040).
#
# At the end:
# - file changed -> 'systemctl restart postfwd'
# (ARGS, INET and PORT are start parameters of the
# daemon - a reload does NOT apply them)
# - file unchanged -> 'systemctl reload postfwd'
# (rereads postfwd.cf and the file: lists)
#
postfwd_default_file="/etc/default/postfwd"
# - Wanted settings: "VAR|VALUE" (VALUE written exactly as it should appear)
wanted_settings=(
'STARTUP|1'
'CONF|/etc/postfix/postfwd.cf'
'INET|127.0.0.1'
'PORT|10040'
'ARGS|"--summary=600 --cache=0"'
)
# -------------
# --- Some functions
# -------------
log_file="$(mktemp)"
clean_up() {
rm -f "$log_file"
exit $1
}
echononl() {
echo -e -n "$*"
}
echo_ok() {
echo -e "\033[60G[ \033[32mok\033[m ]"
}
echo_skipped() {
echo -e "\033[60G[ \033[33m\033[1mskipped\033[m ]"
}
echo_failed() {
echo -e "\033[60G[ \033[1;31mfailed\033[m ]"
}
error() {
echo ""
echo -e "\t[ \033[31m\033[1mError\033[m ]: $*"
echo ""
}
fatal() {
error "$*"
echo -e "\t\033[31m\033[1mScript will be interrupted\033[m"
echo ""
clean_up 1
}
# - set_postfwd_default <VAR> <VALUE>
# -
# - returns 0 if the file was changed, 1 if nothing changed, 2 on error
# -
set_postfwd_default() {
local _var="$1"
local _val="$2"
local _tmp_file
local _rval
echononl " ${_var}=${_val}"
_tmp_file="$(mktemp)"
awk -v var="$_var" -v val="$_val" '
function unq(s) {
gsub(/^[ \t]+|[ \t]+$/, "", s)
if (s ~ /^".*"$/ || s ~ /^\047.*\047$/) s = substr(s, 2, length(s) - 2)
return s
}
$0 ~ "^[ \t]*" var "=" {
cur = $0 ; sub("^[ \t]*" var "=", "", cur)
if (! done && unq(cur) == unq(val)) { print ; done = 1 ; next }
print "#" $0
if (! done) { print var "=" val ; done = 1 }
next
}
{ print }
END { if (! done) print var "=" val }
' "$postfwd_default_file" > "$_tmp_file" 2> "$log_file"
if [[ $? -ne 0 ]] ; then
echo_failed
error "$(cat "$log_file")"
_rval=2
elif cmp -s "$_tmp_file" "$postfwd_default_file" ; then
echo_skipped
_rval=1
else
# - cat instead of mv/cp keeps owner and permissions of the original file
if cat "$_tmp_file" > "$postfwd_default_file" 2> "$log_file" ; then
echo_ok
_rval=0
else
echo_failed
error "$(cat "$log_file")"
_rval=2
fi
fi
rm -f "$_tmp_file"
return $_rval
}
# -------------
# --- Main
# -------------
[[ "$(id -u)" -eq 0 ]] || fatal "This script must be run as root."
command -v postfwd > /dev/null 2>&1 || fatal "postfwd is not installed."
if [[ ! -f "$postfwd_default_file" ]] ; then
touch "$postfwd_default_file" 2> "$log_file" || fatal "$(cat "$log_file")"
fi
echo ""
echo "Update ${postfwd_default_file}"
echo ""
file_changed=false
errors=false
for _setting in "${wanted_settings[@]}" ; do
set_postfwd_default "${_setting%%|*}" "${_setting#*|}"
case $? in
0) file_changed=true ;;
2) errors=true ;;
esac
done
echo ""
if $errors ; then
fatal "Errors while updating '${postfwd_default_file}' - postfwd NOT reloaded."
fi
if $file_changed ; then
echononl " Restart postfwd (start parameters changed)"
_action="restart"
else
echononl " Reload postfwd"
_action="reload"
fi
if systemctl $_action postfwd > "$log_file" 2>&1 ; then
echo_ok
else
echo_failed
error "$(cat "$log_file")"
clean_up 1
fi
echo ""
clean_up 0