sodew-bash
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
# Executes a command inside the postfix container.
|
||||
function postfixExec() {
|
||||
k3sRun exec -it deploy/"$postfixKube" -c "$postfixKube" -- "$@"
|
||||
}
|
||||
|
||||
# Executes a command inside a specific Postfix pod.
|
||||
# $1 (pod): pod name.
|
||||
# $@ (...): command and arguments to execute.
|
||||
function postfixPodExec() {
|
||||
local pod="$1"
|
||||
[[ -n "$pod" ]] || { appError "Pod not specified"; return 1; }
|
||||
shift || true
|
||||
|
||||
k3sRun exec pod/"$pod" -c "$postfixKube" -- "$@"
|
||||
}
|
||||
|
||||
# Converts a domain name to a random 64-char postfix ID.
|
||||
function postfixDomain2id() {
|
||||
domainToRandom "$1" 64
|
||||
}
|
||||
|
||||
# Reloads the Postfix daemon.
|
||||
function postfixReload() {
|
||||
postfixExec postfix reload
|
||||
}
|
||||
|
||||
# Creates or updates a Postfix SASL user.
|
||||
# $1 (login): SASL username.
|
||||
# $2 (password): password.
|
||||
function postfixUserSet() {
|
||||
local login="$1" password="$2"
|
||||
[[ -n "$login" ]] || { appError "Login not specified"; return 1; }
|
||||
[[ -n "$password" ]] || { appError "Password not specified"; return 1; }
|
||||
|
||||
local error
|
||||
runError error postfixExec \
|
||||
env SASL_LOGIN="$login" SASL_PWD="$password" SASL_DB="/config/sasldb2" SASL_REALM="$postfixDefaultRealm" \
|
||||
sh -lc 'printf "%s\n" "$SASL_PWD" | saslpasswd2 -p -c -f "$SASL_DB" -u "$SASL_REALM" "$SASL_LOGIN"' || {
|
||||
appError "Failed to create/update SASL user $login: $error"
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
# Deletes a Postfix SASL user.
|
||||
# $1 (login): SASL username.
|
||||
function postfixUserRemove() {
|
||||
local login="$1"
|
||||
[[ -n "$login" ]] || { appError "Login not specified"; return 1; }
|
||||
|
||||
local error
|
||||
runError error postfixExec saslpasswd2 -d -f "/config/sasldb2" -u "$postfixDefaultRealm" "$login" || {
|
||||
appError "Failed to delete SASL user $login"
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
# Lists all SASL users from the sasldb2 database.
|
||||
function postfixUserList() {
|
||||
local output error
|
||||
run output error postfixExec sasldblistusers2 -f /config/sasldb2 || { appError "$error"; return 1; }
|
||||
|
||||
awk -F':' '
|
||||
/^[[:space:]]*$/ { next }
|
||||
{ gsub(/[[:space:]]+$/, "", $1); print $1 }
|
||||
' <<<"$output"
|
||||
}
|
||||
|
||||
# Rebuilds the senders map from the current SASL user list.
|
||||
function postfixSendersRebuild() {
|
||||
local outFile="$postfixConfigPath/$postfixSendersFile"
|
||||
|
||||
local saslList error
|
||||
run saslList error postfixUserList || { appError "Failed to get SASL list: $error"; return 1; }
|
||||
|
||||
local logins
|
||||
logins=$(awk 'NF' <<<"$saslList" | paste -sd ',' -)
|
||||
|
||||
local tmpOut
|
||||
tmpOut=$(mktemp)
|
||||
[[ -n "$logins" ]] && printf '%s %s\n' "$postfixPostmaster" "$logins" > "$tmpOut"
|
||||
mv -f "$tmpOut" "$outFile"
|
||||
}
|
||||
|
||||
function postfixConfigRebuild() {
|
||||
local domain="$1"
|
||||
if [[ -n "$domain" ]]; then
|
||||
postfixDomainSet "$domain"
|
||||
fi
|
||||
|
||||
local error
|
||||
# runError error postfixExec postmap "lmdb:/config/$postfixDomainsFile" || { appError "Failed rebuild $postfixDomainsFile: $error"; return 1; }
|
||||
# runError error postfixExec postmap "lmdb:/config/$postfixAliasesFile" || { appError "Failed rebuild $postfixAliasesFile: $error"; return 1; }
|
||||
runError error postfixExec postmap "lmdb:/config/$postfixSendersFile" || { appError "Failed rebuild $postfixSendersFile: $error"; return 1; }
|
||||
}
|
||||
|
||||
function postfixDomainSet() {
|
||||
local domain="$1"
|
||||
[[ -n "$domain" ]] || { appError "Domain not specified"; return 1; }
|
||||
domainCheck "$domain" || return 1
|
||||
|
||||
local pfxId
|
||||
pfxId=$(postfixDomain2id "$domain")
|
||||
local postfixUser postfixPass
|
||||
postfixUser=$(siteConfigGetOrSet "$domain" "postfixUser" "$pfxId")
|
||||
postfixPass=$(siteConfigGetOrCreate "$domain" "postfixPass")
|
||||
|
||||
postfixUserSet "$postfixUser" "$postfixPass" || return 1
|
||||
postfixSendersRebuild
|
||||
postfixConfigRebuild
|
||||
}
|
||||
|
||||
function postfixDomainRemove() {
|
||||
local domain="$1"
|
||||
[[ -n "$domain" ]] || { appError "Domain not specified"; return 1; }
|
||||
|
||||
local postfixUser
|
||||
postfixUser=$(siteConfigGet "$domain" "postfixUser")
|
||||
[[ -n "$postfixUser" ]] || { appError "postfixUser not found"; return 1; }
|
||||
|
||||
postfixUserRemove "$postfixUser"
|
||||
postfixSendersRebuild
|
||||
postfixConfigRebuild
|
||||
}
|
||||
|
||||
# Reloads the opendkim daemon.
|
||||
function postfixDkimReload() {
|
||||
postfixExec sh -lc "pkill -HUP -f '/usr/sbin/opendkim' 2>/dev/null" || true
|
||||
}
|
||||
|
||||
# Lists domains that have DKIM key material present.
|
||||
function postfixDkimList() {
|
||||
local f
|
||||
for f in "$postfixDkimPath/keys/"*.txt; do
|
||||
[[ -f "$f" ]] || continue
|
||||
basename -- "$f" .txt
|
||||
done
|
||||
}
|
||||
|
||||
# Generates a DKIM keypair for a domain and updates SigningTable/KeyTable.
|
||||
# $1 (domain): domain name.
|
||||
function postfixDkimAdd() {
|
||||
local domain="$1"
|
||||
[[ -n "$domain" ]] || { appError "Domain not specified"; return 1; }
|
||||
|
||||
if [[ ! -s "$postfixDkimPath/keys/$domain.private" || ! -s "$postfixDkimPath/keys/$domain.txt" ]]; then
|
||||
postfixExec sh -lc "
|
||||
set -e
|
||||
mkdir -p /etc/opendkim/keys
|
||||
opendkim-genkey -b 2048 -r -D '/etc/opendkim/keys' -d '$domain' -s '$postfixDkimSelector'
|
||||
mv -f \"/etc/opendkim/keys/$postfixDkimSelector.private\" \"/etc/opendkim/keys/$domain.private\"
|
||||
mv -f \"/etc/opendkim/keys/$postfixDkimSelector.txt\" \"/etc/opendkim/keys/$domain.txt\"
|
||||
chown opendkim:opendkim \"/etc/opendkim/keys/$domain.private\" \"/etc/opendkim/keys/$domain.txt\" || true
|
||||
chmod 0600 \"/etc/opendkim/keys/$domain.private\"
|
||||
chmod 0644 \"/etc/opendkim/keys/$domain.txt\"
|
||||
" || { appError "Failed to generate DKIM keys for $domain"; return 1; }
|
||||
fi
|
||||
|
||||
local domainEsc="${domain//./\\.}"
|
||||
local selectorEsc="${postfixDkimSelector//./\\.}"
|
||||
sed -i "/^\*@${domainEsc}[[:space:]]/d" "$postfixDkimPath/SigningTable"
|
||||
sed -i "/^${selectorEsc}\._domainkey\.${domainEsc}[[:space:]]/d" "$postfixDkimPath/KeyTable"
|
||||
|
||||
printf '*@%s %s._domainkey.%s\n' "$domain" "$postfixDkimSelector" "$domain" >> "$postfixDkimPath/SigningTable"
|
||||
printf '%s._domainkey.%s %s:%s:/etc/opendkim/keys/%s.private\n' \
|
||||
"$postfixDkimSelector" "$domain" "$domain" "$postfixDkimSelector" "$domain" >> "$postfixDkimPath/KeyTable"
|
||||
|
||||
postfixDkimReload
|
||||
}
|
||||
|
||||
# Ensures DKIM keys exist for a domain and returns the TXT record.
|
||||
# $1 (domain): domain name.
|
||||
function postfixDkimGet() {
|
||||
local domain="$1"
|
||||
[[ -n "$domain" ]] || { appError "Domain not specified"; return 1; }
|
||||
domainCheck "$domain" || return 1
|
||||
postfixDkimAdd "$domain" || return 1
|
||||
cat "$postfixDkimPath/keys/$domain.txt" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# Removes DKIM table entries for a domain and reloads opendkim.
|
||||
# $1 (domain): domain name.
|
||||
function postfixDkimRemove() {
|
||||
local domain="$1"
|
||||
[[ -n "$domain" ]] || { appError "Domain not specified"; return 1; }
|
||||
|
||||
local domainEsc="${domain//./\\.}"
|
||||
local selectorEsc="${postfixDkimSelector//./\\.}"
|
||||
sed -i "/^\*@${domainEsc}[[:space:]]/d" "$postfixDkimPath/SigningTable"
|
||||
sed -i "/^${selectorEsc}\._domainkey\.${domainEsc}[[:space:]]/d" "$postfixDkimPath/KeyTable"
|
||||
|
||||
postfixDkimReload
|
||||
}
|
||||
Reference in New Issue
Block a user