Add Gerrit email account and send-email configuration
We'll have to store Gerrit's email credentials in plain text. Protecting
from outside connections using these in case they'd ever leak is tricky.
We match the account `gerrit@...` in `user.access` and then the local IP
address of the gerrit container in `gerrit-client.access`, only allowing
authenticated users (`permit_sasl_authenticated`) from this IP.
Alternatively, we could use `permit` which would allow the whole gerrit
container to send emails from `gerrit@...` without login. Then the setup
would also allow more efficient, plain-text communication between Gerrit
and Postfix. The password would still be needed to login to IMAP (assu-
ming no further, invasive changes).
diff --git a/.gitignore b/.gitignore
index f2d0bc9..0b36d07 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,5 +16,6 @@
/logs/simpleid/
/mail/config/
/mail/data/
+/mail/passwd/
/mail/rspamd-override.d/
/mail/state/
diff --git a/docker-compose.yml b/docker-compose.yml
index cbabb0b..a120e6c 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -41,13 +41,18 @@
build:
context: .
dockerfile: gerrit/Dockerfile
- env_file: gerrit/environment
+ hostname: review.${SA_PUBLIC_DOMAIN_NAME}
+ env_file:
+ - gerrit/environment
+ - environment
environment:
+ - GERRIT_USER_EMAIL=gerrit@${SA_PUBLIC_DOMAIN_NAME}
- HTTPD_LISTEN_URL=proxy-https://*:8080/
networks:
- gerritnet
volumes:
- ./logs/gerrit/:/var/gerrit/logs/:rw
+ - ./mail/passwd/gerrit/:/var/gerrit/passwd/:rw
- ./gerrit/etc/:/var/gerrit/etc/:rw
- ./gerrit/db/:/var/gerrit/db/:rw
- ./gerrit/git/:/var/gerrit/git/:rw
@@ -69,10 +74,13 @@
- "465:465" # ESMTP (implicit TLS)
- "587:587" # ESMTP (explicit TLS => STARTTLS)
- "993:993" # IMAP4 (implicit TLS)
+ networks:
+ - gerritnet
volumes:
- ./logs/mail-supervisor/:/var/log/supervisor/:rw
- ./logs/mail/:/var/log/mail/:rw
- ./certs/:/etc/letsencrypt/:ro
+ - ./mail/passwd/:/tmp/passwd/:ro
- ./mail/data/:/var/mail/:rw
- ./mail/state/:/var/mail-state/:rw
- ./mail/config/:/tmp/docker-mailserver/:rw
diff --git a/gerrit/Dockerfile.entrypoint b/gerrit/Dockerfile.entrypoint
index 6aa141b..3aa8ae1 100644
--- a/gerrit/Dockerfile.entrypoint
+++ b/gerrit/Dockerfile.entrypoint
@@ -3,7 +3,7 @@
set -e
# Allows us to bind mount arbitrary owned files
-chown -R gerrit:gerrit /var/gerrit/{logs,etc,db,git,index,cache}/
+chown -R gerrit:gerrit /var/gerrit/{logs,etc,db,git,index,cache,passwd}/
# Drop privileges as we set `USER root` only to change file permissions
exec setpriv --reuid=gerrit --regid=gerrit --init-groups --inh-caps=-all /unprivileged.sh "$@"
diff --git a/gerrit/Dockerfile.entrypoint-unprivileged b/gerrit/Dockerfile.entrypoint-unprivileged
index 86574b1..5af70c9 100644
--- a/gerrit/Dockerfile.entrypoint-unprivileged
+++ b/gerrit/Dockerfile.entrypoint-unprivileged
@@ -11,4 +11,25 @@
plugin.gerrit-oauth-provider-github-oauth.client-secret "${GITHUB_OAUTH_CLIENT_SECRET}"
fi
+secret=/var/gerrit/passwd/secret
+
+{
+ if [ ! -f ${secret} ]; then
+ echo $(mktemp -u XXXXXXXXXXXXXXXX) >${secret}
+ fi
+ chmod 400 ${secret}
+}
+
+if [ "${GERRIT_USER_EMAIL}" ]; then
+ passwd=$(cat ${secret})
+
+ git config -f /etc/gerrit/gerrit.config user.email ${GERRIT_USER_EMAIL}
+ git config -f /etc/gerrit/gerrit.config sendemail.smtpServer mail.${SA_PUBLIC_DOMAIN_NAME}
+ git config -f /etc/gerrit/gerrit.config sendemail.smtpServerPort 465
+ git config -f /etc/gerrit/gerrit.config sendemail.smtpEncryption ssl
+ git config -f /etc/gerrit/gerrit.config sendemail.smtpUser ${GERRIT_USER_EMAIL}
+ git config -f /etc/gerrit/gerrit.config sendemail.smtpPass ${passwd}
+ git config -f /etc/gerrit/gerrit.config sendemail.html false
+fi
+
exec /entrypoint.sh "$@"
diff --git a/mail/config/postfix-main.cf b/mail/config/postfix-main.cf
new file mode 100644
index 0000000..378644a
--- /dev/null
+++ b/mail/config/postfix-main.cf
@@ -0,0 +1,3 @@
+gerrit_sender_check = check_client_access hash:/tmp/docker-mailserver/gerrit-client.access, reject
+smtpd_restriction_classes = gerrit_sender_check
+dms_smtpd_sender_restrictions = check_sender_access hash:/tmp/docker-mailserver/user.access, permit_sasl_authenticated, permit_mynetworks, reject_unknown_sender_domain
diff --git a/mail/config/user-patches.sh b/mail/config/user-patches.sh
index 4be7d15..5a10bbd 100644
--- a/mail/config/user-patches.sh
+++ b/mail/config/user-patches.sh
@@ -2,6 +2,46 @@
set -e
+# Add local containers as trusted for postfix relaying.
+add_mynetworks_hosts() {
+ myhosts=
+ for host in mailserver "$@"; do
+ IP=$(host ${host} | sed -n 's/.*has address //p')
+ myhosts="${myhosts} ${IP}/32"
+ done
+ postconf "mynetworks =${myhosts}"
+}
+
+# Create given users, requiring a plain-text password in `/tmp/passwd/`.
+add_users_with_passwd() {
+ for user in "$@"; do
+ i=0
+ while [ -z "$(cat /tmp/passwd/${user}/secret 2>/dev/null)" ]; do
+ if [ ${i} -eq 10 ]; then
+ echo "ERROR: No password file for '${user}' after ${i}s."
+ exit 1
+ fi
+ sleep 1
+ i=$((i+1))
+ done
+
+ if [ ! -d /var/mail/${HOSTNAME#mail.}/${user} ]; then
+ setup email add gerrit@${HOSTNAME#mail.} $(cat /tmp/passwd/${user}/secret)
+ else
+ setup email update gerrit@${HOSTNAME#mail.} $(cat /tmp/passwd/${user}/secret)
+ fi
+ done
+}
+
{
- setup email list | grep -q '^\* gerrit@' || setup email add gerrit@${HOSTNAME#mail.} psst,gerrit
+ add_users_with_passwd gerrit
+
+ # Restrict gerrit@ sending to local IP:
+ if ! grep -q gerrit /tmp/docker-mailserver/user.access 2>/dev/null; then
+ echo "gerrit@${HOSTNAME#mail.} gerrit_sender_check" >>/tmp/docker-mailserver/user.access
+ postmap /tmp/docker-mailserver/user.access
+ fi
+ IP=$(host gerrit | sed -n 's/.*has address //p')
+ echo "${IP} permit_sasl_authenticated" >/tmp/docker-mailserver/gerrit-client.access
+ postmap /tmp/docker-mailserver/gerrit-client.access
}