commit 51ece3178da6c628e9870f186aa04351c2d4ee57 Author: Dave Conroy Date: Sat Jul 14 21:07:01 2018 -0700 0.99 - Initial Release - Fully functioning, lacking full documentation diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2e8a95f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,4 @@ +## 1.0 2018-07-14 + +* Initial Release + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9e0455c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,49 @@ +FROM registry.selfdesign.org/docker/ruby:2.4-alpine-latest +LABEL maintainer="Dave Conroy (dave at tiredofit dot ca)" + +ENV ENABLE_CRON=FALSE \ + ENABLE_SMTP=FALSE + +RUN set -x && \ +# Create User + addgroup -g 2525 postal && \ + adduser -S -D -G postal -u 2525 -h /opt/postal/ postal && \ + \ +# Build Dependencies + apk update && \ + apk add --no-cache --virtual .postal-build-deps \ + git \ + mariadb-dev \ + && \ + \ + apk add --no-cache --virtual .lemonldap-run-deps \ + expect \ + nodejs \ + mariadb-client-libs \ + mariadb-client \ + sudo \ + && \ + \ +### Fetch Source and install Ruby Dependencies + gem install bundler && \ + gem install procodile && \ + git clone https://github.com/atech/postal /opt/postal && \ + \ +### Install Ruby Gems and dependencies + /opt/postal/bin/postal bundle /opt/postal/vendor/bundle && \ + \ +### Housekeeping + ln -s /usr/local/bundle/bin/procodile /usr/sbin && \ + mkdir -p /opt/postal/certs && \ + \ +# Cleanup + chown -R postal. /opt/postal && \ + rm -rf && \ + apk del .postal-build-deps && \ + rm -rf /tmp/* /var/cache/apk/* + +### Networking Setup +EXPOSE 80 5000 + +### Add Files and Assets +ADD install / diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..90cb01a --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 Dave Conroy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..639c1bb --- /dev/null +++ b/README.md @@ -0,0 +1,111 @@ +# hub.docker.com/r/tiredofit/postal + +# Introduction + +Dockerfile to build a [Postal](https://github.com/atech/postal) SMTP server for sending and receiving SMTP / HTTP API email. +* This Container uses a [customized Alpine base](https://hub.docker.com/r/tiredofit/debian) which includes [s6 +overlay](https://github.com/just-containers/s6-overlay) enabled for PID 1 Init capabilities, [zabbix-agent](https://zabbix.org) for +individual container monitoring, Cron also installed along with other tools (bash,curl, less, logrotate, nano, vim) for easier +management. + + + +[Changelog](CHANGELOG.md) + +# Authors + +- [Dave Conroy](https://github.com/tiredofit/) + +# Table of Contents + +- [Introduction](#introduction) + - [Changelog](CHANGELOG.md) +- [Prerequisites](#prerequisites) +- [Installation](#installation) +- [Quick Start](#quick-start) +- [Configuration](#configuration) + - [Data Volumes](#data-volumes) + - [Environment Variables](#environmentvariables) +- [Maintenance](#maintenance) + - [Shell Access](#shell-access) + - [References](#references) + +# Prerequisites + +[RabbitMQ Server](https://github.com/tiredofit/docker-rabbitmq) +[MariaDB Server](https://github.com/tiredofit/docker-mariadb) +[Spamassassin](https://github.com/tiredofit/docker-spamassassin) *optional* +[Clam Antivirus](https://github.com/tiredofit/docker-clamav) *optional* + +# Installation + +Automated builds of the image are available on [Registry](https://hub.docker.com/tiredofit/postal) and is the recommended method of +installation. + + +```bash +docker pull hub.docker.com/tiredofit/postal:(imagetag) +``` + +The following image tags are available: +* `latest` - Most recent release of postal w/Alpine Linux 3.7 + +# Quick Start + +* The quickest way to get started is using [docker-compose](https://docs.docker.com/compose/). See the examples folder for a working +[docker-compose.yml](examples/docker-compose.yml) that can be modified for development or production use. + +* Set various [environment variables](#environment-variables) to understand the capabilities of this image. +* Map [persistent storage](#data-volumes) for access to configuration and data files for backup. + + +# Configuration + +### Environment Variables + +Along with the Environment Variables from the [Base image](https://hub.docker.com/r/tiredofit/alpine), below is the complete list of +available options that can be used to customize your installation. + +| Parameter | Description | +|-----------|-------------| +| `$DB_HOST` | Hostname of MariaDB Container | +| `$DB_NAME` | Name of MariaDB Database | +| `$DB_USER` | Database Username | +| `$DB_PASS` | Password for Above User | +| `$DB_PORT` | MariaDB Server Port - Default `3306` +| `$DB_ROOT_PASS` | Needed for first boot - Assigns privileges to $DB_USER. MySQL Root Pass | +| `$RABBITMQ_HOST` | RabbitMQ Hostname or Container | +| `$RABBITMQ_VHOST` | RabbitMQ VHost shard | +| `$RABBITMQ_USER` | RabbitMQ Username | +| `$RABBITMQ_PASS` | RabbitMQ Password | +| `$RABBITMQ_PORT` | RabbitMQ Port - Default `5672` | +| `ENABLE_CLAMAV` | Enable ClamAV `true` or `false` - Default `false` | +| `ENABLE_SPAMASSASSIN` | Enable Spamassassin `true` or `false` - Default `false` | +| `CLAMAV_HOST` | Hostname of Clamd Server | +| `SPAMASSASSIN_HOST` | Hostname of Spamassassin Server | +| `CLAMAV_PORT` | TCP Port of Clamd Server - Default `3310` | +| `SPAMASSASSIN_PORT` | TCP Port of Spamassassin Process - Default `737` | +| `LOG_CONSOLE` | Log to Stdout Console `true` or `false` - Default `true` | + +### Networking + +| Port | Description | +|-----------|---------------| +| `5000` | Procodile | +| `25` | SMTP | +| `587` | Submission | + +# Maintenance + +#### Shell Access + +For debugging and maintenance purposes you may want access the containers shell. + +```bash +docker exec -it (whatever your container name is e.g. postal) bash +``` + +# References + +* https://github.com/atech/postal + diff --git a/examples/docker-compose.yml b/examples/docker-compose.yml new file mode 100644 index 0000000..674f078 --- /dev/null +++ b/examples/docker-compose.yml @@ -0,0 +1,126 @@ +version: '2' + +services: + postal-app: + container_name: postal-app + image: tiredofit/postal + ports: + - 25:2525 + volumes: + - ./data/postal:/opt/postal/config + environment: + - VIRTUAL_HOST=postal.example.com + - VIRTUAL_NETWORK=nginx-proxy + - VIRTUAL_PORT=5000 + - LETSENCRYPT_HOST=postal.example.com + - LETSENCRYPT_EMAIL=email@example.com + + - ZABBIX_HOSTNAME=postal-app + + - DB_HOST=postal-db + - DB_PORT=3306 + - DB_NAME=postal + - DB_USER=postal + - DB_PASS=postalpass + ## A great idea is to delete this block after first install. + - DB_ROOT_PASS=rootpassword + - ADMIN_EMAIL=example@hostname.com + - ADMIN_PASS=password + - ADMIN_FNAME=Example + - ADMIN_LNAME=Admin + ## + + - RABBITMQ_HOST=postal-rabbitmq + - RABBITMQ_USER=postal + - RABBITMQ_PASS=password + - RABBITMQ_VHOST=/postal + + - ENABLE_SPAMASSASSIN=false + - ENABLE_CLAMAV=false + - CLAMAV_HOST=postal-clamav + - SPAMASSASSIN_HOST=postal-spamassassin + + restart: always + networks: + - proxy-tier + + postal-db: + container_name: postal-db + image: tiredofit/mariadb + restart: always + volumes: + - ./db:/var/lib/mysql + environment: + - MYSQL_ROOT_PASSWORD=rootpassword + - MYSQL_DATABASE=postal + - MYSQL_USER=postal + - MYSQL_PASSWORD=postalpass + - ZABBIX_HOSTNAME=postal-db + networks: + - proxy-tier + + postal-db-backup: + container_name: postal-db-backup + image: tiredofit/db-backup + links: + - postal-db + volumes: + - ./dbbackup:/backup + environment: + - ZABBIX_HOSTNAME=postal-db-backup + - DB_HOST=postal-db + - DB_TYPE=mariadb + - DB_NAME=postal + - DB_USER=postal + - DB_PASS=postalpass + - DB_DUMP_FREQ=1440 + - DB_DUMP_BEGIN=0000 + - DB_CLEANUP_TIME=8640 + - COMPRESSION=BZ + - MD5=TRUE + networks: + - proxy-tier + restart: always + + postal-rabbitmq: + container_name: postal-rabbitmq + image: tiredofit/rabbitmq + environment: + - RABBITMQ_DEFAULT_USER=postal + - RABBITMQ_DEFAULT_PASS=password + - RABBITMQ_DEFAULT_VHOST=/postal + - ZABBIX_HOSTNAME=postal-rabbitmq + networks: + - proxy-tier + restart: always + + postal-clamav: + container_name: postal-clamav + image: tiredofit/clamav + volumes: + - ./data/clamav:/data + - ./logs/clamav:/var/log/clamav + environment: + - ZABBIX_HOSTNAME=postal-clamav + networks: + - proxy-tier + restart: always + + postal-spamassassin: + image: tiredofit/spamassassin + container_name: postal-spamassassin-app + volumes: + - ./logs/spamassassin:/var/log/spamassassin + - ./data/spamassassin/conf:/etc/mail/spamassassin + - ./data/spamassassin/data:/var/lib/spamassassin + environment: + - ZABBIX_HOSTNAME=postal-spamassassin + networks: + - proxy-tier + restart: always + +networks: + proxy-tier: + external: + name: nginx-proxy + diff --git a/install/assets/config/postal.defaults.yml b/install/assets/config/postal.defaults.yml new file mode 100644 index 0000000..e6b834a --- /dev/null +++ b/install/assets/config/postal.defaults.yml @@ -0,0 +1,127 @@ +# These are the default configuration options that will be used if they aren't overriden +# in your postal.yml configuration file. No changes should be made to this file for +# your installation. + +# You can refer to this for a complete listing all available configuration options. + +web: + host: postal.example.com + protocol: http + +general: + use_ip_pools: false + exception_url: + maximum_delivery_attempts: 18 + use_local_ns_for_domains: false + +web_server: + bind_address: 0.0.0.0 + port: 5000 + max_threads: 5 + +fast_server: + enabled: false + bind_address: + # Set appropriate IP addresses to listen on. These should be dedicated IP + # addresses just used for this server. You should list IPv4 and IPv6 addresses + # as appropriate. + # - 1.2.3.4 + # - abcd:a:b:c:d::1 + port: 80 + ssl_port: 443 + proxy_protocol: false + default_private_key_path: # Defaults to config/fast_server.key + default_tls_certificate_path: # Defaults to config/fast_server.cert + +main_db: + host: 127.0.0.1 + port: 3306 + username: postal + password: + database: postal + pool_size: 5 + +logging: + stdout: false + root: # Automatically determined based on config root + max_log_file_size: 20 + max_log_files: 10 + greylog: + host: + port: 12201 + +message_db: + host: 127.0.0.1 + port: 3306 + username: postal + password: + prefix: postal + +rabbitmq: + host: 127.0.0.1 + port: 5672 + username: postal + password: + vhost: /postal + +workers: + quantity: 1 + threads: 4 + +smtp_server: + port: 25 + tls_enabled: false + tls_certificate_path: # Defaults to config/smtp.cert + tls_private_key_path: # Defaults to config/smtp.key + tls_ciphers: + ssl_version: SSLv23 + proxy_protocol: false + log_connect: true + strip_received_headers: false + max_message_size: 14 # size in Megabytes + +smtp_relays: + - + hostname: + port: 25 + ssl_mode: Auto + +dns: + mx_records: + - mx.postal.example.com + smtp_server_hostname: postal.example.com + spf_include: spf.postal.example.com + return_path: rp.postal.example.com + route_domain: routes.postal.example.com + track_domain: track.postal.example.com + helo_hostname: # By default, this will be the same as the `smtp_server_hostname` + dkim_identifier: postal + domain_verify_prefix: postal-verification + custom_return_path_prefix: psrp + +smtp: + host: 127.0.0.1 + port: 25 + username: # Complete when Postal is running and you can + password: # generate the credentials within the interface. + from_name: Postal + from_address: postal@yourdomain.com + +rails: + environment: production + secret_key: + +spamd: + enabled: false + host: 127.0.0.1 + port: 783 + +clamav: + enabled: false + host: 127.0.0.1 + port: 2000 + +smtp_client: + open_timeout: 30 + read_timeout: 60 + diff --git a/install/assets/config/postal.example.yml b/install/assets/config/postal.example.yml new file mode 100644 index 0000000..e6b834a --- /dev/null +++ b/install/assets/config/postal.example.yml @@ -0,0 +1,127 @@ +# These are the default configuration options that will be used if they aren't overriden +# in your postal.yml configuration file. No changes should be made to this file for +# your installation. + +# You can refer to this for a complete listing all available configuration options. + +web: + host: postal.example.com + protocol: http + +general: + use_ip_pools: false + exception_url: + maximum_delivery_attempts: 18 + use_local_ns_for_domains: false + +web_server: + bind_address: 0.0.0.0 + port: 5000 + max_threads: 5 + +fast_server: + enabled: false + bind_address: + # Set appropriate IP addresses to listen on. These should be dedicated IP + # addresses just used for this server. You should list IPv4 and IPv6 addresses + # as appropriate. + # - 1.2.3.4 + # - abcd:a:b:c:d::1 + port: 80 + ssl_port: 443 + proxy_protocol: false + default_private_key_path: # Defaults to config/fast_server.key + default_tls_certificate_path: # Defaults to config/fast_server.cert + +main_db: + host: 127.0.0.1 + port: 3306 + username: postal + password: + database: postal + pool_size: 5 + +logging: + stdout: false + root: # Automatically determined based on config root + max_log_file_size: 20 + max_log_files: 10 + greylog: + host: + port: 12201 + +message_db: + host: 127.0.0.1 + port: 3306 + username: postal + password: + prefix: postal + +rabbitmq: + host: 127.0.0.1 + port: 5672 + username: postal + password: + vhost: /postal + +workers: + quantity: 1 + threads: 4 + +smtp_server: + port: 25 + tls_enabled: false + tls_certificate_path: # Defaults to config/smtp.cert + tls_private_key_path: # Defaults to config/smtp.key + tls_ciphers: + ssl_version: SSLv23 + proxy_protocol: false + log_connect: true + strip_received_headers: false + max_message_size: 14 # size in Megabytes + +smtp_relays: + - + hostname: + port: 25 + ssl_mode: Auto + +dns: + mx_records: + - mx.postal.example.com + smtp_server_hostname: postal.example.com + spf_include: spf.postal.example.com + return_path: rp.postal.example.com + route_domain: routes.postal.example.com + track_domain: track.postal.example.com + helo_hostname: # By default, this will be the same as the `smtp_server_hostname` + dkim_identifier: postal + domain_verify_prefix: postal-verification + custom_return_path_prefix: psrp + +smtp: + host: 127.0.0.1 + port: 25 + username: # Complete when Postal is running and you can + password: # generate the credentials within the interface. + from_name: Postal + from_address: postal@yourdomain.com + +rails: + environment: production + secret_key: + +spamd: + enabled: false + host: 127.0.0.1 + port: 783 + +clamav: + enabled: false + host: 127.0.0.1 + port: 2000 + +smtp_client: + open_timeout: 30 + read_timeout: 60 + diff --git a/install/etc/cont-init.d/10-postal b/install/etc/cont-init.d/10-postal new file mode 100755 index 0000000..4a0d0aa --- /dev/null +++ b/install/etc/cont-init.d/10-postal @@ -0,0 +1,319 @@ +#!/usr/bin/with-contenv /bin/bash + +### Set Defaults +CLAMAV_PORT=${CLAMAV_PORT:-3310} +DB_PORT=${DB_PORT:-3306} +DNS_DKIM_IDENTIFIER=${DNS_DKIM_IDENTIFIER:-"postal"} +DNS_DOMAIN_VERIFY_PREFIX=${DNS_DOMAIN_VERIFY_PREFIX:-"postal-verification"} +DNS_HOSTNAME=${DNS_HOSTNAME:-"postal.example.com"} +DNS_RETURN_PATH=${DNS_RETURN_PATH:-"rp."$DNS_HOSTNAME} +DNS_RETURN_PATH_PREFIX=${DNS_RETURN_PATH_PREFIX:-"psrp"} +DNS_ROUTE_DOMAIN=${DNS_ROUTE_DOMAIN:-"routes."$DNS_HOSTNAME} +DNS_SPF=${DNS_SPF:-"spf."$DNS_HOSTNAME} +DNS_TRACK_DOMAIN=${DNS_TRACK_DOMAIN:-"track."$DNS_HOSTNAME} +ENABLE_CLAMAV=${ENABLE_CLAMAV:-false} +ENABLE_SPAMASSASSIN=${ENABLE_SPAMASSASSIN:-false} +LOG_CONSOLE=${LOG_CONSOLE:-true} +RABBITMQ_PORT=${RABBITMQ_PORT:5672} +SMTP_CLIENT_OPEN_TIMEOUT=${SMTP_CLIENT_OPEN_TIMEOUT:-30} +SMTP_CLIENT_READ_TIMEOUT=${SMTP_CLIENT_READ_TIMEOUT:-60} +SMTP_FROM_ADDRESS=${SMTP_FROM_ADDRESS:-"postal@yourdomain.com"} +SMTP_FROM_NAME=${SMTP_FROM_NAME:-"Postal"} +SMTP_HOST=${SMTP_HOST:-127.0.0.1} +SMTP_PORT=${SMTP_PORT:-25} +SMTP_RELAY_HOST=${SMTP_RELAY_HOST:-""} +SMTP_RELAY_PORT=${SMTP_RELAY_PORT:-25} +SMTP_RELAY_SSL_MODE=${SMTP_RELAY_SSL_MODE:-"Auto"} +SMTP_SERVER_ENABLE_TLS=${SMTP_SERVER_ENABLE_TLS:-"false"} +SMTP_SERVER_HELO_HOSTNAME=${SMTP_SERVER_HELO_HOSTNAME:-$DNS_HOSTNAME} +SMTP_SERVER_LOG_CONNECTIONS=${SMTP_SERVER_LOG_CONNECTIONS:-"true"} +SMTP_SERVER_MAX_MESSAGE_SIZE=${SMTP_SERVER_MAX_MESSAGE_SIZE:-14} +SMTP_SERVER_PORT=${SMTP_SERVER_PORT:-"25"} +SMTP_SERVER_PROXY_PROTOCOL=${SMTP_SERVER_PROXY_PROTOCOL:-"false"} +SMTP_SERVER_SSL_VERSION=${SMTP_SERVER_SSL_VERSION:-"SSLv23"} +SMTP_SERVER_STRIP_RECEIVED_HEADERS=${SMTP_SERVER_STRIP_RECEIVED_HEADERS:-"false"} +SMTP_SERVER_TLS_CERT=${SMTP_SERVER_TLS_CERT:-"cert.pem"} +SMTP_SERVER_TLS_CIPHERS=${SMTP_SERVER_TLS_CIPHERS:-""} +SMTP_SERVER_TLS_KEY=${SMTP_SERVER_TLS_KEY:-"key.pem"} +SPAMASSASSIN_PORT=${SPAMASSASSIN_PORT:-737} + +### Set Debug Mode +if [ "$DEBUG_MODE" = "TRUE" ] || [ "$DEBUG_MODE" = "true" ]; then + set -x +fi + +### Sanity Test +if [ ! -n "$DB_HOST" ]; then + echo '** [postal] ERROR: No Database Host Entered! ' + exit 1 +fi + +if [ ! -n "$DB_NAME" ]; then + echo '** [postal] ERROR: No Database Pass Entered! ' + exit 1 +fi + +if [ ! -n "$DB_USER" ]; then + echo '** [postal] ERROR: No Database User Entered! ' + exit 1 +fi + +if [ ! -n "$DB_PASS" ]; then + echo '** [postal] ERROR: No Database Pass Entered! ' + exit 1 +fi + +if [ ! -n "$RABBITMQ_HOST" ]; then + echo '** [postal] ERROR: No RabbitMQ Host Entered! ' + exit 1 +fi + +if [ ! -n "$RABBITMQ_VHOST" ]; then + echo '** [postal] ERROR: No RabbitMQ Vhost Entered! ' + exit 1 +fi + +if [ ! -n "$RABBITMQ_PASS" ]; then + echo '** [postal] ERROR: No RabbitMQ Pass Entered! ' + exit 1 +fi + +if [ "$ENABLE_CLAMAV" = "true" ]; then + if [ ! -n "$CLAMAV_HOST" ]; then + echo '** [postal] ERROR: No ClamAV Host Entered! ' + exit 1 + fi +fi + +if [ "$ENABLE_SPAMASSASSIN" = "true" ]; then + if [ ! -n "$SPAMASSASSIN_HOST" ]; then + echo '** [postal] ERROR: No Spamassassin Host Entered! ' + exit 1 + fi +fi + +### SSL Configuration +if [ "$SMTP_SERVER_ENABLE_TLS" = "true" ]; then + if [ ! -f "/opt/postal/certs/$SMTP_SERVER_TLS_CERT" ] || [ ! -f "/opt/postal/certs/$SMTP_SERVER_TLS_KEY" ]; then + echo "** [psotal] TLS Key or certificate not found. Generating self-signed certificates" + cat < /tmp/openssl.cnf +[ req ] +default_bits = 2048 +encrypt_key = yes +distinguished_name = req_dn +x509_extensions = cert_type +prompt = no + +[ req_dn ] +C=XX +ST=XX +L=Test Server +O=Postal + +# Organizational Unit Name (eg. section) +OU=SMTP server + +# Common Name (*.example.com is also possible) +CN=$DNS_HOSTNAME + +# E-mail contact +emailAddress=postmaster@$DNS_HOSTNAME + +[ cert_type ] +nsCertType = server +EOF + + openssl req -new -x509 -nodes -days 3650 \ + -config /tmp/openssl.cnf \ + -out /opt/postal/certs/$SMTP_SERVER_TLS_CERT \ + -keyout /opt/postal/certs/$SMTP_SERVER_TLS_KEY + chmod 0600 /opt/postal/certs/$SMTP_SERVER_TLS_KEY + rm -rf /tmp/openssl.cnf + chown -R postal. /opt/postal/certs + fi +fi + +### Create Configuration +cp -R /assets/config/*.yml /opt/postal/config +chown -R postal. /opt/postal/config +/opt/postal/bin/postal initialize-config + +## Modify Configuration file +### Clam Antivirus +sed -i -e '/clamav:/!b' -e ':a' -e "s/enabled.*/enabled: $ENABLE_CLAMAV/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/clamav:/!b' -e ':a' -e "s/host.*/host: $CLAMAV_HOST/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/clamav:/!b' -e ':a' -e "s/port.*/port: $CLAMAV_PORT/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml + +### DNS +sed -i -e '/dns:/!b' -e ':a' -e "s/smtp_server_hostname.*/smtp_server_hostname: $DNS_HOSTNAME/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/dns:/!b' -e ':a' -e "s/spf_include.*/spf_include: $DNS_SPF/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/dns:/!b' -e ':a' -e "s/return_path.*/return_path: $DNS_RETURN_PATH/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/dns:/!b' -e ':a' -e "s/route_domain.*/route_domain: $DNS_ROUTE_DOMAIN/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/dns:/!b' -e ':a' -e "s/track_domain.*/track_domain: $DNS_TRACK_DOMAIN/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/dns:/!b' -e ':a' -e "s/helo_hostname.*/helo_hostname: $SMTP_SERVER_HELO_HOSTNAME/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/dns:/!b' -e ':a' -e "s/dkim_identifier.*/dkim_identifier: $DNS_DKIM_IDENTIFIER/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/dns:/!b' -e ':a' -e "s/domain_verify_prefix.*/domain_verify_prefix: $DNS_DOMAIN_VERIFY_PREFIX/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/dns:/!b' -e ':a' -e "s/custom_return_path_prefix.*/custom_return_path_prefix: $DNS_RETURN_PATH_PREFIX/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml + +### Logging +sed -i -e '/logging:/!b' -e ':a' -e "s/stdout.*/stdout: $LOG_CONSOLE/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml + +### MySQL Main DB +sed -i -e '/main_db:/!b' -e ':a' -e "s/host.*/host: $DB_HOST/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/main_db:/!b' -e ':a' -e "s/username.*/username: $DB_USER/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/main_db:/!b' -e ':a' -e "s/password.*/password: $DB_PASS/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/main_db:/!b' -e ':a' -e "s/database.*/database: $DB_NAME/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/main_db:/!b' -e ':a' -e "s/port.*/port: $DB_PORT/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml + +### MySQL Message DB +sed -i -e '/message_db:/!b' -e ':a' -e "s/host.*/host: $DB_HOST/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/message_db:/!b' -e ':a' -e "s/username.*/username: $DB_USER/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/message_db:/!b' -e ':a' -e "s/password.*/password: $DB_PASS/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/message_db:/!b' -e ':a' -e "s/port.*/port: $DB_PORT/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml + +### RabbitMQ +sed -i -e '/rabbitmq:/!b' -e ':a' -e "s/host.*/host: $RABBITMQ_HOST/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/rabbitmq:/!b' -e ':a' -e "s/username.*/username: $RABBITMQ_USER/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/rabbitmq:/!b' -e ':a' -e "s/password.*/password: $RABBITMQ_PASS/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/rabbitmq:/!b' -e ':a' -e "s/vhost.*/vhost: \/$RABBITMQ_VHOST/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/rabbitmq:/!b' -e ':a' -e "s/port.*/port: $RABBITMQ_PORT/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml + +### SMTP Server +sed -i -e '/smtp_server:/!b' -e ':a' -e "s/port.*/port: $SMTP_SERVER_PORT/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/smtp_server:/!b' -e ':a' -e "s/tls_enabled.*/tls_enabled: $SMTP_SERVER_ENABLE_TLS/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/smtp_server:/!b' -e ':a' -e "s/tls_certificate_path.*/tls_certificate_path: $SMTP_SERVER_TLS_CERT/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/smtp_server:/!b' -e ':a' -e "s/tls_private_key_path.*/tls_private_key_path: $SMTP_SERVER_TLS_KEY/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/smtp_server:/!b' -e ':a' -e "s/tls_ciphers.*/tls_ciphers: $SMTP_SERVER_TLS_CIPHERS/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/smtp_server:/!b' -e ':a' -e "s/ssl_version.*/ssl_version: $SMTP_SERVER_SSL_VERSION/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/smtp_server:/!b' -e ':a' -e "s/proxy_protocol.*/proxy_protocol: $SMTP_SERVER_PROXY_PROTOCOL/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/smtp_server:/!b' -e ':a' -e "s/log_connect.*/log_connect: $SMTP_SERVER_LOG_CONNECTIONS/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/smtp_server:/!b' -e ':a' -e "s/strip_received_headers.*/strip_received_headers: $SMTP_SERVER_STRIP_RECEIVED_HEADERS/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/smtp_server:/!b' -e ':a' -e "s/max_message_size.*/max_message_size: $SMTP_SERVER_MAX_MESSAGE_SIZE/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml + +### SMTP Client +sed -i -e '/smtp_client:/!b' -e ':a' -e "s/open_timeout.*/open_timeout: $SMTP_CLIENT_OPEN_TIMEOUT/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/smtp_client:/!b' -e ':a' -e "s/read_timeout.*/read_timeout: $SMTP_CLIENT_READ_TIMEOUT/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml + +### SMTP Relays +sed -i -e '/smtp_relays:/!b' -e ':a' -e "s/hostname.*/hostname: $SMTP_RELAY_HOST/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/smtp_relays:/!b' -e ':a' -e "s/port.*/port: $SMTP_RELAY_PORT/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/smtp_relays:/!b' -e ':a' -e "s/ssl_mode.*/ssl_mode: $SMTP_RELAY_SSL_MODE/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml + +### SMTP +sed -i -e '/smtp:/!b' -e ':a' -e "s/host.*/host: $SMTP_HOST/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/smtp:/!b' -e ':a' -e "s/port.*/port: $SMTP_PORT/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/smtp:/!b' -e ':a' -e "s/from_name.*/from_name: $SMTP_FROM_NAME/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/smtp:/!b' -e ':a' -e "s/from_address.*/from_address: $SMTP_FROM_ADDRESS/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml + +### Spamassassin +sed -i -e '/spamd:/!b' -e ':a' -e "s/enabled.*/enabled: $ENABLE_SPAMASSASSIN/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/spamd:/!b' -e ':a' -e "s/host.*/host: $SPAMASSASSIN_HOST/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +sed -i -e '/spamd:/!b' -e ':a' -e "s/port.*/port: $SPAMASSASSIN_PORT/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' /opt/postal/config/postal.yml +## + + +## Clean Up +rm -rf /opt/postal/tmp/pids/* + +### Make sure that DB is accessible +while true; do + mysqlcmd="mysql -u$DB_USER -h$DB_HOST -p$DB_PASS -P$DB_PORT" + out="`$mysqlcmd -e "SELECT COUNT(*) FROM information_schema.FILES;" 2>&1`" + echo "$out" | grep -E "COUNT|Enter" 2>&1 > /dev/null + if [ $? -eq 0 ]; then + echo "** [postal] MariaDB Server '"$DB_HOST"' is available" + break + fi + echo "** [postal] MariaDB Server '"$DB_HOST"' unavailable. Sleeping a little bit ..." + sleep 5 +done + +### Make sure that RabbitMQ is accessible +while true; do + nc -z $RABBITMQ_HOST 5672 + if [ $? -eq 0 ]; then + echo "** [postal] RabbitMQ Server '"$RABBITMQ_HOST"' is available" + break + fi + echo "** [postal] RabbitMQ Server '"$RABBITMQ_HOST"' unavailable. Sleeping a little bit ..." + sleep 5 +done + +### Make sure that ClamAV is accessible +if [ "$ENABLE_CLAMAV" = "true" ]; then + while true; do + nc -w1 $CLAMAV_HOST $CLAMAV_PORT< /dev/null 2>&1 > /dev/null + if [ $? -eq 0 ]; then + echo "** [postal] ClamAV Server '"$CLAMAV_HOST"' is available" + break + fi + echo "** [postal] ClamAV Server '"$CLAMAV_HOST"' unavailable. Sleeping a little bit ..." + sleep 5 + done +fi + +### Make sure that Spamassassin is accessible +if [ "$ENABLE_SPAMASSASSIN" = "true" ]; then + while true; do + nc -w1 $SPAMASSASSIN_HOST $SPAMASSASSIN_PORT< /dev/null 2>&1 > /dev/null + if [ $? -eq 0 ]; then + echo "** [postal] Spamassassin Server '"$SPAMASSASSIN_HOST"' is available" + break + fi + echo "** [postal] Spamassassin Server '"$SPAMASSASSIN_HOST"' unavailable. Sleeping a little bit ..." + sleep 5 + done +fi + +if [[ $(mysql -h $DB_HOST -u$DB_USER -p$DB_PASS -s --skip-column-names -e "SELECT COUNT(DISTINCT table_name) FROM information_schema.columns WHERE table_schema = '"$DB_NAME"'") == 0 ]]; then + echo "** [postal] Detecting new Install. Initializing Database" + if [ ! -n "$DB_HOST" ]; then + echo '** [postal] ERROR: No Root Password Entered! You only need to provide the environment variable one time. Please try again.' + exit 1 + fi + + /opt/postal/bin/postal initialize + mysql -uroot -p$DB_ROOT_PASS -h$DB_HOST -e 'GRANT ALL PRIVILEGES ON `'$DB_NAME'-%` . * to `'$DB_USER'`@`%` IDENTIFIED BY "'$DB_PASS'";' + echo "** [postal] Creating Administrative User" + if [ ! -n "$ADMIN_EMAIL" ]; then + echo '** [postal] WARNING: No Admin Email entered, setting default email login to `postal@example.com`' + ADMIN_EMAIL="postal@example.com" + fi + if [ ! -n "$ADMIN_PASS" ]; then + echo '** [postal] WARNING: No Admin Pass entered, setting default password to `postal`' + ADMIN_PASS="postal" + fi + if [ ! -n "$ADMIN_FNAME" ]; then + echo '** [postal] WARNING: No Admin First Name entered, setting default to `Postal`' + ADMIN_FNAME="Postal" + fi + if [ ! -n "$ADMIN_LNAME" ]; then + echo '** [postal] WARNING: No Admin Last Name entered, setting default to `Admin`' + ADMIN_LNAME="Admin" + fi + + cat < /tmp/create-pass.sh +#!/usr/bin/expect + +spawn /usr/bin/with-contenv bash /opt/postal/bin/postal make-user +expect "E-Mail Address :" +send -- "$ADMIN_EMAIL\n" +expect "First Name :" +send -- "$ADMIN_FNAME\n" +expect "Last Name :" +send -- "$ADMIN_LNAME\n" +expect "Initial Password: :" +send -- "$ADMIN_PASS\n" +expect "User has been created" +exit 0 +EOF + +chmod +x /tmp/create-pass.sh +/tmp/create-pass.sh +rm -rf /tmp/create-pass.sh +else + /opt/postal/bin/postal upgrade +fi + +mkdir -p /tmp/state +touch /tmp/state/10-postal-init diff --git a/install/etc/s6/services/10-postal/run b/install/etc/s6/services/10-postal/run new file mode 100755 index 0000000..fbbd5df --- /dev/null +++ b/install/etc/s6/services/10-postal/run @@ -0,0 +1,18 @@ +#!/usr/bin/with-contenv bash + +while [ ! -f /tmp/state/10-postal-init ] +do + sleep 1 +done + + +if [ ! -f /tmp/state/10-postal ]; then + + mkdir -p /tmp/state/ + echo 'Initialization Complete' >/tmp/state/10-postal +fi + +echo '' +echo '** [postal] Starting postal' +exec /opt/postal/bin/postal run +