277 lines
9.1 KiB
Bash
277 lines
9.1 KiB
Bash
postfixLabel="[Postfix]"
|
|
|
|
# Generates a self-signed TLS certificate for Postfix if one does not already exist.
|
|
function cmdPostfixPreparation() {
|
|
printSection "Preparation..."
|
|
|
|
if [[ ! -f "$postfixTlsCrtFile" || ! -f "$postfixTlsKeyFile" ]]; then
|
|
local crtPath; crtPath=$(dirname "$postfixTlsCrtFile")
|
|
local tlsCnfFile="$crtPath/openssl.cnf"
|
|
local cn="${postfixHost:-$postfixDomain}"
|
|
local sanList="DNS:${cn}"
|
|
[[ -n "$postfixDomain" ]] && sanList="${sanList},DNS:${postfixDomain}"
|
|
mkdir -p "$crtPath" || {
|
|
printDotText "preparation" "$labelFail"
|
|
printDanger "Failed to create folder for certificate";
|
|
return 1;
|
|
}
|
|
|
|
cat >"$tlsCnfFile" <<EOF
|
|
[req]
|
|
distinguished_name = dn
|
|
x509_extensions = v3_req
|
|
prompt = no
|
|
[dn]
|
|
CN = ${cn}
|
|
[v3_req]
|
|
subjectAltName = ${sanList}
|
|
keyUsage = digitalSignature, keyEncipherment
|
|
extendedKeyUsage = serverAuth
|
|
EOF
|
|
openssl req -x509 -nodes -newkey rsa:2048 -days 365 -keyout "$postfixTlsKeyFile" -out "$postfixTlsCrtFile" -config "$tlsCnfFile" || {
|
|
printDotText "preparation" "$labelFail"
|
|
printDanger "TLS gen failed";
|
|
return 1;
|
|
}
|
|
fi
|
|
|
|
printDotText "preparation" "$labelDone"
|
|
}
|
|
|
|
# Renders the Postfix Kubernetes YAML manifest via Helm.
|
|
function cmdPostfixYamlRender() {
|
|
local templateFile="templates/$postfixKube.yaml"
|
|
|
|
printSection "Render YAML file | Helm"
|
|
printDotText "Template" "$appAssetsPath/k3s/$templateFile"
|
|
[[ -f "$appAssetsPath/k3s/$templateFile" ]] || {
|
|
printDanger "Template file not found"
|
|
return 1
|
|
}
|
|
|
|
local val postfixTlsCrtB64 postfixTlsKeyB64
|
|
val=$(base64 -w0 "$postfixTlsCrtFile") || {
|
|
printDotText "render" "$labelFail"
|
|
printDanger "Base64 gen failed (1)"
|
|
return 1
|
|
}
|
|
postfixTlsCrtB64=$(sed 's/[&\\]/\\&/g' <<<"$val") || {
|
|
printDotText "render" "$labelFail"
|
|
printDanger "Base64 gen failed (2)"
|
|
return 1
|
|
}
|
|
val=$(base64 -w0 "$postfixTlsKeyFile") || {
|
|
printDotText "render" "$labelFail"
|
|
printDanger "Base64 gen failed (3)"
|
|
return 1
|
|
}
|
|
postfixTlsKeyB64=$(sed 's/[&\\]/\\&/g' <<<"$val") || {
|
|
printDotText "render" "$labelFail"
|
|
printDanger "Base64 gen failed (4)"
|
|
return 1
|
|
}
|
|
|
|
local varsFile
|
|
varsFile=$(mktemp "/tmp/$postfixKube.vars.XXXXXX.yaml") || {
|
|
printDotText "render" "$labelFail"
|
|
printDanger "Create temp variables file"
|
|
return 1
|
|
}
|
|
printDotText "Variables" "$varsFile"
|
|
trap 'rm -f -- "$varsFile"' RETURN
|
|
cat > "$varsFile" <<EOF
|
|
postfixHelm: true
|
|
namespace: $k3sNamespace
|
|
postfix: $postfixKube
|
|
postfixPath: $postfixPath
|
|
postfixTlsCrtB64: $postfixTlsCrtB64
|
|
postfixTlsKeyB64: $postfixTlsKeyB64
|
|
postfixHost: $postfixHost
|
|
postfixPostmaster: $postfixPostmaster
|
|
postfixDefaultRealm: $postfixDefaultRealm
|
|
postfixConfigPath: $postfixConfigPath
|
|
postfixDkimPath: $postfixDkimPath
|
|
postfixDkimSelector: $postfixDkimSelector
|
|
postfixDomainsFile: $postfixDomainsFile
|
|
postfixAliasesFile: $postfixAliasesFile
|
|
postfixSendersFile: $postfixSendersFile
|
|
EOF
|
|
|
|
printDotText "Result" "$postfixYaml"
|
|
mkdir -p -- "$(dirname -- "$postfixYaml")" || return 1
|
|
fileBackup "$postfixYaml"
|
|
helm template stack "$appAssetsPath/k3s" -f "$varsFile" --show-only "$templateFile" > "$postfixYaml" || {
|
|
printDotText "render" "$labelFail"
|
|
printDanger "Render failed"
|
|
return 1
|
|
}
|
|
|
|
printDotText "render" "$labelDone"
|
|
}
|
|
|
|
# Initializes Postfix after install: generates DKIM for postfixHost and sets sasldb2 ownership.
|
|
function cmdPostfixInit() {
|
|
printSection "Initialization..."
|
|
|
|
touch "$postfixConfigPath/$postfixDomainsFile" || return 1
|
|
touch "$postfixConfigPath/$postfixAliasesFile" || return 1
|
|
touch "$postfixConfigPath/$postfixSendersFile" || return 1
|
|
|
|
postfixDkimAdd "$postfixHost" || {
|
|
printDotText "Add DKIM for host" "$labelFail"
|
|
return 1
|
|
}
|
|
printDotText "Add DKIM for host" "$labelDone"
|
|
|
|
local error
|
|
if ! runError error postfixExec chown postfix:postfix /config/sasldb2; then
|
|
printDotText "Set owner /config/sasldb2" "$labelFail"
|
|
printDanger "$error"
|
|
return 1
|
|
fi
|
|
printDotText "Set owner /config/sasldb2" "$labelDone"
|
|
}
|
|
|
|
function cmdPostfixUpdate() {
|
|
cmdPostfixYamlRender || return 1
|
|
cmdK3sYamlApplyEx "$postfixYaml" || return 1
|
|
}
|
|
|
|
# Installs Postfix into Kubernetes.
|
|
function cmdPostfixInstall() {
|
|
cmdPostfixPreparation || return 1
|
|
cmdPostfixYamlRender || return 1
|
|
cmdK3sYamlApplyEx "$postfixYaml" || return 1
|
|
cmdPostfixInit || return 1
|
|
}
|
|
|
|
# Uninstalls Postfix Kubernetes resources.
|
|
function cmdPostfixUninstall() {
|
|
"$k3sCmd" kubectl delete -f "$postfixYaml"
|
|
}
|
|
|
|
function cmdPostfixUser() {
|
|
local output error
|
|
|
|
printRow
|
|
|
|
if ! run output error postfixUserList; then
|
|
printDanger "$error"
|
|
elif [[ -z "$output" ]]; then
|
|
printText "$labelNull"
|
|
else
|
|
printText "$output"
|
|
fi
|
|
}
|
|
|
|
# Prints the Postfix mail version.
|
|
function cmdPostfixInfo() {
|
|
local output error podList ver pid
|
|
|
|
if ! run podList error k3sPodListStatus "$postfixKube"; then
|
|
printDanger "Get pods: $error"
|
|
elif [[ -z "$podList" ]]; then
|
|
printDanger "Pods not found"
|
|
else
|
|
local ready reason
|
|
while IFS='|' read -r pod ready phase reason; do
|
|
printSection "$pod"
|
|
|
|
if [[ "$ready" != "1" ]]; then
|
|
printDotText "Status" "$fontGray$reason $fontRed$phase$fontReset"
|
|
else
|
|
printDotText "Status" "$fontGreen$phase$fontReset"
|
|
|
|
if ! run output error postfixPodExec "$pod" postfix status; then
|
|
printDotText "Postfix status" "$fontRed$labelFail$fontReset"
|
|
printDanger "$error"
|
|
else
|
|
output="${output:-$error}"
|
|
if [[ $output == *"is running"* ]]; then
|
|
pid=${output##*PID: }
|
|
pid=${pid%%[^0-9]*}
|
|
printDotText "Postfix status" "$labelRunning"
|
|
printDotText "PID" "$pid"
|
|
else
|
|
printDotText "Postfix status" "$fontRed$output$fontReset"
|
|
fi
|
|
fi
|
|
|
|
if ! run output error postfixPodExec "$pod" postconf mail_version; then
|
|
printDotText "Postfix mail version" "$fontRed$labelFail$fontReset"
|
|
printDanger "$error"
|
|
else
|
|
ver=$(printf '%s' "$output" | cut -d '=' -f2 | tr -d '\r\n')
|
|
printDotText "Postfix mail version" "$ver"
|
|
fi
|
|
fi
|
|
done < <(awk 'NF' <<< "$podList")
|
|
fi
|
|
}
|
|
|
|
# Checks MTA host DNS records (A, SPF, PTR, DKIM) against configured values.
|
|
function cmdPostfixMtaDnsCheck() {
|
|
local label output error text
|
|
|
|
printSection "MTA DNS: $postfixHost"
|
|
|
|
# A record
|
|
if ! run output error dig +short A "$postfixHost" "$dnsResolver"; then
|
|
printDotText "A record" "$fontRed${output:-$error}$fontReset"
|
|
else
|
|
text=$(printf '%s' "$output" | paste -sd, - | sed 's/,/ \/ /g')
|
|
if grep -Fxq -- "$postfixIp" <<<"$output"; then
|
|
printDotText "A record" "$fontGreen$text$fontReset"
|
|
else
|
|
printDotText "A record" "$fontYellow$text$fontReset"
|
|
fi
|
|
fi
|
|
|
|
# SPF record
|
|
if ! run output error dig +short TXT "$postfixHost" "$dnsResolver"; then
|
|
printDotText "SPF record" "$fontRed${output:-$error}$fontReset"
|
|
elif grep -Eq '^"?v=spf1([[:space:]]|")' <<<"$output"; then
|
|
printDotText "SPF record" "$fontGreen$output$fontReset"
|
|
else
|
|
printDotText "SPF record" "$fontRed$output$fontReset"
|
|
fi
|
|
|
|
# PTR record
|
|
if ! run output error dig -x "$postfixIp" +short "$dnsResolver"; then
|
|
printDotText "PTR record" "$fontRed${output:-$error}$fontReset"
|
|
else
|
|
text=$(printf '%s' "$output" | paste -sd, - | sed 's/,/ \/ /g')
|
|
if grep -Fxq -- "$postfixHost." <<<"$output"; then
|
|
printDotText "PTR record" "$fontGreen$text$fontReset"
|
|
else
|
|
printDotText "PTR record" "$fontYellow$text$fontReset"
|
|
fi
|
|
fi
|
|
|
|
# DKIM record
|
|
if ! run output error dig +short TXT "$postfixDkimSelector._domainkey.$postfixHost"; then
|
|
printDotText "DKIM record" "$fontRed${output:-$error}$fontReset"
|
|
else
|
|
local dkimDnsNorm dkimFileRaw dkimFileNorm
|
|
dkimDnsNorm=$(
|
|
printf '%s\n' "$output" |
|
|
tr -d '\n' |
|
|
sed -e 's/"//g' -e 's/[[:space:]]//g' |
|
|
sed -n 's/.*p=\([^;]*\).*/\1/p'
|
|
)
|
|
dkimFileRaw=$(postfixDkimGet "$postfixHost")
|
|
dkimFileNorm=$(
|
|
printf '%s\n' "$dkimFileRaw" |
|
|
tr -d '\n' |
|
|
sed -e 's/[()"]//g' -e 's/[[:space:]]//g' |
|
|
sed -n 's/.*p=\([^;]*\).*/\1/p'
|
|
)
|
|
if [[ "$dkimDnsNorm" == "$dkimFileNorm" ]]; then
|
|
printText "$fontGreen$dkimDnsNorm$fontReset"
|
|
else
|
|
printText "DNS : $fontYellow$dkimDnsNorm$fontReset"
|
|
printText "File: $fontYellow$dkimFileNorm$fontReset"
|
|
fi
|
|
fi
|
|
}
|