You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
4.6 KiB
160 lines
4.6 KiB
#!/bin/bash |
|
# Jalur B batch: semua mailbox @geonet.co.id kecuali Jalur A (support@) |
|
# — inactive mailbox + transport map → cPanel :587 |
|
# |
|
# Prasyarat AD (manual): keluarkan user dari grup Mail-Users (kecuali support@) |
|
# agar LDAP sync tidak mengaktifkan ulang mailbox. |
|
# |
|
# Usage (di server Mailcow / dalam stack): |
|
# ./setup-jalur-b-batch.sh # apply semua kecuali support@ |
|
# ./setup-jalur-b-batch.sh --dry-run # hanya list + cek |
|
# ./setup-jalur-b-batch.sh --only byprakoso@geonet.co.id,user2@geonet.co.id |
|
# KEEP_ACTIVE=support@geonet.co.id ./setup-jalur-b-batch.sh |
|
# |
|
# Single-user: setup-transport-cpanel-user.sh user@geonet.co.id |
|
set -euo pipefail |
|
|
|
DRY_RUN=0 |
|
ONLY_LIST="" |
|
KEEP_ACTIVE="${KEEP_ACTIVE:-support@geonet.co.id}" |
|
NEXTHOP="${TRANSPORT_NEXTHOP:-[sc138.idcloudhosting.cloud]:587}" |
|
RELAYHOST_ID="${TRANSPORT_RELAYHOST_ID:-1}" |
|
DOMAIN="${MAIL_DOMAIN:-geonet.co.id}" |
|
|
|
MYSQL_C='mailcowdockerized-mysql-mailcow-1' |
|
POSTFIX_C='mailcowdockerized-postfix-mailcow-1' |
|
PHP_C='mailcowdockerized-php-fpm-mailcow-1' |
|
|
|
while [ $# -gt 0 ]; do |
|
case "$1" in |
|
--dry-run) DRY_RUN=1; shift ;; |
|
--only) ONLY_LIST="${2:-}"; shift 2 ;; |
|
-h|--help) |
|
sed -n '2,16p' "$0" |
|
exit 0 |
|
;; |
|
*) |
|
echo "Unknown arg: $1" |
|
exit 1 |
|
;; |
|
esac |
|
done |
|
|
|
mysql_q() { |
|
docker exec "$MYSQL_C" bash -lc "mysql mailcow -uroot -p\"\$MYSQL_ROOT_PASSWORD\" -N -e \"$1\"" |
|
} |
|
|
|
mysql_exec() { |
|
docker exec "$MYSQL_C" bash -lc "mysql mailcow -uroot -p\"\$MYSQL_ROOT_PASSWORD\" -e \"$1\"" |
|
} |
|
|
|
is_kept() { |
|
local e="$1" |
|
local k |
|
IFS=',' read -ra _keep <<< "$KEEP_ACTIVE" |
|
for k in "${_keep[@]}"; do |
|
k="$(echo "$k" | tr -d '[:space:]')" |
|
[ -z "$k" ] && continue |
|
[ "$e" = "$k" ] && return 0 |
|
done |
|
return 1 |
|
} |
|
|
|
in_only() { |
|
local e="$1" |
|
[ -z "$ONLY_LIST" ] && return 0 |
|
local o |
|
IFS=',' read -ra _only <<< "$ONLY_LIST" |
|
for o in "${_only[@]}"; do |
|
o="$(echo "$o" | tr -d '[:space:]')" |
|
[ -z "$o" ] && continue |
|
[ "$e" = "$o" ] && return 0 |
|
done |
|
return 1 |
|
} |
|
|
|
apply_one() { |
|
local EMAIL="$1" |
|
echo "---- ${EMAIL} ----" |
|
|
|
if [ "$DRY_RUN" = "1" ]; then |
|
MB=$(mysql_q "SELECT username, active, authsource FROM mailbox WHERE username='${EMAIL}';") |
|
TR=$(mysql_q "SELECT COUNT(*) FROM transports WHERE destination='${EMAIL}';") |
|
echo "mailbox: ${MB:-MISSING}" |
|
echo "transport_rows: ${TR:-0}" |
|
echo "dry-run: would set active=0 + transport -> ${NEXTHOP}" |
|
return 0 |
|
fi |
|
|
|
mysql_exec "UPDATE mailbox SET active=0 WHERE username='${EMAIL}';" |
|
MB=$(mysql_q "SELECT username, active, authsource FROM mailbox WHERE username='${EMAIL}';") |
|
echo "mailbox after: ${MB:-MISSING}" |
|
|
|
CNT=$(mysql_q "SELECT COUNT(*) FROM transports WHERE destination='${EMAIL}';") |
|
if [ "${CNT}" = "0" ]; then |
|
mysql_exec " |
|
INSERT INTO transports (destination, nexthop, username, password, is_mx_based, active) |
|
SELECT '${EMAIL}', '${NEXTHOP}', r.username, r.password, 0, 1 |
|
FROM relayhosts r |
|
WHERE r.id=${RELAYHOST_ID} AND r.active=1 |
|
LIMIT 1; |
|
" |
|
echo "transport: INSERT" |
|
else |
|
mysql_exec " |
|
UPDATE transports t |
|
JOIN relayhosts r ON r.id=${RELAYHOST_ID} AND r.active=1 |
|
SET t.nexthop='${NEXTHOP}', t.username=r.username, t.password=r.password, t.active=1 |
|
WHERE t.destination='${EMAIL}'; |
|
" |
|
echo "transport: UPDATE" |
|
fi |
|
|
|
ALIAS=$(mysql_q "SELECT COUNT(*) FROM alias WHERE address='${EMAIL}';") |
|
if [ "${ALIAS}" != "0" ]; then |
|
mysql_exec "UPDATE alias SET active=1 WHERE address='${EMAIL}';" |
|
echo "alias: active=1" |
|
else |
|
echo "alias: none" |
|
fi |
|
|
|
docker exec "$POSTFIX_C" postmap -q "${EMAIL}" mysql:/opt/postfix/conf/sql/mysql_transport_maps.cf || true |
|
} |
|
|
|
echo "== Jalur B batch ==" |
|
echo "KEEP_ACTIVE (Jalur A): ${KEEP_ACTIVE}" |
|
echo "NEXTHOP: ${NEXTHOP}" |
|
echo "DRY_RUN: ${DRY_RUN}" |
|
[ -n "$ONLY_LIST" ] && echo "ONLY: ${ONLY_LIST}" |
|
|
|
echo "== LDAP sync ==" |
|
docker exec "$PHP_C" php /crons/ldap-sync.php || true |
|
|
|
echo "== Candidates (@${DOMAIN}) ==" |
|
mapfile -t ALL < <(mysql_q "SELECT username FROM mailbox WHERE username LIKE '%@${DOMAIN}' ORDER BY username;") |
|
|
|
APPLIED=0 |
|
SKIPPED=0 |
|
for EMAIL in "${ALL[@]}"; do |
|
[ -z "$EMAIL" ] && continue |
|
if is_kept "$EMAIL"; then |
|
echo "SKIP (Jalur A): ${EMAIL}" |
|
SKIPPED=$((SKIPPED + 1)) |
|
continue |
|
fi |
|
if ! in_only "$EMAIL"; then |
|
continue |
|
fi |
|
apply_one "$EMAIL" |
|
APPLIED=$((APPLIED + 1)) |
|
done |
|
|
|
if [ "$DRY_RUN" = "0" ] && [ "$APPLIED" -gt 0 ]; then |
|
echo "== Reload postfix ==" |
|
docker exec "$POSTFIX_C" postfix reload |
|
fi |
|
|
|
echo "" |
|
echo "DONE. applied=${APPLIED} skipped_jalur_a=${SKIPPED}" |
|
echo "Manual AD: remove Jalur B users from Mail-Users (keep support@)." |
|
echo "Test: support@ -> each user; verify inbox on cPanel."
|
|
|