2024-03-24 19:22:26 -06:00
#!/usr/bin/env bash
set -a
set -e
# Script is meant for Debian
hostnamectl | grep -q 'Debian' || exit 1
# Insert SSH keys here
sshkeys = ''
# Backup mailservers
2024-03-24 19:51:20 -06:00
backup_mailserver = ( )
2024-03-24 19:22:26 -06:00
# Exit function
function die
{
read -n 1 -s -p $'\n\e[1;33mError encountered, exiting...\e[0m\n'
exit 1
}
# Grab options
while [ ${ 1 } != "" ]
do
case ${ 1 } in
-u | --user )
if [ ${ 2 } != "" ]
then
username = ${ 2 }
shift
fi
; ;
-p | --port )
if [ ${ 2 } != "" ]
then
ssh_port = ${ 2 }
shift
fi
; ;
-d | --domain )
if [ ${ 2 } != "" ]
then
2024-03-24 19:51:20 -06:00
domain_url = ${ 2 }
2024-03-24 19:22:26 -06:00
shift
fi
; ;
2024-03-24 19:51:20 -06:00
-m | --mail-user )
if [ ${ 2 } != "" ]
then
mailuser = ${ 2 }
shift
fi
; ;
2024-03-24 19:22:26 -06:00
-? | -h | --help )
cat <<HELP
Parameters:
-u, --user Unix username
-p, --port SSH port
-d, --domain Domain name ( eg, mail.web.com)
2024-03-24 19:51:20 -06:00
-m, --mail-user Mail username
2024-03-24 19:22:26 -06:00
-?, -h, --help This help
HELP
exit 0
; ;
* )
echo " Unknown parameter ${ 1 } " 1>& 2
exit 1
; ;
esac
shift
done
clear
# Assign random alternate SSH port
if [ -z ${ ssh_port } ]
then
ssh_port = $( shuf -i 10027-65000 -n 1)
fi
# Random username
if [ -z ${ username } ]
then
username = $( cat /dev/urandom | tr -d -c 'a-z' | fold -w 8 | head -n 1)
fi
# Domain
2024-03-24 19:51:20 -06:00
if [ -z ${ domain_url } ]
2024-03-24 19:22:26 -06:00
then
echo -e '\e[1;34mType in your full mail domain name (eg. mael.elgoog.com)\e[0m'
2024-03-24 19:51:20 -06:00
until [ " ${ domain_url } " ]
2024-03-24 19:22:26 -06:00
do
2024-03-24 19:51:20 -06:00
read -r -p 'Domain name: ' domain_url
[ " ${ domain_url } " ] || echo -e '\n\e[1;31mDomain name cannot be empty, try again\e[0m'
2024-03-24 19:22:26 -06:00
done
echo
fi
# Superuser password
echo -e '\e[1;34mCreate a root superuser password\e[0m'
until [ " ${ rootpass } " = " ${ rootpass2 } " -a " ${ rootpass } " ]
do
read -s -r -p 'Superuser password: ' rootpass
read -s -r -p $'\nVerify superuser password: ' rootpass2
if [ -z " ${ rootpass } " ]
then
echo -e '\n\n\e[1;31mPassword field cannot be empty, try again\e[0m'
elif [ " ${ rootpass } " != " ${ rootpass2 } " ]
then
echo -e '\n\n\e[1;31mPasswords did not match, try again\e[0m'
fi
done
printf '%s\n' " ${ rootpass } " " ${ rootpass } " | passwd & >/dev/null
echo -e '\n\n\e[1;32mRoot superuser password has been saved\e[0m\n'
unset rootpass rootpass2
# User password
echo -e '\e[1;34mSet a password for ' " ${ username } " '\e[0m'
until [ " ${ userpass } " = " ${ userpass2 } " -a " ${ userpass } " ]
do
read -s -r -p 'User password: ' userpass
read -s -r -p $'\nVerify user password: ' userpass2
if [ -z " ${ userpass } " ]
then
echo -e '\n\n\e[1;31mPassword field cannot be empty, try again\e[0m'
elif [ " ${ userpass } " != " ${ userpass2 } " ]
then
echo -e '\n\n\e[1;31mPasswords did not match, try again\e[0m'
fi
done
printf '%s\n' " ${ userpass } " " ${ userpass } " "" "" "" "" "" | adduser ${ username } & >/dev/null
2024-03-24 19:51:20 -06:00
echo -e '\n\n\e[1;32mPassword for ' ${ username } '@' ${ domain_url } ' -p' ${ ssh_port } ' has been saved\e[0m\n'
2024-03-24 19:22:26 -06:00
unset userpass userpass2
2024-03-24 19:51:20 -06:00
# Mail username
if [ -z ${ mailuser } ]
then
echo -e '\e[1;34mType in your email username\e[0m'
until [ ${ mailuser } ]
do
read -r -p 'Username: ' mailuser
[ ${ mailuser } ] || echo -e '\n\e[1;31mUsername cannot be empty, try again\e[0m'
done
2024-03-25 07:30:35 -06:00
echo -e '\n\e[1;32mMail user ' ${ mailuser } '@' ${ domain_url } ' has been saved\e[0m\n'
2024-03-24 19:51:20 -06:00
fi
# Mail account password
2024-03-25 09:28:08 -06:00
echo -e '\e[1;34mCreate a password for your mail account\e[0m'
until [ " ${ mailpass } " = " ${ mailpass2 } " -a " ${ mailpass } " ]
do
read -s -r -p 'Mail password: ' mailpass
read -s -r -p $'\nVerify mail password: ' mailpass2
if [ -z " ${ mailpass } " ]
then
echo -e '\n\n\e[1;31mPassword field cannot be empty, try again\e[0m'
elif [ " ${ mailpass } " != " ${ mailpass2 } " ]
then
echo -e '\n\n\e[1;31mPasswords did not match, try again\e[0m'
fi
done
echo -e '\n\n\e[1;32mMail password has been saved\e[0m\n'
2024-03-24 19:51:20 -06:00
# Postfixadmin password
2024-03-25 09:28:08 -06:00
echo -e '\e[1;34mCreate a postfixadmin setup password\e[0m'
until [ " ${ postfixadminpass } " = " ${ postfixadminpass2 } " -a " ${ postfixadminpass } " ]
do
read -s -r -p 'Postfixadmin password: ' postfixadminpass
read -s -r -p $'\nVerify Postfixadmin password: ' postfixadminpass2
if [ -z " ${ postfixadminpass } " ]
then
echo -e '\n\n\e[1;31mPassword field cannot be empty, try again\e[0m'
elif [ " ${ postfixadminpass } " != " ${ postfixadminpass2 } " ]
then
echo -e '\n\n\e[1;31mPasswords did not match, try again\e[0m'
fi
done
echo -e '\n\n\e[1;32mPostfixadmin password has been saved\e[0m\n'
2024-03-24 19:51:20 -06:00
# Static variables
ip_addr = $( wget -q4O- ipv4.icanhazip.com)
subdomain = $( echo ${ domain_url } | awk -F . '{print $1}' )
domain = " $( echo ${ domain_url } | awk -F . '{print $2}' ) . $( echo ${ domain_url } | awk -F . '{print $3}' ) "
eff_email = eff@${ domain }
roundcubedbpass = $( cat /dev/urandom | tr -d -c 'a-zA-Z0-9' | fold -w 128 | head -n 1)
postfixadmindbpass = $( cat /dev/urandom | tr -d -c 'a-zA-Z0-9' | fold -w 128 | head -n 1)
roundcubepass_strength_drive = $( cat /dev/urandom | tr -d -c 'a-z' | fold -w 8 | head -n 1)
# Exit if static variable is null
if [ -z ${ ip_addr } ] || [ -z ${ subdomain } ] || [ -z ${ domain } ] || [ -z ${ eff_email } ]
then
die 'A static variable is nonexistent'
fi
# Interaction end
2024-03-24 19:22:26 -06:00
echo -e '\e[1;34mUpgrading system...\e[0m'
apt remove -y nano exim* & >/dev/null
apt update -y || die
apt upgrade -y || die
apt dist-upgrade -y || die
2024-03-24 19:51:20 -06:00
debconf-set-selections <<< " postfix postfix/mailname string ${ domain } "
debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Internet Site'"
2024-03-24 19:22:26 -06:00
apt install -y sudo ufw vim fail2ban wget telnet dnsutils rsyslog zram-tools \
2024-03-24 19:51:20 -06:00
composer git acl dbconfig-no-thanks \
nginx certbot python3-certbot-nginx \
mariadb-server mariadb-client postfix-mysql dovecot-mysql \
php php-fpm php-imap php-mbstring php-mysql php-json php-curl php-zip php-xml php-bz2 php-intl php-gmp php-net-ldap3 php-imagick php-common php-gd php-sqlite3 php-cli \
postfix postfix-pcre \
dovecot-core dovecot-imapd dovecot-lmtpd \
postfix-policyd-spf-python opendkim opendkim-tools \
opendmarc || die 'Apt failed'
apt autoremove -y
2024-03-24 19:22:26 -06:00
# cron rsyslog
sed -i 's/#cron/cron/' /etc/rsyslog.conf
2024-03-24 19:51:20 -06:00
# UFW
# SSH
2024-03-24 19:22:26 -06:00
ufw allow ${ ssh_port } /tcp >/dev/null
2024-03-24 19:51:20 -06:00
# Mail ports
ufw allow 25/tcp >/dev/null
ufw allow 80,443/tcp >/dev/null
ufw allow 587/tcp >/dev/null
ufw allow 143,993/tcp >/dev/null
2024-03-24 19:22:26 -06:00
yes | ufw enable >/dev/null
2024-03-25 09:28:08 -06:00
systemctl -q enable --now ufw.service
2024-03-24 19:51:20 -06:00
# Check port 25
echo
if ! grep -q 'Connected to' <<< $( printf 'quit' | telnet -4 gmail-smtp-in.l.google.com 25)
then
echo -e '\n\e[1;31mPort 25 needs to be open for mail server installation to continue, exiting...\e[0m\n'
2024-03-25 09:28:08 -06:00
exit 1
2024-03-24 19:51:20 -06:00
fi
2024-03-24 19:22:26 -06:00
# fail2ban
2024-03-25 09:28:08 -06:00
install /dev/stdin /usr/local/bin/fail2ban-jails <<'ALL-JA ILS'
#!/bin/bash
JAILS = $( sudo fail2ban-client status | grep "Jail list" | sed -E 's/^[^:]+:[ \t]+//' | sed 's/,//g' )
for JAIL in $JAILS
do
sudo fail2ban-client status $JAIL
done
ALL-JAILS
cat >/etc/fail2ban/jail.d/sshd.conf <<'SSHD'
2024-03-24 19:22:26 -06:00
[ sshd]
enabled = true
filter = sshd
backend = systemd
maxretry = 5
findtime = 1d
bantime = 4w
ignoreip = 127.0.0.1/8
SSHD
2024-03-25 09:28:08 -06:00
cat >/etc/fail2ban/jail.d/postfix.local <<'POSTFIX-FLOOD-ATTACK'
2024-03-24 19:51:20 -06:00
[ postfix-flood-attack]
enabled = true
bantime = 12h
filter = postfix-flood-attack
action = iptables-multiport[ name = postfix, port = "http,https,smtp,submission,pop3,pop3s,imap,imaps,sieve" , protocol = tcp]
logpath = /var/log/mail.log
[ postfix]
enabled = true
maxretry = 3
bantime = 12h
filter = postfix
logpath = /var/log/mail.log
POSTFIX-FLOOD-ATTACK
2024-03-25 09:28:08 -06:00
cat >/etc/fail2ban/filter.d/postfix-flood-attack.conf <<'POSTFIX-FLOOD-ATTACK'
2024-03-24 19:51:20 -06:00
[ Definition]
failregex = lost connection after AUTH from ( .*) \[ <HOST>\]
ignoreregex =
POSTFIX-FLOOD-ATTACK
2024-03-25 09:28:08 -06:00
systemctl -q enable --now fail2ban.service
2024-03-24 19:22:26 -06:00
# zram swap
echo -e "ALGO=zstd\nPERCENT=60" >>/etc/default/zramswap
# Shut up fstrim
rm -f /etc/cron.weekly/fstrim & >/dev/null
# Hostname and unix users
2024-03-24 19:51:20 -06:00
hostnamectl set-hostname ${ domain_url }
sed -i '/127.0.0.1/ s/$/ ' ${ domain_url } '/' /etc/hosts
2024-03-24 19:22:26 -06:00
adduser ${ username } sudo & >/dev/null
# SSH settings
echo " Port ${ ssh_port }
PermitRootLogin no
PasswordAuthentication no
Protocol 2" >/etc/ssh/sshd_config.d/zz-ssh.conf
# Disable history saving
cat >>~/.bashrc <<EOF
2024-03-25 09:28:08 -06:00
# Disable shell history
unset HISTFILE
if [ -f \$ { HISTFILE} ]
2024-03-24 19:22:26 -06:00
then
2024-03-25 09:28:08 -06:00
rm -f \$ { HISTFILE}
2024-03-24 19:22:26 -06:00
fi
history -c
EOF
2024-03-24 19:51:20 -06:00
if hostname | grep -q " ${ domain_url } " && grep -q " ${ domain_url } " /etc/hosts
then
# Dovecot
cd ~
mkdir -p /usr/share/dovecot /usr/share/webapps
touch /usr/share/dovecot/dh.pem
# PHP
sed -i -e 's/^upload_max_filesize =.*/upload_max_filesize = 0/g' -e 's/^post_max_size =.*/post_max_size = 0/g' -e 's/^memory_limit =.*/memory_limit = 4096M/g' $( find /etc/php -name 'php.ini' | grep fpm)
# Download Postfixadmin and Roundcube
mkdir -p /usr/share/webapps/{ roundcube,postfixadmin}
wget -q4 https://github.com/postfixadmin/postfixadmin/archive/refs/tags/$( wget -q4O- https://api.github.com/repos/postfixadmin/postfixadmin/releases/latest | grep tag_name | awk '{print $2}' | tr -d '"|,' ) .tar.gz -O postfixadmin.tar.gz || die
wget -q4 $( wget -q4O- https://api.github.com/repos/roundcube/roundcubemail/releases/latest | grep 'complete.tar.gz"$' | awk '{print $2}' | tr -d '"|,' ) -O roundcubemail.tar.gz || die
tar zxf roundcubemail.tar.gz -C /usr/share/webapps/roundcube --strip-components 1
tar zxf postfixadmin.tar.gz -C /usr/share/webapps/postfixadmin --strip-components 1
rm *.tar.gz
# Postfixadmin
echo -e '\n\e[1;34mInstalling Postfixadmin\e[0m'
cd /usr/share/webapps/postfixadmin
# Postfixadmin composer
wget -q4O- https://raw.githubusercontent.com/postfixadmin/postfixadmin/master/install.sh | COMPOSER_ALLOW_SUPERUSER = 1 bash -
setfacl -R -m u:www-data:rwx templates_c/
# Roundcube
echo -e '\e[1;34mInstalling Roundcube\e[0m'
# Roundcube composer
cd /usr/share/webapps/roundcube
COMPOSER_ALLOW_SUPERUSER = 1 composer -n update --no-dev
COMPOSER_ALLOW_SUPERUSER = 1 composer -n install --no-dev
chown www-data:www-data temp/ logs/ -R
# Postwhite
cd /usr/local/bin
git clone --quiet https://github.com/spf-tools/spf-tools.git
git clone --quiet https://github.com/stevejenkins/postwhite.git
cp /usr/local/bin/postwhite/postwhite.conf /etc
cd
# Install MariaDB
echo -e '\n\e[1;34mInstalling MariaDB\e[0m'
printf '%s\n' "" "n" "y" " ${ postfixadminpass } " " ${ postfixadminpass } " "" "" "" "" | mysql_secure_installation & >/dev/null
# Roundcube database
mysql -u root <<ROUNDCUBE
CREATE DATABASE roundcubemail CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
GRANT ALL PRIVILEGES ON roundcubemail.* TO 'roundcube' @'localhost' IDENTIFIED BY '${roundcubedbpass}' ;
flush privileges;
ROUNDCUBE
mysql roundcubemail </usr/share/webapps/roundcube/SQL/mysql.initial.sql
# Postfixadmin database
mysql -u root <<POSTFIXADMIN
CREATE DATABASE postfixadmin;
GRANT ALL PRIVILEGES ON postfixadmin.* to 'postfixadmin' @'localhost' IDENTIFIED BY '${postfixadmindbpass}' ;
flush privileges;
POSTFIXADMIN
2024-03-25 09:28:08 -06:00
systemctl -q restart mariadb.service
2024-03-24 19:51:20 -06:00
# Roundcube config setup
echo -e '\n\e[1;34mConfiguring Roundcube webmail\e[0m'
echo " <?php
\$ config[ 'db_dsnw' ] = 'mysql://roundcube:${roundcubedbpass}@localhost/roundcubemail' ;
\$ config[ 'imap_host' ] = 'ssl://${subdomain}.${domain}' ;
\$ config[ 'default_port' ] = 993;
\$ config[ 'smtp_host' ] = 'tls://${subdomain}.${domain}' ;
\$ config[ 'product_name' ] = '${subdomain}.${domain}' ;
\$ config[ 'create_default_folders' ] = true;
\$ config[ 'support_url' ] = '' ;
\$ config[ 'des_key' ] = '$(cat /dev/urandom | tr -d -c ' a-zA-Z0-9' | fold -w 24 | head -n 1)' ;
\$ config[ 'plugins' ] = [ $( printf "'%s', " $( ls /usr/share/webapps/roundcube/plugins | grep -v 'enigma\|database_attachments\|managesieve' ) | sed "s/\(.*\), /\1/" ) ] ; " | tee /usr/share/webapps/roundcube/config/config.inc.php >/dev/null
# Roundcube password plugin
cp /usr/share/webapps/roundcube/plugins/password/config.inc.php.dist /usr/share/webapps/roundcube/plugins/password/config.inc.php
sed -i " /^\$config\['password_db_dsn'\]/ s|=.*|= 'mysql://postfixadmin: ${ postfixadmindbpass } @localhost/postfixadmin';| " /usr/share/webapps/roundcube/plugins/password/config.inc.php
sed -i "/^\$config\['password_query'\]/ s/=.*/= 'UPDATE mailbox SET password=%P,modified=NOW() WHERE username=%u';/" /usr/share/webapps/roundcube/plugins/password/config.inc.php
sed -i " /^\$config\['password_strength_driver'\]/ s/=.*/= ' ${ roundcubepass_strength_drive } ';\\
\$ config[ 'password_"${roundcubepass_strength_drive}"_min_score' ] = 5; /" /usr/share/webapps/roundcube/plugins/password/config.inc.php
sed -i "/^\$config\['password_algorithm'\]/ s/=.*/= 'dovecot';/" /usr/share/webapps/roundcube/plugins/password/config.inc.php
sed -i "/^\$config\['password_dovecotpw'\]/ s|=.*|= '/usr/bin/doveadm pw -r 5';|" /usr/share/webapps/roundcube/plugins/password/config.inc.php
sed -i "/^\$config\['password_dovecotpw_method'\]/ s/=.*/= 'ARGON2I';/" /usr/share/webapps/roundcube/plugins/password/config.inc.php
sed -i "/^\$config\['password_dovecotpw_with_method'\]/ s/=.*/= true;/" /usr/share/webapps/roundcube/plugins/password/config.inc.php
rm /usr/share/webapps/roundcube/installer/ -r
chown www-data:www-data /usr/share/webapps/roundcube/plugins/password/config.inc.php
chmod 600 /usr/share/webapps/roundcube/plugins/password/config.inc.php
# Postfixadmin config setup
# https://git.banananet.work/banananetwork/postfixadmin/raw/commit/864065cd37ef34b6dab915206eea4bd2ac4ebaed/config.inc.php
echo -e '\e[1;34mCreating mail users\e[0m'
echo -e ' <?php
$CONF [ '\' 'configured' \' ' ] = true;
$CONF [ '\' 'database_type' \' '] = ' \' 'mysqli' \' ' ;
$CONF [ '\' 'database_host' \' '] = ' \' 'localhost' \' ' ;
$CONF [ '\' 'database_port' \' '] = ' \' '3306' \' ' ;
$CONF [ '\' 'database_user' \' '] = ' \' 'postfixadmin' \' ' ;
$CONF [ '\' 'database_password' \' '] = ' \' ${ postfixadmindbpass } \' ' ;
$CONF [ '\' 'database_name' \' '] = ' \' 'postfixadmin' \' ' ;
$CONF [ '\' 'encrypt' \' '] = ' \' 'dovecot:ARGON2I' \' ' ;
$CONF [ '\' 'dovecotpw' \' ' ] = "/usr/bin/doveadm pw -r 5" ;
if ( @file_exists( '\' '/usr/bin/doveadm' \' ' ) ) { // @ to silence openbase_dir stuff; see https://github.com/postfixadmin/postfixadmin/issues/171
$CONF [ '\' 'dovecotpw' \' ' ] = "/usr/bin/doveadm pw -r 5" ; # debian
}
$CONF [ '\' 'default_aliases' \' ' ] = array (
'\' 'root' \' ' => ' \' 'postmaster@' ${ domain } '' \' ' ,
'\' 'eff' \' ' => ' \' 'postmaster@' ${ domain } '' \' ' ,
'\' 'dmarc' \' ' => ' \' 'postmaster@' ${ domain } '' \' ' ,
) ;
$CONF [ '\' 'password_validation' \' ' ] = array(
# # '\''/regular expression/'\'' => '\''$PALANG key (optional: + parameter)'\'',
# '\''/.{5}/'\'' => '\''password_too_short 5'\'', # minimum length 5 characters
# '\''/([a-zA-Z].*){3}/'\'' => '\''password_no_characters 3'\'', # must contain at least 3 characters
# '\''/([0-9].*){2}/'\'' => '\''password_no_digits 2'\'', # must contain at least 2 digits
) ;
$CONF [ '\' 'fetchmail' \' '] = ' \' 'NO' \' ' ;
$CONF [ '\' 'show_footer_text' \' '] = ' \' 'NO' \' ' ;
$CONF [ '\' 'quota' \' '] = ' \' 'YES' \' ' ;
$CONF [ '\' 'domain_quota' \' '] = ' \' 'YES' \' ' ;
$CONF [ '\' 'quota_multiplier' \' '] = ' \' '1024000' \' ' ;
$CONF [ '\' 'used_quotas' \' '] = ' \' 'YES' \' ' ;
$CONF [ '\' 'new_quota_table' \' '] = ' \' 'YES' \' ' ;
$CONF [ '\' 'aliases' \' '] = ' \' '0' \' ' ;
$CONF [ '\' 'mailboxes' \' '] = ' \' '0' \' ' ;
$CONF [ '\' 'maxquota' \' '] = ' \' '0' \' ' ;
$CONF [ '\' 'domain_quota_default' \' '] = ' \' '0' \' ' ;
$CONF [ '\' 'password_expiration' \' '] = ' \' 'NO' \' ' ;
# Postfixadmin hash
$CONF [ '\' 'setup_password' \' '] = ' \' $( php -r " echo password_hash(' ${ postfixadminpass } ', PASSWORD_DEFAULT); " ) \' ';' | tee /usr/share/webapps/postfixadmin/config.local.php >/dev/null
# Update Postfixadmin databases
# https://git.banananet.work/banananetwork/postfixadmin/raw/commit/864065cd37ef34b6dab915206eea4bd2ac4ebaed/config.inc.php
runuser -u www-data -- php /usr/share/webapps/postfixadmin/public/upgrade.php
# Create Postfixadmin domain
bash /usr/share/webapps/postfixadmin/scripts/postfixadmin-cli domain add " ${ domain } " --aliases 0 --mailboxes 0 --maxquota 0 --quota 0 --active --default-aliases -q
# Create Postfixadmin admin
bash /usr/share/webapps/postfixadmin/scripts/postfixadmin-cli admin add " postmaster@ ${ domain } " --superadmin --active --domains " ${ domain } " --password " ${ postfixadminpass } " --password2 " ${ postfixadminpass } " -q
# Create Postfixadmin mail users
bash /usr/share/webapps/postfixadmin/scripts/postfixadmin-cli mailbox add " postmaster@ ${ domain } " --active --password " ${ postfixadminpass } " --password2 " ${ postfixadminpass } " -q
bash /usr/share/webapps/postfixadmin/scripts/postfixadmin-cli mailbox add " ${ mailuser } @ ${ domain } " --active --password " ${ mailpass } " --password2 " ${ mailpass } " -q
# Create Postfixadmin mail catch-all alias
bash /usr/share/webapps/postfixadmin/scripts/postfixadmin-cli alias add " *@ ${ domain } " --goto " ${ mailuser } @ ${ domain } " --active -q
unset mailuser postfixadminpass postfixadminpass2 mailpass mailpass2 roundcubedbpass roundcubepass_strength_drive
echo
# Autorestart services
mkdir -p /etc/systemd/system/{ dovecot,postfix} .service.d
tee /etc/systemd/system/dovecot.service.d/restart.conf >/dev/null <<'RESTAR T'
[ Service]
Restart = always
RestartSec = 5s
RESTART
tee /etc/systemd/system/postfix.service.d/restart.conf >/dev/null <<'RESTAR T'
[ Service]
Restart = on-failure
RestartSec = 5s
RESTART
systemctl -q daemon-reload
# Postfix
# postconf myhostname alias_maps alias_database myorigin mydestination relayhost mynetworks mailbox_size_limit recipient_delimiter inet_interfaces inet_protocols
# cat /etc/mailname
echo -e '\e[1;34mConfiguring Postfix\e[0m'
2024-03-25 09:28:08 -06:00
echo ${ domain } >/etc/mailname
2024-03-24 19:51:20 -06:00
postconf -e " myhostname = ${ subdomain } . ${ domain } "
postconf -e 'relay_domains = $mydestination'
postconf -e 'smtp_tls_security_level = may'
postconf -e 'smtp_tls_loglevel = 1'
postconf -e 'smtpd_tls_security_level = may'
postconf -e 'smtpd_tls_loglevel = 1'
postconf -e 'mailbox_size_limit = 0'
postconf -e 'message_size_limit = 0'
postconf -e " authorized_submit_users = root,www-data, ${ USER } "
postconf -e 'smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache'
postconf -e 'smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache'
postconf -e 'smtp_tls_note_starttls_offer = yes'
postconf -e 'smtpd_tls_received_header = yes'
postconf -e 'inet_interfaces = all'
postconf -e 'inet_protocols = ipv4'
postconf -e 'smtp_address_preference = ipv4'
postconf -e " mydomain = ${ domain } "
postconf -e 'myorigin = $mydomain'
postconf -e 'mydestination = $myhostname, localhost.$mydomain, localhost'
2024-03-25 09:28:08 -06:00
# Configure backup mail servers
2024-03-24 19:51:20 -06:00
if [ ${ backup_mailserver } ]
2024-03-24 19:22:26 -06:00
then
2024-03-24 19:51:20 -06:00
postconf -e " $( postconf mynetworks) $( printf ' %s/32' ${ backup_mailserver [@] } ) "
postconf -e " smtp_fallback_relay = $( printf ' [%s]:25' ${ backup_mailserver [@] } ) "
fi
2024-03-24 19:22:26 -06:00
2024-03-24 19:51:20 -06:00
# main.cf
echo -e ' \n # Enforce TLSv1.3 or TLSv1.2
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
2024-03-24 19:22:26 -06:00
2024-03-24 19:51:20 -06:00
# Virtual mailboxes
mailbox_transport = lmtp:unix:private/dovecot-lmtp
smtputf8_enable = no
2024-03-24 19:22:26 -06:00
2024-03-24 19:51:20 -06:00
virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf
virtual_mailbox_maps =
proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf,
proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf
virtual_alias_maps =
proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf,
proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf,
proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_base = /var/vmail
virtual_minimum_uid = 600
virtual_uid_maps = static:600
virtual_gid_maps = static:600
virtual_mailbox_limit = 0
smtp_header_checks = pcre:/etc/postfix/smtp_header_checks
# SPF and DKIM checks
policyd-spf_time_limit = 3600
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
check_policy_service unix:private/policyd-spf,
check_client_access hash:/etc/postfix/rbl_override,
reject_rhsbl_helo dbl.spamhaus.org,
reject_rhsbl_reverse_client dbl.spamhaus.org,
reject_rhsbl_sender dbl.spamhaus.org
# Milter configuration
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters
# Blocking spam
smtpd_sender_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unknown_sender_domain
reject_unknown_reverse_client_hostname
reject_unknown_client_hostname
smtpd_helo_required = yes
smtpd_helo_restrictions =
permit_mynetworks
permit_sasl_authenticated
check_helo_access hash:/etc/postfix/helo_access
reject_invalid_helo_hostname
reject_non_fqdn_helo_hostname
reject_unknown_helo_hostname
# Postscreen spambots
postscreen_access_list = permit_mynetworks cidr:/etc/postfix/postscreen_access.cidr cidr:/etc/postfix/postscreen_spf_whitelist.cidr
postscreen_blacklist_action = drop
postscreen_greet_action = enforce
postscreen_dnsbl_threshold = 3
postscreen_dnsbl_action = enforce
postscreen_dnsbl_sites =
zen.spamhaus.org*3
bl.spameatingmonkey.net*2
bl.spamcop.net
dnsbl.sorbs.net
postscreen_dnsbl_whitelist_threshold = -2
header_checks = pcre:/etc/postfix/header_checks
body_checks = pcre:/etc/postfix/body_checks' | tee -a /etc/postfix/main.cf >/dev/null
# master.cf
sed -i 's/smtp .*smtpd/# &/' /etc/postfix/master.cf
sed -i '/#smtp\|#smtpd\|#dnsblog\|#tlsproxy/ s/^#//' /etc/postfix/master.cf
echo -e ' \n # Enable submission
submission inet n - y - - smtpd
-o syslog_name = postfix/submission
-o smtpd_tls_security_level = encrypt
-o smtpd_tls_wrappermode = no
-o smtpd_sasl_auth_enable = yes
-o smtpd_relay_restrictions = permit_sasl_authenticated,reject
-o smtpd_recipient_restrictions = permit_mynetworks,permit_sasl_authenticated,reject
-o smtpd_sasl_type = dovecot
-o smtpd_sasl_path = private/auth
# SPF Policy
policyd-spf unix - n n - 0 spawn
user = policyd-spf argv = /usr/bin/policyd-spf' | tee -a /etc/postfix/master.cf >/dev/null
# Deleting Email Headers For Outgoing Emails
echo -e ' /^X-Spam-Status:/ IGNORE
/^X-Spam-Checker-Version:/ IGNORE
/^Received:.*/ IGNORE
/^User-Agent:.*/ IGNORE' | tee /etc/postfix/smtp_header_checks >/dev/null
# Header checks
echo " /free mortgage quote/ DISCARD
/repair your credit/ DISCARD
/lose weight/ DISCARD
/To:.*( gmail.com| yahoo.com| outlook| hotmail.com) .*${ mailuser } @${ domain } / DISCARD
/To:.*${ mailuser } @${ domain } .*( gmail.com| yahoo.com| outlook| hotmail.com) / DISCARD
/Cc:.*( gmail.com| yahoo.com| outlook| hotmail.com) .*${ mailuser } @${ domain } / DISCARD
/Cc:.*${ mailuser } @${ domain } .*( gmail.com| yahoo.com| outlook| hotmail.com) / DISCARD
/To:.*<>/ DISCARD
/From:.*<>/ DISCARD" | tee -a /etc/postfix/header_checks >/dev/null
# Body checks
echo " /free mortgage quote/ DISCARD
/repair your credit/ DISCARD
/lose weight/ DISCARD" | tee -a /etc/postfix/body_checks >/dev/null
2024-03-25 09:28:08 -06:00
# Whitelist localhost
2024-03-24 19:51:20 -06:00
echo -e " # Permit my own IP addresses
${ ip_addr } /32\t permit" | tee /etc/postfix/postscreen_access.cidr >/dev/null
# Blocking Email Spam with Postfix
echo -e " ${ domain } OK " | tee /etc/postfix/{ helo_access,rbl_override} >/dev/null
# Virtual mailboxes
mkdir -p /etc/postfix/sql
tee /etc/postfix/sql/mysql_virtual_domains_maps.cf >/dev/null <<EOF
user = postfixadmin
password = ${ postfixadmindbpass }
hosts = localhost
dbname = postfixadmin
query = SELECT domain FROM domain WHERE domain = '%s' AND active = '1'
#query = SELECT domain FROM domain WHERE domain='%s'
#optional query to use when relaying for backup MX
#query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1'
#expansion_limit = 100
EOF
tee /etc/postfix/sql/mysql_virtual_mailbox_maps.cf >/dev/null <<EOF
user = postfixadmin
password = ${ postfixadmindbpass }
hosts = localhost
dbname = postfixadmin
query = SELECT maildir FROM mailbox WHERE username = '%s' AND active = '1'
#expansion_limit = 100
EOF
tee /etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf >/dev/null <<EOF
user = postfixadmin
password = ${ postfixadmindbpass }
hosts = localhost
dbname = postfixadmin
query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT( '%u' , '@' , alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active= '1'
EOF
tee /etc/postfix/sql/mysql_virtual_alias_maps.cf >/dev/null <<EOF
user = postfixadmin
password = ${ postfixadmindbpass }
hosts = localhost
dbname = postfixadmin
query = SELECT goto FROM alias WHERE address = '%s' AND active = '1'
#expansion_limit = 100
EOF
tee /etc/postfix/sql/mysql_virtual_alias_domain_maps.cf >/dev/null <<EOF
user = postfixadmin
password = ${ postfixadmindbpass }
hosts = localhost
dbname = postfixadmin
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT( '%u' , '@' , alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active= '1'
EOF
tee /etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf >/dev/null <<eof
# handles catch-all settings of target-domain
user = postfixadmin
password = ${ postfixadmindbpass }
hosts = localhost
dbname = postfixadmin
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT( '@' , alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active= '1'
eof
chmod 0640 /etc/postfix/sql/*
setfacl -R -m u:postfix:rx /etc/postfix/sql/
adduser vmail --system --group --uid 600 --disabled-login --no-create-home >/dev/null
mkdir -p /var/vmail
chown vmail:vmail /var/vmail/ -R
sed -i 's/#!include auth-sql.conf.ext/!include auth-sql.conf.ext/' /etc/dovecot/conf.d/10-auth.conf
sed -i 's/!include auth-system.conf.ext/#&/' /etc/dovecot/conf.d/10-auth.conf
echo -e ' \n auth_debug = yes
auth_debug_passwords = yes' | tee -a /etc/dovecot/conf.d/10-auth.conf >/dev/null
tee -a /etc/dovecot/dovecot-sql.conf.ext >/dev/null <<eof
# Virtual mailboxes
driver = mysql
connect = host = localhost dbname = postfixadmin user = postfixadmin password = ${ postfixadmindbpass }
default_pass_scheme = ARGON2I
password_query = SELECT username AS user,password FROM mailbox WHERE username = '%u' AND active = '1'
user_query = SELECT maildir, 600 AS uid, 600 AS gid FROM mailbox WHERE username = '%u' AND active = '1'
iterate_query = SELECT username AS user FROM mailbox
eof
unset postfixadmindbpass
postmap /etc/postfix/helo_access /etc/postfix/rbl_override /etc/postfix/smtp_header_checks /etc/postfix/header_checks /etc/postfix/body_checks /etc/postfix/postscreen_access.cidr
# Dovecot
echo -e '\n\e[1;34mConfiguring Dovecot\e[0m'
echo -e '\nprotocols = imap lmtp' | tee -a /etc/dovecot/dovecot.conf >/dev/null
sed -i ' s| ^mail_location = .*| mail_location = maildir:~/Maildir\
'"$(if ! grep -q ' ^mail_home = /var/vmail/%d/%n/' /etc/dovecot/conf.d/10-mail.conf
then
echo 'mail_home = /var/vmail/%d/%n/'
fi ) " '|g' /etc/dovecot/conf.d/10-mail.conf
sed -i ' s| unix_listener lmtp { | unix_listener /var/spool/postfix/private/dovecot-lmtp { \
mode = 0600\
user = postfix\
group = postfix| ' /etc/dovecot/conf.d/10-master.conf
sed -i ' s| unix_listener auth-userdb { | unix_listener /var/spool/postfix/private/auth { \
mode = 0660\
user = postfix\
group = postfix| ' /etc/dovecot/conf.d/10-master.conf
sed -i '/#disable_plaintext_auth/ s/^#//' /etc/dovecot/conf.d/10-auth.conf
sed -i 's/#auth_username_format = %Lu/auth_username_format = %u/' /etc/dovecot/conf.d/10-auth.conf
sed -i 's/#auth_default_realm.*/auth_default_realm = ' ${ domain } '/' /etc/dovecot/conf.d/10-auth.conf
sed -i 's/auth_mechanisms = plain/& login/' /etc/dovecot/conf.d/10-auth.conf
sed -i 's/ssl = yes/ssl = required/' /etc/dovecot/conf.d/10-ssl.conf
sed -i 's/#ssl_prefer_server_ciphers = no/ssl_prefer_server_ciphers = yes/' /etc/dovecot/conf.d/10-ssl.conf
sed -i 's/#ssl_min_protocol =.*/ssl_min_protocol = TLSv1.2/' /etc/dovecot/conf.d/10-ssl.conf
echo -e ' \n service stats {
unix_listener stats-reader {
user = www-data
group = www-data
mode = 0660
}
unix_listener stats-writer {
user = www-data
group = www-data
mode = 0660
}
} ' | tee -a /etc/dovecot/conf.d/10-master.conf >/dev/null
gpasswd -a www-data dovecot >/dev/null
# Mailboxes
sed -i ' s/namespace inbox { /& \
# Archive folder\
mailbox Archive { \
special_use = \\ Archive\
} /' /etc/dovecot/conf.d/15-mailboxes.conf
sed -i ' /Sent Messages/! s/^ mailbox.*{ /& \
auto = subscribe/' /etc/dovecot/conf.d/15-mailboxes.conf
adduser dovecot mail >/dev/null
2024-03-25 09:28:08 -06:00
systemctl restart dovecot.service postfix.service
2024-03-24 19:51:20 -06:00
# SPF and DKIM
echo -e '\e[1;34mConfiguring SPF and DKIM policies\e[0m'
gpasswd -a postfix opendkim >/dev/null
grep -q '^Canonicalization.*relaxed/simple$' /etc/opendkim.conf || sed -i 's|.*Canonicalization.*|Canonicalization relaxed/simple|' /etc/opendkim.conf
sed -i '/^#Mode.*sv\|^#SubDomains.*no/ s/^#//' /etc/opendkim.conf
echo -e ' \n # Map domains in "from" addresses to keys used to sign messages
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
# Hosts to ignore when verifying signatures
ExternalIgnoreList /etc/opendkim/trusted.hosts
# A set of internal hosts whose mail should be signed
InternalHosts /etc/opendkim/trusted.hosts' | tee -a /etc/opendkim.conf >/dev/null
mkdir -p /etc/opendkim/keys
chown -R opendkim:opendkim /etc/opendkim
chmod go-rw /etc/opendkim/keys
2024-03-24 19:22:26 -06:00
2024-03-24 19:51:20 -06:00
echo " *@ ${ domain } default._domainkey. ${ domain } " | tee -a /etc/opendkim/SigningTable >/dev/null
echo " default._domainkey. ${ domain } ${ domain } :default:/etc/opendkim/keys/ ${ domain } /default.private " | tee -a /etc/opendkim/KeyTable >/dev/null
echo " 127.0.0.1
localhost
2024-03-24 19:22:26 -06:00
2024-03-24 19:51:20 -06:00
*.${ domain } " | tee -a /etc/opendkim/trusted.hosts >/dev/null
mkdir -p /etc/opendkim/keys/${ domain }
opendkim-genkey -b 2048 -d ${ domain } -D /etc/opendkim/keys/${ domain } -s default
chown opendkim:opendkim /etc/opendkim/keys/${ domain } /default.private
chmod 600 /etc/opendkim/keys/${ domain } /default.private
mkdir -p /var/spool/postfix/opendkim
chown opendkim:postfix /var/spool/postfix/opendkim
sed -i '/^#Socket.*local:\/var\/spool\/postfix\/opendkim\/opendkim.sock/ s/^#//' /etc/opendkim.conf || sed -i 's\^Socket.*local:/run/opendkim/opendkim.sock\Socket local:/var/spool/postfix/opendkim/opendkim.sock\' /etc/opendkim.conf
sed -i 's\^SOCKET=local:$RUNDIR/opendkim.sock\SOCKET="local:/var/spool/postfix/opendkim/opendkim.sock"\' /etc/default/opendkim
# DMARC
echo -e '\e[1;34mConfiguring DMARC\e[0m'
sed -i 's/# AuthservID name/AuthservID OpenDMARC/' /etc/opendmarc.conf
sed -i 's/# TrustedAuthservIDs HOSTNAME/TrustedAuthservIDs ' ${ subdomain } '.' ${ domain } '/' /etc/opendmarc.conf
sed -i ' s/# RejectFailures false/RejectFailures true\
IgnoreAuthenticatedClients true\
RequiredHeaders true\
SPFSelfValidate true/' /etc/opendmarc.conf
sed -i 's|Socket local:/run/opendmarc/opendmarc.sock|Socket local:/var/spool/postfix/opendmarc/opendmarc.sock|' /etc/opendmarc.conf
mkdir -p /var/spool/postfix/opendmarc
chown opendmarc:opendmarc /var/spool/postfix/opendmarc -R
chmod 750 /var/spool/postfix/opendmarc/ -R
adduser postfix opendmarc >/dev/null
echo -e '\nIgnoreHosts /etc/opendmarc/ignore.hosts' | tee -a /etc/opendmarc.conf >/dev/null
mkdir -p /etc/opendmarc
echo '127.0.0.1' | tee -a /etc/opendmarc/ignore.hosts >/dev/null
# OpenDKIM and OpenDMARC headers
echo -e '\nSoftwareHeader yes' | tee -a /etc/{ opendkim,opendmarc} .conf >/dev/null
2024-03-25 09:28:08 -06:00
systemctl restart postfix.service opendkim.service opendmarc.service
2024-03-24 19:51:20 -06:00
# Roundcube/Nginx
echo -e '\e[1;34mConfiguring Nginx\e[0m'
tee $( find /etc/php/ -type d -name "pool.d" ) /zz-php-handler.conf >/dev/null <<EOF
listen = /run/php/php-fpm.sock
EOF
tee /etc/nginx/proxy_params >/dev/null <<'PROXY'
proxy_set_header Host $http_host ;
proxy_set_header X-Real-IP $remote_addr ;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ;
proxy_set_header X-Forwarded-Proto $scheme ;
PROXY
echo -e '
upstream php-handler {
server unix:/run/php/php-fpm.sock;
}
server {
server_name '${subdomain}' .'${domain}' ;
index index.php index.html;
error_log /var/log/nginx/roundcube_error.log;
access_log /var/log/nginx/roundcube_access.log;
root /usr/share/webapps/roundcube;
# Postfixadmin
location ^~ /admin/ {
proxy_pass http://127.0.0.1:12000/;
include proxy_params;
}
# Roundcube
location ~ \. php$ {
try_files $uri = 404;
fastcgi_split_path_info ^( .+\. php) ( /.+) $;
fastcgi_pass php-handler;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root $fastcgi_script_name ;
fastcgi_param PATH_INFO $fastcgi_path_info ;
}
}
server {
listen 12000;
root /usr/share/webapps/postfixadmin/public/;
index index.php index.html;
client_max_body_size 0;
error_log /var/log/nginx/postfixadmin_error.log;
access_log /var/log/nginx/postfixadmin_access.log;
location / {
try_files $uri $uri / /index.php;
}
location ~ ^/( .+\. php) $ {
try_files $uri = 404;
fastcgi_pass php-handler;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root $fastcgi_script_name ;
include /etc/nginx/fastcgi_params;
}
} ' | tee /etc/nginx/sites-available/mail.conf >/dev/null
ln -s /etc/nginx/sites-available/mail.conf /etc/nginx/sites-enabled/
# Certbot
systemctl -q disable --now apache2.service
systemctl -q reload nginx.service
2024-03-25 07:15:45 -06:00
/etc/init.d/php*-fpm reload >/dev/null
2024-03-24 19:51:20 -06:00
until certbot --nginx --agree-tos --redirect --hsts --no-eff-email --staple-ocsp -m ${ eff_email } -d ${ subdomain } .${ domain }
do
sleep 10
done
setfacl -R -m u:www-data:rx /etc/letsencrypt/live/ /etc/letsencrypt/archive/
# Postfix
postconf -e " smtpd_tls_key_file = /etc/letsencrypt/live/ ${ subdomain } . ${ domain } /privkey.pem "
postconf -e " smtpd_tls_cert_file = /etc/letsencrypt/live/ ${ subdomain } . ${ domain } /fullchain.pem "
# Dovecot
# sed -i 's|ssl_cert = </etc/dovecot/private/dovecot.pem|# &|' /etc/dovecot/conf.d/10-ssl.conf
# sed -i 's|ssl_key = </etc/dovecot/private/dovecot.key|# &|' /etc/dovecot/conf.d/10-ssl.conf
echo 'ssl_cert = </etc/letsencrypt/live/' ${ subdomain } '.' ${ domain } ' /fullchain.pem
ssl_key = </etc/letsencrypt/live/'${subdomain}' .'${domain}' /privkey.pem' | tee /etc/dovecot/ssl-keys.conf >/dev/null
chmod 600 /etc/dovecot/ssl-keys.conf
echo -e '!include_try ssl-keys.conf' | tee -a /etc/dovecot/dovecot.conf >/dev/null
# Cron tasks
echo ' #!/bin/sh
certbot renew --quiet && systemctl -q reload postfix dovecot nginx
/usr/local/bin/postwhite/postwhite & >/dev/null # Update Postscreen Whitelists' | install /dev/stdin /etc/cron.daily/mailserver
echo ' #!/bin/sh
/usr/local/bin/postwhite/scrape_yahoo & >/dev/null # Update Yahoo! IPs for Postscreen Whitelists' | install /dev/stdin /etc/cron.weekly/mailserver
ln -s /usr/share/webapps/roundcube/bin/cleandb.sh /etc/cron.daily/roundcube-cleandb
# Run postwhite installer
echo -e '\n\e[1;34mInstalling Postwhite\e[0m'
/usr/local/bin/postwhite/postwhite
su ${ username } <<"CHANGEUSER"
2024-03-25 07:15:45 -06:00
# SSH
yes | ssh-keygen -t ed25519 -q -f ~/.ssh/id_ed25519 -P ""
echo " ${ sshkeys } " >~/.ssh/authorized_keys
# Home directory mods
cat >>~/.bashrc <<bashrc
# Apt upgrade
alias syu = 'sudo apt update && sudo apt upgrade -y && sudo apt autoremove -y'
2024-03-24 19:51:20 -06:00
2024-03-25 07:15:45 -06:00
# Disable shell history
2024-03-24 19:51:20 -06:00
unset HISTFILE
2024-03-25 07:15:45 -06:00
if [ -f \$ { HISTFILE} ]
then
rm -f \$ { HISTFILE}
fi
2024-03-24 19:51:20 -06:00
history -c
# Mail logs
function mail-watch
{
2024-03-25 07:15:45 -06:00
sudo tail -f /var/log/mail.log
2024-03-24 19:51:20 -06:00
}
function mail-log
{
2024-03-25 07:15:45 -06:00
sudo cat /var/log/mail.log
2024-03-24 19:51:20 -06:00
}
function mail-troubleshoot
{
systemctl status postfix.service dovecot.service opendkim.service opendmarc.service nginx.service mariadb.service
/etc/init.d/php*-fpm status
}
function mail-reboot
{
2024-03-25 07:15:45 -06:00
sudo systemctl -q restart postfix.service dovecot.service opendkim.service opendmarc.service nginx.service mariadb.service
sudo /etc/init.d/php*-fpm restart >/dev/null
2024-03-24 19:51:20 -06:00
}
function mail-check
{
if systemctl list-units --state failed | grep -q 'postfix\|dovecot\|opendkim\|opendmarc\|nginx\|mariadb\|php.*-fpm'
then
echo -e '\nErrors found...\n'
systemctl list-units --state failed
else
echo -e '\nAll good!\n'
fi
}
function mail-test
{
2024-03-25 07:15:45 -06:00
sudo systemctl stop postfix dovecot
2024-03-24 19:51:20 -06:00
read -n 1 -s -p $'\nPress any key to continue...\n'
2024-03-25 07:15:45 -06:00
sudo systemctl start postfix dovecot &&
2024-03-24 19:51:20 -06:00
mail-watch
}
# SSH pubkey access
function ssh-on
{
2024-03-25 07:15:45 -06:00
sudo sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config.d/10-personal-sshd.conf
sudo systemctl -q restart sshd
2024-03-24 19:51:20 -06:00
}
function ssh-off
{
2024-03-25 07:15:45 -06:00
sudo sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config.d/10-personal-sshd.conf
sudo systemctl -q restart sshd
}
bashrc
2024-03-24 19:51:20 -06:00
install /dev/stdin ~/dhparam >/dev/null <<'dhparam'
#!/usr/bin/env bash
echo
2024-03-25 07:15:45 -06:00
# Create certificates
2024-03-24 19:51:20 -06:00
echo -e '\e[1;34mGenerating DH parameters with openssl\e[0m'
echo -e '\e[3m# a notification will pop up once completed\e[0m'
2024-03-25 06:02:17 -06:00
sudo openssl dhparam -out /usr/share/dovecot/dh.pem 4096 &&
2024-03-25 09:28:45 -06:00
echo -e '\e[1;32mOpenssl certificates have successfully been generated!\e[0m\n'
2024-03-24 19:51:20 -06:00
rm ${ 0 }
dhparam
CHANGEUSER
2024-03-24 19:22:26 -06:00
2024-03-25 07:15:45 -06:00
# In your DNS manager, create a TXT record, enter default._domainkey in the name field
echo -e "\e[1;34mUpdate DKIM TXT on DNS registrar and press any key to continue\e[5m...\e[0m"
echo -e "\e[3m# Use default._domainkey in the host field"
echo -e " # Check with 'sudo opendkim-testkey -d ${ domain } -s default' "
echo -e "# Or visit https://www.dmarcanalyzer.com/dkim/dkim-checker/\e[0m"
cat /etc/opendkim/keys/${ domain } /default.txt | sed 's/.*( //' | sed 's/ ).*//' | sed 's/"//g' | sed 's/^[ \t]*//g' | sed ':a;N;$!ba;s/\n//g'
2024-03-24 19:51:20 -06:00
2024-03-25 07:15:45 -06:00
cat <<END
2024-03-24 19:51:20 -06:00
###
### SSH
2024-03-24 19:22:26 -06:00
###
2024-03-24 19:51:20 -06:00
2024-03-24 19:22:26 -06:00
while :
do
clear
2024-03-24 19:51:20 -06:00
if ssh ${ username } @${ domain_url } -p ${ ssh_port } exit
2024-03-24 19:22:26 -06:00
then
2024-03-24 19:51:20 -06:00
echo -e '\e[1m## Run "~/dhparam" upon logging in\e[0m'
echo -e '\e[1m## Installer has completed, access your new email at https://${subdomain}.${domain}\n\e[0m'
ssh ${ username } @${ domain_url } -p ${ ssh_port }
2024-03-24 19:22:26 -06:00
break
else
sleep 1
fi
done
END
2024-03-24 19:51:20 -06:00
. ~/.bashrc
reboot
fi