Compare commits

..

No commits in common. "main" and "2.3.19.1" have entirely different histories.

16 changed files with 192 additions and 113 deletions

View File

@ -1,12 +0,0 @@
name: Build Multiarch Container Image
on: [push]
jobs:
call-reusable-workflow:
uses: container/multiarch-build-workflow/.gitea/workflows/build.yaml@main
with:
repository: ${{ gitea.repository }}
ref_name: ${{ gitea.ref_name }}
sha: ${{ gitea.sha }}
registry_url: ${{ secrets.REGISTRY_URL }}
registry_user: ${{ secrets.REGISTRY_USER }}
registry_pw: ${{ secrets.REGISTRY_PW }}

11
.woodpecker.yml Normal file
View File

@ -0,0 +1,11 @@
pipeline:
publish-docker-image:
image: plugins/kaniko
settings:
repo: docker.io/thallian/dovecot
tags: latest,${CI_COMMIT_SHA:0:8},${CI_COMMIT_TAG=pre}
dockerfile: Dockerfile
username:
from_secret: DOCKER_USER
password:
from_secret: DOCKER_PW

View File

@ -1,25 +0,0 @@
FROM docker.io/thallian/confd-env:3.20-3.1.6.2
RUN apk --no-cache add \
ssmtp \
dovecot \
dovecot-pgsql \
dovecot-lmtpd \
dovecot-pigeonhole-plugin
RUN addgroup -g 2222 access
RUN addgroup dovecot access
RUN addgroup -g 1111 vmail
RUN adduser -u 1111 -h /var/lib/vmail -D -G vmail vmail
RUN mkdir -p /etc/dovecot/conf.d
RUN mkdir /var/lib/vmail/sieve-after/
RUN chown -R vmail:vmail /var/lib/vmail/sieve-after/
EXPOSE 143 4190 6334 7777
VOLUME /var/lib/vmail/mail/ /etc/ssl/mail
ADD /rootfs /

107
Dockerfile Normal file
View File

@ -0,0 +1,107 @@
FROM docker.io/alpine:3.17 as builder
RUN apk --no-cache add \
rpcgen \
g++ \
make \
openssl \
openssl-dev \
lua-dev \
libsodium-dev \
linux-pam-dev \
zlib-dev \
bzip2-dev \
xz-dev \
lz4-dev \
icu-dev \
inotify-tools-dev
ENV SHA256_SUM_DOVECOT=db5abcd87d7309659ea6b45b2cb6ee9c5f97486b2b719a5dd05a759e1f6a5c51
ENV DOVECOT_FILENAME=dovecot-2.3.19.1.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=637709a83fb1338c918e5398049f96b7aeb5ae00696794ed1e5a4d4c0ca3f688
ENV PIGEONHOLE_FILENAME=dovecot-2.3-pigeonhole-0.5.19.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.16
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 \
lua \
lua-rapidjson \
curl \
inotify-tools \
libssl3
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
RUN addgroup -g 1111 vmail
RUN adduser -u 1111 -h /var/lib/vmail -D -G vmail vmail
RUN mkdir -p /etc/dovecot/conf.d
RUN mkdir /var/lib/vmail/sieve-after/
RUN chown -R vmail:vmail /var/lib/vmail/sieve-after/
EXPOSE 143 4190 6334 7777
VOLUME /var/lib/vmail/mail/ /etc/ssl/mail
ADD /rootfs /

View File

@ -1,101 +1,75 @@
[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.
OAuth2 url for token information. Must include client id and client secret in
basic auth format.
## USER_URL
OAuth2 url for getting available users, the username will be appended to the end.
## TOKENINFO_URL
OAuth2 url for requestion information about a token.
OAuth2 url for requestion information about a token. Must include client id and
client secret in basic auth format.
## CLIENT_ID
Id of the OAuth2 application.
## DB_HOST
## CLIENT_SECRET
Secret of the OAuth2 application.
Postgre database host.
## OAUTH_ADMIN_USER
User with which to perform user lookups (does not have to be an admin, but needs enough rights for that).
## 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.
## OAUTH_ADMIN_PASSWORD
Password for the `OAUTH_ADMIN_USER`.
## 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).
@ -103,17 +77,14 @@ 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

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

View File

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

View File

@ -1,5 +1,4 @@
auth_username_chars = {{getenv "ALLOWED_USERNAME_CHARS" "äöüabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@"}}
auth_username_format ="%Ln"
auth_mechanisms = {{getenv "AUTH_MECHANISMS" "plain login oauthbearer xoauth2"}}
disable_plaintext_auth = no
!include auth-oauth2.conf.ext

View File

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

View File

@ -2,11 +2,6 @@ service imap-login {
inet_listener imap {
port = 143
}
inet_listener imaps {
port = 993
ssl = yes
}
}
service lmtp {
@ -26,16 +21,3 @@ service auth {
service auth-worker {
}
service anvil {
chroot =
}
service imap-login {
chroot =
}
service pop3-login {
chroot =
}
service ipc {
chroot =
}

View File

@ -5,6 +5,7 @@ protocols = $protocols sieve
service managesieve-login {
inet_listener sieve {
port = 4190
address = localhost
}
#inet_listener sieve_deprecated {

View File

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

View File

@ -1,4 +1,6 @@
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,4 +1,6 @@
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" }}
@ -6,3 +8,4 @@ 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

@ -1,3 +0,0 @@
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

@ -0,0 +1,44 @@
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/%n"
end
return dovecot.auth.USERDB_RESULT_USER_UNKNOWN, "no such user"
end