#!/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."