use alpine packages, no longer need to compile ourselves
All checks were successful
Build Multiarch Container Image / call-reusable-workflow (push) Successful in 1m0s

This commit is contained in:
Sebastian Hugentobler 2024-04-26 14:55:30 +02:00
parent 659e14a87d
commit f45cab5235
Signed by: shu
GPG Key ID: BB32CF3CA052C2F0
10 changed files with 130 additions and 155 deletions

View File

@ -1,93 +1,84 @@
FROM docker.io/alpine:3.19 as builder
RUN apk --no-cache add \
rpcgen \
g++ \
make \
openssl \
openssl-dev \
lua5.1-dev \
libsodium-dev \
linux-pam-dev \
zlib-dev \
bzip2-dev \
xz-dev \
lz4-dev \
icu-dev \
inotify-tools-dev
ENV SHA256_SUM_DOVECOT=05b11093a71c237c2ef309ad587510721cc93bbee6828251549fc1586c36502d
ENV DOVECOT_FILENAME=dovecot-2.3.21.tar.gz
RUN wget https://www.dovecot.org/releases/2.3/$DOVECOT_FILENAME
RUN echo "$SHA256_SUM_DOVECOT $DOVECOT_FILENAME" | sha256sum -c - || exit 1
RUN mkdir /tmp/dovecot
RUN tar xzf $DOVECOT_FILENAME -C /tmp/dovecot --strip 1
ENV SHA256_SUM_PIGEONHOLE=1ca71d2659076712058a72030288f150b2b076b0306453471c5261498d3ded27
ENV PIGEONHOLE_FILENAME=dovecot-2.3-pigeonhole-0.5.21.tar.gz
RUN wget https://pigeonhole.dovecot.org/releases/2.3/$PIGEONHOLE_FILENAME
RUN echo "$SHA256_SUM_PIGEONHOLE $PIGEONHOLE_FILENAME" | sha256sum -c - || exit 1
RUN mkdir /tmp/pigeonhole
RUN tar xzf $PIGEONHOLE_FILENAME -C /tmp/pigeonhole --strip 1
RUN cd /tmp/dovecot && \
./configure --prefix '' \
--with-notify=inotify \
--with-lua \
--with-zlib \
--with-bzlib \
--with-pam \
--with-ssl=openssl \
--with-sodium \
--without-sql \
--with-lzma \
--with-lz4 \
--with-icu \
--without-shadow \
--with-ssldir=/etc/ssl/mail \
--with-rundir=/run/dovecot \
--disable-static && \
make && \
make install
RUN cd /tmp/pigeonhole && \
./configure --prefix '' \
--with-dovecot=/lib/dovecot \
--disable-static && \
make && make install
# FROM docker.io/alpine:3.19 as builder
#
# RUN apk --no-cache add \
# rpcgen \
# g++ \
# make \
# openssl \
# openssl-dev \
# lua5.1-dev \
# libsodium-dev \
# linux-pam-dev \
# zlib-dev \
# bzip2-dev \
# xz-dev \
# lz4-dev \
# icu-dev \
# inotify-tools-dev
#
# ENV SHA256_SUM_DOVECOT=05b11093a71c237c2ef309ad587510721cc93bbee6828251549fc1586c36502d
# ENV DOVECOT_FILENAME=dovecot-2.3.21.tar.gz
# RUN wget https://www.dovecot.org/releases/2.3/$DOVECOT_FILENAME
# RUN echo "$SHA256_SUM_DOVECOT $DOVECOT_FILENAME" | sha256sum -c - || exit 1
# RUN mkdir /tmp/dovecot
# RUN tar xzf $DOVECOT_FILENAME -C /tmp/dovecot --strip 1
#
# ENV SHA256_SUM_PIGEONHOLE=1ca71d2659076712058a72030288f150b2b076b0306453471c5261498d3ded27
# ENV PIGEONHOLE_FILENAME=dovecot-2.3-pigeonhole-0.5.21.tar.gz
# RUN wget https://pigeonhole.dovecot.org/releases/2.3/$PIGEONHOLE_FILENAME
# RUN echo "$SHA256_SUM_PIGEONHOLE $PIGEONHOLE_FILENAME" | sha256sum -c - || exit 1
# RUN mkdir /tmp/pigeonhole
# RUN tar xzf $PIGEONHOLE_FILENAME -C /tmp/pigeonhole --strip 1
#
# RUN cd /tmp/dovecot && \
# ./configure --prefix '' \
# --with-notify=inotify \
# --with-lua \
# --with-zlib \
# --with-bzlib \
# --with-pam \
# --with-ssl=openssl \
# --with-sodium \
# --without-sql \
# --with-lzma \
# --with-lz4 \
# --with-icu \
# --without-shadow \
# --with-ssldir=/etc/ssl/mail \
# --with-rundir=/run/dovecot \
# --disable-static && \
# make && \
# make install
#
# RUN cd /tmp/pigeonhole && \
# ./configure --prefix '' \
# --with-dovecot=/lib/dovecot \
# --disable-static && \
# make && make install
FROM docker.io/thallian/confd-env:3.19-3.1.6.2
COPY --from=builder /lib/dovecot/ /lib/dovecot/
COPY --from=builder /libexec/dovecot/ /libexec/dovecot/
COPY --from=builder /bin/doveadm /bin/doveadm
COPY --from=builder /bin/doveconf /bin/doveconf
COPY --from=builder /bin/dsync /bin/dsync
COPY --from=builder /sbin/dovecot /sbin/dovecot
COPY --from=builder /bin/sieve* /bin/
# COPY --from=builder /lib/dovecot/ /lib/dovecot/
# COPY --from=builder /libexec/dovecot/ /libexec/dovecot/
# COPY --from=builder /bin/doveadm /bin/doveadm
# COPY --from=builder /bin/doveconf /bin/doveconf
# COPY --from=builder /bin/dsync /bin/dsync
# COPY --from=builder /sbin/dovecot /sbin/dovecot
# COPY --from=builder /bin/sieve* /bin/
RUN apk --no-cache add \
libsodium \
libbz2 \
zlib \
xz-libs \
lz4-libs \
lz4 \
linux-pam \
openssl \
ssmtp \
ca-certificates \
lua5.1-libs \
lua5.1-rapidjson \
curl \
inotify-tools \
libssl3
dovecot \
dovecot-pgsql \
dovecot-lmtpd \
dovecot-pigeonhole-plugin
RUN addgroup -g 150 dovecot
RUN adduser -u 140 -h /dev/null -H -s /sbin/nologin -D -G dovecot dovecot
RUN addgroup -g 151 dovenull
RUN adduser -u 141 -h /dev/null -H -s /sbin/nologin -D -G dovenull dovenull
# RUN addgroup -g 150 dovecot
# RUN adduser -u 140 -h /dev/null -H -s /sbin/nologin -D -G dovecot dovecot
#
# RUN addgroup -g 151 dovenull
# RUN adduser -u 141 -h /dev/null -H -s /sbin/nologin -D -G dovenull dovenull
RUN addgroup -g 2222 access
RUN addgroup dovecot access

View File

@ -1,75 +1,101 @@
[Dovecot](http://www.dovecot.org/) with imap, starttls, oauth2 proxy auth and sieve rules.
[Dovecot](http://www.dovecot.org/) with imap, starttls, oauth2 proxy auth and
sieve rules.
Uses [SSMTP](https://packages.debian.org/stable/mail/ssmtp) to send mails (for example if you have a redirect sieve rule).
Uses [SSMTP](https://packages.debian.org/stable/mail/ssmtp) to send mails (for
example if you have a redirect sieve rule).
Reuses the same database schema as the {postfix container](/container/postfix).
# Volumes
- `/var/lib/vmail/mail`
# Environment Variables
## HOSTNAME
Fully qualified name of the mail host.
## GRANT_URL
OAuth2 url for token grants (password grant type).
## INTROSPECTION_URL
OAuth2 url for token information.
## USER_URL
OAuth2 url for getting available users, the username will be appended to the end.
OAuth2 url for token information. Must include client id and client secret in
basic auth format.
## TOKENINFO_URL
OAuth2 url for requestion information about a token.
## TOKENINFO_URL
## CLIENT_ID
Id of the OAuth2 application.
OAuth2 url for requestion information about a token. Must include client id and
client secret in basic auth format.
## CLIENT_SECRET
Secret of the OAuth2 application.
## DB_HOST
## OAUTH_ADMIN_USER
User with which to perform user lookups (does not have to be an admin, but needs enough rights for that).
Postgre database host.
## OAUTH_ADMIN_PASSWORD
Password for the `OAUTH_ADMIN_USER`.
## DB_USER
User to connect to the database.
## DB_PW
Password to use for the database user.
## DB_NAME
- default: email
Name of the postgre database to connect to.
## SSMTP_MAIL_RELAY
Hostname and port for the used smtp relay (for example `mail.example.com:587`).
## SSMTP_USER
User to authenticate agains the smtp relay.
## SSMTP_PASSWORD
Password to authenticate agains the smtp relay.
## SSMTP_AUTH_METHOD
- default: LOGIN
Which authentication mechanism to use for the smtp relay.
## SSMTP_USE_STARTTLS
- default: yes
Whether to use starttls for the smtp relay.
## ALLOWED_USERNAME_CHARS
- default: äöüabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@
- default:
äöüabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@
List of characters allowed in a username.
## AUTH_MECHANISMS
- default: plain
Space seperated list of supported [authentication mechanisms](http://wiki2.dovecot.org/Authentication/Mechanisms).
Space seperated list of supported
[authentication mechanisms](http://wiki2.dovecot.org/Authentication/Mechanisms).
## SSL_MIN_PROTOCOL
- default: TLSv1.2
Ssl minimum protocol version.
## SSL_CIPHERLIST
- default: ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
- default:
ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
Colon seperated list of supported ciphers (`!`disables a cipher).
@ -77,14 +103,17 @@ Go [here](https://www.openssl.org/docs/manmaster/man1/ciphers.html) for a list
of ciphers.
## IMAP_MAX_USER_CONNECTIONS
- default: 10
Maximum number of connections from the same user + ip.
# Ports
- 143
# Capabilities
- CHOWN
- DAC_OVERRIDE
- FOWNER

View File

@ -0,0 +1,3 @@
[template]
src = "dovecot-sql.userdb.conf.ext.tmpl"
dest = "/etc/dovecot/dovecot-sql.userdb.conf.ext"

View File

@ -1,3 +0,0 @@
[template]
src = "oauth2-userdb.lua.tmpl"
dest = "/etc/dovecot/oauth2-userdb.lua"

View File

@ -23,4 +23,4 @@ namespace inbox {
}
}
mail_plugin_dir = /lib/dovecot
mail_plugin_dir = /usr/lib/dovecot

View File

@ -11,6 +11,7 @@ passdb {
}
userdb {
driver = lua
args = file=/etc/dovecot/oauth2-userdb.lua blocking=yes
driver = sql
args = /etc/dovecot/dovecot-sql.userdb.conf.ext
default_fields = uid=vmail gid=vmail home=/var/lib/vmail/mail/%u
}

View File

@ -1,6 +1,4 @@
grant_url = {{ getenv "GRANT_URL" }}
client_id = {{ getenv "CLIENT_ID" }}
client_secret = {{ getenv "CLIENT_SECRET" }}
introspection_url = {{ getenv "INTROSPECTION_URL" }}
introspection_mode = {{ getenv "INTROSPECTION_MODE" "post" }}
username_attribute = username

View File

@ -1,6 +1,4 @@
grant_url = {{ getenv "GRANT_URL" }}
client_id = {{ getenv "CLIENT_ID" }}
client_secret = {{ getenv "CLIENT_SECRET" }}
tokeninfo_url = {{ getenv "TOKENINFO_URL" }}
introspection_url = {{ getenv "INTROSPECTION_URL" }}
introspection_mode = {{ getenv "INTROSPECTION_MODE" "post" }}
@ -8,4 +6,3 @@ username_attribute = username
tls_ca_cert_file = /etc/ssl/certs/ca-certificates.crt
use_grant_password = no
pass_attrs = pass=%{oauth2:access_token}

View File

@ -0,0 +1,3 @@
driver = pgsql
connect = host={{ getenv "DB_HOST" }} dbname={{ getenv "DB_NAME" }} user={{ getenv "DB_USER" }} password={{ getenv "DB_PW" }}
user_query = SELECT COUNT(email) as count FROM virtual_users WHERE email = '%n' HAVING COUNT(email) > 0;

View File

@ -1,44 +0,0 @@
local rapidjson = require('rapidjson')
local clientId = "{{ getenv "CLIENT_ID" }}"
local clientSecret = "{{ getenv "CLIENT_SECRET" }}"
local username = "{{ getenv "OAUTH_ADMIN_USER" }}"
local password = "{{ getenv "OAUTH_ADMIN_PASSWORD" }}"
local tokenUrl = "{{ getenv "GRANT_URL" }}"
local userUrl = "{{ getenv "USER_URL" }}"
function os.capture(cmd, raw)
local f = assert(io.popen(cmd, 'r'))
local s = assert(f:read('*a'))
f:close()
return s
end
function auth_userdb_lookup(req)
local tokenCmd = "curl -L --silent -X POST -d \"grant_type=password\""
tokenCmd = tokenCmd .. " -d \"client_id=" .. clientId .. "\""
tokenCmd = tokenCmd .. " -d \"client_secret=" .. clientSecret .. "\""
tokenCmd = tokenCmd .. " -d \"username=" .. username .. "\""
tokenCmd = tokenCmd .. " -d \"password=" .. password .. "\""
tokenCmd = tokenCmd .. " \"" .. tokenUrl .. "\""
local tokenRaw = os.capture(tokenCmd)
local tokenJson = rapidjson.decode(tokenRaw)
local accessToken = tokenJson.access_token
local userCmd = "curl -L --silent -H \"Authorization: Bearer " .. accessToken .. "\" \"" .. userUrl .. req.username .. "\""
local userRaw = os.capture(userCmd)
local userJson = rapidjson.decode(userRaw)
if #userJson == 0 then
return dovecot.auth.USERDB_RESULT_USER_UNKNOWN, "no such user"
end
if userJson[1].username == req.username then
return dovecot.auth.USERDB_RESULT_OK, "uid=vmail gid=vmail home=/var/lib/vmail/mail/" .. req.username
end
return dovecot.auth.USERDB_RESULT_USER_UNKNOWN, "no such user"
end