postfwd: install config from files/postfwd, idempotent /etc/default/postfwd handling
- Ship postfwd.cf and list files in files/postfwd; used by install_postfwd.sh and install_postfix_advanced.sh (lists only if missing, cf with backup). - Add update_postfwd_defaults.sh. - install_amavis.sh: disable smtpd_end_of_data_restrictions on localhost:10025. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,99 @@
|
|||||||
|
# Sperrliste fuer den von Postfix gelieferten client_name, nicht fuer HELO.
|
||||||
|
# Perl-Regex pro Zeile; Punkte maskieren und Grenzen verankern.
|
||||||
|
# Beispiel exakter Host: ^mail\.example\.org$
|
||||||
|
# Domaene einschliesslich Subdomains: (^|\.)example\.org$
|
||||||
|
# Es handelt sich nicht um Postfix-pcre:-Tabellen (keine Ergebnis-Spalte).
|
||||||
|
#
|
||||||
|
# Nach Aenderungen: postfwd -f /etc/postfix/postfwd.cf -C
|
||||||
|
# Danach systemctl reload postfwd (setzt mit den gelieferten Optionen Zaehler zurueck).
|
||||||
|
# Der Dienst heisst postfwd, nicht postfwd2. file:-Listen werden beim Laden gelesen.
|
||||||
|
# Leerzeilen und Kommentare werden ignoriert. Dateien muessen lesbar sein.
|
||||||
|
#
|
||||||
|
# # Example:
|
||||||
|
#
|
||||||
|
# # Werkzeug
|
||||||
|
# (^|\.)katherina-remberg\.de$
|
||||||
|
|
||||||
|
# Werkzeug
|
||||||
|
(^|\.)katherina-remberg\.de$
|
||||||
|
|
||||||
|
# Mehr Energie für Ihre Schritte
|
||||||
|
(^|\.)elcoino\.de$
|
||||||
|
|
||||||
|
# Wiederherstellung des Sehvermogens ohne Operation
|
||||||
|
(^|\.)toonaca\.or\.mg$
|
||||||
|
|
||||||
|
# info re_zeptfrei ordern
|
||||||
|
(^|\.)radiotrabajandoparacristoirmp\.com$
|
||||||
|
|
||||||
|
# HL Group
|
||||||
|
(^|\.)group-hire\.com$
|
||||||
|
|
||||||
|
# Erinnerung: Überzahlung entdeckt – Ihre Rückerstattung wartet!
|
||||||
|
#mtasv\.net$
|
||||||
|
|
||||||
|
# edge.toprains.shop:w
|
||||||
|
(^|\.)edge\.toprains\.shop$
|
||||||
|
|
||||||
|
# Ideal für Apple- und Samsung-Fans
|
||||||
|
(^|\.)sdeals\.shop$
|
||||||
|
|
||||||
|
# Spiegel.de
|
||||||
|
(^|\.)delpieroacademy\.com$
|
||||||
|
|
||||||
|
# Kundensupport - photoTAN
|
||||||
|
#mailjet\.com$
|
||||||
|
|
||||||
|
# LOTTO-Rabatt
|
||||||
|
(^|\.)gdwr\.de$
|
||||||
|
|
||||||
|
# info mit ETFs die Millionen knacken?
|
||||||
|
(^|\.)movingcompanywheaton\.com$
|
||||||
|
|
||||||
|
# Specht Office
|
||||||
|
(^|\.)mta3\.dev\.60cr\.com$
|
||||||
|
|
||||||
|
# lichtbringer.sho
|
||||||
|
(^|\.)lichtbringer\.shop$
|
||||||
|
|
||||||
|
# insights.sternenpfad.shop
|
||||||
|
(^|\.)insights\.sternenpfad\.shop$
|
||||||
|
|
||||||
|
# info rezeptfre-i Bestellung
|
||||||
|
(^|\.)ugms\.org$
|
||||||
|
|
||||||
|
# info Herrenmeds anfordern
|
||||||
|
(^|\.)fullendoscopy\.mx$
|
||||||
|
|
||||||
|
# Premium-Werkzeugwagen:
|
||||||
|
(^|\.)minillq\.com$
|
||||||
|
|
||||||
|
# zaubermoment.shop
|
||||||
|
(^|\.)zaubermoment\.shop$
|
||||||
|
|
||||||
|
# Lustexperte
|
||||||
|
(^|\.)jetztpower\.shop$
|
||||||
|
|
||||||
|
# herzenstone.shop
|
||||||
|
(^|\.)herzenstone\.shop$
|
||||||
|
|
||||||
|
# Versand - Wichtige Neiuheit (a2hosted.com)
|
||||||
|
(^|\.)a2hosted\.com$
|
||||||
|
|
||||||
|
# Eleganz trifft Funktion: Metall-Kugelschreiber mit Logo
|
||||||
|
(^|\.)game\.cn$
|
||||||
|
|
||||||
|
# Ein Sprühstoß für die sofortige Erektion!
|
||||||
|
(^|\.)perfektepower\.shop$
|
||||||
|
|
||||||
|
# Home Security / preview.glanzpunkt.shop
|
||||||
|
(^|\.)glanzpunkt\.shop$
|
||||||
|
|
||||||
|
# Phishing IHK
|
||||||
|
(^|\.)rightappearance\.com$
|
||||||
|
|
||||||
|
# info rezeptf-rei Bestellung
|
||||||
|
(^|\.)sectiontrading\.com$
|
||||||
|
|
||||||
|
# Sofortiger zweisprachiger Sprachübersetzer
|
||||||
|
# - kein Eintrag -
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
# Gesperrte Client-IP-Adressen/IPv4-Netze; permanente REJECT-Antwort.
|
||||||
|
# Eine Adresse/ein Netz pro Zeile. IPv4-CIDR-Netze werden unterstuetzt.
|
||||||
|
# postfwd2 1.35: IPv6 nur als exakte Adresse OHNE /128, keine IPv6-Netze.
|
||||||
|
# Vorherige Vollfreistellungen haben Vorrang vor dieser Sperrliste.
|
||||||
|
#
|
||||||
|
# Nach Aenderungen: postfwd -f /etc/postfix/postfwd.cf -C
|
||||||
|
# Danach systemctl reload postfwd (setzt mit den gelieferten Optionen Zaehler zurueck).
|
||||||
|
# Der Dienst heisst postfwd, nicht postfwd2. file:-Listen werden beim Laden gelesen.
|
||||||
|
# Leerzeilen und Kommentare werden ignoriert. Dateien muessen lesbar sein.
|
||||||
|
#
|
||||||
|
# # Example:
|
||||||
|
#
|
||||||
|
# # Werkzeug
|
||||||
|
# 5.135.22.148/30
|
||||||
|
#
|
||||||
|
# # Shop ABC
|
||||||
|
# #83.223.86.76
|
||||||
|
# #2a01:30:0:13:286:96ff:fe4a:6eee
|
||||||
|
|
||||||
|
# Werkzeug
|
||||||
|
5.135.22.148/30
|
||||||
|
|
||||||
|
# Mehr Energie für Ihre Schritte
|
||||||
|
5.196.53.204/30
|
||||||
|
|
||||||
|
# Wiederherstellung des Sehvermogens ohne Operation
|
||||||
|
31.28.27.0/24
|
||||||
|
|
||||||
|
# info re_zeptfrei ordern
|
||||||
|
45.61.128.0/18
|
||||||
|
|
||||||
|
# HL Group
|
||||||
|
45.132.181.0/24
|
||||||
|
|
||||||
|
# Erinnerung: Überzahlung entdeckt – Ihre Rückerstattung wartet!
|
||||||
|
#50.31.205.0/24
|
||||||
|
|
||||||
|
# edge.toprains.shop
|
||||||
|
51.89.16.112
|
||||||
|
|
||||||
|
# Ideal für Apple- und Samsung-Fans
|
||||||
|
51.195.36.112/26
|
||||||
|
|
||||||
|
# Bitcoin Boom / GHOSTnet GmbH
|
||||||
|
85.93.0.0/19
|
||||||
|
|
||||||
|
# Spiegel.de
|
||||||
|
85.93.19.234
|
||||||
|
|
||||||
|
# Kundensupport - photoTAN
|
||||||
|
#87.253.233.0/24
|
||||||
|
|
||||||
|
# LOTTO-Rabatt
|
||||||
|
89.22.116.0/24
|
||||||
|
|
||||||
|
# info mit ETFs die Millionen knacken?
|
||||||
|
89.144.4.211
|
||||||
|
|
||||||
|
# Specht Office
|
||||||
|
91.193.18.0/24
|
||||||
|
|
||||||
|
# lichtbringer.shop
|
||||||
|
94.23.144.0/21
|
||||||
|
|
||||||
|
# insights.sternenpfad.shop
|
||||||
|
94.23.152.0/21
|
||||||
|
|
||||||
|
# info rezeptfre-i Bestellung
|
||||||
|
104.244.72.0/21
|
||||||
|
|
||||||
|
# info Herrenmeds anfordern
|
||||||
|
107.189.0.0/19
|
||||||
|
|
||||||
|
# Premium-Werkzeugwagen:
|
||||||
|
162.220.163.128/25
|
||||||
|
|
||||||
|
# zaubermoment.shop
|
||||||
|
178.32.96.0/19
|
||||||
|
|
||||||
|
# Lustexperte
|
||||||
|
178.32.136.0/21
|
||||||
|
|
||||||
|
# herzenstone.shop
|
||||||
|
178.33.112.0/21
|
||||||
|
|
||||||
|
# ??
|
||||||
|
181.214.99.0/24
|
||||||
|
|
||||||
|
# Versand - Wichtige Neiuheit (a2hosted.com)
|
||||||
|
185.91.69.0/24
|
||||||
|
|
||||||
|
# Eleganz trifft Funktion: Metall-Kugelschreiber mit Logo
|
||||||
|
185.173.235.0/24
|
||||||
|
|
||||||
|
# Ein Sprühstoß für die sofortige Erektion!
|
||||||
|
188.165.0.0/21
|
||||||
|
|
||||||
|
# Home Security / preview.glanzpunkt.shop
|
||||||
|
188.165.128.0/21
|
||||||
|
|
||||||
|
# Phishing IHK
|
||||||
|
191.96.209.0/24
|
||||||
|
|
||||||
|
# info rezeptf-rei Bestellung
|
||||||
|
198.98.48.0/20
|
||||||
|
|
||||||
|
# Sofortiger zweisprachiger Sprachübersetzer
|
||||||
|
213.202.222.185
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Empfaenger mit zusaetzlichem 20-MiB-Limit, NUR bei Einzelempfaengern.
|
||||||
|
# Perl-Regex pro Zeile; z.B.
|
||||||
|
# ^user@example\.org$
|
||||||
|
# @example\.org$
|
||||||
|
# Die Regel greift nur bei recipient_count=1 am END-OF-MESSAGE und bei
|
||||||
|
# size > 20971520 Bytes. Genau 20 MiB bleiben erlaubt.
|
||||||
|
# Bei mehreren Empfaengern fehlt recipient dort; dafuer bietet diese Datei
|
||||||
|
# KEIN verlaessliches Limit. Fuer verbindliche Limits ist eine andere
|
||||||
|
# Loesung erforderlich. Die bisher leere Liste bleibt leer.
|
||||||
|
# Historischer Dateiname mit Schreibfehler bleibt aus Kompatibilitaet erhalten.
|
||||||
|
#
|
||||||
|
# +------------------+----------------------+----------------+----------------------+
|
||||||
|
# | SMTP-Empfaenger | Empfaenger gelistet? | Nachricht | Wirkung dieser Regel |
|
||||||
|
# +------------------+----------------------+----------------+----------------------+
|
||||||
|
# | Genau einer | Ja | Bis 20 MiB | Keine Ablehnung |
|
||||||
|
# | Genau einer | Ja | Ueber 20 MiB | REJECT |
|
||||||
|
# | Genau einer | Nein | Beliebig | Keine Ablehnung |
|
||||||
|
# | Mehrere | Einer oder mehrere | Beliebig | Keine Ablehnung |
|
||||||
|
# | | gelistet | | |
|
||||||
|
# +------------------+----------------------+----------------+----------------------+
|
||||||
|
#
|
||||||
|
# 20 MiB = 20.971.520 Bytes, einschliesslich Header und MIME-Kodierung.
|
||||||
|
#
|
||||||
|
# Bei mehreren SMTP-Empfaengern liefert Postfix am Nachrichtenende
|
||||||
|
# keine einzelne Empfaengeradresse fuer den Listenvergleich.
|
||||||
|
#
|
||||||
|
# Das globale Postfix-Limit message_size_limit gilt weiterhin.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# # Example:
|
||||||
|
#
|
||||||
|
# # # annoying spammer domains
|
||||||
|
# # block all senders of maildomaindomain 'oopen.de'
|
||||||
|
# @acieu\.co\.uk$
|
||||||
|
#
|
||||||
|
# # annoying spammer addresses
|
||||||
|
# # block sender address
|
||||||
|
# error@mailfrom.com
|
||||||
|
# sqek@eike\.se$
|
||||||
|
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
# Sperrliste fuer Envelope-Absender (MAIL FROM), NICHT From:-Header.
|
||||||
|
# Perl-Regex pro Zeile; keine Postfix-pcre:-Tabellen mit Ergebnis-Spalte.
|
||||||
|
#
|
||||||
|
# Exakte Adresse: ^user@example\.org$
|
||||||
|
#
|
||||||
|
# Domaene und Subdomains: @([^@]+\.)?example\.org$
|
||||||
|
#
|
||||||
|
# Ablehnung mit REJECT, kein stilles DISCARD. Domain-Grenzen und maskierte
|
||||||
|
# Punkte vermeiden unbeabsichtigte Treffer auf aehnliche Domainnamen.
|
||||||
|
#
|
||||||
|
|
||||||
|
# reported by MBR
|
||||||
|
^paul\.graber99@gmail\.com$
|
||||||
|
^ludwigpestow@gmail\.com$
|
||||||
|
|
||||||
|
# annoying spammer domains
|
||||||
|
@([^@]+\.)?acieu\.co\.uk$
|
||||||
|
@([^@]+\.)?inbox\.ru$
|
||||||
|
|
||||||
|
# ----
|
||||||
|
|
||||||
|
# Werkzeug
|
||||||
|
@([^@]+\.)?katherina-remberg\.de$
|
||||||
|
|
||||||
|
# Mehr Energie für Ihre Schritte
|
||||||
|
@([^@]+\.)?elcoino\.de$
|
||||||
|
|
||||||
|
# Wiederherstellung des Sehvermogens ohne Operation
|
||||||
|
@([^@]+\.)?toonaca\.or\.mg$
|
||||||
|
|
||||||
|
# info re_zeptfrei ordern
|
||||||
|
@([^@]+\.)?radiotrabajandoparacristoirmp\.com$
|
||||||
|
|
||||||
|
# HL Group
|
||||||
|
@([^@]+\.)?group-hire\.com$
|
||||||
|
|
||||||
|
# Erinnerung: Überzahlung entdeckt – Ihre Rückerstattung wartet!
|
||||||
|
@([^@]+\.)?toldfinancialcapital\.com$
|
||||||
|
|
||||||
|
# edge.toprains.shop
|
||||||
|
@([^@]+\.)?toprains\.shop$
|
||||||
|
|
||||||
|
# Ideal für Apple- und Samsung-Fans
|
||||||
|
@([^@]+\.)?sdeals\.shop$
|
||||||
|
|
||||||
|
# Spiegel.de
|
||||||
|
@([^@]+\.)?delpieroacademy\.com$
|
||||||
|
|
||||||
|
# Kundensupport - photoTAN
|
||||||
|
#@laurash.net
|
||||||
|
|
||||||
|
# LOTTO-Rabatt
|
||||||
|
@([^@]+\.)?gdwr\.de$
|
||||||
|
|
||||||
|
# info mit ETFs die Millionen knacken?
|
||||||
|
@([^@]+\.)?movingcompanywheaton\.com$
|
||||||
|
|
||||||
|
# Specht Offic
|
||||||
|
^officeuf@jxb669\.com$
|
||||||
|
^officeuf@
|
||||||
|
|
||||||
|
# edge.toprains.shop
|
||||||
|
@([^@]+\.)?edge\.toprains\.shop$
|
||||||
|
|
||||||
|
# lichtbringer.shop
|
||||||
|
@([^@]+\.)?lichtbringer\.shop$
|
||||||
|
|
||||||
|
# insights.sternenpfad.shop
|
||||||
|
@([^@]+\.)?insights\.sternenpfad\.shop$
|
||||||
|
|
||||||
|
# info rezeptfre-i Bestellung
|
||||||
|
@([^@]+\.)?ugms\.org$
|
||||||
|
|
||||||
|
# Premium-Werkzeugwagen:
|
||||||
|
@([^@]+\.)?ezhifeng\.co$
|
||||||
|
|
||||||
|
# zaubermoment.shop
|
||||||
|
@([^@]+\.)?zaubermoment\.shop$
|
||||||
|
|
||||||
|
# Lustexperte
|
||||||
|
@([^@]+\.)?jetztpower\.shop$
|
||||||
|
|
||||||
|
# herzenstone.shop
|
||||||
|
@([^@]+\.)?herzenstone\.shop$
|
||||||
|
|
||||||
|
# ?? 181.214.99.0/24
|
||||||
|
@([^@]+\.)?imrx4k\.com$
|
||||||
|
|
||||||
|
# Versand - Wichtige Neiuheit (a2hosted.com)
|
||||||
|
@([^@]+\.)?a2hosted\.com$
|
||||||
|
|
||||||
|
# Eleganz trifft Funktion: Metall-Kugelschreiber mit Logo
|
||||||
|
@([^@]+\.)?izilian\.com$
|
||||||
|
|
||||||
|
# Ein Sprühstoß für die sofortige Erektion!
|
||||||
|
@([^@]+\.)?perfektepower\.shop$
|
||||||
|
|
||||||
|
# Home Security / preview.glanzpunkt.shop
|
||||||
|
@([^@]+\.)?glanzpunkt\.shop$
|
||||||
|
|
||||||
|
# Phishing IHK
|
||||||
|
@([^@]+\.)?rightappearance\.com$
|
||||||
|
|
||||||
|
# info rezeptf-rei Bestellung
|
||||||
|
@([^@]+\.)?sectiontrading\.com$
|
||||||
|
|
||||||
|
# Sofortiger zweisprachiger Sprachübersetzer
|
||||||
|
@([^@]+\.)?delavers\.de$
|
||||||
|
|
||||||
|
# ---
|
||||||
|
|
||||||
|
# Google Mail Adresse
|
||||||
|
@([^@]+\.)?laravel\.digital$
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# Gesperrte SASL-Benutzernamen; permanente REJECT-Antwort.
|
||||||
|
# Exakter Name pro Zeile, keine Regex. Vorherige Vollfreistellungen haben Vorrang.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# # give SASL usernames to block here
|
||||||
|
# ckubu@oopen.de
|
||||||
|
|
||||||
@@ -0,0 +1,227 @@
|
|||||||
|
# Statische Vorlage fuer postfwd 1.35, ohne Jinja-Variablen.
|
||||||
|
#
|
||||||
|
# POSTFIX-EINBINDUNG
|
||||||
|
# main.cf: smtpd_end_of_data_restrictions =
|
||||||
|
# check_policy_service inet:127.0.0.1:10040
|
||||||
|
# Amavis-Rueckgabeport localhost:10025 in master.cf:
|
||||||
|
# -o smtpd_end_of_data_restrictions=
|
||||||
|
# Sonst kann die Wiedereinlieferung mit XFORWARD erneut gezaehlt werden.
|
||||||
|
# /etc/default/postfwd: ARGS="--summary=600 --cache=0"
|
||||||
|
#
|
||||||
|
# AUSWERTUNG
|
||||||
|
# Verschiedene Attribute einer Regel: UND. Gleiches Attribut mehrfach: ODER.
|
||||||
|
# DUNNO beendet diesen postfwd-Aufruf; Postfix setzt eigene Pruefungen fort.
|
||||||
|
# REJECT lehnt permanent, 450 temporaer ab. rate()/rcpt() laufen unterhalb
|
||||||
|
# des Limits weiter. jump(ID) springt zur bezeichneten Regel.
|
||||||
|
# final=yes ist keine Steueranweisung und wird NICHT verwendet.
|
||||||
|
#
|
||||||
|
# LIMITS (fuer nicht vollstaendig freigestellte, nicht lokale SMTP-Clients)
|
||||||
|
#
|
||||||
|
# +--------------------------------+-----------+-----------+------------------+
|
||||||
|
# | Limit | Standard | Benutzer | Benutzer nur in |
|
||||||
|
# | | | 500er- | Empfaenger- |
|
||||||
|
# | | | Liste | Ausnahmeliste |
|
||||||
|
# +--------------------------------+-----------+-----------+------------------+
|
||||||
|
# | Nachrichten / Stunde / Benutzer| 50 | 500 | 50 |
|
||||||
|
# | Empfaenger / Stunde / Benutzer| 250 | 1000 | 1000 |
|
||||||
|
# | Empfaenger / Nachricht | 89 | 89 | 89 |
|
||||||
|
# +--------------------------------+-----------+-----------+------------------+
|
||||||
|
#
|
||||||
|
# Zusaetzlich fuer alle oben genannten Benutzer:
|
||||||
|
#
|
||||||
|
# +------------------------------------------+----------------------------+
|
||||||
|
# | Client-IP | Nachrichten / Minute / IP |
|
||||||
|
# +------------------------------------------+----------------------------+
|
||||||
|
# | Weder IP noch Hostname in Ausnahmeliste | 50 |
|
||||||
|
# | IP ODER Hostname in Ausnahmeliste | 100 |
|
||||||
|
# +------------------------------------------+----------------------------+
|
||||||
|
#
|
||||||
|
# Zusaetzlich fuer nicht authentifizierte Clients:
|
||||||
|
#
|
||||||
|
# +------------------------------------------+----------------------------+
|
||||||
|
# | client_name = unknown | 5 Nachrichten / 5 Minuten |
|
||||||
|
# | | je Client-IP |
|
||||||
|
# +------------------------------------------+----------------------------+
|
||||||
|
#
|
||||||
|
# Unauthentifiziert + client_name=unknown: 5 Nachrichten / 300 Sekunden / IP.
|
||||||
|
# SASL: 50 Nachrichten / 3600 Sekunden / Benutzer; Ausnahme: 500.
|
||||||
|
# IP: 50 Nachrichten / 60 Sekunden; Ausnahme ueber IP ODER Hostname: 100.
|
||||||
|
# SASL: maximal 89 Empfaenger pro Nachricht (Ablehnung ab 90).
|
||||||
|
# SASL: 250 Empfaenger / 3600 Sekunden; Ausnahme: 1000.
|
||||||
|
# Jeder Benutzer der 500er-Nachrichtenliste bekommt auch die 1000er-
|
||||||
|
# Empfaengerausnahme. Die separate Empfaengerliste erlaubt nur 1000 statt
|
||||||
|
# 250 Empfaenger/Stunde, erhoeht aber nicht das Nachrichtenlimit.
|
||||||
|
# Benutzer der 500er-Nachrichtenliste sind vom IP-Minutenlimit (50 bzw.
|
||||||
|
# 100 Nachrichten / 60 Sekunden) ausgenommen: sie versenden meist
|
||||||
|
# automatisiert in Schueben und wuerden sonst trotz 500er-Ausnahme am
|
||||||
|
# Minutenlimit haengen bleiben. Fuer alle anderen bleibt das Minutenlimit
|
||||||
|
# aktiv. Die Empfaengerzahl pro Nachricht (max. 89) gilt fuer alle.
|
||||||
|
#
|
||||||
|
# ZAEHLWEISE
|
||||||
|
# rate() zaehlt END-OF-MESSAGE-Anfragen, rcpt() addiert recipient_count.
|
||||||
|
# Es sind Versandversuche, keine bestaetigten Zustellungen. Wiederholungen
|
||||||
|
# und spaeter abgelehnte Versuche koennen mitgezaehlt werden. Empfaenger
|
||||||
|
# werden aufsummiert, nicht dedupliziert. Kein gleitendes Kalenderstunden-
|
||||||
|
# budget: postfwd verwaltet befristete Zaehler ab ihrer Anlage.
|
||||||
|
# Gemeinsame IPs teilen sich das Minutenlimit, auch bei mehreren Benutzern.
|
||||||
|
#
|
||||||
|
# DATEIEN
|
||||||
|
# file: liest Listen beim Laden der Konfiguration. Danach neu laden/starten.
|
||||||
|
# Fuer IPs/Netze: client_address==file:... (CIDR-Vergleich).
|
||||||
|
# Fuer SASL: sasl_username==file:... (exakte Namen, keine Regex).
|
||||||
|
# Fuer Namen/Adressen: =~file:... (Perl-Regex, keine Postfix-pcre:-Tabelle).
|
||||||
|
# Alle referenzierten Dateien muessen fuer den Benutzer postfw lesbar sein.
|
||||||
|
# Keine Ausnahmeliste mit &&SASL_AUTH in derselben Regel kombinieren:
|
||||||
|
# das waere eine ODER-Verknuepfung auf sasl_username!
|
||||||
|
|
||||||
|
# Nur diese Phase verwenden; keine Zaehleranlage in anderen SMTP-Phasen.
|
||||||
|
id=CHECK_PHASE
|
||||||
|
protocol_state!=END-OF-MESSAGE
|
||||||
|
action=DUNNO
|
||||||
|
|
||||||
|
# Lokaler SMTP-Verkehr wird ausgenommen, IPv4-Loopback und IPv6-Loopback.
|
||||||
|
# Dies ersetzt NICHT die Abschaltung am Amavis-Rueckgabeport: XFORWARD
|
||||||
|
# kann dort die urspruengliche externe Clientadresse wiederherstellen.
|
||||||
|
id=SKIP_LOOPBACK
|
||||||
|
client_address==127.0.0.0/8, ::1
|
||||||
|
action=DUNNO
|
||||||
|
|
||||||
|
# 1. VOLLSTAENDIGE AUSNAHMEN
|
||||||
|
# Bewusst vor den Sperrlisten wie in der bisherigen Konfiguration.
|
||||||
|
# Diese Listen umgehen ALLE folgenden postfwd-Regeln, auch Blacklists.
|
||||||
|
# Fuer nur hoehere Versandlimits ausschliesslich die high-rate-Listen nutzen.
|
||||||
|
id=WHL_NETS
|
||||||
|
client_address==file:/etc/postfix/postfwd.wl-nets
|
||||||
|
action=DUNNO
|
||||||
|
|
||||||
|
id=WHL_HOSTS
|
||||||
|
client_name=~file:/etc/postfix/postfwd.wl-hosts
|
||||||
|
action=DUNNO
|
||||||
|
|
||||||
|
id=WHL_USERS
|
||||||
|
sasl_username==file:/etc/postfix/postfwd.wl-user
|
||||||
|
action=DUNNO
|
||||||
|
|
||||||
|
# Achtung: Envelope-Absender ist keine authentifizierte Identitaet.
|
||||||
|
# Bestehende Freistellung bleibt erhalten; kein SPF-/DKIM-Nachweis hier.
|
||||||
|
id=WHL_SENDERS
|
||||||
|
sender=~file:/etc/postfix/postfwd.wl-sender
|
||||||
|
action=DUNNO
|
||||||
|
|
||||||
|
# 2. SPERRLISTEN: permanente Ablehnung, kein stilles DISCARD.
|
||||||
|
id=BL_NETS
|
||||||
|
client_address==file:/etc/postfix/postfwd.bl-nets
|
||||||
|
action=REJECT Network $$client_address blocked by mailserver admins. Error:BL_NETS
|
||||||
|
|
||||||
|
id=BL_HOSTS
|
||||||
|
client_name=~file:/etc/postfix/postfwd.bl-hosts
|
||||||
|
action=REJECT Client $$client_name blocked by mailserver admins. Error:BL_HOSTS
|
||||||
|
|
||||||
|
id=BL_USERS
|
||||||
|
sasl_username==file:/etc/postfix/postfwd.bl-user
|
||||||
|
action=REJECT User blocked by mailserver admins. Error:BL_USERS
|
||||||
|
|
||||||
|
id=BL_SENDER
|
||||||
|
sender=~file:/etc/postfix/postfwd.bl-sender
|
||||||
|
action=REJECT Sender blocked by mailserver admins. Error:BL_SENDER
|
||||||
|
|
||||||
|
# 3. EMPFAENGERBEZOGENE GROESSE, NUR BEI GENAU EINEM EMPFAENGER
|
||||||
|
# 20 MiB = 20971520 Bytes; mit > bleibt genau dieser Wert erlaubt.
|
||||||
|
# Postfix liefert recipient am Nachrichtenende nur bei einem Empfaenger.
|
||||||
|
# Bei mehreren Empfaengern kann diese Regel KEIN Limit durchsetzen.
|
||||||
|
# Die bisher leere Empfaengerliste bleibt erhalten; solange sie leer ist,
|
||||||
|
# ist diese Zusatzpruefung inaktiv. Global gilt weiter message_size_limit.
|
||||||
|
# Fuer verbindliche empfaengerbezogene Limits auch bei Mehrfachadressierung
|
||||||
|
# ist eine andere Loesung, z.B. ein geeigneter Milter, erforderlich.
|
||||||
|
id=BLOCK_MSG_SIZE_20MB
|
||||||
|
recipient_count==1
|
||||||
|
recipient=~file:/etc/postfix/postfwd.bl-recipient-exeeds-msg-size-20mb
|
||||||
|
size>20971520
|
||||||
|
action=REJECT Message exceeds 20 MiB ($$size bytes). Error:BLOCK_MSG_SIZE_20MB
|
||||||
|
|
||||||
|
# Permanente Empfaengerzahl-Pruefung vor die Rate-Zaehler stellen.
|
||||||
|
# Das bisher wirksame Limit bleibt erhalten: 89 erlaubt, ab 90 ablehnen.
|
||||||
|
id=BLOCK_MSG_RCPT
|
||||||
|
sasl_username!~^$
|
||||||
|
recipient_count=>90
|
||||||
|
action=REJECT Too many recipients, maximum is 89 per message. Error:BLOCK_MSG_RCPT
|
||||||
|
|
||||||
|
# 4. UNBEKANNTE, UNAUTHENTIFIZIERTE CLIENTS
|
||||||
|
# 5 Nachrichten, NICHT 5 Empfaenger oder 5 TCP-Verbindungen.
|
||||||
|
id=RATE_UNKNOWN_CLIENT_ADDR
|
||||||
|
sasl_username=~^$
|
||||||
|
client_name==unknown
|
||||||
|
action=rate(client_address/5/300/450 4.7.1 Only 5 messages per 5 minutes allowed. Error:RATE_UNKNOWN_CLIENT_ADDR)
|
||||||
|
|
||||||
|
# 5. NACHRICHTEN PRO STUNDE UND SASL-BENUTZER
|
||||||
|
# Auswahl VOR dem Zaehlen. Die Ausnahme springt an der 50er-Regel vorbei.
|
||||||
|
# Unterhalb 500 wird nach RATE_MSG_EXCEPTION direkt mit der Empfaenger-
|
||||||
|
# summe (Abschnitt 7) fortgesetzt; die IP-Minutenlimits entfallen bewusst.
|
||||||
|
id=SELECT_MSG_EXCEPTION
|
||||||
|
sasl_username==file:/etc/postfix/postfwd.high-rate-number-messages
|
||||||
|
action=jump(RATE_MSG_EXCEPTION)
|
||||||
|
|
||||||
|
id=RATE_MSG
|
||||||
|
sasl_username!~^$
|
||||||
|
action=rate(sasl_username/50/3600/450 4.7.1 Maximum 50 messages per hour exceeded. Error:RATE_MSG)
|
||||||
|
|
||||||
|
# Standardpfad muss die nachfolgende 500er-Regel ueberspringen.
|
||||||
|
id=AFTER_RATE_MSG
|
||||||
|
action=jump(SELECT_HIGH_RATE_IP)
|
||||||
|
|
||||||
|
id=RATE_MSG_EXCEPTION
|
||||||
|
sasl_username!~^$
|
||||||
|
action=rate(sasl_username/500/3600/450 4.7.1 Maximum 500 messages per hour exceeded. Error:RATE_MSG_EXCEPTION)
|
||||||
|
|
||||||
|
# Nach erfolgreicher 500er-Pruefung die IP-Minutenlimits (Abschnitt 6)
|
||||||
|
# bewusst ueberspringen: automatisierte Versender wuerden sonst am
|
||||||
|
# Minutenlimit scheitern. Empfaengerlimit pro Stunde weiterhin pruefen.
|
||||||
|
id=AFTER_RATE_MSG_EXCEPTION
|
||||||
|
action=jump(SELECT_RCPT_EXCEPTION_MSG)
|
||||||
|
|
||||||
|
# 6. NACHRICHTEN PRO MINUTE UND IP
|
||||||
|
# IP oder Hostname waehlen denselben 100er-Zaehler. Auch bei zwei Treffern
|
||||||
|
# nur eine Zaehlung. Hostname ist der von Postfix gelieferte client_name;
|
||||||
|
# nicht identisch mit einem ungeprueften HELO oder bloss irgendeinem PTR.
|
||||||
|
id=SELECT_HIGH_RATE_IP
|
||||||
|
client_address==file:/etc/postfix/postfwd.high_rate_ip
|
||||||
|
action=jump(HIGH_RATE_CLIENT_ADDR)
|
||||||
|
|
||||||
|
id=SELECT_HIGH_RATE_HOST
|
||||||
|
client_name=~file:/etc/postfix/postfwd.high_rate_hostname
|
||||||
|
action=jump(HIGH_RATE_CLIENT_ADDR)
|
||||||
|
|
||||||
|
id=RATE_CLIENT_ADDR
|
||||||
|
action=rate(client_address/50/60/450 4.7.1 Maximum 50 messages per minute per IP exceeded. Error:RATE_CLIENT_ADDR)
|
||||||
|
|
||||||
|
id=AFTER_RATE_CLIENT_ADDR
|
||||||
|
action=jump(SELECT_RCPT_EXCEPTION_MSG)
|
||||||
|
|
||||||
|
id=HIGH_RATE_CLIENT_ADDR
|
||||||
|
action=rate(client_address/100/60/450 4.7.1 Maximum 100 messages per minute per IP exceeded. Error:HIGH_RATE_CLIENT_ADDR)
|
||||||
|
|
||||||
|
# 7. EMPFAENGERSUMME PRO STUNDE UND SASL-BENUTZER
|
||||||
|
# 500er-Nachrichtenausnahme erhaelt automatisch auch 1000 Empfaenger/Stunde.
|
||||||
|
# So scheitert sie nicht nach spaetestens 250 Ein-Empfaenger-Nachrichten.
|
||||||
|
# Die zweite Liste kann weitere Benutzer NUR fuer die Empfaengersumme nennen.
|
||||||
|
id=SELECT_RCPT_EXCEPTION_MSG
|
||||||
|
sasl_username==file:/etc/postfix/postfwd.high-rate-number-messages
|
||||||
|
action=jump(RATE_RCPT_HIGH)
|
||||||
|
|
||||||
|
id=SELECT_RCPT_EXCEPTION_LIST
|
||||||
|
sasl_username==file:/etc/postfix/postfwd.high-rate-number-recipients
|
||||||
|
action=jump(RATE_RCPT_HIGH)
|
||||||
|
|
||||||
|
id=RATE_RCPT
|
||||||
|
sasl_username!~^$
|
||||||
|
action=rcpt(sasl_username/250/3600/450 4.7.1 Maximum 250 recipients per hour exceeded. Error:RATE_RCPT)
|
||||||
|
|
||||||
|
id=AFTER_RATE_RCPT
|
||||||
|
action=jump(END)
|
||||||
|
|
||||||
|
id=RATE_RCPT_HIGH
|
||||||
|
sasl_username!~^$
|
||||||
|
action=rcpt(sasl_username/1000/3600/450 4.7.1 Maximum 1000 recipients per hour exceeded. Error:RATE_RCPT_HIGH)
|
||||||
|
|
||||||
|
id=END
|
||||||
|
action=DUNNO
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# SASL-Benutzer mit bis zu 500 Nachrichten UND 1000 Empfaengern pro Stunde.
|
||||||
|
#
|
||||||
|
# Exakter sasl_username pro Zeile, keine Regex. Leere Datei = keine Ausnahme.
|
||||||
|
# ===========================================================================
|
||||||
|
#
|
||||||
|
# interne Bemerkung
|
||||||
|
# Die Standardlimits 50 Nachrichten und 250 Empfaenger werden gezielt
|
||||||
|
# uebersprungen, ebenso das IP-Minutenlimit (50 bzw. 100 Nachrichten/Minute).
|
||||||
|
# Maximal 89 Empfaenger/Nachricht gelten weiterhin.
|
||||||
|
# Eine Nachricht mit 10 Empfaengern zaehlt als 1 Nachricht und 10 Empfaenger.
|
||||||
|
# Dies ist keine vollstaendige Freistellung; Blacklists gelten weiterhin.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# buchsys@sprachenatelier-berlin.de
|
||||||
|
# todo@warenform.de
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Zusaetzliche SASL-Benutzer mit bis zu 1000 Empfaengern pro Stunde.
|
||||||
|
#
|
||||||
|
# Exakter sasl_username pro Zeile, keine Regex. Das Nachrichtenlimit bleibt 50,
|
||||||
|
# =============================================================================
|
||||||
|
#
|
||||||
|
# sofern der Benutzer nicht auch in postfwd.high-rate-number-messages steht.
|
||||||
|
# Benutzer der Nachrichtenliste haben die 1000er-Ausnahme bereits automatisch
|
||||||
|
# und muessen hier NICHT doppelt gepflegt werden. Leer ist zulaessig.
|
||||||
|
# Es werden Empfaengervorkommen gezaehlt, keine eindeutigen Adressen.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# # give sasl usernames here
|
||||||
|
# #
|
||||||
|
# ckubu@oopen.de
|
||||||
|
#
|
||||||
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# ============================================================
|
||||||
|
# Whitelist fuer erhoehtes Rate-Limit (100 Nachrichten/Minute)
|
||||||
|
# auf Basis des Client-Hostnamens (Reverse-DNS/PTR-Eintrag),
|
||||||
|
# statt der Standard-Grenze von 50/Minute aus RATE_CLIENT_ADDR
|
||||||
|
#
|
||||||
|
# Format: Perl-Regex pro Zeile (kein Wildcard/Glob!), umschliessende
|
||||||
|
# '/.../' sind optional. Keine Postfix-pcre:-Tabelle.
|
||||||
|
#
|
||||||
|
# postfwd vergleicht jede Zeile gegen den von Postfix aufgeloesten
|
||||||
|
# 'client_name'-Wert (PTR-Eintrag der Client-IP).
|
||||||
|
# Leerzeilen und Zeilen, die mit '#' beginnen, werden ignoriert.
|
||||||
|
#
|
||||||
|
# Example
|
||||||
|
#
|
||||||
|
# ^buchsys3\.buchsys\.de$
|
||||||
|
#
|
||||||
|
# # buchsys.de
|
||||||
|
# # www.buchsys.de
|
||||||
|
# # mail.buchsys.com
|
||||||
|
# # buchsys.org
|
||||||
|
# #www.buchsys.co.uk
|
||||||
|
# (^|\.)buchsys\.[a-z0-9.-]+$
|
||||||
|
#
|
||||||
|
# WICHTIG:
|
||||||
|
# - Diese Regel greift NUR, wenn Reverse-DNS fuer die jeweilige
|
||||||
|
# IP sauber konfiguriert ist und der PTR-Eintrag auf das Muster
|
||||||
|
# passt. Pruefe den tatsaechlichen 'client_name'-Wert vorher in
|
||||||
|
# den postfwd-Logs.
|
||||||
|
# - Ein zu breites Muster (z.B. /buchsys\.de/ ohne Anker) kann auch
|
||||||
|
# unerwuenschte Hosts matchen (z.B. "evil-buchsys.de.attacker.com").
|
||||||
|
# Deshalb immer mit '^' und '$' bzw. '\.' vor der Domain arbeiten.
|
||||||
|
# - Jeder hier gematchte Hostname umgeht das strengere 50er-Limit
|
||||||
|
# und erlaubt bis zu 100 Nachrichten/Minute. Bitte nur Muster
|
||||||
|
# eintragen, denen du tatsaechlich vertraust.
|
||||||
|
# - Benutzer aus postfwd.high-rate-number-messages sind vom
|
||||||
|
# Minutenlimit ohnehin ausgenommen und brauchen hier keinen Eintrag.
|
||||||
|
# - Nach Aenderungen: postfwd -f /etc/postfix/postfwd.cf -C
|
||||||
|
# Danach: systemctl reload postfwd (Dienst heisst postfwd, nicht postfwd2)
|
||||||
|
# - Die Datei wird in postfwd.cf per 'client_name=~file:' eingelesen
|
||||||
|
# (Regel 'SELECT_HIGH_RATE_HOST', Zaehler in 'HIGH_RATE_CLIENT_ADDR').
|
||||||
|
# - Die IP-basierte Auswahl (SELECT_HIGH_RATE_IP) ist zuverlaessiger
|
||||||
|
# und sollte die primaere Loesung sein; diese Hostname-Regel
|
||||||
|
# eignet sich vor allem als Ergaenzung bei wechselnden IPs.
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# ============================================================
|
||||||
|
# Whitelist fuer erhoehtes Rate-Limit (100 Nachrichten/Minute)
|
||||||
|
# statt der Standard-Grenze von 50/Minute aus RATE_CLIENT_ADDR
|
||||||
|
#
|
||||||
|
# Hier werden IP-Adressen bzw. CIDR-Netze von vertrauenswuerdigen
|
||||||
|
# Absende-Systemen eingetragen, die routinemaessig hoehere
|
||||||
|
# Mailmengen ueber eine feste Absender-IP verschicken, z. B.
|
||||||
|
# Kunden-Mailserver, angebundene Fachanwendungen/Buchungssysteme,
|
||||||
|
# Newsletter- oder Transaktionsmail-Versender.
|
||||||
|
#
|
||||||
|
# Format: eine IP-Adresse oder ein CIDR-Netz pro Zeile.
|
||||||
|
# Leerzeilen und Zeilen, die mit '#' beginnen, werden ignoriert.
|
||||||
|
# IPv4 und IPv6 werden unterstuetzt.
|
||||||
|
#
|
||||||
|
# Beispiele:
|
||||||
|
#
|
||||||
|
# 116.202.85.120
|
||||||
|
# 203.0.113.0/24
|
||||||
|
#
|
||||||
|
# WICHTIG:
|
||||||
|
# - Jede hier eingetragene IP umgeht das strengere 50er-Limit
|
||||||
|
# und darf bis zu 100 Nachrichten/Minute senden. Bitte nur
|
||||||
|
# IPs eintragen, denen du tatsaechlich vertraust (kompromittierte
|
||||||
|
# oder falsch eingetragene Systeme koennten sonst zum offenen
|
||||||
|
# Spam-Verteiler werden).
|
||||||
|
# - Benutzer aus postfwd.high-rate-number-messages sind vom
|
||||||
|
# Minutenlimit ohnehin ausgenommen und brauchen hier keinen Eintrag.
|
||||||
|
# - IPv6 nur als exakte Adresse OHNE /128 (postfwd 1.35).
|
||||||
|
# - Nach Aenderungen: postfwd -f /etc/postfix/postfwd.cf -C
|
||||||
|
# Danach: systemctl reload postfwd (Dienst heisst postfwd, nicht postfwd2)
|
||||||
|
# - Die Datei wird in postfwd.cf per 'client_address==file:' eingelesen
|
||||||
|
# (Regel 'SELECT_HIGH_RATE_IP', Zaehler in 'HIGH_RATE_CLIENT_ADDR').
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Vollstaendige Freistellung anhand des von Postfix gelieferten client_name.
|
||||||
|
#
|
||||||
|
# Perl-Regex pro Zeile;
|
||||||
|
#
|
||||||
|
# Beispiel:
|
||||||
|
# ^mail\.example\.org$
|
||||||
|
#
|
||||||
|
# # Domaene einschliesslich Subdomains:
|
||||||
|
# (^|\.)example\.org$
|
||||||
|
#
|
||||||
|
# Umgeht auch Blacklists und alle Versandlimits. Fuer nur 100 Nachrichten pro
|
||||||
|
# Minute die Datei postfwd.high_rate_hostname verwenden.
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# Vollstaendige Freistellung fuer Client-IP-Adressen/IPv4-Netze.
|
||||||
|
# Umgeht auch die nachfolgenden Blacklists und alle Limits; nur bewusst nutzen.
|
||||||
|
# IPv4: einzelne Adresse oder CIDR-Netz. postfwd2 1.35 verarbeitet IPv6 hier
|
||||||
|
# nur als exakten Adresstext OHNE /128, nicht als IPv6-CIDR-Netz.
|
||||||
|
#
|
||||||
|
# Exakte IPv6-Schreibweise wie client_address von Postfix verwenden.
|
||||||
|
# Eine Adresse/ein Netz pro Zeile.
|
||||||
|
#
|
||||||
|
# Beispiele:
|
||||||
|
#
|
||||||
|
# 192.0.2.10
|
||||||
|
# 192.0.2.0/24
|
||||||
|
#
|
||||||
|
# # b.mx.oopen.de
|
||||||
|
# 2a01:4f8:271:1266::73
|
||||||
|
# 2a01:4f8:271:1266::/64
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# d.mx.oopen.de (listen server)
|
||||||
|
95.217.204.227
|
||||||
|
2a01:4f9:4a:47e5::227
|
||||||
|
|
||||||
|
# b.mx.oopen.de
|
||||||
|
162.55.82.73/32
|
||||||
|
2a01:4f8:271:1266::73
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# Vollstaendige Freistellung anhand des Envelope-Absenders, NICHT From:-Header.
|
||||||
|
#
|
||||||
|
# Perl-Regex pro Zeile
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# ^noreply@example\.org$
|
||||||
|
#
|
||||||
|
# ACHTUNG:
|
||||||
|
# Absender ist nachahmbar; diese Liste prueft weder SPF noch DKIM noch
|
||||||
|
# SASL-Identitaet. Treffer umgehen nachfolgende postfwd-Sperren und Limits.
|
||||||
|
# Der vorhandene Eintrag wurde als bisherige Ausnahme beibehalten.
|
||||||
|
#
|
||||||
|
|
||||||
|
^noreply@login\.ubuntu\.com$
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# Vollstaendige Freistellung fuer SASL-Benutzernamen.
|
||||||
|
#
|
||||||
|
# Exakter Name pro Zeile, keine Regex; wie von Postfix als sasl_username geliefert.
|
||||||
|
#
|
||||||
|
# Umgeht auch Blacklists und alle Limits. Fuer nur hoehere Limits stattdessen
|
||||||
|
# postfwd.high-rate-number-messages bzw. -recipients verwenden.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# # give trusted sasl usernames here
|
||||||
|
# ckubu@oopen.de
|
||||||
|
# vertrieb@akweb.de
|
||||||
|
|
||||||
@@ -5205,9 +5205,15 @@ fi
|
|||||||
## - -o smtpd_sender_restrictions=
|
## - -o smtpd_sender_restrictions=
|
||||||
## - -o smtpd_recipient_restrictions=permit_mynetworks,reject
|
## - -o smtpd_recipient_restrictions=permit_mynetworks,reject
|
||||||
## - -o smtpd_data_restrictions=
|
## - -o smtpd_data_restrictions=
|
||||||
|
## - -o smtpd_end_of_data_restrictions=
|
||||||
## - -o mynetworks=127.0.0.0/8,[::1]/128
|
## - -o mynetworks=127.0.0.0/8,[::1]/128
|
||||||
## - -o receive_override_options=no_unknown_recipient_checks
|
## - -o receive_override_options=no_unknown_recipient_checks
|
||||||
## -
|
## -
|
||||||
|
## - - 'smtpd_end_of_data_restrictions=' disables the postfwd policy check
|
||||||
|
## - (main.cf) for mail reinjected by amavis. Otherwise every message
|
||||||
|
## - could be counted twice by the postfwd rate limits (XFORWARD restores
|
||||||
|
## - the original client address on reinjection).
|
||||||
|
## -
|
||||||
## - - take care not to have 'content_filter' set im main.cf
|
## - - take care not to have 'content_filter' set im main.cf
|
||||||
postfix_master_cf="/etc/postfix/master.cf"
|
postfix_master_cf="/etc/postfix/master.cf"
|
||||||
echo ""
|
echo ""
|
||||||
@@ -5281,6 +5287,7 @@ localhost:10025 inet n - y - - smtpd
|
|||||||
-o smtpd_sender_restrictions=
|
-o smtpd_sender_restrictions=
|
||||||
-o smtpd_recipient_restrictions=permit_mynetworks,reject
|
-o smtpd_recipient_restrictions=permit_mynetworks,reject
|
||||||
-o smtpd_data_restrictions=
|
-o smtpd_data_restrictions=
|
||||||
|
-o smtpd_end_of_data_restrictions=
|
||||||
-o mynetworks=127.0.0.0/8,[::1]/128
|
-o mynetworks=127.0.0.0/8,[::1]/128
|
||||||
-o receive_override_options=no_unknown_recipient_checks
|
-o receive_override_options=no_unknown_recipient_checks
|
||||||
EOF
|
EOF
|
||||||
@@ -5336,6 +5343,7 @@ localhost:10025 inet n - y - - smtpd
|
|||||||
-o smtpd_sender_restrictions=
|
-o smtpd_sender_restrictions=
|
||||||
-o smtpd_recipient_restrictions=permit_mynetworks,reject
|
-o smtpd_recipient_restrictions=permit_mynetworks,reject
|
||||||
-o smtpd_data_restrictions=
|
-o smtpd_data_restrictions=
|
||||||
|
-o smtpd_end_of_data_restrictions=
|
||||||
-o mynetworks=127.0.0.0/8,[::1]/128
|
-o mynetworks=127.0.0.0/8,[::1]/128
|
||||||
-o receive_override_options=no_unknown_recipient_checks
|
-o receive_override_options=no_unknown_recipient_checks
|
||||||
EOF
|
EOF
|
||||||
@@ -5384,6 +5392,7 @@ localhost:10025 inet n - y - - smtpd
|
|||||||
-o smtpd_sender_restrictions=
|
-o smtpd_sender_restrictions=
|
||||||
-o smtpd_recipient_restrictions=permit_mynetworks,reject
|
-o smtpd_recipient_restrictions=permit_mynetworks,reject
|
||||||
-o smtpd_data_restrictions=
|
-o smtpd_data_restrictions=
|
||||||
|
-o smtpd_end_of_data_restrictions=
|
||||||
-o mynetworks=127.0.0.0/8,[::1]/128
|
-o mynetworks=127.0.0.0/8,[::1]/128
|
||||||
-o receive_override_options=no_unknown_recipient_checks
|
-o receive_override_options=no_unknown_recipient_checks
|
||||||
EOF
|
EOF
|
||||||
@@ -5416,6 +5425,7 @@ localhost:10025 inet n - y - - smtpd
|
|||||||
-o smtpd_sender_restrictions=
|
-o smtpd_sender_restrictions=
|
||||||
-o smtpd_recipient_restrictions=permit_mynetworks,reject
|
-o smtpd_recipient_restrictions=permit_mynetworks,reject
|
||||||
-o smtpd_data_restrictions=
|
-o smtpd_data_restrictions=
|
||||||
|
-o smtpd_end_of_data_restrictions=
|
||||||
-o mynetworks=127.0.0.0/8,[::1]/128
|
-o mynetworks=127.0.0.0/8,[::1]/128
|
||||||
-o receive_override_options=no_unknown_recipient_checks
|
-o receive_override_options=no_unknown_recipient_checks
|
||||||
EOF
|
EOF
|
||||||
|
|||||||
+126
-403
@@ -1186,443 +1186,166 @@ else
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echononl " Adjust /etc/default/postfwd"
|
## - Adjust /etc/default/postfwd
|
||||||
perl -i -n -p -e "s#^(\s*)(STARTUP=.*)#\#\1\2\nSTARTUP=1#" \
|
## -
|
||||||
/etc/default/postfwd > $log_file 2>&1
|
## - set_postfwd_default <VAR> <VALUE>
|
||||||
|
## -
|
||||||
|
## - - VAR is set (uncommented) and has the wanted value -> nothing to do
|
||||||
|
## - - VAR is set with a different value -> comment out the current
|
||||||
|
## - setting and add the new setting directly below it
|
||||||
|
## - - VAR is not set at all -> append the new setting
|
||||||
|
## -
|
||||||
|
## - Quotes around the value are ignored when comparing ("1" == 1).
|
||||||
|
## -
|
||||||
|
postfwd_default_file="/etc/default/postfwd"
|
||||||
|
|
||||||
|
set_postfwd_default() {
|
||||||
|
local _var="$1"
|
||||||
|
local _val="$2"
|
||||||
|
local _tmp_file
|
||||||
|
|
||||||
|
echononl " ${_var}=${_val}"
|
||||||
|
|
||||||
|
if [[ ! -f "$postfwd_default_file" ]] ; then
|
||||||
|
touch "$postfwd_default_file" > "$log_file" 2>&1 || { echo_failed ; error "$(cat $log_file)" ; return 1 ; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
_tmp_file="$(mktemp)"
|
||||||
|
awk -v var="$_var" -v val="$_val" '
|
||||||
|
function unq(s) {
|
||||||
|
gsub(/^[ \t]+|[ \t]+$/, "", s)
|
||||||
|
if (s ~ /^".*"$/ || s ~ /^\047.*\047$/) s = substr(s, 2, length(s) - 2)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
$0 ~ "^[ \t]*" var "=" {
|
||||||
|
cur = $0 ; sub("^[ \t]*" var "=", "", cur)
|
||||||
|
if (! done && unq(cur) == unq(val)) { print ; done = 1 ; next }
|
||||||
|
print "#" $0
|
||||||
|
if (! done) { print var "=" val ; done = 1 }
|
||||||
|
next
|
||||||
|
}
|
||||||
|
{ print }
|
||||||
|
END { if (! done) print var "=" val }
|
||||||
|
' "$postfwd_default_file" > "$_tmp_file" 2> "$log_file"
|
||||||
|
|
||||||
|
if [[ $? -ne 0 ]] ; then
|
||||||
|
echo_failed
|
||||||
|
error "$(cat $log_file)"
|
||||||
|
elif cmp -s "$_tmp_file" "$postfwd_default_file" ; then
|
||||||
|
echo_skipped
|
||||||
|
else
|
||||||
|
# - cat instead of mv/cp keeps owner and permissions of the original file
|
||||||
|
cat "$_tmp_file" > "$postfwd_default_file" 2> "$log_file"
|
||||||
if [[ $? -eq 0 ]] ; then
|
if [[ $? -eq 0 ]] ; then
|
||||||
echo_ok
|
echo_ok
|
||||||
else
|
else
|
||||||
echo_failed
|
echo_failed
|
||||||
error "$(cat $log_file)"
|
error "$(cat $log_file)"
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
rm -f "$_tmp_file"
|
||||||
|
}
|
||||||
|
|
||||||
_file="/etc/postfix/postfwd.wl-nets"
|
echo ""
|
||||||
echononl " Create whitelist file '$_file' for postfwd"
|
echo " Adjust ${postfwd_default_file}"
|
||||||
if [[ ! -f "$_file" ]]; then
|
set_postfwd_default STARTUP "1"
|
||||||
cat << EOF > "$_file"
|
set_postfwd_default CONF "/etc/postfix/postfwd.cf"
|
||||||
# ---
|
set_postfwd_default INET "127.0.0.1"
|
||||||
# Trusted networks whitelisted by postfwd
|
set_postfwd_default PORT "10040"
|
||||||
#
|
set_postfwd_default ARGS '"--summary=600 --cache=0"'
|
||||||
# Example:
|
echo ""
|
||||||
#
|
|
||||||
# # web0.warenform.de
|
|
||||||
# #83.223.86.76
|
|
||||||
# #2a01:30:0:505:286:96ff:fe4a:6ee
|
|
||||||
# #2a01:30:0:13:286:96ff:fe4a:6eee
|
|
||||||
#
|
|
||||||
# ---
|
|
||||||
|
|
||||||
# give truested networrk adresses here
|
|
||||||
EOF
|
## - Install postfwd configuration and list files shipped with this
|
||||||
|
## - repository (directory 'files/postfwd').
|
||||||
|
## -
|
||||||
|
## - - postfwd.cf: installed; an existing, differing file is saved
|
||||||
|
## - as postfwd.cf.<backup_date> first.
|
||||||
|
## - - list files (whitelists, blacklists, high-rate exceptions):
|
||||||
|
## - only installed if not yet present - existing lists contain
|
||||||
|
## - local data and are never overwritten.
|
||||||
|
## -
|
||||||
|
postfwd_src_dir="${working_dir}/files/postfwd"
|
||||||
|
postfwd_conf_dir="/etc/postfix"
|
||||||
|
|
||||||
|
postfwd_list_files="
|
||||||
|
postfwd.wl-nets
|
||||||
|
postfwd.wl-hosts
|
||||||
|
postfwd.wl-user
|
||||||
|
postfwd.wl-sender
|
||||||
|
postfwd.bl-nets
|
||||||
|
postfwd.bl-hosts
|
||||||
|
postfwd.bl-user
|
||||||
|
postfwd.bl-sender
|
||||||
|
postfwd.bl-recipient-exeeds-msg-size-20mb
|
||||||
|
postfwd.high_rate_ip
|
||||||
|
postfwd.high_rate_hostname
|
||||||
|
postfwd.high-rate-number-messages
|
||||||
|
postfwd.high-rate-number-recipients
|
||||||
|
"
|
||||||
|
|
||||||
|
if [[ ! -d "$postfwd_src_dir" ]] || [[ ! -f "${postfwd_src_dir}/postfwd.cf" ]] ; then
|
||||||
|
error "Directory '${postfwd_src_dir}' (or postfwd.cf in it) not found - postfwd configuration NOT installed!"
|
||||||
|
else
|
||||||
|
|
||||||
|
for _file in $postfwd_list_files ; do
|
||||||
|
echononl " Install list file '${postfwd_conf_dir}/${_file}'"
|
||||||
|
if [[ ! -f "${postfwd_src_dir}/${_file}" ]] ; then
|
||||||
|
echo_failed
|
||||||
|
error "Source file '${postfwd_src_dir}/${_file}' not found."
|
||||||
|
elif [[ -f "${postfwd_conf_dir}/${_file}" ]] ; then
|
||||||
|
echo_skipped
|
||||||
|
else
|
||||||
|
install -m 0644 -o root -g root "${postfwd_src_dir}/${_file}" \
|
||||||
|
"${postfwd_conf_dir}/${_file}" > "$log_file" 2>&1
|
||||||
if [[ $? -eq 0 ]] ; then
|
if [[ $? -eq 0 ]] ; then
|
||||||
echo_ok
|
echo_ok
|
||||||
else
|
else
|
||||||
echo_failed
|
echo_failed
|
||||||
|
error "$(cat $log_file)"
|
||||||
fi
|
fi
|
||||||
else
|
|
||||||
echo_skipped
|
|
||||||
fi
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
_file="/etc/postfix/postfwd.wl-hosts"
|
_file="${postfwd_conf_dir}/postfwd.cf"
|
||||||
echononl " Create whitelist file '$_file' for postfwd"
|
if [[ -f "$_file" ]] && ! cmp -s "${postfwd_src_dir}/postfwd.cf" "$_file" ; then
|
||||||
if [[ ! -f "$_file" ]]; then
|
echononl " Backup existing '${_file}'"
|
||||||
cat << EOF > "$_file"
|
cp -a "$_file" "${_file}.${backup_date}" > "$log_file" 2>&1
|
||||||
# ---
|
|
||||||
# Trusted hosts whitelisted by postfwd
|
|
||||||
#
|
|
||||||
# This file is called with '=~'. This means perl regexp is possible
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# # all hosts of domain 'oopen.de'
|
|
||||||
# \.oopen\.de$
|
|
||||||
#
|
|
||||||
# # host a.mx.oopen.de
|
|
||||||
# a.mx.oopen.de
|
|
||||||
#
|
|
||||||
# ---
|
|
||||||
|
|
||||||
# give truested hostnames here
|
|
||||||
|
|
||||||
EOF
|
|
||||||
if [[ $? -eq 0 ]] ; then
|
if [[ $? -eq 0 ]] ; then
|
||||||
echo_ok
|
echo_ok
|
||||||
else
|
else
|
||||||
echo_failed
|
echo_failed
|
||||||
|
error "$(cat $log_file)"
|
||||||
fi
|
fi
|
||||||
else
|
fi
|
||||||
|
|
||||||
|
echononl " Install configuration file '${_file}'"
|
||||||
|
if [[ -f "$_file" ]] && cmp -s "${postfwd_src_dir}/postfwd.cf" "$_file" ; then
|
||||||
echo_skipped
|
echo_skipped
|
||||||
fi
|
else
|
||||||
|
install -m 0644 -o root -g root "${postfwd_src_dir}/postfwd.cf" "$_file" > "$log_file" 2>&1
|
||||||
_file="/etc/postfix/postfwd.wl-user"
|
|
||||||
echononl " Create whitelist file '$_file' for postfwd"
|
|
||||||
if [[ ! -f "$_file" ]]; then
|
|
||||||
cat << EOF > "$_file"
|
|
||||||
# ---
|
|
||||||
# SASL Users whitelisted by postfwd
|
|
||||||
# ---
|
|
||||||
|
|
||||||
EOF
|
|
||||||
if [[ $? -eq 0 ]] ; then
|
if [[ $? -eq 0 ]] ; then
|
||||||
echo_ok
|
echo_ok
|
||||||
else
|
else
|
||||||
echo_failed
|
echo_failed
|
||||||
|
error "$(cat $log_file)"
|
||||||
fi
|
fi
|
||||||
else
|
|
||||||
echo_skipped
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_file="/etc/postfix/postfwd.wl-sender"
|
# - Check configuration: postfwd reports missing list files, undefined
|
||||||
echononl " Create whitelist file '$_file' for postfwd"
|
# - macros or invalid lines only as warnings and keeps running.
|
||||||
if [[ ! -f "$_file" ]]; then
|
echononl " Check postfwd configuration"
|
||||||
cat << EOF > "$_file"
|
_postfwd_check="$(postfwd --showconfig --file "$_file" 2>&1 \
|
||||||
# ---
|
| grep -E '^\[LOG (warning|err|crit)')"
|
||||||
# Trusted senders whitelisted by postfwd
|
if [[ -z "$_postfwd_check" ]] ; then
|
||||||
#
|
|
||||||
# This file is called with '=~'. This means perl regexp is possible
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# # all senders of maildomaindomain 'oopen.de'
|
|
||||||
# @oopen\.de$
|
|
||||||
#
|
|
||||||
# # sender address ckubu@oopen.de
|
|
||||||
# ckubu@oopen.de
|
|
||||||
#
|
|
||||||
# ---
|
|
||||||
|
|
||||||
# give trusted sender addresses here
|
|
||||||
|
|
||||||
EOF
|
|
||||||
if [[ $? -eq 0 ]] ; then
|
|
||||||
echo_ok
|
echo_ok
|
||||||
else
|
else
|
||||||
echo_failed
|
echo_warning
|
||||||
fi
|
warn "postfwd reports problems with '${_file}':\n\n${_postfwd_check}"
|
||||||
else
|
|
||||||
echo_skipped
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_file="/etc/postfix/postfwd.bl-nets"
|
|
||||||
echononl " Create whitelist file '$_file' for postfwd"
|
|
||||||
if [[ ! -f "$_file" ]]; then
|
|
||||||
cat << EOF > "$_file"
|
|
||||||
# ---
|
|
||||||
# Networks blocked by postfwd
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# # web0.warenform.de
|
|
||||||
# #83.223.86.76
|
|
||||||
# #2a01:30:0:505:286:96ff:fe4a:6ee
|
|
||||||
# #2a01:30:0:13:286:96ff:fe4a:6eee
|
|
||||||
#
|
|
||||||
# ---
|
|
||||||
|
|
||||||
# give networks to block here
|
|
||||||
|
|
||||||
EOF
|
|
||||||
if [[ $? -eq 0 ]] ; then
|
|
||||||
echo_ok
|
|
||||||
else
|
|
||||||
echo_failed
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo_skipped
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_file="/etc/postfix/postfwd.bl-hosts"
|
|
||||||
echononl " Create whitelist file '$_file' for postfwd"
|
|
||||||
if [[ ! -f "$_file" ]]; then
|
|
||||||
cat << EOF > "$_file"
|
|
||||||
# ---
|
|
||||||
# hosts blocked by postfwd
|
|
||||||
#
|
|
||||||
# This file is called with '=~'. This means perl regexp is possible
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# # block all hosts of domain 'oopen.de'
|
|
||||||
# \.oopen\.de$
|
|
||||||
#
|
|
||||||
# # block host a.mx.oopen.de
|
|
||||||
# a.mx.oopen.de
|
|
||||||
#
|
|
||||||
# ---
|
|
||||||
|
|
||||||
# give hostnames to blocke here
|
|
||||||
|
|
||||||
EOF
|
|
||||||
if [[ $? -eq 0 ]] ; then
|
|
||||||
echo_ok
|
|
||||||
else
|
|
||||||
echo_failed
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo_skipped
|
|
||||||
fi
|
|
||||||
|
|
||||||
_file="/etc/postfix/postfwd.bl-user"
|
|
||||||
echononl " Create whitelist file '$_file' for postfwd"
|
|
||||||
if [[ ! -f "$_file" ]]; then
|
|
||||||
cat << EOF > "$_file"
|
|
||||||
# ---
|
|
||||||
# SASL Users blocked by postfwd
|
|
||||||
# ---
|
|
||||||
|
|
||||||
EOF
|
|
||||||
if [[ $? -eq 0 ]] ; then
|
|
||||||
echo_ok
|
|
||||||
else
|
|
||||||
echo_failed
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo_skipped
|
|
||||||
fi
|
|
||||||
|
|
||||||
_file="/etc/postfix/postfwd.bl-sender"
|
|
||||||
echononl " Create whitelist file '$_file' for postfwd"
|
|
||||||
if [[ ! -f "$_file" ]]; then
|
|
||||||
cat << EOF > "$_file"
|
|
||||||
# ---
|
|
||||||
# Sender addresses blocked by postfwd
|
|
||||||
# ---
|
|
||||||
|
|
||||||
# annoying spammer domains
|
|
||||||
@acieu.co.uk
|
|
||||||
|
|
||||||
# annoying spammer addresses
|
|
||||||
error@mailfrom.com
|
|
||||||
|
|
||||||
EOF
|
|
||||||
if [[ $? -eq 0 ]] ; then
|
|
||||||
echo_ok
|
|
||||||
else
|
|
||||||
echo_failed
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo_skipped
|
|
||||||
fi
|
|
||||||
|
|
||||||
_file="/etc/postfix/postfwd.bl-sender"
|
|
||||||
echononl " Create whitelist file '$_file' for postfwd"
|
|
||||||
if [[ ! -f "$_file" ]]; then
|
|
||||||
cat << EOF > "$_file"
|
|
||||||
# ---
|
|
||||||
# Sender addresses blocked by postfwd
|
|
||||||
#
|
|
||||||
# This file is called with '=~'. This means perl regexp is possible
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# # all senders of maildomaindomain 'oopen.de'
|
|
||||||
# @oopen\.de$
|
|
||||||
#
|
|
||||||
# # sender address ckubu@oopen.de
|
|
||||||
# ckubu@oopen.de
|
|
||||||
#
|
|
||||||
# ---
|
|
||||||
|
|
||||||
# annoying spammer domains
|
|
||||||
@acieu.co.uk
|
|
||||||
|
|
||||||
# annoying spammer addresses
|
|
||||||
error@mailfrom.com
|
|
||||||
|
|
||||||
EOF
|
|
||||||
if [[ $? -eq 0 ]] ; then
|
|
||||||
echo_ok
|
|
||||||
else
|
|
||||||
echo_failed
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo_skipped
|
|
||||||
fi
|
|
||||||
|
|
||||||
echononl " Create configuration file '/etc/postfix/postfwd.cf'.."
|
|
||||||
if [[ ! -f "/etc/postfix/postfwd.cf" ]]; then
|
|
||||||
cat << EOF > /etc/postfix/postfwd.cf
|
|
||||||
|
|
||||||
#======= Definitions ============
|
|
||||||
|
|
||||||
# Match messages with an associated SASL username
|
|
||||||
&&SASL_AUTH {
|
|
||||||
sasl_username!~^\$
|
|
||||||
}
|
|
||||||
|
|
||||||
# Trusted networks
|
|
||||||
&&TRUSTED_NETS {
|
|
||||||
client_address==file:/etc/postfix/postfwd.wl-nets
|
|
||||||
}
|
|
||||||
|
|
||||||
# Trusted hostnames
|
|
||||||
# client_name~=.warenform.de$
|
|
||||||
&&TRUSTED_HOSTS {
|
|
||||||
client_name=~file:/etc/postfix/postfwd.wl-hosts
|
|
||||||
}
|
|
||||||
|
|
||||||
# Trusted users
|
|
||||||
&&TRUSTED_USERS {
|
|
||||||
sasl_username==file:/etc/postfix/postfwd.wl-user
|
|
||||||
}
|
|
||||||
|
|
||||||
# Trusted senders
|
|
||||||
&&TRUSTED_SENDERS {
|
|
||||||
sender=~file:/etc/postfix/postfwd.wl-sender
|
|
||||||
}
|
|
||||||
|
|
||||||
# Blacklist networks
|
|
||||||
&&BLOCK_NETS {
|
|
||||||
client_address==file:/etc/postfix/postfwd.bl-nets
|
|
||||||
}
|
|
||||||
|
|
||||||
# Blacklist hostnames
|
|
||||||
&&BLOCK_HOSTS {
|
|
||||||
client_name=~file:/etc/postfix/postfwd.bl-hosts
|
|
||||||
}
|
|
||||||
|
|
||||||
# Blacklist users
|
|
||||||
&&BLOCK_USERS {
|
|
||||||
sasl_username==file:/etc/postfix/postfwd.bl-user
|
|
||||||
}
|
|
||||||
|
|
||||||
# Blacklist sender adresses
|
|
||||||
&&BLOCK_SENDER {
|
|
||||||
# =~
|
|
||||||
# using '=~' allows also matching entries for domains (i.e. @acieu.co.uk)
|
|
||||||
sender=~file:/etc/postfix/postfwd.bl-sender
|
|
||||||
}
|
|
||||||
|
|
||||||
# Inbound emails only
|
|
||||||
&&INCOMING {
|
|
||||||
client_address!=127.0.0.1
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#======= Rule Sets ============
|
|
||||||
|
|
||||||
# ---
|
|
||||||
#
|
|
||||||
# Processing of the Rule Sets
|
|
||||||
#
|
|
||||||
# The parser checks the elements of a policy delegation request against the postfwd set
|
|
||||||
# of rules and, if necessary, triggers the configured action (action=). Similar to a
|
|
||||||
# classic firewall, a rule is considered true if every element of the set of rules (or
|
|
||||||
# one from every element list) applies to the comparison. I.e. the following rule:
|
|
||||||
#
|
|
||||||
# client_address=1.1.1.1, 1.1.1.2; client_name==unknown; action=REJECT
|
|
||||||
#
|
|
||||||
# triggers a REJECT if the
|
|
||||||
#
|
|
||||||
# Client address is equal (1.1.1.1 OR 1.1.1.2) AND the client name 'unknown'
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# Note:
|
|
||||||
# If an element occurs more than once, an element list is formed:
|
|
||||||
#
|
|
||||||
# The following rule set is equivalent to the above:
|
|
||||||
#
|
|
||||||
# client_address=1.1.1.1; client_address=1.1.1.2; client_name==unknown; action=REJECT
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# triggers a REJECT if (as above) the
|
|
||||||
#
|
|
||||||
# Client address (1.1.1.1 OR 1.1.1.2) AND the client name 'unknown'
|
|
||||||
#
|
|
||||||
# ---
|
|
||||||
|
|
||||||
# Whitelists
|
|
||||||
|
|
||||||
# Whitelist trusted networks
|
|
||||||
id=WHL_NETS
|
|
||||||
&&TRUSTED_NETS
|
|
||||||
action=DUNNO
|
|
||||||
|
|
||||||
# Whitelist trusted hostnames
|
|
||||||
id=WHL_HOSTS
|
|
||||||
&&TRUSTED_HOSTS
|
|
||||||
action=DUNNO
|
|
||||||
|
|
||||||
# Whitelist sasl users
|
|
||||||
id=WHL_USERS
|
|
||||||
&&TRUSTED_USERS
|
|
||||||
action=DUNNO
|
|
||||||
|
|
||||||
# Whitelist senders
|
|
||||||
id=WHL_SENDERS
|
|
||||||
&&INCOMING
|
|
||||||
&&TRUSTED_SENDERS
|
|
||||||
action=DUNNO
|
|
||||||
|
|
||||||
|
|
||||||
# Blacklists
|
|
||||||
|
|
||||||
# Block networks
|
|
||||||
id=BL_NETS
|
|
||||||
&&BLOCK_NETS
|
|
||||||
action=REJECT Network Address \$\$client_address blocked by Mailserver admins. Error: BL_NETS
|
|
||||||
|
|
||||||
# Block hostname
|
|
||||||
id=BL_HOSTS
|
|
||||||
&&BLOCK_HOSTS
|
|
||||||
action=REJECT \$\$client_name blocked by Mailserver admins. Error: BL_HOSTS
|
|
||||||
|
|
||||||
# Block users
|
|
||||||
id=BL_USERS
|
|
||||||
&&BLOCK_USERS
|
|
||||||
action=REJECT User is blocked by Mailserver admins. Error: BL_USERS
|
|
||||||
|
|
||||||
# Blacklist sender
|
|
||||||
#
|
|
||||||
# Claim successful delivery and silently discard the message.
|
|
||||||
#
|
|
||||||
id=BL_SENDER
|
|
||||||
&&BLOCK_SENDER
|
|
||||||
#action=DISCARD
|
|
||||||
action=REJECT Sender address is blocked by Mailserver admins. Error: BL_SENDER
|
|
||||||
|
|
||||||
|
|
||||||
# Rate Limits
|
|
||||||
|
|
||||||
# Throttle unknown clients to 5 recipients per 5 minutes:
|
|
||||||
id=RATE_UNKNOWN_CLIENT_ADDR
|
|
||||||
sasl_username =~ /^$/
|
|
||||||
client_name==unknown
|
|
||||||
action=rate(client_address/5/300/450 4.7.1 only 5 recipients per 5 minutes allowed)
|
|
||||||
|
|
||||||
# Block clients (ip-addresses) sending more than 50 messages per minute exceeded. Error:RATE_CLIENT)
|
|
||||||
id=RATE_CLIENT_ADDR
|
|
||||||
&&INCOMING
|
|
||||||
action=rate(\$\$client_address/50/60/421 421 4.7.0 Too many connections from \$\$client_address)
|
|
||||||
|
|
||||||
# Block messages with more than 50 recipients
|
|
||||||
id=BLOCK_MSG_RCPT
|
|
||||||
&&INCOMING
|
|
||||||
&&SASL_AUTH
|
|
||||||
recipient_count=50
|
|
||||||
action=REJECT Too many recipients, please reduce to less than 50 or consider using a mailing list. Error: BLOCK_MSG_RCPT
|
|
||||||
|
|
||||||
# Block users sending more than 50 messages/hour
|
|
||||||
id=RATE_MSG
|
|
||||||
&&INCOMING
|
|
||||||
&&SASL_AUTH
|
|
||||||
action=rate(\$\$sasl_username/50/3600/450 4.7.1 Number messages per hour exceeded. Error:RATE_MSG)
|
|
||||||
|
|
||||||
# Block users sending more than 250 recipients total/hour
|
|
||||||
id=RATE_RCPT
|
|
||||||
&&INCOMING
|
|
||||||
&&SASL_AUTH
|
|
||||||
action=rcpt(\$\$sasl_username/250/3600/450 4.7.1 Number recipients per hour exceeded. Error:RATE_RCPT)
|
|
||||||
|
|
||||||
EOF
|
|
||||||
if [[ $? -eq 0 ]] ; then
|
|
||||||
echo_ok
|
|
||||||
else
|
|
||||||
echo_failed
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo_skipped
|
|
||||||
fi
|
|
||||||
|
|
||||||
echononl " Enable Postfix firewall daemon at boot time .."
|
echononl " Enable Postfix firewall daemon at boot time .."
|
||||||
if $systemd_exists ; then
|
if $systemd_exists ; then
|
||||||
|
|||||||
+132
-396
@@ -1,6 +1,10 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
working_dir="$(dirname "$(realpath "$0")")"
|
||||||
|
|
||||||
tmp_err_msg=$(mktemp)
|
tmp_err_msg=$(mktemp)
|
||||||
|
log_file="$tmp_err_msg"
|
||||||
|
backup_date="$(date +%Y-%m-%d-%H%M)"
|
||||||
|
|
||||||
# -------------
|
# -------------
|
||||||
# --- Some functions
|
# --- Some functions
|
||||||
@@ -89,434 +93,166 @@ else
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echononl " Adjust /etc/default/postfwd"
|
## - Adjust /etc/default/postfwd
|
||||||
perl -i -n -p -e "s#^(\s*)(STARTUP=.*)#\#\1\2\nSTARTUP=1#" \
|
## -
|
||||||
/etc/default/postfwd > $tmp_err_msg 2>&1
|
## - set_postfwd_default <VAR> <VALUE>
|
||||||
if [[ $? -eq 0 ]] ; then
|
## -
|
||||||
echo_ok
|
## - - VAR is set (uncommented) and has the wanted value -> nothing to do
|
||||||
else
|
## - - VAR is set with a different value -> comment out the current
|
||||||
echo_failed
|
## - setting and add the new setting directly below it
|
||||||
error "$(cat $tmp_err_msg)"
|
## - - VAR is not set at all -> append the new setting
|
||||||
|
## -
|
||||||
|
## - Quotes around the value are ignored when comparing ("1" == 1).
|
||||||
|
## -
|
||||||
|
postfwd_default_file="/etc/default/postfwd"
|
||||||
|
|
||||||
|
set_postfwd_default() {
|
||||||
|
local _var="$1"
|
||||||
|
local _val="$2"
|
||||||
|
local _tmp_file
|
||||||
|
|
||||||
|
echononl " ${_var}=${_val}"
|
||||||
|
|
||||||
|
if [[ ! -f "$postfwd_default_file" ]] ; then
|
||||||
|
touch "$postfwd_default_file" > "$log_file" 2>&1 || { echo_failed ; error "$(cat $log_file)" ; return 1 ; }
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_file="/etc/postfix/postfwd.wl-nets"
|
_tmp_file="$(mktemp)"
|
||||||
echononl " Create whitelist file '$_file' for postfwd"
|
awk -v var="$_var" -v val="$_val" '
|
||||||
if [[ ! -f "$_file" ]]; then
|
function unq(s) {
|
||||||
cat << EOF > "$_file"
|
gsub(/^[ \t]+|[ \t]+$/, "", s)
|
||||||
# ---
|
if (s ~ /^".*"$/ || s ~ /^\047.*\047$/) s = substr(s, 2, length(s) - 2)
|
||||||
# Trusted networks whitelisted by postfwd
|
return s
|
||||||
#
|
}
|
||||||
# Example:
|
$0 ~ "^[ \t]*" var "=" {
|
||||||
#
|
cur = $0 ; sub("^[ \t]*" var "=", "", cur)
|
||||||
# # web0.warenform.de
|
if (! done && unq(cur) == unq(val)) { print ; done = 1 ; next }
|
||||||
# #83.223.86.76
|
print "#" $0
|
||||||
# #2a01:30:0:505:286:96ff:fe4a:6ee
|
if (! done) { print var "=" val ; done = 1 }
|
||||||
# #2a01:30:0:13:286:96ff:fe4a:6eee
|
next
|
||||||
#
|
}
|
||||||
# ---
|
{ print }
|
||||||
|
END { if (! done) print var "=" val }
|
||||||
|
' "$postfwd_default_file" > "$_tmp_file" 2> "$log_file"
|
||||||
|
|
||||||
# give truested networrk adresses here
|
if [[ $? -ne 0 ]] ; then
|
||||||
EOF
|
|
||||||
if [[ $? -eq 0 ]] ; then
|
|
||||||
echo_ok
|
|
||||||
else
|
|
||||||
echo_failed
|
echo_failed
|
||||||
fi
|
error "$(cat $log_file)"
|
||||||
else
|
elif cmp -s "$_tmp_file" "$postfwd_default_file" ; then
|
||||||
echo_skipped
|
echo_skipped
|
||||||
fi
|
else
|
||||||
|
# - cat instead of mv/cp keeps owner and permissions of the original file
|
||||||
_file="/etc/postfix/postfwd.wl-hosts"
|
cat "$_tmp_file" > "$postfwd_default_file" 2> "$log_file"
|
||||||
echononl " Create whitelist file '$_file' for postfwd"
|
|
||||||
if [[ ! -f "$_file" ]]; then
|
|
||||||
cat << EOF > "$_file"
|
|
||||||
# ---
|
|
||||||
# Trusted hosts whitelisted by postfwd
|
|
||||||
#
|
|
||||||
# This file is called with '=~'. This means perl regexp is possible
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# # all hosts of domain 'oopen.de'
|
|
||||||
# \.oopen\.de$
|
|
||||||
#
|
|
||||||
# # host a.mx.oopen.de
|
|
||||||
# a.mx.oopen.de
|
|
||||||
#
|
|
||||||
# ---
|
|
||||||
|
|
||||||
# give truested hostnames here
|
|
||||||
|
|
||||||
EOF
|
|
||||||
if [[ $? -eq 0 ]] ; then
|
if [[ $? -eq 0 ]] ; then
|
||||||
echo_ok
|
echo_ok
|
||||||
else
|
else
|
||||||
echo_failed
|
echo_failed
|
||||||
|
error "$(cat $log_file)"
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
rm -f "$_tmp_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo " Adjust ${postfwd_default_file}"
|
||||||
|
set_postfwd_default STARTUP "1"
|
||||||
|
set_postfwd_default CONF "/etc/postfix/postfwd.cf"
|
||||||
|
set_postfwd_default INET "127.0.0.1"
|
||||||
|
set_postfwd_default PORT "10040"
|
||||||
|
set_postfwd_default ARGS '"--summary=600 --cache=0"'
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
|
||||||
|
## - Install postfwd configuration and list files shipped with this
|
||||||
|
## - repository (directory 'files/postfwd').
|
||||||
|
## -
|
||||||
|
## - - postfwd.cf: installed; an existing, differing file is saved
|
||||||
|
## - as postfwd.cf.<backup_date> first.
|
||||||
|
## - - list files (whitelists, blacklists, high-rate exceptions):
|
||||||
|
## - only installed if not yet present - existing lists contain
|
||||||
|
## - local data and are never overwritten.
|
||||||
|
## -
|
||||||
|
postfwd_src_dir="${working_dir}/files/postfwd"
|
||||||
|
postfwd_conf_dir="/etc/postfix"
|
||||||
|
|
||||||
|
postfwd_list_files="
|
||||||
|
postfwd.wl-nets
|
||||||
|
postfwd.wl-hosts
|
||||||
|
postfwd.wl-user
|
||||||
|
postfwd.wl-sender
|
||||||
|
postfwd.bl-nets
|
||||||
|
postfwd.bl-hosts
|
||||||
|
postfwd.bl-user
|
||||||
|
postfwd.bl-sender
|
||||||
|
postfwd.bl-recipient-exeeds-msg-size-20mb
|
||||||
|
postfwd.high_rate_ip
|
||||||
|
postfwd.high_rate_hostname
|
||||||
|
postfwd.high-rate-number-messages
|
||||||
|
postfwd.high-rate-number-recipients
|
||||||
|
"
|
||||||
|
|
||||||
|
if [[ ! -d "$postfwd_src_dir" ]] || [[ ! -f "${postfwd_src_dir}/postfwd.cf" ]] ; then
|
||||||
|
error "Directory '${postfwd_src_dir}' (or postfwd.cf in it) not found - postfwd configuration NOT installed!"
|
||||||
else
|
else
|
||||||
|
|
||||||
|
for _file in $postfwd_list_files ; do
|
||||||
|
echononl " Install list file '${postfwd_conf_dir}/${_file}'"
|
||||||
|
if [[ ! -f "${postfwd_src_dir}/${_file}" ]] ; then
|
||||||
|
echo_failed
|
||||||
|
error "Source file '${postfwd_src_dir}/${_file}' not found."
|
||||||
|
elif [[ -f "${postfwd_conf_dir}/${_file}" ]] ; then
|
||||||
echo_skipped
|
echo_skipped
|
||||||
fi
|
else
|
||||||
|
install -m 0644 -o root -g root "${postfwd_src_dir}/${_file}" \
|
||||||
_file="/etc/postfix/postfwd.wl-user"
|
"${postfwd_conf_dir}/${_file}" > "$log_file" 2>&1
|
||||||
echononl " Create whitelist file '$_file' for postfwd"
|
|
||||||
if [[ ! -f "$_file" ]]; then
|
|
||||||
cat << EOF > "$_file"
|
|
||||||
# ---
|
|
||||||
# SASL Users whitelisted by postfwd
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# # give trusted sasl_user here
|
|
||||||
# admin@warenform.de
|
|
||||||
#
|
|
||||||
# ---
|
|
||||||
|
|
||||||
# give trusted sasl_user here
|
|
||||||
|
|
||||||
EOF
|
|
||||||
if [[ $? -eq 0 ]] ; then
|
if [[ $? -eq 0 ]] ; then
|
||||||
echo_ok
|
echo_ok
|
||||||
else
|
else
|
||||||
echo_failed
|
echo_failed
|
||||||
|
error "$(cat $log_file)"
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
_file="${postfwd_conf_dir}/postfwd.cf"
|
||||||
|
if [[ -f "$_file" ]] && ! cmp -s "${postfwd_src_dir}/postfwd.cf" "$_file" ; then
|
||||||
|
echononl " Backup existing '${_file}'"
|
||||||
|
cp -a "$_file" "${_file}.${backup_date}" > "$log_file" 2>&1
|
||||||
|
if [[ $? -eq 0 ]] ; then
|
||||||
|
echo_ok
|
||||||
else
|
else
|
||||||
|
echo_failed
|
||||||
|
error "$(cat $log_file)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echononl " Install configuration file '${_file}'"
|
||||||
|
if [[ -f "$_file" ]] && cmp -s "${postfwd_src_dir}/postfwd.cf" "$_file" ; then
|
||||||
echo_skipped
|
echo_skipped
|
||||||
fi
|
else
|
||||||
|
install -m 0644 -o root -g root "${postfwd_src_dir}/postfwd.cf" "$_file" > "$log_file" 2>&1
|
||||||
_file="/etc/postfix/postfwd.wl-sender"
|
|
||||||
echononl " Create whitelist file '$_file' for postfwd"
|
|
||||||
if [[ ! -f "$_file" ]]; then
|
|
||||||
cat << EOF > "$_file"
|
|
||||||
# ---
|
|
||||||
# Trusted senders whitelisted by postfwd
|
|
||||||
#
|
|
||||||
# This file is called with '=~'. This means perl regexp is possible
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# # all senders of maildomaindomain 'oopen.de'
|
|
||||||
# @oopen\.de$
|
|
||||||
#
|
|
||||||
# # sender address ckubu@oopen.de
|
|
||||||
# ckubu@oopen.de
|
|
||||||
#
|
|
||||||
# ---
|
|
||||||
|
|
||||||
# give trusted sender addresses here
|
|
||||||
|
|
||||||
EOF
|
|
||||||
if [[ $? -eq 0 ]] ; then
|
if [[ $? -eq 0 ]] ; then
|
||||||
echo_ok
|
echo_ok
|
||||||
else
|
else
|
||||||
echo_failed
|
echo_failed
|
||||||
|
error "$(cat $log_file)"
|
||||||
fi
|
fi
|
||||||
else
|
|
||||||
echo_skipped
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_file="/etc/postfix/postfwd.bl-nets"
|
# - Check configuration: postfwd reports missing list files, undefined
|
||||||
echononl " Create whitelist file '$_file' for postfwd"
|
# - macros or invalid lines only as warnings and keeps running.
|
||||||
if [[ ! -f "$_file" ]]; then
|
echononl " Check postfwd configuration"
|
||||||
cat << EOF > "$_file"
|
_postfwd_check="$(postfwd --showconfig --file "$_file" 2>&1 \
|
||||||
# ---
|
| grep -E '^\[LOG (warning|err|crit)')"
|
||||||
# Networks blocked by postfwd
|
if [[ -z "$_postfwd_check" ]] ; then
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# # web0.warenform.de
|
|
||||||
# #83.223.86.76
|
|
||||||
# #2a01:30:0:505:286:96ff:fe4a:6ee
|
|
||||||
# #2a01:30:0:13:286:96ff:fe4a:6eee
|
|
||||||
#
|
|
||||||
# ---
|
|
||||||
|
|
||||||
# give networks to block here
|
|
||||||
|
|
||||||
EOF
|
|
||||||
if [[ $? -eq 0 ]] ; then
|
|
||||||
echo_ok
|
echo_ok
|
||||||
else
|
else
|
||||||
echo_failed
|
echo_warning
|
||||||
fi
|
warn "postfwd reports problems with '${_file}':\n\n${_postfwd_check}"
|
||||||
else
|
|
||||||
echo_skipped
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_file="/etc/postfix/postfwd.bl-hosts"
|
|
||||||
echononl " Create whitelist file '$_file' for postfwd"
|
|
||||||
if [[ ! -f "$_file" ]]; then
|
|
||||||
cat << EOF > "$_file"
|
|
||||||
# ---
|
|
||||||
# hosts blocked by postfwd
|
|
||||||
#
|
|
||||||
# This file is called with '=~'. This means perl regexp is possible
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# # block all hosts of domain 'oopen.de'
|
|
||||||
# \.oopen\.de$
|
|
||||||
#
|
|
||||||
# # block host a.mx.oopen.de
|
|
||||||
# a.mx.oopen.de
|
|
||||||
#
|
|
||||||
# ---
|
|
||||||
|
|
||||||
# give hostnames to blocke here
|
|
||||||
|
|
||||||
EOF
|
|
||||||
if [[ $? -eq 0 ]] ; then
|
|
||||||
echo_ok
|
|
||||||
else
|
|
||||||
echo_failed
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo_skipped
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_file="/etc/postfix/postfwd.bl-user"
|
|
||||||
echononl " Create whitelist file '$_file' for postfwd"
|
|
||||||
if [[ ! -f "$_file" ]]; then
|
|
||||||
cat << EOF > "$_file"
|
|
||||||
# ---
|
|
||||||
# SASL Users blocked by postfwd
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# # give sasl_user to block here
|
|
||||||
# ckubu@warenform.de
|
|
||||||
# ---
|
|
||||||
|
|
||||||
# give sasl_user to block here
|
|
||||||
|
|
||||||
EOF
|
|
||||||
if [[ $? -eq 0 ]] ; then
|
|
||||||
echo_ok
|
|
||||||
else
|
|
||||||
echo_failed
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo_skipped
|
|
||||||
fi
|
|
||||||
|
|
||||||
_file="/etc/postfix/postfwd.bl-sender"
|
|
||||||
echononl " Create whitelist file '$_file' for postfwd"
|
|
||||||
if [[ ! -f "$_file" ]]; then
|
|
||||||
cat << EOF > "$_file"
|
|
||||||
# ---
|
|
||||||
# Sender addresses blocked by postfwd
|
|
||||||
#
|
|
||||||
# This file is called with '=~'. This means perl regexp is possible
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# # all senders of maildomaindomain 'oopen.de'
|
|
||||||
# @oopen\.de$
|
|
||||||
#
|
|
||||||
# # sender address ckubu@oopen.de
|
|
||||||
# ckubu@oopen.de
|
|
||||||
#
|
|
||||||
# ---
|
|
||||||
|
|
||||||
# annoying spammer domains
|
|
||||||
@acieu.co.uk
|
|
||||||
|
|
||||||
# annoying spammer addresses
|
|
||||||
error@mailfrom.com
|
|
||||||
|
|
||||||
EOF
|
|
||||||
if [[ $? -eq 0 ]] ; then
|
|
||||||
echo_ok
|
|
||||||
else
|
|
||||||
echo_failed
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo_skipped
|
|
||||||
fi
|
|
||||||
|
|
||||||
echononl " Create configuration file '/etc/postfix/postfwd.cf'.."
|
|
||||||
#if [[ ! -f "/etc/postfix/postfwd.cf" ]]; then
|
|
||||||
cat << EOF > /etc/postfix/postfwd.cf
|
|
||||||
|
|
||||||
#======= Definitions ============
|
|
||||||
|
|
||||||
# Match messages with an associated SASL username
|
|
||||||
&&SASL_AUTH {
|
|
||||||
sasl_username!~^\$
|
|
||||||
}
|
|
||||||
|
|
||||||
# Trusted networks
|
|
||||||
&&TRUSTED_NETS {
|
|
||||||
client_address==file:/etc/postfix/postfwd.wl-nets
|
|
||||||
}
|
|
||||||
|
|
||||||
# Trusted hostnames
|
|
||||||
# client_name~=.warenform.de$
|
|
||||||
&&TRUSTED_HOSTS {
|
|
||||||
client_name=~file:/etc/postfix/postfwd.wl-hosts
|
|
||||||
}
|
|
||||||
|
|
||||||
# Trusted users
|
|
||||||
&&TRUSTED_USERS {
|
|
||||||
sasl_username==file:/etc/postfix/postfwd.wl-user
|
|
||||||
}
|
|
||||||
|
|
||||||
# Trusted senders
|
|
||||||
&&TRUSTED_SENDERS {
|
|
||||||
sender=~file:/etc/postfix/postfwd.wl-sender
|
|
||||||
}
|
|
||||||
|
|
||||||
# Blacklist networks
|
|
||||||
&&BLOCK_NETS {
|
|
||||||
client_address==file:/etc/postfix/postfwd.bl-nets
|
|
||||||
}
|
|
||||||
|
|
||||||
# Blacklist hostnames
|
|
||||||
&&BLOCK_HOSTS {
|
|
||||||
client_name=~file:/etc/postfix/postfwd.bl-hosts
|
|
||||||
}
|
|
||||||
|
|
||||||
# Blacklist users
|
|
||||||
&&BLOCK_USERS {
|
|
||||||
sasl_username==file:/etc/postfix/postfwd.bl-user
|
|
||||||
}
|
|
||||||
|
|
||||||
# Blacklist sender adresses
|
|
||||||
&&BLOCK_SENDER {
|
|
||||||
# =~
|
|
||||||
# using '=~' allows also matching entries for domains (i.e. @acieu.co.uk)
|
|
||||||
sender=~file:/etc/postfix/postfwd.bl-sender
|
|
||||||
}
|
|
||||||
|
|
||||||
# Inbound emails only
|
|
||||||
&&INCOMING {
|
|
||||||
client_address!=127.0.0.1
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#======= Rule Sets ============
|
|
||||||
|
|
||||||
# ---
|
|
||||||
#
|
|
||||||
# Processing of the Rule Sets
|
|
||||||
#
|
|
||||||
# The parser checks the elements of a policy delegation request against the postfwd set
|
|
||||||
# of rules and, if necessary, triggers the configured action (action=). Similar to a
|
|
||||||
# classic firewall, a rule is considered true if every element of the set of rules (or
|
|
||||||
# one from every element list) applies to the comparison. I.e. the following rule:
|
|
||||||
#
|
|
||||||
# client_address=1.1.1.1, 1.1.1.2; client_name==unknown; action=REJECT
|
|
||||||
#
|
|
||||||
# triggers a REJECT if the
|
|
||||||
#
|
|
||||||
# Client address is equal (1.1.1.1 OR 1.1.1.2) AND the client name 'unknown'
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# Note:
|
|
||||||
# If an element occurs more than once, an element list is formed:
|
|
||||||
#
|
|
||||||
# The following rule set is equivalent to the above:
|
|
||||||
#
|
|
||||||
# client_address=1.1.1.1; client_address=1.1.1.2; client_name==unknown; action=REJECT
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# triggers a REJECT if (as above) the
|
|
||||||
#
|
|
||||||
# Client address (1.1.1.1 OR 1.1.1.2) AND the client name 'unknown'
|
|
||||||
#
|
|
||||||
# ---
|
|
||||||
|
|
||||||
# Whitelists
|
|
||||||
|
|
||||||
# Whitelist trusted networks
|
|
||||||
id=WHL_NETS
|
|
||||||
&&TRUSTED_NETS
|
|
||||||
action=DUNNO
|
|
||||||
|
|
||||||
# Whitelist trusted hostnames
|
|
||||||
id=WHL_HOSTS
|
|
||||||
&&TRUSTED_HOSTS
|
|
||||||
action=DUNNO
|
|
||||||
|
|
||||||
# Whitelist sasl users
|
|
||||||
id=WHL_USERS
|
|
||||||
&&TRUSTED_USERS
|
|
||||||
action=DUNNO
|
|
||||||
|
|
||||||
# Whitelist senders
|
|
||||||
id=WHL_SENDERS
|
|
||||||
&&INCOMING
|
|
||||||
&&TRUSTED_SENDERS
|
|
||||||
action=DUNNO
|
|
||||||
|
|
||||||
|
|
||||||
# Blacklists
|
|
||||||
|
|
||||||
# Block networks
|
|
||||||
id=BL_NETS
|
|
||||||
&&BLOCK_NETS
|
|
||||||
action=REJECT Network Address \$\$client_address blocked by Mailserver admins. Error: BL_NETS
|
|
||||||
|
|
||||||
# Block hostname
|
|
||||||
id=BL_HOSTS
|
|
||||||
&&BLOCK_HOSTS
|
|
||||||
action=REJECT \$\$client_name blocked by Mailserver admins. Error: BL_HOSTS
|
|
||||||
|
|
||||||
# Block users
|
|
||||||
id=BL_USERS
|
|
||||||
&&BLOCK_USERS
|
|
||||||
action=REJECT User is blocked by Mailserver admins. Error: BL_USERS
|
|
||||||
|
|
||||||
# Blacklist sender
|
|
||||||
#
|
|
||||||
# Claim successful delivery and silently discard the message.
|
|
||||||
#
|
|
||||||
id=BL_SENDER
|
|
||||||
&&BLOCK_SENDER
|
|
||||||
#action=DISCARD
|
|
||||||
action=REJECT Sender address is blocked by Mailserver admins. Error: BL_SENDER
|
|
||||||
|
|
||||||
|
|
||||||
# Rate Limits
|
|
||||||
|
|
||||||
# Throttle unknown clients to 5 recipients per 5 minutes:
|
|
||||||
id=RATE_UNKNOWN_CLIENT_ADDR
|
|
||||||
sasl_username =~ /^$/
|
|
||||||
client_name==unknown
|
|
||||||
action=rate(client_address/5/300/450 4.7.1 only 5 recipients per 5 minutes allowed)
|
|
||||||
|
|
||||||
# Block clients (ip-addresses) sending more than 50 messages per minute exceeded. Error:RATE_CLIENT)
|
|
||||||
id=RATE_CLIENT_ADDR
|
|
||||||
&&INCOMING
|
|
||||||
action=rate(\$\$client_address/50/60/421 421 4.7.0 Too many connections from \$\$client_address)
|
|
||||||
|
|
||||||
# Block messages with more than 50 recipients
|
|
||||||
id=BLOCK_MSG_RCPT
|
|
||||||
&&INCOMING
|
|
||||||
&&SASL_AUTH
|
|
||||||
recipient_count=50
|
|
||||||
action=REJECT Too many recipients, please reduce to less than 50 or consider using a mailing list. Error: BLOCK_MSG_RCPT
|
|
||||||
|
|
||||||
# Block users sending more than 50 messages/hour
|
|
||||||
id=RATE_MSG
|
|
||||||
&&INCOMING
|
|
||||||
&&SASL_AUTH
|
|
||||||
action=rate(\$\$sasl_username/50/3600/450 4.7.1 Number messages per hour exceeded. Error:RATE_MSG)
|
|
||||||
|
|
||||||
# Block users sending more than 250 recipients total/hour
|
|
||||||
id=RATE_RCPT
|
|
||||||
&&INCOMING
|
|
||||||
&&SASL_AUTH
|
|
||||||
action=rcpt(\$\$sasl_username/250/3600/450 4.7.1 Number recipients per hour exceeded. Error:RATE_RCPT)
|
|
||||||
|
|
||||||
EOF
|
|
||||||
if [[ $? -eq 0 ]] ; then
|
|
||||||
echo_ok
|
|
||||||
else
|
|
||||||
echo_failed
|
|
||||||
fi
|
|
||||||
#else
|
|
||||||
# echo_skipped
|
|
||||||
#fi
|
|
||||||
|
|
||||||
echononl " Restart Postfix firewall daemon 'postfwd'.."
|
echononl " Restart Postfix firewall daemon 'postfwd'.."
|
||||||
if $systemd_exists ; then
|
if $systemd_exists ; then
|
||||||
|
|||||||
Executable
+172
@@ -0,0 +1,172 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Update /etc/default/postfwd (idempotent) and reload postfwd.
|
||||||
|
#
|
||||||
|
# For every variable below:
|
||||||
|
# - already set to the wanted value -> nothing to do
|
||||||
|
# - set to a different value -> comment out the current setting
|
||||||
|
# and add the new one directly below
|
||||||
|
# - not set at all -> append the new setting
|
||||||
|
#
|
||||||
|
# Quotes around values are ignored when comparing (PORT="10040" == PORT=10040).
|
||||||
|
#
|
||||||
|
# At the end:
|
||||||
|
# - file changed -> 'systemctl restart postfwd'
|
||||||
|
# (ARGS, INET and PORT are start parameters of the
|
||||||
|
# daemon - a reload does NOT apply them)
|
||||||
|
# - file unchanged -> 'systemctl reload postfwd'
|
||||||
|
# (rereads postfwd.cf and the file: lists)
|
||||||
|
#
|
||||||
|
|
||||||
|
postfwd_default_file="/etc/default/postfwd"
|
||||||
|
|
||||||
|
# - Wanted settings: "VAR|VALUE" (VALUE written exactly as it should appear)
|
||||||
|
wanted_settings=(
|
||||||
|
'STARTUP|1'
|
||||||
|
'CONF|/etc/postfix/postfwd.cf'
|
||||||
|
'INET|127.0.0.1'
|
||||||
|
'PORT|10040'
|
||||||
|
'ARGS|"--summary=600 --cache=0"'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# -------------
|
||||||
|
# --- Some functions
|
||||||
|
# -------------
|
||||||
|
|
||||||
|
log_file="$(mktemp)"
|
||||||
|
|
||||||
|
clean_up() {
|
||||||
|
rm -f "$log_file"
|
||||||
|
exit $1
|
||||||
|
}
|
||||||
|
|
||||||
|
echononl() {
|
||||||
|
echo -e -n "$*"
|
||||||
|
}
|
||||||
|
echo_ok() {
|
||||||
|
echo -e "\033[60G[ \033[32mok\033[m ]"
|
||||||
|
}
|
||||||
|
echo_skipped() {
|
||||||
|
echo -e "\033[60G[ \033[33m\033[1mskipped\033[m ]"
|
||||||
|
}
|
||||||
|
echo_failed() {
|
||||||
|
echo -e "\033[60G[ \033[1;31mfailed\033[m ]"
|
||||||
|
}
|
||||||
|
error() {
|
||||||
|
echo ""
|
||||||
|
echo -e "\t[ \033[31m\033[1mError\033[m ]: $*"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
fatal() {
|
||||||
|
error "$*"
|
||||||
|
echo -e "\t\033[31m\033[1mScript will be interrupted\033[m"
|
||||||
|
echo ""
|
||||||
|
clean_up 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# - set_postfwd_default <VAR> <VALUE>
|
||||||
|
# -
|
||||||
|
# - returns 0 if the file was changed, 1 if nothing changed, 2 on error
|
||||||
|
# -
|
||||||
|
set_postfwd_default() {
|
||||||
|
local _var="$1"
|
||||||
|
local _val="$2"
|
||||||
|
local _tmp_file
|
||||||
|
local _rval
|
||||||
|
|
||||||
|
echononl " ${_var}=${_val}"
|
||||||
|
|
||||||
|
_tmp_file="$(mktemp)"
|
||||||
|
awk -v var="$_var" -v val="$_val" '
|
||||||
|
function unq(s) {
|
||||||
|
gsub(/^[ \t]+|[ \t]+$/, "", s)
|
||||||
|
if (s ~ /^".*"$/ || s ~ /^\047.*\047$/) s = substr(s, 2, length(s) - 2)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
$0 ~ "^[ \t]*" var "=" {
|
||||||
|
cur = $0 ; sub("^[ \t]*" var "=", "", cur)
|
||||||
|
if (! done && unq(cur) == unq(val)) { print ; done = 1 ; next }
|
||||||
|
print "#" $0
|
||||||
|
if (! done) { print var "=" val ; done = 1 }
|
||||||
|
next
|
||||||
|
}
|
||||||
|
{ print }
|
||||||
|
END { if (! done) print var "=" val }
|
||||||
|
' "$postfwd_default_file" > "$_tmp_file" 2> "$log_file"
|
||||||
|
|
||||||
|
if [[ $? -ne 0 ]] ; then
|
||||||
|
echo_failed
|
||||||
|
error "$(cat "$log_file")"
|
||||||
|
_rval=2
|
||||||
|
elif cmp -s "$_tmp_file" "$postfwd_default_file" ; then
|
||||||
|
echo_skipped
|
||||||
|
_rval=1
|
||||||
|
else
|
||||||
|
# - cat instead of mv/cp keeps owner and permissions of the original file
|
||||||
|
if cat "$_tmp_file" > "$postfwd_default_file" 2> "$log_file" ; then
|
||||||
|
echo_ok
|
||||||
|
_rval=0
|
||||||
|
else
|
||||||
|
echo_failed
|
||||||
|
error "$(cat "$log_file")"
|
||||||
|
_rval=2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f "$_tmp_file"
|
||||||
|
return $_rval
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# -------------
|
||||||
|
# --- Main
|
||||||
|
# -------------
|
||||||
|
|
||||||
|
[[ "$(id -u)" -eq 0 ]] || fatal "This script must be run as root."
|
||||||
|
|
||||||
|
command -v postfwd > /dev/null 2>&1 || fatal "postfwd is not installed."
|
||||||
|
|
||||||
|
if [[ ! -f "$postfwd_default_file" ]] ; then
|
||||||
|
touch "$postfwd_default_file" 2> "$log_file" || fatal "$(cat "$log_file")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Update ${postfwd_default_file}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
file_changed=false
|
||||||
|
errors=false
|
||||||
|
|
||||||
|
for _setting in "${wanted_settings[@]}" ; do
|
||||||
|
set_postfwd_default "${_setting%%|*}" "${_setting#*|}"
|
||||||
|
case $? in
|
||||||
|
0) file_changed=true ;;
|
||||||
|
2) errors=true ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if $errors ; then
|
||||||
|
fatal "Errors while updating '${postfwd_default_file}' - postfwd NOT reloaded."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if $file_changed ; then
|
||||||
|
echononl " Restart postfwd (start parameters changed)"
|
||||||
|
_action="restart"
|
||||||
|
else
|
||||||
|
echononl " Reload postfwd"
|
||||||
|
_action="reload"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if systemctl $_action postfwd > "$log_file" 2>&1 ; then
|
||||||
|
echo_ok
|
||||||
|
else
|
||||||
|
echo_failed
|
||||||
|
error "$(cat "$log_file")"
|
||||||
|
clean_up 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
clean_up 0
|
||||||
Reference in New Issue
Block a user