From 999e965d2ee820128a3fd04f160ec78f22971fbe Mon Sep 17 00:00:00 2001 From: Julian Rother <julian@cccv.de> Date: Tue, 26 Oct 2021 17:57:06 +0200 Subject: [PATCH] Debian packaging with fixed systemd unit files Co-authored-by: nd <nd@cccv.de> --- .gitlab-ci.yml | 15 ++- README.md | 29 ++++- cccv-archive-key.gpg | Bin 0 -> 1752 bytes debian/contrib/uffd-socketmap-postfix.conf | 7 ++ .../contrib/uffd-socketmap-postfix.service | 14 ++- debian/contrib/uffd-socketmap-postfix.socket | 11 ++ debian/control | 16 +++ debian/create_changelog.py | 106 ++++++++++++++++++ debian/install | 4 + debian/links | 1 + debian/postinst | 21 ++++ debian/rules | 3 + server.py | 1 + uffd-socketmap@.socket | 12 -- 14 files changed, 214 insertions(+), 26 deletions(-) create mode 100644 cccv-archive-key.gpg create mode 100644 debian/contrib/uffd-socketmap-postfix.conf rename uffd-socketmap@.service => debian/contrib/uffd-socketmap-postfix.service (70%) create mode 100644 debian/contrib/uffd-socketmap-postfix.socket create mode 100644 debian/control create mode 100755 debian/create_changelog.py create mode 100644 debian/install create mode 100644 debian/links create mode 100755 debian/postinst create mode 100755 debian/rules mode change 100644 => 100755 server.py delete mode 100644 uffd-socketmap@.socket diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a0eb5d3..10cafd6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ image: registry.git.cccv.de/uffd/docker-images/buster variables: - DEBIAN_FRONTEND: noninteractive + DEBIAN_FRONTEND: noninteractive GIT_SUBMODULE_STRATEGY: normal PYLINT_PIN: pylint~=2.10.0 @@ -12,6 +12,17 @@ before_script: - python3 -m pylint --version - python3 -m coverage --version +build:apt: + script: + - ./debian/create_changelog.py uffd-socketmap > debian/changelog + - dpkg-buildpackage -us -uc + - mv ../*.deb ./ + - dpkg-deb -I *.deb + - dpkg-deb -c *.deb + artifacts: + paths: + - ./*.deb + linter:bullseye: image: registry.git.cccv.de/uffd/docker-images/bullseye stage: test @@ -19,7 +30,7 @@ linter:bullseye: - pip3 install $PYLINT_PIN pylint-gitlab pylint-flask-sqlalchemy # this force-updates jinja2 and some other packages! - python3 -m pylint --exit-zero --rcfile .pylintrc --output-format=pylint_gitlab.GitlabCodeClimateReporter 'server.py' > codeclimate.json - python3 -m pylint --exit-zero --rcfile .pylintrc --output-format=pylint_gitlab.GitlabPagesHtmlReporter 'server.py' > pylint.html - - python3 -m pylint --rcfile .pylintrc --output-format=text 'server.py' + - python3 -m pylint --rcfile .pylintrc --output-format=text 'server.py' artifacts: when: always paths: diff --git a/README.md b/README.md index a4083d6..670f8e3 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,29 @@ -Socketmap proxy for uffd mail alias lookup -========================================== +Socketmap server to integrate uffd mail aliases with postfix +============================================================ + +[uffd](https://git.cccv.de/uffd/uffd) has features that rely on mail aliases. +To make those mail aliases work, it provides an API to lookup alias addresses +for a given address. uffd-socketmap uses this API to integrate alias lookup +with MTAs that support the socketmap protocol, like sendmail and postfix. + +uffd-socketmap can be run manually. For production deployments, use the +provided debian packages. Add our package mirror to `/etc/sources.list`: -Run it like this: ``` -SERVER_API_KEY=my_secret_api_key server.py --socket-path /var/run/uffd-socketmap.sock --api-url=https://sso.example.com +deb https://packages.cccv.de/uffd bullseye main ``` +Then download [cccv-archive-key.gpg](cccv-archive-key.gpg) and add it to +the trusted repository keys in `/etc/apt/trusted.gpg.d/`. Afterwards run +`apt update && apt install uffd-socketmap` to install the package. + +Set the API url and secret in `/etc/uffd-socketmap-postfix.conf`, enable +and start `uffd-socketmap-postfix.socket`. Then configure Postfix, e.g. +by adding the following lines to `/etc/postfix/main.cf`: -Configure Postfix to use it by setting `virtual_alias_maps` in `/etc/postfix/main.cf` like this: ``` -virtual_alias_maps = socketmap:unix:/var/run/uffd-socketmap.sock:virtual +# Note that postfix runs in a chroot (/var/spool/postfix) and paths are +# relative to that! +virtual_alias_maps = socketmap:unix:/uffd-socketmap.sock:virtual +# Defaults to $virtual_alias_maps, which does not work here, so unset it +virtual_alias_domains = ``` diff --git a/cccv-archive-key.gpg b/cccv-archive-key.gpg new file mode 100644 index 0000000000000000000000000000000000000000..b0ac4de43a0786a52060bade75c5150ac552ade7 GIT binary patch literal 1752 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 N_@ZXs9flCkAOI7rD7ydv literal 0 HcmV?d00001 diff --git a/debian/contrib/uffd-socketmap-postfix.conf b/debian/contrib/uffd-socketmap-postfix.conf new file mode 100644 index 0000000..c427afa --- /dev/null +++ b/debian/contrib/uffd-socketmap-postfix.conf @@ -0,0 +1,7 @@ +# Both options must be set +#SERVER_API_URL="https://localhost" +#SERVER_API_KEY="my_secret_api_token" + +# The socket path is hard-coded to "/var/spool/postfix/uffd-socketmap.sock" +# ("/uffd-socketmap.sock" in the postfix sandbox). Use systemd overwrites +# for uffd-socketmap-postfix.socket to change it. diff --git a/uffd-socketmap@.service b/debian/contrib/uffd-socketmap-postfix.service similarity index 70% rename from uffd-socketmap@.service rename to debian/contrib/uffd-socketmap-postfix.service index 50344e7..65a8275 100644 --- a/uffd-socketmap@.service +++ b/debian/contrib/uffd-socketmap-postfix.service @@ -1,17 +1,19 @@ [Unit] -Description=Socketmap proxy for uffd mail alias lookup +Description=Socketmap server to integrate uffd mail aliases with postfix After=network.target Before=postfix.service +BindsTo=uffd-socketmap-postfix.socket [Service] ExecStart=/usr/bin/uffd-socketmap --socket-fd 3 Restart=always RestartSec=10 -StandardOutput=syslog -StandardError=syslog -SyslogIdentifier=uffd-socketmap-%I +StandardOutput=journal +StandardError=journal +SyslogIdentifier=uffd-socketmap-postfix +DynamicUser=true PrivateUsers=true CapabilityBoundingSet= NoNewPrivileges=true @@ -34,9 +36,9 @@ PrivateTmp=true PrivateDevices=true SystemCallArchitectures=native SystemCallFilter=@system-service +MemoryDenyWriteExecute=true -EnvironmentFile=/etc/uffd-socketmap/defaults -EnvironmentFile=/etc/uffd-socketmap/$I.env +EnvironmentFile=/etc/uffd-socketmap-postfix.conf [Install] WantedBy=default.target diff --git a/debian/contrib/uffd-socketmap-postfix.socket b/debian/contrib/uffd-socketmap-postfix.socket new file mode 100644 index 0000000..3c2e0a4 --- /dev/null +++ b/debian/contrib/uffd-socketmap-postfix.socket @@ -0,0 +1,11 @@ +[Unit] +Description=Socketmap server to integrate uffd mail aliases with postfix + +[Socket] +ListenStream=/var/spool/postfix/uffd-socketmap.sock +SocketUser=postfix +SocketGroup=postfix +SocketMode=0640 + +[Install] +WantedBy=sockets.target diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..22732be --- /dev/null +++ b/debian/control @@ -0,0 +1,16 @@ +Source: uffd-socketmap +Section: python +Priority: optional +Maintainer: CCCV <it@cccv.de> +Build-Depends: + debhelper-compat (= 12), +Standards-Version: 4.5.0 +Homepage: https://git.cccv.de/uffd/socketmap-proxy +Vcs-Git: https://git.cccv.de/uffd/socketmap-proxy.git + +Package: uffd-socketmap +Architecture: all +Depends: + ${misc:Depends}, + python3-requests, +Description: Socketmap server to integrate uffd mail aliases with postfix diff --git a/debian/create_changelog.py b/debian/create_changelog.py new file mode 100755 index 0000000..b62f211 --- /dev/null +++ b/debian/create_changelog.py @@ -0,0 +1,106 @@ +#!/usr/bin/python3 +import sys +import re +import textwrap +import datetime +import email.utils + +import git + +package_name = 'UNKNOWN' + +alias_names = { + 'julian': 'Julian Rother', + 'Julian': 'Julian Rother', +} + +ignore_commit_regexes = [ + '^fixup!', +] + +def print_release(tag=None, commits=tuple(), last_tag=None): + release_version = '0.0.0' + release_author = git.objects.util.Actor('None', 'undefined@example.com') + release_date = 0 + release_status = 'UNRELEASED' + message = '' + + if tag: + release_status = 'unstable' + release_version = tag.name[1:] # strip leading "v" + if isinstance(tag.object, git.TagObject): + release_author = tag.object.tagger + release_date = tag.object.tagged_date + message = tag.object.message.split('-----BEGIN PGP SIGNATURE-----')[0].strip() + else: + release_author = tag.object.committer + release_date = tag.object.committed_date + elif commits: + release_author = commits[0].committer + release_date = commits[0].committed_date + date = datetime.datetime.fromtimestamp(release_date).strftime('%Y%m%dT%H%M%S') + last_version = '0.0.0' + if last_tag: + last_version = last_tag.name[1:] # strip leading "v" + release_version = f'{last_version}+git{date}-{commits[0].hexsha[:8]}' + + print(f'{package_name} ({release_version}) {release_status}; urgency=medium') + print() + if message: + print(textwrap.indent(message, ' ')) + print() + commit_authors = [] # list of (key, author), sorted by first commit date + commit_author_emails = {} # author email -> key + commit_author_names = {} # author name -> key + commit_author_commits = {} # key -> list of commits + for commit in commits: + if any(filter(lambda pattern: re.match(pattern, commit.summary), ignore_commit_regexes)): + continue + if len(commit.parents) > 1: + continue # Ignore merge commits + author_name = alias_names.get(commit.author.name, commit.author.name) + key = commit_author_emails.get(commit.author.email) + if key is None: + key = commit_author_names.get(author_name) + if key is None: + key = commit.author.email + commit_authors.append((key, author_name)) + commit_author_emails[commit.author.email] = key + commit_author_names[author_name] = key + commit_author_commits[key] = commit_author_commits.get(key, []) + [commit] + commit_authors.sort(key=lambda args: len(commit_author_commits[args[0]])) + for key, author_name in commit_authors: + print(f' [ {author_name} ]') + for commit in commit_author_commits[key]: + lines = '\n'.join(textwrap.wrap(commit.summary, 90)) + lines = ' * ' + textwrap.indent(lines, ' ').strip() + print(lines) + print() + print(f' -- {alias_names.get(release_author.name, release_author.name)} <{release_author.email}> {email.utils.formatdate(release_date)}') + +if __name__ == '__main__': + repo = git.Repo('.') + package_name = sys.argv[1] + + version_commits = {} + for tag in repo.tags: + if not re.fullmatch('v[0-9]+[.][0-9]+[.][0-9]+.*', tag.name): + continue + if isinstance(tag.object, git.TagObject): + commit_hexsha = tag.object.object.hexsha + else: + commit_hexsha = tag.object.hexsha + version_commits[commit_hexsha] = tag + + tag = None + commits = [] + for commit in repo.iter_commits('HEAD'): + if commit.hexsha in version_commits: + prev_tag = version_commits[commit.hexsha] + if commits: + print_release(tag, commits, last_tag=prev_tag) + print() + tag = prev_tag + commits = [] + commits.append(commit) + print_release(tag, commits) diff --git a/debian/install b/debian/install new file mode 100644 index 0000000..e886322 --- /dev/null +++ b/debian/install @@ -0,0 +1,4 @@ +server.py /usr/lib/uffd-socketmap/ +debian/contrib/uffd-socketmap-postfix.service /usr/lib/systemd/system/ +debian/contrib/uffd-socketmap-postfix.socket /usr/lib/systemd/system/ +debian/contrib/uffd-socketmap-postfix.conf /etc/ diff --git a/debian/links b/debian/links new file mode 100644 index 0000000..5c199f3 --- /dev/null +++ b/debian/links @@ -0,0 +1 @@ +/usr/lib/uffd-socketmap/server.py /usr/bin/uffd-socketmap diff --git a/debian/postinst b/debian/postinst new file mode 100755 index 0000000..bdba6dc --- /dev/null +++ b/debian/postinst @@ -0,0 +1,21 @@ +#!/bin/sh + +set -e + +case "$1" in + configure) + chmod 0640 /etc/uffd-socketmap-postfix.conf + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +#DEBHELPER# + +exit 0 diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..cbe925d --- /dev/null +++ b/debian/rules @@ -0,0 +1,3 @@ +#!/usr/bin/make -f +%: + dh $@ diff --git a/server.py b/server.py old mode 100644 new mode 100755 index 3fbfc67..dd59646 --- a/server.py +++ b/server.py @@ -1,3 +1,4 @@ +#!/usr/bin/python3 import os import sys import logging diff --git a/uffd-socketmap@.socket b/uffd-socketmap@.socket deleted file mode 100644 index dcff275..0000000 --- a/uffd-socketmap@.socket +++ /dev/null @@ -1,12 +0,0 @@ -[Unit] -Description=Socket proxy for uffd mail alias lookup -PartOf=uffd-socketmap@%i.service - -[Socket] -ListenStream=/run/socketmap-proxy/%I.sock -SocketUser=postfix -SocketGroup=postfix -SocketMode=0640 - -[Install] -WantedBy=sockets.target -- GitLab