From 365b1b54bd0478092323e36efc8a0291ffa6b635 Mon Sep 17 00:00:00 2001 From: Matt Simerson Date: Fri, 29 Mar 2024 22:03:34 -0700 Subject: [PATCH] mailman & wildduck (#576) - shell: add set -o vi - mt: add WILDDUCK_MAIL_DOMAIN & WILDDUCK_HOSTNAME - mailman: updates - wildduck: subsume zonemta and haraka into it --- include/shell.sh | 1 + mail-toaster.sh | 25 ++- provision/mailman.sh | 195 +++++++++++++++++ provision/wildduck.sh | 484 ++++++++++++++++++++++++++++++++++++++---- 4 files changed, 655 insertions(+), 50 deletions(-) create mode 100755 provision/mailman.sh diff --git a/include/shell.sh b/include/shell.sh index fa2fa5c0..85f2a756 100755 --- a/include/shell.sh +++ b/include/shell.sh @@ -51,6 +51,7 @@ export HISTIGNORE="&:[bf]g:exit" shopt -s histappend shopt -s cdspell +set -o vi if [[ $- == *i* ]] then diff --git a/mail-toaster.sh b/mail-toaster.sh index b4a193ff..88307607 100755 --- a/mail-toaster.sh +++ b/mail-toaster.sh @@ -163,7 +163,7 @@ export BOURNE_SHELL=${BOURNE_SHELL:="bash"} export JAIL_NET_PREFIX=${JAIL_NET_PREFIX:="172.16.15"} export JAIL_NET_MASK=${JAIL_NET_MASK:="/12"} export JAIL_NET_INTERFACE=${JAIL_NET_INTERFACE:="lo1"} -export JAIL_ORDERED_LIST="syslog base dns mysql clamav spamassassin dspam vpopmail haraka webmail munin haproxy rspamd avg dovecot redis geoip nginx mailtest apache postgres minecraft joomla php7 memcached sphinxsearch elasticsearch nictool sqwebmail dhcp letsencrypt tinydns roundcube squirrelmail rainloop rsnapshot mediawiki smf wordpress whmcs squirrelcart horde grafana unifi mongodb gitlab gitlab_runner dcc prometheus influxdb telegraf statsd mail_dmarc ghost jekyll borg nagios postfix puppeteer snappymail knot nsd bsd_cache wildduck zonemta centos ubuntu bhyve-ubuntu" +export JAIL_ORDERED_LIST="syslog base dns mysql clamav spamassassin dspam vpopmail haraka webmail munin haproxy rspamd avg dovecot redis geoip nginx mailtest apache postgres minecraft joomla php7 memcached sphinxsearch elasticsearch nictool sqwebmail dhcp letsencrypt tinydns roundcube squirrelmail rainloop rsnapshot mediawiki smf wordpress whmcs squirrelcart horde grafana unifi mongodb gitlab gitlab_runner dcc prometheus influxdb telegraf statsd mail_dmarc ghost jekyll borg nagios postfix puppeteer snappymail knot nsd bsd_cache wildduck zonemta centos ubuntu bhyve-ubuntu mailman" export ZFS_VOL=${ZFS_VOL:="zroot"} export ZFS_BHYVE_VOL="${ZFS_BHYVE_VOL:=$ZFS_VOL}" @@ -194,6 +194,8 @@ export ROUNDCUBE_SQL=${ROUNDCUBE_SQL:="$TOASTER_MYSQL"} export ROUNDCUBE_PRODUCT_NAME=${ROUNDCUBE_PRODUCT_NAME:="Roundcube Webmail"} export ROUNDCUBE_ATTACHMENT_SIZE_MB=${ROUNDCUBE_ATTACHMENT_SIZE_MB:="25"} export SQUIRREL_SQL=${SQUIRREL_SQL:="$TOASTER_MYSQL"} +export WILDDUCK_MAIL_DOMAIN=${WILDDUCK_MAIL_DOMAIN:="$TOASTER_MAIL_DOMAIN"} +export WILDDUCK_HOSTNAME=${WILDDUCK_HOSTNAME:="$TOASTER_HOSTNAME"} # shellcheck disable=2009,2317 if ps -o args= -p "$$" | grep csh; then @@ -1020,9 +1022,11 @@ unmount_data() get_public_facing_nic() { + local _ver=${1:-"ipv4"} + export PUBLIC_NIC - if [ "$1" = 'ipv6' ]; then + if [ "$_ver" = 'ipv6' ]; then PUBLIC_NIC=$(netstat -rn | grep default | awk '{ print $4 }' | tail -n1) else PUBLIC_NIC=$(netstat -rn | grep default | awk '{ print $4 }' | head -n1) @@ -1033,20 +1037,25 @@ get_public_facing_nic() echo "public NIC detection failed" exit 1 fi + + echo "$PUBLIC_NIC" } get_public_ip() { - get_public_facing_nic "$1" + local _ver=${1:-"ipv4"} + + get_public_facing_nic "$_ver" + + export PUBLIC_IP6 + export PUBLIC_IP4 - if [ "$1" = "ipv6" ]; then - if [ -n "$PUBLIC_IP6" ]; then return; fi - export PUBLIC_IP6 + if [ "$_ver" = "ipv6" ]; then PUBLIC_IP6=$(ifconfig "$PUBLIC_NIC" inet6 | grep inet | grep -v fe80 | awk '{print $2}' | head -n1) + echo "$PUBLIC_IP6" else - if [ -n "$PUBLIC_IP4" ]; then return; fi - export PUBLIC_IP4 PUBLIC_IP4=$(ifconfig "$PUBLIC_NIC" inet | grep inet | awk '{print $2}' | head -n1) + echo "$PUBLIC_IP4" fi } diff --git a/provision/mailman.sh b/provision/mailman.sh new file mode 100755 index 00000000..793fc86f --- /dev/null +++ b/provision/mailman.sh @@ -0,0 +1,195 @@ +#!/bin/sh + +. mail-toaster.sh || exit + +export JAIL_START_EXTRA="" +export JAIL_CONF_EXTRA="" + +_dkim_private_key="$ZFS_DATA_MNT/mailman/dkim/$TOASTER_MAIL_DOMAIN.private" +_has_dkim="" +if [ -f "$_dkim_private_key" ]; then _has_dkim=1; fi + +install_mailman() +{ + install_postfix + + tell_status "installing mailman" + stage_pkg_install py39-mailman sassc lynx nginx fcgiwrap || exit + stage_exec chown -R mailman /usr/local/mailman + stage_exec chpass -s /bin/sh mailman + + if [ -n "$TOASTER_NRPE" ]; then + tell_status "installing nagios-plugins" + stage_pkg_install nagios-plugins || exit + fi + + tell_status "installing mailman web" + stage_pkg_install py39-pip rust || exit + stage_exec pip install postorius hyperkitty mailman-hyperkitty whoosh mailmanclient mailman-web || exit + + _mmhk_pkg="mailman-hyperkitty-1.2.1.tar.gz" + if [ ! -d "$ZFS_DATA_MNT/$_mmhk_pkg" ]; then + tell_status "installing mailman-hyperkitty" + stage_exec fetch -o /data -m "https://files.pythonhosted.org/packages/41/77/352f7f8d1843cd7217d5dffce54fabdfdb403e78870db781c4859a8e9e35/$_mmhk_pkg" + stage_exec tar -C /data -xvf "/data/$_mmhk_pkg" + fi + + tell_status "installing hyperkitty" + tell_status "installing postorius" + tell_status "installing mailman-suite" +} + +install_postfix() +{ + tell_status "installing postfix" + stage_pkg_install postfix-sasl opendkim portconfig || exit +} + +configure_mailman() +{ + configure_opendkim + configure_postfix + + tell_status "configuring mailman" + stage_sysrc mailman_enable=YES + stage_sysrc nginx_enable=YES + stage_sysrc uwsgi_enable=YES + stage_sysrc uwsgi_socket_owner="www:mailman" + stage_sysrc fcgiwrap_enable=YES + stage_sysrc fcgiwrap_socket_owner=www + + _mm_etc="usr/local/mailman/etc" + if [ -f "$ZFS_JAIL_MNT/mailman/$_mm_etc/mailman.cfg" ]; then + tell_status "preserving /$_mm_etc/mailman.cfg" + cp "$ZFS_JAIL_MNT/mailman/$_mm_etc/mailman.cfg" "$STAGE_MNT/$_mm_etc/" + fi +} + +configure_opendkim() +{ + stage_sysrc milteropendkim_enable=YES + stage_sysrc milteropendkim_cfgfile=/data/etc/opendkim.conf + + tell_status "See http://www.opendkim.org/opendkim-README" + + if [ ! -d "$STAGE_MNT/data/etc" ]; then mkdir "$STAGE_MNT/data/etc"; fi + if [ ! -d "$STAGE_MNT/data/dkim" ]; then mkdir "$STAGE_MNT/data/dkim"; fi + + if [ -f "$STAGE_MNT/data/etc/opendkim.conf" ]; then + echo "opendkim config retained" + return + fi + + sed \ + -e "/^Domain/ s/example.com/$TOASTER_MAIL_DOMAIN/" \ + -e "/^KeyFile/ s/\/.*$/\/data\/dkim\/$TOASTER_MAIL_DOMAIN.private/" \ + -e '/^Socket/ s/inet:port@localhost/inet:8891/' \ + -e "/^Selector/ s/my-selector-name/$(date '+%b%Y' | tr '[:upper:]' '[:lower:]')/" \ + "$STAGE_MNT/usr/local/etc/mail/opendkim.conf.sample" \ + > "$STAGE_MNT/data/etc/opendkim.conf" +} + +configure_postfix() +{ + stage_sysrc postfix_enable=YES + stage_exec postconf -e "myhostname = mailman.$TOASTER_HOSTNAME" + stage_exec postconf -e 'smtp_tls_security_level = may' + stage_exec postconf -e "mynetworks = ${JAIL_NET_PREFIX}.0${JAIL_NET_MASK}" + stage_exec postconf -e 'owner_request_special=no' + stage_exec postconf -e 'transport_maps=hash:/usr/local/mailman/data/postfix_lmtp' + stage_exec postconf -e 'local_recipient_maps=hash:/usr/local/mailman/data/postfix_lmtp' + stage_exec postconf -e 'relay_domains=hash:/usr/local/mailman/data/postfix_domains' + + if [ -f "$ZFS_DATA_MNT/etc/sasl_passwd" ]; then + stage_exec postmap /data/etc/sasl_passwd + stage_exec postconf -e 'smtp_sasl_auth_enable = yes' + stage_exec postconf -e 'smtp_sasl_password_maps = hash:/data/etc/sasl_passwd' + fi + + if [ -n "$TOASTER_NRPE" ]; then + stage_sysrc nrpe3_enable=YES + stage_sysrc nrpe3_configfile="/data/etc/nrpe.cfg" + fi + + for _f in master main + do + if [ -f "$ZFS_DATA_MNT/postfix/etc/$_f.cf" ]; then + tell_status "preserving /usr/local/etc/postfix/$_f.cf" + cp "$ZFS_DATA_MNT/postfix/etc/$_f.cf" "$STAGE_MNT/usr/local/etc/postfix/" + fi + done + + if [ -f "$ZFS_JAIL_MNT/mailman/etc/aliases" ]; then + tell_status "preserving /etc/aliases" + cp "$ZFS_JAIL_MNT/mailman/etc/aliases" "$STAGE_MNT/etc/aliases" + stage_exec newaliases + fi + + if [ ! -f "$ZFS_JAIL_MNT/mailman/usr/local/etc/mail/mailer.conf" ]; then + if [ ! -d "$ZFS_JAIL_MNT/mailman/usr/local/etc/mail" ]; then + mkdir -p "$ZFS_JAIL_MNT/mailman/usr/local/etc/mail" + fi + stage_exec install -m 0644 /usr/local/share/postfix/mailer.conf.postfix /usr/local/etc/mail/mailer.conf + fi +} + +start_mailman() +{ + if [ -n "$_has_dkim" ]; then + stage_exec service milter-opendkim start + fi + + start_postfix + + tell_status "starting mailman" + stage_exec service fcgiwrap start || exit + stage_exec service nginx start || exit + stage_exec service mailman start || exit +} + +start_postfix() +{ + tell_status "starting postfix" + stage_exec service postfix start || exit +} + +test_mailman() +{ + tell_status "testing mailman" + stage_listening 8001 + echo "it worked." + + test_postfix + test_http +} + +test_http() +{ + tell_status "testing postfix" + stage_test_running master + stage_listening 25 + echo "it worked." +} + +test_postfix() +{ + if [ -n "$_has_dkim" ]; then + tell_status "testing opendkim" + stage_test_running opendkim + stage_listening 2016 + fi + + tell_status "testing postfix" + stage_test_running master + stage_listening 25 + echo "it worked." +} + +base_snapshot_exists || exit +create_staged_fs mailman +start_staged_jail mailman +install_mailman +configure_mailman +start_mailman +test_mailman +promote_staged_jail mailman diff --git a/provision/wildduck.sh b/provision/wildduck.sh index 6b0728be..750b2f9a 100755 --- a/provision/wildduck.sh +++ b/provision/wildduck.sh @@ -20,104 +20,491 @@ preflight_check() done } -install_webmail() -{ - if [ ! -e "$STAGE_MNT/data/webmail" ]; then - tell_status "installing wildduck webmail" - stage_exec bash -c "cd /data && git clone https://github.com/nodemailer/wildduck-webmail.git webmail" || exit 1 - stage_exec bash -c "cd /data/webmail && npm install" - stage_exec bash -c "cd /data/webmail && npm run bowerdeps" - else - tell_status "updating wildduck webmail" - stage_exec bash -c "cd /data/webmail && git pull && npm install && npm run bowerdeps" - stage_exec bash -c "cd /data/webmail && mkdir -p public/components" - stage_exec bash -c "cd /data/webmail && npx bower install --allow-root" - fi -} - install_wildduck() { tell_status "installing wildduck dependencies" stage_pkg_install npm-node20 git-tiny || exit - if [ ! -e "$STAGE_MNT/data/webmail" ]; then + if [ ! -e "$STAGE_MNT/data/wildduck" ]; then tell_status "installing wildduck" - stage_exec bash -c "cd /data && git clone https://github.com/nodemailer/wildduck.git" || exit 1 + stage_exec bash -c "cd /data && git clone https://github.com/nodemailer/wildduck.git wildduck" stage_exec bash -c "cd /data/wildduck && npm install --production" else tell_status "updating wildduck" stage_exec bash -c "cd /data/wildduck && git pull && npm install --production" fi +} + +install_wildduck_webmail() +{ + if [ ! -e "$STAGE_MNT/data/wildduck-webmail" ]; then + tell_status "installing wildduck webmail" + stage_exec bash -c "cd /data && git clone https://github.com/nodemailer/wildduck-webmail.git wildduck-webmail" + stage_exec bash -c "cd /data/wildduck-webmail && npm install" + stage_exec bash -c "cd /data/wildduck-webmail && npm run bowerdeps" + else + tell_status "updating wildduck webmail" + stage_exec bash -c "cd /data/wildduck-webmail && git pull && npm install && npm run bowerdeps" + stage_exec bash -c "cd /data/wildduck-webmail && mkdir -p public/components" + stage_exec bash -c "cd /data/wildduck-webmail && npx bower install --allow-root" + fi +} + +install_zonemta() +{ + _npm_ins="npm install --production --no-optional --no-package-lock --no-audit --ignore-scripts --no-shrinkwrap --progress=false --unsafe-perm" + + if [ ! -e "$STAGE_MNT/data/zone-mta" ]; then + tell_status "installing ZoneMTA" + stage_exec bash -c "cd /data && git clone https://github.com/zone-eu/zone-mta-template.git zone-mta" + stage_exec bash -c "cd /data/zone-mta/plugins && git clone https://github.com/nodemailer/zonemta-wildduck.git wildduck" + stage_exec bash -c "cd /data/zone-mta/plugins/wildduck && rm -f package-lock.json && $_npm_ins" + stage_exec bash -c "cd /data/zone-mta && $_npm_ins" + else + tell_status "updating ZoneMTA" + stage_exec bash -c "cd /data/zone-mta/plugins/wildduck && git pull && rm -f package-lock.json && $_npm_ins" + stage_exec bash -c "cd /data/zone-mta && git pull && $_npm_ins" + fi + + # stage_exec bash -c "cd /data/zone-mta && npm install zonemta-delivery-counters --save" +} + +install_zonemta_webadmin() +{ + tell_status "installing ZoneMTA webadmin" + if [ ! -e "$STAGE_MNT/data/zone-mta-admin" ]; then + stage_exec bash -c "cd /data && git clone https://github.com/zone-eu/zmta-webadmin.git zone-mta-admin" + stage_exec bash -c "cd /data/zone-mta-admin && npm install --production" + else + stage_exec bash -c "cd /data/zone-mta-admin && git pull && npm install --production" + fi +} + +install_haraka() +{ + local _npm_cmd="npm install --production --no-package-lock --no-audit --no-shrinkwrap" + + if [ ! -e "$STAGE_MNT/data/haraka" ]; then + tell_status "installing haraka" + stage_exec bash -c "cd /data && git clone https://github.com/haraka/Haraka.git haraka" + stage_exec bash -c "cd /data/haraka && $_npm_cmd" + else + tell_status "updating haraka" + stage_exec bash -c "cd /data/haraka && git pull && $_npm_cmd" + fi + + if [ ! -e "$STAGE_MNT/data/haraka/plugin/wildduck" ]; then + stage_exec bash -c "cd /data/haraka/plugin && git clone https://github.com/nodemailer/haraka-plugin-wildduck wildduck" + stage_exec bash -c "cd /data/haraka/plugin/wildduck && npm install --omit=dev --omit=optional" + fi +} + +install_pm2() +{ + stage_exec npm install -g pm2 + stage_exec pm2 startup + stage_sysrc pm2_toor_enable=YES +} + +configure_wildduck() +{ + local _cfg="$STAGE_MNT/data/wildduck/config" + + if grep -qE '^mongo.*127' "$_cfg/dbs.toml"; then + tell_status "configuring $_cfg/dbs.toml" + sed -i '' \ + -e "/^mongo/ s/127.0.0.1/$(get_jail_ip mongodb)/" \ + -e "/^#redis/ s/127.0.0.1/$(get_jail_ip redis)/; s|/3|/9|" \ + -e "/^host=/ s/127.0.0.1/$(get_jail_ip redis)/" \ + -e "/^db=3/ s/3/9/" \ + "$_cfg/dbs.toml" + + if [ -n "$WILDDUCK_MONGO_DSN" ]; then + sed -i '' \ + -e "/^mongo/ s|=.*$|=$WILDDUCK_MONGO_DSN|" \ + "$_cfg/dbs.toml" + fi + fi + + if [ ! -e "$_cfg/wildduck.toml" ]; then + tell_status "creating $_cfg/wildduck.toml" + sed \ + -e '/^#emailDomain/ s/^#//' \ + -e "/^emailDomain/ s/mydomain.info/$WILDDUCK_MAIL_DOMAIN/" \ + -e "/rpId/ s/example.com/$WILDDUCK_MAIL_DOMAIN/" \ + -e "/^hostname/ s/localhost/$WILDDUCK_HOSTNAME/" \ + -e '/^port/ s/2587/587/' \ + "$_cfg/default.toml" > "$_cfg/wildduck.toml" + fi + + if ! grep -q "$TOASTER_ORG_NAME" "$_cfg/api.toml"; then + tell_status "configuring $_cfg/api.toml" + sed -i '' \ + -e "/^organization/ s/WildDuck Mail Services/$TOASTER_ORG_NAME/" \ + "$_cfg/api.toml" + fi + + if ! grep -q "$WILDDUCK_HOSTNAME" "$_cfg/imap.toml"; then + tell_status "configuring $_cfg/imap.toml" + sed -i '' \ + -e '/^port/ s/9993/993/' \ + -e "/^#key=/ s/^#//; /^key=/ s|^.*$|/data/etc/tls/private/$WILDDUCK_HOSTNAME.pem|" \ + -e "/^#cert=/ s/^#//; /^cert=/ s|^.*$|/data/etc/tls/certs/$WILDDUCK_HOSTNAME.pem|" \ + -e "/^hostname/ s/localhost/$WILDDUCK_HOSTNAME/" \ + "$_cfg/imap.toml" + fi + + if ! grep -q "$WILDDUCK_HOSTNAME" "$_cfg/lmtp.toml"; then + tell_status "configuring $_cfg/lmtp.toml" + sed -i '' \ + -e '/^enabled/ s/false/true/' \ + -e '/^port/ s/2424/24/' \ + -e "/^#key=/ s/^#//; /^key=/ s|^.*$|/data/etc/tls/private/$WILDDUCK_HOSTNAME.pem|" \ + -e "/^#cert=/ s/^#//; /^cert=/ s|^.*$|/data/etc/tls/certs/$WILDDUCK_HOSTNAME.pem|" \ + -e "/^name/ s/false/\"$WILDDUCK_HOSTNAME\"/" \ + "$_cfg/lmtp.toml" + fi + + if ! grep -q "$WILDDUCK_HOSTNAME" "$_cfg/pop3.toml"; then + tell_status "configuring $_cfg/pop3.toml" + sed -i '' \ + -e '/^port/ s/9995/995/' \ + -e "/^#key=/ s/^#//; /^key=/ s|^.*$|/data/etc/tls/private/$WILDDUCK_HOSTNAME.pem|" \ + -e "/^#cert=/ s/^#//; /^cert=/ s|^.*$|/data/etc/tls/certs/$WILDDUCK_HOSTNAME.pem|" \ + -e "/^hostname/ s/localhost/$WILDDUCK_HOSTNAME/" \ + "$_cfg/pop3.toml" + fi + + if ! grep -q ^secret "$_cfg/dkim.toml"; then + tell_status "configuring $_cfg/dkim.toml" + echo "secret = \"$(get_random_pass 14)\"" >> "$_cfg/dkim.toml" + fi + + if ! grep -q "$WILDDUCK_HOSTNAME" "$_cfg/tls.toml"; then + tell_status "configuring $_cfg/tls.toml" + store_config "$_cfg/tls.toml" < "$_cfg/wildduck-webmail.toml" + fi +} + +configure_zonemta() +{ + tell_status "configure zonemta-wildduck" + local _cfg="$STAGE_MNT/data/zone-mta/config" + + if ! grep -q "$JAIL_NET_PREFIX" "$_cfg/dbs-production.toml"; then + tell_status "configuring $_cfg/dbs-production.toml" + sed -i '' \ + -e "/^mongo/ s/127.0.0.1/$(get_jail_ip mongodb)/" \ + -e "/^redis/ s/localhost/$(get_jail_ip redis)/; s|/2|/9|" \ + "$_cfg/dbs-production.toml" + + if [ -n "$ZONEMTA_MONGO_DSN" ]; then + sed -i '' \ + -e "/^mongo/ s|=.*$|=$ZONEMTA_MONGO_DSN|" \ + "$_cfg/dbs-production.toml" + fi + + echo "# @include \"/data/wildduck/config/dbs.toml\"" \ + >> "$_cfg/dbs-production.toml" + fi + + if ! grep -q "$JAIL_NET_PREFIX" "$_cfg/dbs-development.toml"; then + tell_status "configuring $_cfg/dbs-development.toml" + sed -i '' \ + -e "/^mongo/ s/127.0.0.1/$(get_jail_ip mongodb)/" \ + -e "/^host = / s/localhost/$(get_jail_ip redis)/" \ + "$_cfg/dbs-development.toml" + cat <> "$_cfg/interfaces/feeder.toml" +key="/data/etc/tls/private/$WILDDUCK_HOSTNAME.pem" +cert="/data/etc/tls/certs/$WILDDUCK_HOSTNAME.pem" +EO_ZONEMTA_TLS + fi + + tell_status "disabling DNS cache" + sed -i '' \ + -e '/^caching/ s/true/false/' \ + "$_cfg/dns.toml" - install_webmail + tell_status "configuring $_cfg/interfaces/feeder.toml" + sed -i '' \ + -e '/^host/ s/127.0.0.1/0.0.0.0/' \ + -e '/^port=/ s/2525/587/' \ + -e '/^authentication=/ s/false/true/' \ + "$_cfg/interfaces/feeder.toml" + + store_config "$_cfg/pools.toml" "overwrite" < port { 993 995 } -> \$int_ip4 -rdr inet6 proto tcp from any to port { 993 995 } -> \$int_ip6 +rdr inet proto tcp from any to port { 25 587 80 443 993 995 } -> \$int_ip4 +rdr inet6 proto tcp from any to port { 25 587 80 443 993 995 } -> \$int_ip6 EO_PF_RDR + get_public_ip + + store_config "$_pf_etc/nat.conf" < \$ext_ip4 +#nat on \$ext_if from \$int_ip6 to any -> \$ext_ip6 +EO_PF_NAT + store_config "$_pf_etc/allow.conf" < persist { \$int_ip4, \$int_ip6 } -pass in quick proto tcp from any to port { 3000 993 995 } -pass in quick proto tcp from any to port { 3000 993 995 } +pass in quick proto tcp from any to port { 25 587 80 443 993 995 } +pass in quick proto tcp from any to port { 25 587 80 443 993 995 } EO_PF_ALLOW } -configure_wildduck() +configure_haraka() { - _db_cfg="$STAGE_MNT/data/wildduck/config/dbs.toml" - if grep -qE '^mongo.*127' "$_db_cfg"; then - sed -i '' \ - -e "/^mongo/ s/127.0.0.1/$(get_jail_ip mongodb)/" \ - -e "/^#redis/ s/127.0.0.1/$(get_jail_ip redis)/; s/\/3/\/8/" \ - -e "/^host=/ s/127.0.0.1/$(get_jail_ip redis)/" \ - -e "/^db=3/ s/3/8/" \ - "$_db_cfg" - fi + tell_status "configuring Haraka" + local _cfg="$ZFS_DATA_MNT/wildduck/haraka/config" - stage_exec npm install -g pm2 - stage_exec pm2 startup + store_config "$_cfg/clamd.ini" < "$_cfg/me" + echo "local_mx_ok=true" >> "$_cfg/outbound.ini" + echo "wildduck" >> "$_cfg/plugins" + + sed -i '' \ + -e '/^#process_title/ s/#//' \ + -e '/^# fcrdns/ s/^# //' \ + -e '/^#early_talker/ s/^#//' \ + -e '/^# tls/ s/# //' \ + -e '/^rcpt_to.in_host_list/ s/^rcpt/#rcpt/' \ + -e '/^#attachment/ s/^#//' \ + -e '/^#clamd/ s/^#//' \ + -e '/^#spamassassin/ s/^#//' \ + -e '/^spamassassin/ a\ +rspamd' \ + -e '/^queue/ s/queue/#queue/' \ + "$_cfg/plugins" + + store_config "$_cfg/rspamd.ini" < "$_cfg/wildduck.yaml" + # -e "/secret: / s/secret value/$TODO/" \ + # -e "/loopSecret: / s/secret value/$TODO/" \ + fi } start_wildduck() { tell_status "starting wildduck" stage_exec service pm2_toor start - stage_exec bash -c 'cd /data/wildduck && NODE_ENV=production pm2 start "node server.js" -n wildduck' + stage_exec pm2 save +} + +start_wildduck_webmail() +{ + stage_exec bash -c 'cd /data/wildduck-webmail && NODE_ENV=production pm2 start "node server.js" -n wildduck-webmail' + stage_exec pm2 save +} + +start_zonemta() +{ + tell_status "starting zonemta" + stage_exec bash -c 'cd /data/zone-mta && NODE_ENV=production pm2 start "npm run start" -n zone-mta' + stage_exec pm2 save +} - stage_exec bash -c 'cd /data/webmail && NODE_ENV=production pm2 start "node server.js" -n webmail' +start_zonemta_webadmin() +{ + tell_status "starting zonemta webadmin" + stage_exec bash -c 'cd /data/zone-mta-admin && NODE_ENV=production pm2 start "npm run start" -n zone-mta-admin' + stage_exec pm2 save +} +start_haraka() +{ + tell_status "starting Haraka" + stage_exec bash -c 'cd /data/haraka && NODE_ENV=production pm2 start "/data/haraka/bin/haraka -c /data/haraka" -n haraka' stage_exec pm2 save } test_wildduck() { tell_status "testing wildduck" - stage_listening 9993 3 - stage_listening 9995 3 - stage_listening 3000 3 + stage_listening 24 3 + stage_listening 993 3 + stage_listening 995 3 - # MUA_TEST_USER="postmaster@${TOASTER_MAIL_DOMAIN}" + # MUA_TEST_USER="postmaster@${WILDDUCK_MAIL_DOMAIN}" # MUA_TEST_PASS=$(jexec vpopmail /usr/local/vpopmail/bin/vuserinfo -C "${MUA_TEST_USER}") # MUA_TEST_HOST=$(get_jail_ip stage) # test_imap # test_pop3 + + tell_status "testing wildduck API" + stage_listening 8080 3 + + tell_status "testing wildduck webmail" + stage_listening 3000 3 + + tell_status "testing ZoneMTA" + stage_listening 587 3 + + tell_status "testing ZoneMTA webadmin" + stage_listening 8082 3 + + tell_status "testing Haraka" + stage_listening 25 3 + + echo "it worked" +} + +test_zonemta() +{ + tell_status "testing zonemta" + stage_listening 2525 3 + echo "it worked" + stage_listening 8082 3 echo "it worked" } @@ -126,7 +513,20 @@ preflight_check create_staged_fs wildduck start_staged_jail wildduck install_wildduck +install_wildduck_webmail +install_zonemta +install_zonemta_webadmin +install_pm2 configure_wildduck +configure_wildduck_webmail +configure_zonemta +configure_zonemta_admin +configure_haraka +configure_pf start_wildduck +start_wildduck_webmail +start_zonemta +start_zonemta_webadmin +start_haraka test_wildduck promote_staged_jail wildduck