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" < "$varsFile" < "$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 while IFS='|' read -r pod phase; do printSection "$pod" if [[ "$phase" != "Running" ]]; then printDotText "Phase" "$fontRed$phase$fontReset" else printDotText "Phase" "$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 label="$postfixLabel DKIM record: $postfixHost" 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 }