Compare commits

...

10 Commits

Author SHA1 Message Date
573d71fd8c
update alpine version
All checks were successful
Build Multiarch Container Image / call-reusable-workflow (push) Successful in 1m4s
2024-06-27 09:14:06 +02:00
7f169c3896
can not disable plaintext auth yet, breaks sieve
All checks were successful
Build Multiarch Container Image / call-reusable-workflow (push) Successful in 1m14s
2024-04-26 22:08:09 +02:00
88645e7dd0
add imaps listener
All checks were successful
Build Multiarch Container Image / call-reusable-workflow (push) Successful in 1m14s
2024-04-26 20:23:06 +02:00
f45cab5235
use alpine packages, no longer need to compile ourselves
All checks were successful
Build Multiarch Container Image / call-reusable-workflow (push) Successful in 1m0s
2024-04-26 14:55:30 +02:00
659e14a87d
return proper home dir from userdb 2024-02-18 11:57:05 +01:00
09cf75eccb
push to 2.3.21 2023-09-26 16:05:12 +02:00
edb0b700b0
add missig continuation line 2023-02-16 22:40:47 +01:00
8fa36e7ded
fix lua dependencies to lua 5.1 2023-02-16 22:39:21 +01:00
5724cc82eb
disable service chroots until I understand the problems properly 2023-02-16 22:15:08 +01:00
87adbb9b0c push to 2.3.20 2023-01-25 08:33:01 +01:00
16 changed files with 113 additions and 192 deletions

View File

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

View File

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

25
Containerfile Normal file
View File

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

View File

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

@ -1,4 +1,5 @@
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 = /lib/dovecot
mail_plugin_dir = /usr/lib/dovecot

View File

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

View File

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

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