mirror of
https://git.myvelabs.com/docker/myvemail.git
synced 2025-12-17 21:26:19 +00:00
First commit
This commit is contained in:
commit
7b58f82156
21 changed files with 1951 additions and 0 deletions
34
build/Dockerfile.alpine
Normal file
34
build/Dockerfile.alpine
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# syntax = docker/dockerfile:1
|
||||
FROM alpine:edge
|
||||
|
||||
# LABEL about the custom image
|
||||
LABEL description="MyveMail"
|
||||
|
||||
# Env files (differs between distros)
|
||||
ENV MYVEMAIL_NGINX_USERGROUP=nginx
|
||||
ENV MYVEMAIL_OPENDKIM_CONF=/etc/opendkim/opendkim.conf
|
||||
ENV MYVEMAIL_OPENDMARC_CONF=/etc/opendmarc/opendmarc.conf
|
||||
|
||||
# Copy required files folders
|
||||
ADD run/bin /usr/local/bin/
|
||||
ADD run/docker-entrypoint /docker-entrypoint/
|
||||
COPY run/installer-alpine.sh /tmp/installer.sh
|
||||
|
||||
# Update Ubuntu Software repository and install requisites
|
||||
RUN printf '%s\n' 'https://dl-cdn.alpinelinux.org/alpine/edge/main/' \
|
||||
'https://dl-cdn.alpinelinux.org/alpine/edge/community/' >/etc/apk/repositories \
|
||||
&& apk update \
|
||||
&& apk upgrade \
|
||||
&& apk add --no-cache \
|
||||
bash bash-completion ncurses \
|
||||
&& /tmp/installer.sh \
|
||||
&& rm /tmp/installer.sh
|
||||
|
||||
# Expose ports
|
||||
EXPOSE 25
|
||||
EXPOSE 80
|
||||
EXPOSE 587
|
||||
EXPOSE 143 993
|
||||
|
||||
# Entrypoint hd-wallet-derive script
|
||||
CMD ["/docker-entrypoint/entrypoint.sh"]
|
||||
31
build/Dockerfile.ubuntu
Normal file
31
build/Dockerfile.ubuntu
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# syntax = docker/dockerfile:1
|
||||
FROM ubuntu:latest
|
||||
|
||||
# LABEL about the custom image
|
||||
LABEL description="MyveMail"
|
||||
|
||||
# Disable Prompt During Packages Installation
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Env files (differs between distros)
|
||||
ENV MYVEMAIL_NGINX_USERGROUP=www-data
|
||||
ENV MYVEMAIL_OPENDKIM_CONF=/etc/opendkim.conf
|
||||
ENV MYVEMAIL_OPENDMARC_CONF=/etc/opendmarc.conf
|
||||
|
||||
# Copy required files folders
|
||||
ADD run/bin /usr/local/bin/
|
||||
ADD run/docker-entrypoint /docker-entrypoint/
|
||||
COPY run/installer-ubuntu.sh /tmp/installer.sh
|
||||
|
||||
# Update Ubuntu Software repository and install requisites
|
||||
RUN /tmp/installer.sh \
|
||||
&& rm /tmp/installer.sh
|
||||
|
||||
# Expose ports
|
||||
EXPOSE 25
|
||||
EXPOSE 80
|
||||
EXPOSE 587
|
||||
EXPOSE 143 993
|
||||
|
||||
# Entrypoint hd-wallet-derive script
|
||||
CMD ["/docker-entrypoint/entrypoint.sh"]
|
||||
96
build/run/bin/add-user
Executable file
96
build/run/bin/add-user
Executable file
|
|
@ -0,0 +1,96 @@
|
|||
#!/usr/bin/env bash
|
||||
# Exit if any errors pop up
|
||||
set -e
|
||||
|
||||
# Array of available domains
|
||||
domains=(${MYVEMAIL_DOMAIN})
|
||||
domains+=(${MYVEMAIL_ADDMX//,/ })
|
||||
|
||||
# Check if postfixadmin db has been installed
|
||||
if [ ! -d /var/lib/mysql/${MYVEMAIL_POSTFIXADMIN_DBNAME}/ ]
|
||||
then
|
||||
echo "Run setup script before proceeding"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if mariadb is active
|
||||
if ! ps aux | grep -q mariadb
|
||||
then
|
||||
mariadbd --user=root --datadir=/var/lib/mysql/ &
|
||||
until mariadb --user=root --database=mysql -e "show tables;" >/dev/null
|
||||
do
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
|
||||
# Proceed only if postfixadmin db is installed
|
||||
if mariadb --user=root --database=${MYVEMAIL_POSTFIXADMIN_DBNAME} -e "select * from domain;" | grep -q ${MYVEMAIL_DOMAIN}
|
||||
then
|
||||
# Mail account domain
|
||||
echo -e "\e[1;34mChoose an available domain from the following: ${domains[@]}\e[0m"
|
||||
until [ ${MYVEMAIL_ADDUSER_DOMAIN} ] && [[ ${domains[@]} =~ ${MYVEMAIL_ADDUSER_DOMAIN} ]]
|
||||
do
|
||||
read -r -p 'Domain: ' MYVEMAIL_ADDUSER_DOMAIN
|
||||
if [ -z "${MYVEMAIL_ADDUSER_DOMAIN}" ]
|
||||
then
|
||||
echo -e '\n\e[1;31mField cannot be empty, try again\e[0m'
|
||||
elif ! [[ ${domains[@]} =~ ${MYVEMAIL_ADDUSER_DOMAIN} ]]
|
||||
then
|
||||
echo -e '\n\e[1;31mChoose a valid domain\e[0m'
|
||||
fi
|
||||
done
|
||||
|
||||
# Mail username
|
||||
if [ -z ${MYVEMAIL_MAIL_USER} ]
|
||||
then
|
||||
echo -e '\n\e[1;34mType in your email username\e[0m'
|
||||
until [ ${MYVEMAIL_MAIL_USER} ]
|
||||
do
|
||||
read -r -p 'Username: ' MYVEMAIL_MAIL_USER
|
||||
[ ${MYVEMAIL_MAIL_USER} ] || echo -e '\n\e[1;31mUsername cannot be empty, try again\e[0m'
|
||||
done
|
||||
echo -e '\n\e[1;32mMail user '${MYVEMAIL_MAIL_USER}'@'${MYVEMAIL_ADDUSER_DOMAIN}' has been saved\e[0m\n'
|
||||
fi
|
||||
|
||||
# Mail account password
|
||||
echo -e '\e[1;34mCreate a password for your mail account\e[0m'
|
||||
until [ "${MYVEMAIL_MAIL_PASS}" = "${MYVEMAIL_MAIL_PASS2}" -a "${MYVEMAIL_MAIL_PASS}" ]
|
||||
do
|
||||
read -s -r -p 'Mail password: ' MYVEMAIL_MAIL_PASS
|
||||
read -s -r -p $'\nVerify mail password: ' MYVEMAIL_MAIL_PASS2
|
||||
if [ -z "${MYVEMAIL_MAIL_PASS}" ]
|
||||
then
|
||||
echo -e '\n\n\e[1;31mPassword field cannot be empty, try again\e[0m'
|
||||
elif [ "${MYVEMAIL_MAIL_PASS}" != "${MYVEMAIL_MAIL_PASS2}" ]
|
||||
echo -e '\n\n\e[1;31mPasswords did not match, try again\e[0m'
|
||||
then
|
||||
fi
|
||||
done
|
||||
echo -e '\n\n\e[1;32mMail password has been saved\e[0m\n'
|
||||
|
||||
# Catch-all alias
|
||||
until [[ ${MYVEMAIL_USER_CATCHALL} = [yYnN] ]]
|
||||
do
|
||||
echo -n -e '\e[1;34mWill the user use a catch-all alias?\e[0m '
|
||||
read -n 1 -r MYVEMAIL_USER_CATCHALL
|
||||
echo
|
||||
echo
|
||||
if ! [[ ${MYVEMAIL_USER_CATCHALL} = [yYnN] ]]
|
||||
then
|
||||
echo -e '\e[1;31mNot a valid answer, type "y" or "n"\e[0m'
|
||||
fi
|
||||
done
|
||||
|
||||
# Create Postfixadmin mail users
|
||||
bash /usr/share/webapps/postfixadmin/scripts/postfixadmin-cli mailbox add "${MYVEMAIL_MAIL_USER}@${MYVEMAIL_ADDUSER_DOMAIN}" --active --password "${MYVEMAIL_MAIL_PASS}" --password2 "${MYVEMAIL_MAIL_PASS}" -q
|
||||
|
||||
# Create Postfixadmin mail catch-all alias
|
||||
if [[ ${MYVEMAIL_USER_CATCHALL} = [yY] ]]
|
||||
then
|
||||
bash /usr/share/webapps/postfixadmin/scripts/postfixadmin-cli alias add "*@${MYVEMAIL_ADDUSER_DOMAIN}" --goto "${MYVEMAIL_MAIL_USER}@${MYVEMAIL_ADDUSER_DOMAIN}" --active -q
|
||||
fi
|
||||
else
|
||||
echo "Postfixadmin database does not seem to be installed"
|
||||
echo "Run setup script before proceeding"
|
||||
exit 1
|
||||
fi
|
||||
24
build/run/bin/install-mariadb
Executable file
24
build/run/bin/install-mariadb
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/env bash
|
||||
# Exit if any errors pop up
|
||||
set -e
|
||||
|
||||
# Install mariadb
|
||||
rm -r /var/lib/mysql/* -f
|
||||
mariadb-install-db --user=root --datadir=/var/lib/mysql/
|
||||
|
||||
# Wait for mariadb start
|
||||
mariadbd-safe --user=root --datadir=/var/lib/mysql/ &
|
||||
until mariadb --user=root --database=mysql -e "show tables;" >/dev/null
|
||||
do
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Secure installation
|
||||
printf '%s\n' "" "n" "n" "" "" "" "" | mariadb-secure-installation
|
||||
|
||||
# Shutdown mariadb
|
||||
mariadb --user=root -e "shutdown;"
|
||||
until ! mariadb --user=root --database=mysql -e "show tables;" >/dev/null
|
||||
do
|
||||
sleep 1
|
||||
done
|
||||
10
build/run/bin/list-dkim
Executable file
10
build/run/bin/list-dkim
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
for domain in /etc/opendkim/keys/*/default.txt
|
||||
do
|
||||
# In your DNS manager, create a TXT record, enter default._domainkey in the name field
|
||||
echo -e "\n\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 'opendkim-testkey -d ${domain} -s default'"
|
||||
echo -e "# Or visit https://www.dmarcanalyzer.com/dkim/dkim-checker/\e[0m"
|
||||
cat ${domain} | sed 's/.*( //' | sed 's/ ).*//' | sed 's/"//g' | sed 's/^[ \t]*//g' | sed ':a;N;$!ba;s/\n//g'
|
||||
done
|
||||
191
build/run/bin/setup
Executable file
191
build/run/bin/setup
Executable file
|
|
@ -0,0 +1,191 @@
|
|||
#!/usr/bin/env bash
|
||||
# Exit if any errors pop up
|
||||
set -e
|
||||
|
||||
# Exit if setup has already been run
|
||||
if [ -d /var/lib/mysql/${MYVEMAIL_POSTFIXADMIN_DBNAME}/ ]
|
||||
then
|
||||
echo "Setup appears to have already been completed, exiting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to wait for mariadb to be ready
|
||||
function wait_for_mariadb_start
|
||||
{
|
||||
until mariadb --user=root --database=mysql -e "show tables;" >/dev/null
|
||||
do
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
# Function to wait for mariadb to fully exit
|
||||
function wait_for_mariadb_stop
|
||||
{
|
||||
mariadb --user=root -e "shutdown;"
|
||||
until ! mariadb --user=root --database=mysql -e "show tables;" >/dev/null
|
||||
do
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
|
||||
# Install mariadb if it isn't already installed
|
||||
if [ ! -d /var/lib/mysql/mysql/ ]
|
||||
then
|
||||
/usr/local/bin/install-mariadb
|
||||
fi
|
||||
|
||||
# Start mariadb server
|
||||
mariadbd --user=root --datadir=/var/lib/mysql/ &
|
||||
wait_for_mariadb_start
|
||||
|
||||
if [ ! -d /var/lib/mysql/${MYVEMAIL_POSTFIXADMIN_DBNAME}/ ]
|
||||
then
|
||||
# Postfixadmin database
|
||||
mariadb --user=root <<- POSTFIXADMIN
|
||||
CREATE DATABASE ${MYVEMAIL_POSTFIXADMIN_DBNAME};
|
||||
GRANT ALL PRIVILEGES ON ${MYVEMAIL_POSTFIXADMIN_DBNAME}.* to '${MYVEMAIL_POSTFIXADMIN_DBUSER}'@'localhost' IDENTIFIED BY '${MYVEMAIL_POSTFIXADMIN_DBPASS}';
|
||||
flush privileges;
|
||||
POSTFIXADMIN
|
||||
fi
|
||||
|
||||
if ! mariadb --user=root --database=${MYVEMAIL_POSTFIXADMIN_DBNAME} -e "select * from domain;" | grep -q ${MYVEMAIL_DOMAIN}
|
||||
then
|
||||
|
||||
# Mail username
|
||||
if [ -z ${MYVEMAIL_MAIL_USER} ]
|
||||
then
|
||||
echo -e '\n\e[1;34mType in your email username\e[0m'
|
||||
until [ ${MYVEMAIL_MAIL_USER} ]
|
||||
do
|
||||
read -r -p 'Username: ' MYVEMAIL_MAIL_USER
|
||||
[ ${MYVEMAIL_MAIL_USER} ] || echo -e '\n\e[1;31mUsername cannot be empty, try again\e[0m'
|
||||
done
|
||||
echo -e '\n\e[1;32mMail user '${MYVEMAIL_MAIL_USER}'@'${MYVEMAIL_DOMAIN}' has been saved\e[0m\n'
|
||||
fi
|
||||
|
||||
# Mail account password
|
||||
echo -e '\e[1;34mCreate a password for your mail account\e[0m'
|
||||
until [ "${MYVEMAIL_MAIL_PASS}" = "${MYVEMAIL_MAIL_PASS2}" -a "${MYVEMAIL_MAIL_PASS}" ]
|
||||
do
|
||||
read -s -r -p 'Mail password: ' MYVEMAIL_MAIL_PASS
|
||||
read -s -r -p $'\nVerify mail password: ' MYVEMAIL_MAIL_PASS2
|
||||
if [ -z "${MYVEMAIL_MAIL_PASS}" ]
|
||||
then
|
||||
echo -e '\n\n\e[1;31mPassword field cannot be empty, try again\e[0m'
|
||||
elif [ "${MYVEMAIL_MAIL_PASS}" != "${MYVEMAIL_MAIL_PASS2}" ]
|
||||
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'
|
||||
|
||||
# Postfixadmin password
|
||||
echo -e '\e[1;34mCreate a postfixadmin setup password\e[0m'
|
||||
until [ "${MYVEMAIL_POSTFIXADMIN_PASS}" = "${MYVEMAIL_POSTFIXADMIN_PASS2}" -a "${MYVEMAIL_POSTFIXADMIN_PASS}" ]
|
||||
do
|
||||
read -s -r -p 'Postfixadmin password: ' MYVEMAIL_POSTFIXADMIN_PASS
|
||||
read -s -r -p $'\nVerify Postfixadmin password: ' MYVEMAIL_POSTFIXADMIN_PASS2
|
||||
if [ -z "${MYVEMAIL_POSTFIXADMIN_PASS}" ]
|
||||
then
|
||||
echo -e '\n\n\e[1;31mPassword field cannot be empty, try again\e[0m'
|
||||
elif [ "${MYVEMAIL_POSTFIXADMIN_PASS}" != "${MYVEMAIL_POSTFIXADMIN_PASS2}" ]
|
||||
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'
|
||||
|
||||
# Install roundcube and postfixadmin if not already installed
|
||||
if [ ! -d /usr/share/webapps/roundcube ] || [ ! -d /usr/share/webapps/postfixadmin ]
|
||||
then
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
# Postfixadmin
|
||||
mkdir /usr/share/webapps/postfixadmin/templates_c/
|
||||
|
||||
# Roundcube password plugin
|
||||
sed -e "/^\$config\['password_query'\]/ s/=.*/= 'UPDATE mailbox SET password=%P,modified=NOW() WHERE username=%u';/" \
|
||||
-e "/^\$config\['password_algorithm'\]/ s/=.*/= 'dovecot';/" \
|
||||
-e "/^\$config\['password_dovecotpw'\]/ s|=.*|= '/usr/bin/doveadm pw -r 5';|" \
|
||||
-e "/^\$config\['password_dovecotpw_method'\]/ s/=.*/= 'ARGON2I';/" \
|
||||
-e "/^\$config\['password_dovecotpw_with_method'\]/ s/=.*/= true;/" \
|
||||
/usr/share/webapps/roundcube/plugins/password/config.inc.php.dist >/usr/share/webapps/roundcube/plugins/password/config.inc.php
|
||||
|
||||
# Cleanup
|
||||
rm *.tar.gz /usr/share/webapps/roundcube/installer/ -r
|
||||
fi
|
||||
|
||||
# Postfixadmin setup
|
||||
echo -e '<?php
|
||||
$CONF['\''configured'\''] = true;
|
||||
$CONF['\''database_type'\''] = '\''mysqli'\'';
|
||||
$CONF['\''database_host'\''] = '\''localhost'\'';
|
||||
$CONF['\''database_port'\''] = '\''3306'\'';
|
||||
$CONF['\''database_user'\''] = '\'${MYVEMAIL_POSTFIXADMIN_DBUSER}\'';
|
||||
$CONF['\''database_password'\''] = '\'${MYVEMAIL_POSTFIXADMIN_DBPASS}\'';
|
||||
$CONF['\''database_name'\''] = '\'${MYVEMAIL_POSTFIXADMIN_DBNAME}\'';
|
||||
$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@'${MYVEMAIL_DOMAIN}''\'',
|
||||
'\''eff'\'' => '\''postmaster@'${MYVEMAIL_DOMAIN}''\'',
|
||||
'\''dmarc'\'' => '\''postmaster@'${MYVEMAIL_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('${MYVEMAIL_POSTFIXADMIN_PASS}', 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
|
||||
su -s /bin/bash ${MYVEMAIL_NGINX_USERGROUP} -c "php /usr/share/webapps/postfixadmin/public/upgrade.php"
|
||||
|
||||
# Create Postfixadmin domain
|
||||
bash /usr/share/webapps/postfixadmin/scripts/postfixadmin-cli domain add "${MYVEMAIL_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@${MYVEMAIL_DOMAIN}" --superadmin --active --domains "${MYVEMAIL_DOMAIN}" --password "${MYVEMAIL_POSTFIXADMIN_PASS}" --password2 "${MYVEMAIL_POSTFIXADMIN_PASS}" -q
|
||||
|
||||
# Create Postfixadmin mail users
|
||||
bash /usr/share/webapps/postfixadmin/scripts/postfixadmin-cli mailbox add "postmaster@${MYVEMAIL_DOMAIN}" --active --password "${MYVEMAIL_POSTFIXADMIN_PASS}" --password2 "${MYVEMAIL_POSTFIXADMIN_PASS}" -q
|
||||
bash /usr/share/webapps/postfixadmin/scripts/postfixadmin-cli mailbox add "${MYVEMAIL_MAIL_USER}@${MYVEMAIL_DOMAIN}" --active --password "${MYVEMAIL_MAIL_PASS}" --password2 "${MYVEMAIL_MAIL_PASS}" -q
|
||||
|
||||
# Create Postfixadmin mail catch-all alias
|
||||
bash /usr/share/webapps/postfixadmin/scripts/postfixadmin-cli alias add "*@${MYVEMAIL_DOMAIN}" --goto "${MYVEMAIL_MAIL_USER}@${MYVEMAIL_DOMAIN}" --active -q
|
||||
|
||||
# Add extra domains to Postfixadmin
|
||||
domains+=(${MYVEMAIL_ADDMX//,/ })
|
||||
for domain in ${domains[@]}
|
||||
do
|
||||
bash /usr/share/webapps/postfixadmin/scripts/postfixadmin-cli domain add "${domain}" --aliases 0 --mailboxes 0 --maxquota 0 --quota 0 --active --default-aliases -q >/dev/null
|
||||
done
|
||||
|
||||
fi
|
||||
17
build/run/bin/upgrade-roundcube
Executable file
17
build/run/bin/upgrade-roundcube
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/env bash
|
||||
# Installer for updating Roundcube
|
||||
set -e
|
||||
|
||||
# Temporary work directory
|
||||
workdir=$(mktemp -d)
|
||||
|
||||
# Download and update
|
||||
cd ${workdir}
|
||||
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
|
||||
mkdir ./roundcube
|
||||
tar zxf roundcubemail.tar.gz -C ./roundcube --strip-components 1
|
||||
./roundcube/bin/installto.sh /usr/share/webapps/roundcube/
|
||||
cd
|
||||
|
||||
# Cleanup
|
||||
rm -r ${workdir} -f
|
||||
39
build/run/docker-entrypoint/entrypoint.sh
Executable file
39
build/run/docker-entrypoint/entrypoint.sh
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/env bash
|
||||
# Abort if an error is encountered
|
||||
set -e
|
||||
|
||||
# Exit function
|
||||
trap '[ "${?}" -ne 77 ] || exit 77' ERR
|
||||
function die
|
||||
{
|
||||
local reset="\e[0m"
|
||||
local red="\e[0m\e[0;31m"
|
||||
local yellow="\e[0m\e[0;33m"
|
||||
|
||||
echo -e "${red}
|
||||
Error encountered in the following init script:
|
||||
${yellow}
|
||||
${@}
|
||||
${red}
|
||||
Aborting...
|
||||
${reset}"
|
||||
|
||||
exit 77
|
||||
}
|
||||
|
||||
# Reset logs
|
||||
echo | tee /var/log/dovecot.log /var/log/postfix.log /usr/share/webapps/roundcube/logs/errors.log >/dev/null
|
||||
|
||||
# Run all scripts in init folder
|
||||
for file in /docker-entrypoint/init.d/*.sh
|
||||
do
|
||||
bash -c ${file} || die ${file}
|
||||
done
|
||||
|
||||
# Reload services
|
||||
dovecot reload &&
|
||||
postfix reload &&
|
||||
echo -e "\n\e[1;32mMail service is ready\e[0m\n"
|
||||
|
||||
# Monitor log
|
||||
tail -f /var/log/dovecot.log /var/log/postfix.log /usr/share/webapps/roundcube/logs/errors.log
|
||||
64
build/run/docker-entrypoint/init.d/00-mariadb.sh
Executable file
64
build/run/docker-entrypoint/init.d/00-mariadb.sh
Executable file
|
|
@ -0,0 +1,64 @@
|
|||
#!/usr/bin/env bash
|
||||
# Exit if any errors pop up
|
||||
set -e
|
||||
|
||||
# Remove sock
|
||||
rm -f /run/mysqld/mysqld.sock
|
||||
|
||||
# Abort if setup hasn't been completed yet
|
||||
if [ ! -d /var/lib/mysql/mysql/ ]
|
||||
then
|
||||
echo "MariaDB does not appear to be properly installed. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to wait for temporary mariadb to be ready
|
||||
function wait_for_mariadb_start
|
||||
{
|
||||
# Start mariadb
|
||||
mariadbd-safe --user=root --datadir=/var/lib/mysql/ &
|
||||
until mariadb --user=root --database=mysql -e "show tables;" >/dev/null
|
||||
do
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
# Function to wait for mariadb to fully exit
|
||||
function wait_for_mariadb_stop
|
||||
{
|
||||
mariadb --user=root -e "shutdown;"
|
||||
until ! mariadb --user=root --database=mysql -e "show tables;" >/dev/null
|
||||
do
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
|
||||
# Roundcube database
|
||||
if [ ! -d /var/lib/mysql/${MYVEMAIL_ROUNDCUBE_DBNAME}/ ]
|
||||
then
|
||||
wait_for_mariadb_start
|
||||
|
||||
mariadb -u root <<- ROUNDCUBE
|
||||
CREATE DATABASE ${MYVEMAIL_ROUNDCUBE_DBNAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
GRANT ALL PRIVILEGES ON ${MYVEMAIL_ROUNDCUBE_DBNAME}.* TO '${MYVEMAIL_ROUNDCUBE_DBUSER}'@'localhost' IDENTIFIED BY '${MYVEMAIL_ROUNDCUBE_DBPASS}';
|
||||
flush privileges;
|
||||
ROUNDCUBE
|
||||
mariadb ${MYVEMAIL_ROUNDCUBE_DBNAME} </usr/share/webapps/roundcube/SQL/mysql.initial.sql
|
||||
|
||||
wait_for_mariadb_stop
|
||||
fi
|
||||
|
||||
# Postfixadmin database
|
||||
if [ ! -d /var/lib/mysql/${MYVEMAIL_POSTFIXADMIN_DBNAME}/ ]
|
||||
then
|
||||
wait_for_mariadb_start
|
||||
mariadb -u root <<- POSTFIXADMIN
|
||||
CREATE DATABASE ${MYVEMAIL_POSTFIXADMIN_DBNAME};
|
||||
GRANT ALL PRIVILEGES ON ${MYVEMAIL_POSTFIXADMIN_DBNAME}.* to '${MYVEMAIL_POSTFIXADMIN_DBUSER}'@'localhost' IDENTIFIED BY '${MYVEMAIL_POSTFIXADMIN_DBPASS}';
|
||||
flush privileges;
|
||||
POSTFIXADMIN
|
||||
|
||||
wait_for_mariadb_stop
|
||||
fi
|
||||
|
||||
# Start mariadb
|
||||
mariadbd --user=root --datadir=/var/lib/mysql/ &
|
||||
22
build/run/docker-entrypoint/init.d/10-ssl.sh
Executable file
22
build/run/docker-entrypoint/init.d/10-ssl.sh
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env bash
|
||||
# Generate ssl keys
|
||||
if [ ! -f /etc/ssl/dovecot/tls.pem ] || [ ! -f /etc/ssl/dovecot/tls.key ]
|
||||
then
|
||||
exit 1
|
||||
# mkdir -p /etc/ssl/dovecot/
|
||||
# openssl req \
|
||||
# -x509 \
|
||||
# -newkey rsa:4096 \
|
||||
# -sha512 \
|
||||
# -nodes \
|
||||
# -keyout /etc/ssl/dovecot/tls.key \
|
||||
# -out /etc/ssl/dovecot/tls.pem \
|
||||
# -subj "/CN=${MYVEMAIL_SUBDOMAIN}.${MYVEMAIL_DOMAIN}" \
|
||||
# -days 3650
|
||||
fi
|
||||
|
||||
# dh.pem
|
||||
[ -f /etc/ssl/dovecot/dh.pem ] || openssl dhparam -out /etc/ssl/dovecot/dh.pem 4096
|
||||
|
||||
# Permissions
|
||||
setfacl -R -m u:${MYVEMAIL_NGINX_USERGROUP}:rx /etc/ssl/dovecot/
|
||||
45
build/run/docker-entrypoint/init.d/15-opendkimmarc.sh
Executable file
45
build/run/docker-entrypoint/init.d/15-opendkimmarc.sh
Executable file
|
|
@ -0,0 +1,45 @@
|
|||
#!/usr/bin/env bash
|
||||
# Grab domain list
|
||||
domains=(${MYVEMAIL_DOMAIN})
|
||||
domains+=(${MYVEMAIL_ADDMX//,/ })
|
||||
|
||||
# Permissions
|
||||
chmod go-rw /etc/opendkim/keys
|
||||
|
||||
# Remove socks
|
||||
rm -f /var/spool/postfix/opendkim/opendkim.sock \
|
||||
/var/spool/postfix/opendmarc/opendmarc.sock
|
||||
|
||||
# Opendkim
|
||||
# Add domain entries to DKIM tables
|
||||
for domain in ${domains[@]}
|
||||
do
|
||||
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 "*.${domain}" | tee -a /etc/opendkim/trusted.hosts >/dev/null
|
||||
|
||||
# Generate DKIM key
|
||||
if [ ! -f /etc/opendkim/keys/${domain}/default.private ]
|
||||
then
|
||||
mkdir -p /etc/opendkim/keys/${domain}
|
||||
opendkim-genkey -b 2048 -d ${domain} -D /etc/opendkim/keys/${domain} -s default
|
||||
|
||||
# In your DNS manager, create a TXT record, enter default._domainkey in the name field
|
||||
echo -e "\n\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 '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'
|
||||
fi
|
||||
done
|
||||
|
||||
# OpenDMARC
|
||||
sed -i "s/{{HOSTNAME}}/${MYVEMAIL_SUBDOMAIN}.${MYVEMAIL_DOMAIN}/" ${MYVEMAIL_OPENDMARC_CONF}
|
||||
|
||||
# Permissions
|
||||
chown opendkim:opendkim /etc/opendkim/keys/*/default.private
|
||||
chmod 600 /etc/opendkim/keys/*/default.private
|
||||
|
||||
# Start services
|
||||
opendkim -x ${MYVEMAIL_OPENDKIM_CONF} -p /var/spool/postfix/opendkim/opendkim.sock
|
||||
opendmarc -c ${MYVEMAIL_OPENDMARC_CONF} -p /var/spool/postfix/opendmarc/opendmarc.sock
|
||||
57
build/run/docker-entrypoint/init.d/20-nginx.sh
Executable file
57
build/run/docker-entrypoint/init.d/20-nginx.sh
Executable file
|
|
@ -0,0 +1,57 @@
|
|||
#!/usr/bin/env bash
|
||||
# Roundcube
|
||||
if [ ! -f /usr/share/webapps/roundcube/config/config.inc.php ]
|
||||
then
|
||||
|
||||
echo "<?php
|
||||
\$config['db_dsnw'] = 'mysql://${MYVEMAIL_ROUNDCUBE_DBUSER}:${MYVEMAIL_ROUNDCUBE_DBPASS}@localhost/${MYVEMAIL_ROUNDCUBE_DBNAME}';
|
||||
|
||||
\$config['imap_host'] = 'ssl://${MYVEMAIL_SUBDOMAIN}.${MYVEMAIL_DOMAIN}';
|
||||
\$config['default_port'] = 993;
|
||||
|
||||
\$config['smtp_host'] = 'tls://${MYVEMAIL_SUBDOMAIN}.${MYVEMAIL_DOMAIN}';
|
||||
\$config['product_name'] = '${MYVEMAIL_SUBDOMAIN}.${MYVEMAIL_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\|redundant_attachments') | sed "s/\(.*\), /\1/")];" | tee /usr/share/webapps/roundcube/config/config.inc.php >/dev/null
|
||||
|
||||
# Password plugin
|
||||
roundcubepass_strength_drive=$(cat /dev/urandom | tr -d -c 'a-z' | fold -w 8 | head -n 1)
|
||||
sed -e "/^\$config\['password_db_dsn'\]/ s|=.*|= 'mysql://${MYVEMAIL_POSTFIXADMIN_DBUSER}:${MYVEMAIL_POSTFIXADMIN_DBPASS}@localhost/${MYVEMAIL_POSTFIXADMIN_DBNAME}';|" \
|
||||
-e "/^\$config\['password_strength_driver'\]/ s/=.*/= '${roundcubepass_strength_drive}';\\
|
||||
\$config['password_"${roundcubepass_strength_drive}"_min_score'] = 5;/" \
|
||||
-i /usr/share/webapps/roundcube/plugins/password/config.inc.php
|
||||
|
||||
fi
|
||||
|
||||
# Permissions
|
||||
setfacl -R -m u:${MYVEMAIL_NGINX_USERGROUP}:rwx /usr/share/webapps/postfixadmin/templates_c/
|
||||
chown ${MYVEMAIL_NGINX_USERGROUP}:${MYVEMAIL_NGINX_USERGROUP} /usr/share/webapps/roundcube/{temp,logs}/ -R
|
||||
chown ${MYVEMAIL_NGINX_USERGROUP}:${MYVEMAIL_NGINX_USERGROUP} /usr/share/webapps/roundcube/plugins/password/config.inc.php
|
||||
chmod 0600 /usr/share/webapps/roundcube/plugins/password/config.inc.php
|
||||
|
||||
# Start services
|
||||
/usr/sbin/php-fpm* -D
|
||||
nginx
|
||||
|
||||
# <<- ##appendix
|
||||
# \$config['imap_conn_options'] = array(
|
||||
# 'ssl' => array(
|
||||
# 'verify_peer' => true,
|
||||
# 'verify_peer_name' => true,
|
||||
# 'allow_self_signed' => true,
|
||||
# ),
|
||||
# );
|
||||
#
|
||||
# \$config['smtp_conn_options'] = array(
|
||||
# 'ssl' => array(
|
||||
# 'verify_peer' => true,
|
||||
# 'verify_peer_name' => true,
|
||||
# 'allow_self_signed' => true,
|
||||
# ),
|
||||
# );
|
||||
# ##appendix
|
||||
15
build/run/docker-entrypoint/init.d/25-dovecot.sh
Executable file
15
build/run/docker-entrypoint/init.d/25-dovecot.sh
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
# 10-auth.conf
|
||||
sed -i "s/{{MYVEMAIL_DOMAIN}}/${MYVEMAIL_DOMAIN}/" /etc/dovecot/conf.d/10-auth.conf
|
||||
|
||||
# dovecot-sql.conf.ext
|
||||
sed -e "s/{{MYVEMAIL_POSTFIXADMIN_DBNAME}}/${MYVEMAIL_POSTFIXADMIN_DBNAME}/" \
|
||||
-e "s/{{MYVEMAIL_POSTFIXADMIN_DBUSER}}/${MYVEMAIL_POSTFIXADMIN_DBUSER}/" \
|
||||
-e "s/{{MYVEMAIL_POSTFIXADMIN_DBPASS}}/${MYVEMAIL_POSTFIXADMIN_DBPASS}/" \
|
||||
-i /etc/dovecot/dovecot-sql.conf.ext
|
||||
|
||||
# Permissions
|
||||
chown vmail:vmail /var/vmail/ -R
|
||||
|
||||
# Start dovecot
|
||||
dovecot
|
||||
48
build/run/docker-entrypoint/init.d/30-postfix.sh
Executable file
48
build/run/docker-entrypoint/init.d/30-postfix.sh
Executable file
|
|
@ -0,0 +1,48 @@
|
|||
#!/usr/bin/env bash
|
||||
# Postfix
|
||||
echo ${MYVEMAIL_DOMAIN} >/etc/mailname
|
||||
postconf -e "myhostname = ${MYVEMAIL_SUBDOMAIN}.${MYVEMAIL_DOMAIN}"
|
||||
postconf -e "mydomain = ${MYVEMAIL_DOMAIN}"
|
||||
|
||||
# resolv.conf
|
||||
mkdir /var/spool/postfix/etc
|
||||
cp /etc/resolv.conf /var/spool/postfix/etc/resolv.conf
|
||||
|
||||
# Whitelist localhost
|
||||
sed -i "s/{{LOCAL_IPADDRESS}}/$(wget -q4O- ipv4.icanhazip.com)/" /etc/postfix/postscreen_access.cidr
|
||||
|
||||
# Configure backup mail servers
|
||||
if [ ${MYVEMAIL_BACKUPMX} ]
|
||||
then
|
||||
backupmx+=(${MYVEMAIL_BACKUPMX//,/ })
|
||||
|
||||
postconf -e "$(postconf mynetworks)$(printf ' %s/32' ${backupmx[@]})"
|
||||
postconf -e "smtp_fallback_relay =$(printf ' [%s]:25' ${backupmx[@]})"
|
||||
|
||||
# Whitelist
|
||||
for domain in ${backupmx[@]}
|
||||
do
|
||||
echo "${domain}/32 permit" >>/etc/postfix/postscreen_access.cidr
|
||||
done
|
||||
fi
|
||||
|
||||
# Whitelist
|
||||
addmx=(${MYVEMAIL_DOMAIN})
|
||||
addmx+=(${MYVEMAIL_ADDMX//,/ })
|
||||
for domain in ${addmx[@]}
|
||||
do
|
||||
echo "${domain} OK" | tee -a /etc/postfix/{helo_access,rbl_override} >/dev/null
|
||||
done
|
||||
|
||||
# Virtual mailboxes
|
||||
sed -e "s/{{MYVEMAIL_POSTFIXADMIN_DBNAME}}/${MYVEMAIL_POSTFIXADMIN_DBNAME}/" \
|
||||
-e "s/{{MYVEMAIL_POSTFIXADMIN_DBUSER}}/${MYVEMAIL_POSTFIXADMIN_DBUSER}/" \
|
||||
-e "s/{{MYVEMAIL_POSTFIXADMIN_DBPASS}}/${MYVEMAIL_POSTFIXADMIN_DBPASS}/" \
|
||||
-i /etc/postfix/sql/*.cf
|
||||
|
||||
# Permissions
|
||||
setfacl -R -m u:postfix:rx /etc/postfix/sql/
|
||||
|
||||
# Start postfix
|
||||
postfix start
|
||||
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
|
||||
34
build/run/docker-entrypoint/init.d/50-cron.sh
Executable file
34
build/run/docker-entrypoint/init.d/50-cron.sh
Executable file
|
|
@ -0,0 +1,34 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Update Postscreen Whitelists (daily)
|
||||
while true
|
||||
do
|
||||
sleep 1d
|
||||
/usr/local/bin/postwhite/postwhite
|
||||
done &
|
||||
|
||||
# Update Yahoo! IPs for Postscreen Whitelists (weekly)
|
||||
while true
|
||||
do
|
||||
sleep 7d
|
||||
/usr/local/bin/postwhite/scrape_yahoo
|
||||
done &
|
||||
|
||||
# Roundcube cleanup (daily)
|
||||
while true
|
||||
do
|
||||
sleep 1d
|
||||
/usr/share/webapps/roundcube/bin/cleandb.sh
|
||||
done &
|
||||
|
||||
# # Refresh ssl keys daily
|
||||
# # https://www.golinuxcloud.com/renew-self-signed-certificate-openssl/
|
||||
# while true
|
||||
# do
|
||||
# sleep 1d
|
||||
# openssl x509 -x509toreq -in /etc/ssl/dovecot/tls.pem -signkey /etc/ssl/dovecot/tls.key -out /tmp/new-certificate-sign-request.csr
|
||||
# openssl x509 -req -days 3650 -in /tmp/new-certificate-sign-request.csr -signkey /etc/ssl/dovecot/tls.key -out /etc/ssl/dovecot/tls.pem
|
||||
# rm /tmp/new-certificate-sign-request.csr
|
||||
# dovecot reload
|
||||
# postfix reload
|
||||
# done &
|
||||
9
build/run/docker-entrypoint/init.d/60-postwhite.sh
Executable file
9
build/run/docker-entrypoint/init.d/60-postwhite.sh
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/env bash
|
||||
# Install postwhite
|
||||
if [ ! -s /etc/postfix/postscreen_spf_whitelist.cidr ]
|
||||
then
|
||||
/usr/local/bin/postwhite/postwhite
|
||||
fi
|
||||
|
||||
# Permissions
|
||||
chown root:root /etc/postfix/postscreen_spf_whitelist.cidr
|
||||
509
build/run/installer-alpine.sh
Executable file
509
build/run/installer-alpine.sh
Executable file
|
|
@ -0,0 +1,509 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
###############
|
||||
#//
|
||||
#// Alpine specific
|
||||
#//
|
||||
###############
|
||||
# Pre-create vmail user
|
||||
addgroup -g 600 vmail
|
||||
adduser -S -D -h /var/vmail -u 600 -G vmail vmail
|
||||
|
||||
# Update and install
|
||||
apk add --no-cache \
|
||||
nginx \
|
||||
mariadb mariadb-client \
|
||||
ca-certificates acl \
|
||||
git wget bind-tools \
|
||||
postfix postfix-mysql postfix-pcre \
|
||||
dovecot dovecot-mysql dovecot-lmtpd \
|
||||
postfix-policyd-spf-perl opendkim opendkim-utils \
|
||||
opendmarc \
|
||||
php php-fpm php-imap php-mbstring php-mysqli php-curl php-zip php-xml php-bz2 php-intl php-gmp php-ldap php-common php-gd php-sqlite3 \
|
||||
php-session php-pdo_mysql php-dom php-ctype
|
||||
|
||||
# Nginx
|
||||
sed '/^http {/a\ \
|
||||
types_hash_max_size 4096;\ \
|
||||
server_names_hash_bucket_size 128;\n' -i /etc/nginx/nginx.conf
|
||||
|
||||
###############
|
||||
#//
|
||||
#// Users and directories
|
||||
#//
|
||||
###############
|
||||
# Add users to groups
|
||||
adduser dovecot mail >/dev/null
|
||||
adduser ${MYVEMAIL_NGINX_USERGROUP} dovecot >/dev/null
|
||||
adduser postfix opendkim >/dev/null
|
||||
|
||||
# Virtual mailboxes
|
||||
mkdir /etc/postfix/sql
|
||||
|
||||
# MariaDB
|
||||
install -m 1777 -d /run/mysqld
|
||||
|
||||
# DKIM/DMARC
|
||||
mkdir /{run,etc}/{opendkim,opendmarc}
|
||||
install -o opendkim -g postfix -d /var/spool/postfix/opendkim/
|
||||
install -m 750 -o opendmarc -g postfix -d /var/spool/postfix/opendmarc/
|
||||
|
||||
###############
|
||||
#//
|
||||
#// PHP
|
||||
#//
|
||||
###############
|
||||
sed -e '/upload_max_filesize =/c upload_max_filesize = 0' \
|
||||
-e '/post_max_size =/c post_max_size = 0' \
|
||||
-e '/memory_limit =/c memory_limit = 4096M' \
|
||||
-i $(find /etc/php*/ -name 'php.ini')
|
||||
|
||||
###############
|
||||
#//
|
||||
#// Postfix
|
||||
#//
|
||||
###############
|
||||
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,${MYVEMAIL_NGINX_USERGROUP}"
|
||||
|
||||
postconf -e 'smtpd_tls_session_cache_database = lmdb:${data_directory}/smtpd_scache'
|
||||
postconf -e 'smtp_tls_session_cache_database = lmdb:${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 'myorigin = $mydomain'
|
||||
postconf -e 'mydestination = $myhostname, localhost.$mydomain, localhost'
|
||||
|
||||
postconf -e "smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt"
|
||||
postconf -e "smtpd_tls_key_file = /etc/ssl/dovecot/tls.key"
|
||||
postconf -e "smtpd_tls_cert_file = /etc/ssl/dovecot/tls.pem"
|
||||
|
||||
# Enforce TLSv1.2 or TLSv1.2
|
||||
postconf -e "smtpd_tls_mandatory_protocols = >=TLSv1.2"
|
||||
postconf -e "smtp_tls_mandatory_protocols = >=TLSv1.2"
|
||||
postconf -e "smtpd_tls_protocols = >=TLSv1.2"
|
||||
postconf -e "smtp_tls_protocols = >=TLSv1.2"
|
||||
|
||||
# Logging
|
||||
postconf -e "maillog_file = /var/log/postfix.log"
|
||||
|
||||
# Virtual mailboxes
|
||||
postconf -e "mailbox_transport = lmtp:unix:private/dovecot-lmtp"
|
||||
postconf -e "smtputf8_enable = no"
|
||||
|
||||
postconf -e "virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/virtual_domains_maps.cf"
|
||||
postconf -e "virtual_mailbox_maps = proxy:mysql:/etc/postfix/sql/virtual_mailbox_maps.cf, proxy:mysql:/etc/postfix/sql/virtual_alias_domain_mailbox_maps.cf"
|
||||
postconf -e "virtual_alias_maps = proxy:mysql:/etc/postfix/sql/virtual_alias_maps.cf, proxy:mysql:/etc/postfix/sql/virtual_alias_domain_maps.cf, proxy:mysql:/etc/postfix/sql/virtual_alias_domain_catchall_maps.cf"
|
||||
|
||||
postconf -e "virtual_transport = lmtp:unix:private/dovecot-lmtp"
|
||||
|
||||
postconf -e "virtual_mailbox_base = /var/vmail"
|
||||
postconf -e "virtual_uid_maps = static:600"
|
||||
postconf -e "virtual_gid_maps = static:600"
|
||||
postconf -e "virtual_minimum_uid = 600"
|
||||
postconf -e "virtual_mailbox_limit = 0"
|
||||
|
||||
postconf -e "smtp_header_checks = pcre:/etc/postfix/smtp_header_checks"
|
||||
|
||||
# SPF and DKIM checks
|
||||
postconf -e "policy_time_limit = 3600"
|
||||
postconf -e "smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, check_policy_service unix:private/policy, check_client_access lmdb:/etc/postfix/rbl_override"
|
||||
|
||||
# Milter configuration
|
||||
postconf -e "milter_default_action = accept"
|
||||
postconf -e "milter_protocol = 6"
|
||||
postconf -e "smtpd_milters = local:opendkim/opendkim.sock, local:opendmarc/opendmarc.sock"
|
||||
postconf -e 'non_smtpd_milters = $smtpd_milters'
|
||||
|
||||
# Blocking spam
|
||||
postconf -e "smtpd_sender_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unknown_sender_domain, reject_unknown_reverse_client_hostname, reject_unknown_client_hostname"
|
||||
postconf -e "smtpd_helo_required = yes"
|
||||
postconf -e "smtpd_helo_restrictions =, permit_mynetworks, permit_sasl_authenticated, check_helo_access lmdb:/etc/postfix/helo_access, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_unknown_helo_hostname"
|
||||
|
||||
# Postscreen spambots
|
||||
postconf -e "postscreen_access_list = permit_mynetworks cidr:/etc/postfix/postscreen_access.cidr cidr:/etc/postfix/postscreen_spf_whitelist.cidr"
|
||||
postconf -e "postscreen_blacklist_action = drop"
|
||||
|
||||
postconf -e "postscreen_greet_action = enforce"
|
||||
|
||||
postconf -e "postscreen_dnsbl_threshold = 3"
|
||||
postconf -e "postscreen_dnsbl_action = enforce"
|
||||
postconf -e "postscreen_dnsbl_sites = zen.spamhaus.org*3, bl.spameatingmonkey.net*2, bl.spamcop.net, dnsbl.sorbs.net"
|
||||
|
||||
postconf -e "postscreen_dnsbl_whitelist_threshold = -2"
|
||||
|
||||
postconf -e "header_checks = pcre:/etc/postfix/header_checks"
|
||||
postconf -e "body_checks = pcre:/etc/postfix/body_checks"
|
||||
|
||||
# master.cf
|
||||
sed -e 's/^smtp .*smtpd$/# &/' \
|
||||
-e '/#smtp\|#smtpd\|#dnsblog\|#tlsproxy/ s/^#//' -i /etc/postfix/master.cf
|
||||
tee -a /etc/postfix/master.cf >/dev/null <<- 'master.cf'
|
||||
|
||||
# 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
|
||||
policy unix - n n - 0 spawn
|
||||
user=nobody argv=/usr/bin/postfix-policyd-spf-perl
|
||||
master.cf
|
||||
|
||||
# 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:.*<>/ 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
|
||||
|
||||
# Whitelist localhost
|
||||
tee /etc/postfix/postscreen_access.cidr >/dev/null <<- postscreen_access.cidr
|
||||
# Permit my own IP addresses
|
||||
{{LOCAL_IPADDRESS}}/32 permit
|
||||
postscreen_access.cidr
|
||||
|
||||
# Touch aliases db
|
||||
newaliases
|
||||
|
||||
###############
|
||||
#//
|
||||
#// Dovecot
|
||||
#//
|
||||
###############
|
||||
# dovecot.conf
|
||||
tee -a /etc/dovecot/dovecot.conf >/dev/null <<- dovecot.conf
|
||||
|
||||
!include_try ssl-keys.conf
|
||||
protocols = imap lmtp
|
||||
dovecot.conf
|
||||
|
||||
# Logging
|
||||
echo "log_path = /var/log/dovecot.log" >/etc/dovecot/conf.d/10-logging.conf
|
||||
|
||||
# 10-auth.conf
|
||||
sed '/include auth-sql.conf.ext\|disable_plaintext_auth =\|auth_username_format =\|auth_mechanisms =\|auth_default_realm =\|include auth-system.conf.ext/d' \
|
||||
-i /etc/dovecot/conf.d/10-auth.conf
|
||||
tee -a /etc/dovecot/conf.d/10-auth.conf >/dev/null <<- '10-auth.conf'
|
||||
|
||||
!include auth-sql.conf.ext
|
||||
disable_plaintext_auth = yes
|
||||
auth_username_format = %Lu
|
||||
auth_mechanisms = plain login
|
||||
auth_default_realm = {{MYVEMAIL_DOMAIN}}
|
||||
|
||||
auth_debug = yes
|
||||
auth_debug_passwords = yes
|
||||
10-auth.conf
|
||||
|
||||
# dovecot-sql.conf.ext
|
||||
tee -a /etc/dovecot/dovecot-sql.conf.ext >/dev/null <<- 'dovecot'
|
||||
|
||||
# Virtual mailboxes
|
||||
driver = mysql
|
||||
connect = host=localhost dbname={{MYVEMAIL_POSTFIXADMIN_DBNAME}} user={{MYVEMAIL_POSTFIXADMIN_DBUSER}} password={{MYVEMAIL_POSTFIXADMIN_DBPASS}}
|
||||
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
|
||||
dovecot
|
||||
|
||||
# 10-mail.conf
|
||||
sed '/mail_location =\|mail_home =\|mail_privileged_group =/d' \
|
||||
-i /etc/dovecot/conf.d/10-mail.conf
|
||||
tee -a /etc/dovecot/conf.d/10-mail.conf >/dev/null <<- '10-mail.conf'
|
||||
|
||||
mail_privileged_group = mail
|
||||
mail_location = maildir:~/Maildir
|
||||
mail_home = /var/vmail/%d/%n/
|
||||
10-mail.conf
|
||||
|
||||
# 10-master.conf
|
||||
sed -e 's|unix_listener lmtp {|unix_listener /var/spool/postfix/private/dovecot-lmtp {\
|
||||
mode = 0600\
|
||||
user = postfix\
|
||||
group = postfix|' \
|
||||
-e 's|unix_listener auth-userdb {|unix_listener /var/spool/postfix/private/auth {\
|
||||
mode = 0660\
|
||||
user = postfix\
|
||||
group = postfix|' \
|
||||
-i /etc/dovecot/conf.d/10-master.conf
|
||||
|
||||
# 10-ssl.conf
|
||||
rm -f /etc/ssl/dovecot/*
|
||||
install -m 0600 /dev/stdin /etc/dovecot/ssl-keys.conf <<- ssl-keys.conf
|
||||
ssl_dh = </etc/ssl/dovecot/dh.pem
|
||||
ssl_cert = </etc/ssl/dovecot/tls.pem
|
||||
ssl_key = </etc/ssl/dovecot/tls.key
|
||||
ssl-keys.conf
|
||||
sed '/ssl_dh =\|ssl_cert =\|ssl_key\|ssl =\|ssl_prefer_server_ciphers =\|ssl_min_protocol =/d' -i /etc/dovecot/conf.d/10-ssl.conf
|
||||
tee -a /etc/dovecot/conf.d/10-ssl.conf >/dev/null <<- '10-ssl.conf'
|
||||
|
||||
ssl = required
|
||||
ssl_prefer_server_ciphers = yes
|
||||
ssl_min_protocol = TLSv1.2
|
||||
10-ssl.conf
|
||||
|
||||
# Stats service
|
||||
tee -a /etc/dovecot/conf.d/10-master.conf >/dev/null <<- 10-master.conf
|
||||
|
||||
service stats {
|
||||
unix_listener stats-reader {
|
||||
user = ${MYVEMAIL_NGINX_USERGROUP}
|
||||
group = ${MYVEMAIL_NGINX_USERGROUP}
|
||||
mode = 0660
|
||||
}
|
||||
|
||||
unix_listener stats-writer {
|
||||
user = ${MYVEMAIL_NGINX_USERGROUP}
|
||||
group = ${MYVEMAIL_NGINX_USERGROUP}
|
||||
mode = 0660
|
||||
}
|
||||
}
|
||||
10-master.conf
|
||||
|
||||
# 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
|
||||
|
||||
# Virtual mailboxes
|
||||
install -m 0640 /dev/stdin /etc/postfix/sql/virtual_domains_maps.cf <<- eof
|
||||
hosts = localhost
|
||||
dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}}
|
||||
user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}}
|
||||
password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}}
|
||||
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
|
||||
|
||||
install -m 0640 /dev/stdin /etc/postfix/sql/virtual_mailbox_maps.cf <<- eof
|
||||
hosts = localhost
|
||||
dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}}
|
||||
user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}}
|
||||
password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}}
|
||||
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'
|
||||
#expansion_limit = 100
|
||||
eof
|
||||
|
||||
install -m 0640 /dev/stdin /etc/postfix/sql/virtual_alias_domain_mailbox_maps.cf <<- eof
|
||||
hosts = localhost
|
||||
dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}}
|
||||
user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}}
|
||||
password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}}
|
||||
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
|
||||
|
||||
install -m 0640 /dev/stdin /etc/postfix/sql/virtual_alias_maps.cf <<- eof
|
||||
hosts = localhost
|
||||
dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}}
|
||||
user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}}
|
||||
password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}}
|
||||
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
|
||||
#expansion_limit = 100
|
||||
eof
|
||||
|
||||
install -m 0640 /dev/stdin /etc/postfix/sql/virtual_alias_domain_maps.cf <<- eof
|
||||
hosts = localhost
|
||||
dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}}
|
||||
user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}}
|
||||
password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}}
|
||||
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
|
||||
|
||||
install -m 0640 /dev/stdin /etc/postfix/sql/virtual_alias_domain_catchall_maps.cf <<- eof
|
||||
# handles catch-all settings of target-domain
|
||||
hosts = localhost
|
||||
dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}}
|
||||
user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}}
|
||||
password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}}
|
||||
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
|
||||
|
||||
###############
|
||||
#//
|
||||
#// OpenDKIM
|
||||
#//
|
||||
###############
|
||||
# sed -i 's\^SOCKET=local:$RUNDIR/opendkim.sock\SOCKET="local:/var/spool/postfix/opendkim/opendkim.sock"\' /etc/default/opendkim
|
||||
sed -i "/Canonicalization\|Mode\|SubDomains\|Socket\|SoftwareHeader\|UserID\|UMask/d" ${MYVEMAIL_OPENDKIM_CONF}
|
||||
tee -a ${MYVEMAIL_OPENDKIM_CONF} >/dev/null <<- 'opendkim.conf'
|
||||
|
||||
Canonicalization relaxed/simple
|
||||
Mode sv
|
||||
SubDomains no
|
||||
Socket local:/var/spool/postfix/opendkim/opendkim.sock
|
||||
SoftwareHeader yes
|
||||
|
||||
UserID opendkim
|
||||
UMask 007
|
||||
|
||||
# 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
|
||||
opendkim.conf
|
||||
|
||||
# trusted.hosts
|
||||
cat >/etc/opendkim/trusted.hosts <<- trusted.hosts
|
||||
127.0.0.1
|
||||
localhost
|
||||
|
||||
trusted.hosts
|
||||
|
||||
###############
|
||||
#//
|
||||
#// OpenDMARC
|
||||
#//
|
||||
###############
|
||||
sed '/TrustedAuthservIDs\|AuthservID\|RejectFailures\|IgnoreAuthenticatedClients\|RequiredHeaders\|SPFSelfValidate\|Socket\|IgnoreHosts\|UMask\|UserID/d' \
|
||||
-i ${MYVEMAIL_OPENDMARC_CONF}
|
||||
|
||||
tee -a ${MYVEMAIL_OPENDMARC_CONF} >/dev/null <<- 'opendmarc.conf'
|
||||
|
||||
TrustedAuthservIDs {{HOSTNAME}}
|
||||
AuthservID OpenDMARC
|
||||
RejectFailures true
|
||||
IgnoreAuthenticatedClients true
|
||||
RequiredHeaders true
|
||||
SPFSelfValidate true
|
||||
|
||||
Socket local:/var/spool/postfix/opendmarc/opendmarc.sock
|
||||
IgnoreHosts /etc/opendmarc/ignore.hosts
|
||||
|
||||
UserID opendmarc
|
||||
UMask 0002
|
||||
opendmarc.conf
|
||||
|
||||
echo '127.0.0.1' | tee -a /etc/opendmarc/ignore.hosts >/dev/null
|
||||
|
||||
###############
|
||||
#//
|
||||
#// Nginx
|
||||
#//
|
||||
###############
|
||||
# php-fpm sock
|
||||
cat >$(find /etc/php* -type d \( -name "pool.d" -o -name "php-fpm.d" \))/zz-listen.conf <<- php-fpm.sock
|
||||
listen = 127.0.0.1:9000
|
||||
user = ${MYVEMAIL_NGINX_USERGROUP}
|
||||
group = ${MYVEMAIL_NGINX_USERGROUP}
|
||||
listen.owner = ${MYVEMAIL_NGINX_USERGROUP}
|
||||
listen.group = ${MYVEMAIL_NGINX_USERGROUP}
|
||||
listen.mode = 0660
|
||||
php-fpm.sock
|
||||
|
||||
# proxy_params
|
||||
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
|
||||
|
||||
# Roundcube/Postfixadmin virtual proxy
|
||||
tee $(find /etc/nginx -type f -name "default*") >/dev/null <<- 'nginx'
|
||||
upstream php-handler {
|
||||
server 127.0.0.1:9000;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80 default_server;
|
||||
server_name _;
|
||||
|
||||
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$ {
|
||||
client_max_body_size 0;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
nginx
|
||||
|
||||
###############
|
||||
#//
|
||||
#// 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
|
||||
511
build/run/installer-ubuntu.sh
Executable file
511
build/run/installer-ubuntu.sh
Executable file
|
|
@ -0,0 +1,511 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
###############
|
||||
#//
|
||||
#// Ubuntu specific
|
||||
#//
|
||||
###############
|
||||
# Update and install
|
||||
apt remove -y nano* exim*
|
||||
apt update
|
||||
apt upgrade -y
|
||||
apt dist-upgrade -y
|
||||
debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Internet Site'"
|
||||
apt install -y \
|
||||
ca-certificates \
|
||||
git wget bind9-host acl dbconfig-no-thanks \
|
||||
rsyslog \
|
||||
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
|
||||
apt autoremove -y
|
||||
apt clean
|
||||
rm -r -f /var/lib/apt/lists
|
||||
|
||||
# Create vmail user
|
||||
adduser vmail --system --group --uid 600 --disabled-login --home /var/vmail/ --quiet
|
||||
|
||||
###############
|
||||
#//
|
||||
#// Users and directories
|
||||
#//
|
||||
###############
|
||||
# Add users to groups
|
||||
adduser dovecot mail >/dev/null
|
||||
adduser ${MYVEMAIL_NGINX_USERGROUP} dovecot >/dev/null
|
||||
adduser postfix opendkim >/dev/null
|
||||
|
||||
# Virtual mailboxes
|
||||
mkdir /etc/postfix/sql
|
||||
|
||||
# MariaDB
|
||||
install -m 1777 -d /run/mysqld
|
||||
|
||||
# DKIM/DMARC
|
||||
mkdir /{run,etc}/{opendkim,opendmarc}
|
||||
install -o opendkim -g postfix -d /var/spool/postfix/opendkim/
|
||||
install -m 750 -o opendmarc -g postfix -d /var/spool/postfix/opendmarc/
|
||||
|
||||
###############
|
||||
#//
|
||||
#// PHP
|
||||
#//
|
||||
###############
|
||||
sed -e '/upload_max_filesize =/c upload_max_filesize = 0' \
|
||||
-e '/post_max_size =/c post_max_size = 0' \
|
||||
-e '/memory_limit =/c memory_limit = 4096M' \
|
||||
-i $(find /etc/php*/ -name 'php.ini')
|
||||
|
||||
###############
|
||||
#//
|
||||
#// Postfix
|
||||
#//
|
||||
###############
|
||||
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,${MYVEMAIL_NGINX_USERGROUP}"
|
||||
|
||||
postconf -e 'smtpd_tls_session_cache_database = lmdb:${data_directory}/smtpd_scache'
|
||||
postconf -e 'smtp_tls_session_cache_database = lmdb:${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 'myorigin = $mydomain'
|
||||
postconf -e 'mydestination = $myhostname, localhost.$mydomain, localhost'
|
||||
|
||||
postconf -e "smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt"
|
||||
postconf -e "smtpd_tls_key_file = /etc/ssl/dovecot/tls.key"
|
||||
postconf -e "smtpd_tls_cert_file = /etc/ssl/dovecot/tls.pem"
|
||||
|
||||
# Enforce TLSv1.2 or TLSv1.2
|
||||
postconf -e "smtpd_tls_mandatory_protocols = >=TLSv1.2"
|
||||
postconf -e "smtp_tls_mandatory_protocols = >=TLSv1.2"
|
||||
postconf -e "smtpd_tls_protocols = >=TLSv1.2"
|
||||
postconf -e "smtp_tls_protocols = >=TLSv1.2"
|
||||
|
||||
# Logging
|
||||
postconf -e "maillog_file = /var/log/postfix.log"
|
||||
|
||||
# Virtual mailboxes
|
||||
postconf -e "mailbox_transport = lmtp:unix:private/dovecot-lmtp"
|
||||
postconf -e "smtputf8_enable = no"
|
||||
|
||||
postconf -e "virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/virtual_domains_maps.cf"
|
||||
postconf -e "virtual_mailbox_maps = proxy:mysql:/etc/postfix/sql/virtual_mailbox_maps.cf, proxy:mysql:/etc/postfix/sql/virtual_alias_domain_mailbox_maps.cf"
|
||||
postconf -e "virtual_alias_maps = proxy:mysql:/etc/postfix/sql/virtual_alias_maps.cf, proxy:mysql:/etc/postfix/sql/virtual_alias_domain_maps.cf, proxy:mysql:/etc/postfix/sql/virtual_alias_domain_catchall_maps.cf"
|
||||
|
||||
postconf -e "virtual_transport = lmtp:unix:private/dovecot-lmtp"
|
||||
|
||||
postconf -e "virtual_mailbox_base = /var/vmail"
|
||||
postconf -e "virtual_uid_maps = static:600"
|
||||
postconf -e "virtual_gid_maps = static:600"
|
||||
postconf -e "virtual_minimum_uid = 600"
|
||||
postconf -e "virtual_mailbox_limit = 0"
|
||||
|
||||
postconf -e "smtp_header_checks = pcre:/etc/postfix/smtp_header_checks"
|
||||
|
||||
# SPF and DKIM checks
|
||||
postconf -e "policy_time_limit = 3600"
|
||||
postconf -e "smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, check_policy_service unix:private/policy, check_client_access lmdb:/etc/postfix/rbl_override"
|
||||
|
||||
# Milter configuration
|
||||
postconf -e "milter_default_action = accept"
|
||||
postconf -e "milter_protocol = 6"
|
||||
postconf -e "smtpd_milters = local:opendkim/opendkim.sock, local:opendmarc/opendmarc.sock"
|
||||
postconf -e 'non_smtpd_milters = $smtpd_milters'
|
||||
|
||||
# Blocking spam
|
||||
postconf -e "smtpd_sender_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unknown_sender_domain, reject_unknown_reverse_client_hostname, reject_unknown_client_hostname"
|
||||
postconf -e "smtpd_helo_required = yes"
|
||||
postconf -e "smtpd_helo_restrictions =, permit_mynetworks, permit_sasl_authenticated, check_helo_access lmdb:/etc/postfix/helo_access, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_unknown_helo_hostname"
|
||||
|
||||
# Postscreen spambots
|
||||
postconf -e "postscreen_access_list = permit_mynetworks cidr:/etc/postfix/postscreen_access.cidr cidr:/etc/postfix/postscreen_spf_whitelist.cidr"
|
||||
postconf -e "postscreen_blacklist_action = drop"
|
||||
|
||||
postconf -e "postscreen_greet_action = enforce"
|
||||
|
||||
postconf -e "postscreen_dnsbl_threshold = 3"
|
||||
postconf -e "postscreen_dnsbl_action = enforce"
|
||||
postconf -e "postscreen_dnsbl_sites = zen.spamhaus.org*3, bl.spameatingmonkey.net*2, bl.spamcop.net, dnsbl.sorbs.net"
|
||||
|
||||
postconf -e "postscreen_dnsbl_whitelist_threshold = -2"
|
||||
|
||||
postconf -e "header_checks = pcre:/etc/postfix/header_checks"
|
||||
postconf -e "body_checks = pcre:/etc/postfix/body_checks"
|
||||
|
||||
# master.cf
|
||||
sed -e 's/^smtp .*smtpd$/# &/' \
|
||||
-e '/#smtp\|#smtpd\|#dnsblog\|#tlsproxy/ s/^#//' -i /etc/postfix/master.cf
|
||||
tee -a /etc/postfix/master.cf >/dev/null <<- 'master.cf'
|
||||
|
||||
# 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
|
||||
policy unix - n n - 0 spawn
|
||||
user=nobody argv=/usr/bin/postfix-policyd-spf-perl
|
||||
master.cf
|
||||
|
||||
# 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:.*<>/ 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
|
||||
|
||||
# Whitelist localhost
|
||||
tee /etc/postfix/postscreen_access.cidr >/dev/null <<- postscreen_access.cidr
|
||||
# Permit my own IP addresses
|
||||
{{LOCAL_IPADDRESS}}/32 permit
|
||||
postscreen_access.cidr
|
||||
|
||||
# Touch aliases db
|
||||
newaliases
|
||||
|
||||
###############
|
||||
#//
|
||||
#// Dovecot
|
||||
#//
|
||||
###############
|
||||
# dovecot.conf
|
||||
tee -a /etc/dovecot/dovecot.conf >/dev/null <<- dovecot.conf
|
||||
|
||||
!include_try ssl-keys.conf
|
||||
protocols = imap lmtp
|
||||
dovecot.conf
|
||||
|
||||
# Logging
|
||||
echo "log_path = /var/log/dovecot.log" >/etc/dovecot/conf.d/10-logging.conf
|
||||
|
||||
# 10-auth.conf
|
||||
sed '/include auth-sql.conf.ext\|disable_plaintext_auth =\|auth_username_format =\|auth_mechanisms =\|auth_default_realm =\|include auth-system.conf.ext/d' \
|
||||
-i /etc/dovecot/conf.d/10-auth.conf
|
||||
tee -a /etc/dovecot/conf.d/10-auth.conf >/dev/null <<- '10-auth.conf'
|
||||
|
||||
!include auth-sql.conf.ext
|
||||
disable_plaintext_auth = yes
|
||||
auth_username_format = %Lu
|
||||
auth_mechanisms = plain login
|
||||
auth_default_realm = {{MYVEMAIL_DOMAIN}}
|
||||
|
||||
auth_debug = yes
|
||||
auth_debug_passwords = yes
|
||||
10-auth.conf
|
||||
|
||||
# dovecot-sql.conf.ext
|
||||
tee -a /etc/dovecot/dovecot-sql.conf.ext >/dev/null <<- 'dovecot'
|
||||
|
||||
# Virtual mailboxes
|
||||
driver = mysql
|
||||
connect = host=localhost dbname={{MYVEMAIL_POSTFIXADMIN_DBNAME}} user={{MYVEMAIL_POSTFIXADMIN_DBUSER}} password={{MYVEMAIL_POSTFIXADMIN_DBPASS}}
|
||||
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
|
||||
dovecot
|
||||
|
||||
# 10-mail.conf
|
||||
sed '/mail_location =\|mail_home =\|mail_privileged_group =/d' \
|
||||
-i /etc/dovecot/conf.d/10-mail.conf
|
||||
tee -a /etc/dovecot/conf.d/10-mail.conf >/dev/null <<- '10-mail.conf'
|
||||
|
||||
mail_privileged_group = mail
|
||||
mail_location = maildir:~/Maildir
|
||||
mail_home = /var/vmail/%d/%n/
|
||||
10-mail.conf
|
||||
|
||||
# 10-master.conf
|
||||
sed -e 's|unix_listener lmtp {|unix_listener /var/spool/postfix/private/dovecot-lmtp {\
|
||||
mode = 0600\
|
||||
user = postfix\
|
||||
group = postfix|' \
|
||||
-e 's|unix_listener auth-userdb {|unix_listener /var/spool/postfix/private/auth {\
|
||||
mode = 0660\
|
||||
user = postfix\
|
||||
group = postfix|' \
|
||||
-i /etc/dovecot/conf.d/10-master.conf
|
||||
|
||||
# 10-ssl.conf
|
||||
rm -f /etc/ssl/dovecot/*
|
||||
install -m 0600 /dev/stdin /etc/dovecot/ssl-keys.conf <<- ssl-keys.conf
|
||||
ssl_dh = </etc/ssl/dovecot/dh.pem
|
||||
ssl_cert = </etc/ssl/dovecot/tls.pem
|
||||
ssl_key = </etc/ssl/dovecot/tls.key
|
||||
ssl-keys.conf
|
||||
sed '/ssl_dh =\|ssl_cert =\|ssl_key\|ssl =\|ssl_prefer_server_ciphers =\|ssl_min_protocol =/d' -i /etc/dovecot/conf.d/10-ssl.conf
|
||||
tee -a /etc/dovecot/conf.d/10-ssl.conf >/dev/null <<- '10-ssl.conf'
|
||||
|
||||
ssl = required
|
||||
ssl_prefer_server_ciphers = yes
|
||||
ssl_min_protocol = TLSv1.2
|
||||
10-ssl.conf
|
||||
|
||||
# Stats service
|
||||
tee -a /etc/dovecot/conf.d/10-master.conf >/dev/null <<- 10-master.conf
|
||||
|
||||
service stats {
|
||||
unix_listener stats-reader {
|
||||
user = ${MYVEMAIL_NGINX_USERGROUP}
|
||||
group = ${MYVEMAIL_NGINX_USERGROUP}
|
||||
mode = 0660
|
||||
}
|
||||
|
||||
unix_listener stats-writer {
|
||||
user = ${MYVEMAIL_NGINX_USERGROUP}
|
||||
group = ${MYVEMAIL_NGINX_USERGROUP}
|
||||
mode = 0660
|
||||
}
|
||||
}
|
||||
10-master.conf
|
||||
|
||||
# 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
|
||||
|
||||
# Virtual mailboxes
|
||||
install -m 0640 /dev/stdin /etc/postfix/sql/virtual_domains_maps.cf <<- eof
|
||||
hosts = localhost
|
||||
dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}}
|
||||
user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}}
|
||||
password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}}
|
||||
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
|
||||
|
||||
install -m 0640 /dev/stdin /etc/postfix/sql/virtual_mailbox_maps.cf <<- eof
|
||||
hosts = localhost
|
||||
dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}}
|
||||
user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}}
|
||||
password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}}
|
||||
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'
|
||||
#expansion_limit = 100
|
||||
eof
|
||||
|
||||
install -m 0640 /dev/stdin /etc/postfix/sql/virtual_alias_domain_mailbox_maps.cf <<- eof
|
||||
hosts = localhost
|
||||
dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}}
|
||||
user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}}
|
||||
password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}}
|
||||
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
|
||||
|
||||
install -m 0640 /dev/stdin /etc/postfix/sql/virtual_alias_maps.cf <<- eof
|
||||
hosts = localhost
|
||||
dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}}
|
||||
user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}}
|
||||
password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}}
|
||||
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
|
||||
#expansion_limit = 100
|
||||
eof
|
||||
|
||||
install -m 0640 /dev/stdin /etc/postfix/sql/virtual_alias_domain_maps.cf <<- eof
|
||||
hosts = localhost
|
||||
dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}}
|
||||
user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}}
|
||||
password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}}
|
||||
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
|
||||
|
||||
install -m 0640 /dev/stdin /etc/postfix/sql/virtual_alias_domain_catchall_maps.cf <<- eof
|
||||
# handles catch-all settings of target-domain
|
||||
hosts = localhost
|
||||
dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}}
|
||||
user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}}
|
||||
password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}}
|
||||
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
|
||||
|
||||
###############
|
||||
#//
|
||||
#// OpenDKIM
|
||||
#//
|
||||
###############
|
||||
# sed -i 's\^SOCKET=local:$RUNDIR/opendkim.sock\SOCKET="local:/var/spool/postfix/opendkim/opendkim.sock"\' /etc/default/opendkim
|
||||
sed -i "/Canonicalization\|Mode\|SubDomains\|Socket\|SoftwareHeader\|UserID\|UMask/d" ${MYVEMAIL_OPENDKIM_CONF}
|
||||
tee -a ${MYVEMAIL_OPENDKIM_CONF} >/dev/null <<- 'opendkim.conf'
|
||||
|
||||
Canonicalization relaxed/simple
|
||||
Mode sv
|
||||
SubDomains no
|
||||
Socket local:/var/spool/postfix/opendkim/opendkim.sock
|
||||
SoftwareHeader yes
|
||||
|
||||
UserID opendkim
|
||||
UMask 007
|
||||
|
||||
# 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
|
||||
opendkim.conf
|
||||
|
||||
# trusted.hosts
|
||||
cat >/etc/opendkim/trusted.hosts <<- trusted.hosts
|
||||
127.0.0.1
|
||||
localhost
|
||||
|
||||
trusted.hosts
|
||||
|
||||
###############
|
||||
#//
|
||||
#// OpenDMARC
|
||||
#//
|
||||
###############
|
||||
sed '/TrustedAuthservIDs\|AuthservID\|RejectFailures\|IgnoreAuthenticatedClients\|RequiredHeaders\|SPFSelfValidate\|Socket\|IgnoreHosts\|UMask\|UserID/d' \
|
||||
-i ${MYVEMAIL_OPENDMARC_CONF}
|
||||
|
||||
tee -a ${MYVEMAIL_OPENDMARC_CONF} >/dev/null <<- 'opendmarc.conf'
|
||||
|
||||
TrustedAuthservIDs {{HOSTNAME}}
|
||||
AuthservID OpenDMARC
|
||||
RejectFailures true
|
||||
IgnoreAuthenticatedClients true
|
||||
RequiredHeaders true
|
||||
SPFSelfValidate true
|
||||
|
||||
Socket local:/var/spool/postfix/opendmarc/opendmarc.sock
|
||||
IgnoreHosts /etc/opendmarc/ignore.hosts
|
||||
|
||||
UserID opendmarc
|
||||
UMask 0002
|
||||
opendmarc.conf
|
||||
|
||||
echo '127.0.0.1' | tee -a /etc/opendmarc/ignore.hosts >/dev/null
|
||||
|
||||
###############
|
||||
#//
|
||||
#// Nginx
|
||||
#//
|
||||
###############
|
||||
# php-fpm sock
|
||||
cat >$(find /etc/php* -type d \( -name "pool.d" -o -name "php-fpm.d" \))/zz-listen.conf <<- php-fpm.sock
|
||||
listen = 127.0.0.1:9000
|
||||
user = ${MYVEMAIL_NGINX_USERGROUP}
|
||||
group = ${MYVEMAIL_NGINX_USERGROUP}
|
||||
listen.owner = ${MYVEMAIL_NGINX_USERGROUP}
|
||||
listen.group = ${MYVEMAIL_NGINX_USERGROUP}
|
||||
listen.mode = 0660
|
||||
php-fpm.sock
|
||||
|
||||
# proxy_params
|
||||
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
|
||||
|
||||
# Roundcube/Postfixadmin virtual proxy
|
||||
tee $(find /etc/nginx -type f -name "default*") >/dev/null <<- 'nginx'
|
||||
upstream php-handler {
|
||||
server 127.0.0.1:9000;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80 default_server;
|
||||
server_name _;
|
||||
|
||||
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$ {
|
||||
client_max_body_size 0;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
nginx
|
||||
|
||||
###############
|
||||
#//
|
||||
#// 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
|
||||
51
docker-compose.yaml
Normal file
51
docker-compose.yaml
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
services:
|
||||
|
||||
myvemail:
|
||||
image: git.myvelabs.com/lab/myvemail:${MYVEMAIL_VERSION:-edge}
|
||||
container_name: myvemail
|
||||
restart: unless-stopped
|
||||
|
||||
# build: .
|
||||
|
||||
ports:
|
||||
- ${MYVEMAIL_PORT:-80}:80/tcp
|
||||
- 25:25/tcp
|
||||
- 587:587/tcp
|
||||
- 143:143/tcp
|
||||
- 993:993/tcp
|
||||
|
||||
environment:
|
||||
# Mail domain details
|
||||
MYVEMAIL_SUBDOMAIN: ${MYVEMAIL_SUBDOMAIN}
|
||||
MYVEMAIL_DOMAIN: ${MYVEMAIL_DOMAIN}
|
||||
|
||||
# Additional mail domains separated by commas
|
||||
MYVEMAIL_ADDMX: ${MYVEMAIL_ADDMX}
|
||||
|
||||
# Backup mail servers separated by commas
|
||||
MYVEMAIL_BACKUPMX: ${MYVEMAIL_BACKUPMX}
|
||||
|
||||
# Roundcube
|
||||
MYVEMAIL_ROUNDCUBE_DBNAME: ${MYVEMAIL_ROUNDCUBE_DBNAME:-roundcube}
|
||||
MYVEMAIL_ROUNDCUBE_DBUSER: ${MYVEMAIL_ROUNDCUBE_DBUSER:-roundcube}
|
||||
MYVEMAIL_ROUNDCUBE_DBPASS: ${MYVEMAIL_ROUNDCUBE_DBPASS:-roundcube}
|
||||
|
||||
# Postfixadmin
|
||||
MYVEMAIL_POSTFIXADMIN_DBNAME: ${MYVEMAIL_POSTFIXADMIN_DBNAME:-postfixadmin}
|
||||
MYVEMAIL_POSTFIXADMIN_DBUSER: ${MYVEMAIL_POSTFIXADMIN_DBUSER:-postfixadmin}
|
||||
MYVEMAIL_POSTFIXADMIN_DBPASS: ${MYVEMAIL_POSTFIXADMIN_DBPASS:-postfixadmin}
|
||||
|
||||
volumes:
|
||||
# Required
|
||||
- ${MYVEMAIL_VOLUME_MARIADB:-./data/sql}:/var/lib/mysql:Z
|
||||
- ${MYVEMAIL_VOLUME_DATA:-./data/webapps}:/usr/share/webapps
|
||||
- ${MYVEMAIL_VOLUME_MAIL:-./data/mail}:/var/vmail
|
||||
|
||||
# SSL (point to individual files in case symlinks are being used)
|
||||
- ${MYVEMAIL_VOLUME_SSL:-./data/ssl}/tls.key:/etc/ssl/dovecot/tls.key
|
||||
- ${MYVEMAIL_VOLUME_SSL:-./data/ssl}/tls.pem:/etc/ssl/dovecot/tls.pem
|
||||
- ${MYVEMAIL_VOLUME_SSL:-./data/ssl}/dh.pem:/etc/ssl/dovecot/dh.pem
|
||||
|
||||
# Optional
|
||||
- ${MYVEMAIL_VOLUME_DKIM:-./data/dkim}:/etc/opendkim/keys
|
||||
- ${MYVEMAIL_VOLUME_POSTWHITE:-./data/postwhite}:/etc/postfix/postscreen_spf_whitelist.cidr
|
||||
38
generate-env.sh
Executable file
38
generate-env.sh
Executable file
|
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/env bash
|
||||
cat >./.env <<- gen-env
|
||||
# Required
|
||||
# Mail domain
|
||||
MYVEMAIL_SUBDOMAIN=${SUBDOMAIN}
|
||||
MYVEMAIL_DOMAIN=${DOMAIN}
|
||||
|
||||
# Optional
|
||||
# Version: edge or stable
|
||||
MYVEMAIL_VERSION=edge
|
||||
|
||||
# Webmail port
|
||||
MYVEMAIL_PORT=${PORT}
|
||||
|
||||
# Additional mail domains separated by commas
|
||||
MYVEMAIL_ADDMX=
|
||||
|
||||
# Backup mail servers separated by commas
|
||||
MYVEMAIL_BACKUPMX=
|
||||
|
||||
# Volumes
|
||||
MYVEMAIL_VOLUME_MARIADB=
|
||||
MYVEMAIL_VOLUME_SSL=
|
||||
MYVEMAIL_VOLUME_DATA=
|
||||
MYVEMAIL_VOLUME_MAIL=
|
||||
MYVEMAIL_VOLUME_DKIM=
|
||||
MYVEMAIL_VOLUME_POSTWHITE=
|
||||
|
||||
# MariaDB
|
||||
# Roundcube
|
||||
MYVEMAIL_ROUNDCUBE_DBNAME=roundcube
|
||||
MYVEMAIL_ROUNDCUBE_DBUSER=roundcube
|
||||
MYVEMAIL_ROUNDCUBE_DBPASS=$(openssl rand -hex 32)
|
||||
# Postfixadmin
|
||||
MYVEMAIL_POSTFIXADMIN_DBNAME=postfixadmin
|
||||
MYVEMAIL_POSTFIXADMIN_DBUSER=postfixadmin
|
||||
MYVEMAIL_POSTFIXADMIN_DBPASS=$(openssl rand -hex 32)
|
||||
gen-env
|
||||
106
nginx-setup.sh
Executable file
106
nginx-setup.sh
Executable file
|
|
@ -0,0 +1,106 @@
|
|||
#!/usr/bin/env bash
|
||||
# Fill in the following variables
|
||||
appname= #google
|
||||
proxyurl= #http://webapps.kvm:4001
|
||||
domain= #www.google.com
|
||||
eff_email_address= #eff@eff.com
|
||||
|
||||
# Check privilege
|
||||
if [ $(id -u) -ne 0 ]
|
||||
then
|
||||
echo "This script must be run by root" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Variable check
|
||||
if [ -z ${appname} ] || [ -z ${proxyurl} ] || [ -z ${domain} ] || [ -z ${eff_email_address} ]
|
||||
then
|
||||
echo "Missing variable, exiting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Figure out nginx conf directory
|
||||
if grep -q 'include.*conf.d' /etc/nginx/nginx.conf
|
||||
then
|
||||
nginxdir=/etc/nginx/conf.d
|
||||
elif grep -q 'include.*sites-available' /etc/nginx/nginx.conf
|
||||
then
|
||||
nginxdir=/etc/nginx/sites-available
|
||||
ln -s -f /etc/nginx/sites-available/${appname}.conf /etc/nginx/sites-enabled/
|
||||
else
|
||||
echo "Missing nginx directory, exiting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Virtual proxy
|
||||
cat <<- 'proxy' | \
|
||||
sed -e "s|{{domain}}|${domain}|" \
|
||||
-e "s|{{proxyurl}}|${proxyurl}|" \
|
||||
-e "s|{{appname}}|${appname}|" | tee ${nginxdir}/${appname}.conf >/dev/null
|
||||
server {
|
||||
server_name {{domain}};
|
||||
|
||||
location / {
|
||||
proxy_pass {{proxyurl}};
|
||||
error_log /var/log/nginx/{{appname}}_error.log;
|
||||
access_log /var/log/nginx/{{appname}}_access.log;
|
||||
|
||||
# proxy_params;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
proxy_set_header X-Forwarded-Scheme $scheme;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header Accept-Encoding "";
|
||||
proxy_set_header Host $host;
|
||||
|
||||
client_body_buffer_size 512k;
|
||||
proxy_read_timeout 86400s;
|
||||
client_max_body_size 0;
|
||||
|
||||
# Websocket
|
||||
proxy_http_version 1.1;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
|
||||
# http_upgrade
|
||||
# Security
|
||||
server_tokens off;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "strict-origin" always;
|
||||
add_header X-Permitted-Cross-Domain-Policies "none" always;
|
||||
add_header X-Robots-Tag "noindex, nofollow" always;
|
||||
# add_header Content-Security-Policy "default-src 'self';" always;
|
||||
|
||||
# http2
|
||||
http2 on;
|
||||
|
||||
# http3
|
||||
listen 443 quic;
|
||||
add_header Alt-Svc 'h3=":443"; ma=86400';
|
||||
quic_retry on;
|
||||
http3 on;
|
||||
|
||||
# Certbot defaults
|
||||
listen 443 ssl;
|
||||
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||||
add_header Strict-Transport-Security "max-age=31536000" always;
|
||||
}
|
||||
proxy
|
||||
|
||||
# Run certbot
|
||||
if nginx -t
|
||||
then
|
||||
certbot --nginx --non-interactive --agree-tos --no-eff-email -m ${eff_email_address} -d ${domain} \
|
||||
--staple-ocsp --hsts --no-redirect --renew-hook 'docker exec --interactive --tty myvemail /bin/ash -c "dovecot reload; postfix reload"'
|
||||
|
||||
# Link certificates
|
||||
ln -s /etc/letsencrypt/live/${domain}/fullchain.pem ./data/ssl/tls.pem
|
||||
ln -s /etc/letsencrypt/live/${domain}/privkey.pem ./data/ssl/tls.key
|
||||
fi
|
||||
Loading…
Add table
Add a link
Reference in a new issue