Sync all scripts from website downloads — 352 scripts total
Includes updated JS challenge scripts with Claude-User whitelist, same-site referer bypass, Blackbox-Exporter allowed bot, and all new exporters, cheat sheets, and automation scripts.
This commit is contained in:
@@ -0,0 +1,455 @@
|
||||
#!/bin/bash
|
||||
################################################################################
|
||||
# Script Name: postfix-relay-install.sh
|
||||
# Version: 1.0
|
||||
# Description: Automated Postfix satellite relay installation — configures
|
||||
# Postfix as a relay-only MTA with SASL auth, TLS, sender
|
||||
# rewriting, and firewall lockdown
|
||||
#
|
||||
# Author: Phil Connor
|
||||
# Contact: contact@mylinux.work
|
||||
# Website: https://mylinux.work
|
||||
# License: MIT
|
||||
#
|
||||
# Usage:
|
||||
# sudo ./postfix-relay-install.sh --relay smtp.example.com --port 587
|
||||
# sudo ./postfix-relay-install.sh --relay smtp.example.com --user user --pass pass
|
||||
# sudo ./postfix-relay-install.sh --dry-run
|
||||
#
|
||||
################################################################################
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ============================================================================
|
||||
# DEFAULTS
|
||||
# ============================================================================
|
||||
|
||||
RELAY_HOST=""
|
||||
RELAY_PORT="587"
|
||||
SASL_USER=""
|
||||
SASL_PASS=""
|
||||
FROM_ADDRESS=""
|
||||
HOSTNAME_OVERRIDE=""
|
||||
ROOT_ALIAS=""
|
||||
TLS_MODE="may"
|
||||
NO_FIREWALL=false
|
||||
DRY_RUN=false
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m'
|
||||
|
||||
# ============================================================================
|
||||
# HELPER FUNCTIONS
|
||||
# ============================================================================
|
||||
|
||||
log_info() { echo -e "${GREEN}[INFO]${NC} $*"; }
|
||||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||
log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
|
||||
log_step() { echo -e "${CYAN}[STEP]${NC} $*"; }
|
||||
|
||||
show_usage() {
|
||||
cat <<EOF
|
||||
Usage: $0 [OPTIONS]
|
||||
|
||||
Installs and configures Postfix as a satellite relay (outbound only).
|
||||
|
||||
OPTIONS:
|
||||
--relay HOST Relay host FQDN or IP (required)
|
||||
--port PORT Relay port: 25, 465, 587 (default: 587)
|
||||
--user USER SASL authentication username
|
||||
--pass PASS SASL authentication password
|
||||
--from ADDRESS Rewrite all sender addresses to this
|
||||
--hostname NAME Set Postfix myhostname
|
||||
--root-alias ADDR Forward root mail to this address
|
||||
--tls MODE TLS mode: may, required, wrapper (default: may)
|
||||
--no-firewall Skip firewall configuration
|
||||
--dry-run Show what would be done
|
||||
-h, --help Show this help
|
||||
|
||||
EXAMPLES:
|
||||
sudo $0 --relay smtp.example.com --port 587
|
||||
sudo $0 --relay smtp.example.com --user alerts@example.com --pass AppPass
|
||||
sudo $0 --relay smtp.example.com --from noreply@example.com --tls required
|
||||
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
parse_args() {
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-h|--help) show_usage ;;
|
||||
--relay) RELAY_HOST="$2"; shift 2 ;;
|
||||
--port) RELAY_PORT="$2"; shift 2 ;;
|
||||
--user) SASL_USER="$2"; shift 2 ;;
|
||||
--pass) SASL_PASS="$2"; shift 2 ;;
|
||||
--from) FROM_ADDRESS="$2"; shift 2 ;;
|
||||
--hostname) HOSTNAME_OVERRIDE="$2"; shift 2 ;;
|
||||
--root-alias) ROOT_ALIAS="$2"; shift 2 ;;
|
||||
--tls) TLS_MODE="$2"; shift 2 ;;
|
||||
--no-firewall) NO_FIREWALL=true; shift ;;
|
||||
--dry-run) DRY_RUN=true; shift ;;
|
||||
*) log_error "Unknown option: $1"; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$RELAY_HOST" ]; then
|
||||
log_error "--relay is required"
|
||||
echo ""
|
||||
show_usage
|
||||
fi
|
||||
}
|
||||
|
||||
check_root() {
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
log_error "This script must be run as root"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# OS DETECTION
|
||||
# ============================================================================
|
||||
|
||||
detect_os() {
|
||||
if [ -f /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
OS_FAMILY=""
|
||||
case "$ID" in
|
||||
debian|ubuntu) OS_FAMILY="debian" ;;
|
||||
rhel|centos|rocky|almalinux|fedora) OS_FAMILY="rhel" ;;
|
||||
*)
|
||||
if [ -n "${ID_LIKE:-}" ]; then
|
||||
case "$ID_LIKE" in
|
||||
*debian*|*ubuntu*) OS_FAMILY="debian" ;;
|
||||
*rhel*|*centos*|*fedora*) OS_FAMILY="rhel" ;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$OS_FAMILY" ]; then
|
||||
log_error "Unsupported OS: $ID"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Detected OS: $PRETTY_NAME (family: $OS_FAMILY)"
|
||||
else
|
||||
log_error "Cannot detect OS"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# INSTALLATION
|
||||
# ============================================================================
|
||||
|
||||
remove_conflicting_mta() {
|
||||
log_step "Removing conflicting MTAs..."
|
||||
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
log_info "[DRY RUN] Would remove sendmail/exim if present"
|
||||
return
|
||||
fi
|
||||
|
||||
case "$OS_FAMILY" in
|
||||
debian)
|
||||
apt-get remove -y -qq exim4 exim4-base exim4-daemon-light sendmail 2>/dev/null || true
|
||||
;;
|
||||
rhel)
|
||||
dnf remove -y -q sendmail 2>/dev/null || true
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_postfix() {
|
||||
log_step "Installing Postfix..."
|
||||
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
log_info "[DRY RUN] Would install postfix and dependencies"
|
||||
return
|
||||
fi
|
||||
|
||||
case "$OS_FAMILY" in
|
||||
debian)
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq \
|
||||
postfix libsasl2-modules mailutils ca-certificates >/dev/null 2>&1
|
||||
;;
|
||||
rhel)
|
||||
dnf install -y -q \
|
||||
postfix cyrus-sasl-plain mailx ca-certificates >/dev/null 2>&1
|
||||
;;
|
||||
esac
|
||||
|
||||
log_info "Postfix installed"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# CONFIGURATION
|
||||
# ============================================================================
|
||||
|
||||
configure_relay() {
|
||||
log_step "Configuring relay host: [$RELAY_HOST]:$RELAY_PORT"
|
||||
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
log_info "[DRY RUN] Would configure main.cf"
|
||||
return
|
||||
fi
|
||||
|
||||
local my_hostname
|
||||
my_hostname="${HOSTNAME_OVERRIDE:-$(hostname -f 2>/dev/null || hostname)}"
|
||||
local my_domain
|
||||
my_domain=$(echo "$my_hostname" | sed 's/^[^.]*\.//')
|
||||
|
||||
# Build main.cf
|
||||
cat > /etc/postfix/main.cf <<EOF
|
||||
# Postfix Satellite Relay Configuration
|
||||
# Generated by postfix-relay-install.sh v1.0
|
||||
|
||||
# Identity
|
||||
myhostname = $my_hostname
|
||||
mydomain = $my_domain
|
||||
myorigin = \$mydomain
|
||||
|
||||
# Relay configuration
|
||||
relayhost = [$RELAY_HOST]:$RELAY_PORT
|
||||
|
||||
# Listen only on loopback — relay only, no inbound mail
|
||||
inet_interfaces = loopback-only
|
||||
inet_protocols = all
|
||||
mydestination = \$myhostname, localhost.\$mydomain, localhost
|
||||
|
||||
# SASL authentication
|
||||
smtp_sasl_auth_enable = $([ -n "$SASL_USER" ] && echo "yes" || echo "no")
|
||||
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
|
||||
smtp_sasl_security_options = noanonymous
|
||||
smtp_sasl_tls_security_options = noanonymous
|
||||
|
||||
# TLS configuration
|
||||
smtp_use_tls = yes
|
||||
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
|
||||
smtp_tls_security_level = $TLS_MODE
|
||||
smtp_tls_loglevel = 1
|
||||
|
||||
# Misc
|
||||
alias_maps = hash:/etc/aliases
|
||||
alias_database = hash:/etc/aliases
|
||||
mailbox_size_limit = 0
|
||||
recipient_delimiter = +
|
||||
compatibility_level = 2
|
||||
|
||||
# Queue settings
|
||||
maximal_queue_lifetime = 1d
|
||||
bounce_queue_lifetime = 1d
|
||||
EOF
|
||||
|
||||
# Handle TLS wrapper mode (port 465)
|
||||
if [ "$TLS_MODE" = "wrapper" ]; then
|
||||
postconf -e "smtp_tls_wrappermode = yes"
|
||||
postconf -e "smtp_tls_security_level = encrypt"
|
||||
fi
|
||||
|
||||
# Fix CA cert path for RHEL
|
||||
if [ "$OS_FAMILY" = "rhel" ]; then
|
||||
postconf -e "smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt"
|
||||
fi
|
||||
|
||||
log_info "main.cf configured"
|
||||
}
|
||||
|
||||
configure_sasl() {
|
||||
if [ -z "$SASL_USER" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
log_step "Configuring SASL authentication..."
|
||||
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
log_info "[DRY RUN] Would create sasl_passwd"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "[$RELAY_HOST]:$RELAY_PORT $SASL_USER:$SASL_PASS" > /etc/postfix/sasl_passwd
|
||||
postmap /etc/postfix/sasl_passwd
|
||||
chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
|
||||
|
||||
log_info "SASL credentials configured"
|
||||
}
|
||||
|
||||
configure_sender_rewrite() {
|
||||
if [ -z "$FROM_ADDRESS" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
log_step "Configuring sender rewriting: $FROM_ADDRESS"
|
||||
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
log_info "[DRY RUN] Would create sender_canonical"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "/.+/ $FROM_ADDRESS" > /etc/postfix/sender_canonical_regexp
|
||||
postconf -e "sender_canonical_maps = regexp:/etc/postfix/sender_canonical_regexp"
|
||||
|
||||
log_info "Sender rewriting configured"
|
||||
}
|
||||
|
||||
configure_aliases() {
|
||||
if [ -z "$ROOT_ALIAS" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
log_step "Configuring root alias: $ROOT_ALIAS"
|
||||
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
log_info "[DRY RUN] Would set root alias"
|
||||
return
|
||||
fi
|
||||
|
||||
if grep -q "^root:" /etc/aliases 2>/dev/null; then
|
||||
sed -i "s/^root:.*$/root: $ROOT_ALIAS/" /etc/aliases
|
||||
else
|
||||
echo "root: $ROOT_ALIAS" >> /etc/aliases
|
||||
fi
|
||||
|
||||
newaliases
|
||||
log_info "Root alias set"
|
||||
}
|
||||
|
||||
configure_firewall() {
|
||||
if [ "$NO_FIREWALL" = true ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
log_step "Configuring firewall (blocking inbound SMTP)..."
|
||||
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
log_info "[DRY RUN] Would block inbound port 25"
|
||||
return
|
||||
fi
|
||||
|
||||
# UFW
|
||||
if command -v ufw >/dev/null 2>&1 && ufw status 2>/dev/null | grep -q "active"; then
|
||||
ufw deny in 25/tcp >/dev/null 2>&1 || true
|
||||
log_info "UFW: blocked inbound port 25"
|
||||
fi
|
||||
|
||||
# firewalld
|
||||
if command -v firewall-cmd >/dev/null 2>&1 && systemctl is-active --quiet firewalld 2>/dev/null; then
|
||||
firewall-cmd --permanent --remove-service=smtp >/dev/null 2>&1 || true
|
||||
firewall-cmd --reload >/dev/null 2>&1 || true
|
||||
log_info "firewalld: removed smtp service"
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# SERVICE MANAGEMENT
|
||||
# ============================================================================
|
||||
|
||||
start_postfix() {
|
||||
log_step "Starting Postfix..."
|
||||
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
log_info "[DRY RUN] Would enable and start postfix"
|
||||
return
|
||||
fi
|
||||
|
||||
systemctl enable postfix >/dev/null 2>&1
|
||||
systemctl restart postfix
|
||||
|
||||
if systemctl is-active --quiet postfix; then
|
||||
log_info "Postfix is running"
|
||||
else
|
||||
log_error "Postfix failed to start"
|
||||
journalctl -u postfix --no-pager -n 10
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
send_test() {
|
||||
log_step "Sending test email..."
|
||||
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
log_info "[DRY RUN] Would send test email"
|
||||
return
|
||||
fi
|
||||
|
||||
local test_to="${ROOT_ALIAS:-root}"
|
||||
echo "Test email from $(hostname) via Postfix relay through $RELAY_HOST" | \
|
||||
mail -s "Postfix Relay Test — $(hostname) — $(date '+%Y-%m-%d %H:%M')" "$test_to" 2>/dev/null || true
|
||||
|
||||
log_info "Test email queued (check $test_to inbox)"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# VERIFICATION
|
||||
# ============================================================================
|
||||
|
||||
verify() {
|
||||
log_step "Verifying configuration..."
|
||||
echo ""
|
||||
|
||||
if systemctl is-active --quiet postfix; then
|
||||
log_info "✓ Postfix service: running"
|
||||
else
|
||||
log_error "✗ Postfix service: not running"
|
||||
fi
|
||||
|
||||
log_info "Relay host: $(postconf -h relayhost 2>/dev/null)"
|
||||
log_info "TLS level: $(postconf -h smtp_tls_security_level 2>/dev/null)"
|
||||
log_info "SASL auth: $(postconf -h smtp_sasl_auth_enable 2>/dev/null)"
|
||||
log_info "Interfaces: $(postconf -h inet_interfaces 2>/dev/null)"
|
||||
|
||||
echo ""
|
||||
log_info "Mail queue:"
|
||||
mailq 2>/dev/null | tail -5
|
||||
|
||||
echo ""
|
||||
log_info "Installation complete"
|
||||
echo ""
|
||||
log_info "Useful commands:"
|
||||
echo " mailq — view mail queue"
|
||||
echo " postqueue -f — flush mail queue"
|
||||
echo " tail -f /var/log/mail.log — watch mail log (Debian)"
|
||||
echo " tail -f /var/log/maillog — watch mail log (RHEL)"
|
||||
echo " echo test | mail -s test root — send test email"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# MAIN
|
||||
# ============================================================================
|
||||
|
||||
main() {
|
||||
parse_args "$@"
|
||||
check_root
|
||||
detect_os
|
||||
|
||||
echo ""
|
||||
log_info "=== Postfix Relay Install Script v1.0 ==="
|
||||
echo ""
|
||||
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
log_warn "DRY RUN MODE — no changes will be made"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
remove_conflicting_mta
|
||||
install_postfix
|
||||
configure_relay
|
||||
configure_sasl
|
||||
configure_sender_rewrite
|
||||
configure_aliases
|
||||
configure_firewall
|
||||
start_postfix
|
||||
send_test
|
||||
|
||||
if [ "$DRY_RUN" != true ]; then
|
||||
verify
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user