--- /dev/null
+roster
+var/
--- /dev/null
+pillar encryption:
+echo 'example' | gpg --armor --batch --encrypt --recipient "yourid"
--- /dev/null
+# Released under MIT License
+
+Copyright (c) 2025 Andreas Glashauser.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--- /dev/null
+This repository contains my personal SaltStack infrastructure states.
+
+The provided configuration states can be executed on a Salt master without requiring root or sudo privileges. However, the limitation of this root-less approach is that every command must be executed from the project root directory.
+
+You must adapt the Saltfile, master and pillar data to your specific environment and requirements. The default pillar data provided in this repository is GPG-encrypted, so if you do not modify the pillars accordingly, applying states will not work.
+
+
+Important Notice:
+It is critical that you review and fully understand the contents of this repository before deploying any states. Blindly copying configurations without proper understanding could, and will, lead to unintended consequences.
+
+If you encounter any issues, have questions, or require further clarification, please feel free to contact me.
--- /dev/null
+salt-ssh:
+ config_dir: "/home/user/salt-infra/"
+ roster_file: "/home/user/salt-infra/roster"
+ ssh_wipe: True
--- /dev/null
+root_dir: "/home/user/salt-infra"
+file_roots:
+ base:
+ - /home/user/salt-infra/salt/states
+pillar_roots:
+ base:
+ - /home/user/salt-infra/salt/pillar
+renderer: jinja | yaml | gpg # if this is not set, salt gpg integration doesnt work
+
+gpg_keydir: /home/user/.gnupg
--- /dev/null
+{% set fqdn = grains['fqdn'] %}
+common:
+ fqdn: {{ fqdn }}
+ domain: {{ fqdn.split('.', 1)[-1] }}
--- /dev/null
+#!yaml|gpg
+mail:
+ default_to: |
+ -----BEGIN PGP MESSAGE-----
+
+ hF4D+CZXdqKq9X4SAQdAOxNOj/iO+KQebGHlKk5RgGzRbamm9fk/NyFK6c3M7gcw
+ nvcom0++LwQY9kQS2178GQSi29aR+NDDPJZtwHHxvBvzKZSSjK1NBCLwe6rl+hOT
+ 0lEBgsJYNxCXChGuo96+VDVAk+gv6gAHmil97Jkc/xMlEVXqNP1ws9pRCpQYvItv
+ /BBNnwbmgeqTLB9HhwTFq2wfSmGdrZF6tjZYWvzRXoECA68=
+ =Yxo9
+ -----END PGP MESSAGE-----
--- /dev/null
+mailtype: mailforwarding
--- /dev/null
+mailtype: mailserver
--- /dev/null
+#!yaml|gpg
+services:
+ ssh:
+ port: |
+ -----BEGIN PGP MESSAGE-----
+
+ hF4D+CZXdqKq9X4SAQdACvvcX5wI4Vh9morKBgxjkiIDMx6UyIXBOf/1rRb6+B8w
+ wnP1qC+T1JXTBIL26uXDwBWCQSpNgz4iqYMMGWzoGm15jASWQ+Do3pq6m6cI4M1I
+ 0j4BcVGjmVtZxTd46NWF2/LEjETe5R+qvRyOxDbu66HVnT7alV1YQF9QmLYRbl9E
+ BD1hIsaWN8w4OacqlGWE3g==
+ =bBHx
+ -----END PGP MESSAGE-----
+ knockd:
+ open_sequence: |
+ -----BEGIN PGP MESSAGE-----
+
+ hF4D+CZXdqKq9X4SAQdAW0tjBV8LZiF8MivHFtG5TKjqErwxWwG0RpMlpUJMTwgw
+ p9sZJ2hm+0NnNSDiaI1ytoPLYKRWpVkRupbPXJGAT0BMdqTR1o2wkMczMRm8Bi9W
+ 0kcBQ9pUqEdnRK5iquRkIC4F7o1zztWJX9OjEYgKYIdA8lqhum0xafDQA3fQ3GEi
+ MGdQC+RcgZ4cxoRe9saXD2qabrXiqRUCWw==
+ =An0U
+ -----END PGP MESSAGE-----
+ close_sequence: |
+ -----BEGIN PGP MESSAGE-----
+
+ hF4D+CZXdqKq9X4SAQdAsN0yU705iy9d/ntKPXTSma49Due2Ea3l1ahuoamv+FYw
+ xoHmiSJ5vs/zYlDoDVEJMwLk1n/9DPDCUJjqDjGlS4MWUVvj+njIl2gELKspdcjp
+ 0kcBd1kwF+r1tZkofQJbln/ZFP7Hra4HOmPVF2Qcqmfh/Xq1/WEzlZx2qy4Djvgx
+ sn1RH3ZsFJjJi28CZKMVqsznNEESbYYyjg==
+ =EIvh
+ -----END PGP MESSAGE-----
--- /dev/null
+base:
+ '*':
+ - common
+ - users
+ - services
+ - mail
+
+ 'mailforwarding':
+ - mailforwarding
+
+ 'mailserver':
+ - mailserver
--- /dev/null
+#!yaml|gpg
+users:
+ main:
+ account: |
+ -----BEGIN PGP MESSAGE-----
+
+ hF4D+CZXdqKq9X4SAQdAWSpFNLDT1jSKdWY9vmCsmHuQR1OOBI1G48nXPXOz2wQw
+ 1LQop5a3AAUlciH0rjnP2w6cfGqtsT3r7doL9iJEo3x6PPK2eL8RLLRX1sCKh9jp
+ 0j4BIfy0IxM8AW+LDsT8VmkaMQypkKZ7ZwIqJQhK3FO+YfjpaH5Vwz7zk6fYTMDC
+ RD+KK8THLjvrS4RA8M/m5A==
+ =UAZt
+ -----END PGP MESSAGE-----
+ password: |
+ -----BEGIN PGP MESSAGE-----
+
+ hF4D+CZXdqKq9X4SAQdAc27v75gDTMaN07qxt7yS3VvKo/5ww9GMuOCJkY7HJC8w
+ 1BMuhsylJYUaIsFDEBUxqcpYJW482IP099D5QBoRTUHir6AQGqWfvG4jokdwXHv/
+ 0lUB5NTqhrop46aSwDkqTjsipK8cB/eZ9DzdQIVND7XlCz9qCBgPeDctG/yr+D7z
+ caRa2xP9hxW6NFAw6OJ8sJM7JgZ2SqHN0jjJDCHsyeCmdq/UzEl1
+ =Vzlw
+ -----END PGP MESSAGE-----
+ mutt:
+ real_name: |
+ -----BEGIN PGP MESSAGE-----
+
+ hF4D+CZXdqKq9X4SAQdAqjWFqw4T3xDTLg4XB7VMG5KTfEo/uOMSNMNCEmrq0VUw
+ q/VNgFWpoRuqLeoL/boH3IVYrpJbN30GJBraxxlOEyE8z4HZ3FdOLPNx0UmsxX6Y
+ 0k4BflYUJFNG9hEtKAmVmyiYXjTpk9UPrJ3eGCMH60AFczxXjm2XWUqHw+zVvWrk
+ QG8Dk9GnUI4vQAyZlckzub7JsCt4xv/bcrgiWXkbySU=
+ =6zGQ
+ -----END PGP MESSAGE-----
+ from: |
+ -----BEGIN PGP MESSAGE-----
+
+ hF4D+CZXdqKq9X4SAQdA3UGDWQSR28X8PY4DQtUrEkiX2SQS+cS273l2i50570sw
+ spGepcpa1EoGpMLWyi+X9LaM7m6+Bw/WoV0o2SUH20Ph6JdydpnVP78s/HU37JqV
+ 0lQBjNu2BBzZ+hUxa0ZpSCpiLsOsTxaeP12zp4ZEu2MQt1+6tKHBCj2ARiJUYgKF
+ AKLWGm5rAVcJ4X8vtd8O0Cm8yv3iSouj24o9pe4p6alJ7Ojq/uY=
+ =/oY/
+ -----END PGP MESSAGE-----
--- /dev/null
+bind9--config-resolvedconf:
+ file.managed:
+ - user: root
+ - group: root
+ - mode: 644
+ - names:
+ - /etc/systemd/resolved.conf:
+ - source: salt://bind9/files/resolved.conf
+ - /etc/bind/named.conf.options:
+ - source: salt://bind9/files/named.conf.options
+ - require:
+ - bind9--install-packages
--- /dev/null
+bind9--remove-packages:
+ pkg.removed:
+ - pkgs:
+ - resolvconf
+
+bind9--install-packages:
+ pkg.installed:
+ - pkgs:
+ - bind9
+ - bind9-utils
+ - bind9-host
+ - dnsutils
+ - systemd-resolved
+ - require:
+ - pkg: bind9--remove-packages
--- /dev/null
+bind9--systemd-service:
+ service.running:
+ - name: bind9
+ - enable: True
+ - reload: True
+ - watch:
+ - /etc/bind/named.conf.options
+ - require:
+ - pkg: bind9--install-packages
--- /dev/null
+options {
+ directory "/var/cache/bind";
+
+ // If there is a firewall between you and nameservers you want
+ // to talk to, you may need to fix the firewall to allow multiple
+ // ports to talk. See http://www.kb.cert.org/vuls/id/800113
+
+ // If your ISP provided one or more IP addresses for stable
+ // nameservers, you probably want to use them as forwarders.
+ // Uncomment the following block, and insert the addresses replacing
+ // the all-0's placeholder.
+
+ recursion yes;
+
+ allow-query { localhost; };
+ allow-query-cache { localhost; };
+ allow-recursion { localhost; };
+
+ //========================================================================
+ // If BIND logs error messages about the root key being expired,
+ // you will need to update your keys. See https://www.isc.org/bind-keys
+ //========================================================================
+ dnssec-validation auto;
+
+ listen-on-v6 { any; };
+
+ version none;
+};
--- /dev/null
+[Resolve]
+DNS=127.0.0.1
+Domains=~.
--- /dev/null
+include:
+ - bind9.bind9--install-packages
+ - bind9.bind9--configure
+ - bind9.bind9--systemd-service
--- /dev/null
+certbot--install-packages:
+ pkg.installed:
+ - refresh: true
+ - pkgs:
+ - certbot
--- /dev/null
+include:
+ - common.ufw
+
+certbot--ensure-ufw-open-port-80:
+ cmd.run:
+ - name: ufw allow 80/tcp
+ - require:
+ - pkg: ufw--install-packages
+
+certbot--issue-certbot-certificate-apache:
+ cmd.run:
+ - name: certbot --apache -d {{ pillar['common']['fqdn'] }} --non-interactive --agree-tos --email certbot@{{ pillar['common']['domain'] }}
+ - unless: test -f /etc/letsencrypt/live/{{ pillar['common']['domain'] }}/fullchain.pem
+ - require:
+ - cmd: certbot--ensure-ufw-open-port-80
+ - pkg: certbot--install-packages
+ - onlyif: test -f /usr/sbin/apache2
+
+certbot--issue-certbot-certificate:
+ cmd.run:
+ - name: certbot certonly --standalone -d {{ pillar['common']['fqdn'] }} --non-interactive --agree-tos --email certbot@{{ pillar['common']['domain'] }}
+ - unless: test -f /etc/letsencrypt/live/{{ pillar['common']['domain'] }}/fullchain.pem
+ - require:
+ - cmd: certbot--ensure-ufw-open-port-80
+ - pkg: certbot--install-packages
+ - unless: test -f /usr/sbin/apache2
--- /dev/null
+include:
+ - certbot.certbot--install-packages
+ - certbot.certbot--issue-certificate
--- /dev/null
+apparmor--install-packages:
+ pkg.installed:
+ - pkgs:
+ - apparmor
+ - apparmor-utils
+ - apparmor-profiles
--- /dev/null
+apparmor--systemd-service:
+ service.running:
+ - name: apparmor
+ - enable: True
+ - require:
+ - pkg: apparmor--install-packages
--- /dev/null
+include:
+ - common.apparmor.apparmor--install-packages
+ - common.apparmor.apparmor--systemd-service
--- /dev/null
+/etc/security/limits.conf:
+ file.append:
+ - text:
+ - '* hard core 0'
+ - '* soft core 0'
+
+/etc/sysctl.d/9999-disable-core-dump.conf:
+ file.managed:
+ - contents: |
+ fs.suid_dumpable=0
+ kernel.core_pattern=|/bin/false
+ - user: root
+ - group: root
+ - mode: 644
+
+apply_sysctl_changes:
+ cmd.run:
+ - name: sysctl -p /etc/sysctl.d/9999-disable-core-dump.conf
+ - unless: sysctl -n fs.suid_dumpable | grep -q 0
--- /dev/null
+cron--configure:
+ file.managed:
+ - name: /etc/crontab
+ - source: salt://common/crontab/files/crontab
+ - template: jinja
--- /dev/null
+MAILTO=crontab@{{ pillar['mail']['default_to'] }}
+# /etc/crontab: system-wide crontab
+# Unlike any other crontab you don't have to run the `crontab'
+# command to install the new version when you edit this file
+# and files in /etc/cron.d. These files also have username fields,
+# that none of the other crontabs do.
+
+SHELL=/bin/sh
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+
+# Example of job definition:
+# .---------------- minute (0 - 59)
+# | .------------- hour (0 - 23)
+# | | .---------- day of month (1 - 31)
+# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
+# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
+# | | | | |
+# * * * * * user-name command to be executed
+17 * * * * root cd / && run-parts --report /etc/cron.hourly
+25 6 * * * root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.daily; }
+47 6 * * 7 root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.weekly; }
+52 6 1 * * root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.monthly; }
+#
--- /dev/null
+include:
+ - common.crontab.crontab--configure
--- /dev/null
+debsums--configure:
+ file.managed:
+ - name: /etc/default/debsums
+ - source: salt://common/debsums/files/debsums
+ - user: root
+ - group: root
+ - mode: 644
+ - require:
+ - pkg: debsums--install-packages
--- /dev/null
+debsums--install-packages:
+ pkg.installed:
+ - pkgs:
+ - debsums
--- /dev/null
+CRON_CHECK=daily
--- /dev/null
+include:
+ - common.debsums.debsums--install-packages
+ - common.debsums.debsums--configure
--- /dev/null
+fail2ban--configure:
+ file.managed:
+ - name: /etc/fail2ban/jail.local
+ - source: salt://common/fail2ban/files/jail.local
+ - user: root
+ - group: root
+ - mode: 644
+ - require:
+ - pkg: fail2ban--install-packages
--- /dev/null
+fail2ban--install-packages:
+ pkg.installed:
+ - pkgs:
+ - fail2ban
--- /dev/null
+fail2ban--fail2ban-systemd-service:
+ service.running:
+ - name: fail2ban
+ - enable: True
+ - reload: True
+ - require:
+ - fail2ban--install-packages
--- /dev/null
+#
+# WARNING: heavily refactored in 0.9.0 release. Please review and
+# customize settings for your setup.
+#
+# Changes: in most of the cases you should not modify this
+# file, but provide customizations in jail.local file,
+# or separate .conf files under jail.d/ directory, e.g.:
+#
+# HOW TO ACTIVATE JAILS:
+#
+# YOU SHOULD NOT MODIFY THIS FILE.
+#
+# It will probably be overwritten or improved in a distribution update.
+#
+# Provide customizations in a jail.local file or a jail.d/customisation.local.
+# For example to change the default bantime for all jails and to enable the
+# ssh-iptables jail the following (uncommented) would appear in the .local file.
+# See man 5 jail.conf for details.
+#
+# [DEFAULT]
+# bantime = 1h
+#
+# [sshd]
+# enabled = true
+#
+# See jail.conf(5) man page for more information
+
+
+
+# Comments: use '#' for comment lines and ';' (following a space) for inline comments
+
+
+[INCLUDES]
+
+#before = paths-distro.conf
+before = paths-debian.conf
+
+# The DEFAULT allows a global definition of the options. They can be overridden
+# in each jail afterwards.
+
+[DEFAULT]
+
+#
+# MISCELLANEOUS OPTIONS
+#
+
+# "bantime.increment" allows to use database for searching of previously banned ip's to increase a
+# default ban time using special formula, default it is banTime * 1, 2, 4, 8, 16, 32...
+#bantime.increment = true
+
+# "bantime.rndtime" is the max number of seconds using for mixing with random time
+# to prevent "clever" botnets calculate exact time IP can be unbanned again:
+#bantime.rndtime =
+
+# "bantime.maxtime" is the max number of seconds using the ban time can reach (doesn't grow further)
+#bantime.maxtime =
+
+# "bantime.factor" is a coefficient to calculate exponent growing of the formula or common multiplier,
+# default value of factor is 1 and with default value of formula, the ban time
+# grows by 1, 2, 4, 8, 16 ...
+#bantime.factor = 1
+
+# "bantime.formula" used by default to calculate next value of ban time, default value below,
+# the same ban time growing will be reached by multipliers 1, 2, 4, 8, 16, 32...
+#bantime.formula = ban.Time * (1<<(ban.Count if ban.Count<20 else 20)) * banFactor
+#
+# more aggressive example of formula has the same values only for factor "2.0 / 2.885385" :
+#bantime.formula = ban.Time * math.exp(float(ban.Count+1)*banFactor)/math.exp(1*banFactor)
+
+# "bantime.multipliers" used to calculate next value of ban time instead of formula, corresponding
+# previously ban count and given "bantime.factor" (for multipliers default is 1);
+# following example grows ban time by 1, 2, 4, 8, 16 ... and if last ban count greater as multipliers count,
+# always used last multiplier (64 in example), for factor '1' and original ban time 600 - 10.6 hours
+#bantime.multipliers = 1 2 4 8 16 32 64
+# following example can be used for small initial ban time (bantime=60) - it grows more aggressive at begin,
+# for bantime=60 the multipliers are minutes and equal: 1 min, 5 min, 30 min, 1 hour, 5 hour, 12 hour, 1 day, 2 day
+#bantime.multipliers = 1 5 30 60 300 720 1440 2880
+
+# "bantime.overalljails" (if true) specifies the search of IP in the database will be executed
+# cross over all jails, if false (default), only current jail of the ban IP will be searched
+#bantime.overalljails = false
+
+# --------------------
+
+# "ignoreself" specifies whether the local resp. own IP addresses should be ignored
+# (default is true). Fail2ban will not ban a host which matches such addresses.
+#ignoreself = true
+
+# "ignoreip" can be a list of IP addresses, CIDR masks or DNS hosts. Fail2ban
+# will not ban a host which matches an address in this list. Several addresses
+# can be defined using space (and/or comma) separator.
+#ignoreip = 127.0.0.1/8 ::1
+
+# External command that will take an tagged arguments to ignore, e.g. <ip>,
+# and return true if the IP is to be ignored. False otherwise.
+#
+# ignorecommand = /path/to/command <ip>
+ignorecommand =
+
+# "bantime" is the number of seconds that a host is banned.
+bantime = 10m
+
+# A host is banned if it has generated "maxretry" during the last "findtime"
+# seconds.
+findtime = 10m
+
+# "maxretry" is the number of failures before a host get banned.
+maxretry = 5
+
+# "maxmatches" is the number of matches stored in ticket (resolvable via tag <matches> in actions).
+maxmatches = %(maxretry)s
+
+# "backend" specifies the backend used to get files modification.
+# Available options are "pyinotify", "gamin", "polling", "systemd" and "auto".
+# This option can be overridden in each jail as well.
+#
+# pyinotify: requires pyinotify (a file alteration monitor) to be installed.
+# If pyinotify is not installed, Fail2ban will use auto.
+# gamin: requires Gamin (a file alteration monitor) to be installed.
+# If Gamin is not installed, Fail2ban will use auto.
+# polling: uses a polling algorithm which does not require external libraries.
+# systemd: uses systemd python library to access the systemd journal.
+# Specifying "logpath" is not valid for this backend.
+# See "journalmatch" in the jails associated filter config
+# auto: will try to use the following backends, in order:
+# pyinotify, gamin, polling.
+#
+# Note: if systemd backend is chosen as the default but you enable a jail
+# for which logs are present only in its own log files, specify some other
+# backend for that jail (e.g. polling) and provide empty value for
+# journalmatch. See https://github.com/fail2ban/fail2ban/issues/959#issuecomment-74901200
+backend = auto
+
+# "usedns" specifies if jails should trust hostnames in logs,
+# warn when DNS lookups are performed, or ignore all hostnames in logs
+#
+# yes: if a hostname is encountered, a DNS lookup will be performed.
+# warn: if a hostname is encountered, a DNS lookup will be performed,
+# but it will be logged as a warning.
+# no: if a hostname is encountered, will not be used for banning,
+# but it will be logged as info.
+# raw: use raw value (no hostname), allow use it for no-host filters/actions (example user)
+usedns = warn
+
+# "logencoding" specifies the encoding of the log files handled by the jail
+# This is used to decode the lines from the log file.
+# Typical examples: "ascii", "utf-8"
+#
+# auto: will use the system locale setting
+logencoding = auto
+
+# "enabled" enables the jails.
+# By default all jails are disabled, and it should stay this way.
+# Enable only relevant to your setup jails in your .local or jail.d/*.conf
+#
+# true: jail will be enabled and log files will get monitored for changes
+# false: jail is not enabled
+enabled = false
+
+
+# "mode" defines the mode of the filter (see corresponding filter implementation for more info).
+mode = normal
+
+# "filter" defines the filter to use by the jail.
+# By default jails have names matching their filter name
+#
+filter = %(__name__)s[mode=%(mode)s]
+
+
+#
+# ACTIONS
+#
+
+# Some options used for actions
+
+# Destination email address used solely for the interpolations in
+# jail.{conf,local,d/*} configuration files.
+destemail = root@localhost
+
+# Sender email address used solely for some actions
+sender = root@<fq-hostname>
+
+# E-mail action. Since 0.8.1 Fail2Ban uses sendmail MTA for the
+# mailing. Change mta configuration parameter to mail if you want to
+# revert to conventional 'mail'.
+mta = sendmail
+
+# Default protocol
+protocol = tcp
+
+# Specify chain where jumps would need to be added in ban-actions expecting parameter chain
+chain = <known/chain>
+
+# Ports to be banned
+# Usually should be overridden in a particular jail
+port = 0:65535
+
+# Format of user-agent https://tools.ietf.org/html/rfc7231#section-5.5.3
+fail2ban_agent = Fail2Ban/%(fail2ban_version)s
+
+#
+# Action shortcuts. To be used to define action parameter
+
+# Default banning action (e.g. iptables, iptables-new,
+# iptables-multiport, shorewall, etc) It is used to define
+# action_* variables. Can be overridden globally or per
+# section within jail.local file
+banaction = iptables-multiport
+banaction_allports = iptables-allports
+
+# The simplest action to take: ban only
+action_ = %(banaction)s[port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
+
+# ban & send an e-mail with whois report to the destemail.
+action_mw = %(action_)s
+ %(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]
+
+# ban & send an e-mail with whois report and relevant log lines
+# to the destemail.
+action_mwl = %(action_)s
+ %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
+
+# See the IMPORTANT note in action.d/xarf-login-attack for when to use this action
+#
+# ban & send a xarf e-mail to abuse contact of IP address and include relevant log lines
+# to the destemail.
+action_xarf = %(action_)s
+ xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]
+
+# ban & send a notification to one or more of the 50+ services supported by Apprise.
+# See https://github.com/caronc/apprise/wiki for details on what is supported.
+#
+# You may optionally over-ride the default configuration line (containing the Apprise URLs)
+# by using 'apprise[config="/alternate/path/to/apprise.cfg"]' otherwise
+# /etc/fail2ban/apprise.conf is sourced for your supported notification configuration.
+# action = %(action_)s
+# apprise
+
+# ban IP on CloudFlare & send an e-mail with whois report and relevant log lines
+# to the destemail.
+action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
+ %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
+
+# Report block via blocklist.de fail2ban reporting service API
+#
+# See the IMPORTANT note in action.d/blocklist_de.conf for when to use this action.
+# Specify expected parameters in file action.d/blocklist_de.local or if the interpolation
+# `action_blocklist_de` used for the action, set value of `blocklist_de_apikey`
+# in your `jail.local` globally (section [DEFAULT]) or per specific jail section (resp. in
+# corresponding jail.d/my-jail.local file).
+#
+action_blocklist_de = blocklist_de[email="%(sender)s", service="%(__name__)s", apikey="%(blocklist_de_apikey)s", agent="%(fail2ban_agent)s"]
+
+# Report ban via abuseipdb.com.
+#
+# See action.d/abuseipdb.conf for usage example and details.
+#
+action_abuseipdb = abuseipdb
+
+# Choose default action. To change, just override value of 'action' with the
+# interpolation to the chosen action shortcut (e.g. action_mw, action_mwl, etc) in jail.local
+# globally (section [DEFAULT]) or per specific section
+action = %(action_)s
+
+
+#
+# JAILS
+#
+
+#
+# SSH servers
+#
+
+[sshd]
+
+# To use more aggressive sshd modes set filter parameter "mode" in jail.local:
+# normal (default), ddos, extra or aggressive (combines all).
+# See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and details.
+#mode = normal
+port = ssh
+logpath = %(sshd_log)s
+backend = %(sshd_backend)s
+
+
+[dropbear]
+
+port = ssh
+logpath = %(dropbear_log)s
+backend = %(dropbear_backend)s
+
+
+[selinux-ssh]
+
+port = ssh
+logpath = %(auditd_log)s
+
+
+#
+# HTTP servers
+#
+
+[apache-auth]
+
+port = http,https
+logpath = %(apache_error_log)s
+
+
+[apache-badbots]
+# Ban hosts which agent identifies spammer robots crawling the web
+# for email addresses. The mail outputs are buffered.
+port = http,https
+logpath = %(apache_access_log)s
+bantime = 48h
+maxretry = 1
+
+
+[apache-noscript]
+
+port = http,https
+logpath = %(apache_error_log)s
+
+
+[apache-overflows]
+
+port = http,https
+logpath = %(apache_error_log)s
+maxretry = 2
+
+
+[apache-nohome]
+
+port = http,https
+logpath = %(apache_error_log)s
+maxretry = 2
+
+
+[apache-botsearch]
+
+port = http,https
+logpath = %(apache_error_log)s
+maxretry = 2
+
+
+[apache-fakegooglebot]
+
+port = http,https
+logpath = %(apache_access_log)s
+maxretry = 1
+ignorecommand = %(fail2ban_confpath)s/filter.d/ignorecommands/apache-fakegooglebot <ip>
+
+
+[apache-modsecurity]
+
+port = http,https
+logpath = %(apache_error_log)s
+maxretry = 2
+
+
+[apache-shellshock]
+
+port = http,https
+logpath = %(apache_error_log)s
+maxretry = 1
+
+
+[openhab-auth]
+
+filter = openhab
+banaction = %(banaction_allports)s
+logpath = /opt/openhab/logs/request.log
+
+
+# To use more aggressive http-auth modes set filter parameter "mode" in jail.local:
+# normal (default), aggressive (combines all), auth or fallback
+# See "tests/files/logs/nginx-http-auth" or "filter.d/nginx-http-auth.conf" for usage example and details.
+[nginx-http-auth]
+# mode = normal
+port = http,https
+logpath = %(nginx_error_log)s
+
+# To use 'nginx-limit-req' jail you should have `ngx_http_limit_req_module`
+# and define `limit_req` and `limit_req_zone` as described in nginx documentation
+# http://nginx.org/en/docs/http/ngx_http_limit_req_module.html
+# or for example see in 'config/filter.d/nginx-limit-req.conf'
+[nginx-limit-req]
+port = http,https
+logpath = %(nginx_error_log)s
+
+[nginx-botsearch]
+
+port = http,https
+logpath = %(nginx_error_log)s
+
+[nginx-bad-request]
+port = http,https
+logpath = %(nginx_access_log)s
+
+# Ban attackers that try to use PHP's URL-fopen() functionality
+# through GET/POST variables. - Experimental, with more than a year
+# of usage in production environments.
+
+[php-url-fopen]
+
+port = http,https
+logpath = %(nginx_access_log)s
+ %(apache_access_log)s
+
+
+[suhosin]
+
+port = http,https
+logpath = %(suhosin_log)s
+
+
+[lighttpd-auth]
+# Same as above for Apache's mod_auth
+# It catches wrong authentifications
+port = http,https
+logpath = %(lighttpd_error_log)s
+
+
+#
+# Webmail and groupware servers
+#
+
+[roundcube-auth]
+
+port = http,https
+logpath = %(roundcube_errors_log)s
+# Use following line in your jail.local if roundcube logs to journal.
+#backend = %(syslog_backend)s
+
+
+[openwebmail]
+
+port = http,https
+logpath = /var/log/openwebmail.log
+
+
+[horde]
+
+port = http,https
+logpath = /var/log/horde/horde.log
+
+
+[groupoffice]
+
+port = http,https
+logpath = /home/groupoffice/log/info.log
+
+
+[sogo-auth]
+# Monitor SOGo groupware server
+# without proxy this would be:
+# port = 20000
+port = http,https
+logpath = /var/log/sogo/sogo.log
+
+
+[tine20]
+
+logpath = /var/log/tine20/tine20.log
+port = http,https
+
+
+#
+# Web Applications
+#
+#
+
+[drupal-auth]
+
+port = http,https
+logpath = %(syslog_daemon)s
+backend = %(syslog_backend)s
+
+[guacamole]
+
+port = http,https
+logpath = /var/log/tomcat*/catalina.out
+#logpath = /var/log/guacamole.log
+
+[monit]
+#Ban clients brute-forcing the monit gui login
+port = 2812
+logpath = /var/log/monit
+ /var/log/monit.log
+
+
+[webmin-auth]
+
+port = 10000
+logpath = %(syslog_authpriv)s
+backend = %(syslog_backend)s
+
+
+[froxlor-auth]
+
+port = http,https
+logpath = %(syslog_authpriv)s
+backend = %(syslog_backend)s
+
+
+#
+# HTTP Proxy servers
+#
+#
+
+[squid]
+
+port = 80,443,3128,8080
+logpath = /var/log/squid/access.log
+
+
+[3proxy]
+
+port = 3128
+logpath = /var/log/3proxy.log
+
+
+#
+# FTP servers
+#
+
+
+[proftpd]
+
+port = ftp,ftp-data,ftps,ftps-data
+logpath = %(proftpd_log)s
+backend = %(proftpd_backend)s
+
+
+[pure-ftpd]
+
+port = ftp,ftp-data,ftps,ftps-data
+logpath = %(pureftpd_log)s
+backend = %(pureftpd_backend)s
+
+
+[gssftpd]
+
+port = ftp,ftp-data,ftps,ftps-data
+logpath = %(syslog_daemon)s
+backend = %(syslog_backend)s
+
+
+[wuftpd]
+
+port = ftp,ftp-data,ftps,ftps-data
+logpath = %(wuftpd_log)s
+backend = %(wuftpd_backend)s
+
+
+[vsftpd]
+# or overwrite it in jails.local to be
+# logpath = %(syslog_authpriv)s
+# if you want to rely on PAM failed login attempts
+# vsftpd's failregex should match both of those formats
+port = ftp,ftp-data,ftps,ftps-data
+logpath = %(vsftpd_log)s
+
+
+#
+# Mail servers
+#
+
+# ASSP SMTP Proxy Jail
+[assp]
+
+port = smtp,465,submission
+logpath = /root/path/to/assp/logs/maillog.txt
+
+
+[courier-smtp]
+
+port = smtp,465,submission
+logpath = %(syslog_mail)s
+backend = %(syslog_backend)s
+
+
+[postfix]
+# To use another modes set filter parameter "mode" in jail.local:
+mode = more
+port = smtp,465,submission
+logpath = %(postfix_log)s
+backend = %(postfix_backend)s
+
+
+[postfix-rbl]
+
+filter = postfix[mode=rbl]
+port = smtp,465,submission
+logpath = %(postfix_log)s
+backend = %(postfix_backend)s
+maxretry = 1
+
+
+[sendmail-auth]
+
+port = submission,465,smtp
+logpath = %(syslog_mail)s
+backend = %(syslog_backend)s
+
+
+[sendmail-reject]
+# To use more aggressive modes set filter parameter "mode" in jail.local:
+# normal (default), extra or aggressive
+# See "tests/files/logs/sendmail-reject" or "filter.d/sendmail-reject.conf" for usage example and details.
+#mode = normal
+port = smtp,465,submission
+logpath = %(syslog_mail)s
+backend = %(syslog_backend)s
+
+
+[qmail-rbl]
+
+filter = qmail
+port = smtp,465,submission
+logpath = /service/qmail/log/main/current
+
+
+# dovecot defaults to logging to the mail syslog facility
+# but can be set by syslog_facility in the dovecot configuration.
+[dovecot]
+
+port = pop3,pop3s,imap,imaps,submission,465,sieve
+logpath = %(dovecot_log)s
+backend = %(dovecot_backend)s
+
+
+[sieve]
+
+port = smtp,465,submission
+logpath = %(dovecot_log)s
+backend = %(dovecot_backend)s
+
+
+[solid-pop3d]
+
+port = pop3,pop3s
+logpath = %(solidpop3d_log)s
+
+
+[exim]
+# see filter.d/exim.conf for further modes supported from filter:
+#mode = normal
+port = smtp,465,submission
+logpath = %(exim_main_log)s
+
+
+[exim-spam]
+
+port = smtp,465,submission
+logpath = %(exim_main_log)s
+
+
+[kerio]
+
+port = imap,smtp,imaps,465
+logpath = /opt/kerio/mailserver/store/logs/security.log
+
+
+#
+# Mail servers authenticators: might be used for smtp,ftp,imap servers, so
+# all relevant ports get banned
+#
+
+[courier-auth]
+
+port = smtp,465,submission,imap,imaps,pop3,pop3s
+logpath = %(syslog_mail)s
+backend = %(syslog_backend)s
+
+
+[postfix-sasl]
+
+filter = postfix[mode=auth]
+port = smtp,465,submission,imap,imaps,pop3,pop3s
+# You might consider monitoring /var/log/mail.warn instead if you are
+# running postfix since it would provide the same log lines at the
+# "warn" level but overall at the smaller filesize.
+logpath = %(postfix_log)s
+backend = %(postfix_backend)s
+
+
+[perdition]
+
+port = imap,imaps,pop3,pop3s
+logpath = %(syslog_mail)s
+backend = %(syslog_backend)s
+
+
+[squirrelmail]
+
+port = smtp,465,submission,imap,imap2,imaps,pop3,pop3s,http,https,socks
+logpath = /var/lib/squirrelmail/prefs/squirrelmail_access_log
+
+
+[cyrus-imap]
+
+port = imap,imaps
+logpath = %(syslog_mail)s
+backend = %(syslog_backend)s
+
+
+[uwimap-auth]
+
+port = imap,imaps
+logpath = %(syslog_mail)s
+backend = %(syslog_backend)s
+
+
+#
+#
+# DNS servers
+#
+
+
+# !!! WARNING !!!
+# Since UDP is connection-less protocol, spoofing of IP and imitation
+# of illegal actions is way too simple. Thus enabling of this filter
+# might provide an easy way for implementing a DoS against a chosen
+# victim. See
+# http://nion.modprobe.de/blog/archives/690-fail2ban-+-dns-fail.html
+# Please DO NOT USE this jail unless you know what you are doing.
+#
+# IMPORTANT: see filter.d/named-refused for instructions to enable logging
+# This jail blocks UDP traffic for DNS requests.
+# [named-refused-udp]
+#
+# filter = named-refused
+# port = domain,953
+# protocol = udp
+# logpath = /var/log/named/security.log
+
+# IMPORTANT: see filter.d/named-refused for instructions to enable logging
+# This jail blocks TCP traffic for DNS requests.
+
+[named-refused]
+
+port = domain,953
+logpath = /var/log/named/security.log
+
+
+[nsd]
+
+port = 53
+action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
+ %(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
+logpath = /var/log/nsd.log
+
+
+#
+# Miscellaneous
+#
+
+[asterisk]
+
+port = 5060,5061
+action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
+ %(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
+logpath = /var/log/asterisk/messages
+maxretry = 10
+
+
+[freeswitch]
+
+port = 5060,5061
+action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
+ %(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
+logpath = /var/log/freeswitch.log
+maxretry = 10
+
+
+# enable adminlog; it will log to a file inside znc's directory by default.
+[znc-adminlog]
+
+port = 6667
+logpath = /var/lib/znc/moddata/adminlog/znc.log
+
+
+# To log wrong MySQL access attempts add to /etc/my.cnf in [mysqld] or
+# equivalent section:
+# log-warnings = 2
+#
+# for syslog (daemon facility)
+# [mysqld_safe]
+# syslog
+#
+# for own logfile
+# [mysqld]
+# log-error=/var/log/mysqld.log
+[mysqld-auth]
+
+port = 3306
+logpath = %(mysql_log)s
+backend = %(mysql_backend)s
+
+
+[mssql-auth]
+# Default configuration for Microsoft SQL Server for Linux
+# See the 'mssql-conf' manpage how to change logpath or port
+logpath = /var/opt/mssql/log/errorlog
+port = 1433
+filter = mssql-auth
+
+
+# Log wrong MongoDB auth (for details see filter 'filter.d/mongodb-auth.conf')
+[mongodb-auth]
+# change port when running with "--shardsvr" or "--configsvr" runtime operation
+port = 27017
+logpath = /var/log/mongodb/mongodb.log
+
+
+# Jail for more extended banning of persistent abusers
+# !!! WARNINGS !!!
+# 1. Make sure that your loglevel specified in fail2ban.conf/.local
+# is not at DEBUG level -- which might then cause fail2ban to fall into
+# an infinite loop constantly feeding itself with non-informative lines
+# 2. Increase dbpurgeage defined in fail2ban.conf to e.g. 648000 (7.5 days)
+# to maintain entries for failed logins for sufficient amount of time
+[recidive]
+
+logpath = /var/log/fail2ban.log
+banaction = %(banaction_allports)s
+bantime = 1w
+findtime = 1d
+
+
+# Generic filter for PAM. Has to be used with action which bans all
+# ports such as iptables-allports, shorewall
+
+[pam-generic]
+# pam-generic filter can be customized to monitor specific subset of 'tty's
+banaction = %(banaction_allports)s
+logpath = %(syslog_authpriv)s
+backend = %(syslog_backend)s
+
+
+[xinetd-fail]
+
+banaction = iptables-multiport-log
+logpath = %(syslog_daemon)s
+backend = %(syslog_backend)s
+maxretry = 2
+
+
+# stunnel - need to set port for this
+[stunnel]
+
+logpath = /var/log/stunnel4/stunnel.log
+
+
+[ejabberd-auth]
+
+port = 5222
+logpath = /var/log/ejabberd/ejabberd.log
+
+
+[counter-strike]
+
+logpath = /opt/cstrike/logs/L[0-9]*.log
+tcpport = 27030,27031,27032,27033,27034,27035,27036,27037,27038,27039
+udpport = 1200,27000,27001,27002,27003,27004,27005,27006,27007,27008,27009,27010,27011,27012,27013,27014,27015
+action_ = %(default/action_)s[name=%(__name__)s-tcp, port="%(tcpport)s", protocol="tcp"]
+ %(default/action_)s[name=%(__name__)s-udp, port="%(udpport)s", protocol="udp"]
+
+[softethervpn]
+port = 500,4500
+protocol = udp
+logpath = /usr/local/vpnserver/security_log/*/sec.log
+
+[gitlab]
+port = http,https
+logpath = /var/log/gitlab/gitlab-rails/application.log
+
+[grafana]
+port = http,https
+logpath = /var/log/grafana/grafana.log
+
+[bitwarden]
+port = http,https
+logpath = /home/*/bwdata/logs/identity/Identity/log.txt
+
+[centreon]
+port = http,https
+logpath = /var/log/centreon/login.log
+
+# consider low maxretry and a long bantime
+# nobody except your own Nagios server should ever probe nrpe
+[nagios]
+
+logpath = %(syslog_daemon)s ; nrpe.cfg may define a different log_facility
+backend = %(syslog_backend)s
+maxretry = 1
+
+
+[oracleims]
+# see "oracleims" filter file for configuration requirement for Oracle IMS v6 and above
+logpath = /opt/sun/comms/messaging64/log/mail.log_current
+banaction = %(banaction_allports)s
+
+[directadmin]
+logpath = /var/log/directadmin/login.log
+port = 2222
+
+[portsentry]
+logpath = /var/lib/portsentry/portsentry.history
+maxretry = 1
+
+[pass2allow-ftp]
+# this pass2allow example allows FTP traffic after successful HTTP authentication
+port = ftp,ftp-data,ftps,ftps-data
+# knocking_url variable must be overridden to some secret value in jail.local
+knocking_url = /knocking/
+filter = apache-pass[knocking_url="%(knocking_url)s"]
+# access log of the website with HTTP auth
+logpath = %(apache_access_log)s
+blocktype = RETURN
+returntype = DROP
+action = %(action_)s[blocktype=%(blocktype)s, returntype=%(returntype)s,
+ actionstart_on_demand=false, actionrepair_on_unban=true]
+bantime = 1h
+maxretry = 1
+findtime = 1
+
+
+[murmur]
+# AKA mumble-server
+port = 64738
+action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
+ %(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
+logpath = /var/log/mumble-server/mumble-server.log
+
+
+[screensharingd]
+# For Mac OS Screen Sharing Service (VNC)
+logpath = /var/log/system.log
+logencoding = utf-8
+
+[haproxy-http-auth]
+# HAProxy by default doesn't log to file you'll need to set it up to forward
+# logs to a syslog server which would then write them to disk.
+# See "haproxy-http-auth" filter for a brief cautionary note when setting
+# maxretry and findtime.
+logpath = /var/log/haproxy.log
+
+[slapd]
+port = ldap,ldaps
+logpath = /var/log/slapd.log
+
+[domino-smtp]
+port = smtp,ssmtp
+logpath = /home/domino01/data/IBM_TECHNICAL_SUPPORT/console.log
+
+[phpmyadmin-syslog]
+port = http,https
+logpath = %(syslog_authpriv)s
+backend = %(syslog_backend)s
+
+
+[zoneminder]
+# Zoneminder HTTP/HTTPS web interface auth
+# Logs auth failures to apache2 error log
+port = http,https
+logpath = %(apache_error_log)s
+
+[traefik-auth]
+# to use 'traefik-auth' filter you have to configure your Traefik instance,
+# see `filter.d/traefik-auth.conf` for details and service example.
+port = http,https
+logpath = /var/log/traefik/access.log
+
+[scanlogd]
+logpath = %(syslog_local0)s
+banaction = %(banaction_allports)s
+
+[monitorix]
+port = 8080
+logpath = /var/log/monitorix-httpd
--- /dev/null
+include:
+ - common.fail2ban.fail2ban--install-packages
+ - common.fail2ban.fail2ban--configure
+ - common.fail2ban.fail2ban--systemd-service
--- /dev/null
+Example call:
+salt-ssh 'myserver' state.apply common.init pillar='{"hostname": "myhostname"}'
--- /dev/null
+{{ pillar['hostname'] }}
--- /dev/null
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGPWuTBZblSStdSKYebTt1ggVQMrBRPJitU2ju4kvrGY user@app-split-ssh
--- /dev/null
+{{ pillar['users']['main']['account'] }} ALL=(ALL:ALL) NOPASSWD:ALL
--- /dev/null
+init--configure-user-sudoers:
+ file.append:
+ - name: /etc/sudoers
+ - source: salt://common/init/files/sudoers
+
+init--configure-user-auth:
+ ssh_auth.present:
+ - user: {{ pillar['users']['main']['account'] }}
+ - source: salt://common/init/files/id_ed25519.pub
+ - require:
+ - user: init--create-user
--- /dev/null
+init--create-user:
+ user.present:
+ - name: {{ pillar['users']['main']['account'] }}
+ - password: {{ pillar['users']['main']['password'] }}
+ - hash_password: True
+ - createhome: True
+ - usergroup: True
+ - shell: /bin/bash
+ - groups:
+ - sudo
--- /dev/null
+init--set-hostname:
+ file.managed:
+ - name: /etc/hostname
+ - source: salt://common/init/files/hostname
+ - template: jinja
+ - mode: 644
--- /dev/null
+include:
+ - common.init.init--configure-user
+ - common.init.init--create-user
+ - common.init.init--set-hostname
+ - reboot
--- /dev/null
+[options]
+ UseSyslog
+
+[openSSH]
+ sequence = {{ pillar['services']['knockd']['open_sequence'] }}
+ seq_timeout = 5
+ command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport {{ pillar['services']['ssh']['port'] }} -j ACCEPT
+ tcpflags = syn
+
+[closeSSH]
+ sequence = {{ pillar['services']['knockd']['close_sequence'] }}
+ seq_timeout = 5
+ command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport {{ pillar['services']['ssh']['port'] }} -j ACCEPT
+ tcpflags = syn
--- /dev/null
+include:
+ - common.knockd.knockd--install-packages
+ - common.knockd.knockd--configure
+ - common.knockd.knockd--systemd-service
--- /dev/null
+knockd--configure:
+ file.managed:
+ - name: /etc/knockd.conf
+ - source: salt://common/knockd/files/knockd.conf
+ - user: root
+ - group: root
+ - mode: 600
+ - template: jinja
+ - require:
+ - pkg: knockd--install-packages
--- /dev/null
+knockd--install-packages:
+ pkg.installed:
+ - pkgs:
+ - knockd
--- /dev/null
+knockd--systemd-service:
+ service.running:
+ - name: knockd
+ - enable: true
+ - reload: true
+ - watch:
+ - file: knockd--configure
--- /dev/null
+# Be sure to understand this config, you probably want to change this to your specific needs!
+/var/log/**/*.log {
+weekly
+rotate 2
+notifempty
+create
+dateext
+compress
+shred
+shredcycles 5
+}
--- /dev/null
+include:
+ - common.logrotate.logrotate--install-packages
+ - common.logrotate.logrotate--configure
--- /dev/null
+logrotate--configure:
+ file.managed:
+ - name: /etc/logrotate.conf
+ - source: salt://common/logrotate/files/logrotate.conf
+ - user: root
+ - group: root
+ - mode: 600
+ - require:
+ - pkg: logrotate--install-packages
--- /dev/null
+logrotate--install-packages:
+ pkg.installed:
+ - pkgs:
+ - logrotate
--- /dev/null
+########################################################
+# This guide was written and is maintained by:
+# Kirk Bauer <kirk@kaybee.org>
+#
+# Please send all comments, suggestions, bug reports,
+# etc, to kirk@kaybee.org.
+#
+########################################################
+
+# NOTE:
+# All these options are the defaults if you run logwatch with no
+# command-line arguments. You can override all of these on the
+# command-line.
+
+# You can put comments anywhere you want to. They are effective for the
+# rest of the line.
+
+# this is in the format of <name> = <value>. Whitespace at the beginning
+# and end of the lines is removed. Whitespace before and after the = sign
+# is removed. Everything is case *insensitive*.
+
+# Yes = True = On = 1
+# No = False = Off = 0
+
+# You can override the default temp directory (/tmp) here
+# TmpDir = /var/cache/logwatch
+
+# Output/Format Options
+# By default Logwatch will print to stdout in text with no encoding.
+# To make email Default set Output = mail to save to file set Output = file
+Output = mail
+# To make Html the default formatting Format = html
+Format = text
+# To make Base64 [aka uuencode] Encode = base64
+# Encode = none is the same as Encode = 8bit.
+# You can also specify 'Encode = 7bit', but only if all text is ASCII only.
+Encode = none
+
+# Input Encoding
+# Logwatch assumes that the input is in UTF-8 encoding. Defining CharEncoding
+# will use iconv to convert text to the UTF-8 encoding. Set CharEncoding
+# to an empty string to use the default current locale. If set to a valid
+# encoding, the input characters are converted to UTF-8, discarding any
+# illegal characters. Valid encodings are as used by the iconv program,
+# and `iconv -l` lists valid character set encodings.
+# Setting CharEncoding to UTF-8 simply discards illegal UTF-8 characters.
+#CharEncoding = ""
+
+# Default person to mail reports to. Can be a local account or a
+# complete email address. Variable Output should be set to mail, or
+# --output mail should be passed on command line to enable mail feature.
+MailTo = logwatch@{{ pillar['mail']['default_to'] }}
+# WHen using option --multiemail, it is possible to specify a different
+# email recipient per host processed. For example, to send the report
+# for hostname host1 to user@example.com, use:
+#Mailto_host1 = user@example.com
+# Multiple recipients can be specified by separating them with a space.
+
+# Default person to mail reports from. Can be a local account or a
+# complete email address.
+MailFrom = Logwatch
+
+# if set, the results will be saved in <filename> instead of mailed
+# or displayed. Be sure to set Output = file also.
+#Filename = /tmp/logwatch
+
+# Use archives? If set to 'Yes', the archives of logfiles
+# (i.e. /var/log/messages.1 or /var/log/messages.1.gz) will
+# be searched in addition to the /var/log/messages file.
+# This usually will not do much if your range is set to just
+# 'Yesterday' or 'Today'... it is probably best used with Range = All
+# By default this is now set to Yes. To turn off Archives uncomment this.
+#Archives = No
+
+# The default time range for the report...
+# The current choices are All, Today, Yesterday
+Range = yesterday
+
+# The default detail level for the report.
+# This can either be Low, Med, High or a number.
+# Low = 0
+# Med = 5
+# High = 10
+Detail = High
+
+
+# The 'Service' option expects either the name of a filter
+# (in /usr/share/logwatch/scripts/services/*) or 'All'.
+# The default service(s) to report on. This should be left as All for
+# most people.
+Service = All
+# You can also disable certain services (when specifying all)
+Service = "-zz-network" # Prevents execution of zz-network service, which
+ # prints useful network configuration info.
+Service = "-zz-sys" # Prevents execution of zz-sys service, which
+ # prints useful system configuration info.
+Service = "-eximstats" # Prevents execution of eximstats service, which
+ # is a wrapper for the eximstats program.
+# If you only cared about FTP messages, you could use these 2 lines
+# instead of the above:
+#Service = ftpd-messages # Processes ftpd messages in /var/log/messages
+#Service = ftpd-xferlog # Processes ftpd messages in /var/log/xferlog
+# Maybe you only wanted reports on PAM messages, then you would use:
+#Service = pam_pwdb # PAM_pwdb messages - usually quite a bit
+#Service = pam # General PAM messages... usually not many
+
+ You can also choose to use the 'LogFile' option. This will cause
+# logwatch to only analyze that one logfile.. for example:
+#LogFile = messages
+# will process /var/log/messages. This will run all the filters that
+# process that logfile. This option is probably not too useful to
+# most people. Setting 'Service' to 'All' above analyzes all LogFiles
+# anyways...
+
+#
+# By default we assume that all Unix systems have sendmail or a sendmail-like MTA.
+# The mailer code prints a header with To: From: and Subject:.
+# At this point you can change the mailer to anything that can handle this output
+# stream.
+# TODO test variables in the mailer string to see if the To/From/Subject can be set
+# From here with out breaking anything. This would allow mail/mailx/nail etc..... -mgt
+mailer = "/usr/sbin/sendmail -t"
+
+#
+# With this option set to a comma separated list of hostnames, only log entries
+# for these particular hosts will be processed. This can allow a log host to
+# process only its own logs, or Logwatch can be run once per a set of hosts
+# included in the logfiles.
+# Example: HostLimit = hosta,hostb,myhost
+#
+# The default is to report on all log entries, regardless of its source host.
+# Note that some logfiles do not include host information and will not be
+# influenced by this setting.
+#
+#HostLimit = myhost
+
+# Default Log Directory
+# All log-files are assumed to be given relative to the LogDir directory.
+# Multiple LogDir statements are possible. Additional configuration variables
+# to set particular directories follow, so LogDir need not be set.
+#LogDir = /var/log
+#
+# By default /var/adm is searched after LogDir.
+#AppendVarAdmToLogDirs = 1
+#
+# By default /var/log is to be searched after LogDir and /var/adm/ .
+#AppendVarLogToLogDirs = 1
+#
+# The current working directory can be searched after the above. Not set by
+# default.
+#AppendCWDToLogDirs = 0
+
+# vi: shiftwidth=3 tabstop=3 et
--- /dev/null
+include:
+ - common.logwatch.logwatch--install-packages
+ - common.logwatch.logwatch--configure
--- /dev/null
+logwatch--conf-logwatchconf:
+ file.managed:
+ - name: /etc/logwatch/conf/logwatch.conf
+ - source: salt://common/logwatch/files/logwatch.conf
+ - user: root
+ - group: root
+ - mode: 644
+ - template: jinja
+ - require:
+ - logwatch--install-packages
--- /dev/null
+logwatch--install-packages:
+ pkg.installed:
+ - pkgs:
+ - logwatch
--- /dev/null
+include:
+ - common.remove-unwanted-packages.remove-unwanted-packages--packages
--- /dev/null
+remove-unwanted-packages--packages:
+ pkg.removed:
+ - pkgs:
+ - nano
+ - vim
+ - neovim
+ - exim4
+ - cups
+ - samba*
+ - snapd
+ - bluetooth
+ - bluez
+ - doc-debian
+ - manpages-de
+ - xinetd
+ - nis
+ - yp-tools
+ - tftpd
+ - atftpd
+ - tftpd-hpa
+ - telnetd
+ - rsh-server
+ - rsh-redone-server
+ - acpid
+ - aptitude
+ - at
+
+remove-unwanted-packages--apt-cleanup:
+ cmd.run:
+ - name: "apt-get autoremove -y && apt-get clean && apt-get autopurge"
+ - onchanges:
+ - pkg: remove-unwanted-packages--packages
--- /dev/null
+Warning!! Authorized users only. All others will be prosecuted.
--- /dev/null
+{%- set users = salt['cmd.run']('sh -c "getent passwd | grep /home | cut -d: -f1"').splitlines() -%}
+# SSH configuration sourced from various blog posts, mailing lists, forums, etc.
+# Depending on your security needs, you may want to consider using tools like:
+# - fail2ban
+# - denyhosts
+# - knockd
+
+AddressFamily inet # Change this to inet6 to use IPv6 only
+Protocol 2
+Port {{ pillar['services']['ssh']['port'] }}
+
+AllowUsers {{ users | join(" ") }} # Make sure to understand this line, otherwise you risk locking yourself out of ssh access to the server
+
+PermitRootLogin no
+PermitEmptyPasswords no
+PasswordAuthentication no
+KbdInteractiveAuthentication no
+ChallengeResponseAuthentication no
+AuthenticationMethods publickey
+PubkeyAuthentication yes
+IgnoreRhosts yes
+HostbasedAuthentication no
+KerberosAuthentication no
+
+MaxAuthTries 3
+MaxSessions 2
+TCPKeepAlive no
+ClientAliveInterval 300
+ClientAliveCountMax 2
+
+LogLevel VERBOSE
+
+Banner /etc/ssh/sshd_banner
+PrintMotd no
+
+AllowAgentForwarding no
+X11Forwarding no
+AllowTcpForwarding no
+AllowStreamLocalForwarding no
+GatewayPorts no
+PermitTunnel no
+
+# Key exchange & encryption settings
+# I prefer a blacklisting approach for key exchange and encryption algorithms,
+# so I avoid excluding new algorithms in the future. For this, I use tools like https://sshcheck.com/ to keep track.
+# If you prefer a whitelisting approach, Mozilla's guidelines are a common resource:
+# https://infosec.mozilla.org/guidelines/openssh.html
+HostKeyAlgorithms -ecdsa-sha2-nistp256,-ecdsa-sha2-nistp384,-ecdsa-sha2-nistp521,-ssh-dss,-ssh-rsa
+KexAlgorithms -diffie-hellman-group14-sha256,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521
+MACs -umac-64-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,hmac-sha1
+
+AcceptEnv LANG LC_*
+
+# scp needs this. If you don't use scp (so, also Saltstack), you can delete this line.
+Subsystem sftp /usr/lib/openssh/sftp-server
--- /dev/null
+include:
+ - common.ssh.ssh--configure
+ - common.ssh.ssh--systemd-service
--- /dev/null
+ssh--configure:
+ file.managed:
+ - user: root
+ - group: root
+ - mode: 600
+ - template: jinja
+ - names:
+ - /etc/ssh/sshd_config:
+ - source: salt://common/ssh/files/sshd_config
+ - /etc/ssh/sshd_banner:
+ - source: salt://common/ssh/files/sshd_banner
--- /dev/null
+ssh--systemd-service:
+ service.running:
+ - name: sshd
+ - enable: true
+ - reload: true
+ - watch:
+ - file: /etc/ssh/sshd_config
+ - file: /etc/ssh/sshd_banner
--- /dev/null
+include:
+ - common.ufw.ufw--install-packages
+ - common.ufw.ufw--systemd-service
+ - common.ufw.ufw--enable
--- /dev/null
+ufw--enable:
+ cmd.run:
+ - name: ufw --force enable
+ - require:
+ - pkg: ufw--install-packages
--- /dev/null
+ufw--install-packages:
+ pkg.installed:
+ - pkgs:
+ - ufw
--- /dev/null
+ufw--systemd-service:
+ service.running:
+ - name: ufw
+ - enable: True
+ - reload: True
+ - require:
+ - pkg: ufw--install-packages
--- /dev/null
+// Unattended-Upgrade::Origins-Pattern controls which packages are
+// upgraded.
+//
+// Lines below have the format "keyword=value,...". A
+// package will be upgraded only if the values in its metadata match
+// all the supplied keywords in a line. (In other words, omitted
+// keywords are wild cards.) The keywords originate from the Release
+// file, but several aliases are accepted. The accepted keywords are:
+// a,archive,suite (eg, "stable")
+// c,component (eg, "main", "contrib", "non-free")
+// l,label (eg, "Debian", "Debian-Security")
+// o,origin (eg, "Debian", "Unofficial Multimedia Packages")
+// n,codename (eg, "jessie", "jessie-updates")
+// site (eg, "http.debian.net")
+// The available values on the system are printed by the command
+// "apt-cache policy", and can be debugged by running
+// "unattended-upgrades -d" and looking at the log file.
+//
+// Within lines unattended-upgrades allows 2 macros whose values are // derived from /etc/debian_version:
+// ${distro_id} Installed origin.
+// ${distro_codename} Installed codename (eg, "buster")
+Unattended-Upgrade::Origins-Pattern {
+ // Codename based matching:
+ // This will follow the migration of a release through different
+ // archives (e.g. from testing to stable and later oldstable).
+ // Software will be the latest available for the named release,
+ // but the Debian release itself will not be automatically upgraded.
+// "origin=Debian,codename=${distro_codename}-updates";
+// "origin=Debian,codename=${distro_codename}-proposed-updates";
+ "origin=Debian,codename=${distro_codename},label=Debian";
+ "origin=Debian,codename=${distro_codename},label=Debian-Security";
+ "origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
+
+ // Archive or Suite based matching:
+ // Note that this will silently match a different release after
+ // migration to the specified archive (e.g. testing becomes the
+ // new stable).
+// "o=Debian,a=stable";
+// "o=Debian,a=stable-updates";
+// "o=Debian,a=proposed-updates";
+// "o=Debian Backports,a=${distro_codename}-backports,l=Debian Backports";
+};
+
+// Python regular expressions, matching packages to exclude from upgrading
+Unattended-Upgrade::Package-Blacklist {
+ // The following matches all packages starting with linux-
+// "linux-";
+
+ // Use $ to explicitely define the end of a package name. Without
+ // the $, "libc6" would match all of them.
+// "libc6$";
+// "libc6-dev$";
+// "libc6-i686$";
+
+ // Special characters need escaping
+// "libstdc\+\+6$";
+
+ // The following matches packages like xen-system-amd64, xen-utils-4.1,
+ // xenstore-utils and libxenstore3.0
+// "(lib)?xen(store)?";
+
+ // For more information about Python regular expressions, see
+ // https://docs.python.org/3/howto/regex.html
+};
+
+// This option allows you to control if on a unclean dpkg exit
+// unattended-upgrades will automatically run
+// dpkg --force-confold --configure -a
+// The default is true, to ensure updates keep getting installed
+//Unattended-Upgrade::AutoFixInterruptedDpkg "true";
+
+// Split the upgrade into the smallest possible chunks so that
+// they can be interrupted with SIGTERM. This makes the upgrade
+// a bit slower but it has the benefit that shutdown while a upgrade
+// is running is possible (with a small delay)
+//Unattended-Upgrade::MinimalSteps "true";
+
+// Install all updates when the machine is shutting down
+// instead of doing it in the background while the machine is running.
+// This will (obviously) make shutdown slower.
+// Unattended-upgrades increases logind's InhibitDelayMaxSec to 30s.
+// This allows more time for unattended-upgrades to shut down gracefully
+// or even install a few packages in InstallOnShutdown mode, but is still a
+// big step back from the 30 minutes allowed for InstallOnShutdown previously.
+// Users enabling InstallOnShutdown mode are advised to increase
+// InhibitDelayMaxSec even further, possibly to 30 minutes.
+//Unattended-Upgrade::InstallOnShutdown "false";
+
+// Send email to this address for problems or packages upgrades
+// If empty or unset then no email is sent, make sure that you
+// have a working mail setup on your system. A package that provides
+// 'mailx' must be installed. E.g. "user@example.com"
+Unattended-Upgrade::Mail "unattended-upgrade@{{ pillar['mail']['default_to'] }}";
+
+// Set this value to one of:
+// "always", "only-on-error" or "on-change"
+// If this is not set, then any legacy MailOnlyOnError (boolean) value
+// is used to chose between "only-on-error" and "on-change"
+Unattended-Upgrade::MailReport "always";
+
+// Remove unused automatically installed kernel-related packages
+// (kernel images, kernel headers and kernel version locked tools).
+Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
+
+// Do automatic removal of newly unused dependencies after the upgrade
+Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
+
+// Do automatic removal of unused packages after the upgrade
+// (equivalent to apt-get autoremove)
+Unattended-Upgrade::Remove-Unused-Dependencies "true";
+
+// Automatically reboot *WITHOUT CONFIRMATION* if
+// the file /var/run/reboot-required is found after the upgrade
+Unattended-Upgrade::Automatic-Reboot "false";
+
+// Automatically reboot even if there are users currently logged in
+// when Unattended-Upgrade::Automatic-Reboot is set to true
+Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
+
+// If automatic reboot is enabled and needed, reboot at the specific
+// time instead of immediately
+// Default: "now"
+//Unattended-Upgrade::Automatic-Reboot-Time "02:00";
+
+// Use apt bandwidth limit feature, this example limits the download
+// speed to 70kb/sec
+//Acquire::http::Dl-Limit "70";
+
+// Enable logging to syslog. Default is False
+// Unattended-Upgrade::SyslogEnable "false";
+
+// Specify syslog facility. Default is daemon
+// Unattended-Upgrade::SyslogFacility "daemon";
+
+// Download and install upgrades only on AC power
+// (i.e. skip or gracefully stop updates on battery)
+// Unattended-Upgrade::OnlyOnACPower "true";
+
+// Download and install upgrades only on non-metered connection
+// (i.e. skip or gracefully stop updates on a metered connection)
+// Unattended-Upgrade::Skip-Updates-On-Metered-Connections "true";
+
+// Verbose logging
+// Unattended-Upgrade::Verbose "false";
+
+// Print debugging information both in unattended-upgrades and
+// in unattended-upgrade-shutdown
+// Unattended-Upgrade::Debug "false";
+
+// Allow package downgrade if Pin-Priority exceeds 1000
+// Unattended-Upgrade::Allow-downgrade "false";
+
+// When APT fails to mark a package to be upgraded or installed try adjusting
+// candidates of related packages to help APT's resolver in finding a solution
+// where the package can be upgraded or installed.
+// This is a workaround until APT's resolver is fixed to always find a
+// solution if it exists. (See Debian bug #711128.)
+// The fallback is enabled by default, except on Debian's sid release because
+// uninstallable packages are frequent there.
+// Disabling the fallback speeds up unattended-upgrades when there are
+// uninstallable packages at the expense of rarely keeping back packages which
+// could be upgraded or installed.
+// Unattended-Upgrade::Allow-APT-Mark-Fallback "true";
--- /dev/null
+include:
+ - common.unattended-upgrades.unattended-upgrades--install-packages
+ - common.unattended-upgrades.unattended-upgrades--configure
--- /dev/null
+unattended-upgrades--configure:
+ file.managed:
+ - name: /etc/apt/apt.conf.d/50unattended-upgrades
+ - source: salt://common/unattended-upgrades/files/50unattended-upgrades
+ - user: root
+ - group: root
+ - mode: 600
+ - template: jinja
+ - require:
+ - pkg: unattended-upgrades--install-packages
--- /dev/null
+unattended-upgrades--install-packages:
+ pkg.installed:
+ - pkgs:
+ - unattended-upgrades
--- /dev/null
+sudo cat /etc/opendkim/keys/<domain.tld>/defualt.txt
+
+Copy output, remove all qotes and blank spaces from the record value, then publish it to your DNS Zone.
+
+Check if everything is OK (Note: If you have not configured DNSSEC, you will get the message "Key not secure". You can ignore that")
+sudo opendkim-testkey -d example.com -s default -vvv
+
+Test DKIM:
+send a mail to an mail account where you can check the mail headers OR go through your system logs
+
+Test DMARC:
+send a mail to an mail account where you can check the mail headers OR go through your system logs. You should find something like this:
+
+Authentication-Results: OpenDMARC; dmarc=pass (p=reject dis=none) header.from=mydomain.tld
--- /dev/null
+{% set smtpd_milters_line = '' %}
+{% set non_smtpd_milters_line = '' %}
+
+{%- if salt['file.file_exists']('/etc/postfix/main.cf') %}
+ {% for line in salt['file.read']('/etc/postfix/main.cf').splitlines() %}
+ {% if line.startswith('smtpd_milters') %}
+ {% set smtpd_milters_line = line %}
+ {% elif line.startswith('non_smtpd_milters') %}
+ {% set non_smtpd_milters_line = line %}
+ {% endif %}
+ {% endfor %}
+
+ {% set smtpd_milters_value = smtpd_milters_line.split('=')[1].strip() if smtpd_milters_line and '=' in smtpd_milters_line else '' %}
+ {% set non_smtpd_milters_value = non_smtpd_milters_line.split('=')[1].strip() if non_smtpd_milters_line and '=' in non_smtpd_milters_line else '' %}
+{%- else %}
+ {% set smtpd_milters_value = '' %}
+ {% set non_smtpd_milters_value = '' %}
+{% endif %}
+
+dmarc-dkim--configure-postfix-maincf-smtpd_milters:
+ file.replace:
+ - name: /etc/postfix/main.cf
+ - pattern: '^smtpd_milters =.*'
+ - repl: "smtpd_milters = {{ smtpd_milters_value + (', ' if smtpd_milters_value else '') }}inet:127.0.0.1:8891, inet:127.0.0.1:8893"
+ - unless: "grep -q 'smtpd_milters =.*inet:127.0.0.1:8891.*inet:127.0.0.1:8893' /etc/postfix/main.cf"
+ - require:
+ - file: postfix--configure
+
+dmarc-dkim--configure-postfix-maincf-non_smtpd_milters:
+ file.replace:
+ - name: /etc/postfix/main.cf
+ - pattern: '^non_smtpd_milters =.*'
+ - repl: "non_smtpd_milters = {{ non_smtpd_milters_value + (', ' if non_smtpd_milters_value else '') }}inet:127.0.0.1:8891, inet:127.0.0.1:8893"
+ - unless: "grep -q 'non_smtpd_milters =.*inet:127.0.0.1:8891.*inet:127.0.0.1:8893' /etc/postfix/main.cf"
+ - require:
+ - file: postfix--configure
+
+dmarc-dkim--configure-opendkim:
+ file.managed:
+ - user: opendkim
+ - group: opendkim
+ - mode: 644
+ - template: jinja
+ - makedirs: True
+ - names:
+ - /etc/opendkim/KeyTable:
+ - source: salt://dmarc-dkim/files/KeyTable
+ - /etc/opendkim/TrustedHosts:
+ - source: salt://dmarc-dkim/files/TrustedHosts
+ - /etc/opendkim/SigningTable:
+ - source: salt://dmarc-dkim/files/SigningTable
+ - /etc/opendkim.conf:
+ - source: salt://dmarc-dkim/files/opendkim.conf
+ - /etc/default/opendkim:
+ - source: salt://dmarc-dkim/files/opendkim
+
+dmarc-dkim--configure-opendmarc:
+ file.managed:
+ - name: /etc/opendmarc.conf
+ - source: salt://dmarc-dkim/files/opendmarc.conf
+ - user: opendmarc
+ - group: opendmarc
+ - mode: 644
+ - template: jinja
--- /dev/null
+dmarc-dkim--opendkim-keys-directory:
+ file.directory:
+ - name: /etc/opendkim/keys
+ - user: opendkim
+ - group: opendkim
+ - makedirs: True
+ - mode: 755
+
+dmarc-dkim-opendkim-keys-directory:
+ file.directory:
+ - name: /etc/opendkim/keys/{{ pillar['common']['domain'] }}
+ - user: opendkim
+ - group: opendkim
+ - makedirs: True
+ - mode: 750
+
+dmarc-dkim--dkim-generate-key-{{ pillar['common']['domain'] }}:
+ cmd.run:
+ - name: sudo opendkim-genkey -b 2048 -d {{ pillar['common']['domain'] }} -s default
+ - cwd: /etc/opendkim/keys/{{ pillar['common']['domain'] }}
+ - creates: /etc/opendkim/keys/{{ pillar['common']['domain'] }}/default.private
+ - require:
+ - file: dmarc-dkim--opendkim-keys-directory
+
+dmarc-dkim--dkim-key-txt-update-rights:
+ file.managed:
+ - name: /etc/opendkim/keys/{{ pillar['common']['domain'] }}/default.txt
+ - user: opendkim
+ - group: opendkim
+ - replace: False
+ - require:
+ - cmd: dmarc-dkim--dkim-generate-key-{{ pillar['common']['domain'] }}
+
+dmarc-dkim--dkim-key-private-update-rights:
+ file.managed:
+ - name: /etc/opendkim/keys/{{ pillar['common']['domain'] }}/default.private
+ - user: opendkim
+ - group: opendkim
+ - replace: False
+ - require:
+ - cmd: dmarc-dkim--dkim-generate-key-{{ pillar['common']['domain'] }}
--- /dev/null
+dmarc-dkim--install-packages:
+ pkg.installed:
+ - refresh: True
+ - pkgs:
+ - opendmarc
+ - opendkim
+ - opendkim-tools
--- /dev/null
+dmarc-dkim--systemd-service-opendkim:
+ service.running:
+ - name: opendkim
+ - enable: True
+ - reload: True
+ - watch:
+ - file: /etc/opendkim.conf
+ - file: /etc/opendkim/SigningTable
+ - file: /etc/opendkim/TrustedHosts
+ - file: /etc/opendkim/KeyTable
+ - file: /etc/default/opendkim
+ - require:
+ - pkg: dmarc-dkim--install-packages
+
+dmarc-dkim--systemd-service-opendmarc:
+ service.running:
+ - name: opendmarc
+ - enable: True
+ - reload: True
+ - watch:
+ - file: /etc/opendmarc.conf
+ - require:
+ - pkg: dmarc-dkim--install-packages
--- /dev/null
+default._domainkey.{{ pillar['common']['domain'] }} {{ pillar['common']['domain'] }}:default:/etc/opendkim/keys/{{ pillar['common']['domain'] }}/default.private
--- /dev/null
+*@{{ pillar['common']['domain'] }} default._domainkey.{{ pillar['common']['domain'] }}
+*@*.{{ pillar['common']['domain'] }} default._domainkey.{{ pillar['common']['domain'] }}
--- /dev/null
+127.0.0.1
+localhost
+.{{ pillar['common']['domain'] }}
--- /dev/null
+# TODO: check if this is still needed?
+# NOTE: This is a legacy configuration file. It is not used by the opendkim
+# systemd service. Please use the corresponding configuration parameters in
+# /etc/opendkim.conf instead.
+#
+# Previously, one would edit the default settings here, and then execute
+# /lib/opendkim/opendkim.service.generate to generate systemd override files at
+# /etc/systemd/system/opendkim.service.d/override.conf and
+# /etc/tmpfiles.d/opendkim.conf. While this is still possible, it is now
+# recommended to adjust the settings directly in /etc/opendkim.conf.
+#
+#DAEMON_OPTS=""
+# Change to /var/spool/postfix/run/opendkim to use a Unix socket with
+# postfix in a chroot:
+#RUNDIR=/var/spool/postfix/run/opendkim
+RUNDIR=/run/opendkim
+#
+# Uncomment to specify an alternate socket
+# Note that setting this will override any Socket value in opendkim.conf
+# default:
+SOCKET=local:$RUNDIR/opendkim.sock
+# listen on all interfaces on port 54321:
+#SOCKET=inet:54321
+# listen on loopback on port 12345:
+#SOCKET=inet:12345@localhost
+# listen on 192.0.2.1 on port 12345:
+#SOCKET=inet:12345@192.0.2.1
+USER=opendkim
+GROUP=opendkim
+PIDFILE=$RUNDIR/$NAME.pid
+EXTRAAFTER=
--- /dev/null
+# This is a basic configuration for signing and verifying. It can easily be
+# adapted to suit a basic installation. See opendkim.conf(5) and
+# /usr/share/doc/opendkim/examples/opendkim.conf.sample for complete
+# documentation of available configuration parameters.
+
+Syslog yes
+SyslogSuccess yes
+LogWhy no
+
+# Common signing and verification parameters. In Debian, the "From" header is
+# oversigned, because it is often the identity key used by reputation systems
+# and thus somewhat security sensitive.
+Canonicalization relaxed/simple
+Mode sv
+SubDomains yes
+OversignHeaders From
+
+# Signing domain, selector, and key (required). For example, perform signing
+# for domain "example.com" with selector "2020" (2020._domainkey.example.com),
+# using the private key stored in /etc/dkimkeys/example.private. More granular
+# setup options can be found in /usr/share/doc/opendkim/README.opendkim.
+Domain {{ pillar['common']['domain'] }}
+#Selector 2020
+#KeyFile /etc/dkimkeys/example.private
+
+# In Debian, opendkim runs as user "opendkim". A umask of 007 is required when
+# using a local socket with MTAs that access the socket as a non-privileged
+# user (for example, Postfix). You may need to add user "postfix" to group
+# "opendkim" in that case.
+UserID opendkim
+UMask 007
+
+# Socket for the MTA connection (required). If the MTA is inside a chroot jail,
+# it must be ensured that the socket is accessible. In Debian, Postfix runs in
+# a chroot in /var/spool/postfix, therefore a Unix socket would have to be
+# configured as shown on the last line below.
+#Socket local:/run/opendkim/opendkim.sock
+Socket inet:8891@localhost
+#Socket inet:8891
+#Socket local:/var/spool/postfix/opendkim/opendkim.sock
+
+PidFile /run/opendkim/opendkim.pid
+
+# Hosts for which to sign rather than verify, default is 127.0.0.1. See the
+# OPERATION section of opendkim(8) for more information.
+#InternalHosts 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12
+
+# The trust anchor enables DNSSEC. In Debian, the trust anchor file is provided
+# by the package dns-root-data.
+TrustAnchorFile /usr/share/dns/root.key
+#Nameservers 127.0.0.1
+
+# custom:
+
+AutoRestart yes
+AutoRestartRate 10/1M
+Background yes
+DNSTimeout 5
+SignatureAlgorithm rsa-sha256
+
+KeyFile /etc/opendkim/keys/default.private
+KeyTable /etc/opendkim/KeyTable
+SigningTable refile:/etc/opendkim/SigningTable
+ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
+InternalHosts refile:/etc/opendkim/TrustedHosts
--- /dev/null
+# This is a basic configuration that can easily be adapted to suit a standard
+# installation. For more advanced options, see openmarc.conf(5) and/or
+# /usr/share/doc/opendmarc/examples/opendmarc.conf.sample.
+
+## AuthservID (string)
+## defaults to MTA name
+##
+## Sets the "authserv-id" to use when generating the Authentication-Results:
+## header field after verifying a message. If the string "HOSTNAME" is
+## provided, the name of the host running the filter (as returned by the
+## gethostname(3) function) will be used.
+#
+AuthservID OpenDMARC
+
+## FailureReports { true | false }
+## default "false"
+##
+## Enables generation of failure reports when the DMARC test fails and the
+## purported sender of the message has requested such reports. Reports are
+## formatted per RFC6591.
+#
+# FailureReports false
+
+## PidFile path
+## default (none)
+##
+## Specifies the path to a file that should be created at process start
+## containing the process ID.
+#
+PidFile /run/opendmarc/opendmarc.pid
+
+## PublicSuffixList path
+## default (none)
+##
+## Specifies the path to a file that contains top-level domains (TLDs) that
+## will be used to compute the Organizational Domain for a given domain name,
+## as described in the DMARC specification. If not provided, the filter will
+## not be able to determine the Organizational Domain and only the presented
+## domain will be evaluated.
+#
+PublicSuffixList /usr/share/publicsuffix/public_suffix_list.dat
+
+## RejectFailures { true | false }
+## default "false"
+##
+## If set, messages will be rejected if they fail the DMARC evaluation, or
+## temp-failed if evaluation could not be completed. By default, no message
+## will be rejected or temp-failed regardless of the outcome of the DMARC
+## evaluation of the message. Instead, an Authentication-Results header
+## field will be added.
+#
+# RejectFailures false
+
+## Socket socketspec
+## default (none)
+##
+## Specifies the socket that should be established by the filter to receive
+## connections from sendmail(8) in order to provide service. socketspec is
+## in one of two forms: local:path, which creates a UNIX domain socket at
+## the specified path, or inet:port[@host] or inet6:port[@host] which creates
+## a TCP socket on the specified port for the appropriate protocol family.
+## If the host is not given as either a hostname or an IP address, the
+## socket will be listening on all interfaces. This option is mandatory
+## either in the configuration file or on the command line. If an IP
+## address is used, it must be enclosed in square brackets.
+#
+Socket inet:8893@localhost
+
+## Syslog { true | false }
+## default "false"
+##
+## Log via calls to syslog(3) any interesting activity.
+#
+Syslog true
+
+## SyslogFacility facility-name
+## default "mail"
+##
+## Log via calls to syslog(3) using the named facility. The facility names
+## are the same as the ones allowed in syslog.conf(5).
+#
+# SyslogFacility mail
+
+## TrustedAuthservIDs string
+## default HOSTNAME
+##
+## Specifies one or more "authserv-id" values to trust as relaying true
+## upstream DKIM and SPF results. The default is to use the name of
+## the MTA processing the message. To specify a list, separate each entry
+## with a comma. The key word "HOSTNAME" will be replaced by the name of
+## the host running the filter as reported by the gethostname(3) function.
+#
+TrustedAuthservIDs mail.andreasglashauser.com
+
+## UMask mask
+## default (none)
+##
+## Requests a specific permissions mask to be used for file creation. This
+## only really applies to creation of the socket when Socket specifies a
+## UNIX domain socket, and to the HistoryFile and PidFile (if any); temporary
+## files are normally created by the mkstemp(3) function that enforces a
+## specific file mode on creation regardless of the process umask. See
+## umask(2) for more information.
+#
+UMask 0002
+
+## UserID user[:group]
+## default (none)
+##
+## Attempts to become the specified userid before starting operations.
+## The process will be assigned all of the groups and primary group ID of
+## the named userid unless an alternate group is specified.
+#
+UserID opendmarc
+
+SPFSelfValidate true
--- /dev/null
+include:
+ - dmarc-dkim.dmarc-dkim--install-packages
+ - dmarc-dkim.dmarc-dkim--systemd-service
+ - dmarc-dkim.dmarc-dkim--configure
+ - dmarc-dkim.dmarc-dkim--generate-dkim-key
--- /dev/null
+git--configure:
+ file.directory:
+ - name: /srv/git
+ - user: git
+ - group: git
+ - mode: 755
+ - makedirs: True
+ - require:
+ - user: git--create-user
--- /dev/null
+git--create-user:
+ user.present:
+ - name: git
+ - shell: /bin/bash
+ - system: True
+ - createhome: False
+ - usergroup: True
+ - password: '!'
--- /dev/null
+git--install-packages:
+ pkg.installed:
+ - refresh: True
+ - pkgs:
+ - git
--- /dev/null
+include:
+ - git.git--install-packages
+ - git.git--create-user
+ - git.git--configure
--- /dev/null
+ServerTokens Prod
+ServerSignature Off
+FileETag None
+
+<VirtualHost *:80>
+ ServerName {{ pillar['common']['fqdn'] }}
+ Redirect permanent / https://{{ pillar['common']['fqdn'] }}/
+</VirtualHost>
+
+<VirtualHost *:443>
+ ServerName {{ pillar['common']['fqdn'] }}
+ DocumentRoot /usr/share/gitweb
+
+ Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
+ Header always set X-Frame-Options "DENY"
+ Header always set Content-Security-Policy "default-src 'self';"
+ Header always set X-Content-Type-Options "nosniff"
+ Header always set Referrer-Policy "no-referrer"
+ Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
+
+ <IfModule mod_evasive20.c>
+ DOSHashTableSize 2048
+ DOSPageCount 5
+ DOSSiteCount 100
+ DOSPageInterval 1
+ DOSSiteInterval 1
+ DOSBlockingPeriod 60
+ DOSEmailNotify "apache@{{ pillar['mail']['default_to'] }}"
+ DOSLogDir "/var/log/apache2/mod_evasive"
+ </IfModule>
+
+ <Directory /usr/share/gitweb>
+ Options +ExecCGI +FollowSymLinks
+ AddHandler cgi-script .cgi
+ DirectoryIndex gitweb.cgi
+ Require all granted
+ </Directory>
+
+
+ SetEnv GIT_PROJECT_ROOT /srv/git
+ SetEnv GIT_HTTP_EXPORT_ALL
+ ScriptAlias /git/ /usr/lib/git-core/git-http-backend/
+
+ <Directory "/usr/lib/git-core">
+ Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
+ Require all granted
+ </Directory>
+
+</VirtualHost>
--- /dev/null
+# path to git projects (<project>.git)
+$projectroot = "/srv/git";
+$site_name = "Andreas Glashauser | Gitweb";
+$omit_owner = 1;
+@git_base_url_list = ("https://git.andreasglashauser.com/git");
+
+# directory to use for temp files
+#$git_temp = "/tmp";
+
+# target of the home link on top of all pages
+#$home_link = $my_uri || "/";
+
+# html text to include at home page
+#$home_text = "indextext.html";
+
+# file with project list; by default, simply scan the projectroot dir.
+#$projects_list = $projectroot;
+
+# stylesheet to use
+#@stylesheets = ("static/gitweb.css");
+
+# javascript code for gitweb
+#$javascript = "static/gitweb.js";
+
+# logo to use
+#$logo = "static/git-logo.png";
+
+# the 'favicon'
+#$favicon = "static/git-favicon.png";
+
+# git-diff-tree(1) options to use for generated patches
+#@diff_opts = ("-M");
+@diff_opts = ();
--- /dev/null
+gitweb--configure:
+ file.managed:
+ - template: jinja
+ - names:
+ - /etc/gitweb.conf:
+ - source: salt://gitweb/files/gitweb.conf
+ - /etc/apache2/sites-available/git.conf:
+ - source: salt://gitweb/files/git.conf
--- /dev/null
+include:
+ - git.git--install-packages
+ - common.ufw.ufw--install-packages
+
+gitweb--install-packages:
+ pkg.installed:
+ - refresh: True
+ - pkgs:
+ - gitweb
+ - apache2
+ - libapache2-mod-evasive
+ - python3-certbot-apache
+
+gitweb--ensure-ufw-open-port-80:
+ cmd.run:
+ - name: ufw allow 80/tcp
+ - require:
+ - pkg: ufw--install-packages
+
+gitweb--ensure-ufw-open-port-443:
+ cmd.run:
+ - name: ufw allow 443/tcp
+ - require:
+ - pkg: ufw--install-packages
--- /dev/null
+gitweb--www-data-group:
+ group.present:
+ - name: git
+ - members:
+ - www-data
+ - git
+
+gitweb--srv-git-directory:
+ file.directory:
+ - name: /srv/git
+ - recurse:
+ - group
+ - group: www-data
+ - require:
+ - group: gitweb--www-data-group
+
+gitweb--set-git-permissions:
+ cmd.run:
+ - name: chmod -R g+rx /srv/git
+ - require:
+ - file: gitweb--srv-git-directory
--- /dev/null
+gitweb--enable-cgi:
+ cmd.run:
+ - name: a2enmod cgi
+ - unless: apache2ctl -M | grep -q 'cgi_module'
+ - require:
+ - pkg: gitweb--install-packages
+
+gitweb--enable-ssl:
+ cmd.run:
+ - name: a2enmod ssl
+ - unless: apache2ctl -M | grep -q 'ssl'
+ - require:
+ - pkg: gitweb--install-packages
+
+gitweb--enable-git-conf:
+ cmd.run:
+ - name: a2ensite git.conf
+ - require:
+ - pkg: gitweb--install-packages
+
+gitweb--enable-evasive:
+ cmd.run:
+ - name: a2enmod evasive
+ - require:
+ - pkg: gitweb--install-packages
+
+gitweb--enable-headers:
+ cmd.run:
+ - name: a2enmod headers
+ - require:
+ - pkg: gitweb--install-packages
+
+gitweb--systemd-service:
+ service.running:
+ - name: apache2
+ - enable: True
+ - reload: True
+ - watch:
+ - file: gitweb--configure
+ - cmd: gitweb--enable-cgi
+ - cmd: gitweb--enable-git-conf
+ - cmd: gitweb--enable-evasive
+ - cmd: gitweb--enable-ssl
+ - cmd: gitweb--enable-headers
--- /dev/null
+include:
+ - gitweb.gitweb--install-packages
+ - gitweb.gitweb--configure
+ - gitweb.gitweb--permissions
+ - gitweb.gitweb--systemd-service
--- /dev/null
+set realname = "{{ pillar['users']['main']['mutt']['real_name'] }}"
+set from = "{{ pillar['users']['main']['mutt']['from'] }}"
+set use_from = yes
+set envelope_from = yes
+
+set mail_check = 30
+set editor = "vi"
+
+set mbox_type = Maildir
+set folder = "~/Maildir"
+set spoolfile = "+INBOX"
+set record = "+Sent"
+set postponed = "+Drafts"
+set trash = "+Trash"
--- /dev/null
+include:
+ - mutt.mutt--install-packages
+ - mutt.mutt--configure
--- /dev/null
+{% set users = salt['cmd.run']('getent passwd | grep /home | cut -d: -f1').splitlines() %}
+{% set maildirs = ['INBOX', 'Sent', 'Trash', 'Drafts'] %}
+
+{% for user in users %}
+
+mutt--configure-{{ user }}-muttrc:
+ file.managed:
+ - name: /home/{{ user }}/.muttrc
+ - source: salt://mutt/files/muttrc
+ - template: jinja
+ - user: {{ user }}
+ - group: {{ user }}
+ - mode: 644
+
+mutt--create-maildir-folders:
+ file.directory:
+ - user: {{ user }}
+ - group: {{ user }}
+ - mode: 755
+ - makedirs: True
+ - names:
+ {%- for folder in maildirs %}
+ - /home/{{ user }}/Maildir/{{ folder }}/cur
+ - /home/{{ user }}/Maildir/{{ folder }}/new
+ - /home/{{ user }}/Maildir/{{ folder }}/tmp
+ {%- endfor %}
+
+{% endfor %}
--- /dev/null
+mutt--install-packages:
+ pkg.installed:
+ - pkgs:
+ - mutt
--- /dev/null
+{%- if grains['id'] in ['mailserver', 'mailforwarding'] -%}
+compatibility_level = 3.6
+delay_warning_time = 4h
+disable_vrfy_command = yes
+
+home_mailbox = Maildir/INBOX/
+mailbox_size_limit = 0
+
+milter_default_action = accept
+
+mydestination = $myhostname, $mydomain, localhost.localdomain, localhost
+mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
+
+non_smtpd_milters = inet:127.0.0.1:8891, inet:127.0.0.1:8893
+postscreen_bare_newline_action = enforce
+postscreen_bare_newline_enable = yes
+postscreen_dnsbl_action = enforce
+postscreen_dnsbl_sites =
+ zen.spamhaus.org*3,
+ b.barracudacentral.org=127.0.0.[2..11]*2,
+ bl.spameatingmonkey.net*2,
+ bl.spamcop.net,
+ dnsbl.sorbs.net,
+ swl.spamhaus.org*-4,
+ list.dnswl.org=127.[0..255].[0..255].0*-2,
+ list.dnswl.org=127.[0..255].[0..255].1*-4,
+ list.dnswl.org=127.[0..255].[0..255].[2..3]*-6
+postscreen_dnsbl_threshold = 3
+postscreen_dnsbl_whitelist_threshold = -2
+postscreen_non_smtp_command_action = enforce
+postscreen_non_smtp_command_enable = yes
+postscreen_pipelining_enable = yes
+
+recipient_delimiter = +
+
+smtp_tls_CApath = /etc/ssl/certs
+smtp_tls_security_level = encrypt
+smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
+
+smtpd_banner = $myhostname ESMTP
+smtpd_discard_ehlo_keywords = silent-discard, dsn
+smtpd_helo_required = yes
+smtpd_milters = inet:127.0.0.1:8891, inet:127.0.0.1:8893
+smtpd_recipient_restrictions =
+ reject_non_fqdn_sender,
+ reject_non_fqdn_recipient,
+ reject_unknown_sender_domain,
+ reject_unknown_recipient_domain,
+ reject_unknown_helo_hostname,
+ reject_unknown_client_hostname,
+ reject_plaintext_session
+smtpd_tls_cert_file = /etc/letsencrypt/live/{{ pillar['common']['fqdn'] }}/fullchain.pem
+smtpd_tls_key_file = /etc/letsencrypt/live/{{ pillar['common']['fqdn'] }}/privkey.pem
+smtpd_tls_mandatory_ciphers = high
+smtpd_tls_mandatory_protocols = >=TLSv1.3
+smtpd_tls_security_level = encrypt
+
+virtual_alias_maps = hash:/etc/postfix/virtual
+{%- else -%}
+compatibility_level = 3.6
+delay_warning_time = 4h
+disable_vrfy_command = yes
+
+inet_interfaces = loopback-only
+mydestination = $myhostname, localhost.localdomain, localhost
+mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
+
+smtp_tls_CApath = /etc/ssl/certs
+smtp_tls_security_level = encrypt
+smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
+smtpd_recipient_restrictions = reject
+
+smtpd_tls_cert_file = /etc/letsencrypt/live/{{ pillar['common']['fqdn'] }}/fullchain.pem
+smtpd_tls_key_file = /etc/letsencrypt/live/{{ pillar['common']['fqdn'] }}/privkey.pem
+
+smtpd_tls_mandatory_ciphers = high
+smtpd_tls_mandatory_protocols = >=TLSv1.3
+smtpd_tls_security_level = encrypt
+{%- endif -%}
--- /dev/null
+#
+# Postfix master process configuration file. For details on the format
+# of the file, see the master(5) manual page (command: "man 5 master" or
+# on-line: http://www.postfix.org/master.5.html).
+#
+# Do not forget to execute "postfix reload" after editing this file.
+#
+# ==========================================================================
+# service type private unpriv chroot wakeup maxproc command + args
+# (yes) (yes) (no) (never) (100)
+# ==========================================================================
+#smtp inet n - y - - smtpd
+smtp inet n - y - 1 postscreen
+smtpd pass - - y - - smtpd
+dnsblog unix - - y - 0 dnsblog
+tlsproxy unix - - y - 0 tlsproxy
+# Choose one: enable submission for loopback clients only, or for any client.
+#127.0.0.1:submission inet n - y - - smtpd
+
+#submission inet n - y - - smtpd
+# -o syslog_name=postfix/submission
+# -o smtpd_tls_security_level=encrypt
+# -o smtpd_sasl_auth_enable=yes
+# -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
+
+
+#submission inet n - y - - smtpd
+# -o syslog_name=postfix/submission
+# -o smtpd_tls_security_level=encrypt
+# -o smtpd_sasl_auth_enable=yes
+# -o smtpd_tls_auth_only=yes
+# -o smtpd_reject_unlisted_recipient=no
+# Instead of specifying complex smtpd_<xxx>_restrictions here,
+# specify "smtpd_<xxx>_restrictions=$mua_<xxx>_restrictions"
+# here, and specify mua_<xxx>_restrictions in main.cf (where
+# "<xxx>" is "client", "helo", "sender", "relay", or "recipient").
+# -o smtpd_client_restrictions=
+# -o smtpd_helo_restrictions=
+# -o smtpd_sender_restrictions=
+# -o smtpd_relay_restrictions=
+# -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
+# -o milter_macro_daemon_name=ORIGINATING
+# Choose one: enable submissions for loopback clients only, or for any client.
+#127.0.0.1:submissions inet n - y - - smtpd
+#submissions inet n - y - - smtpd
+# -o syslog_name=postfix/submissions
+# -o smtpd_tls_wrappermode=yes
+# -o smtpd_sasl_auth_enable=yes
+# -o smtpd_reject_unlisted_recipient=no
+# Instead of specifying complex smtpd_<xxx>_restrictions here,
+# specify "smtpd_<xxx>_restrictions=$mua_<xxx>_restrictions"
+# here, and specify mua_<xxx>_restrictions in main.cf (where
+# "<xxx>" is "client", "helo", "sender", "relay", or "recipient").
+# -o smtpd_client_restrictions=
+# -o smtpd_helo_restrictions=
+# -o smtpd_sender_restrictions=
+# -o smtpd_relay_restrictions=
+# -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
+# -o milter_macro_daemon_name=ORIGINATING
+#628 inet n - y - - qmqpd
+pickup unix n - y 60 1 pickup
+cleanup unix n - y - 0 cleanup
+qmgr unix n - n 300 1 qmgr
+#qmgr unix n - n 300 1 oqmgr
+tlsmgr unix - - y 1000? 1 tlsmgr
+rewrite unix - - y - - trivial-rewrite
+bounce unix - - y - 0 bounce
+defer unix - - y - 0 bounce
+trace unix - - y - 0 bounce
+verify unix - - y - 1 verify
+flush unix n - y 1000? 0 flush
+proxymap unix - - n - - proxymap
+proxywrite unix - - n - 1 proxymap
+smtp unix - - y - - smtp
+relay unix - - y - - smtp
+ -o syslog_name=postfix/$service_name
+# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
+showq unix n - y - - showq
+error unix - - y - - error
+retry unix - - y - - error
+discard unix - - y - - discard
+local unix - n n - - local
+virtual unix - n n - - virtual
+lmtp unix - - y - - lmtp
+anvil unix - - y - 1 anvil
+scache unix - - y - 1 scache
+postlog unix-dgram n - n - 1 postlogd
+#
+# ====================================================================
+# Interfaces to non-Postfix software. Be sure to examine the manual
+# pages of the non-Postfix software to find out what options it wants.
+#
+# Many of the following services use the Postfix pipe(8) delivery
+# agent. See the pipe(8) man page for information about ${recipient}
+# and other message envelope options.
+# ====================================================================
+#
+# maildrop. See the Postfix MAILDROP_README file for details.
+# Also specify in main.cf: maildrop_destination_recipient_limit=1
+#
+maildrop unix - n n - - pipe
+ flags=DRXhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
+#
+# ====================================================================
+# Recent Cyrus versions can use the existing "lmtp" master.cf entry.
+#
+# Specify in cyrus.conf:
+# lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4
+#
+# Specify in main.cf one or more of the following:
+# mailbox_transport = lmtp:inet:localhost
+# virtual_transport = lmtp:inet:localhost
+#
+# ====================================================================
+#
+# Cyrus 2.1.5 (Amos Gouaux)
+# Also specify in main.cf: cyrus_destination_recipient_limit=1
+#
+#cyrus unix - n n - - pipe
+# flags=DRX user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user}
+#
+# ====================================================================
+# Old example of delivery via Cyrus.
+#
+#old-cyrus unix - n n - - pipe
+# flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user}
+#
+# ====================================================================
+#
+# See the Postfix UUCP_README file for configuration details.
+#
+uucp unix - n n - - pipe
+ flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
+#
+# Other external delivery methods.
+#
+ifmail unix - n n - - pipe
+ flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
+bsmtp unix - n n - - pipe
+ flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
+scalemail-backend unix - n n - 2 pipe
+ flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
+mailman unix - n n - - pipe
+ flags=FRX user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py ${nexthop} ${user}
+
--- /dev/null
+{%- if pillar.get('mailtype') == 'mailserver' -%}
+@{{ pillar['common']['domain'] }} {{ pillar['users']['main']['account'] }}
+{%- elif pillar.get('mailtype') == 'mailforwarding' -%}
+@{{ pillar['common']['domain'] }} @{{ pillar['mail']['default_to'] }}
+{%- endif -%}
--- /dev/null
+include:
+ - postfix.postfix--install-packages
+ - postfix.postfix--configure
+ - postfix.postfix--systemd-service
--- /dev/null
+postfix--configure:
+ file.managed:
+ - user: root
+ - group: root
+ - mode: 644
+ - template: jinja
+ - names:
+ - /etc/postfix/main.cf:
+ - source: salt://postfix/files/main.cf
+ - /etc/postfix/master.cf:
+ - source: salt://postfix/files/master.cf
+ - /etc/postfix/virtual:
+ - source: salt://postfix/files/virtual
+ - require:
+ - postfix--install-packages
+
+include:
+ - postfix.postfix--update-virtualdb
--- /dev/null
+postfix--install-packages:
+ pkg.installed:
+ - pkgs:
+ - postfix
+ - rsyslog
--- /dev/null
+include:
+ - common.ufw
+
+postfix--systemd-service:
+ service.running:
+ - name: postfix
+ - enable: True
+ - reload: True
+ - watch:
+ - /etc/postfix/main.cf
+ - /etc/postfix/master.cf
+
+{% if grains['id'] in ['mailserver', 'mailforwarding'] %}
+
+postfix--ufw-allow-smtp:
+ cmd.run:
+ - name: ufw allow 25
+ - required:
+ - pkg: ufw--installed-packages
+
+{% endif %}
--- /dev/null
+postfix--update-virtual-db:
+ cmd.run:
+ - name: postmap /etc/postfix/virtual
+ - watch:
+ - file: /etc/postfix/virtual
--- /dev/null
+reboot--system-reboot:
+ module.run:
+ - name: system.reboot
--- /dev/null
+base:
+ '*':
+ - common.remove-unwanted-packages
+ - common.apparmor
+ - common.coredumps
+ - common.crontab
+ - common.debsums
+ - common.fail2ban
+ - common.ssh
+ - common.knockd
+ - common.logrotate
+ - common.unattended-upgrades
+ - common.ufw
+ - common.logwatch
+
+ 'mailserver':
+ - postfix
+ - dmarc-dkim
+ - mutt
+ - certbot
+ - bind9
+ - reboot
+
+ 'mailforwarding':
+ - postfix
+ - dmarc-dkim
+ - certbot
+ - bind9
+ - reboot
+
+ 'gitserver':
+ - postfix
+ - git
+ - gitweb
+ - certbot
+ - bind9
+ - reboot