diff options
-rw-r--r-- | etc/guix/system.scm | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/etc/guix/system.scm b/etc/guix/system.scm index 943f63d..56505b9 100644 --- a/etc/guix/system.scm +++ b/etc/guix/system.scm @@ -1,4 +1,24 @@ (use-modules + + (xyz euandreh queue) + (gnu packages mail) + (gnu packages admin) + (guix download) + (guix build-system gnu) + ((guix licenses) #:prefix license:) + (guix records) + (gnu services mail) + (gnu services shepherd) + (gnu system setuid) + (gnu packages dbm) + (gnu packages cyrus-sasl) + (gnu packages onc-rpc) + (gnu packages tls) + (gnu packages perl) + (gnu packages m4) + (guix utils) + + ((xyz euandreh heredoc) #:prefix heredoc:) (gnu bootloader) (gnu bootloader grub) @@ -27,10 +47,272 @@ (heredoc:enable-syntax) (define whoami "andreh") +(define priv-statedir (string-append "/var/lib/" whoami)) (define toph "toph") (define toph.tld "arrobaponto.org") +(define-record-type* <postfix-configuration> + postfix-configuration + make-postfix-configuration + postfix-configuration? + (postfix postfix-configuration-postfix (default postfix)) + (set-sendmail? postfix-configuration-set-sendmail? (default #t)) + (master.cf-file postfix-configuration-master.cf-file (default #f)) + (main.cf-file postfix-configuration-main.cf-file (default #f)) + (master.cf-extra postfix-configuration-master.cf-extra (default "")) + (main.cf-extra postfix-configuration-main.cf-extra (default "")) + (data-directory postfix-configuration-data-directory (default "/var/lib/postfix")) + (queue-directory postfix-configuration-queue-directory (default "/var/spool/postfix")) + (user postfix-configuration-user (default "postfix")) + (group postfix-configuration-group (default "postfix")) + (setgid-group postfix-configuration-setgid-group (default "postdrop")) + (root-aliases postfix-configuration-root-aliases (default '("abuse" "admin" "hostmaster" "postmaster"))) + (cert-file postfix-configuration-cert-file (default #f)) + (key-file postfix-configuration-key-file (default #f)) + (hostname postfix-configuration-hostname (default (gethostname)))) + +(define (generate-master.cf config) + (match-record config <postfix-configuration> + (master.cf-extra) + (format #f + #"- + # ============================================================================================================ + # service type private unpriv chroot wakeup maxproc command + args + # (yes) (yes) (no) (never) (100) + # ============================================================================================================= + + + anvil unix - - n - 1 anvil + bounce unix - - n - 0 bounce + cleanup unix n - n - 0 cleanup + defer unix - - n - 0 bounce + discard unix - - n - - discard + error unix - - n - - error + flush unix n - n 1000? 0 flush + lmtp unix - - n - - lmtp + local unix - n n - - local + pickup unix n - n 60 1 pickup + proxymap unix - - n - - proxymap + proxywrite unix - - n - 1 proxymap + qmgr unix n - n 300 1 qmgr + relay unix - - n - - smtp + retry unix - - n - - error + rewrite unix - - n - - trivial-rewrite + scache unix - - n - 1 scache + showq unix n - n - - showq + smtp unix - - n - - smtp + smtp inet n - n - - smtpd -v -o syslog_name=postfix/smtp + tlsmgr unix - - n 1000? 1 tlsmgr + trace unix - - n - 0 bounce + verify unix - - n - 1 verify + virtual unix - n n - - virtual + postlog unix-dgram n - n - 1 postlogd + ~a + "# + master.cf-extra))) + +(define (generate-main.cf config) + (match-record config <postfix-configuration> + (postfix queue-directory data-directory user setgid-group hostname main.cf-extra) + (format #f + #"- + compatibility_level = 3.6 + + mynetworks = 127.0.0.0/8 + + queue_directory = ~a + data_directory = ~a + mail_owner = ~a + setgid_group = ~a + + # myhostname = ~a + # mydestination = $myhostname, $mydomain, localhost.$mydomain, localhost + + alias_maps = hash:/etc/aliases + + home_mailbox = Mail/Inbox + + header_checks = regexp:{ { /^Received:.*/ IGNORE }, { /^X-Originating-IP:.*/ IGNORE } } + ~a + + sender_dependent_relayhost_maps = hash:~a/postfix/relayhosts-maps + smtp_sasl_auth_enable = yes + smtp_sasl_password_maps = hash:~a/postfix/sasl-password + smtp_sasl_security_options = noanonymous + smtp_tls_security_level = encrypt + smtp_tls_note_starttls_offer = yes + smtp_use_tls = yes + smtp_sender_dependent_authentication = yes + smtp_sasl_mechanism_filter = login, plain + "# + queue-directory + data-directory + user + setgid-group + hostname + ;; hostname + main.cf-extra + priv-statedir + priv-statedir))) + +(define (postfix-etc-files config) + (match-record config <postfix-configuration> + (master.cf-file main.cf-file) + `(("postfix" + ,(file-union + "postfix" + `(("master.cf" ,(plain-file "master.cf" (or master.cf-file (generate-master.cf config)))) + ("main.cf" ,(plain-file "main.cf" (or main.cf-file (generate-main.cf config)))))))))) + +(define (postfix-accounts config) + (match-record config <postfix-configuration> + (user group setgid-group) + (list + (user-account + (name user) + (group group) + (comment "Postfix system user") + (home-directory "/var/empty") + (shell (file-append shadow "/sbin/nologin")) + (system? #t)) + (user-group + (name group) + (system? #t)) + (user-group + (name setgid-group) + (system? #t))))) + +(define (postfix-setuid-programs config) + (match-record config <postfix-configuration> + (postfix setgid-group set-sendmail?) + (append + (list + (setuid-program + (program (file-append postfix "/sbin/postdrop")) + (setuid? #f) + (setgid? #t) + (group setgid-group)) + (setuid-program + (program (file-append postfix "/sbin/postqueue")) + (setuid? #f) + (setgid? #t) + (group setgid-group))) + (if set-sendmail? + (list + (setuid-program + (program (file-append postfix "/sbin/sendmail")) + (setuid? #f) + (setgid? #t) + (group setgid-group))) + '())))) + +(define (postfix-activation config) + (match-record config <postfix-configuration> + (queue-directory) + #~(begin + (use-modules (guix build utils)) + (let ((user (getpwnam "root"))) + (format (current-error-port) + "Creating Postfix queue directory: \"~a\".~%" #$queue-directory) + (mkdir-p #$queue-directory) + (chown #$queue-directory (passwd:uid user) (passwd:gid user)) + (chmod #$queue-directory #o755) + (format (current-error-port) + "Creating email spool director: \"/var/mail\".~%") + (mkdir-p "/var/mail") + (format (current-error-port) + "Updating /etc/aliases.~%") + (invoke #$(file-append postfix "/bin/newaliases")))))) + +(define (postfix-shepherd-service config) + (match-record config <postfix-configuration> + (postfix data-directory) + (list + (shepherd-service + (provision '(postfix)) + (documentation + #"- + Run the Postfix MTA. + + This is the entrypoint for starting the "master" process. Then the + "master" process itself takes responsability of starting all the + required daemons and commands."#) + (start #~(make-forkexec-constructor + (list + #$(file-append postfix "/sbin/postfix") + "-v" + "start-fg") + #:pid-file (string-append #$data-directory "/master.lock"))) + (stop #~(make-kill-destructor)) + (actions + (list + (shepherd-action + (name 'reload) + (documentation + #"- + Re-read the "master.cf" and "main.cf" configuration files. + + Daemon processes terminate when possible, and when restarted + use the values of the new configuration files. + + This live-reload option is usually preferable over a stop/start + cycle, as it incurs in no interruption of the running service."#) + (procedure + #~(lambda _ + (invoke #$(file-append postfix "/sbin/postfix") "reload")))))))))) + +(define (postfix-aliases config) + (match-record config <postfix-configuration> + (root-aliases) + (map (lambda (alias) + `(,alias "root")) + root-aliases))) + +(define postfix-service-type + (service-type + (name 'postfix) + (extensions + (list + (service-extension etc-service-type + postfix-etc-files) + (service-extension account-service-type + postfix-accounts) + (service-extension setuid-program-service-type + postfix-setuid-programs) + (service-extension activation-service-type + postfix-activation) + (service-extension mail-aliases-service-type + postfix-aliases) + (service-extension profile-service-type + (compose list postfix-configuration-postfix)) + (service-extension shepherd-root-service-type + postfix-shepherd-service))) + (default-value (postfix-configuration)) + (description + #"- + Run the Postfix MTA. + + This is the top-level system service for Postfix. + + It includes: + - populating /etc/postfix/ with read-only configuration files; + - the user and groups used by Postfix when handling email delivery; + - the special setgid binaries for daily usage, such as "sendmail"; + - the Shepherd service for starting, stopping and *reloading* the + service without restarting it; + - the activation script for creating the required directories and + configuring them with the correct permissions; + - the binaries in the system profile so that one doesn't need to explicilty + include the package when the service is already enabled. + + An extension to the log-rotation service isn't included: the default + rottlog configuration already includes /var/log/maillog in its routine, + so it is kept out. + The defaults of <postfix-configuration> provide sane default values for + most things, such as group names, data and queue directories, etc. When + used as-is, it creates a Postfix server that sends email from local users + of the domain provided by "/etc/hostname"."#))) (operating-system (kernel linux) @@ -106,6 +388,7 @@ (mkdir-p #$priv-statedir) (chown #$priv-statedir (passwd:uid user) (passwd:gid user)) (chmod #$priv-statedir #o700)))) + (service postfix-service-type) (service mail-aliases-service-type `(("root" ,whoami))) (service wireguard-service-type |