diff --git a/fix-apache.sh b/fix-apache.sh new file mode 100755 index 0000000..5055e47 --- /dev/null +++ b/fix-apache.sh @@ -0,0 +1,139 @@ +#!/bin/bash + +# Fix Apache Configuration Script +# This script fixes common Apache issues after the main setup + +set -euo pipefail + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +error() { + echo -e "${RED}ERROR: $1${NC}" >&2 + exit 1 +} + +info() { + echo -e "${BLUE}INFO: $1${NC}" +} + +success() { + echo -e "${GREEN}SUCCESS: $1${NC}" +} + +warning() { + echo -e "${YELLOW}WARNING: $1${NC}" +} + +# Check if running as root +if [[ $EUID -ne 0 ]]; then + error "This script must be run as root" +fi + +info "Fixing Apache configuration..." + +# Stop any conflicting services +info "Stopping conflicting services..." +if systemctl is-active --quiet nginx 2>/dev/null; then + systemctl stop nginx + systemctl disable nginx + success "Nginx stopped and disabled" +fi + +if pgrep nginx > /dev/null; then + pkill nginx + success "Killed remaining nginx processes" +fi + +# Stop Apache +systemctl stop apache2 2>/dev/null || true + +# Check what's listening on ports 80 and 443 +info "Checking port usage..." +if ss -tlnp | grep -q ":80 "; then + warning "Something is listening on port 80:" + ss -tlnp | grep ":80 " +fi + +if ss -tlnp | grep -q ":443 "; then + warning "Something is listening on port 443:" + ss -tlnp | grep ":443 " +fi + +# Enable required Apache modules +info "Enabling Apache modules..." +a2enmod ssl +a2enmod rewrite +a2enmod proxy +a2enmod proxy_fcgi +a2enmod setenvif + +# Enable PHP-FPM +info "Configuring PHP-FPM..." +a2enconf php*-fpm +systemctl enable php*-fpm +systemctl restart php*-fpm + +# Check if PostfixAdmin site exists and enable it +if [[ -f "/etc/apache2/sites-available/postfixadmin.conf" ]]; then + a2ensite postfixadmin + success "PostfixAdmin site enabled" +else + warning "PostfixAdmin site configuration not found" +fi + +# Disable default site +a2dissite 000-default 2>/dev/null || true + +# Test Apache configuration +info "Testing Apache configuration..." +if apachectl configtest; then + success "Apache configuration is valid" +else + error "Apache configuration has errors" +fi + +# Start Apache +info "Starting Apache..." +systemctl enable apache2 +systemctl start apache2 + +# Wait for Apache to start +sleep 3 + +# Check if Apache is running +if systemctl is-active --quiet apache2; then + success "Apache is running" +else + error "Apache failed to start" +fi + +# Check listening ports +info "Checking Apache listening ports..." +if ss -tlnp | grep -q ":80.*apache"; then + success "Apache is listening on port 80" +else + warning "Apache is not listening on port 80" +fi + +if ss -tlnp | grep -q ":443.*apache"; then + success "Apache is listening on port 443" +else + warning "Apache is not listening on port 443" +fi + +# Show Apache status +info "Apache status:" +systemctl status apache2 --no-pager + +# Show enabled sites +info "Enabled Apache sites:" +a2ensite 2>&1 | grep "already enabled" || echo "No sites explicitly enabled" + +info "Apache configuration fix completed!" +info "You can check Apache error logs with: journalctl -u apache2 -f" +info "You can also check: /var/log/apache2/error.log" diff --git a/fix-postfixadmin-site.sh b/fix-postfixadmin-site.sh index 6983eaf..e69de29 100755 --- a/fix-postfixadmin-site.sh +++ b/fix-postfixadmin-site.sh @@ -1,118 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -# Colors -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' - -info() { echo -e "${BLUE}INFO: $1${NC}"; } -success() { echo -e "${GREEN}SUCCESS: $1${NC}"; } -warning() { echo -e "${YELLOW}WARNING: $1${NC}"; } -error() { echo -e "${RED}ERROR: $1${NC}"; } - -HOSTNAME="mail.terrible.dev" - -info "Configuring Apache for PostfixAdmin..." - -# Check if PostfixAdmin directory exists -if [[ ! -d "/var/www/postfixadmin" ]]; then - error "PostfixAdmin directory not found at /var/www/postfixadmin" - echo "This means the PostfixAdmin installation step was not completed." - echo "You may need to run the resume-setup.sh script first." - exit 1 -fi - -# Create PostfixAdmin Apache configuration -info "Creating PostfixAdmin Apache site configuration..." -sudo tee /etc/apache2/sites-available/postfixadmin.conf > /dev/null << EOF - - ServerName $HOSTNAME - Redirect permanent / https://$HOSTNAME/ - - - - ServerName $HOSTNAME - DocumentRoot /var/www/postfixadmin/public - - SSLEngine on - SSLCertificateFile /etc/letsencrypt/live/$HOSTNAME/fullchain.pem - SSLCertificateKeyFile /etc/letsencrypt/live/$HOSTNAME/privkey.pem - - # Modern SSL configuration - SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 - SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384 - SSLHonorCipherOrder on - - - Options -Indexes - AllowOverride All - Require all granted - - - # Alternative document root if public folder doesn't exist - - Options -Indexes - AllowOverride All - Require all granted - - - ErrorLog \${APACHE_LOG_DIR}/postfixadmin_error.log - CustomLog \${APACHE_LOG_DIR}/postfixadmin_access.log combined - -EOF - -# Check if public directory exists, if not use main directory -if [[ ! -d "/var/www/postfixadmin/public" ]]; then - warning "PostfixAdmin public directory not found, using main directory" - sudo sed -i 's|DocumentRoot /var/www/postfixadmin/public|DocumentRoot /var/www/postfixadmin|' /etc/apache2/sites-available/postfixadmin.conf -fi - -# Disable default site and enable PostfixAdmin -info "Enabling PostfixAdmin site..." -sudo a2dissite 000-default 2>/dev/null || true -sudo a2ensite postfixadmin - -# Test Apache configuration -if sudo apache2ctl configtest; then - success "Apache configuration is valid" -else - error "Apache configuration test failed" - exit 1 -fi - -# Reload Apache -sudo systemctl reload apache2 - -# Test PostfixAdmin access -info "Testing PostfixAdmin access..." -sleep 2 - -if curl -I -k https://$HOSTNAME/postfixadmin/ 2>/dev/null | grep -q "200\|302\|301"; then - success "PostfixAdmin is accessible!" - echo - echo "🎉 PostfixAdmin URLs:" - echo " Setup: https://$HOSTNAME/postfixadmin/setup.php" - echo " Login: https://$HOSTNAME/postfixadmin/" - echo -elif curl -I -k https://$HOSTNAME/ 2>/dev/null | grep -q "200\|302\|301"; then - warning "Site accessible but PostfixAdmin may need setup" - echo - echo "📋 Try these URLs:" - echo " Main: https://$HOSTNAME/" - echo " Setup: https://$HOSTNAME/setup.php" - echo " Admin: https://$HOSTNAME/admin/" -else - error "PostfixAdmin not accessible" - echo "Check Apache error logs:" - echo "sudo tail -f /var/log/apache2/error.log" -fi - -info "Current site status:" -echo "Available sites:" -sudo ls -la /etc/apache2/sites-available/ | grep postfixadmin || echo " No postfixadmin config found" -echo "Enabled sites:" -sudo ls -la /etc/apache2/sites-enabled/ diff --git a/setup-email-server.sh b/setup-email-server.sh index e4d55a7..9db4258 100755 --- a/setup-email-server.sh +++ b/setup-email-server.sh @@ -4,7 +4,7 @@ # Components: Postfix, Dovecot, Amavis, SpamAssassin, OpenDKIM, PostgreSQL, PostfixAdmin # SSL: Let's Encrypt (DNS-01 Challenge) # Author: Email Server Setup Script -# Date: $(date) +# Date: Sun Aug 3 15:05:28 EDT 2025 set -euo pipefail @@ -24,6 +24,7 @@ DB_USER="postfix" DB_PASSWORD="" POSTFIXADMIN_PASSWORD="" WEBROOT="/var/www/postfixadmin" +POSTFIXADMIN_VHOST_FILE="/etc/apache2/sites-available/postfixadmin.conf" # Logging LOG_FILE="/var/log/email-server-setup.log" @@ -60,6 +61,46 @@ check_root() { fi } + +verify_email_storage() { + info "Verifying email storage at /mnt/MainEmail..." + + # Check if directory exists + if [[ ! -d "/mnt/MainEmail" ]]; then + error "Email storage directory /mnt/MainEmail does not exist. Please run prepare-email-storage.sh first." + fi + + # Check if vmail user exists + if ! getent passwd vmail >/dev/null; then + error "vmail user does not exist. Please run prepare-email-storage.sh first." + fi + + # Check ownership + OWNER=$(stat -c '%U:%G' /mnt/MainEmail) + if [[ "$OWNER" != "vmail:vmail" ]]; then + warning "Incorrect ownership on /mnt/MainEmail. Expected vmail:vmail, got $OWNER" + info "Fixing ownership..." + chown vmail:vmail /mnt/MainEmail + fi + + # Check write permissions + if ! sudo -u vmail test -w /mnt/MainEmail; then + error "vmail user cannot write to /mnt/MainEmail. Please run prepare-email-storage.sh first." + fi + + # Check available space + AVAILABLE_SPACE=$(df --output=avail /mnt/MainEmail | tail -n1) + AVAILABLE_GB=$((AVAILABLE_SPACE / 1024 / 1024)) + + if [[ $AVAILABLE_GB -lt 5 ]]; then + warning "Low disk space: only ${AVAILABLE_GB}GB available in /mnt/MainEmail" + else + info "Email storage ready: ${AVAILABLE_GB}GB available" + fi + + success "Email storage verification completed" +} + # Get user input get_configuration() { echo -e "${BLUE}Email Server Configuration${NC}" @@ -101,6 +142,33 @@ update_system() { install_packages() { info "Installing required packages..." + # Check for and stop Nginx if it's running to avoid port conflicts with Apache + if systemctl is-active --quiet nginx 2>/dev/null; then + warning "Nginx is running and will be stopped to allow Apache to run." + systemctl stop nginx + systemctl disable nginx + elif command -v nginx &> /dev/null; then + warning "Nginx is installed but not running as a service." + # Check if nginx is running manually and kill it + if pgrep nginx > /dev/null; then + warning "Found nginx processes, killing them..." + pkill nginx + fi + fi + + # Also check if anything is listening on port 80 or 443 + if ss -tlnp | grep -q ":80 "; then + warning "Something is already listening on port 80:" + ss -tlnp | grep ":80 " + echo "You may need to stop this service manually before Apache can start." + fi + + if ss -tlnp | grep -q ":443 "; then + warning "Something is already listening on port 443:" + ss -tlnp | grep ":443 " + echo "You may need to stop this service manually before Apache can start." + fi + # Install basic packages apt install -y \ curl \ @@ -109,7 +177,6 @@ install_packages() { lsb-release \ software-properties-common \ certbot \ - nginx \ ufw # Install PostgreSQL @@ -303,7 +370,7 @@ mydestination = localhost virtual_mailbox_domains = pgsql:/etc/postfix/pgsql-virtual-mailbox-domains.cf virtual_mailbox_maps = pgsql:/etc/postfix/pgsql-virtual-mailbox-maps.cf virtual_alias_maps = pgsql:/etc/postfix/pgsql-virtual-alias-maps.cf -virtual_mailbox_base = /var/mail/vhosts +virtual_mailbox_base = /mnt/MainEmail virtual_minimum_uid = 100 virtual_uid_maps = static:5000 virtual_gid_maps = static:5000 @@ -427,10 +494,10 @@ smtp-amavis unix - - - - 2 smtp EOF # Create virtual mailbox directory - mkdir -p /var/mail/vhosts + mkdir -p /mnt/MainEmail groupadd -g 5000 vmail 2>/dev/null || true - useradd -g vmail -u 5000 vmail -d /var/mail/vhosts -m 2>/dev/null || true - chown -R vmail:vmail /var/mail/vhosts + useradd -g vmail -u 5000 vmail -d /mnt/MainEmail -m 2>/dev/null || true + chown -R vmail:vmail /mnt/MainEmail success "Postfix configured" } @@ -452,7 +519,7 @@ EOF # 10-mail.conf cat > /etc/dovecot/conf.d/10-mail.conf << EOF -mail_location = maildir:/var/mail/vhosts/%d/%n +mail_location = maildir:/mnt/MainEmail/%d/%n namespace inbox { inbox = yes } @@ -480,7 +547,7 @@ passdb { } userdb { driver = static - args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n + args = uid=vmail gid=vmail home=/mnt/MainEmail/%d/%n } EOF @@ -722,7 +789,7 @@ get_ssl_certificates() { success "SSL certificates obtained" } -# Install PostfixAdmin +# Install PostfixAdmin and configure Apache install_postfixadmin() { info "Installing PostfixAdmin..." @@ -769,7 +836,7 @@ function maildir_name_hook(\$domain, \$user) { EOF # Configure Apache virtual host - cat > /etc/apache2/sites-available/postfixadmin.conf << EOF + cat > "$POSTFIXADMIN_VHOST_FILE" << EOF ServerName $HOSTNAME Redirect permanent / https://$HOSTNAME/ @@ -777,30 +844,61 @@ EOF ServerName $HOSTNAME - DocumentRoot $WEBROOT/public + DocumentRoot $WEBROOT + DirectoryIndex index.php index.html SSLEngine on SSLCertificateFile /etc/letsencrypt/live/$HOSTNAME/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/$HOSTNAME/privkey.pem + SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 + SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384 + SSLHonorCipherOrder on - + Options -Indexes AllowOverride All Require all granted + # PHP configuration + + SetHandler "proxy:unix:/run/php/php-fpm.sock|fcgi://localhost" + + ErrorLog \${APACHE_LOG_DIR}/postfixadmin_error.log CustomLog \${APACHE_LOG_DIR}/postfixadmin_access.log combined EOF - # Enable Apache modules and site + # Stop Apache before configuration changes + if systemctl is-active --quiet apache2; then + systemctl stop apache2 + fi + + # Enable required Apache modules a2enmod ssl a2enmod rewrite + a2enmod proxy + a2enmod proxy_fcgi + a2enmod setenvif + + # Enable PHP-FPM configuration + a2enconf php*-fpm + + # Enable PostfixAdmin site and disable default a2ensite postfixadmin a2dissite 000-default - success "PostfixAdmin installed" + # Ensure PHP-FPM is running + systemctl enable php*-fpm + systemctl start php*-fpm + + # Check Apache config before starting + if ! apachectl configtest; then + error "Apache configuration test failed. Please check $POSTFIXADMIN_VHOST_FILE" + fi + + success "PostfixAdmin installed and Apache configured" } # Configure firewall @@ -852,8 +950,28 @@ start_services() { systemctl enable --now clamav-daemon systemctl enable --now clamav-freshclam systemctl enable --now opendkim - systemctl enable --now apache2 + # Start Apache2 and verify + info "Starting Apache2..." + systemctl enable apache2 + systemctl restart apache2 + + # Wait a moment for Apache to start + sleep 2 + + if ! systemctl is-active --quiet apache2; then + error "Apache2 failed to start. Check 'journalctl -xeu apache2' for details." + fi + + # Verify Apache is listening on both ports + if ! ss -tlnp | grep -q ":80 "; then + warning "Apache is not listening on port 80" + fi + + if ! ss -tlnp | grep -q ":443 "; then + warning "Apache is not listening on port 443" + fi + success "All services started and enabled" } @@ -877,10 +995,10 @@ display_final_info() { cat /etc/opendkim/keys/$DOMAIN/mail.txt echo echo -e "${YELLOW}=== Next Steps ===${NC}" - echo "1. Add the DNS records shown above" - echo "2. Visit https://$HOSTNAME/postfixadmin/setup.php to complete PostfixAdmin setup" - echo "3. Create your first domain and mailbox in PostfixAdmin" - echo "4. Test email sending and receiving" + echo "1. Add the DNS records shown above." + echo "2. Visit https://$HOSTNAME/postfixadmin/setup.php to complete PostfixAdmin setup." + echo "3. Create your first domain and mailbox in PostfixAdmin." + echo "4. Test email sending and receiving." echo echo -e "${BLUE}=== Multiple Domain Support ===${NC}" echo "This server supports unlimited virtual domains!" @@ -902,26 +1020,27 @@ display_final_info() { echo -e "${GREEN}Setup completed successfully!${NC}" } -# Main execution +# Main function to run all setup steps main() { - echo -e "${BLUE}Email Server Setup Script${NC}" - echo "=========================" - echo + log "Starting email server setup script" check_root + verify_email_storage get_configuration update_system install_packages configure_postgresql - get_ssl_certificates configure_postfix configure_dovecot configure_opendkim configure_amavis + get_ssl_certificates install_postfixadmin configure_firewall start_services display_final_info + + log "Email server setup completed successfully" } # Run main function diff --git a/test-apache.sh b/test-apache.sh new file mode 100755 index 0000000..3f1b811 --- /dev/null +++ b/test-apache.sh @@ -0,0 +1,134 @@ +#!/bin/bash + +# Test Apache and PostfixAdmin Setup +# This script helps diagnose Apache and PostfixAdmin issues + +set -euo pipefail + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +info() { + echo -e "${BLUE}INFO: $1${NC}" +} + +success() { + echo -e "${GREEN}SUCCESS: $1${NC}" +} + +warning() { + echo -e "${YELLOW}WARNING: $1${NC}" +} + +error() { + echo -e "${RED}ERROR: $1${NC}" +} + +info "=== Apache and PostfixAdmin Diagnostic ===" + +# Check Apache status +info "1. Checking Apache status..." +if systemctl is-active --quiet apache2; then + success "Apache is running" +else + error "Apache is not running" + echo "Try: systemctl start apache2" +fi + +# Check listening ports +info "2. Checking listening ports..." +echo "Ports 80 and 443:" +ss -tlnp | grep -E ":(80|443) " || warning "No services listening on ports 80 or 443" + +# Check Apache sites +info "3. Checking Apache sites..." +echo "Available sites:" +ls -la /etc/apache2/sites-available/ 2>/dev/null || warning "No sites-available directory" + +echo "Enabled sites:" +ls -la /etc/apache2/sites-enabled/ 2>/dev/null || warning "No sites-enabled directory" + +# Check PostfixAdmin directory +info "4. Checking PostfixAdmin installation..." +WEBROOT="/var/www/postfixadmin" +if [[ -d "$WEBROOT" ]]; then + success "PostfixAdmin directory exists: $WEBROOT" + echo "Contents:" + ls -la "$WEBROOT" | head -10 + + # Check if index.php exists + if [[ -f "$WEBROOT/index.php" ]]; then + success "index.php found" + elif [[ -f "$WEBROOT/public/index.php" ]]; then + success "index.php found in public directory" + warning "You may need to update DocumentRoot to $WEBROOT/public" + else + warning "index.php not found" + fi + + # Check permissions + echo "Permissions:" + ls -ld "$WEBROOT" +else + error "PostfixAdmin directory not found: $WEBROOT" +fi + +# Check PHP-FPM +info "5. Checking PHP-FPM..." +if systemctl is-active --quiet php*-fpm; then + success "PHP-FPM is running" +else + warning "PHP-FPM may not be running" + echo "Try: systemctl status php*-fpm" +fi + +# Check Apache configuration +info "6. Testing Apache configuration..." +if apachectl configtest 2>/dev/null; then + success "Apache configuration is valid" +else + error "Apache configuration has errors:" + apachectl configtest +fi + +# Check SSL certificates +info "7. Checking SSL certificates..." +HOSTNAME=$(hostname -f 2>/dev/null || hostname) +if [[ -f "/etc/letsencrypt/live/$HOSTNAME/fullchain.pem" ]]; then + success "SSL certificate found for $HOSTNAME" +else + warning "SSL certificate not found for $HOSTNAME" + echo "Check: ls -la /etc/letsencrypt/live/" +fi + +# Check Apache error log +info "8. Recent Apache errors (last 10 lines):" +if [[ -f "/var/log/apache2/error.log" ]]; then + tail -10 /var/log/apache2/error.log +else + warning "Apache error log not found" +fi + +# Test HTTP response +info "9. Testing HTTP response..." +if command -v curl &> /dev/null; then + echo "HTTP (port 80) response:" + curl -I -s http://localhost/ 2>/dev/null | head -5 || warning "No response on port 80" + + echo "HTTPS (port 443) response:" + curl -I -s -k https://localhost/ 2>/dev/null | head -5 || warning "No response on port 443" +else + warning "curl not installed, cannot test HTTP responses" +fi + +info "=== Diagnostic completed ===" +echo +info "If Apache is not working:" +echo "1. Check: journalctl -u apache2 -f" +echo "2. Check: /var/log/apache2/error.log" +echo "3. Try: systemctl restart apache2" +echo "4. Run: ./fix-apache.sh"