ok stop
This commit is contained in:
0
prepare-email-storage.sh
Normal file → Executable file
0
prepare-email-storage.sh
Normal file → Executable file
@@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
# Email Server Setup Script
|
# Email Server Setup Script
|
||||||
# Components: Postfix, Dovecot, Amavis, SpamAssassin, OpenDKIM, PostgreSQL, PostfixAdmin
|
# Components: Postfix, Dovecot, Amavis, SpamAssassin, OpenDKIM, PostgreSQL, PostfixAdmin
|
||||||
# SSL: Let's Encrypt (DNS-01 Challenge)
|
# SSL: Let's Encrypt
|
||||||
|
# Web Server: Nginx
|
||||||
# Author: Email Server Setup Script
|
# Author: Email Server Setup Script
|
||||||
# Date: Sun Aug 3 15:05:28 EDT 2025
|
# Date: $(date)
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
@@ -24,7 +25,7 @@ DB_USER="postfix"
|
|||||||
DB_PASSWORD=""
|
DB_PASSWORD=""
|
||||||
POSTFIXADMIN_PASSWORD=""
|
POSTFIXADMIN_PASSWORD=""
|
||||||
WEBROOT="/var/www/postfixadmin"
|
WEBROOT="/var/www/postfixadmin"
|
||||||
POSTFIXADMIN_VHOST_FILE="/etc/apache2/sites-available/postfixadmin.conf"
|
POSTFIXADMIN_VERSION="postfixadmin-3.3.11.tar.gz"
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
LOG_FILE="/var/log/email-server-setup.log"
|
LOG_FILE="/var/log/email-server-setup.log"
|
||||||
@@ -61,46 +62,6 @@ check_root() {
|
|||||||
fi
|
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 user input
|
||||||
get_configuration() {
|
get_configuration() {
|
||||||
echo -e "${BLUE}Email Server Configuration${NC}"
|
echo -e "${BLUE}Email Server Configuration${NC}"
|
||||||
@@ -142,33 +103,6 @@ update_system() {
|
|||||||
install_packages() {
|
install_packages() {
|
||||||
info "Installing required 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
|
# Install basic packages
|
||||||
apt install -y \
|
apt install -y \
|
||||||
curl \
|
curl \
|
||||||
@@ -177,6 +111,8 @@ install_packages() {
|
|||||||
lsb-release \
|
lsb-release \
|
||||||
software-properties-common \
|
software-properties-common \
|
||||||
certbot \
|
certbot \
|
||||||
|
python3-certbot-nginx \
|
||||||
|
nginx \
|
||||||
ufw
|
ufw
|
||||||
|
|
||||||
# Install PostgreSQL
|
# Install PostgreSQL
|
||||||
@@ -217,10 +153,8 @@ install_packages() {
|
|||||||
# Install OpenDKIM
|
# Install OpenDKIM
|
||||||
apt install -y opendkim opendkim-tools
|
apt install -y opendkim opendkim-tools
|
||||||
|
|
||||||
# Install PHP and Apache for PostfixAdmin
|
# Install PHP and extensions for PostfixAdmin
|
||||||
apt install -y \
|
apt install -y \
|
||||||
apache2 \
|
|
||||||
php \
|
|
||||||
php-fpm \
|
php-fpm \
|
||||||
php-cli \
|
php-cli \
|
||||||
php-pgsql \
|
php-pgsql \
|
||||||
@@ -242,13 +176,13 @@ configure_postgresql() {
|
|||||||
systemctl enable postgresql
|
systemctl enable postgresql
|
||||||
|
|
||||||
# Create database and user
|
# Create database and user
|
||||||
sudo -u postgres psql -c "CREATE DATABASE $DB_NAME;"
|
sudo -u postgres psql -c "CREATE DATABASE $DB_NAME;" || warning "Database already exists, skipping."
|
||||||
sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASSWORD';"
|
sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASSWORD';" || warning "User already exists, skipping."
|
||||||
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;"
|
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;"
|
||||||
|
|
||||||
# Create tables for Postfix
|
# Create tables for Postfix
|
||||||
sudo -u postgres psql -d "$DB_NAME" << 'EOF'
|
sudo -u postgres psql -d "$DB_NAME" << 'EOF'
|
||||||
CREATE TABLE domains (
|
CREATE TABLE IF NOT EXISTS domains (
|
||||||
domain varchar(50) NOT NULL,
|
domain varchar(50) NOT NULL,
|
||||||
description varchar(255),
|
description varchar(255),
|
||||||
aliases int NOT NULL default '0',
|
aliases int NOT NULL default '0',
|
||||||
@@ -263,7 +197,7 @@ CREATE TABLE domains (
|
|||||||
PRIMARY KEY (domain)
|
PRIMARY KEY (domain)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE aliases (
|
CREATE TABLE IF NOT EXISTS aliases (
|
||||||
address varchar(255) NOT NULL,
|
address varchar(255) NOT NULL,
|
||||||
goto text NOT NULL,
|
goto text NOT NULL,
|
||||||
domain varchar(255) NOT NULL,
|
domain varchar(255) NOT NULL,
|
||||||
@@ -273,7 +207,7 @@ CREATE TABLE aliases (
|
|||||||
PRIMARY KEY (address)
|
PRIMARY KEY (address)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE mailbox (
|
CREATE TABLE IF NOT EXISTS mailbox (
|
||||||
username varchar(255) NOT NULL,
|
username varchar(255) NOT NULL,
|
||||||
password varchar(255) NOT NULL,
|
password varchar(255) NOT NULL,
|
||||||
name varchar(255) NOT NULL default '',
|
name varchar(255) NOT NULL default '',
|
||||||
@@ -287,7 +221,7 @@ CREATE TABLE mailbox (
|
|||||||
PRIMARY KEY (username)
|
PRIMARY KEY (username)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE domain_admins (
|
CREATE TABLE IF NOT EXISTS domain_admins (
|
||||||
username varchar(255) NOT NULL,
|
username varchar(255) NOT NULL,
|
||||||
domain varchar(255) NOT NULL,
|
domain varchar(255) NOT NULL,
|
||||||
created timestamp NOT NULL default now(),
|
created timestamp NOT NULL default now(),
|
||||||
@@ -295,7 +229,7 @@ CREATE TABLE domain_admins (
|
|||||||
PRIMARY KEY (username, domain)
|
PRIMARY KEY (username, domain)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE admin (
|
CREATE TABLE IF NOT EXISTS admin (
|
||||||
username varchar(255) NOT NULL,
|
username varchar(255) NOT NULL,
|
||||||
password varchar(255) NOT NULL,
|
password varchar(255) NOT NULL,
|
||||||
created timestamp NOT NULL default now(),
|
created timestamp NOT NULL default now(),
|
||||||
@@ -304,7 +238,7 @@ CREATE TABLE admin (
|
|||||||
PRIMARY KEY (username)
|
PRIMARY KEY (username)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE log (
|
CREATE TABLE IF NOT EXISTS log (
|
||||||
timestamp timestamp NOT NULL default now(),
|
timestamp timestamp NOT NULL default now(),
|
||||||
username varchar(255) NOT NULL default '',
|
username varchar(255) NOT NULL default '',
|
||||||
domain varchar(255) NOT NULL default '',
|
domain varchar(255) NOT NULL default '',
|
||||||
@@ -312,7 +246,7 @@ CREATE TABLE log (
|
|||||||
data text NOT NULL default ''
|
data text NOT NULL default ''
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE vacation (
|
CREATE TABLE IF NOT EXISTS vacation (
|
||||||
email varchar(255) NOT NULL,
|
email varchar(255) NOT NULL,
|
||||||
subject varchar(255) NOT NULL,
|
subject varchar(255) NOT NULL,
|
||||||
body text NOT NULL,
|
body text NOT NULL,
|
||||||
@@ -323,14 +257,14 @@ CREATE TABLE vacation (
|
|||||||
PRIMARY KEY (email)
|
PRIMARY KEY (email)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE quota (
|
CREATE TABLE IF NOT EXISTS quota (
|
||||||
username varchar(255) NOT NULL,
|
username varchar(255) NOT NULL,
|
||||||
path varchar(100) NOT NULL,
|
path varchar(100) NOT NULL,
|
||||||
current bigint NOT NULL default 0,
|
current bigint NOT NULL default 0,
|
||||||
PRIMARY KEY (username, path)
|
PRIMARY KEY (username, path)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE quota2 (
|
CREATE TABLE IF NOT EXISTS quota2 (
|
||||||
username varchar(100) NOT NULL,
|
username varchar(100) NOT NULL,
|
||||||
bytes bigint NOT NULL default 0,
|
bytes bigint NOT NULL default 0,
|
||||||
messages int NOT NULL default 0,
|
messages int NOT NULL default 0,
|
||||||
@@ -370,7 +304,7 @@ mydestination = localhost
|
|||||||
virtual_mailbox_domains = pgsql:/etc/postfix/pgsql-virtual-mailbox-domains.cf
|
virtual_mailbox_domains = pgsql:/etc/postfix/pgsql-virtual-mailbox-domains.cf
|
||||||
virtual_mailbox_maps = pgsql:/etc/postfix/pgsql-virtual-mailbox-maps.cf
|
virtual_mailbox_maps = pgsql:/etc/postfix/pgsql-virtual-mailbox-maps.cf
|
||||||
virtual_alias_maps = pgsql:/etc/postfix/pgsql-virtual-alias-maps.cf
|
virtual_alias_maps = pgsql:/etc/postfix/pgsql-virtual-alias-maps.cf
|
||||||
virtual_mailbox_base = /mnt/MainEmail
|
virtual_mailbox_base = /var/mail/vhosts
|
||||||
virtual_minimum_uid = 100
|
virtual_minimum_uid = 100
|
||||||
virtual_uid_maps = static:5000
|
virtual_uid_maps = static:5000
|
||||||
virtual_gid_maps = static:5000
|
virtual_gid_maps = static:5000
|
||||||
@@ -494,10 +428,10 @@ smtp-amavis unix - - - - 2 smtp
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Create virtual mailbox directory
|
# Create virtual mailbox directory
|
||||||
mkdir -p /mnt/MainEmail
|
mkdir -p /var/mail/vhosts
|
||||||
groupadd -g 5000 vmail 2>/dev/null || true
|
groupadd -g 5000 vmail 2>/dev/null || true
|
||||||
useradd -g vmail -u 5000 vmail -d /mnt/MainEmail -m 2>/dev/null || true
|
useradd -g vmail -u 5000 vmail -d /var/mail/vhosts -m 2>/dev/null || true
|
||||||
chown -R vmail:vmail /mnt/MainEmail
|
chown -R vmail:vmail /var/mail/vhosts
|
||||||
|
|
||||||
success "Postfix configured"
|
success "Postfix configured"
|
||||||
}
|
}
|
||||||
@@ -519,7 +453,7 @@ EOF
|
|||||||
|
|
||||||
# 10-mail.conf
|
# 10-mail.conf
|
||||||
cat > /etc/dovecot/conf.d/10-mail.conf << EOF
|
cat > /etc/dovecot/conf.d/10-mail.conf << EOF
|
||||||
mail_location = maildir:/mnt/MainEmail/%d/%n
|
mail_location = maildir:/var/mail/vhosts/%d/%n
|
||||||
namespace inbox {
|
namespace inbox {
|
||||||
inbox = yes
|
inbox = yes
|
||||||
}
|
}
|
||||||
@@ -547,7 +481,7 @@ passdb {
|
|||||||
}
|
}
|
||||||
userdb {
|
userdb {
|
||||||
driver = static
|
driver = static
|
||||||
args = uid=vmail gid=vmail home=/mnt/MainEmail/%d/%n
|
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
@@ -762,46 +696,20 @@ EOF
|
|||||||
success "Amavis and SpamAssassin configured"
|
success "Amavis and SpamAssassin configured"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get Let's Encrypt certificates using the DNS challenge
|
# Install PostfixAdmin
|
||||||
get_ssl_certificates() {
|
|
||||||
info "Obtaining Let's Encrypt certificates..."
|
|
||||||
|
|
||||||
if [[ ! -f "/etc/letsencrypt/live/$HOSTNAME/fullchain.pem" ]]; then
|
|
||||||
warning "SSL certificates for $HOSTNAME were not found."
|
|
||||||
echo -e "${YELLOW}This script will use the DNS challenge method with Certbot, which does not require opening port 80.${NC}"
|
|
||||||
echo -e "${YELLOW}You will need to manually update your DNS records during this process.${NC}"
|
|
||||||
echo
|
|
||||||
echo -e "${BLUE}1. Install the appropriate Certbot DNS plugin for your DNS provider (e.g., 'certbot-dns-cloudflare' for Cloudflare).${NC}"
|
|
||||||
echo -e "${BLUE}2. Create the necessary API credentials file for Certbot to access your DNS provider's API.${NC}"
|
|
||||||
echo -e "${BLUE}3. Run the following command (with your plugin and credentials) to obtain your certificate:${NC}"
|
|
||||||
echo -e "${GREEN} certbot certonly --dns-PLUGIN --dns-PLUGIN-credentials /path/to/credentials.ini -d \"$HOSTNAME\" -d \"www.$HOSTNAME\" --agree-tos --email \"$ADMIN_EMAIL\"${NC}"
|
|
||||||
echo -e "${YELLOW}After running the command and successfully obtaining the certificates, press ENTER to continue this script.${NC}"
|
|
||||||
read -p ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -f "/etc/letsencrypt/live/$HOSTNAME/fullchain.pem" ]]; then
|
|
||||||
error "Failed to find SSL certificate. Please obtain it manually and re-run this script."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Set up auto-renewal
|
|
||||||
(crontab -l 2>/dev/null; echo "0 12 * * * /usr/bin/certbot renew --quiet") | crontab -
|
|
||||||
|
|
||||||
success "SSL certificates obtained"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Install PostfixAdmin and configure Apache
|
|
||||||
install_postfixadmin() {
|
install_postfixadmin() {
|
||||||
info "Installing PostfixAdmin..."
|
info "Installing PostfixAdmin..."
|
||||||
|
|
||||||
# Download PostfixAdmin
|
# Download PostfixAdmin
|
||||||
cd /tmp
|
cd /tmp
|
||||||
wget https://github.com/postfixadmin/postfixadmin/archive/postfixadmin-3.3.11.tar.gz
|
wget -q https://github.com/postfixadmin/postfixadmin/archive/$POSTFIXADMIN_VERSION || error "Failed to download PostfixAdmin"
|
||||||
tar -xzf postfixadmin-3.3.11.tar.gz
|
tar -xzf $POSTFIXADMIN_VERSION
|
||||||
mv postfixadmin-postfixadmin-3.3.11 $WEBROOT
|
mv postfixadmin-postfixadmin-3.3.11 $WEBROOT
|
||||||
|
|
||||||
# Set permissions
|
# Set permissions
|
||||||
chown -R www-data:www-data $WEBROOT
|
chown -R www-data:www-data $WEBROOT
|
||||||
chmod -R 755 $WEBROOT
|
find $WEBROOT -type d -exec chmod 755 {} \;
|
||||||
|
find $WEBROOT -type f -exec chmod 644 {} \;
|
||||||
|
|
||||||
# Create PostfixAdmin configuration
|
# Create PostfixAdmin configuration
|
||||||
cat > $WEBROOT/config.local.php << EOF
|
cat > $WEBROOT/config.local.php << EOF
|
||||||
@@ -835,70 +743,64 @@ function maildir_name_hook(\$domain, \$user) {
|
|||||||
?>
|
?>
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Configure Apache virtual host
|
# Configure Nginx virtual host for PostfixAdmin
|
||||||
cat > "$POSTFIXADMIN_VHOST_FILE" << EOF
|
cat > /etc/nginx/sites-available/postfixadmin.conf << EOF
|
||||||
<VirtualHost *:80>
|
server {
|
||||||
ServerName $HOSTNAME
|
listen 80;
|
||||||
Redirect permanent / https://$HOSTNAME/
|
server_name $HOSTNAME;
|
||||||
</VirtualHost>
|
return 301 https://\$server_name\$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
<VirtualHost *:443>
|
server {
|
||||||
ServerName $HOSTNAME
|
listen 443 ssl http2;
|
||||||
DocumentRoot $WEBROOT
|
server_name $HOSTNAME;
|
||||||
DirectoryIndex index.php index.html
|
|
||||||
|
root $WEBROOT/public;
|
||||||
SSLEngine on
|
index index.php index.html index.htm;
|
||||||
SSLCertificateFile /etc/letsencrypt/live/$HOSTNAME/fullchain.pem
|
|
||||||
SSLCertificateKeyFile /etc/letsencrypt/live/$HOSTNAME/privkey.pem
|
location / {
|
||||||
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
|
try_files \$uri \$uri/ /index.php?\$args;
|
||||||
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
|
}
|
||||||
SSLHonorCipherOrder on
|
|
||||||
|
location ~ \.php$ {
|
||||||
<Directory $WEBROOT>
|
include snippets/fastcgi-php.conf;
|
||||||
Options -Indexes
|
fastcgi_pass unix:/var/run/php/php$(php -r "echo PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION;")-fpm.sock;
|
||||||
AllowOverride All
|
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
|
||||||
Require all granted
|
fastcgi_read_timeout 600s;
|
||||||
</Directory>
|
}
|
||||||
|
|
||||||
# PHP configuration
|
# SSL configuration, to be updated by Certbot
|
||||||
<FilesMatch "\.php$">
|
ssl_certificate /etc/letsencrypt/live/$HOSTNAME/fullchain.pem;
|
||||||
SetHandler "proxy:unix:/run/php/php-fpm.sock|fcgi://localhost"
|
ssl_certificate_key /etc/letsencrypt/live/$HOSTNAME/privkey.pem;
|
||||||
</FilesMatch>
|
ssl_trusted_certificate /etc/letsencrypt/live/$HOSTNAME/chain.pem;
|
||||||
|
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||||
ErrorLog \${APACHE_LOG_DIR}/postfixadmin_error.log
|
}
|
||||||
CustomLog \${APACHE_LOG_DIR}/postfixadmin_access.log combined
|
|
||||||
</VirtualHost>
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Stop Apache before configuration changes
|
# Enable Nginx site and disable default
|
||||||
if systemctl is-active --quiet apache2; then
|
ln -s /etc/nginx/sites-available/postfixadmin.conf /etc/nginx/sites-enabled/
|
||||||
systemctl stop apache2
|
rm /etc/nginx/sites-enabled/default
|
||||||
|
|
||||||
|
# Reload Nginx to apply changes
|
||||||
|
systemctl reload nginx
|
||||||
|
|
||||||
|
success "PostfixAdmin installed and Nginx configured"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get Let's Encrypt certificates
|
||||||
|
get_ssl_certificates() {
|
||||||
|
info "Obtaining Let's Encrypt certificates..."
|
||||||
|
|
||||||
|
# Use certbot with the nginx plugin
|
||||||
|
certbot --nginx -d $HOSTNAME --email $ADMIN_EMAIL --agree-tos --non-interactive
|
||||||
|
|
||||||
|
if [[ ! -f "/etc/letsencrypt/live/$HOSTNAME/fullchain.pem" ]]; then
|
||||||
|
error "Failed to obtain SSL certificate"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Enable required Apache modules
|
# Certbot automatically sets up a cronjob for renewal with the nginx plugin
|
||||||
a2enmod ssl
|
|
||||||
a2enmod rewrite
|
|
||||||
a2enmod proxy
|
|
||||||
a2enmod proxy_fcgi
|
|
||||||
a2enmod setenvif
|
|
||||||
|
|
||||||
# Enable PHP-FPM configuration
|
success "SSL certificates obtained and Nginx configured for HTTPS"
|
||||||
a2enconf php*-fpm
|
|
||||||
|
|
||||||
# Enable PostfixAdmin site and disable default
|
|
||||||
a2ensite postfixadmin
|
|
||||||
a2dissite 000-default
|
|
||||||
|
|
||||||
# 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
|
# Configure firewall
|
||||||
@@ -950,28 +852,9 @@ start_services() {
|
|||||||
systemctl enable --now clamav-daemon
|
systemctl enable --now clamav-daemon
|
||||||
systemctl enable --now clamav-freshclam
|
systemctl enable --now clamav-freshclam
|
||||||
systemctl enable --now opendkim
|
systemctl enable --now opendkim
|
||||||
|
systemctl enable --now nginx
|
||||||
|
systemctl enable --now php$(php -r "echo PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION;")-fpm
|
||||||
|
|
||||||
# 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"
|
success "All services started and enabled"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -995,10 +878,10 @@ display_final_info() {
|
|||||||
cat /etc/opendkim/keys/$DOMAIN/mail.txt
|
cat /etc/opendkim/keys/$DOMAIN/mail.txt
|
||||||
echo
|
echo
|
||||||
echo -e "${YELLOW}=== Next Steps ===${NC}"
|
echo -e "${YELLOW}=== Next Steps ===${NC}"
|
||||||
echo "1. Add the DNS records shown above."
|
echo "1. Add the DNS records shown above"
|
||||||
echo "2. Visit https://$HOSTNAME/postfixadmin/setup.php to complete PostfixAdmin setup."
|
echo "2. Visit https://$HOSTNAME/postfixadmin/setup.php to complete PostfixAdmin setup"
|
||||||
echo "3. Create your first domain and mailbox in PostfixAdmin."
|
echo "3. Create your first domain and mailbox in PostfixAdmin"
|
||||||
echo "4. Test email sending and receiving."
|
echo "4. Test email sending and receiving"
|
||||||
echo
|
echo
|
||||||
echo -e "${BLUE}=== Multiple Domain Support ===${NC}"
|
echo -e "${BLUE}=== Multiple Domain Support ===${NC}"
|
||||||
echo "This server supports unlimited virtual domains!"
|
echo "This server supports unlimited virtual domains!"
|
||||||
@@ -1009,6 +892,12 @@ display_final_info() {
|
|||||||
echo "3. Configure the domain in PostfixAdmin"
|
echo "3. Configure the domain in PostfixAdmin"
|
||||||
echo "4. Create mailboxes for the new domain"
|
echo "4. Create mailboxes for the new domain"
|
||||||
echo
|
echo
|
||||||
|
echo "Each domain can have its own:"
|
||||||
|
echo " • Independent mailboxes and aliases"
|
||||||
|
echo " • DKIM signing for authentication"
|
||||||
|
echo " • Custom quotas and limits"
|
||||||
|
echo " • Application SMTP access"
|
||||||
|
echo
|
||||||
echo -e "${BLUE}=== Application SMTP Configuration ===${NC}"
|
echo -e "${BLUE}=== Application SMTP Configuration ===${NC}"
|
||||||
echo "Your applications can send email using these settings:"
|
echo "Your applications can send email using these settings:"
|
||||||
echo " Host: $HOSTNAME"
|
echo " Host: $HOSTNAME"
|
||||||
@@ -1020,27 +909,26 @@ display_final_info() {
|
|||||||
echo -e "${GREEN}Setup completed successfully!${NC}"
|
echo -e "${GREEN}Setup completed successfully!${NC}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Main function to run all setup steps
|
# Main execution
|
||||||
main() {
|
main() {
|
||||||
log "Starting email server setup script"
|
echo -e "${BLUE}Email Server Setup Script${NC}"
|
||||||
|
echo "========================="
|
||||||
|
echo
|
||||||
|
|
||||||
check_root
|
check_root
|
||||||
verify_email_storage
|
|
||||||
get_configuration
|
get_configuration
|
||||||
update_system
|
update_system
|
||||||
install_packages
|
install_packages
|
||||||
configure_postgresql
|
configure_postgresql
|
||||||
|
install_postfixadmin
|
||||||
|
get_ssl_certificates
|
||||||
configure_postfix
|
configure_postfix
|
||||||
configure_dovecot
|
configure_dovecot
|
||||||
configure_opendkim
|
configure_opendkim
|
||||||
configure_amavis
|
configure_amavis
|
||||||
get_ssl_certificates
|
|
||||||
install_postfixadmin
|
|
||||||
configure_firewall
|
configure_firewall
|
||||||
start_services
|
start_services
|
||||||
display_final_info
|
display_final_info
|
||||||
|
|
||||||
log "Email server setup completed successfully"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Run main function
|
# Run main function
|
||||||
|
|||||||
Reference in New Issue
Block a user