~dricottone/container-images

bae25e4edce890d731319f5c0e0896db7bfde8ee — Dominic Ricottone 1 year, 6 months ago 06b0211
Postfix redesign

Now there are three images tags for `postfix`. `:latest` uses encryption
and authentication for inbound and outbound mail. It listens on posts 25
and 465. Because it authenticates, I dropped the requirement for
senders to have a LAN IP.

`:tls-in` drops outbound encryption and authentication. This is
generally going to be useful for receiving mail and handing it to a
local service.

`:tls-out` drops inbound encryption and authentication and listining on
port 465. This is useful for relaying mail off of a trusted host.
M README.md => README.md +1 -1
@@ 15,7 15,7 @@ It should be easy to get things working on another build system.
|[nginx](/~dricottone/container-images/tree/dev/item/nginx/README.md)|latest|`registry.intra.dominic-ricottone.com/nginx:latest`|
|[nitter](/~dricottone/container-images/tree/dev/item/nitter/README.md)|amd64,arm64|`registry.intra.dominic-ricottone.com/nitter:amd64`|
|[php](/~dricottone/container-images/tree/dev/item/php/README.md)|latest,readwrite,fpm,development,fpm-development|`registry.intra.dominic-ricottone.com/php:latest`|
|[postfix](/~dricottone/container-images/tree/dev/item/postfix/README.md)|latest|`registry.intra.dominic-ricottone.com/postfix:latest`|
|[postfix](/~dricottone/container-images/tree/dev/item/postfix/README.md)|latest,tls-in,tls-out|`registry.intra.dominic-ricottone.com/postfix:latest`|
|[srht-core](/~dricottone/container-images/tree/dev/item/srht-core/README.md)|latest|`registry.intra.dominic-ricottone.com/srht-core:latest`|
|[srht-git-api](/~dricottone/container-images/tree/dev/item/srht-git-api/README.md)|latest|`registry.intra.dominic-ricottone.com/srht-git-api:latest`|
|[srht-git-core](/~dricottone/container-images/tree/dev/item/srht-git-core/README.md)|latest|`registry.intra.dominic-ricottone.com/srht-git-core:latest`|

M postfix/Dockerfile => postfix/Dockerfile +4 -3
@@ 1,21 1,22 @@
FROM docker.io/library/alpine:latest

COPY aliases /etc/postfix/aliases
COPY *.cf /etc/postfix/
COPY master.cf /etc/postfix/master.cf
COPY main.cf /etc/postfix/main.cf

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

RUN mkdir /etc/postfix/sasl && chmod 700 /etc/postfix/sasl
COPY smtpd.conf /etc/postfix/sasl/smtpd.conf

RUN addgroup -S mailer
RUN adduser -SD -s /bin/sh -G mailer -g mailer mailer

RUN apk add --no-cache postfix
RUN apk add --no-cache postfix cyrus-sasl

EXPOSE 25
EXPOSE 465
EXPOSE 587

ENTRYPOINT ["/entrypoint.sh"]


A postfix/Dockerfile.tls-in => postfix/Dockerfile.tls-in +24 -0
@@ 0,0 1,24 @@
FROM docker.io/library/alpine:latest

COPY aliases /etc/postfix/aliases
COPY master.cf /etc/postfix/master.cf
COPY main.cf.tls-in /etc/postfix/main.cf

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

RUN mkdir /etc/postfix/sasl && chmod 700 /etc/postfix/sasl
COPY smtpd.conf /etc/postfix/sasl/smtpd.conf

RUN addgroup -S mailer
RUN adduser -SD -s /bin/sh -G mailer -g mailer mailer

RUN apk add --no-cache postfix cyrus-sasl

EXPOSE 25
EXPOSE 465

ENTRYPOINT ["/entrypoint.sh"]

CMD ["postfix", "start-fg"]


A postfix/Dockerfile.tls-out => postfix/Dockerfile.tls-out +22 -0
@@ 0,0 1,22 @@
FROM docker.io/library/alpine:latest

COPY aliases /etc/postfix/aliases
COPY master.cf /etc/postfix/master.cf
COPY main.cf.tls-out /etc/postfix/main.cf

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

RUN mkdir /etc/postfix/sasl && chmod 700 /etc/postfix/sasl

RUN addgroup -S mailer
RUN adduser -SD -s /bin/sh -G mailer -g mailer mailer

RUN apk add --no-cache postfix

EXPOSE 25

ENTRYPOINT ["/entrypoint.sh"]

CMD ["postfix", "start-fg"]


M postfix/Makefile => postfix/Makefile +19 -3
@@ 2,12 2,28 @@ CONMAN=sudo docker

REGISTRY=registry.intra.dominic-ricottone.com
IMAGE=postfix
TAG=latest
TAG_TLS_ALL=latest
TAG_TLS_IN=tls-in
TAG_TLS_OUT=tls-out

image:
image: image-tls-all image-tls-in image-tls-out

image-tls-all:
	$(CONMAN) buildx build --push \
		--platform linux/arm64,linux/amd64 \
		--tag $(REGISTRY)/$(IMAGE):$(TAG) \
		--tag $(REGISTRY)/$(IMAGE):$(TAG_TLS_ALL) \
		.

image-tls-in:
	$(CONMAN) buildx build --push \
		--platform linux/arm64,linux/amd64 \
		--tag $(REGISTRY)/$(IMAGE):$(TAG_TLS_IN) \
		. -f Dockerfile.tls-in

image-tls-out:
	$(CONMAN) buildx build --push \
		--platform linux/arm64,linux/amd64 \
		--tag $(REGISTRY)/$(IMAGE):$(TAG_TLS_OUT) \
		. -f Dockerfile.tls-out

.PHONY: image

M postfix/README.md => postfix/README.md +22 -3
@@ 11,6 11,8 @@ make image
### Tags

 + `latest`
 + `tls-in` (listens on the SMTPS port, but sends without encryption or authentication)
 + `tls-out` (sends with encryption and authentication, but only listens on SMTP port)

----



@@ 41,7 43,7 @@ example.com  local
*            relay:[smtp.gmail.com]:587
```

Create an authentication file in `$saslfile`.
Create an outbound authentication file in `$saslfile`.
This is required for relaying mail to major email providers, including GMail.
It must also be owned (on the host system) by the user that will create the
container (i.e. `root` for conventional `docker(1)` deployments).


@@ 51,7 53,17 @@ It should look like:
[smtp.gmail.com]:587 example@gmail.com:wwwwxxxxyyyyzzzz
```

Create a configuration file in `$conffile`.
Create an inbound authentication file in `$sasldb`.
It must also be owned (on the host system) by the user that will create the
container (i.e. `root` for conventional `docker(1)` deployments).
It should be created like:

```
docker run --rm --interactive --tty \
  --mount type=bind,src=$(pwd)/sasldb2,dst=/etc/sasldb2 \
  registry.intra.dominic-ricottone.com/postfix:latest \
  /usr/sbin/saslpasswd2 -c -f /etc/sasldb2 -u example.com username
```

Try:



@@ 60,7 72,14 @@ $conman run --detach --name postfix --restart always \
  --mount type=bind,src=$genericfile,dst=/etc/postfix/generic,readonly \
  --mount type=bind,src=$transportfile,dst=/etc/postfix/transport,readonly \
  --mount type=bind,src=$saslfile,dst=/etc/postfix/sasl/sasl_passwd,readonly \
  --mount type=bind,src=$conffile,dst=/etc/postfix/main.cf,readonly \
  --mount type=bind,src=$sasldb,dst=/etc/sasldb2,readonly \
  --env DOMAIN=example.com --env DESTINATION="mail.example.com" \
  --publish 0.0.0.0:25:25 --publish 0.0.0.0:465:465 \
  registry.intra.dominic-ricottone.com/postfix:latest
```

If using the `tls-out` image, skip `$sasldb`.
Similarly, if using the `tls-in` image, skip `$saslfile`.

If using the `tls-in` image, do not publish port 465.


M postfix/entrypoint.sh => postfix/entrypoint.sh +3 -0
@@ 4,5 4,8 @@ postmap /etc/postfix/transport
postmap /etc/postfix/generic
postmap /etc/postfix/sasl/sasl_passwd

sed -i /etc/postfix/main.cf -e "s/^mydomain.*/mydomain = ${DOMAIN}/"
sed -i /etc/postfix/main.cf -e "s/^mydestination.*/mydestination = \$myhostname, ${DESTINATION}, localhost, localhost.localdomain/"

exec "$@"


M postfix/main.cf => postfix/main.cf +10 -1
@@ 5,7 5,7 @@ compatibility_level = 3.6

# Allowed interfaces and addresses
inet_protocols = ipv4
mynetworks = 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
inet_interfaces = all

# Values for default settings
mydomain = dominic-ricottone.com


@@ 23,13 23,22 @@ smtp_generic_maps = lmdb:/etc/postfix/generic
transport_maps = lmdb:/etc/postfix/transport

# Authentication
cyrus_sasl_config_path = /etc/postfix/sasl/
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = lmdb:/etc/postfix/sasl/sasl_passwd
smtp_sasl_security_options = noanonymous
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous, noplaintext
smtpd_sasl_tls_security_options = noanonymous
smtpd_tls_auth_only = yes

# Encryption
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
smtp_tls_security_level = encrypt
smtpd_tls_chain_files = /var/letsencrypt/chain.pem
smtpd_tls_mandatory_ciphers = high
smtpd_tls_mandatory_protocols = >=TLSv1.2
smtpd_tls_security_level = may

# If set, mail destined for any member of `$mydestination` would be rejected if user lookup failed
local_recipient_maps =

A postfix/main.cf.tls-in => postfix/main.cf.tls-in +62 -0
@@ 0,0 1,62 @@
# postfix main configuration file
# see `postconf(5)` or https://www.postfix.org/BASIC_CONFIGURATION_README.html

compatibility_level = 3.6

# Allowed interfaces and addresses
inet_protocols = ipv4
inet_interfaces = all

# Values for default settings
mydomain = dominic-ricottone.com
myhostname = fedora3.$mydomain
mydestination = $myhostname, todo.$mydomain, lists.$mydomain, localhost, localhost.localdomain
myorigin = $mydomain

# Advertise host name after SMTP 200
smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)

# Address rewriting
smtp_generic_maps = lmdb:/etc/postfix/generic

# Transport map
transport_maps = lmdb:/etc/postfix/transport

# Authentication
cyrus_sasl_config_path = /etc/postfix/sasl/
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous, noplaintext
smtpd_sasl_tls_security_options = noanonymous
smtpd_tls_auth_only = yes

# Encryption
smtpd_tls_chain_files = /var/letsencrypt/chain.pem
smtpd_tls_mandatory_ciphers = high
smtpd_tls_mandatory_protocols = >=TLSv1.2
smtpd_tls_security_level = may

# If set, mail destined for any member of `$mydestination` would be rejected if user lookup failed
local_recipient_maps =

# Local management
mail_owner = postfix
setgid_group = postdrop

home_mailbox = Maildir/

sendmail_path = /usr/sbin/sendmail
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq

command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
html_directory = no
manpage_directory = /usr/share/man
mail_spool_directory = /var/spool/mail
meta_directory = /etc/postfix
queue_directory = /var/spool/postfix
readme_directory = /usr/share/doc/postfix/readme
sample_directory = /etc/postfix
shlib_directory = /usr/lib/postfix


A postfix/main.cf.tls-out => postfix/main.cf.tls-out +58 -0
@@ 0,0 1,58 @@
# postfix main configuration file
# see `postconf(5)` or https://www.postfix.org/BASIC_CONFIGURATION_README.html

compatibility_level = 3.6

# Allowed interfaces and addresses
inet_protocols = ipv4
mynetworks = 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16

# Values for default settings
mydomain = dominic-ricottone.com
myhostname = fedora3.$mydomain
mydestination = $myhostname, todo.$mydomain, lists.$mydomain, localhost, localhost.localdomain
myorigin = $mydomain

# Advertise host name after SMTP 200
smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)

# Address rewriting
smtp_generic_maps = lmdb:/etc/postfix/generic

# Transport map
transport_maps = lmdb:/etc/postfix/transport

# Authentication
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = lmdb:/etc/postfix/sasl/sasl_passwd
smtp_sasl_security_options = noanonymous

# Encryption
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
smtp_tls_security_level = encrypt

# If set, mail destined for any member of `$mydestination` would be rejected if user lookup failed
local_recipient_maps =

# Local management
mail_owner = postfix
setgid_group = postdrop

home_mailbox = Maildir/

sendmail_path = /usr/sbin/sendmail
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq

command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
html_directory = no
manpage_directory = /usr/share/man
mail_spool_directory = /var/spool/mail
meta_directory = /etc/postfix
queue_directory = /var/spool/postfix
readme_directory = /usr/share/doc/postfix/readme
sample_directory = /etc/postfix
shlib_directory = /usr/lib/postfix


A postfix/smtpd.conf => postfix/smtpd.conf +4 -0
@@ 0,0 1,4 @@
pwcheck_method: auxprop
auxprop_plugin: sasldb
mech_list: PLAIN LOGIN CRAM-MD5 DIGEST-MD5 NTLM