Update install-mailcow-debian.sh

This commit is contained in:
HHF Technology 2024-12-06 16:31:19 +05:30
parent 3a542bf108
commit e7896a3028

View file

@ -1,75 +1,121 @@
#!/bin/bash #!/bin/bash
# Exit on any error # Exit on error
set -e set -e
# Checkpoint file
CHECKPOINT_FILE="/tmp/mailcow_install_progress"
MAILCOW_DIR="/opt/mailcow-dockerized"
# Function to log messages # Function to log messages
log_message() { log_message() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
} }
# Function to save checkpoint
save_checkpoint() {
echo "$1" > "$CHECKPOINT_FILE"
log_message "Checkpoint saved: $1"
}
# Function to get last checkpoint
get_checkpoint() {
if [ -f "$CHECKPOINT_FILE" ]; then
cat "$CHECKPOINT_FILE"
else
echo "start"
fi
}
# Function to check if a step is completed
is_step_completed() {
local current_checkpoint=$(get_checkpoint)
local step=$1
case $current_checkpoint in
"docker_installed"|"fail2ban_configured"|"mailcow_installed"|"complete")
if [ "$step" = "system_updated" ]; then return 0; fi
;;
"fail2ban_configured"|"mailcow_installed"|"complete")
if [ "$step" = "docker_installed" ]; then return 0; fi
;;
"mailcow_installed"|"complete")
if [ "$step" = "fail2ban_configured" ]; then return 0; fi
;;
"complete")
if [ "$step" = "mailcow_installed" ]; then return 0; fi
;;
esac
return 1
}
# Check if script is run as root # Check if script is run as root
if [ "$EUID" -ne 0 ]; then if [ "$EUID" -ne 0 ]; then
echo "Please run as root" echo "Please run as root"
exit 1 exit 1
fi fi
# Update system # Start or resume installation
log_message "Updating system packages..." log_message "Starting or resuming installation from checkpoint: $(get_checkpoint)"
apt-get update && apt-get upgrade -y
# Install essential packages # Step 1: Update system and install prerequisites
log_message "Installing essential packages..." if ! is_step_completed "system_updated"; then
apt-get install -y \ log_message "Updating system packages..."
apt-get update && apt-get upgrade -y
apt-get install -y \
apt-transport-https \
ca-certificates \ ca-certificates \
curl \ curl \
gnupg \ gnupg \
ufw \ ufw \
fail2ban \ fail2ban \
git \ git \
sudo sudo \
wget \
lsb-release
save_checkpoint "system_updated"
fi
# Install Docker # Step 2: Install Docker
log_message "Installing Docker..." if ! is_step_completed "docker_installed"; then
install -m 0755 -d /etc/apt/keyrings log_message "Installing Docker..."
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
# Add Docker repository # Remove any old Docker installations
echo \ for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
apt-get remove -y $pkg || true
done
# Add Docker's official GPG key
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Create docker user and set up permissions # Create docker user if not exists
log_message "Creating docker user and setting up permissions..." if ! id "dockeruser" &>/dev/null; then
useradd -m -s /bin/bash dockeruser useradd -m -s /bin/bash dockeruser
usermod -aG docker dockeruser usermod -aG docker dockeruser
echo "dockeruser ALL=(ALL) NOPASSWD: /usr/bin/docker, /usr/bin/docker-compose" | sudo tee /etc/sudoers.d/dockeruser fi
# Configure UFW # Start and enable Docker service
log_message "Configuring firewall..." systemctl start docker
ufw default deny incoming systemctl enable docker
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 25/tcp
ufw allow 80/tcp
ufw allow 110/tcp
ufw allow 143/tcp
ufw allow 443/tcp
ufw allow 465/tcp
ufw allow 587/tcp
ufw allow 993/tcp
ufw allow 995/tcp
ufw allow 4190/tcp
ufw --force enable
# Configure fail2ban for SSH save_checkpoint "docker_installed"
log_message "Configuring fail2ban for SSH protection..." fi
cat > /etc/fail2ban/jail.local << EOL
# Step 3: Configure fail2ban
if ! is_step_completed "fail2ban_configured"; then
log_message "Configuring fail2ban..."
cat > /etc/fail2ban/jail.local << EOL
[DEFAULT] [DEFAULT]
bantime = 1h bantime = 1h
findtime = 10m findtime = 10m
@ -89,129 +135,92 @@ bantime = 1d
findtime = 10m findtime = 10m
EOL EOL
# Reload systemd daemon # Enable and restart fail2ban
systemctl daemon-reload systemctl enable fail2ban
systemctl restart fail2ban
# Restart fail2ban save_checkpoint "fail2ban_configured"
systemctl restart fail2ban
# Restart fail2ban
systemctl restart fail2ban
# Set up Mailcow directory and permissions
log_message "Setting up Mailcow directory..."
mkdir -p /opt/mailcow-dockerized
chown dockeruser:dockeruser /opt/mailcow-dockerized
# Function to get FQDN input
get_fqdn() {
local fqdn
while true; do
read -p "Please enter your Fully Qualified Domain Name (FQDN) (e.g., mail.example.com): " fqdn
if [[ $fqdn =~ ^[a-zA-Z0-9][a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
echo "$fqdn"
return 0
else
echo "Invalid FQDN format. Please try again."
fi
done
}
# Get timezone
get_timezone() {
local timezone
while true; do
read -p "Please enter your timezone (e.g., Europe/Berlin) [default: UTC]: " timezone
timezone=${timezone:-UTC}
if [ -f "/usr/share/zoneinfo/$timezone" ]; then
echo "$timezone"
return 0
else
echo "Invalid timezone. Please try again."
fi
done
}
# Function to configure mailcow
configure_mailcow() {
local fqdn=$1
local timezone=$2
# Create temporary config file
cat > /tmp/mailcow_config << EOL
MAILCOW_HOSTNAME=${fqdn}
TIMEZONE=${timezone}
EOL
# Ask for additional configuration
read -p "Do you want to customize additional mailcow configuration? (y/N): " customize
if [[ $customize =~ ^[Yy]$ ]]; then
nano /tmp/mailcow_config
fi
return 0
}
# Switch to dockeruser and install Mailcow
log_message "Installing Mailcow as dockeruser..."
# Get configuration parameters
FQDN=$(get_fqdn)
TIMEZONE=$(get_timezone)
# Store configuration for dockeruser
echo "FQDN=$FQDN" > /tmp/mailcow_vars
echo "TIMEZONE=$TIMEZONE" >> /tmp/mailcow_vars
configure_mailcow "$FQDN" "$TIMEZONE"
su - dockeruser << 'EOF'
# Source the configuration variables
source /tmp/mailcow_vars
# Clone and set up mailcow
cd /opt
git clone https://github.com/mailcow/mailcow-dockerized
cd mailcow-dockerized
# Use the prepared configuration
cat /tmp/mailcow_config > mailcow.conf
# Generate config with the provided FQDN
printf "%s\n" "$FQDN" | ./generate_config.sh
# Offer to edit the full configuration
read -p "Would you like to review and edit the full mailcow configuration? (y/N): " edit_conf
if [[ $edit_conf =~ ^[Yy]$ ]]; then
nano mailcow.conf
fi fi
# Start Mailcow # Step 4: Install and configure Mailcow
docker compose pull if ! is_step_completed "mailcow_installed"; then
docker compose up -d log_message "Setting up Mailcow..."
EOF
# Clean up temporary files # Check if FQDN is already set
rm -f /tmp/mailcow_vars /tmp/mailcow_config if [ ! -f "/tmp/mailcow_hostname" ]; then
read -p "Please enter your Fully Qualified Domain Name (FQDN) (e.g., mail.example.com): " MAILCOW_HOSTNAME
echo "$MAILCOW_HOSTNAME" > /tmp/mailcow_hostname
else
MAILCOW_HOSTNAME=$(cat /tmp/mailcow_hostname)
log_message "Using saved FQDN: $MAILCOW_HOSTNAME"
fi
# Final security checks # Create mailcow directory if not exists
log_message "Performing final security checks..." if [ ! -d "$MAILCOW_DIR" ]; then
su - dockeruser -c "cd /opt/mailcow-dockerized && docker compose ps" mkdir -p "$MAILCOW_DIR"
ufw status chown dockeruser:dockeruser "$MAILCOW_DIR"
systemctl status fail2ban
log_message "Installation complete! Please check the logs above for any errors." # Clone repository
log_message "Remember to:" su - dockeruser -c "cd /opt && git clone https://github.com/mailcow/mailcow-dockerized"
log_message "1. Change the default passwords" fi
log_message "2. Configure your DNS records"
log_message "3. Set up SSL certificates"
log_message "4. Regular backup your configuration"
# Print access information # Generate config if not already generated
echo "================================================================" if [ ! -f "$MAILCOW_DIR/mailcow.conf" ]; then
echo "Mailcow web interface: https://$(hostname)" cd "$MAILCOW_DIR"
echo "Docker user: dockeruser" echo "$MAILCOW_HOSTNAME" | ./generate_config.sh
echo "Mailcow location: /opt/mailcow-dockerized"
echo "Firewall status:" echo "Would you like to edit the mailcow configuration? (y/N)"
ufw status numbered read -n1 -r
echo "================================================================" echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
nano mailcow.conf
fi
fi
# Start Mailcow services
log_message "Starting Mailcow services..."
su - dockeruser -c "cd $MAILCOW_DIR && docker compose pull && docker compose up -d"
save_checkpoint "mailcow_installed"
fi
# Configure UFW if not already configured
if ! ufw status | grep -q "Status: active"; then
log_message "Configuring firewall..."
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 25/tcp
ufw allow 80/tcp
ufw allow 110/tcp
ufw allow 143/tcp
ufw allow 443/tcp
ufw allow 465/tcp
ufw allow 587/tcp
ufw allow 993/tcp
ufw allow 995/tcp
ufw allow 4190/tcp
ufw --force enable
fi
# Final steps and cleanup
if [ "$(get_checkpoint)" = "mailcow_installed" ]; then
log_message "Installation completed successfully!"
rm -f "$CHECKPOINT_FILE" "/tmp/mailcow_hostname"
save_checkpoint "complete"
# Print access information
echo "================================================================"
echo "Mailcow web interface: https://$MAILCOW_HOSTNAME"
echo "Docker user: dockeruser"
echo "Mailcow location: $MAILCOW_DIR"
echo "Firewall status:"
ufw status numbered
echo "Fail2ban status:"
fail2ban-client status
echo "================================================================"
echo "Next steps:"
echo "1. Configure your DNS records for $MAILCOW_HOSTNAME"
echo "2. Access the web interface at https://$MAILCOW_HOSTNAME"
echo "3. Default credentials: admin / moohoo"
echo "================================================================"
fi