aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWojtek Kosior <koszko@koszko.org>2023-09-01 13:57:48 +0200
committerWojtek Kosior <koszko@koszko.org>2023-09-01 14:42:30 +0200
commit816ff7ecd4a39c9918141c9fee10932cecb52565 (patch)
tree82598a73ffa03ab0e263b15109057a6e60610fc6
parentb659857f486ac1fe696c3d57c43a002cfb05b784 (diff)
downloadkoszko-org-server-816ff7ecd4a39c9918141c9fee10932cecb52565.tar.gz
koszko-org-server-816ff7ecd4a39c9918141c9fee10932cecb52565.zip
Add Dovecot to the container
-rw-r--r--Makefile13
-rw-r--r--container.scm75
-rwxr-xr-xguix-container.sh44
3 files changed, 116 insertions, 16 deletions
diff --git a/Makefile b/Makefile
index 524c437..f1e8fbe 100644
--- a/Makefile
+++ b/Makefile
@@ -76,6 +76,7 @@ sample-malcontent:
LETSENCRYPT_ETC_DIR = $(TEST_ROOT_DIR)/etc/letsencrypt
EXIM_ETC_DIR = $(TEST_ROOT_DIR)/etc/exim
+DOVECOT_ETC_DIR = $(TEST_ROOT_DIR)/etc/dovecot
HYDRILLA_WEBSITE_ETC_DIR = $(TEST_ROOT_DIR)/etc/guix-container/hydrilla-website
MALCONTENT_DIR = $(TEST_ROOT_DIR)/var/lib/hydrilla/malcontent_dirs
GITOLITE_DIR = $(TEST_ROOT_DIR)/var/lib/gitolite3
@@ -131,6 +132,18 @@ prepare-test-root: sample-malcontent
echo >> $(EXIM_ETC_DIR)/passwd
chmod 640 $(EXIM_ETC_DIR)/passwd
chown 106:113 $(EXIM_ETC_DIR)/passwd
+ @# Prepare replacement `/etc/dovecot`
+ mkdir --mode=755 -p $(DOVECOT_ETC_DIR)
+ printf koszko: > $(DOVECOT_ETC_DIR)/users
+ $(GUIX_SHELL) -C --no-cwd dovecot coreutils bash-minimal -- \
+ bash -c 'mkdir /etc/dovecot; \
+ touch /etc/dovecot/dovecot.conf; \
+ doveadm pw -s SHA256-CRYPT -p silnehaslo;' \
+ >> $(DOVECOT_ETC_DIR)/users
+ sed -i 's|$$|:1000:1000::/home/urz:/bin/bash:userdb_mail=maildir:/home/urz/Maildir/|' \
+ $(DOVECOT_ETC_DIR)/users
+ chmod 640 $(DOVECOT_ETC_DIR)/users
+ chgrp 115 $(DOVECOT_ETC_DIR)/users
@# Prepare replacement `/etc`
mkdir --mode=750 -p $(HYDRILLA_WEBSITE_ETC_DIR)
printf 'test non-secret\n' > $(HYDRILLA_WEBSITE_ETC_DIR)/secret.txt
diff --git a/container.scm b/container.scm
index 046a8c1..a2f3cb6 100644
--- a/container.scm
+++ b/container.scm
@@ -560,6 +560,55 @@ exim_path = /run/setuid-programs/exim
("koszko" "urz")
("my-contribution-is-licensed-cc0" "urz"))))
+(define koszko-dovecot-service-type
+ (service-type
+ (inherit dovecot-service-type)
+ (extensions (filter-map
+ (lambda (ext)
+ (cond
+ ((extension-of-type? ext account-service-type)
+ ;; Avoid double declaration of "dovecot" and "dovenull"
+ ;; users and groups.
+ #f)
+ (else
+ ext)))
+ (service-type-extensions dovecot-service-type)))))
+
+(define %koszko-dovecot-service
+ (service koszko-dovecot-service-type
+ (dovecot-configuration
+ (services (list (service-configuration
+ (kind "imap-login")
+ (listeners (list (inet-listener-configuration
+ (protocol "imaps")
+ (port 993)
+ (ssl? #t))))
+ ;; '1' is more secure than '0' because each
+ ;; connection is handled in a separate process.
+ (service-count 1))
+ (service-configuration
+ (kind "imap"))
+ (service-configuration
+ (kind "auth")
+ (listeners (list (unix-listener-configuration
+ (path "auth-userdb"))))
+ ;; Dovecot requires process-limit to be 1 here.
+ (service-count 0)
+ (process-limit 1))))
+ (ssl-cert "</etc/letsencrypt/live/guixbot_koszko.org/fullchain.pem")
+ (ssl-key "</etc/letsencrypt/live/guixbot_koszko.org/privkey.pem")
+ (auth-mechanisms '("plain" "login"))
+ (passdbs (list (passdb-configuration
+ (driver "passwd-file")
+ (args '("scheme=CRYPT"
+ "username_format=%u"
+ "/etc/dovecot/users")))))
+ (userdbs (list (userdb-configuration
+ (driver "passwd-file")
+ (args '("username_format=%u"
+ "/etc/dovecot/users")))))
+ (mail-location "maildir:~/Maildir"))))
+
(operating-system
(host-name "koszko")
(timezone "Europe/Warsaw")
@@ -572,6 +621,14 @@ exim_path = /run/setuid-programs/exim
(id 113)
(system? #t))
(user-group
+ (name "dovecot")
+ (id 115)
+ (system? #t))
+ (user-group
+ (name "dovenull")
+ (id 116)
+ (system? #t))
+ (user-group
(name "httpd")
(id 133)
(system? #t))
@@ -601,6 +658,23 @@ exim_path = /run/setuid-programs/exim
(home-directory "/var/empty")
(shell (file-append shadow "/sbin/nologin")))
(user-account
+ (name "dovecot")
+ (group "dovecot")
+ (supplementary-groups '("certsaccess"))
+ (uid 108)
+ (system? #t)
+ (comment "Dovecot daemon user")
+ (home-directory "/var/empty")
+ (shell (file-append shadow "/sbin/nologin")))
+ (user-account
+ (name "dovenull")
+ (group "dovenull")
+ (uid 109)
+ (system? #t)
+ (comment "Dovecot daemon login user")
+ (home-directory "/var/empty")
+ (shell (file-append shadow "/sbin/nologin")))
+ (user-account
(name "httpd")
(group "httpd")
(supplementary-groups '("gitolite3" "certsaccess"))
@@ -661,4 +735,5 @@ exim_path = /run/setuid-programs/exim
%koszko-certbot-service
%koszko-exim-service
%koszko-mail-aliases-service
+ %koszko-dovecot-service
%base-services)))
diff --git a/guix-container.sh b/guix-container.sh
index 411e4ff..2a96b71 100755
--- a/guix-container.sh
+++ b/guix-container.sh
@@ -81,6 +81,7 @@ done
GUILE_PID=
SUCCESS=
QUIET_EXIT=
+FORWARDED_PORTLISTS="25,12525,465,587 993"
is_running() {
test -e "$PIDFILE" && test -n "$(ps -o pid= --pid $(cat "$PIDFILE"))"
@@ -118,16 +119,20 @@ network_setup() {
for LINKNAME in $(ip route | grep default | awk '{print $5}'); do
iptables -t nat -A POSTROUTING \
-s 10.207.87.1/24 -o "$LINKNAME" -j MASQUERADE
- iptables -t nat -A PREROUTING \
- -i "$LINKNAME" -p tcp \
- -m multiport --dports 25,12525,465,587 \
- -j DNAT --to-destination 10.207.87.2
+ for PORTLIST in $FORWARDED_PORTLISTS; do
+ iptables -t nat -A PREROUTING \
+ -i "$LINKNAME" -p tcp \
+ -m multiport --dports "$PORTLIST" \
+ -j DNAT --to-destination 10.207.87.2
+ done
done
- iptables -t nat -A OUTPUT \
- -d "$(resolve_ipv4_domain koszko.org)" -p tcp \
- -m multiport --dports 25,12525,465,587 \
- -j DNAT --to-destination 10.207.87.2
+ for PORTLIST in $FORWARDED_PORTLISTS; do
+ iptables -t nat -A OUTPUT \
+ -d "$(resolve_ipv4_domain koszko.org)" -p tcp \
+ -m multiport --dports "$PORTLIST" \
+ -j DNAT --to-destination 10.207.87.2
+ done
cat /etc/resolv.conf |
nsenter --target "$SHEPHERD_PID" --all \
@@ -154,19 +159,23 @@ network_rip() {
echo 0 > /proc/sys/net/ipv4/ip_forward
for LINKNAME in $(ip route | grep default | awk '{print $5}'); do
- iptables_rip_rule -t nat -D PREROUTING \
- -i "$LINKNAME" -p tcp \
- -m multiport --dports 25,12525,465,587 \
- -j DNAT --to-destination 10.207.87.2
+ for PORTLIST in $FORWARDED_PORTLISTS; do
+ iptables_rip_rule -t nat -D PREROUTING \
+ -i "$LINKNAME" -p tcp \
+ -m multiport --dports "$PORTLIST" \
+ -j DNAT --to-destination 10.207.87.2
+ done
iptables_rip_rule -t nat -D POSTROUTING \
-s 10.207.87.1/24 -o "$LINKNAME" \
-j MASQUERADE
done
- iptables_rip_rule -t nat -D OUTPUT \
- -d "$(resolve_ipv4_domain koszko.org)" -p tcp \
- -m multiport --dports 25,12525,465,587 \
- -j DNAT --to-destination 10.207.87.2
+ for PORTLIST in $FORWARDED_PORTLISTS; do
+ iptables_rip_rule -t nat -D OUTPUT \
+ -d "$(resolve_ipv4_domain koszko.org)" -p tcp \
+ -m multiport --dports "$PORTLIST" \
+ -j DNAT --to-destination 10.207.87.2
+ done
}
stop() {
@@ -222,6 +231,7 @@ start() {
LOG_REAL="$LOG_DIR"/container
ETC_LETSENCRYPT_REAL="$HOST_SYSTEM_ROOT"/etc/letsencrypt
ETC_EXIM_REAL="$HOST_SYSTEM_ROOT"/etc/exim
+ ETC_DOVECOT_REAL="$HOST_SYSTEM_ROOT"/etc/dovecot
ETC_REAL="$HOST_SYSTEM_ROOT"/etc/guix-container
VAR_SPOOL_EXIM_REAL="$HOST_SYSTEM_ROOT"/var/spool/exim
VAR_HYDRILLA_REAL="$HOST_SYSTEM_ROOT"/var/lib/hydrilla
@@ -234,6 +244,7 @@ start() {
LOG_DIR_SHARE_OPT=--share="$LOG_REAL"=/var/log
ETC_LETSENCRYPT_DIR_SHARE_OPT=--share="$ETC_LETSENCRYPT_REAL"=/etc/letsencrypt
ETC_EXIM_DIR_SHARE_OPT=--share="$ETC_EXIM_REAL"=/etc/exim
+ ETC_DOVECOT_DIR_SHARE_OPT=--share="$ETC_DOVECOT_REAL"=/etc/dovecot
ETC_DIR_SHARE_OPT=--share="$ETC_REAL"=/etc
VAR_SPOOL_EXIM_DIR_SHARE_OPT=--share="$VAR_SPOOL_EXIM_REAL"=/var/spool/exim
VAR_HYDRILLA_DIR_SHARE_OPT=--share="$VAR_HYDRILLA_REAL"=/var/lib/hydrilla
@@ -249,6 +260,7 @@ start() {
"$LOG_DIR_SHARE_OPT" \
"$ETC_LETSENCRYPT_DIR_SHARE_OPT" \
"$ETC_EXIM_DIR_SHARE_OPT" \
+ "$ETC_DOVECOT_DIR_SHARE_OPT" \
"$ETC_DIR_SHARE_OPT" \
"$VAR_SPOOL_EXIM_DIR_SHARE_OPT" \
"$VAR_HYDRILLA_DIR_SHARE_OPT" \