6 Commits

Author SHA1 Message Date
nick
f831f935b9 Correct sasl_passwd file creation method 2021-07-08 21:23:43 -05:00
nick
222d3fad72 feat: Parameterize destination config value 2021-07-08 21:23:43 -05:00
BuildTools
8011cddf8a feat: Add support to load username from file 2021-05-22 21:54:18 -05:00
Juan Luis Baptiste
543ac4aa8d Added a pull request template 2021-05-22 20:27:08 -05:00
Juan Luis Baptiste
1cfdcb5f18 feat: Removed supervisor and rsyslog
As mentioned in discussion #54, since version 3.3.0, postfix can run in
foreground mode, and since 3.4.0 it can log directly to stdout.
2021-05-22 17:49:25 -05:00
Juan Luis Baptiste
546e849593 Updated README with info about multiarch builds and versioned tags 2021-04-25 22:09:56 -05:00
11 changed files with 68 additions and 238 deletions

View File

@@ -28,3 +28,6 @@
# Optional: This will rewrite the from address overwriting it with the specified address for all email being relayed. # Optional: This will rewrite the from address overwriting it with the specified address for all email being relayed.
#OVERWRITE_FROM="Your Name" <email@company.com> #OVERWRITE_FROM="Your Name" <email@company.com>
# Optional: This will use allow you to set a custom $mydestination value. Default is localhost.
#DESTINATION=

36
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,36 @@
# Creating a Pull Request
We use github actions to do automatic [semantic versioning](https://github.com/semantic-release/semantic-release), so please use the following nomenclature for the commit message according to the type of change:
* Prefix with `feat:`, and it will trigger a minor version bump.
* Prefix with `fix`:, and it will trigger a patch version bump.
* Prefix with `BREAKING CHANGE:`, and it will trigger a major version bump.
## Description of the change
<!--Please be very clear on the intention of the modifications included in the pull request.-->
<!--If it is a bug, explain what is the issue at hand and how you are fixing it. -->
<!--If it is an improvement, explain why do you think it is needed and the benefits it brings to the project. -->
<!--Ideally I would recommend to create an issue first to discuss the new feature with the developers.-->
## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, tests ran to see how -->
## Types of Changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation (adding or updating documentation)
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [ ] My change requires a change to the documentation and I have updated the documentation accordingly.
- [ ] My change adds a new configuration variable and I have updated the `.env.example` file accordingly.
And lastly, many thanks for taking your time to help us improve this project !

View File

@@ -4,12 +4,11 @@ MAINTAINER Juan Luis Baptiste juan.baptiste@gmail.com
RUN apk update && \ RUN apk update && \
apk add bash gawk cyrus-sasl cyrus-sasl-login cyrus-sasl-crammd5 mailx \ apk add bash gawk cyrus-sasl cyrus-sasl-login cyrus-sasl-crammd5 mailx \
perl supervisor postfix rsyslog && \ postfix && \
rm -rf /var/cache/apk/* && \ rm -rf /var/cache/apk/* && \
mkdir -p /var/log/supervisor/ /var/run/supervisor/ && \ mkdir -p /var/log/supervisor/ /var/run/supervisor/ && \
sed -i -e 's/inet_interfaces = localhost/inet_interfaces = all/g' /etc/postfix/main.cf sed -i -e 's/inet_interfaces = localhost/inet_interfaces = all/g' /etc/postfix/main.cf
COPY etc/ /etc/
COPY run.sh / COPY run.sh /
RUN chmod +x /run.sh RUN chmod +x /run.sh
RUN newaliases RUN newaliases

View File

@@ -5,14 +5,28 @@
Simple Postfix SMTP TLS relay [docker](http://www.docker.com) alpine based image with no local authentication enabled (to be run in a secure LAN). Simple Postfix SMTP TLS relay [docker](http://www.docker.com) alpine based image with no local authentication enabled (to be run in a secure LAN).
It also includes rsyslog to enable logging to stdout. This image is available for the following architectures:
* 386
* amd64 (_latest_ and _alpine_ tags)
* armv6
* armv7
* arm64
_If you want to follow the development of this project check out [my blog](https://www.juanbaptiste.tech/category/postfx)._ _If you want to follow the development of this project check out [my blog](https://www.juanbaptiste.tech/category/postfx)._
### Available image tags ### Available image tags
Currently we only handle a rolling release of new versions so only _latest_ tag is available, but there is [work in progress](https://github.com/juanluisbaptiste/docker-postfix/pull/29) to start releasing versioned images to be able to pin to specific versions in production deployments. We use semantic versioning for this image. For all supported architectures there are the following versioned tags:
* Major (1)
* Minor (1.0)
* Patch (1.0.0)
Additionally the amd64 architecture has the following tags:
* _latest_
* _alpine_
*_NOTES_*: *_NOTES_*:
* The _alpine_ tag has been switched to use the master branch, but it's irrelevant as it is the same as _latest_. * The _alpine_ tag has been switched to use the master branch, but it's irrelevant as it is the same as _latest_.
@@ -52,12 +66,19 @@ The following env variable(s) are optional.
* `SMTP_PASSWORD_FILE` Setting this to a mounted file containing the password, to avoid passwords in env variables. Used like * `SMTP_PASSWORD_FILE` Setting this to a mounted file containing the password, to avoid passwords in env variables. Used like
-e SMTP_PASSWORD_FILE=/secrets/smtp_password -e SMTP_PASSWORD_FILE=/secrets/smtp_password
-v $(pwd)/secrets/:/secrets/ -v $(pwd)/secrets/:/secrets/
* `SMTP_USERNAME_FILE` Setting this to a mounted file containing the username, to avoid usernames in env variables. Used like
-e SMTP_USERNAME_FILE=/secrets/smtp_username
-v $(pwd)/secrets/:/secrets/
* `ALWAYS_ADD_MISSING_HEADERS` This is related to the [always\_add\_missing\_headers](http://www.postfix.org/postconf.5.html#always_add_missing_headers) Postfix option (default: `no`). If set to `yes`, Postfix will always add missing headers among `From:`, `To:`, `Date:` or `Message-ID:`. * `ALWAYS_ADD_MISSING_HEADERS` This is related to the [always\_add\_missing\_headers](http://www.postfix.org/postconf.5.html#always_add_missing_headers) Postfix option (default: `no`). If set to `yes`, Postfix will always add missing headers among `From:`, `To:`, `Date:` or `Message-ID:`.
* `OVERWRITE_FROM` This will rewrite the from address overwriting it with the specified address for all email being relayed. Example settings: * `OVERWRITE_FROM` This will rewrite the from address overwriting it with the specified address for all email being relayed. Example settings:
OVERWRITE_FROM=email@company.com OVERWRITE_FROM=email@company.com
OVERWRITE_FROM="Your Name" <email@company.com> OVERWRITE_FROM="Your Name" <email@company.com>
* `DESTINATION` This will define a list of domains from which incoming messages will be accepted.
To use this container from anywhere, the 25 port or the one specified by `SMTP_PORT` needs to be exposed to the docker host server: To use this container from anywhere, the 25 port or the one specified by `SMTP_PORT` needs to be exposed to the docker host server:
docker run -d --name postfix -p "25:25" \ docker run -d --name postfix -p "25:25" \

View File

@@ -1,90 +0,0 @@
# rsyslog configuration file
# For more information see /usr/share/doc/rsyslog-*/rsyslog_conf.html
# If you experience problems, see http://www.rsyslog.com/doc/troubleshoot.html
#### MODULES ####
# The imjournal module bellow is now used as a message source instead of imuxsock.
$ModLoad imuxsock # provides support for local system logging (e.g. via logger command)
#$ModLoad imklog # reads kernel messages (the same are read from journald)
#$ModLoad immark # provides --MARK-- message capability
# Provides UDP syslog reception
#$ModLoad imudp
#$UDPServerRun 514
# Provides TCP syslog reception
#$ModLoad imtcp
#$InputTCPServerRun 514
#### GLOBAL DIRECTIVES ####
# Where to place auxiliary files
$WorkDirectory /var/lib/rsyslog
# Use default timestamp format
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
# File syncing capability is disabled by default. This feature is usually not required,
# not useful and an extreme performance hit
#$ActionFileEnableSync on
# Include all config files in /etc/rsyslog.d/
$IncludeConfig /etc/rsyslog.d/*.conf
# Turn off message reception via local log socket;
# local messages are retrieved through imjournal now.
$OmitLocalLogging off
# File to store the position in the journal
#$IMJournalStateFile imjournal.state
#### RULES ####
# Log all kernel messages to the console.
# Logging much else clutters up the screen.
#kern.* /dev/console
# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;authpriv.none;cron.none /var/log/messages
# The authpriv file has restricted access.
authpriv.* /var/log/secure
# Log all the mail messages in one place.
mail.* -/var/log/maillog
# Log cron stuff
cron.* /var/log/cron
# Everybody gets emergency messages
*.emerg :omusrmsg:*
# Save news errors of level crit and higher in a special file.
uucp,news.crit /var/log/spooler
# Save boot messages also to boot.log
local7.* /var/log/boot.log
# ### begin forwarding rule ###
# The statement between the begin ... end define a SINGLE forwarding
# rule. They belong together, do NOT split them. If you create multiple
# forwarding rules, duplicate the whole block!
# Remote Logging (we use TCP for reliable delivery)
#
# An on-disk queue is created for this action. If the remote host is
# down, messages are spooled to disk and sent when it is up again.
#$ActionQueueFileName fwdRule1 # unique name prefix for spool files
#$ActionQueueMaxDiskSpace 1g # 1gb space limit (use as much as possible)
#$ActionQueueSaveOnShutdown on # save messages to disk on shutdown
#$ActionQueueType LinkedList # run asynchronously
#$ActionResumeRetryCount -1 # infinite retries if host is down
# remote host is: name/ip:port, e.g. 192.168.0.1:514, port optional
#*.* @@remote-host:514
# ### end of the forwarding rule ###

View File

@@ -1 +0,0 @@
$SystemLogSocketName /dev/log

View File

@@ -1,129 +0,0 @@
; Sample supervisor config file.
[unix_http_server]
file=/var/run/supervisor/supervisor.sock ; (the path to the socket file)
;chmod=0700 ; sockef file mode (default 0700)
;chown=nobody:nogroup ; socket file uid:gid owner
;username=user ; (default is no username (open server))
;password=123 ; (default is no password (open server))
;[inet_http_server] ; inet (TCP) server disabled by default
;port=127.0.0.1:9001 ; (ip_address:port specifier, *:port for all iface)
;username=user ; (default is no username (open server))
;password=123 ; (default is no password (open server))
[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
loglevel=info ; (log level;default info; others: debug,warn,trace)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=true ; (start in foreground if true;default false)
minfds=1024 ; (min. avail startup file descriptors;default 1024)
minprocs=200 ; (min. avail process descriptors;default 200)
;umask=022 ; (process file creation umask;default 022)
user=root ; (default is current user, required if root)
;identifier=supervisor ; (supervisord identifier, default is 'supervisor')
;directory=/tmp ; (default is not to cd during start)
;nocleanup=true ; (don't clean up tempfiles at start;default false)
;childlogdir=/tmp ; ('AUTO' child log dir, default $TEMP)
;environment=KEY=value ; (key value pairs to add to environment)
;strip_ansi=false ; (strip ansi escape codes in logs; def. false)
; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor/supervisor.sock ; use a unix:// URL for a unix socket
;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
;username=chris ; should be same as http_username if set
;password=123 ; should be same as http_password if set
;prompt=mysupervisor ; cmd line prompt (default "supervisor")
;history_file=~/.sc_history ; use readline history if available
; The below sample program section shows all possible program subsection values,
; create one or more 'real' program: sections to be able to control them under
; supervisor.
;[program:theprogramname]
;command=/bin/cat ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
;numprocs=1 ; number of processes copies to start (def 1)
;directory=/tmp ; directory to cwd to before exec (def no cwd)
;umask=022 ; umask for process (default None)
;priority=999 ; the relative start priority (default 999)
;autostart=true ; start at supervisord start (default: true)
;autorestart=true ; retstart at unexpected quit (default: true)
;startsecs=10 ; number of secs prog must stay running (def. 1)
;startretries=3 ; max # of serial start failures (default 3)
;exitcodes=0,2 ; 'expected' exit codes for process (default 0,2)
;stopsignal=QUIT ; signal used to kill process (default TERM)
;stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10)
;user=chrism ; setuid to this UNIX account to run the program
;redirect_stderr=true ; redirect proc stderr to stdout (default false)
;stdout_logfile=/a/path ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10 ; # of stdout logfile backups (default 10)
;stdout_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0)
;stdout_events_enabled=false ; emit events on stdout writes (default false)
;stderr_logfile=/a/path ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10 ; # of stderr logfile backups (default 10)
;stderr_capture_maxbytes=1MB ; number of bytes in 'capturemode' (default 0)
;stderr_events_enabled=false ; emit events on stderr writes (default false)
;environment=A=1,B=2 ; process environment additions (def no adds)
;serverurl=AUTO ; override serverurl computation (childutils)
; The below sample eventlistener section shows all possible
; eventlistener subsection values, create one or more 'real'
; eventlistener: sections to be able to handle event notifications
; sent by supervisor.
;[eventlistener:theeventlistenername]
;command=/bin/eventlistener ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
;numprocs=1 ; number of processes copies to start (def 1)
;events=EVENT ; event notif. types to subscribe to (req'd)
;buffer_size=10 ; event buffer queue size (default 10)
;directory=/tmp ; directory to cwd to before exec (def no cwd)
;umask=022 ; umask for process (default None)
;priority=-1 ; the relative start priority (default -1)
;autostart=true ; start at supervisord start (default: true)
;autorestart=unexpected ; restart at unexpected quit (default: unexpected)
;startsecs=10 ; number of secs prog must stay running (def. 1)
;startretries=3 ; max # of serial start failures (default 3)
;exitcodes=0,2 ; 'expected' exit codes for process (default 0,2)
;stopsignal=QUIT ; signal used to kill process (default TERM)
;stopwaitsecs=10 ; max num secs to wait b4 SIGKILL (default 10)
;user=chrism ; setuid to this UNIX account to run the program
;redirect_stderr=true ; redirect proc stderr to stdout (default false)
;stdout_logfile=/a/path ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10 ; # of stdout logfile backups (default 10)
;stdout_events_enabled=false ; emit events on stdout writes (default false)
;stderr_logfile=/a/path ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups ; # of stderr logfile backups (default 10)
;stderr_events_enabled=false ; emit events on stderr writes (default false)
;environment=A=1,B=2 ; process environment additions
;serverurl=AUTO ; override serverurl computation (childutils)
; The below sample group section shows all possible group values,
; create one or more 'real' group: sections to create "heterogeneous"
; process groups.
;[group:thegroupname]
;programs=progname1,progname2 ; each refers to 'x' in [program:x] definitions
;priority=999 ; the relative start priority (default 999)
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves.
[include]
files = supervisord.d/*.ini

View File

@@ -1,5 +0,0 @@
[program:postfix]
process_name = master
command=/usr/sbin/postfix -c /etc/postfix start
startsecs=0
autorestart=false

View File

@@ -1,4 +0,0 @@
[program:readlog]
command=/usr/bin/tail -f /var/log/maillog
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0

View File

@@ -1,2 +0,0 @@
[program:rsyslog]
command=/usr/sbin/rsyslogd -n

8
run.sh
View File

@@ -13,8 +13,9 @@ function add_config_value() {
postconf -e "${key} = ${value}" postconf -e "${key} = ${value}"
} }
# Read password from file to avoid unsecure env variables # Read password and username from file to avoid unsecure env variables
if [ -n "${SMTP_PASSWORD_FILE}" ]; then [ -f "${SMTP_PASSWORD_FILE}" ] && read SMTP_PASSWORD < ${SMTP_PASSWORD_FILE} || echo "SMTP_PASSWORD_FILE defined, but file not existing, skipping."; fi if [ -n "${SMTP_PASSWORD_FILE}" ]; then [ -f "${SMTP_PASSWORD_FILE}" ] && read SMTP_PASSWORD < ${SMTP_PASSWORD_FILE} || echo "SMTP_PASSWORD_FILE defined, but file not existing, skipping."; fi
if [ -n "${SMTP_USERNAME_FILE}" ]; then [ -f "${SMTP_USERNAME_FILE}" ] && read SMTP_USERNAME < ${SMTP_USERNAME_FILE} || echo "SMTP_USERNAME_FILE defined, but file not existing, skipping."; fi
[ -z "${SMTP_SERVER}" ] && echo "SMTP_SERVER is not set" && exit 1 [ -z "${SMTP_SERVER}" ] && echo "SMTP_SERVER is not set" && exit 1
[ -z "${SERVER_HOSTNAME}" ] && echo "SERVER_HOSTNAME is not set" && exit 1 [ -z "${SERVER_HOSTNAME}" ] && echo "SERVER_HOSTNAME is not set" && exit 1
@@ -26,9 +27,10 @@ SMTP_PORT="${SMTP_PORT:-587}"
DOMAIN=`echo ${SERVER_HOSTNAME} | awk 'BEGIN{FS=OFS="."}{print $(NF-1),$NF}'` DOMAIN=`echo ${SERVER_HOSTNAME} | awk 'BEGIN{FS=OFS="."}{print $(NF-1),$NF}'`
# Set needed config options # Set needed config options
add_config_value "maillog_file" "/dev/stdout"
add_config_value "myhostname" ${SERVER_HOSTNAME} add_config_value "myhostname" ${SERVER_HOSTNAME}
add_config_value "mydomain" ${DOMAIN} add_config_value "mydomain" ${DOMAIN}
add_config_value "mydestination" 'localhost' add_config_value "mydestination" "${DESTINATION:-localhost}"
add_config_value "myorigin" '$mydomain' add_config_value "myorigin" '$mydomain'
add_config_value "relayhost" "[${SMTP_SERVER}]:${SMTP_PORT}" add_config_value "relayhost" "[${SMTP_SERVER}]:${SMTP_PORT}"
add_config_value "smtp_use_tls" "yes" add_config_value "smtp_use_tls" "yes"
@@ -90,4 +92,4 @@ fi
# starting services # starting services
rm -f /var/spool/postfix/pid/master.pid rm -f /var/spool/postfix/pid/master.pid
exec supervisord -c /etc/supervisord.conf exec /usr/sbin/postfix -c /etc/postfix start-fg