浏览代码

[Postfix] Remove Zeyple, base on Buster

andryyy 6 年之前
父节点
当前提交
3136e020f6

+ 7 - 12
data/Dockerfiles/postfix/Dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:bionic
+FROM debian:buster-slim
 LABEL maintainer "Andre Peters <andre.peters@servercow.de>"
 
 ARG DEBIAN_FRONTEND=noninteractive
@@ -9,12 +9,17 @@ RUN dpkg-divert --local --rename --add /sbin/initctl \
 	&& dpkg-divert --local --rename --add /usr/bin/ischroot \
 	&& ln -sf /bin/true /usr/bin/ischroot
 
-RUN apt-get update && apt-get install -y --no-install-recommends \
+# Add groups and users before installing Postfix to not break compatibility
+RUN groupadd -g 102 postfix \
+  && groupadd -g 103 postdrop \
+  && useradd -g postfix -u 101 -d /var/spool/postfix -s /usr/sbin/nologin postfix \
+  && apt-get update && apt-get install -y --no-install-recommends \
 	ca-certificates \
 	curl \
 	dirmngr \
 	gnupg \
 	libsasl2-modules \
+  mariadb-client \
 	perl \
 	postfix \
 	postfix-mysql \
@@ -32,16 +37,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   && printf '#!/bin/bash\n/usr/sbin/postconf -c /opt/postfix/conf "$@"' > /usr/local/sbin/postconf \
   && chmod +x /usr/local/sbin/postconf
 
-RUN addgroup --system --gid 600 zeyple \
-  && adduser --system --home /var/lib/zeyple --no-create-home --uid 600 --gid 600 --disabled-login zeyple \
-  && touch /var/log/zeyple.log \
-  && chown zeyple: /var/log/zeyple.log \
-  && mkdir -p /opt/mailman/var/data \
-  && touch /opt/mailman/var/data/postfix_lmtp \
-  && touch /opt/mailman/var/data/postfix_domains
-
-COPY zeyple.py /usr/local/bin/zeyple.py
-COPY zeyple.conf /etc/zeyple.conf
 COPY supervisord.conf /etc/supervisor/supervisord.conf
 COPY syslog-ng.conf /etc/syslog-ng/syslog-ng.conf
 COPY postfix.sh /opt/postfix.sh

+ 6 - 5
data/Dockerfiles/postfix/postfix.sh

@@ -4,6 +4,12 @@ trap "postfix stop" EXIT
 
 [[ ! -d /opt/postfix/conf/sql/ ]] && mkdir -p /opt/postfix/conf/sql/
 
+# Wait for MySQL to warm-up
+while ! mysqladmin status --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent; do
+  echo "Waiting for database to come up..."
+  sleep 2
+done
+
 cat <<EOF > /etc/aliases
 # Autogenerated by mailcow
 null: /dev/null
@@ -286,11 +292,6 @@ query = SELECT goto FROM spamalias
     AND validity >= UNIX_TIMESTAMP()
 EOF
 
-# Reset GPG key permissions
-mkdir -p /var/lib/zeyple/keys
-chmod 700 /var/lib/zeyple/keys
-chown -R 600:600 /var/lib/zeyple/keys
-
 # Fix Postfix permissions
 chown -R root:postfix /opt/postfix/conf/sql/
 chmod 640 /opt/postfix/conf/sql/*.cf

+ 2 - 1
data/Dockerfiles/postfix/syslog-ng.conf

@@ -1,9 +1,10 @@
-@version: 3.13
+@version: 3.19
 @include "scl.conf"
 options {
   chain_hostnames(off);
   flush_lines(0);
   use_dns(no);
+  dns_cache(no);
   use_fqdn(no);
   owner("root"); group("adm"); perm(0640);
   stats_freq(0);

+ 0 - 9
data/Dockerfiles/postfix/zeyple.conf

@@ -1,9 +0,0 @@
-[zeyple]
-log_file = /dev/null
-
-[gpg]
-home = /var/lib/zeyple/keys
-
-[relay]
-host = localhost
-port = 10026

+ 0 - 274
data/Dockerfiles/postfix/zeyple.py

@@ -1,274 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import sys
-import os
-import logging
-import email
-import email.mime.multipart
-import email.mime.application
-import email.encoders
-import smtplib
-import copy
-from io import BytesIO
-
-try:
-    from configparser import SafeConfigParser  # Python 3
-except ImportError:
-    from ConfigParser import SafeConfigParser  # Python 2
-
-import gpgme
-
-# Boiler plate to avoid dependency on six
-# BBB: Python 2.7 support
-PY3K = sys.version_info > (3, 0)
-
-
-def message_from_binary(message):
-    if PY3K:
-        return email.message_from_bytes(message)
-    else:
-        return email.message_from_string(message)
-
-
-def as_binary_string(email):
-    if PY3K:
-        return email.as_bytes()
-    else:
-        return email.as_string()
-
-
-def encode_string(string):
-    if isinstance(string, bytes):
-        return string
-    else:
-        return string.encode('utf-8')
-
-
-__title__ = 'Zeyple'
-__version__ = '1.2.0'
-__author__ = 'Cédric Félizard'
-__license__ = 'AGPLv3+'
-__copyright__ = 'Copyright 2012-2016 Cédric Félizard'
-
-
-class Zeyple:
-    """Zeyple Encrypts Your Precious Log Emails"""
-
-    def __init__(self, config_fname='zeyple.conf'):
-        self.config = self.load_configuration(config_fname)
-
-        log_file = self.config.get('zeyple', 'log_file')
-        logging.basicConfig(
-            filename=log_file, level=logging.DEBUG,
-            format='%(asctime)s %(process)s %(levelname)s %(message)s'
-        )
-        logging.info("Zeyple ready to encrypt outgoing emails")
-
-    def load_configuration(self, filename):
-        """Reads and parses the config file"""
-
-        config = SafeConfigParser()
-        config.read([
-            os.path.join('/etc/', filename),
-            filename,
-        ])
-        if not config.sections():
-            raise IOError('Cannot open config file.')
-        return config
-
-    @property
-    def gpg(self):
-        protocol = gpgme.PROTOCOL_OpenPGP
-
-        if self.config.has_option('gpg', 'executable'):
-            executable = self.config.get('gpg', 'executable')
-        else:
-            executable = None  # Default value
-
-        home_dir = self.config.get('gpg', 'home')
-
-        ctx = gpgme.Context()
-        ctx.set_engine_info(protocol, executable, home_dir)
-        ctx.armor = True
-
-        return ctx
-
-    def process_message(self, message_data, recipients):
-        """Encrypts the message with recipient keys"""
-        message_data = encode_string(message_data)
-
-        in_message = message_from_binary(message_data)
-        logging.info(
-            "Processing outgoing message %s", in_message['Message-id'])
-
-        if not recipients:
-            logging.warn("Cannot find any recipients, ignoring")
-
-        sent_messages = []
-        for recipient in recipients:
-            logging.info("Recipient: %s", recipient)
-
-            key_id = self._user_key(recipient)
-            logging.info("Key ID: %s", key_id)
-
-            if key_id:
-                out_message = self._encrypt_message(in_message, key_id)
-
-                # Delete Content-Transfer-Encoding if present to default to
-                # "7bit" otherwise Thunderbird seems to hang in some cases.
-                del out_message["Content-Transfer-Encoding"]
-            else:
-                logging.warn("No keys found, message will be sent unencrypted")
-                out_message = copy.copy(in_message)
-
-            self._add_zeyple_header(out_message)
-            self._send_message(out_message, recipient)
-            sent_messages.append(out_message)
-
-        return sent_messages
-
-    def _get_version_part(self):
-        ret = email.mime.application.MIMEApplication(
-            'Version: 1\n',
-            'pgp-encrypted',
-            email.encoders.encode_noop,
-        )
-        ret.add_header(
-            'Content-Description',
-            "PGP/MIME version identification",
-        )
-        return ret
-
-    def _get_encrypted_part(self, payload):
-        ret = email.mime.application.MIMEApplication(
-            payload,
-            'octet-stream',
-            email.encoders.encode_noop,
-            name="encrypted.asc",
-        )
-        ret.add_header('Content-Description', "OpenPGP encrypted message")
-        ret.add_header(
-            'Content-Disposition',
-            'inline',
-            filename='encrypted.asc',
-        )
-        return ret
-
-    def _encrypt_message(self, in_message, key_id):
-        if in_message.is_multipart():
-            # get the body (after the first \n\n)
-            payload = in_message.as_string().split("\n\n", 1)[1].strip()
-
-            # prepend the Content-Type including the boundary
-            content_type = "Content-Type: " + in_message["Content-Type"]
-            payload = content_type + "\n\n" + payload
-
-            message = email.message.Message()
-            message.set_payload(payload)
-
-            payload = message.get_payload()
-
-        else:
-            payload = in_message.get_payload()
-            payload = encode_string(payload)
-
-            quoted_printable = email.charset.Charset('ascii')
-            quoted_printable.body_encoding = email.charset.QP
-
-            message = email.mime.nonmultipart.MIMENonMultipart(
-                'text', 'plain', charset='utf-8'
-            )
-            message.set_payload(payload, charset=quoted_printable)
-
-            mixed = email.mime.multipart.MIMEMultipart(
-                'mixed',
-                None,
-                [message],
-            )
-
-            # remove superfluous header
-            del mixed['MIME-Version']
-
-            payload = as_binary_string(mixed)
-
-        encrypted_payload = self._encrypt_payload(payload, [key_id])
-
-        version = self._get_version_part()
-        encrypted = self._get_encrypted_part(encrypted_payload)
-
-        out_message = copy.copy(in_message)
-        out_message.preamble = "This is an OpenPGP/MIME encrypted " \
-                               "message (RFC 4880 and 3156)"
-
-        if 'Content-Type' not in out_message:
-            out_message['Content-Type'] = 'multipart/encrypted'
-        else:
-            out_message.replace_header(
-                'Content-Type',
-                'multipart/encrypted',
-            )
-
-        out_message.set_param('protocol', 'application/pgp-encrypted')
-        out_message.set_payload([version, encrypted])
-
-        return out_message
-
-    def _encrypt_payload(self, payload, key_ids):
-        """Encrypts the payload with the given keys"""
-        payload = encode_string(payload)
-
-        plaintext = BytesIO(payload)
-        ciphertext = BytesIO()
-
-        self.gpg.armor = True
-
-        recipient = [self.gpg.get_key(key_id) for key_id in key_ids]
-
-        self.gpg.encrypt(recipient, gpgme.ENCRYPT_ALWAYS_TRUST,
-                         plaintext, ciphertext)
-
-        return ciphertext.getvalue()
-
-    def _user_key(self, email):
-        """Returns the GPG key for the given email address"""
-        logging.info("Trying to encrypt for %s", email)
-        keys = [key for key in self.gpg.keylist(email)]
-
-        if keys:
-            key = keys.pop()  # NOTE: looks like keys[0] is the master key
-            key_id = key.subkeys[0].keyid
-            return key_id
-
-        return None
-
-    def _add_zeyple_header(self, message):
-        if self.config.has_option('zeyple', 'add_header') and \
-           self.config.getboolean('zeyple', 'add_header'):
-            message.add_header(
-                'X-Zeyple',
-                "processed by {0} v{1}".format(__title__, __version__)
-            )
-
-    def _send_message(self, message, recipient):
-        """Sends the given message through the SMTP relay"""
-        logging.info("Sending message %s", message['Message-id'])
-
-        smtp = smtplib.SMTP(self.config.get('relay', 'host'),
-                            self.config.get('relay', 'port'))
-
-        smtp.sendmail(message['From'], recipient, message.as_string())
-        smtp.quit()
-
-        logging.info("Message %s sent", message['Message-id'])
-
-
-if __name__ == '__main__':
-    recipients = sys.argv[1:]
-
-    # BBB: Python 2.7 support
-    binary_stdin = sys.stdin.buffer if PY3K else sys.stdin
-    message = binary_stdin.read()
-
-    zeyple = Zeyple()
-    zeyple.process_message(message, recipients)