diff options
Diffstat (limited to 'roles/common')
76 files changed, 2313 insertions, 2470 deletions
diff --git a/roles/common/files/etc/apt/apt.conf.d/50unattended-upgrades b/roles/common/files/etc/apt/apt.conf.d/50unattended-upgrades index c9adc5f..fd7cf1d 100644 --- a/roles/common/files/etc/apt/apt.conf.d/50unattended-upgrades +++ b/roles/common/files/etc/apt/apt.conf.d/50unattended-upgrades @@ -1,93 +1,164 @@ // Unattended-Upgrade::Origins-Pattern controls which packages are // upgraded. // -// Lines below have the format format is "keyword=value,...". A +// 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", "crontrib", "non-free") +// 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, "jessie") +// ${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). -// "o=Debian,n=jessie"; -// "o=Debian,n=jessie-updates"; -// "o=Debian,n=jessie-proposed-updates"; -// "o=Debian,n=jessie,l=Debian-Security"; + // 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"; - "origin=Debian,codename=${distro_codename}"; - "origin=Debian,codename=${distro_codename},label=Debian-Security"; +// "o=Debian Backports,a=${distro_codename}-backports,l=Debian Backports"; }; -// List of packages to not update (regexp are supported) +// Python regular expressions, matching packages to exclude from upgrading Unattended-Upgrade::Package-Blacklist { -// "vim"; -// "libc6"; -// "libc6-dev"; -// "libc6-i686"; + // 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 "false"; +//Unattended-Upgrade::AutoFixInterruptedDpkg "true"; // Split the upgrade into the smallest possible chunks so that -// they can be interrupted with SIGUSR1. This makes the upgrade +// 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 unattended-upgrades when the machine is shuting down -// instead of doing it in the background while the machine is running -// This will (obviously) make shutdown slower -//Unattended-Upgrade::InstallOnShutdown "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 "admin@fripost.org"; -// Set this value to "true" to get emails only on errors. Default -// is to always send a mail if Unattended-Upgrade::Mail is set -//Unattended-Upgrade::MailOnlyOnError "true"; +// 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 "on-change"; + +// 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 new unused dependencies after the upgrade +// 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 "false"; // Automatically reboot *WITHOUT CONFIRMATION* if -// the file /var/run/reboot-required is found after the upgrade +// 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 256kb/sec Acquire::http::Dl-Limit "256"; + +// 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"; diff --git a/roles/common/files/etc/apt/listchanges.conf b/roles/common/files/etc/apt/listchanges.conf index dc31f5e..cee0648 100644 --- a/roles/common/files/etc/apt/listchanges.conf +++ b/roles/common/files/etc/apt/listchanges.conf @@ -1,6 +1,9 @@ [apt] frontend=mail email_address=admin@fripost.org confirm=0 save_seen=/var/lib/apt/listchanges.db which=news +email_format=text +headers=false +reverse=false diff --git a/roles/common/files/etc/default/rkhunter b/roles/common/files/etc/default/rkhunter index da59a73..2e7fae7 100644 --- a/roles/common/files/etc/default/rkhunter +++ b/roles/common/files/etc/default/rkhunter @@ -1,34 +1,34 @@ # Defaults for rkhunter automatic tasks # sourced by /etc/cron.*/rkhunter and /etc/apt/apt.conf.d/90rkhunter # # This is a POSIX shell fragment # # Set this to yes to enable rkhunter daily runs -# (default: true) +# (default: false) CRON_DAILY_RUN="yes" # Set this to yes to enable rkhunter weekly database updates -# (default: true) +# (default: false) CRON_DB_UPDATE="yes" # Set this to yes to enable reports of weekly database updates # (default: false) DB_UPDATE_EMAIL="false" # Set this to the email address where reports and run output should be sent # (default: root) REPORT_EMAIL="admin@fripost.org" # Set this to yes to enable automatic database updates # (default: false) APT_AUTOGEN="false" # Nicenesses range from -20 (most favorable scheduling) to 19 (least favorable) # (default: 0) NICE="10" # Should daily check be run when running on battery # powermgmt-base is required to detect if running on battery or on AC power # (default: false) -RUN_CHECK_ON_BATTERY="false" +RUN_CHECK_ON_BATTERY="false" diff --git a/roles/common/files/etc/fail2ban/action.d/nftables-allports.local b/roles/common/files/etc/fail2ban/action.d/nftables-allports.local new file mode 100644 index 0000000..3b9ebc8 --- /dev/null +++ b/roles/common/files/etc/fail2ban/action.d/nftables-allports.local @@ -0,0 +1,16 @@ +[Definition] +# No need to create sets and rules, these are defined globally in nftables.conf +actionstart = +actionstop = +actioncheck = + +# unbanning is taken care of by setting a timeout on the nft set already +actionunban = + +[Init] +# With banaction = *-allports there is no need for separate rule names +table = filter +addr_set = fail2ban + +[Init?family=inet6] +addr_set = fail2ban6 diff --git a/roles/common/files/etc/fail2ban/fail2ban.local b/roles/common/files/etc/fail2ban/fail2ban.local new file mode 100644 index 0000000..23a92e9 --- /dev/null +++ b/roles/common/files/etc/fail2ban/fail2ban.local @@ -0,0 +1,9 @@ +[Definition] + +# Options: dbfile +# Notes.: Set the file for the fail2ban persistent data to be stored. +# A value of ":memory:" means database is only stored in memory +# and data is lost when fail2ban is stopped. +# A value of "None" disables the database. +# Values: [ None :memory: FILE ] Default: /var/lib/fail2ban/fail2ban.sqlite3 +dbfile = None diff --git a/roles/common/files/etc/fail2ban/filter.d/nextcloud.conf b/roles/common/files/etc/fail2ban/filter.d/nextcloud.conf new file mode 100644 index 0000000..22305d6 --- /dev/null +++ b/roles/common/files/etc/fail2ban/filter.d/nextcloud.conf @@ -0,0 +1,6 @@ +# Source: https://github.com/nextcloud/vm/blob/master/apps/fail2ban.sh + +[Definition] +failregex=(?:^{|,)\"message\":\"Login failed: <F-USER>.*?</F-USER> \(Remote IP: '<HOST>'\)\"(:?,|}$) + (?:^{|,)\"message\":\"Login failed: <F-USER>.*?</F-USER> \(Remote IP: <HOST>\)\"(:?,|}$) + (?:^{|,)\"remoteAddr\":\"<HOST>\",.*Trusted domain error diff --git a/roles/common/files/etc/fail2ban/filter.d/roundcube.conf b/roles/common/files/etc/fail2ban/filter.d/roundcube.conf deleted file mode 100644 index c8cb5d3..0000000 --- a/roles/common/files/etc/fail2ban/filter.d/roundcube.conf +++ /dev/null @@ -1,16 +0,0 @@ -[Definition] - -# Option: failregex -# Notes.: regex to match the password failures messages in the logfile. The -# host must be matched by a group named "host". The tag "<HOST>" can -# be used for standard IP/hostname matching and is only an alias for -# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+) -# Values: TEXT -# -failregex = IMAP Error: Login failed for \S+ from <HOST>\. AUTHENTICATE \S+: Authentication failed\. - -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# -ignoreregex = diff --git a/roles/common/files/etc/initramfs-tools/conf.d/resume b/roles/common/files/etc/initramfs-tools/conf.d/resume new file mode 100644 index 0000000..213a0e2 --- /dev/null +++ b/roles/common/files/etc/initramfs-tools/conf.d/resume @@ -0,0 +1 @@ +RESUME=none diff --git a/roles/common/files/etc/logcheck/ignore.d.server/common-local b/roles/common/files/etc/logcheck/ignore.d.server/common-local index 769e326..3a4cb36 100644 --- a/roles/common/files/etc/logcheck/ignore.d.server/common-local +++ b/roles/common/files/etc/logcheck/ignore.d.server/common-local @@ -1,40 +1,138 @@ # Ansible Managed # Do NOT edit this file directly! # -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: subsystem request for sftp by user [-_.[:alnum:]]+$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: User [-_.[:alnum:]]+ not allowed because account is locked$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: fatal: Read from socket failed: (Connection reset by peer|Connection timed out) \[preauth\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: (error: )?Received disconnect from [:.[:xdigit:]]+: (3|11|14): .* \[preauth\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Protocol major versions differ for [:.[:xdigit:]]+: SSH-2\.0-OpenSSH_ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Disconnecting: Change of username or service not allowed: \(\S+\) -> \(\S+\) \[preauth\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Disconnecting: Too many authentication failures for invalid user [-_.[:alnum:]]+ from [:.[:xdigit:]]+ port [[:digit:]]+ ssh2? \[preauth\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: userauth_pubkey: unsupported public key algorithm: [[:alnum:]-]+ \[preauth\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: fatal: Write failed: (Connection (timed out|reset by peer)|Broken pipe) \[preauth\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: fatal: (no hostkey alg|Unable to negotiate a key exchange method) \[preauth\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: fatal: no matching cipher found: client [.@[:alnum:]-]+(,[.@[:alnum:]-]+)* server [.@[:alnum:]-]+(,[.@[:alnum:]-]+)* \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: (error: )?Received disconnect from [:.[:xdigit:]]+ port [0-9]+:(3|11|14): .* \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: maximum authentication attempts exceeded for invalid user .* from [:.[:xdigit:]]+ port [0-9]+ ssh2 \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: (Disconnected from|Connection (closed|reset) by)( invalid user .*)? [[:xdigit:].:]{3,39} port [0-9]+( \[preauth\])?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: (Did not receive identification string|Invalid user .*) from [[:xdigit:].:]{3,39} port [0-9]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: (Disconnected from|Connection closed by) (invalid|authenticating) user .* \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Disconnecting (authenticating|invalid) user .* [[:xdigit:].:]{3,39} port [0-9]+: (Change of username or service not allowed: .* -> .*|Too many authentication failures) \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: ssh_dispatch_run_fatal: Connection from (invalid user .* )?[[:xdigit:].:]{3,39} port [0-9]+: (message authentication code incorrect|Connection corrupted|Broken pipe) \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Disconnected from user [a-z0-9]+ [[:xdigit:].:]{3,39} port [0-9]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Unable to negotiate with [:.[:xdigit:]]+ port [[:digit:]]+: no matching (host key type|key exchange method|cipher) found\. Their offer: [@.[:alnum:],-]+ \[preauth\]$ +no matching cipher found: client [.@[:alnum:]-]+(,[.@[:alnum:]-]+)* server [.@[:alnum:]-]+(,[.@[:alnum:]-]+)* \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Bad packet length [0-9]+\. \[preauth\]$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Bad protocol version identification '.*' from [:.[:xdigit:]]+ port [[:digit:]]+$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Accepted publickey for [^[:space:]]+ from [^[:space:]]+ port [[:digit:]]+( (ssh|ssh2))?(: (RSA|ECDSA|ED25519) ([[:xdigit:]]{2}:){15}[[:xdigit:]]{2})?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: WARNING: no suitable primes in /etc/ssh/primes$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: Bad remote protocol version identification: '.*'$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Corrupted MAC on input\. \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: Protocol major versions differ for [[:xdigit:].:]{3,39} port [0-9]+: .+ vs\. .+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: Protocol major versions differ: .+ vs\. .+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: banner exchange: Connection from [[:xdigit:].:]{3,39} port [0-9]+: could not read protocol version$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: userauth_pubkey: key type [-[:alnum:]]+ not in PubkeyAcceptedKeyTypes \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: kex_exchange_identification: Connection closed by remote host$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: kex_exchange_identification: read: Connection reset by peer$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: kex_exchange_identification: client sent invalid protocol identifier " +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: kex_exchange_identification: banner line contains invalid characters$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: kex_protocol_error: type [0-9]+ seq [0-9]+ \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: fatal: ssh_packet_send_debug: Broken pipe$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: send_error: write: Connection reset by peer$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: fatal: userauth_pubkey: parse request failed: incomplete message \[preauth\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: banner exchange: Connection from [[:xdigit:].:]{3,39} port [0-9]+: invalid format$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: error: beginning MaxStartups throttling$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: exited MaxStartups throttling after [0-9]{2}:[0-9]{2}:[0-9]{2}, [0-9]+ connections dropped$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: drop connection #[0-9]+ from \[[[:xdigit:].:]{3,39}\]:[0-9]+ on \[[[:xdigit:].:]{3,39}\]:[0-9]+ past MaxStartups$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sshd\[[[:digit:]]+\]: User .+ from [[:xdigit:].:]{3,39} not allowed because none of user's groups are listed in AllowGroups$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Start(ing|ed) Cleanup of Temporary Directories\.(\.\.)?$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ slapd\[[[:digit:]]+\]: connection_input: conn=[[:digit:]]+ deferring operation: binding$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (slapd\[[[:digit:]]+\]|slap(acl|add|auth|cat|dn|index)|ldap(add|compare|delete|exop|modify|modrdn|passwd|search|url|whoami)): DIGEST-MD5 common mech free$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sudo:[[:space:]]+[_[:alnum:].-]+ : TTY=(unknown|(pts/|tty|vc/)[[:digit:]]+) ; PWD=[^;]+ ; USER=[._[:alnum:]-]+ (; ENV=([_a-zA-Z]+=\S* )+)?; COMMAND=(/(usr|etc|bin|sbin)/|sudoedit ) -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: bytecode\.(cld|cvd) (is up to date|updated) \(version: [[:digit:]]+, sigs: [[:digit:]]+, f-level: [[:digit:]]+, builder: [._[:alnum:]-]+\)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: WARNING: Your ClamAV installation is OUTDATED!$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: WARNING: Local version: [[:digit:]]+(\.[[:digit:]]+)* Recommended version: [[:digit:]]+(\.[[:digit:]]+)*$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: (Created|Removed) slice User Slice of UID [-[:alnum:]]+\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[[0-9]+\]: (Listening on|Closed) .*\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Starting (Cleanup of Temporary Directories|Daily man-db regeneration)\.\.\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Started (Cleanup of Temporary Directories|Daily man-db regeneration)\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Start(ing|ed) Session [0-9]+ of user [-[:alnum:]]+\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[[0-9]+\]: Startup finished in \S+\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd: pam_unix\(systemd-user:session\): session (opened|closed) for user [-[:alnum:]]+( by \(uid=0\))?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[[0-9]+\]: [-[:alnum:]\\_@]+\.(mount|scope|service|socket): Succeeded\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd(-[a-z]+)?\[[0-9]+\]: \[/[^]]+:[0-9]+\] Line references path below legacy directory /var/run/, updating /var/run/ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: /lib/systemd/system/[-[:alnum:]\\_@]+\.service:[0-9]+: PIDFile= references path below legacy directory /var/run/, updating /var/run/ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ runuser: pam_unix\(runuser:session\): session (opened|closed) for user [-[:alnum:]]+( by \(uid=0\))?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ CRON\[[0-9]+\]: pam_unix\(cron:session\): session (opened|closed) for user _?[-[:alnum:]]+(\(uid=[0-9]+\))?( by \(uid=0\))?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Start(ing|ed) Session [0-9]+ of user [-[:alnum:]]+\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd-logind\[[0-9]+\]: New session c?[0-9]+ of user [-[:alnum:]]+\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd-logind\[[0-9]+\]: Removed session c?[0-9]+\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd-logind\[[0-9]+\]: Session [0-9]+ logged out\. Waiting for processes to exit\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: apt-daily(-upgrade)?\.timer: Adding .* random time\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Starting Daily apt-listbugs preferences cleanup\.\.\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Finished (Daily apt-listbugs preferences cleanup|Cleanup of Temporary Directories|Autocommit of changes in /etc directory|Clean php session files|Launch apticron to notify of packages pending an update|Online ext4 Metadata Check for All Filesystems|Autocommit of changes in /etc directory)\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: [[:alnum:]@-]+\.(service|scope): Consumed ([0-9]+min )?[0-9.]+s CPU time\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: rsyslog\.service: Sent signal SIGHUP to main process [0-9]+ \(rsyslogd\) on client request\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sudo:[[:space:]]+[_[:alnum:].-]+ : (TTY=(unknown|(pts/|tty|vc/)[[:digit:]]+) ; )?PWD=[^;]+ ; USER=[._[:alnum:]-]+ (; ENV=([_a-zA-Z]+=\S* )+)?; COMMAND=(/(usr|etc|bin|sbin)/|sudoedit ) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> daily database available for update \(local version: [[:digit:]]+, remote version: [[:digit:]]+\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> (bytecode|main|daily)\.(cld|cvd) (database )?(is up to date|is up-to-date|updated) \(version: [[:digit:]]+, sigs: [[:digit:]]+, f-level: [[:digit:]]+, builder: [._[:alnum:]-]+\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Testing database: '/var/lib/clamav/tmp[^/]*/clamav-.*' \.\.\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Database test passed\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Received signal: wake up$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> ClamAV update process started at \w{3} \w{3} [ :[:digit:]]{16}$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: (\w{3} \w{3} [ :[:digit:]]{16} -> \^|WARNING: )Your ClamAV installation is OUTDATED!$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: (\w{3} \w{3} [ :[:digit:]]{16} -> \^|WARNING: )Local version: [[:digit:]]+(\.[[:digit:]]+)* Recommended version: [[:digit:]]+(\.[[:digit:]]+)*$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: WARNING: getfile: [._[:alnum:]-]+ not found on remote server \(IP: [.[:digit:]]+\)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: WARNING: Incremental update failed, trying to download daily\.cvd$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: (WARNING|ERROR): (getpatch: )?Can't download [._[:alnum:]-]+ from [.[:alnum:]-]+$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: Trying host [.[:alnum:]-]+ \([.[:digit:]]+\)\.\.\.$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: Trying again in [[:digit:]]+ secs\.\.\.$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: Giving up on [.[:alnum:]-]+\.\.\.$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: Downloading [._[:alnum:]-]+ \[[[:digit:]]+%\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: DON'T PANIC! Read http://www\.clamav\.net/support/faq$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> \*Can't query [._[:alnum:]-]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Downloading [._[:alnum:]-]+ \[[[:digit:]]+%\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> DON'T PANIC! Read https?://www\.clamav\.net/(support/faq|documents/upgrading-clamav)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> DON'T PANIC! Read https://docs\.clamav\.net/manual/Installing\.html$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[0-9]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Database updated \([0-9]+ signatures\) from .* \(IP: [[:xdigit:].:]{3,39}\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[0-9]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Clamd successfully notified about the update\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ freshclam\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Received signal: re-opening log file$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ clamd\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Reading databases from /var/lib/clamav$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ clamd\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> SelfCheck: (Database status OK|Database modification detected\. Forcing reload)\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ clamd\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Database correctly reloaded \([0-9]+ signatures\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ clamd\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> SIGHUP caught: re-opening log file\.$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ clamd\[[[:digit:]]+\]: \w{3} \w{3} [ :[:digit:]]{16} -> Activating the newly loaded database\.\.\.$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ kernel: \[ *[[:digit:]]+\.[[:digit:]]+ *\] Peer [.[:digit:]]+:[[:digit:]]+/[[:digit:]]+ unexpectedly shrunk window [[:digit:]]+:[[:digit:]]+ \(repaired\)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rsyslogd: \[origin software="rsyslogd" swVersion="[.[:digit:]]+" x-pid="[[:digit:]]+" x-info="http://www.rsyslog.com"\] rsyslogd was HUPed$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rsyslogd-?([[:digit:]]+): action '[^']+' (resumed \(module '[.[:alnum:]-]+:[.[:alnum:]-]+'\)|suspended, next retry is \w{3} \w{3} [ :[:digit:]]{16}) \[try http://www\.rsyslog\.com/e/\1 \]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ansible-([_a-z]+|<stdin>): Invoked with -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (sympa\((command|distribute)\)|wwsympa|archived|bounced|bulk|task_manager)\[[[:digit:]]+\]: (info|notice)\s -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[[:digit:]]+\]: err .* main::check_action_parameters\(\) user not logged in$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rsyslogd: \[origin software="rsyslogd" swVersion="[0-9.]+" x-pid="[0-9]+" x-info="https://www\.rsyslog\.com"\] rsyslogd was HUPed$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ smartd\[[0-9]+\]: Device: /dev/sd[a-z] \[SAT\], CHECK POWER STATUS spins up disk \(0x[0-9a-f]{2} -> 0xff\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ansible-([_a-z0-9.]+|<stdin>): Invoked with +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ python3(\.[0-9]+)?\[[0-9]+\]: ansible-[_a-z0-9.]+ Invoked with +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ fail2ban-server\[[0-9]+\]: fail2ban\.filter\s*\[[0-9]+\]: INFO\s+\[[._[:alnum:]-]+\] (Found [[:xdigit:].:]{3,39} - |Ignore [[:xdigit:].:]{3,39} by ip$) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ fail2ban-server\[[0-9]+\]: fail2ban\.actions\s*\[[0-9]+\]: NOTICE\s+\[[._[:alnum:]-]+\] (Ban|Unban) [[:xdigit:].:]{3,39} +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: notice Sympa::Request::Message:: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: notice Sympa::(Bulk|Spool)::store\(\) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: info Sympa::Spool::_create\(\) Creating directory /var/spool/sympa/auth +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: (info|notice) Sympa::Spindle::Process(Incoming|Message|Template|Digest):: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: info Sympa::Spindle::Do(Command|Message):: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: info Sympa::Request::Handler::(subscribe|confirm|reject|signoff|distribute)::_twist\(\) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: (info|notice) Sympa::Spindle::To(List|Moderation|Auth|Held):: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: notice Sympa::Spindle::AuthorizeMessage::_twist\(\) Message Sympa::Message .* rejected\(\) because sender not allowed$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: err main::#[0-9]+ > Sympa::Spindle::spin#[0-9]+ > +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ task_manager\[[0-9]+\]: (info|notice) main:: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ task_manager\[[0-9]+\]: (info|notice) Sympa::(Spindle::ProcessTask|Spool):: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info main:: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info Sympa::Ticket::load\(\) Ticket: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: notice main:: Redirecting to\s +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: notice main::do_login\(\) Authentication failed$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: err main::#[0-9]+ > main::do_login#[0-9]+ > Sympa::WWW::Auth::check_auth#[0-9]+ > Sympa::WWW::Auth::authentication#[0-9]+ Incorrect password for user\s +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: notice Sympa::WWW::Tools::_get_css_url\(\) Template file /usr/share/sympa/default/web_tt2/css\.tt2 or configuration has changed; updating CSS file /var/lib/sympa/css/[.[:alnum:]-]+/style\.css$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info Sympa::WWW::Session::new\(\) Ignoring unknown session cookie +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: err main::#[0-9]+ > main::get_parameters#[0-9]+ \[robot [.[:alnum:]-]+\] \[client [[:xdigit:].:]{3,39}\] Syntax error for parameter action value "(lists|search_list_request)#[^"]+" not conform to regexp: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: err main::#[0-9]+ > main::check_action_parameters#[0-9]+ \[robot [.[:alnum:]-]+\] \[session [[:xdigit:]]+\] \[client [[:xdigit:].:]{3,39}\] \[list [.[:alnum:]-]+\] User not logged in$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: err main::#[0-9]+ > main::do_arc#[0-9]+ \[robot [.[:alnum:]-]+\] \[session [[:xdigit:]]+\] \[client [[:xdigit:].:]{3,39}\] \[list [.[:alnum:]-]+\] Empty archive Sympa::Archive < +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: notice Sympa::Spindle::Process(Request|Template)::_twist\(\) Processing Sympa:: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info Sympa::Spindle::ToAuth:: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: notice Sympa::Bulk::store\(\) Message Sympa::Message::Template < +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (wwsympa|sympa_msg)\[[0-9]+\]: notice Sympa::Spool::Outgoing::store\(\) Message Sympa::Message::Template < +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: notice Sympa::Spool::store\(\) Sympa::Request < +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info Sympa::Request::Handler::(add|signoff|subscribe)::_twist\(\) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: info Sympa::Scenario::authz\(\) Sympa::Scenario <create_list\.[.[:alnum:]-]+;ERROR>: No rule match, reject$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[0-9]+\]: err main::#[0-9]+ > main::check_param_in#[0-9]+ > Sympa::Scenario::new#[0-9]+ Unable to find scenario file " +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sympa_msg\[[0-9]+\]: notice Sympa::Spool::Outgoing::store\(\) Message Sympa::Message <[^>]+> is stored into bulk spool as <[^>]+>$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ mysqld\[[0-9]+\]: [0-9: -]{19} [0-9]+ \[Warning\] Aborted connection [0-9]+ to db: '[^']+' user: '[^']+' host: 'localhost' \(Got (timeout|an error) reading communication packets\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bulk\[[0-9]+\]: notice main:: Bulk exited normally due to signal$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bulk\[[0-9]+\]: notice Sympa::Mailer::store\(\) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bulk\[[0-9]+\]: (info|notice) Sympa::Spindle::ProcessOutgoing:: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bounced\[[0-9]+\]: notice Sympa::Tracking::store\(\) Sympa::Message < +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bounced\[[0-9]+\]: notice Sympa::Spindle::ProcessBounce::_twist\(\) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bounced\[[0-9]+\]: info Sympa::Spindle::ProcessBounce::_twist\(\) No address found in message Sympa::Message < +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ archived\[[0-9]+\]: notice Sympa::Spindle::ProcessArchive:: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ archived\[[0-9]+\]: (info|notice) Sympa::Archive:: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ikiwiki\[[[:digit:]]+\]: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ikiwiki: \[Fripost wiki\] (invalid page|unknown do) parameter$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ unbound: \[[0-9]+:[0-9]+\] info: generate keytag query _ta-[[:xdigit:]]+\. NULL IN$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rrdcached\[[[:digit:]]+\]: (flushing old values|rotating journals|started new journal /\S+$|removing old journal /\S+$) ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rrdcached\[[[:digit:]]+\]: queue_thread_main: rrd_update_r \(([^)]+)\) failed with status -1. \(opening '\1': No such file or directory\) -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ stunnel: LOG3\[[[:digit:]]+\]: SSL_accept: (Peer suddenly disconnected|[[:xdigit:]]+: error:[[:xdigit:]]+:SSL routines:SSL2?3_GET_CLIENT_HELLO:(unknown protocol|http request))$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ auditd\[[[:digit:]]+\]: Audit daemon rotating log files$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dhclient\[[[:digit:]]+\]: DHCPREQUEST for [[:digit:].]{3,15} on [[:alnum:]]+ to [[:digit:].]{3,15} port 67$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ bacula-sd\[[[:digit:]]+\]: [._[:alnum:]-]+: askdir\.c:[0-9]+-[0-9]+ Discard: JobMedia Vol=[._[:alnum:]-]+ wrote=[0-9]+ MediaId=[0-9]+ FI=[0-9]+ LI=[0-9]+ StartAddr=[0-9]+ EndAddr=[0-9]+$ +### +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ slapd\[[[:digit:]]+\]: connection_read\([[:digit:]]+\): no connection!$ diff --git a/roles/common/files/etc/logcheck/ignore.d.server/dovecot-local b/roles/common/files/etc/logcheck/ignore.d.server/dovecot-local index 5f474ed..532a2a0 100644 --- a/roles/common/files/etc/logcheck/ignore.d.server/dovecot-local +++ b/roles/common/files/etc/logcheck/ignore.d.server/dovecot-local @@ -1,26 +1,23 @@ # Ansible Managed # Do NOT edit this file directly! # -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap\([-_.@[:alnum:]]+\): Disconnected(: Logged out| for inactivity( in reading our output)?|: Disconnected( in [[:upper:]]+)?| in [[:upper:]]+( \([[:digit:]]+ msgs, [[:digit:]]+ secs, [[:digit:]]+/[[:digit:]]+ bytes\))?|: Too many invalid IMAP commands\.|: IMAP session state is inconsistent, please relogin\.)? in=[[:digit:]]+ out=[[:digit:]]+$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: managesieve\([-_.@[:alnum:]]+\): Disconnected for inactivity bytes=[[:digit:]]+/[[:digit:]]+$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap\([-_.@[:alnum:]]+\): Connection closed(: Connection reset by peer)?( in=[[:digit:]]+ out=[[:digit:]]+)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap)-login: Login: user=<[^>]*>, method=[[:alnum:]-]+, rip=[.:[:xdigit:]]+, lip=[.:[:xdigit:]]+, mpid=[0-9]+(, (TLS|secured)(: Disconnected)?, session=<[^>]+>)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap)-login: Aborted login( \(auth failed, [[:digit:]]+ attempts in [[:digit:]]+ secs\))?: (user=<[^>]*>, method=[[:alnum:]-]+, )?rip=[.:[:xdigit:]]+, lip=[.:[:xdigit:]]+, TLS, session=<[^>]+>$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap|managesieve)-login: (Disconnected|Aborted login)(: Inactivity)? (\(no auth attempts in [[:digit:]]+ secs\):( user=<>,)?|\(auth failed, [[:digit:]]+ attempts in [[:digit:]]+ secs\): user=<[^>]*>, method=PLAIN,|\(aborted authentication\): method=PLAIN,) rip=[.:[:xdigit:]]+, lip=[.:[:xdigit:]]+(, (TLS|SSL)( handshaking)?(: SSL_(accept|read)\(\) (syscall failed: Connection reset by peer|failed: error:140940E5:SSL routines:SSL3_READ_BYTES:ssl handshake failure: SSL alert number 10|failed: error:14094412:SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate: SSL alert number 42|failed: error:14094416:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate unknown: SSL alert number 46|failed: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca: SSL alert number 48|failed: error:[[:xdigit:]]+:SSL routines:SSL2?3_GET_CLIENT_HELLO:(unknown protocol|unsupported protocol|http request|no shared cipher|wrong version number)|failed: error:[[:xdigit:]]+:SSL routines:SSL_BYTES_TO_CIPHER_LIST:inappropriate fallback)|: Disconnected)?|, secured)?, session=<[^>]+>$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: auth: Warning: auth client [[:digit:]]+ disconnected with [[:digit:]]+ pending requests: EOF$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap)-login: Warning: Auth connection closed with [[:digit:]]+ pending requests \(max [[:digit:]]+ secs, pid=[[:digit:]]+, EOF\)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap)-login: Disconnected \((auth process communication failure|client didn't finish SASL auth, waited [[:digit:]]+ secs)\): user=<>, method=PLAIN, rip=[.:[:xdigit:]]+, lip=[.:[:xdigit:]]+(, (TLS|secured)(: SSL_read\(\) syscall failed: Connection reset by peer|: Disconnected)?, session=<[^>]+>)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap)-login: Error: SSL: Stacked error: error:140943F2:SSL routines:SSL3_READ_BYTES:sslv3 alert unexpected message: SSL alert number 10$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap-login: (Disconnected: Inactivity during authentication|Aborted login) \(client didn't finish SASL auth, waited [[:digit:]]+ secs\): user=<[^>]*>, method=[[:alnum:]-]+, rip=[.:[:xdigit:]]+, lip=[.:[:xdigit:]]+(, (TLS|secured)(: Disconnected)?, session=<[^>]+>)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap|managesieve)-login: Disconnected \(tried to use unsupported auth mechanism\): user=<>, method=[[:alnum:]-]+, rip=[.:[:xdigit:]]+, lip=[.:[:xdigit:]]+(, (TLS|secured), session=<[^>]+>)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([0-9]+, [-_.@[:alnum:]]+\): [^:]{22}: msgid=<?.*>?( \((added by [^[:space:]]+|sfid-[_[:xdigit:]]+)\)?)?[[:space:]]*: (saved mail to [-_.[:alnum:]]+|(forwarded|discarded duplicate forward) to <[^[:space:]]+>)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap|managesieve)-login: Maximum number of connections from user\+IP exceeded \(mail_max_userip_connections=[[:digit:]]+\): user=<[^>]*>, method=[[:alnum:]-]+, rip=[.:[:xdigit:]]+, lip=[.:[:xdigit:]]+(, (TLS|secured), session=<[^>]+>)?$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([-_.@[:alnum:]]+\): Connect from local$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([-_.@[:alnum:]]+\): Disconnect from local: (Client quit|Connection closed) \(in reset\)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([-_.@[:alnum:]]+, [^@]+@[^@]+\): [+/[:alnum:]]{22}: sieve: msgid=(\S+ )?|<[^>]*>( \(added by \S+\))?: (stored mail into mailbox '|marked message to be discarded if not explicitly delivered \(discard action\)$|forwarded to ) -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([-_.@[:alnum:]]+, [^@]+@[^@]+\): Error: [+/[:alnum:]]{22}: sieve: execution of script \S+ failed, but implicit keep was successful \(user logfile \S+ may reveal additional details\)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([0-9]+\): Disconnect from local: Successful quit$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap|managesieve)-login: Login: user=<[^>]*>, method=[[:alnum:]-]+, rip=[.:[:xdigit:]]+, lip=[.:[:xdigit:]]+, mpid=[0-9]+(, TLS, session=<[^>]+>)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: managesieve\([-_.@[:alnum:]]+\): Disconnected: Logged out bytes=[[:digit:]]+/[[:digit:]]+?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: ssl-params: (Generating SSL parameters|SSL parameters regeneration completed)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: stats: Error: Mail server input error: UPDATE-SESSION [-_.@[:alnum:]]+ imap: stats shrank: (mcache|mrcount|mrbytes) [[:digit:]]+ < [[:digit:]]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap\([-_.@[:alnum:]]+\)<[0-9]+><[+/[:alnum:]]+>: Connection closed(: read\(size=[0-9]+\) failed: Connection reset by peer)? \((((UID )?[[:alpha:]\-]* finished [0-9.]+ secs ago|IDLE running for [^\)]+, state=wait-input|No commands sent)\))?( in=[0-9]+ out=[0-9]+ deleted=[0-9]+ expunged=[0-9]+ trashed=[0-9]+ hdr_count=[0-9]+ hdr_bytes=[0-9]+ body_count=[0-9]+ body_bytes=[0-9]+)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap\(.+\)<[0-9]+><[+/[:alnum:]]+>(: Disconnected)?(: Logged out| for inactivity( in reading our output)?|: Disconnected in [[:upper:]]+ \([0-9]+ msgs, [0-9]+ secs, [0-9]+/[0-9]+ bytes\)|: Too many invalid IMAP commands\.)?( in=[0-9]+ out=[0-9]+ deleted=[0-9]+ expunged=[0-9]+ trashed=[0-9]+ hdr_count=[0-9]+ hdr_bytes=[0-9]+ body_count=[0-9]+ body_bytes=[0-9]+)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap: Logged out in=[0-9]+ out=[0-9]+ deleted=0 expunged=0 trashed=0 hdr_count=0 hdr_bytes=0 body_count=0 body_bytes=0$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap\([-_.@[:alnum:]]+\)<[0-9]+><[+/[:alnum:]]+>: Connection closed(: (read\(size=[0-9]+\) failed: )?Connection reset by peer)?( \((LOGOUT,)?(UID )?[[:alpha:]\-]+ (running for|finished) [^\)]+\))? in=[0-9]+ out=[0-9]+ deleted=[0-9]+ expunged=[0-9]+ trashed=[0-9]+ hdr_count=[0-9]+ hdr_bytes=[0-9]+ body_count=[0-9]+ body_bytes=[0-9]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: imap-hibernate\([-_.@[:alnum:]]+\)<[0-9]+><[+/[:alnum:]]+>: Connection closed in=[0-9]+ out=[0-9]+ deleted=[0-9]+ expunged=[0-9]+ trashed=[0-9]+ hdr_count=[0-9]+ hdr_bytes=[0-9]+ body_count=[0-9]+ body_bytes=[0-9]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap|managesieve)-login: Login: user=<[^>]*>, method=[[:alnum:]-]+, rip=[[:xdigit:].:]{3,39}, lip=[[:xdigit:].:]{3,39}, mpid=[0-9]+, (TLS|secured)(: (read\(size=[0-9]+\) failed: )?Connection (closed|reset by peer))?, session=<[^>]+>$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: managesieve\([-_.@[:alnum:]]+\)<[0-9]+><[+/[:alnum:]]+>: Disconnected: Logged out bytes=[[:digit:]]+/[[:digit:]]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (imap|managesieve)-login: (Disconnected(: Inactivity)?|Aborted login) \(auth failed, [[:digit:]]+ attempts in [[:digit:]]+ secs\): user=<[^>]*>, method=[A-Z\-]+, rip=[[:xdigit:].:]{3,39}, lip=[[:xdigit:].:]{3,39}, (TLS|SSL|secured)[:,] +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (imap|managesieve)-login: Disconnected \((no auth attempts in|disconnected before auth was ready, waited) [[:digit:]]+ secs\):( user=<>,)? rip=[[:xdigit:].:]{3,39}, lip=[[:xdigit:].:]{3,39}, (TLS|SSL)( handshaking)?: (SSL_accept\(\)( syscall)? failed:|(read\(size=[0-9]+\) failed: )?Connection (closed|reset by peer), session=<[+/[:alnum:]]+>$|SSL_read failed: error:[[:xdigit:]]+:SSL routines:(ssl3_get_record:decryption failed or bad record mac|ssl3_read_bytes:unexpected record), session=<[+/[:alnum:]]+>$) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (imap|managesieve)-login: (Disconnected(: (Inactivity|Too many invalid commands\.?))?|Aborted login) \(no auth attempts in [[:digit:]]+ secs\):( user=<>,)? rip=[[:xdigit:].:]{3,39}, lip=[[:xdigit:].:]{3,39}(, (TLS|SSL)( handshaking)?)?, session=<[+/[:alnum:]]+>$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap)-login: Disconnected(: Inactivity during authentication)? \(client didn't finish SASL auth, waited [[:digit:]]+ secs\): user=<>, method=[[:alnum:]-]+, rip=[[:xdigit:].:]{3,39}, lip=[[:xdigit:].:]{3,39}, TLS(: (read\(size=[0-9]+\) failed: Connection reset by peer|Disconnected|Connection closed))?, session=<[^>]+>$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([-_.@[:alnum:]]+\)<[0-9]+><[+/[:alnum:]]{22}(:[0-9]+)?>: msgid=(\? )?(<[^>]*>|[^[:blank:]]*|[^,()]+@[.[:alnum:]-]+)( \(added by \S+@[.[:alnum:]-]+\))?: saved mail to\s +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([-_.@[:alnum:]]+\)<[0-9]+><[+/[:alnum:]]{22}(:[0-9]+)?>: sieve: msgid=(\? )?(<[^>]*>\s*|[^[:blank:]]*|[^,()]+@[.[:alnum:]-]+)( \(added by \S+@[.[:alnum:]-]+\)| [[:alnum:]]+ action)?: (stored mail into mailbox '|(forwarded|discarded duplicate forward) to <[^[:space:]]+>$|Marked message to be discarded if not explicitly delivered \(discard action\)$) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([^@]+@[^@]+\)<[0-9]+><[+/[:alnum:]]{22}(:[0-9]+)?>: sieve: Execution of script \S+ failed, but implicit keep was successful \(user logfile \S+ may reveal additional details\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: (pop3|imap|managesieve)-login: Maximum number of connections from user\+IP exceeded \(mail_max_userip_connections=[[:digit:]]+\): user=<[^>]*>, method=[[:alnum:]-]+, rip=[[:xdigit:].:]{3,39}, lip=[[:xdigit:].:]{3,39}(, TLS, session=<[^>]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: lmtp\([0-9]+\): Disconnect from local: (Client has quit the connection|Remote closed connection) \(state=[[:upper:]]+\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: auth: Warning: auth client [0-9]+ disconnected with [0-9]+ pending requests: (Connection reset by peer|EOF)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: stats: Warning: UPDATE-CMD: Already expired$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Start(ing|ed) Dovecot authentication proxy\.(\.\.)?$ diff --git a/roles/common/files/etc/logcheck/ignore.d.server/postfix-local b/roles/common/files/etc/logcheck/ignore.d.server/postfix-local index 4364197..dcc1198 100644 --- a/roles/common/files/etc/logcheck/ignore.d.server/postfix-local +++ b/roles/common/files/etc/logcheck/ignore.d.server/postfix-local @@ -1,97 +1,133 @@ # Ansible Managed # Do NOT edit this file directly! # -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix/local\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^[:space:]]+>,( orig_to=<[^[:space:]]+>,)? relay=local, delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=2(\.[[:digit:]]+){2})?, status=sent \(forwarded as [[:xdigit:]]{10}\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix/local\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,)? relay=local, delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=2(\.[[:digit:]]+){2})?, status=sent \(forwarded as [[:xdigit:]]{10}\)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/postfix-script\[[[:digit:]]+\]: refreshing the Postfix mail system$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/master[[[:digit:]]+]: reload -- version [.[:digit:]]+, configuration /etc/postfix$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/smtpd\[[[:digit:]]+\]: (dis)?connect from [^[:space:]]+$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: [45][[:digit:]][[:digit:]] [45](\.[[:digit:]]+){2} <[^>]+>: Recipient address rejected: ((unverified|undeliverable) address:|Domain not found;) -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/[ls]mtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^[:space:]]+>,( orig_to=<[^[:space:]]+>,)? relay=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\](:[[:digit:]]{1,5})?, (conn_use=[[:digit:]]+, )?delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=2(\.[[:digit:]]+){2})?, status=(sent|deliverable) \(2[[:digit:]][[:digit:]] .+\)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/anvil\[[[:digit:]]+\]: statistics: max (message|recipient|connection) (count|rate) [/[:digit:]s]+ for \(([.:[:xdigit:]]+)?(smtp[sd]?|25|submission|587)?:([.:[:xdigit:]]+|unknown)\) at \w{3} [ :[:digit:]]{11}$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/[ls]mtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,)? relay=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\](:[[:digit:]]{1,5})?, (conn_use=[[:digit:]]+, )?delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=2(\.[[:digit:]]+){2})?, status=(sent|deliverable) \(2[[:digit:]][[:digit:]] .+\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/anvil\[[[:digit:]]+\]: statistics: max (message|recipient|connection) (count|rate) [/[:digit:]s]+ for \((\[[.:[:xdigit:]]+\]:)?(smtp[sd]?|25|submissions?|587|465)?:([.:[:xdigit:]]+|unknown)\) at \w{3} [ :[:digit:]]{11}$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/anvil\[[[:digit:]]+\]: statistics: max cache size [[:digit:]]+ at \w{3} [ :[:digit:]]{11}$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/scache\[[[:digit:]]+\]: statistics: start interval \w{3} [ :[:digit:]]{11}$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/scache\[[[:digit:]]+\]: statistics: (domain|address) lookup hits=[[:digit:]]+ miss=[[:digit:]]+ success=[[:digit:]]+%$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/scache\[[[:digit:]]+\]: statistics: max simultaneous domains=[[:digit:]]+ addresses=[[:digit:]]+ connection=[[:digit:]]+$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: client=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/cleanup\[[[:digit:]]+\]: [[:xdigit:]]+: (resent-|)message-id=(<[^>]*>|[[:alnum:]_/+.@-]+)( \(added by [^[:space:]]+\))?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: from=<[^[:space:]]*>, size=[[:digit:]]+, nrcpt=[[:digit:]]+ \(queue active\)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/n?qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: from=<.*>, status=expired, returned to sender$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/n?qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: message-id=(<[^>]*>|[[:alnum:]_/+.@-]+)( \(added by [^[:space:]]+\))? +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/cleanup\[[[:digit:]]+\]: [[:xdigit:]]+: (resent-)?message-id=([^[:blank:]]*|(mid:)?[[:alnum:]_/+.$@-]+|[^,()]+@[.[:alnum:]-]+)( \(added by [^[:space:]]+\))?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/cleanup\[[[:digit:]]+\]: warning: unix_trigger_event: read timeout for service public/qmgr$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/cleanup\[[[:digit:]]+\]: warning: milter unix:public/opendmarc: can't read SMFIC_BODYEOB reply packet header: Success$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: from=<[^>]*>, size=[[:digit:]]+, nrcpt=[[:digit:]]+ \(queue active\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/n?qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: from=<[^>]*>, status=expired, returned to sender$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/n?qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: message-id=(<[^>]*>|[[:alnum:]_/+.$@-]+)( \(added by [^[:space:]]+\))? ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/n?qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: removed$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/n?qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: skipped, still being delivered$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/verify\[[[:digit:]]+\]: close database /var/lib/postfix\1/verify_cache\.db: No such file or directory \(possible Berkeley DB bug\)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/verify\[[[:digit:]]+\]: cache btree:/var/lib/postfix\1/verify_cache full cleanup: retained=[[:digit:]]+ dropped=[[:digit:]]+ entries$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: lost connection after (AUTH|DATA \([[:digit:]]+ bytes\)) from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-\w+/smtpd\[[[:digit:]]+\]: lost connection after (CONNECT|STARTTLS) from [._[:alnum:]-]+\[([[:xdigit:].:]{3,39}|unknown)\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/verify\[[[:digit:]]+\]: cache [a-z]+:\S+ (partial|full) cleanup: retained=[[:digit:]]+ dropped=[[:digit:]]+ entries$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/smtpd\[[[:digit:]]+\]: disconnect from [._[:alnum:]-]+\[([[:xdigit:].:]{3,39}|unknown)\]( (ehlo|helo|xforward|starttls|auth|mail|rcpt|data|bdat|noop|rset|quit|commands|unknown)=[0-9]+(/[0-9]+)?)+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: warning: non-SMTP command from [-._[:alnum:]]+\[[[:xdigit:].:]{3,39}\]:\s +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/pickup\[[[:digit:]]+\]: [[:xdigit:]]+: uid=[[:digit:]]+ from=<[^>]*>$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/cleanup\[[[:digit:]]+\]: [[:xdigit:]]+: replace: header\s ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: client=[^[:space:]]+, sasl_method=[-[:alnum:]]+, sasl_username=[-_.@[:alnum:]]+(, sasl_sender=[-_.@[:alnum:]]+)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: warning: [-._[:alnum:]]+\[[.[:digit:]]+\]: SASL (PLAIN|LOGIN) authentication failed(:[ [:alnum:]]*)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: improper command pipelining after (EHLO|HELO|MAIL) from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: warning: [-._[:alnum:]]+\[[[:xdigit:].:]{3,39}\]: SASL [[:alpha:]]+ authentication (failed|aborted)(:|$) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: improper command pipelining after (CONNECT|EHLO|HELO|AUTH|MAIL|QUIT) from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: warning: hostname [._[:alnum:]-]+ does not resolve to address [[:xdigit:].:]{3,39}(: Name or service not known)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: warning: Connection concurrency limit exceeded: [0-9]+ from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] for service smtpd$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 5[[:digit:]]{2} 5(\.[[:digit:]]){2} <[^>]+>: Helo command rejected: need fully-qualified hostname;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^>]+>)? +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: warning: Connection concurrency limit exceeded: [0-9]+ from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] for service (submissions?|smtpd)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 5[[:digit:]]{2} 5(\.[[:digit:]]+){2} <[^>]+>: Helo command rejected: need fully-qualified hostname;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^>]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 4[[:digit:]]{2} 4(\.[[:digit:]]+){2} <[^>]+>: Sender address rejected: (Domain not found|Malformed DNS server reply);( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^>]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 5[[:digit:]]{2} 5(\.[[:digit:]]+){2} <[^>]+>: Sender address rejected: Domain [.[:alnum:]-]+ does not accept mail \(nullMX\);( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^>]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 5[[:digit:]]{2} 5(\.[[:digit:]]+){2} Service unavailable; (Unverified Client host|Sender address) \[\S+\] blocked using [._[:alnum:]-]+(; Listed by DBL, see https?://[^[:blank:];]+)?; from=<[^>]*> to=<[^>]+> proto=E?SMTP( helo=<[^>]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[([[:xdigit:].:]{3,39})\]: 4[[:digit:]]{2} 4(\.[[:digit:]]+){2} Client host rejected: cannot find your hostname, \[\1\]; from=<[^>]*> to=<[^>]+> proto=E?SMTP( helo=<[^>]+>)?$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: timeout after [-[:upper:]]+( \([[:digit:]]+ bytes\))? from [^[:space:]]+$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-((msa|mx)/smtpd|out/smtp)\[[[:digit:]]+\]: warning: (tls_text_name: [-._[:alnum:]]+\[[[:xdigit:].:]{3,39}\]: )?peer certificate has no (subject CN|issuer Organization)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 450( 4\.1\.2)? <[^>]*>: Recipient address rejected: Domain not found;( from=<[^>]*> to=<[^[:space:]]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 450( 4\.1\.8)? <[^>]*>: Sender address rejected: Domain not found;( from=<[^>]*> to=<[^[:space:]]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 504( 5\.5\.2)? <[^>]*>: (Recipient|Sender) address rejected: need fully-qualified address;( from=<[^>]*> to=<[^[:space:]]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 554 5\.7\.1 <[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]>: Client host rejected: Access denied;( from=<[^>]*> to=<[^[:space:]]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mda/lmtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^[:space:]]+>,( orig_to=<[^[:space:]]+>,)? relay=[._[:alnum:]-]+\[private/dovecot-lmtpd\],( conn_use=[[:digit:]]+,)? delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=2(\.[[:digit:]]+){2})?, status=sent \(2[[:digit:]][[:digit:]] .+\)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-\w+/(error|n?qmgr|smtp)\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^[:space:]]+>,( orig_to=<[^[:space:]]+>,)? relay=(none|[^[:space:]]+\[[[:xdigit:].:]{3,39}\]:[[:digit:]]+),( conn_use=[[:digit:]]+,)? delay=[[:digit:].]+,( delays=[[:digit:]./]+,)?( dsn=[45]\.[[:digit:]]\.[[:digit:]],)? status=(deferred|undeliverable|bounced) \((delivery temporarily suspended: )?((lost connection with [^[:space:]]+|conversation with [^[:space:]]+ timed out) while (sending [[:alnum:]]+( [[:alnum:]]+)?|performing the (HELO|EHLO) handshake|receiving the initial server greeting|sending [[:alnum:]]+( [/[:alnum:]]+)?|sending end of data -- message may be sent more than once)|connect to [^[:space:]]+: (Connection timed out|read timeout|Connection refused|Network is unreachable)|host [^[:space:]]+ refused to talk to me: [45][[:digit:]][[:digit:]].*|Host or domain name not found. Name service error for name=[^[:space:]]+ type=MX: Host not found, try again|User unknown in virtual alias table|host [^[:space:]]+\[[[:xdigit:].:]{3,39}\] said: [45][[:digit:]][[:digit:]] [45](\.[[:digit:]]+){2} <[^>]+>: (Temporarily rejected\. Try again later\.|Recipient address rejected: ((undeliverable|unverified) address:|Domain not found)) .*)\)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: lost connection with [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] while (receiving the initial server greeting|sending [[:upper:] ]+)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 450( 4\.1\.2)? <[^>]*>: Recipient address rejected: Domain not found;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 450( 4\.1\.8)? <[^>]*>: Sender address rejected: Domain not found;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: [[:upper:]]+ from [^[:space:]]+: 554( 5\.7\.1)? <>: Sender address rejected: Null sender not allowed; from=<> to=<[^>]+> proto=E?SMTP( helo=<[^[:space:]]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: [[:upper:]]+ from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 550( 5\.7\.23)? <[^>]+>: Sender address rejected: Message rejected due to: (domain owner discourages use of this host|SPF fail - not authorized)\. Please see https?://www\.openspf\.net/Why\?\S+; from=<[^>]+> to=<[^>]+> proto=E?SMTP( helo=<[^[:space:]]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ policyd-spf\[[[:digit:]]+\]: 550( 5\.7\.23)? Message rejected due to: (domain owner discourages use of this host|SPF fail - not authorized)\. Please see https?://www\.openspf\.net/Why\?\S+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 5[[:digit:]]{2} 5(\.[[:digit:]]+){2} <[^>]*>: (Recipient|Sender) address rejected: need fully-qualified address;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 554 5\.7\.1 <[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]>: Client host rejected: Access denied;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mda/lmtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,)? relay=[._[:alnum:]-]+\[private/dovecot-lmtpd\],( conn_use=[[:digit:]]+,)? delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=2(\.[[:digit:]]+){2})?, status=sent \(2[[:digit:]][[:digit:]] .+\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-\w+/(error|n?qmgr|smtp)\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,)? relay=(none|[^[:space:]]+\[[[:xdigit:].:]{3,39}\]:[[:digit:]]+),( conn_use=[[:digit:]]+,)? delay=[[:digit:].]+,( delays=[[:digit:]./]+,)?( dsn=[45]\.[[:digit:]]\.[[:digit:]],)? status=(deferred|undeliverable|bounced) \((delivery temporarily suspended: )?((lost connection with [^[:space:]]+|conversation with [^[:space:]]+ timed out) while (sending [[:alnum:]]+( [[:alnum:]]+)?|performing the (HELO|EHLO) handshake|receiving the initial server greeting|sending [[:alnum:]]+( [/[:alnum:]]+)?|sending end of data -- message may be sent more than once)|connect to [^[:space:]]+: (Connection timed out|read timeout|Connection refused|Network is unreachable|No route to host)|host [^[:space:]]+ refused to talk to me: [45][[:digit:]][[:digit:]].*|Host or domain name not found. Name service error for name=[^[:space:]]+ type=(MX|A|AAAA): Host (not found, try again|found but no data record of requested type)|User unknown in virtual alias table|host [^[:space:]]+\[[[:xdigit:].:]{3,39}\] said: [45][[:digit:]][[:digit:]] [45](\.[[:digit:]]+){2} <[^>]+>: (Temporarily rejected\. Try again later\.|Recipient address rejected: ((undeliverable|unverified) address:|Domain not found)) .*)\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,)? relay=[^[:space:]]+\[[[:xdigit:].:]{3,39}\]:[[:digit:]]+,( conn_use=[[:digit:]]+,)? delay=[[:digit:].]+,( delays=[[:digit:]./]+,)?( dsn=[45]\.[[:digit:]]\.[[:digit:]],)? status=undeliverable \(host +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: host [^[:space:]]+\[[[:xdigit:].:]{3,39}\]( said: 45[01][ -].* \(in reply to (MAIL FROM|RCPT TO) command\)| refused to talk to me: (421|450) ) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(out|msa)/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: lost connection with [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] while (receiving the initial server greeting|sending [[:upper:] ]+|performing the HELO handshake|sending end of data -- message may be sent more than once)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: conversation with [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] timed out while (sending message body|receiving the initial server greeting)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^[:space:]]+>(, orig_to=<[^[:space:]]+>)?, relay=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\](:[[:digit:]]{1,5})?,( conn_use=[[:digit:]]+,)? delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=[45](\.[[:digit:]]+){2})?, status=(deferred|bounced|undeliverable|SOFTBOUNCE) \(host [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] said: [45][[:digit:]][[:digit:]][- ]+.* \(in reply to (HELO|EHLO|MAIL FROM|RCPT TO|DATA|end of DATA) command\)\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>(, orig_to=<[^>]+>)?, relay=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\](:[[:digit:]]{1,5})?,( conn_use=[[:digit:]]+,)? delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=[45](\.[[:digit:]]+){2})?, status=(deferred|bounced|undeliverable|SOFTBOUNCE) \(host [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] said: [45][[:digit:]][[:digit:]][- ]+.* \(in reply to (HELO|EHLO|MAIL FROM|RCPT TO|DATA|end of DATA) command\)\)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: connect to [^[:space:]]+: (read timeout|Connection (refused|timed out)|Network is unreachable|No route to host)( \(port [[:digit:]]+\))?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/[ls]mtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^[:space:]]+>, relay=(none|[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\](:[[:digit:]]{1,5})?), (conn_use=[[:digit:]]+, )?delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=[45](\.[[:digit:]]+){2})?, status=(deferred|bounced|undeliverable) \((host [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] said: [45][[:digit:]][[:digit:]] .+ \(in reply to (HELO|EHLO|MAIL FROM|RCPT TO|end of DATA) command\)|connect to [^[:space:]]+: (read timeout|Connection (refused|timed out)|Network is unreachable|No route to host)( \(port [[:digit:]]+\))?)\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/[ls]mtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>, relay=(none|[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\](:[[:digit:]]{1,5})?), (conn_use=[[:digit:]]+, )?delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=[45](\.[[:digit:]]+){2})?, status=(deferred|bounced|undeliverable) \((host [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] said: [45][[:digit:]][[:digit:]] .+ \(in reply to (HELO|EHLO|MAIL FROM|RCPT TO|end of DATA) command\)|connect to [^[:space:]]+: (read timeout|Connection (refused|timed out)|Network is unreachable|No route to host)( \(port [[:digit:]]+\))?|mail for [._[:alnum:]-]+ loops back to myself)\)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: host [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] said: [45][[:digit:]][[:digit:]][- ]+.* \(in reply to (HELO|EHLO|MAIL FROM|RCPT TO|(end of )?DATA) command\)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mda|out)/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: client=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\], orig_queue_id=[[:xdigit:]]+, orig_client=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [A-Z[:digit:]]+: to=<[^[:space:]]+>,( orig_to=<[^[:space:]]+>,) relay=[^[:space:]]+, delay=[[:digit:]]+, status=deferred \(host [^[:space:]]+ said: [45][[:digit:]]{2} <[^[:space:]]*>: Recipient address rejected: Greylisted for [[:digit:]]+ (seconds|minutes)(\(see http://isg.ee.ethz.ch/tools/postgrey/help/[.[:alnum:]-]+.html\))? \(in reply to (HELO|EHLO|MAIL FROM|RCPT TO|DATA|end of DATA) command\)\)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<.*>,( orig_to=<[^[:space:]]+>,)? relay=[^[:space:]]+\](:[[:digit:]]+)?,( conn_use=[[:digit:]]+,)? delay=[[:digit:].]+,( delays=[[:digit:]./]+,)?( dsn=4\.[[:digit:]]\.[[:digit:]],)? status=deferred \(host [^[:space:]]+\] said: .*$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mda|out)/smtpd?\[[[:digit:]]+\]: warning: numeric domain name in resource data of MX record for [._[:alnum:]-]+: [[:xdigit:].:]{3,39}$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/smtpd\[[[:digit:]]+\]: SSL_accept error from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: (lost connection|Connection reset by peer|-?[[:digit:]]+|Connection timed out)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:SSL3_READ_BYTES:(sslv3|tlsv1) alert (unknown ca|certificate unknown):s3_pkt.c:[0-9]+:SSL alert number [[:digit:]]+:$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mda|out|lists)/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: client=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\], orig_queue_id=[[:xdigit:]]+, orig_client=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [A-Z[:digit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,) relay=[^[:space:]]+, delay=[[:digit:]]+, status=deferred \(host [^[:space:]]+ said: [45][[:digit:]]{2} <[^[:space:]]*>: Recipient address rejected: Greylisted for [[:digit:]]+ (seconds|minutes)(\(see http://isg.ee.ethz.ch/tools/postgrey/help/[.[:alnum:]-]+.html\))? \(in reply to (HELO|EHLO|MAIL FROM|RCPT TO|DATA|end of DATA) command\)\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<.*>,( orig_to=<[^>]+>,)? relay=[^[:space:]]+\](:[[:digit:]]+)?,( conn_use=[[:digit:]]+,)? delay=[[:digit:].]+,( delays=[[:digit:]./]+,)?( dsn=4\.[[:digit:]]\.[[:digit:]],)? status=deferred \(host [^[:space:]]+\] said: .*$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mda|out|mx)/smtpd?\[[[:digit:]]+\]: warning: valid_hostname: numeric hostname: [0-9]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mda|out|mx)/smtpd?\[[[:digit:]]+\]: warning: (malformed|numeric) domain name in resource data of MX record for [._[:alnum:]-]+:\s +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: warning: no MX host for [._[:alnum:]-]+ has a valid address record$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix(-\w+)?/smtpd\[[[:digit:]]+\]: SSL_accept error from [._[:alnum:]-]+\[([[:xdigit:].:]{3,39}|unknown)\]: (lost connection|Connection reset by peer|-?[[:digit:]]+|Connection timed out|Broken pipe)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:SSL3_READ_BYTES:(sslv3|tlsv1) alert (unknown ca|certificate unknown):s3_pkt\.c:[0-9]+:SSL alert number [[:digit:]]+:$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(out|mx)/bounce\[[[:digit:]]+\]: [[:xdigit:]]+: sender (delay|non-delivery|delivery status) notification: [[:xdigit:]]+$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: host [^[:space:]]+ refused to talk to me: [45][[:digit:]][[:digit:]].*$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: enabling PIX <CRLF>\.<CRLF> workaround for [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\](:[[:digit:]]{1,5})?$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: enabling PIX workarounds:( (disable_esmtp|delay_dotcrlf))+ for [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\](:[[:digit:]]{1,5})?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>, relay=[-_.[:alnum:]]+, delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=4(\.[[:digit:]]+){2})?, status=deferred \(connect to [._[:alnum:]-]+\[(unknown|[[:xdigit:].:]{3,39})\]:[[:digit:]]+: (Network is unreachable|No route to host)\)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: reject: RCPT from [^[:space:]]+: 4[[:digit:]][[:digit:]]( 4(\.[[:digit:]]){2}) <[^[:space:]]*>: Recipient address rejected: Greylisted( for [[:digit:]]+ (second|minute)s)?, see https?://[-_.:/[:alnum:]]+\.html?; from=<[^[:space:]]*> to=<[^[:space:]]+> proto=E?SMTP helo=<[^[:space:]]+>$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/smtpd\[[[:digit:]]+\]: lost connection after [[:upper:]]+( \([[:digit:]]+ bytes\))? from [._[:alnum:]-]+\[(unknown|[[:xdigit:].:]{3,39})\]$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: reject: (CONNECT|RCPT) from [^[:space:]]+: [45][[:digit:]][[:digit:]]( [45](\.[[:digit:]]){2})? Service unavailable; Client host \[([[:xdigit:].:]{3,39}|[-._[:alnum:]]+)\] blocked using [._[:alnum:]-]+;( .+;)? (from=<[^[:space:]]*> to=<[^[:space:]]+> )?proto=E?SMTP( helo=<[^[:space:]]+>)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: RCPT from [^[:space:]]+: [[:digit:]]{3}( [45](\.[[:digit:]]){2})? <[^[:space:]]*>: Relay access denied; from=<[^[:space:]]*> to=<[^[:space:]]+> proto=E?SMTP helo=<[^[:space:]]+>$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: warning: ([-._[:alnum:]]+): RBL lookup error: Host or domain name not found\. Name service error for name=\1 type=A: Host not found, try again$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/(smtpd|tlsproxy)\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:SSL2?3_(GET_RECORD:(decryption failed or bad record mac|wrong version number):s3_pkt\.c:[0-9]+:|READ_BYTES:(reason\([[:digit:]]+\)|sslv3 alert (unexpected message|bad certificate)):s3_pkt\.c:[[:digit:]]+:SSL alert number (0|10|42):|GET_CLIENT_HELLO:(unsupported protocol|no shared cipher|unknown protocol):s2?3_srvr\.c:[0-9]+:)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 554( 5\.1\.[01])? <[^[:space:]]*>: Recipient address rejected: User unknown in virtual alias table;( from=<[^[:space:]]*> to=<[^[:space:]]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: reject: RCPT from [^[:space:]]+: [45][[:digit:]][[:digit:]]( [45](\.[[:digit:]]){2})? <[^[:space:]]*>: Helo command rejected: .+; from=<[^[:space:]]*> to=<[^[:space:]]+> proto=E?SMTP helo=<[^[:space:]]+>$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>, relay=[-_.[:alnum:]]+, delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=4(\.[[:digit:]]+){2})?, status=deferred \(connect to [._[:alnum:]-]+\[(unknown|[[:xdigit:].:]{3,39})\]:[[:digit:]]+: (Network is unreachable|No route to host|Connection refused)\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: SSL_connect error to [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]:[[:digit:]]+: -?[[:digit:]]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:SSL2?3_CHECK_CERT_AND_ALGORITHM:dh key too small:s2?3_clnt\.c:[0-9]+:$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: Cannot start TLS: handshake failure$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/tlsproxy\[[[:digit:]]+\]: TLS handshake failed for service=smtpd peer=\[[[:xdigit:].:]{3,39}\]:[0-9]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: Host offered STARTTLS: \[[._[:alnum:]-]+\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: reject: RCPT from [^[:space:]]+: 4[[:digit:]][[:digit:]]( 4(\.[[:digit:]]+){2}) <[^[:space:]]*>: Recipient address rejected: Greylisted( for [[:digit:]]+ (second|minute)s)?, see https?://[-_.:/[:alnum:]]+\.html?; from=<[^>]*> to=<[^>]+> proto=E?SMTP helo=<[^[:space:]]+>$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-\w+/smtpd\[[[:digit:]]+\]: lost connection after [[:upper:]]+( \([[:digit:]]+ bytes\))? from [._[:alnum:]-]+\[(unknown|[[:xdigit:].:]{3,39})\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: reject: (CONNECT|RCPT) from [^[:space:]]+: [45][[:digit:]][[:digit:]]( [45](\.[[:digit:]]+){2})? Service unavailable; Client host \[([[:xdigit:].:]{3,39}|[-._[:alnum:]]+)\] blocked using [._[:alnum:]-]+;( .+;)? (from=<[^>]*> to=<[^>]+> )?proto=E?SMTP( helo=<[^[:space:]]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: RCPT from [^[:space:]]+: [[:digit:]]{3}( [45](\.[[:digit:]]+){2})? <[^[:space:]]*>: Relay access denied; from=<[^>]*> to=<[^>]+> proto=E?SMTP helo=<[^[:space:]]+>$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: warning: ([-._[:alnum:]]+): RBL lookup error: Host or domain name not found\. Name service error for name=\1 type=A(AAA)?: Host not found, try again$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/(smtpd|tlsproxy)\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:SSL2?3_(GET_RECORD:(decryption failed or bad record mac|wrong version number):s3_pkt\.c:[0-9]+:|READ_BYTES:(reason\([[:digit:]]+\)|sslv3 alert (unexpected message|bad certificate)):s3_pkt\.c:[[:digit:]]+:SSL alert number (0|10|42):|GET_CLIENT_HELLO:(unsupported protocol|no shared cipher|unknown protocol|wrong version number):s2?3_srvr\.c:[0-9]+:)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/(smtpd|tlsproxy)\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:(ssl3_get_record:(wrong version number|http request|packet length too long|bad record type)|tls_post_process_client_hello:no shared cipher): +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/(smtpd|tlsproxy)\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:ssl3_read_bytes:(sslv3 alert bad certificate|unexpected record|tlsv1 alert user cancelled): +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/(smtpd|tlsproxy)\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:tls_parse_ctos_key_share:bad key share: +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/(smtpd|tlsproxy)\[[[:digit:]]+\]: warning: TLS library problem: error:[[:xdigit:]]+:SSL routines:tls_((early_)?post_)?process_client_hello:(no shared cipher|unknown protocol|unsupported protocol|version too low):\.\./ssl/statem/statem_srvr\.c:[0-9]+:$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 55[0-9]( 5\.1\.[01])? <[^[:space:]]*>: Recipient address rejected: User unknown in virtual alias table;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: [[:xdigit:]]+: reject: RCPT from [^[:space:]]+: [45][[:digit:]][[:digit:]]( [45](\.[[:digit:]]+){2})? <[^[:space:]]*>: Helo command rejected: .+; from=<[^>]*> to=<[^>]+> proto=E?SMTP helo=<[^[:space:]]+>$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: too many errors after ([[:upper:]]{4}|END-OF-MESSAGE|UNKNOWN|DATA \(0 bytes\)) from [._[:alnum:]-]+\[[.[:digit:]]+\]$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/smtpd\[[[:digit:]]+\]: warning: hostname [^[:space:]]+ does not resolve to address [[:xdigit:].:]{3,39}: (No address associated with hostname|Temporary failure in name resolution)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: warning: (numeric hostname: [[:xdigit:].:]{3,39}|valid_hostname: misplaced delimiter: \S)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|lists)/pipe\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^[:space:]]+>,( orig_to=<[^[:space:]]+>,)* relay=([-_.[:alnum:]]+), delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=2(\.[[:digit:]]+){2})?, status=sent \(delivered via \3 service\)$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/discard\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^[:space:]]+>,( orig_to=<[^[:space:]]+>,)* relay=none, delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=2(\.[[:digit:]]+){2})?, status=sent \(discard\.fripost\.org\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/smtpd\[[[:digit:]]+\]: warning: (numeric hostname: [[:xdigit:].:]{3,39}|valid_hostname: misplaced delimiter: \S)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|lists)/pipe\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,)* relay=([-_.[:alnum:]]+), delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=2(\.[[:digit:]]+){2})?, status=sent \(delivered via \3 service\)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/discard\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>,( orig_to=<[^>]+>,)* relay=none, delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=2(\.[[:digit:]]+){2})?, status=sent \(discard\.fripost\.org\)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mx|msa)/smtpd\[[[:digit:]]+\]: warning: Illegal address syntax from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] in (MAIL|RCPT) command:\s ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: (PASS (OLD|NEW)|WHITELISTED) \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: CONNECT from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+ to \[[[:xdigit:].:]{3,39}\]:25$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: DISCONNECT \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: PREGREET [[:digit:]]+ after [.[:digit:]]+ from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+:\s ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: HANGUP after [.[:digit:]]+ from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+ in tests (before|after) SMTP handshake$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: BARE NEWLINE from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+( after\s.*)?$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: NON-SMTP COMMAND from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+\s ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: COMMAND PIPELINING from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+ after\s ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: DNSBL rank [[:digit:]]+ for \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from (\[[[:xdigit:].:]{3,39}\]):[[:digit:]]+: [45][[:digit:]][[:digit:]]( [45](\.[[:digit:]]){2})? (Service unavailable; client \1 blocked using [._[:alnum:]-]+|Protocol error);( .+;)? (from=<[^>]*>, to=<[^>]+>, )?proto=E?SMTP(, helo=<[^[:space:]]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: [[:upper:]]+ without valid RCPT from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from (\[[[:xdigit:].:]{3,39}\]):[[:digit:]]+: [45][[:digit:]][[:digit:]]( [45](\.[[:digit:]]+){2})? (Service unavailable; client \1 blocked using [._[:alnum:]-]+|Protocol error|Service currently unavailable);( .+;)? (from=<[^>]*>, to=<[^>]+>, )?proto=E?SMTP(, helo=<[^[:space:]]+>)?$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: NOQUEUE: reject: CONNECT from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+: too many connections$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: COMMAND (COUNT|TIME) LIMIT from \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+( after [[:upper:]]+)?$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: cache [a-z]+:\S+ full cleanup: retained=[[:digit:]]+ dropped=[[:digit:]]+ entries$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: cache [a-z]+:\S+ (partial|full) cleanup: retained=[[:digit:]]+ dropped=[[:digit:]]+ entries$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: warning: getpeername: Transport endpoint is not connected -- dropping this connection$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: warning: psc_cache_update: btree:/var/lib/postfix-mx/postscreen_cache update average delay is [[:digit:]]+ ms$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: warning: psc_cache_update: lmdb:/var/lib/postfix-mx/postscreen_cache update average delay is [[:digit:]]+ ms$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/postscreen\[[[:digit:]]+\]: warning: dnsblog reply timeout [[:digit:]]+s for [._[:alnum:]-]+$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/dnsblog\[[[:digit:]]+\]: addr [[:xdigit:].:]{3,39} listed by domain [._[:alnum:]-]+ as [[:xdigit:].:]{3,39}$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/dnsblog\[[[:digit:]]+\]: warning: dnsblog_query: lookup error for DNS query ([._[:alnum:]-]+): Host or domain name not found. Name service error for name=\1 type=A: Host not found, try again$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/dnsblog\[[[:digit:]]+\]: warning: dnsblog_query: lookup error for DNS query ([._[:alnum:]-]+): Host or domain name not found. Name service error for name=\1 type=A(AAA)?: Host not found, try again$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:xdigit:]]+: to=<[^>]+>, relay=none, delay=[.[:digit:]]+(, delays=([.[:digit:]]+/){3}[.[:digit:]]+)?(, dsn=5(\.[[:digit:]]+){2})?, status=(undeliverable|bounced) \(Host or domain name not found. Name service error for name=[^[:space:]]+ type=A(AAA)?: Host not found\)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/tlsproxy\[[[:digit:]]+\]: (CONNECT from|DISCONNECT) \[[[:xdigit:].:]{3,39}\]:[[:digit:]]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ systemd\[1\]: Start(ing|ed) Postfix sender login socketmap\.(\.\.)?$ # # Amavis -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ amavis\[[[:digit:]]+\]: \([-[:digit:]]+\) Passed (CLEAN|SPAM|UNCHECKED(-[A-Z]+)?|BAD-HEADER-[28]) {Relayed(Tagged)?(Internal|Inbound|Outbound)}, (INCOMING|OUTGOING)( LOCAL)? \[(IPv6:)?[[:xdigit:].:]{3,39}\](:[[:digit:]]+)?( \[[[:xdigit:].:]{3,39}\])? <[^>]*> -> (<[^>]*>,)+( Queue-ID: [[:xdigit:]]+,)?( Message-ID: <[^>]+>,)?( Resent-Message-ID: <[^>]+>,)? mail_id: [_-+[:alnum:]]+, Hits: -?[[:digit:].]*, size: [[:digit:]]+, queued_as: [[:xdigit:]]+(, dkim_(new|sd)?=[-.:[:alnum:]]+)?, [[:digit:]]+ ms$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ amavis\[[[:digit:]]+\]: \([-[:digit:]]+\) Passed (CLEAN|SPAM|UNCHECKED(-[A-Z]+)?|BAD-HEADER-[28]) {Relayed(Tagged)?(Internal|Inbound|Outbound)}, (INCOMING|OUTGOING)( LOCAL)? \[(IPv6:)?[[:xdigit:].:]{3,39}\](:[[:digit:]]+)?( \[[[:xdigit:].:]{3,39}\])? <[^>]*> -> (<[^>]*>,)+( Queue-ID: [[:xdigit:]]+,)?( Message-ID: <[^>]+>,)?( Resent-Message-ID: <[^>]+>,)? mail_id: [-_+[:alnum:]]+, Hits: -?[[:digit:].]*, size: [[:digit:]]+, queued_as: [[:xdigit:]]+(, dkim_(new|sd)?=[-_.,:[:alnum:]]+)?, [[:digit:]]+ ms$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ amavis\[[[:digit:]]+\]: \([-[:digit:]]+\) Passed (CLEAN|SPAM|UNCHECKED(-[A-Z]+)?|BAD-HEADER-[28]) {Relayed(Tagged)?(Internal|Inbound|Outbound)}, (INCOMING|OUTGOING)( LOCAL)? \[(IPv6:)?[[:xdigit:].:]{3,39}\](:[[:digit:]]+)?( \[[[:xdigit:].:]{3,39}\])? <[^>]*> -> (<[^>]*>,)*(<[^>]*)?\.\.\.$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ amavis\[[[:digit:]]+\]: \([-[:digit:]]+\) \.\.\.([^>]*>)?(,<[^>]*>)*,( Queue-ID: [[:xdigit:]]+,)?( Message-ID: <[^>]+>,)?( Resent-Message-ID: <[^>]+>,)? mail_id: [_-+[:alnum:]]+, Hits: -?[[:digit:].]*, size: [[:digit:]]+, queued_as: [[:xdigit:]]+(, dkim_(new|sd)?=[-.:[:alnum:]]+)?, [[:digit:]]+ ms$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ amavis\[[[:digit:]]+\]: \([-[:digit:]]+\) \.\.\.([^>]*>)?(,<[^>]*>)*,( Queue-ID: [[:xdigit:]]+,)?( Message-ID: <[^>]+>,)?( Resent-Message-ID: <[^>]+>,)? mail_id: [-_+[:alnum:]]+, Hits: -?[[:digit:].]*, size: [[:digit:]]+, queued_as: [[:xdigit:]]+(, dkim_(new|sd)?=[-_.,:[:alnum:]]+)?, [[:digit:]]+ ms$ # SMTP client connection caching was introduced in 2.6.0; the SMTP session is held for the next task, and is terminated by Postfix if the next mail comes soon enough ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtpd\[[[:digit:]]+\]: timeout after END-OF-MESSAGE from [._[:alnum:]-]+\[(127.0.0.1|::1)\]$ +# +# OpenDMARC +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: implicit authentication service: [-_.[:alnum:]]+\.fripost\.org$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+: RFC5322 requirement error: (not exactly one Date field|multiple Message-Id fields)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+: unable to parse From header field$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+:? ignoring Authentication-Results at\s +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+: ignoring invalid ARC-Authentication-Results header ".*" +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+: SPF\((mailfrom|helo)\): \S+ (none|tempfail|fail|pass)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+: [-_.[:alnum:]]+ (none|fail|pass)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: [[:xdigit:]]+: opendmarc_policy_query_dmarc\([._[:alnum:]-]+\) returned status 4$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ opendmarc\[[0-9]+\]: opendmarc: opendmarc-arcares\.c:[0-9]+: opendmarc_arcares_strip_whitespace: Assertion `.*' failed\.$ diff --git a/roles/common/files/etc/logcheck/ignore.d.server/strongswan-local b/roles/common/files/etc/logcheck/ignore.d.server/strongswan-local new file mode 100644 index 0000000..e78e9f0 --- /dev/null +++ b/roles/common/files/etc/logcheck/ignore.d.server/strongswan-local @@ -0,0 +1,24 @@ +# Ansible Managed +# Do NOT edit this file directly! +# +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] creating acquire job for policy [[:xdigit:].:]{3,39}/[[:digit:]]+(\[\w+(/[[:alnum:]-]+)?\])? === [[:xdigit:].:]{3,39}/[[:digit:]]+(\[\w+(/[[:alnum:]-]+)?\])? with reqid \{[[:digit:]]+\}$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] creating rekey job for CHILD_SA ESP/0x[[:xdigit:]]{8}/[[:xdigit:].:]{3,39}$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] creating delete job for CHILD_SA ESP/0x[[:xdigit:]]{8}/([[:xdigit:].:]{3,39}|%any)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] CHILD_SA ESP/0x[[:xdigit:]]{8}/([[:xdigit:].:]{3,39}|%any) not found for delete$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ipsec\[[[:digit:]]+\]: [[:digit:]]+\[JOB\] spawning [0-9]+ worker threads$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] initiating IKE_SA [[:alnum:]._-]+\[[[:digit:]]+\] to [[:xdigit:].:]{3,39}$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] [[:xdigit:].:]{3,39} is initiating an IKE_SA$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] establishing CHILD_SA [[:alnum:]._-]+(\{[[:digit:]]+\}( reqid [0-9]+)?)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] IKE_SA [[:alnum:]._-]+\[[[:digit:]]+\] established between [[:xdigit:].:]{3,39}\[[^]\"]+\]\.\.\.[[:xdigit:].:]{3,39}\[[^]]+\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] ((in|out)bound )?CHILD_SA [[:alnum:]._-]+\{[[:digit:]]+\} established with SPIs [[:xdigit:]]{8}_i [[:xdigit:]]{8}_o and TS [[:xdigit:].:]{3,39}/[[:digit:]]+ === [[:xdigit:].:]{3,39}/[[:digit:]]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] closing CHILD_SA [[:alnum:]._-]+\{[[:digit:]]+\} with SPIs [[:xdigit:]]{8}_i \([[:digit:]]+ bytes\) [[:xdigit:]]{8}_o \([[:digit:]]+ bytes\) and TS [[:xdigit:].:]{3,39}/[[:digit:]]+ === [[:xdigit:].:]{3,39}/[[:digit:]]+$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] reauthenticating IKE_SA [[:alnum:]._-]+\[[[:digit:]]+\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] deleting IKE_SA after [[:digit:]]+ seconds of CHILD_SA inactivity$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] deleting IKE_SA [[:alnum:]._-]+\[[[:digit:]]+\] between [[:xdigit:].:]{3,39}\[[^]\"]+\]\.\.\.[[:xdigit:].:]{3,39}\[[^]]+\]$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] deleting CHILD_SA after [[:digit:]]+ seconds of inactivity$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] CHILD_SA \{[[:digit:]]+\} not found for delete$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[JOB\] deleting half open IKE_SA with [[:xdigit:].:]{3,39} after timeout$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[IKE\] IKE_SA deleted$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[MGR\] ignoring request with ID [[:digit:]]+, already processing$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] flags changed for [[:xdigit:].:]{3,39} on e[nt][[:alnum:]]+ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (charon|ipsec\[[[:digit:]]+\]): [[:digit:]]+\[KNL\] [[:xdigit:].:]{3,39} appeared on e[nt][[:alnum:]]+$ diff --git a/roles/common/files/etc/logcheck/logcheck.conf b/roles/common/files/etc/logcheck/logcheck.conf index 9a7e7c6..4c7ff10 100644 --- a/roles/common/files/etc/logcheck/logcheck.conf +++ b/roles/common/files/etc/logcheck/logcheck.conf @@ -52,34 +52,45 @@ FQDN=1 # Controls the base directory for rules file location # This must be an absolute path #RULEDIR="/etc/logcheck" # Controls if syslog-summary is run over each section. # Alternatively, set to "1" to enable extra summary. # HINT: syslog-summary needs to be installed. #SYSLOGSUMMARY=0 # Controls Subject: lines on logcheck reports: #ATTACKSUBJECT="Security Alerts" #SECURITYSUBJECT="Security Events" #EVENTSSUBJECT="System Events" # Controls [logcheck] prefix on Subject: lines -#ADDTAG="no" +#ADDTAG="no" + +# Previous versions of logcheck always sent messages in 7bit encoding, +# even if that resulted in RFC-violating messages. For example, really +# long syslog lines would generate too-long SMTP lines, which are +# rejected at least by Debian's default exim configuration. The new +# default is to let mime-construct pick an appropriate encoding, but you +# can override it by setting the below (to any of the encodings +# supported by mime-construct). You may need to do this if you have +# tools handling logcheck emails that don't understand MIME encoding. + +#MIMEENCODING= # Set a different location for temporary files than /tmp # this is useful if your /tmp is small and you are getting # errors such as: # cp: writing `/tmp/logcheck.y12449/checked': No space left on device # /usr/sbin/logcheck: line 161: cannot create temp file for here document: No space left on device # mail: /tmp/mail.RsXXXXpc2eAx: No space left on device # Null message body; hope that's ok # # If this is happening, likely you will want to change the following to be some other # location, such as /var/tmp TMP="/tmp" diff --git a/roles/common/files/etc/logcheck/violations.ignore.d/logcheck-sudo b/roles/common/files/etc/logcheck/violations.ignore.d/logcheck-sudo index e474019..70673ae 100644 --- a/roles/common/files/etc/logcheck/violations.ignore.d/logcheck-sudo +++ b/roles/common/files/etc/logcheck/violations.ignore.d/logcheck-sudo @@ -1,7 +1,5 @@ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sudo: pam_krb5\(sudo:auth\): user [[:alnum:]-]+ authenticated as [[:alnum:]-]+@[.A-Z]+$ -# ignore sudo with custom ENV -#^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo:[[:space:]]+[_[:alnum:].-]+ : TTY=(unknown|console|(pts/|tty|vc/)[[:digit:]]+) ; PWD=[^;]+ ; USER=[._[:alnum:]-]+ ; COMMAND=((/(usr|etc|bin|sbin)/|sudoedit ).*|list)$ -^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo:[[:space:]]+[_[:alnum:].-]+ : TTY=(unknown|console|(pts/|tty|vc/)[[:digit:]]+) ; PWD=[^;]+ ; USER=[._[:alnum:]-]+ (; ENV=([_a-zA-Z]+=\S* )+)?; COMMAND=((/(usr|etc|bin|sbin)/|sudoedit ).*|list)$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ sudo: pam_krb5\(sudo:auth\): user [._[:alnum:]-]+ authenticated as [._[:alnum:]-]+@[.A-Z]+$ +^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo:[[:space:]]+[_[:alnum:].-]+ : (TTY=(unknown|console|(pts/|tty|vc/)[[:digit:]]+) ; )?PWD=[^;]+ ; USER=[._[:alnum:]-]+( ; GROUP=[._[:alnum:]-]+)? ; COMMAND=((/(usr|etc|bin|sbin)/|sudoedit ).*|list)$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo:[[:space:]]+[_[:alnum:].-]+ : \(command continued\).*$ -^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo: pam_[[:alnum:]]+\(sudo:session\): session opened for user [[:alnum:]-]+ by ([[:alnum:]-]+)?\(uid=[0-9]+\)$ -^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo: pam_[[:alnum:]]+\(sudo:session\): session closed for user [[:alnum:]-]+$ +^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo: pam_[[:alnum:]]+\(sudo:session\): session opened for user [._[:alnum:]-]+\(uid=[0-9]+\) by ([[:alnum:]-]+)?\(uid=[0-9]+\)$ +^\w{3} [ :0-9]{11} [._[:alnum:]-]+ sudo: pam_[[:alnum:]]+\(sudo:session\): session closed for user [._[:alnum:]-]+$ diff --git a/roles/common/files/etc/logrotate.d/fripost-mail b/roles/common/files/etc/logrotate.d/fripost-mail index 4fc1a85..7f7ffc2 100644 --- a/roles/common/files/etc/logrotate.d/fripost-mail +++ b/roles/common/files/etc/logrotate.d/fripost-mail @@ -1,34 +1,34 @@ # Don't forget to remove these log files from other files under # /etc/logrotate.d/ ! /var/log/mail.log /var/log/mail.info { rotate 3 daily missingok notifempty compress delaycompress sharedscripts postrotate - invoke-rc.d rsyslog rotate > /dev/null + /usr/lib/rsyslog/rsyslog-rotate endscript } # Keep a mapping Postfix's message ID -> SASL username for a month, to # find authors of potential abuse emails (if we are shown the header of # such emails.) /var/log/mail.sasl { rotate 4 weekly missingok notifempty compress delaycompress sharedscripts postrotate - invoke-rc.d rsyslog rotate > /dev/null + /usr/lib/rsyslog/rsyslog-rotate endscript } diff --git a/roles/common/files/etc/network/if-post-down.d/iptables b/roles/common/files/etc/network/if-post-down.d/iptables deleted file mode 100755 index d27977d..0000000 --- a/roles/common/files/etc/network/if-post-down.d/iptables +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -# A post-down hook to flush ip tables and delete custom chains in the -# loaded v4 and v6 rulesets. -# Copyright © 2013 Guilhem Moulin <guilhem@fripost.org> -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -set -ue -PATH=/usr/sbin:/usr/bin:/sbin:/bin - -# Ignore the loopback interface; run the script for ifdown only. -[ "$IFACE" != lo -a "$MODE" = stop ] || exit 0 - -case "$ADDRFAM" in - inet) ipts=/sbin/iptables-save; ipt=/sbin/iptables;; - inet6) ipts=/sbin/ip6tables-save; ipt=/sbin/ip6tables;; - *) exit 0 -esac - -$ipts | sed -nr 's/^\*//p' | \ -while read table; do - $ipt -t "$table" -F - $ipt -t "$table" -X -done diff --git a/roles/common/files/etc/network/if-pre-up.d/iptables b/roles/common/files/etc/network/if-pre-up.d/iptables deleted file mode 100755 index 2b83cdc..0000000 --- a/roles/common/files/etc/network/if-pre-up.d/iptables +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash - -# A pre-up hook to auto-(re)load the iptables rulesets whenever the -# network is brought up. If the action fails, an alert message is passed -# to syslogd. -# Copyright © 2013 Guilhem Moulin <guilhem@fripost.org> -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -set -uo pipefail -PATH=/usr/sbin:/usr/bin:/sbin:/bin - -# NOTE: syslog starts after networking during the boot process, messages -# won't be logged at boot time. -log="/usr/bin/logger -st firewall" - -# Ignore the loopback interface; run the script for ifup only. -[ "$IFACE" != lo -a "$MODE" = start ] || exit 0 - -# We support only IPv4 and IPv6. -[ "$ADDRFAM" = inet -o "$ADDRFAM" = inet6 ] || exit 0 - -$log -p user.info -- "Loading $ADDRFAM firewall on interface $IFACE." - -case "$ADDRFAM" in - inet) iptr=/sbin/iptables-restore; rules=rules.v4;; - inet6)iptr=/sbin/ip6tables-restore; rules=rules.v6;; -esac -rules="/etc/iptables/$rules" - -$iptr < $rules 2>&1 | $log -p user.err -rv=$? - -[ $rv -gt 0 ] && $log -p user.alert \ - "WARN: Failed to load iptables rulesets; the machine may be unprotected!" -exit $rv diff --git a/roles/common/files/etc/postfix/master.cf b/roles/common/files/etc/postfix/master.cf deleted file mode 100644 index 9b81c70..0000000 --- a/roles/common/files/etc/postfix/master.cf +++ /dev/null @@ -1,80 +0,0 @@ -# -# Postfix master process configuration file. For details on the format -# of the file, see the master(5) manual page (command: "man 5 master"). -# -# Do not forget to execute "postfix reload" after editing this file. -# -# ========================================================================== -# service type private unpriv chroot wakeup maxproc command + args -# (yes) (yes) (yes) (never) (100) -# ========================================================================== -smtpd pass - - n - - smtpd - -o cleanup_service_name=cleanup_nochroot -smtp inet n - n - 1 postscreen -tlsproxy unix - - n - 0 tlsproxy -dnsblog unix - - n - 0 dnsblog -submission inet n - - - - smtpd -pickup fifo n - - 60 1 pickup -cleanup unix n - - - 0 cleanup -cleanup_nochroot unix n - n - 0 cleanup -qmgr fifo n - n 300 1 qmgr -tlsmgr unix - - - 1000? 1 tlsmgr -rewrite unix - - - - - trivial-rewrite -bounce unix - - - - 0 bounce -defer unix - - - - 0 bounce -trace unix - - - - 0 bounce -verify unix - - - - 1 verify -flush unix n - - 1000? 0 flush -proxymap unix - - n - - proxymap -proxywrite unix - - n - 1 proxymap -smtp unix - - - - - smtp -smtpl unix - - - - - smtp - -o smtp_bind_address=127.0.0.1 -relay unix - - - - - smtp -# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 -showq unix n - - - - showq -error unix - - - - - error -retry unix - - - - - error -discard unix - - - - - discard -local unix - n n - - local -virtual unix - n n - - virtual -lmtp unix - - - - - lmtp -anvil unix - - - - 1 anvil -scache unix - - - - 1 scache -127.0.0.1:16132 inet n - - - - smtpd -2525 inet n - - - - smtpd -2526 inet n - - - - smtpd -2527 inet n - - - - smtpd -reserved-alias unix - n n - - pipe - flags=Rhu user=nobody argv=/usr/local/bin/reserved-alias.pl ${sender} ${original_recipient} @fripost.org -sympa unix - n n - - pipe - flags=Rhu user=sympa argv=/usr/local/bin/sympa-queue ${user} - -# Client part (lmtp) - amavis -amavisfeed unix - - n - 5 lmtp - -o lmtp_destination_recipient_limit=1000 - -o lmtp_send_xforward_command=yes - -o lmtp_data_done_timeout=1200s - -o disable_dns_lookups=yes - -# Server part (smtpd) - amavis (if the MDA and outgoing proxy are on the -# same machine, we need to create another entry, on another port.) -127.0.0.1:10025 inet n - n - - smtpd - -o content_filter= - -o smtpd_delay_reject=no - -o smtpd_client_restrictions=permit_mynetworks,reject - -o smtpd_helo_restrictions= - -o smtpd_sender_restrictions= - -o smtpd_relay_restrictions=permit_mynetworks,reject - -o smtpd_data_restrictions=reject_unauth_pipelining - -o smtpd_end_of_data_restrictions= - -o smtpd_restriction_classes= - -o mynetworks_style=host - -o smtpd_error_sleep_time=0 - -o smtpd_soft_error_limit=1001 - -o smtpd_hard_error_limit=1000 - -o smtpd_client_connection_count_limit=0 - -o smtpd_client_connection_rate_limit=0 - -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_milters - -o local_header_rewrite_clients= - -o smtpd_authorized_xforward_hosts=127.0.0.0/8 diff --git a/roles/common/files/etc/rkhunter.conf b/roles/common/files/etc/rkhunter.conf index 31b3062..c7358d0 100644 --- a/roles/common/files/etc/rkhunter.conf +++ b/roles/common/files/etc/rkhunter.conf @@ -1,139 +1,142 @@ # # This is the main configuration file for Rootkit Hunter. # # You can modify this file directly, or you can create a local configuration # file. The local file must be named 'rkhunter.conf.local', and must reside # in the same directory as this file. Alternatively you can create a directory, # named 'rkhunter.d', which also must be in the same directory as this # configuration file. Within the 'rkhunter.d' directory you can place further # configuration files. There is no restriction on the file names used, other # than they must end in '.conf'. # # Please modify the configuration file(s) to your own requirements. It is # recommended that the command 'rkhunter -C' is run after any changes have # been made. # # Please review the documentation before posting bug reports or questions. -# To report bugs, obtain updates, or provide patches or comments, please go -# to: http://rkhunter.sourceforge.net +# To report bugs, provide patches or comments, please go to: +# http://rkhunter.sourceforge.net # # To ask questions about rkhunter, please use the 'rkhunter-users' mailing list. # Note that this is a moderated list, so please subscribe before posting. # # In the configuration files, lines beginning with a hash (#), and blank lines, # are ignored. Also, end-of-line comments are not supported. # # Any of the configuration options may appear more than once. However, several # options only take one value, and so the last one seen will be used. Some # options are allowed to appear more than once, and the text describing the # option will say if this is so. These configuration options will, in effect, # have their values concatenated together. To delete a previously specified # option list, specify the option with no value (that is, a null string). # # Some of the options are space-separated lists, others, typically those # specifying pathnames, are newline-separated lists. These must be entered # as one item per line. Quotes must not be used to surround the pathname. # # For example, to specify two pathnames, '/tmp/abc' and '/tmp/xyz', for an # option: XXX=/tmp/abc (correct) # XXX=/tmp/xyz # # XXX="/tmp/abc" (incorrect) # XXX="/tmp/xyz" # # XXX=/tmp/abc /tmp/xyz (incorrect) # or XXX="/tmp/abc /tmp/xyz" (incorrect) # or XXX="/tmp/abc" "/tmp/xyz" (incorrect) # # The last three examples are being configured as space-separated lists, # which is incorrect, generally, for options specifying pathnames. They # should be configured with one entry per line as in the first example. # # If wildcard characters (globbing) are allowed for an option, then the -# text describing the option will say so. +# text describing the option will say so. Any globbing character explicitly +# required in a pathname should be escaped. # # Space-separated lists may be enclosed by quotes, although they are not # required. If they are used, then they must only appear at the start and # end of the list, not in the middle. # # For example: XXX=abc def gh (correct) # XXX="abc def gh" (correct) # XXX="abc" "def" "gh" (incorrect) # # Space-separated lists may also be entered simply as one entry per line. # # For example: XXX=abc (correct) # XXX=def # XXX="gh" # # If a configuration option is never set, then the program will assume a # default value. The text describing the option will state the default value. # If there is no default, then rkhunter will calculate a value or pathname -# to use. +# to use. If a value is set for a configuration option, then the default +# value is ignored. If it is wished to keep the default value, as well as +# any other set value, then the default must be explicitly set. # # # If this option is set to '1', it specifies that the mirrors file # ('mirrors.dat'), which is used when the '--update' and '--versioncheck' # options are used, is to be rotated. Rotating the entries in the file allows # a basic form of load-balancing between the mirror sites whenever the above # options are used. # # If the option is set to '0', then the mirrors will be treated as if in a # priority list. That is, the first mirror listed will always be used first. # The second mirror will only be used if the first mirror fails, the third # mirror will only be used if the second mirror fails, and so on. # # If the mirrors file is read-only, then the '--versioncheck' command-line # option can only be used if this option is set to '0'. # # The default value is '1'. # #ROTATE_MIRRORS=1 # # If this option is set to '1', it specifies that when the '--update' option is # used, then the mirrors file is to be checked for updates as well. If the # current mirrors file contains any local mirrors, these will be prepended to # the updated file. If this option is set to '0', the mirrors file can only be # updated manually. This may be useful if only using local mirrors. # # The default value is '1'. # -#UPDATE_MIRRORS=1 +UPDATE_MIRRORS=0 # # The MIRRORS_MODE option tells rkhunter which mirrors are to be used when # the '--update' or '--versioncheck' command-line options are given. # Possible values are: # 0 - use any mirror # 1 - only use local mirrors # 2 - only use remote mirrors # # Local and remote mirrors can be defined in the mirrors file by using the # 'local=' and 'remote=' keywords respectively. # # The default value is '0'. # -#MIRRORS_MODE=0 +MIRRORS_MODE=1 # # Email a message to this address if a warning is found when the system is # being checked. Multiple addresses may be specified simply be separating # them with a space. To disable the option, simply set it to the null string # or comment it out. # # The option may be specified more than once. # # The default value is the null string. # # Also see the MAIL_CMD option. # MAIL-ON-WARNING=admin@fripost.org # # This option specifies the mail command to use if MAIL-ON-WARNING is set. # # NOTE: Double quotes are not required around the command, but are required # around the subject line if it contains spaces. @@ -201,41 +204,41 @@ SCRIPTDIR=/usr/share/rkhunter/scripts # rkhunter --lang en --list languages # # The default language is 'en' (English). # #LANGUAGE=en # # This option is a space-separated list of the languages that are to be updated # when the '--update' option is used. If unset, then all the languages will be # updated. If none of the languages are to be updated, then set this option to # just 'en'. # # The default language, specified by the LANGUAGE option, and the English (en) # language file will always be updated regardless of this option. # # This option may be specified more than once. # # The default value is the null string, indicating that all the language files # will be updated. # -#UPDATE_LANG="" +UPDATE_LANG="en" # # This option specifies the log file pathname. The file will be created if it # does not initially exist. If the option is unset, then the program will # display a message each time it is run saying that the default value is being # used. # # The default value is '/var/log/rkhunter.log'. # LOGFILE=/var/log/rkhunter.log # # Set this option to '1' if the log file is to be appended to whenever rkhunter # is run. A value of '0' will cause a new log file to be created whenever the # program is run. # # The default value is '0'. # #APPEND_LOG=0 @@ -247,41 +250,41 @@ LOGFILE=/var/log/rkhunter.log # If the option value is '0', then the log file will not be copied regardless # of whether any errors or warnings occurred. # # The default value is '0'. # #COPY_LOG_ON_ERROR=0 # # Set the following option to enable the rkhunter check start and finish times # to be logged by syslog. Warning messages will also be logged. The value of # the option must be a standard syslog facility and priority, separated by a # dot. For example: # # USE_SYSLOG=authpriv.warning # # Setting the value to 'NONE', or just leaving the option commented out, # disables the use of syslog. # # The default value is not to use syslog. # -#USE_SYSLOG=authpriv.notice +USE_SYSLOG=authpriv.warning # # Set the following option to '1' if the second colour set is to be used. This # can be useful if your screen uses black characters on a white background # (for example, a PC instead of a server). A value of '0' will cause the default # colour set to be used. # # The default value is '0'. # #COLOR_SET2=0 # # Set the following option to '0' if rkhunter should not detect if X is being # used. If X is detected as being used, then the second colour set will # automatically be used. If set to '1', then the use of X will be detected. # # The default value is '0'. # AUTO_X_DETECT=1 @@ -300,144 +303,147 @@ AUTO_X_DETECT=1 # 'PermitRootLogin' option. A warning will be displayed if they do not match. # However, if a value has not been set in the SSH configuration file, then a # value here of 'unset' can be used to avoid warning messages. # # The default value is 'no'. # #ALLOW_SSH_ROOT_USER=no # # Set this option to '1' to allow the use of the SSH-1 protocol, but note # that theoretically it is weaker, and therefore less secure, than the # SSH-2 protocol. Do not modify this option unless you have good reasons # to use the SSH-1 protocol (for instance for AFS token passing or Kerberos4 # authentication). If the 'Protocol' option has not been set in the SSH # configuration file, then a value of '2' may be set here in order to # suppress a warning message. A value of '0' indicates that the use of # SSH-1 is not allowed. # # The default value is '0'. # -#ALLOW_SSH_PROT_V1=0 +ALLOW_SSH_PROT_V1=2 # # This setting tells rkhunter the directory containing the SSH configuration -# file. This setting will be worked out by rkhunter, and so should not -# usually need to be set. +# file. If unset, this setting will be worked out by rkhunter, and so should +# not usually need to be set. # # This option has no default value. # #SSH_CONFIG_DIR=/etc/ssh # # These two options determine which tests are to be performed. The ENABLE_TESTS # option can use the word 'ALL' to refer to all of the available tests. The # DISABLE_TESTS option can use the word 'NONE' to mean that no tests are # disabled. The list of disabled tests is applied to the list of enabled tests. # # Both options are space-separated lists of test names, and both options may # be specified more than once. The currently available test names can be seen # by using the command 'rkhunter --list tests'. # # The supplied configuration file has some tests already disabled, and these # are tests that will be used only occasionally, can be considered 'advanced' # or that are prone to produce more than the average number of false-positives. # # Please read the README file for more details about enabling and disabling # tests, the test names, and how rkhunter behaves when these options are used. # # The default values are to enable all tests and to disable none. However, if # either of the options below are specified, then they will override the # program defaults. # -# hidden_procs test requires the unhide and/or unhide.rb commands which are -# part of the unhide respectively unhide.rb packages in Debian. -# -# apps test is disabled by default as it triggers warnings about outdated -# applications (and warns about possible security risk: we better trust -# the Debian Security Team). -# ENABLE_TESTS=ALL -DISABLE_TESTS=suspscan hidden_procs deleted_files packet_cap_apps apps +DISABLE_TESTS=suspscan hidden_ports hidden_procs deleted_files packet_cap_apps apps # # The HASH_CMD option can be used to specify the command to use for the file # properties hash value check. It can be specified as just the command name or # the full pathname. If just the command name is given, and it is one of MD5, # SHA1, SHA224, SHA256, SHA384 or SHA512, then rkhunter will first look for the # relevant command, such as 'sha256sum', and then for 'sha256'. If neither of # these are found, it will then look to see if a perl module has been installed # which will support the relevant hash function. To see which perl modules have # been installed use the command 'rkhunter --list perl'. # # Systems using prelinking are restricted to using either the SHA1 or MD5 # function. # # A value of 'NONE' (in uppercase) can be specified to indicate that no hash # function should be used. Rkhunter will detect this, and automatically disable # the file properties hash check test. # # Examples: # For Solaris 9 : HASH_CMD=gmd5sum # For Solaris 10: HASH_CMD=sha1sum # For AIX (>5.2): HASH_CMD="csum -hMD5" # For NetBSD : HASH_CMD="cksum -a sha512" # # NOTE: Whenever this option is changed 'rkhunter --propupd' must be run. # -# The default value is the SHA1 function, or MD5 if SHA1 cannot be found. +# The default value is the SHA256 function, unless prelinking is used in +# which case it defaults to the SHA1 function. # -# Also see the HASH_FLD_IDX option. +# Also see the HASH_FLD_IDX option. In addition, note the comments under +# the PKGMGR option relating to the use of HASH_CMD. # -HASH_CMD=sha512sum +HASH_CMD=SHA512 # # The HASH_FLD_IDX option specifies which field from the HASH_CMD command # output contains the hash value. The fields are assumed to be space-separated. # # The option value must be an integer greater than zero. # # The default value is '1', but for *BSD users rkhunter will, by default, use a # value of '4' if the HASH_CMD option has not been set. # #HASH_FLD_IDX=4 # # The PKGMGR option tells rkhunter to use the specified package manager to # obtain the file property information. This is used when updating the file # properties file ('rkhunter.dat'), and when running the file properties check. # For RedHat/RPM-based systems, 'RPM' can be used to get information from the # RPM database. For Debian-based systems 'DPKG' can be used, for *BSD systems -# 'BSD' can be used, and for Solaris systems 'SOLARIS' can be used. No value, -# or a value of 'NONE', indicates that no package manager is to be used. +# 'BSD' can be used, or for *BSD systems with the 'pkg' command 'BSDng' can be +# used, and for Solaris systems 'SOLARIS' can be used. No value, or a value of +# 'NONE', indicates that no package manager is to be used. # -# The current package managers, except 'SOLARIS', store the file hash values -# using an MD5 hash function. The Solaris package manager includes a checksum -# value, but this is not used by default (see USE_SUNSUM below). +# The package managers obtain each file hash value using a hash function. The +# Solaris package manager includes a 16-bit checksum value, but this is not +# used by default (see USE_SUNSUM below). The 'RPM' and 'BSDng' package managers +# currently use a SHA256 hash function. Other package managers will, typically, +# use an MD5 hash function. # -# The 'DPKG' and 'BSD' package managers only provide MD5 hash values. -# The 'RPM' package manager additionally provides values for the inode, -# file permissions, uid, gid and other values. The 'SOLARIS' also provides -# most of the values, similar to 'RPM', but not the inode number. +# The 'DPKG', 'BSD' and 'BSDng' package managers only provide a file hash value. +# The 'RPM' package manager additionally provides values for the inode, file +# permissions, uid, gid and other values. The 'SOLARIS' package manager also +# provides most of the values, similar to 'RPM', but not the inode number. # # For any file not part of a package, rkhunter will revert to using the -# HASH_CMD hash function instead. +# HASH_CMD hash function instead. This means that if the HASH_CMD option +# is set, and PKGMGR is set, then the HASH_CMD hash function is only used, +# and stored, for non-packaged files. All packaged files will use, and store, +# whatever hash function the relevant package manager uses. So, for example, +# with the 'RPM' package manager, packaged files will be stored with their +# SHA256 value regardless of the value of the HASH_CMD option. # # NOTE: Whenever this option is changed 'rkhunter --propupd' must be run. # # The default value is 'NONE'. # # Also see the PKGMGR_NO_VRFY and USE_SUNSUM options. # # NONE is the default for Debian as well, as running --propupd takes # about 4 times longer when it's set to DPKG # #PKGMGR=NONE # # It is possible that a file, which is part of a package, may have been # modified by the administrator. Typically this occurs for configuration # files. However, the package manager may list the file as being modified. # For the RPM package manager this may well depend on how the package was # built. This option specifies a pathname which is to be exempt from the # package manager verification process, and which will be treated # as a non-packaged file. As such, the file properties are still checked. @@ -482,199 +488,225 @@ HASH_CMD=sha512sum # # The default value is the null string. # #IGNORE_PRELINK_DEP_ERR=/bin/ps /usr/bin/top # # These options specify a command, directory or file pathname which will be # included or excluded in the file properties checks. # # For the USER_FILEPROP_FILES_DIRS option, simple command names - for example, # 'top' - and directory names are added to the internal list of directories to # be searched for each of the command names in the command list. Additionally, # full pathnames to files, which need not be commands, may be given. Any files # or directories which are already part of the internal lists will be silently # ignored from the configuration. # # For the USER_FILEPROP_FILES_DIRS option, wildcards are allowed, except for # simple command names. # For example, 'top*' cannot be given, but '/usr/bin/top*' is allowed. # +# To extend the use of wildcards to include recursive checking of directories, +# see the GLOBSTAR configuration option. +# # Specific files may be excluded by using the EXCLUDE_USER_FILEPROP_FILES_DIRS # option. Wildcards may be used with this option. # # By combining these two options, and using wildcards, whole directories can be # excluded. For example: # # USER_FILEPROP_FILES_DIRS=/etc/* # USER_FILEPROP_FILES_DIRS=/etc/*/* # EXCLUDE_USER_FILEPROP_FILES_DIRS=/etc/rc?.d/* # # This will look for files in the first two directory levels of '/etc'. However, # anything in '/etc/rc0.d', '/etc/rc1.d', '/etc/rc2.d' and so on, will be # excluded. # # NOTE: Only files and directories which have been added by the user, and are # not part of the internal lists, can be excluded. So, for example, it is not # possible to exclude the 'ps' command by using '/bin/ps'. These will be # silently ignored from the configuration. # # Both options can be specified more than once. # # NOTE: Whenever these options are changed 'rkhunter --propupd' must be run. # # The default value for both options is the null string. # #USER_FILEPROP_FILES_DIRS=top #USER_FILEPROP_FILES_DIRS=/usr/local/sbin #USER_FILEPROP_FILES_DIRS=/etc/rkhunter.conf #USER_FILEPROP_FILES_DIRS=/etc/rkhunter.conf.local -#USER_FILEPROP_FILES_DIRS=/var/lib/rkhunter/db/* -#USER_FILEPROP_FILES_DIRS=/var/lib/rkhunter/db/i18n/* +#USER_FILEPROP_FILES_DIRS=/etc/rkhunter.d/* #EXCLUDE_USER_FILEPROP_FILES_DIRS=/opt/ps* -#EXCLUDE_USER_FILEPROP_FILES_DIRS=/var/lib/rkhunter/db/mirrors.dat -#EXCLUDE_USER_FILEPROP_FILES_DIRS=/var/lib/rkhunter/db/rkhunter* # # This option whitelists files and directories from existing, or not existing, # on the system at the time of testing. This option is used when the # configuration file options themselves are checked, and during the file # properties check, the hidden files and directories checks, and the filesystem # check of the '/dev' directory. # # This option may be specified more than once, and may use wildcards. # Be aware though that this is probably not what you want to do as the # wildcarding will be expanded after files have been deleted. As such # deleted files won't be whitelisted if wildcarded. # # NOTE: The user must take into consideration how often the file will appear # and disappear from the system in relation to how often rkhunter is run. If # the file appears, and disappears, too often then rkhunter may not notice -# this. All it will see is that the file has changed. The inode-number and DTM +# this. All it will see is that the file has changed. The inode number and DTM # will certainly be different for each new file, and rkhunter will report this. # # The default value is the null string. # #EXISTWHITELIST="" +# work around for usr-merge, cf. https://bugs.debian.org/932594 +EXISTWHITELIST=/usr/bin/egrep +EXISTWHITELIST=/usr/bin/fgrep + # # Whitelist various attributes of the specified file. The attributes are those # of the 'attributes' test. Specifying a file name here does not include it # being whitelisted for the write permission test (see below). # # This option may be specified more than once, and may use wildcard characters. # # The default value is the null string. # #ATTRWHITELIST=/usr/bin/date # # Allow the specified file to have the 'others' (world) permission have the # write-bit set. For example, files with permissions r-xr-xrwx or rwxrwxrwx. # # This option may be specified more than once, and may use wildcard characters. # # The default value is the null string. # #WRITEWHITELIST=/usr/bin/date # # Allow the specified file to be a script. # # This option may be specified more than once, and may use wildcard characters. # # The default value is the null string. # SCRIPTWHITELIST=/bin/egrep SCRIPTWHITELIST=/bin/fgrep -SCRIPTWHITELIST=/bin/which -SCRIPTWHITELIST=/usr/bin/groups +SCRIPTWHITELIST=/usr/bin/egrep +SCRIPTWHITELIST=/usr/bin/fgrep +SCRIPTWHITELIST=/usr/bin/which SCRIPTWHITELIST=/usr/bin/ldd -#SCRIPTWHITELIST=/usr/bin/lwp-request +SCRIPTWHITELIST=/usr/bin/lwp-request SCRIPTWHITELIST=/usr/sbin/adduser #SCRIPTWHITELIST=/usr/sbin/prelink -#SCRIPTWHITELIST=/usr/bin/unhide.rb +#SCRIPTWHITELIST=/usr/sbin/unhide.rb # # Allow the specified file to have the immutable attribute set. # # This option may be specified more than once, and may use wildcard characters. # # The default value is the null string. # #IMMUTWHITELIST=/sbin/ifdown # # If this option is set to '1', then the immutable-bit test is reversed. That # is, the files are expected to have the bit set. A value of '0' means that the # immutable-bit should not be set. # # The default value is '0'. # #IMMUTABLE_SET=0 # +# If this option is set to '1', then any changed inode value is ignored in +# the file properties check. The inode test itself still runs, but it will +# always return that no inodes have changed. +# +# This option may be useful for filesystems such as Btrfs, which handle inodes +# slightly differently than other filesystems. +# +# The default value is '0'. +# +#SKIP_INODE_CHECK=0 + +# # Allow the specified hidden directory to be whitelisted. # # This option may be specified more than once, and may use wildcard characters. # # The default value is the null string. # -ALLOWHIDDENDIR=/etc/.java +#ALLOWHIDDENDIR=/etc/.java ALLOWHIDDENDIR=/etc/.git +#ALLOWHIDDENDIR=/dev/.lxc # # Allow the specified hidden file to be whitelisted. # # This option may be specified more than once, and may use wildcard characters. # # The default value is the null string. # #ALLOWHIDDENFILE=/usr/share/man/man1/..1.gz #ALLOWHIDDENFILE=/usr/bin/.fipscheck.hmac #ALLOWHIDDENFILE=/usr/bin/.ssh.hmac #ALLOWHIDDENFILE=/usr/lib/.libfipscheck.so.1.1.0.hmac #ALLOWHIDDENFILE=/usr/lib/hmaccalc/sha1hmac.hmac #ALLOWHIDDENFILE=/usr/lib/hmaccalc/sha256hmac.hmac #ALLOWHIDDENFILE=/usr/sbin/.sshd.hmac #ALLOWHIDDENFILE=/usr/share/man/man5/.k5login.5.gz -ALLOWHIDDENFILE=/etc/.etckeeper +#ALLOWHIDDENFILE=/usr/share/man/man5/.k5identity.5.gz ALLOWHIDDENFILE=/etc/.gitignore #ALLOWHIDDENFILE=/etc/.bzrignore - +ALLOWHIDDENFILE=/etc/.etckeeper # # Allow the specified process to use deleted files. The process name may be -# followed by a colon-separated list of full pathnames. The process will then -# only be whitelisted if it is using one of the given files. For example: +# followed by a colon-separated list of full pathnames (which have been +# deleted). The process will then only be whitelisted if it is using one of +# the given pathnames. For example: # # ALLOWPROCDELFILE=/usr/libexec/gconfd-2:/tmp/abc:/var/tmp/xyz # # This option may be specified more than once. It may also use wildcards, but -# only in the file names. +# only in the deleted file pathnames, not in the process name. The use of +# extended pattern matching in pathname expansion (for example, '**') is not +# supported for this option. However, the option itself extends globbing when +# the '*' character is used by matching zero or more characters in the +# pathname, including those in sub-directories. For example, the pathname +# '/tmp/abc/def/xyz' would not be matched by shell globbing using '/tmp/*/xyz' +# but is matched when used in this option. Similarly, using '/tmp/*' will +# match any file found in the '/tmp' directory or any sub-directories. # # The default value is the null string. # #ALLOWPROCDELFILE=/sbin/cardmgr #ALLOWPROCDELFILE=/usr/lib/libgconf2-4/gconfd-2 #ALLOWPROCDELFILE=/usr/sbin/mysqld:/tmp/ib* -#ALLOWPROCDELFILE=/usr/lib/iceweasel/firefox-bin +#ALLOWPROCDELFILE=/usr/lib/iceweasel/iceweasel #ALLOWPROCDELFILE=/usr/bin/file-roller # # Allow the specified process to listen on any network interface. # # This option may be specified more than once, and may use wildcard characters. # # The default value is the null string. # #ALLOWPROCLISTEN=/sbin/dhclient #ALLOWPROCLISTEN=/usr/bin/dhcpcd #ALLOWPROCLISTEN=/usr/sbin/tcpdump #ALLOWPROCLISTEN=/usr/sbin/snort-plain # # Allow the specified network interfaces to be in promiscuous mode. # # This is a space-separated list of interface names. The option may be # specified more than once. # @@ -690,40 +722,80 @@ ALLOWHIDDENFILE=/etc/.gitignore # it is highly recommended that this value is used. # # The default value is 'THOROUGH'. # # Also see the ALLOWDEVFILE option. # #SCAN_MODE_DEV=THOROUGH # # Allow the specified file to be present in the '/dev' directory, and not # regarded as suspicious. # # This option may be specified more than once, and may use wildcard characters. # # The default value is the null string. # #ALLOWDEVFILE=/dev/shm/pulse-shm-* #ALLOWDEVFILE=/dev/shm/sem.ADBE_* # +# Allow the specified process pathnames to use shared memory segments. +# +# This option may be specified more than once, and may use wildcard characters. +# +# The default value is the null string. +# +#ALLOWIPCPROC=/usr/bin/firefox +#ALLOWIPCPROC=/usr/bin/vlc + +# +# Allow the specified memory segment creator PIDs to use shared memory segments. +# +# This is a space-separated list of PID numbers (as given by the +# 'ipcs -p' command). This option may be specified more than once. +# +# The default value is the null string. +# +#ALLOWIPCPID=12345 6789 + +# +# Allow the specified account names to use shared memory segments. +# +# This is a space-separated list of account names. The option may be specified +# more than once. +# +# The default value is the null string. +# +#ALLOWIPCUSER=usera userb + +# +# This option can be used to set the maximum shared memory segment size +# (in bytes) that is not considered suspicious. Any segment above this size, +# and with 600 or 666 permissions, will be considered suspicious during the +# shared memory check. +# +# The default is 1048576 (1M) bytes. +# +#IPC_SEG_SIZE=1048576 + +# # This option is used to indicate if the Phalanx2 test is to perform a basic # check, or a more thorough check. If the option is set to '0', then a basic # check is performed. If it is set to '1', then all the directories in the # '/etc' and '/usr' directories are scanned. # # NOTE: Setting this option to '1' will cause the test to take longer # to complete. # # The default value is '0'. # #PHALANX2_DIRTEST=0 # # This option tells rkhunter where the inetd configuration file is located. # # The default value is the null string. # #INETD_CONF_PATH=/etc/inetd.conf # @@ -759,92 +831,93 @@ ALLOWHIDDENFILE=/etc/.gitignore # This option tells rkhunter where the xinetd configuration file is located. # # The default value is the null string. # #XINETD_CONF_PATH=/etc/xinetd.conf # # This option allows the specified enabled xinetd services. Whilst it would be # nice to use the service names themselves, at the time of testing we only have # the pathname available. As such, these entries are the xinetd file pathnames. # # This is a space-separated list of service names. The option may be specified # more than once. # # The default value is the null string. # #XINETD_ALLOWED_SVC=/etc/xinetd.d/echo # # This option tells rkhunter the local system startup file pathnames. The -# directories will be searched for files. By default rkhunter will try and -# determine were the startup files are located. If the option is set to 'NONE', -# then certain tests will be skipped. +# directories will be searched for files. If unset, then rkhunter will try +# and determine were the startup files are located. If the option is set to +# 'NONE' then certain tests will be skipped. # # This is a space-separated list of file and directory pathnames. The option # may be specified more than once, and may use wildcard characters. # # This option has no default value. # #STARTUP_PATHS=/etc/init.d /etc/rc.local # # This option tells rkhunter the pathname to the file containing the user -# account passwords. This setting will be worked out by rkhunter, and so -# should not usually need to be set. Users of TCB shadow files should not -# set this option. +# account passwords. If unset, this setting will be worked out by rkhunter, +# and so should not usually need to be set. Users of TCB shadow files should +# not set this option. # # This option has no default value. # #PASSWORD_FILE=/etc/shadow # # This option allows the specified accounts to be root equivalent. These # accounts will have a UID value of zero. The 'root' account does not need # to be listed as it is automatically whitelisted. # # This is a space-separated list of account names. The option may be specified # more than once. # # NOTE: For *BSD systems you will probably need to use this option for the # 'toor' account. # # The default value is the null string. # #UID0_ACCOUNTS=toor rooty sashroot # # This option allows the specified accounts to have no password. NIS/YP entries # do not need to be listed as they are automatically whitelisted. # # This is a space-separated list of account names. The option may be specified # more than once. # # The default value is the null string. # #PWDLESS_ACCOUNTS=abc # # This option tells rkhunter the pathname to the syslog configuration file. -# This setting will be worked out by rkhunter, and so should not usually need -# to be set. A value of 'NONE' can be used to indicate that there is no -# configuration file, but that the syslog daemon process may be running. +# If unset, this setting will be worked out by rkhunter, and so should not +# usually need to be set. A value of 'NONE' can be used to indicate that +# there is no configuration file, but that the syslog daemon process may +# be running. # # This is a space-separated list of pathnames. The option may be specified # more than once. # # This option has no default value. # #SYSLOG_CONFIG_FILE=/etc/syslog.conf # # If this option is set to '1', then the use of syslog remote logging is # permitted. A value of '0' disallows the use of remote logging. # # The default value is '0'. # #ALLOW_SYSLOG_REMOTE_LOGGING=0 # # This option allows the specified applications, or a specific version of an # application, to be whitelisted. If a specific version is to be whitelisted, # then the name must be followed by a colon and then the version number. @@ -879,51 +952,63 @@ ALLOWHIDDENFILE=/etc/.gitignore # #SUSPSCAN_DIRS=/tmp /var/tmp # # This option specifies the directory for temporary files used by the # 'suspscan' test. A memory-based directory, such as a tempfs filesystem, is # better (faster). Do not use a directory name that is listed in SUSPSCAN_DIRS # as that is highly likely to cause false-positive results. # # The default value is '/dev/shm'. # #SUSPSCAN_TEMP=/dev/shm # # This option specifies the 'suspscan' test maximum filesize in bytes. Files # larger than this will not be inspected. Do make sure you have enough space # available in your temporary files directory. # # The default value is '1024000'. # -#SUSPSCAN_MAXSIZE=10240000 +#SUSPSCAN_MAXSIZE=1024000 # # This option specifies the 'suspscan' test score threshold. Below this value # no hits will be reported. # # The default value is '200'. # #SUSPSCAN_THRESH=200 # +# This option may be used to whitelist file pathnames from the suspscan test. +# +# Shell globbing may be used in the pathname. Also see the GLOBSTAR configuration +# option. +# +# This option may be specified more than once. +# +# The default value is the null string. +# +#SUSPSCAN_WHITELIST="" + +# # The following options can be used to whitelist network ports which are known # to have been used by malware. # # The PORT_WHITELIST option is a space-separated list of one or more of two # types of whitelisting. These are: # # 1) a 'protocol:port' pair # 2) an asterisk ('*') # # Only the UDP or TCP protocol may be specified, and the port number must be # between 1 and 65535 inclusive. # # The asterisk can be used to indicate that any executable which rkhunter can # locate as a command, is whitelisted. (Also see BINDIR) # # The PORT_PATH_WHITELIST option specifies one of two types of whitelisting. # These are: # # 1) a pathname to an executable # 2) a combined pathname, protocol and port @@ -1059,90 +1144,105 @@ ALLOWHIDDENFILE=/etc/.gitignore #READLINK_CMD=BUILTIN # # In the file properties test any modification date/time is displayed as the # number of epoch seconds. Rkhunter will try and use the 'date' command, or # failing that the 'perl' command, to display the date and time in a # human-readable format as well. This option may be used if some other command # should be used instead. The given command must understand the '%s' and # 'seconds ago' options found in the GNU 'date' command. # # A value of 'NONE' may be used to request that only the epoch seconds be shown. # A value of 'PERL' may be used to force rkhunter to use the 'perl' command, if # it is present. # # This option has no default value. # #EPOCH_DATE_CMD="" # # This setting tells rkhunter the directory containing the available Linux -# kernel modules. This setting will be worked out by rkhunter, and so should -# not usually need to be set. +# kernel modules. If unset, this setting will be worked out by rkhunter, and +# so should not usually need to be set. # # This option has no default value. # #MODULES_DIR="" # # The following option can be set to a command which rkhunter will use when # downloading files from the Internet - that is, when the '--update' or # '--versioncheck' option is used. The command can take options. # # This allows the user to use a command other than the one automatically # selected by rkhunter, but still one which it already knows about. # For example: # # WEB_CMD=curl # # Alternatively, the user may specify a completely new command. However, note # that rkhunter expects the downloaded file to be written to stdout, and that # everything written to stderr is ignored. For example: # # WEB_CMD="/opt/bin/dlfile --timeout 5m -q" # # *BSD users may want to use the 'ftp' command, provided that it supports the # HTTP protocol: # # WEB_CMD="ftp -o -" # # This option has no default value. # -#WEB_CMD="" +WEB_CMD="/bin/false" # # Set the following option to '1' if locking is to be used when rkhunter runs. # The lock is set just before logging starts, and is removed when the program # ends. It is used to prevent items such as the log file, and the file # properties file, from becoming corrupted if rkhunter is running more than -# once. The mechanism used is to simply create a lock file in the TMPDIR +# once. The mechanism used is to simply create a lock file in the LOCKDIR # directory. If the lock file already exists, because rkhunter is already # running, then the current process simply loops around sleeping for 10 seconds # and then retrying the lock. A value of '0' means not to use locking. # # The default value is '0'. # -# Also see the LOCK_TIMEOUT and SHOW_LOCK_MSGS options. +# Also see the LOCKDIR, LOCK_TIMEOUT and SHOW_LOCK_MSGS options. # #USE_LOCKING=0 # +# This option specifies the directory to be used when locking is enabled. +# If the option is unset, then the directory to be used will be worked out +# by rkhunter. In that instance the directories '/run/lock', '/var/lock', +# '/var/run/lock', '/run' and '/var/run' will be checked in turn. If none +# of those can be found, or are not read/writeable, then the TMPDIR directory +# will be used. +# +# To avoid the lock file persisting across a server reboot, the directory +# used should be memory-resident. +# +# This option has no default value. +# +#LOCKDIR="" + +# # If locking is used, then rkhunter may have to wait to get the lock file. # This option sets the total amount of time, in seconds, that rkhunter should # wait. It will retry the lock every 10 seconds, until either it obtains the # lock or the timeout value has been reached. # # The default value is 300 seconds (5 minutes). # #LOCK_TIMEOUT=300 # # If locking is used, then rkhunter may be doing nothing for some time if it # has to wait for the lock. If this option is set to '1', then some simple # messages are echoed to the users screen to let them know that rkhunter is # waiting for the lock. Set this option to '0' if the messages are not to be # displayed. # # The default value is '1'. # #SHOW_LOCK_MSGS=1 @@ -1174,56 +1274,40 @@ ALLOWHIDDENFILE=/etc/.gitignore # list, and will be executed in the order given. # # This option may be specified more than once. # # The default value is 'sys' in order to maintain compatibility with older # versions of 'unhide'. # #UNHIDE_TESTS=sys # # The following option can be used to set options for the 'unhide-tcp' command. # The options are space-separated. # # This option may be specified more than once. # # The default value is the null string. # #UNHIDETCP_OPTS="" # -# If both the C 'unhide', and Ruby 'unhide.rb', programs exist on the system, -# then it is possible to disable the execution of one of the programs if -# desired. By default rkhunter will look for both programs, and execute each -# of them as they are found. If the value of this option is '0', then both -# programs will be executed if they are present. A value of '1' will disable -# execution of the C 'unhide' program, and a value of '2' will disable the Ruby -# 'unhide.rb' program. To disable both programs, then disable the -# 'hidden_procs' test. -# -# The default value is '0'. -# -DISABLE_UNHIDE=1 - -INSTALLDIR=/usr - -# # This option can be set to either '0' or '1'. If set to '1' then the summary, # shown after rkhunter has run, will display the actual number of warnings # found. If it is set to '0', then the summary will simply indicate that # 'One or more' warnings were found. If no warnings were found, and this option # is set to '1', then a "0" will be shown. If the option is set to '0', then # the words 'No warnings' will be shown. # # The default value is '0'. # #SHOW_SUMMARY_WARNINGS_NUMBER=0 # # This option is used to determine where, if anywhere, the summary scan time is # displayed. A value of '0' indicates that it should not be displayed anywhere. # A value of '1' indicates that the time should only appear on the screen, and a # value of '2' that it should only appear in the log file. A value of '3' # indicates that the time taken should appear both on the screen and in the log # file. # # The default value is '3'. @@ -1232,20 +1316,42 @@ INSTALLDIR=/usr # # The two options below may be used to check if a file is missing or empty # (that is, it has a size of zero). The EMPTY_LOGFILES option will also check # if the file is missing, since that can be interpreted as a file of no size. # However, the file will only be reported as missing if the MISSING_LOGFILES # option hasn't already done this. # # Both options are space-separated lists of pathnames, and may be specified # more than once. # # NOTE: Log files are usually 'rotated' by some mechanism. At that time it is # perfectly possible for the file to be either missing or empty. As such these # options may produce false-positive warnings when log files are rotated. # # For both options the default value is the null string. # #EMPTY_LOGFILES="" #MISSING_LOGFILES="" +# +# This option can be set to either '0' or '1'. If set to '1' then the globbing +# characters '**' can be used to allow the recursive checking of directories. +# This can be useful, for example, with the USER_FILEPROP_FILES_DIRS option. +# For example: +# +# USER_FILEPROP_FILES_DIRS=/etc/**/*.conf +# +# This will check all '.conf' files within the '/etc' directory, and any +# sub-directories (at any level). If GLOBSTAR is not set, then the shell will +# interpret '**' as '*' and only one level of sub-directories will be checked. +# +# NOTE: This option is only valid for those shells which support the 'globstar' +# option. Typically this will be 'bash' (version 4 and above) via the 'shopt' command, +# and 'ksh' via the 'set' command. +# +# The default value is '0'. +# +#GLOBSTAR=0 + +INSTALLDIR=/usr + diff --git a/roles/common/files/etc/rsyslog.conf b/roles/common/files/etc/rsyslog.conf index 6ebaa92..42b01c5 100644 --- a/roles/common/files/etc/rsyslog.conf +++ b/roles/common/files/etc/rsyslog.conf @@ -1,45 +1,41 @@ -# /etc/rsyslog.conf Configuration file for rsyslog. +# /etc/rsyslog.conf configuration file for rsyslog # -# For more information see -# /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html +# For more information install rsyslog-doc and see +# /usr/share/doc/rsyslog-doc/html/configuration/index.html ################# #### MODULES #### ################# -$ModLoad imuxsock # provides support for local system logging -$ModLoad imklog # provides kernel logging support -#$ModLoad immark # provides --MARK-- message capability +module(load="imuxsock") # provides support for local system logging +module(load="imklog") # provides kernel logging support +#module(load="immark") # provides --MARK-- message capability # provides UDP syslog reception -#$ModLoad imudp -#$UDPServerRun 514 +#module(load="imudp") +#input(type="imudp" port="514") # provides TCP syslog reception -#$ModLoad imtcp -#$InputTCPServerRun 514 - -# Disable rate-limiting (the default for rsyslog v7, but not for rsyslog v5) -$SystemLogRateLimitInterval 0 -$SystemLogRateLimitBurst 0 +#module(load="imtcp") +#input(type="imtcp" port="514") ########################### #### GLOBAL DIRECTIVES #### ########################### # # Use traditional timestamp format. # To enable high precision timestamps, comment out the following line. # $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat # # Set the default permissions for all log files. # $FileOwner root $FileGroup adm $FileCreateMode 0640 $DirCreateMode 0755 $Umask 0022 @@ -62,74 +58,45 @@ $IncludeConfig /etc/rsyslog.d/*.conf # # Logging for the mail system. Split it up so that # it is easy to write scripts to parse these files. # mail.* -/var/log/mail.log mail.info -/var/log/mail.info mail.warn -/var/log/mail.warn mail.err /var/log/mail.err # To preserve the privacy of our users, we stop processing relevant log # entries (eg, we don't put them into /var/log/syslog) that are of # severity info and lower. Those lines are put into mail.log and # mail.info for troubleshooting, but those files are rotated frequently. # XXX: we should improve that: we shouldn't log envelopes and IPs unless # the mail is bounced, for instance. if $programname == 'amavis' and $syslogfacility-text == 'mail' and $syslogseverity >= 5 then ~ if ($programname startswith 'postfix-' or $programname == 'dovecot') and $syslogfacility-text == 'mail' and $syslogseverity >= 6 then ~ # -# Some standard log files. Log by facility. +# First some standard log files. Log by facility. # -auth,authpriv.* /var/log/auth.log +auth,authpriv.* /var/log/auth.log *.*;auth,authpriv.none -/var/log/syslog #cron.* /var/log/cron.log daemon.* -/var/log/daemon.log kern.* -/var/log/kern.log lpr.* -/var/log/lpr.log user.* -/var/log/user.log # -# Logging for INN news system. -# -news.crit /var/log/news/news.crit -news.err /var/log/news/news.err -news.notice -/var/log/news/news.notice - -# # Some "catch-all" log files. # *.=debug;\ auth,authpriv.none;\ - news.none;mail.none -/var/log/debug + mail.none -/var/log/debug *.=info;*.=notice;*.=warn;\ auth,authpriv.none;\ cron,daemon.none;\ - mail,news.none -/var/log/messages + mail.none -/var/log/messages # # Emergencies are sent to everybody logged in. # *.emerg :omusrmsg:* - -# -# I like to have messages displayed on the console, but only on a virtual -# console I usually leave idle. -# -#daemon,mail.*;\ -# news.=crit;news.=err;news.=notice;\ -# *.=debug;*.=info;\ -# *.=notice;*.=warn /dev/tty8 - -# The named pipe /dev/xconsole is for the `xconsole' utility. To use it, -# you must invoke `xconsole' with the `-file' option: -# -# $ xconsole -file /dev/xconsole [...] -# -# NOTE: adjust the list below, or you'll go crazy if you have a reasonably -# busy site.. -# -#daemon.*;mail.*;\ -# news.err;\ -# *.=debug;*.=info;\ -# *.=notice;*.=warn |/dev/xconsole diff --git a/roles/common/files/etc/samhain/samhainrc b/roles/common/files/etc/samhain/samhainrc deleted file mode 100644 index 7f304b7..0000000 --- a/roles/common/files/etc/samhain/samhainrc +++ /dev/null @@ -1,711 +0,0 @@ -##################################################################### -# -# Configuration file template for samhain. -# -##################################################################### -# -# -- empty lines and lines starting with '#', ';' or '//' are ignored -# -- boolean options can be Yes/No or True/False or 1/0 -# -- you can PGP clearsign this file -- samhain will check (if compiled -# with support) or otherwise ignore the signature -# -- CHECK mail address -# -# To each log facility, you can assign a threshold severity. Only -# reports with at least the threshold severity will be logged -# to the respective facility (even further below). -# -##################################################################### -# -# SETUP for file system checking: -# -# (i) There are several policies, each has its own section. Put files -# into the section for the appropriate policy (see below). -# (ii) Section [EventSeverity]: -# To each policy, you can assign a severity (further below). -# (iii) Section [Log]: -# To each log facility, you can assign a threshold severity. Only -# reports with at least the threshold severity will be logged -# to the respective facility (even further below). -# -##################################################################### - -##################################################################### -# -# Files are defined with: file = /absolute/path -# -# Directories are defined with: dir = /absolute/path -# or with an optional recursion depth (N <= 99): dir = N/absolute/path -# -# Directory inodes are checked. If you only want to check files -# in a directory, but not the directory inode itself, use (e.g.): -# -# [ReadOnly] -# dir = /some/directory -# [IgnoreAll] -# file = /some/directory -# -# You can use shell-style globbing patterns, like: file = /path/foo* -# -###################################################################### - -[Misc] -## -## Add or subtract tests from the policies -## - if you want to change their definitions, -## you need to do that before using the policies -## -# RedefReadOnly = (no default) -# RedefAttributes=(no default) -# RedefLogFiles=(no default) -# RedefGrowingLogFiles=(no default) -# RedefIgnoreAll=(no default) -# RedefIgnoreNone=(no default) -# RedefUser0=(no default) -# RedefUser1=(no default) -FileNamesAreUTF8 = yes -# Switch off hardlink check for BTRFS -UseHardlinkCheck=no - -[Attributes] -## -## for these files, only changes in permissions and ownership are checked -## -file=/etc/mtab -#file=/etc/ssh_random_seed -#file=/etc/asound.conf -file=/etc/resolv.conf -file=/etc/localtime -#file=/etc/ioctl.save -#file=/etc/passwd.backup -#file=/etc/shadow.backup -#file=/etc/postfix/prng_exch -file=/etc/adjtime -file=/etc/network/run/ifstate -#file=/etc/lvm/.cache -file=/etc/ld.so.cache - -# -# There are files in /etc that might change, thus changing the directory -# timestamps. Put it here as 'file', and in the ReadOnly section as 'dir'. -# -file=/etc - -[LogFiles] -## -## for these files, changes in signature, timestamps, and size are ignored -## -file=/var/run/utmp -file=/etc/motd - - - -##################################################################### -# -# This would be the proper syntax for parts that should only be -# included for certain hosts. -# You may enclose anything in a @HOSTNAME/@end bracket, as long as the -# result still has the proper syntax for the config file. -# You may have any number of @HOSTNAME/@end brackets. -# HOSTNAME should be the fully qualified 'official' name -# (e.g. 'nixon.watergate.com', not 'nixon'), no aliases. -# No IP number - except if samhain cannot determine the -# fully qualified hostname. -# -# @HOSTNAME -# file=/foo/bar -# @end -# -# These are two examples for conditional inclusion/exclusion -# of a machine based on the output from 'uname -srm' -# -# $Linux:2.*.7:i666 -# file=/foo/bar3 -# $end -# -# !$Linux:2.*.7:i686 -# file=/foo/bar2 -# $end -# -##################################################################### - -[GrowingLogFiles] -## -## for these files, changes in signature, timestamps, and increase in size -## are ignored -## -#file=/var/log/warn -file=/var/log/messages -file=/var/log/wtmp -file=/var/log/faillog -file=/var/log/auth.log -file=/var/log/daemon.log -file=/var/log/user.log -file=/var/log/kern.log -file=/var/log/syslog - - -[IgnoreAll] -## -## for these files, no modifications are reported -## -## This file might be created or removed by the system sometimes. -## -#file=/etc/resolv.conf.pcmcia.save -#file=/etc/nologin -file=/etc/network/run -file=/etc/.etckeeper -dir=-1/etc/.git - - -[IgnoreNone] -## -## for these files, all modifications (even access time) are reported -## - you may create some interesting-looking file (like /etc/safe_passwd), -## just to watch whether someone will access it ... -## - -[Prelink] -## -## Use for prelinked files or directories holding them -## - - -[ReadOnly] -## -## for these files, only access time is ignored -## -dir=/usr/bin -dir=/bin -dir=/boot -# -# SuSE (old) has the boot init scripts in /sbin/init.d/*, -# so we go 3 levels deep -# -dir=3/sbin -dir=/usr/sbin -dir=/lib -# -# RedHat and Debian have the bootinit scripts in /etc/init.d/* or /etc/rc.d/*, -# so we go 3 levels deep there too -# -dir=3/etc - -# Various directories / files that may include / be SUID/SGID binaries -# -# -file=/usr/lib/pt_chown -# X11, in Debian X7 this is now a symlink -#dir=/usr/X11R6/bin -#dir=/usr/X11R6/lib/X11/xmcd/bin -# Apache: -#file=/usr/lib/apache/suexec -#file=/usr/lib/apache/suexec.disabled -# Extra directories: -#dir=/opt/gnome/bin -#dir=/opt/kde/bin - -[User0] -[User1] -## User0 and User1 are sections for files/dirs with user-definable checking -## (see the manual) - - -[EventSeverity] -## -## Here you can assign severities to policy violations. -## If this severity exceeds the treshold of a log facility (see below), -## a policy violation will be logged to that facility. -## -## Severity for verification failures. -## -# SeverityReadOnly=crit -# SeverityLogFiles=crit -# SeverityGrowingLogs=crit -# SeverityIgnoreNone=crit -# SeverityAttributes=crit -# SeverityUser0=crit -# SeverityUser1=crit - -# Default behaviour -SeverityReadOnly=crit -SeverityLogFiles=crit -SeverityGrowingLogs=warn -SeverityIgnoreNone=crit -SeverityAttributes=crit - - -## -## We have a file in IgnoreAll that might or might not be present. -## Setting the severity to 'info' prevents messages about deleted/new file. -## -# SeverityIgnoreAll=crit -SeverityIgnoreAll=info - -## Files : file access problems -# SeverityFiles=crit - -## Dirs : directory access problems -# SeverityDirs=crit - -## Names : suspect (non-printable) characters in a pathname -# SeverityNames=crit - -# Default behaviour -SeverityFiles=crit -SeverityDirs=crit -SeverityNames=warn - - -[Log] -## -## Switch on/OFF log facilities and set their threshold severity -## -## Values: debug, info, notice, warn, mark, err, crit, alert, none. -## 'mark' is used for timestamps. -## -## -## Use 'none' to SWITCH OFF a log facility -## -## By default, everything equal to and above the threshold is logged. -## The specifiers '*', '!', and '=' are interpreted as -## 'all', 'all but', and 'only', respectively (like syslogd(8) does, -## at least on Linux). Examples: -## MailSeverity=* -## MailSeverity=!warn -## MailSeverity==crit - -## E-mail -## -MailSeverity=crit - -## Console -## -PrintSeverity=none - -## Logfile -## -LogSeverity=warn - -## Syslog -## -SyslogSeverity=alert - -## Remote server (yule) -## -# ExportSeverity=none - -## External script or program -## -# ExternalSeverity = none - -## Logging to a database -## -# DatabaseSeverity = none - - - - - -##################################################### -# -# Optional modules -# -##################################################### - -# [SuidCheck] -## -## --- Check the filesystem for SUID/SGID binaries -## - -## Switch on -# -# SuidCheckActive = yes - -## Interval for check (seconds) -# -# SuidCheckInterval = 7200 - -## Alternative: crontab-like schedule -# -# SuidCheckSchedule = NULL - -## Directory to exclude -# -# SuidCheckExclude = NULL - -## Limit on files per second (0 == no limit) -# -# SuidCheckFps = 0 - -## Alternative: yield after every file -# -# SuidCheckYield = no - -## Severity of a detection -# -# SeveritySuidCheck = crit - -## Quarantine SUID/SGID files if found -# -# SuidCheckQuarantineFiles = yes - -## Method for Quarantining files: -# 0 - Delete or truncate the file. -# 1 - Remove SUID/SGID permissions from file. -# 2 - Move SUID/SGID file to quarantine dir. -# -# SuidCheckQuarantineMethod = 0 - -## For method 1 and 3, really delete instead of truncating -# -# SuidCheckQuarantineDelete = yes - -# [Kernel] -## -## --- Check for loadable kernel module rootkits (Linux/FreeBSD only) -## - -## Switch on/off -# -# KernelCheckActive = True - -## Check interval (seconds); btw., the check is VERY fast -# -# KernelCheckInterval = 300 - -## Severity -# -# SeverityKernel = crit - - -# [Utmp] -## -## --- Logging of login/logout events -## - -## Switch on/off -# -# LoginCheckActive = True - -## Severity for logins, multiple logins, logouts -# -# SeverityLogin=info -# SeverityLoginMulti=warn -# SeverityLogout=info - -## Interval for login/logout checks -# -# LoginCheckInterval = 300 - - -# [Database] -## -## --- Logging to a relational database -## - -## Database name -# -# SetDBName = samhain - -## Database table -# -# SetDBTable = log - -## Database user -# -# SetDBUser = samhain - -## Database password -# -# SetDBPassword = (default: none) - -## Database host -# -# SetDBHost = localhost - -## Log the server timestamp for received messages -# -# SetDBServerTstamp = True - -## Use a persistent connection -# -# UsePersistent = True - -# [External] -## -## Interface to call external scripts/programs for logging -## - -## The absolute path to the command -## - Each invocation of this directive will end the definition of the -## preceding command, and start the definition of -## an additional, new command -# -# OpenCommand = (no default) - -## Type (log or rv) -## - log for log messages, srv for messages received by the server -# -# SetType = log - -## The command (full command line) to execute -# -# SetCommandLine = (no default) - -## The environment (KEY=value; repeat for more) -# -# SetEnviron = TZ=(your timezone) - -## The TIGER192 checksum (optional) -# -# SetChecksum = (no default) - -## User who runs the command -# -# SetCredentials = (default: samhain process uid) - -## Words not allowed in message -# -# SetFilterNot = (none) - -## Words required (ALL of them) -# -# SetFilterAnd = (none) - -## Words required (at least one) -# -# SetFilterOr = (none) - -## Deadtime between consecutive calls -# -# SetDeadtime = 0 - -## Add default environment (HOME, PATH, SHELL) -# -# SetDefault = no - - -##################################################### -# -# Miscellaneous configuration options -# -##################################################### - -[Misc] - -## whether to become a daemon process -## (this is not honoured on database initialisation) -# -# Daemon = no -Daemon = yes - -## whether to test signature of files (init/check/none) -## - if 'none', then we have to decide this on the command line - -# -# ChecksumTest = none -ChecksumTest=check - -## whether to drop linux capabilities that are not required -## - will make a root process a 'mere mortal' in many respects -# -# UseCaps = yes - -## Set nice level (-19 to 19, see 'man nice'), -## and I/O limit (kilobytes per second; 0 == off) -## to reduce load on host. -# -SetNiceLevel = 19 -# SetIOLimit = 0 - -## The version string to embed in file signature databases -# -# VersionString = NULL - -## Interval between time stamp messages -# -# SetLoopTime = 60 -SetLoopTime = 21600 - -## Interval between file checks -# -# SetFileCheckTime = 600 -SetFileCheckTime = 7200 - -## Alternative: crontab-like schedule -# -# FileCheckScheduleOne = NULL - -## Alternative: crontab-like schedule(2) -# -# FileCheckScheduleTwo = NULL - -## Report only once on modified fles -## Setting this to 'FALSE' will generate a report for any policy -## violation (old and new ones) each time the daemon checks the file system. -# -# ReportOnlyOnce = True - -## Report in full detail -# -# ReportFullDetail = False - -## Report file timestamps in local time rather than GMT -# -# UseLocalTime = No - -## The console device (can also be a file or named pipe) -## - There are two console devices. Accordingly, you can use -## this directive a second time to set the second console device. -## If you have not defined the second device at compile time, -## and you don't want to use it, then: -## setting it to /dev/null is less effective than just leaving -## it alone (setting to /dev/null will waste time by opening -## /dev/null and writing to it) -# -# SetConsole = /dev/console - -## Activate the SysV IPC message queue -# -# MessageQueueActive = False - - -## If false, skip reverse lookup when connecting to a host known -## by name rather than IP address (i.e. trust the DNS) -# -# SetReverseLookup = True - -## --- E-Mail --- - -# Only highest-level (alert) reports will be mailed immediately, -# others will be queued. Here you can define, when the queue will -# be flushed (Note: the queue is automatically flushed after -# completing a file check). -# -SetMailTime = 86400 - -## Maximum number of mails to queue -# -SetMailNum = 10 - -## Recipient (max. 8) -# -SetMailAddress = admin@fripost.org - -## Mail relay (IP address) -# -# XXX: it's unfortunate that samhain cannot use the sendmail binary. We -# use a custom port here to avoid conflicts with the usual SMTP port the -# MX:es need to listen on. -# See also: /usr/share/doc/samhain/TODO.Debian -SetMailRelay = 127.0.0.1 -SetMailPort = 16132 - -## Custom subject format -# -MailSubject = [Samhain at %H] %T: %S - -## --- end E-Mail --- - -## Path to the prelink executable -# -# SetPrelinkPath = /usr/sbin/prelink - -## TIGER192 checksum of the prelink executable -# -# SetPrelinkChecksum = (no default) - - -## Path to the executable. If set, will be checksummed after startup -## and before exit. -# -# SamhainPath = (no default) - - -## The IP address of the log server -# -# SetLogServer = (default: compiled-in) - -## The IP address of the time server -# -# SetTimeServer = (default: compiled-in) - -## Trusted Users (comma delimited list of user names) -# -# TrustedUser = (no default; this adds to the compiled-in list) - -## Path to the file signature database -# -# SetDatabasePath = (default: compiled-in) - -## Path to the log file -# -# SetLogfilePath = (default: compiled-in) - -## Path to the PID file -# -# SetLockPath = (default: compiled-in) - - -## The digest/checksum/hash algorithm -# -# DigestAlgo = TIGER192 - - -## Custom format for message header. -## CAREFUL if you use XML logfile format. -## -## %S severity -## %T timestamp -## %C class -## -## %F source file -## %L source line -# -# MessageHeader="%S %T " - - -## Don't log path to config/database file on startup -# -# HideSetup = False - -## The syslog facility, if you log to syslog -# -# SyslogFacility = LOG_AUTHPRIV -SyslogFacility=LOG_LOCAL2 - -## The message authentication method -## - If you change this, you *must* change it -## on client *and* server -# -# MACType = HMAC-TIGER - - -## everything below is ignored -[EOF] - -##################################################################### -# This would be the proper syntax for parts that should only be -# included for certain hosts. -# You may enclose anything in a @HOSTNAME/@end bracket, as long as the -# result still has the proper syntax for the config file. -# You may have any number of @HOSTNAME/@end brackets. -# HOSTNAME should be the fully qualified 'official' name -# (e.g. 'nixon.watergate.com', not 'nixon'), no aliases. -# No IP number - except if samhain cannot determine the -# fully qualified hostname. -# -# @HOSTNAME -# file=/foo/bar -# @end -# -# These are two examples for conditional inclusion/exclusion -# of a machine based on the output from 'uname -srm' -# $Linux:2.*.7:i666 -# file=/foo/bar3 -# $end -# -# !$Linux:2.*.7:i686 -# file=/foo/bar2 -# $end -# -##################################################################### diff --git a/roles/common/files/etc/strongswan.d/charon.conf b/roles/common/files/etc/strongswan.d/charon.conf new file mode 100644 index 0000000..efb241c --- /dev/null +++ b/roles/common/files/etc/strongswan.d/charon.conf @@ -0,0 +1,419 @@ +# Options for the charon IKE daemon. +charon { + + # Deliberately violate the IKE standard's requirement and allow the use of + # private algorithm identifiers, even if the peer implementation is unknown. + # accept_private_algs = no + + # Accept unencrypted ID and HASH payloads in IKEv1 Main Mode. + # accept_unencrypted_mainmode_messages = no + + # Maximum number of half-open IKE_SAs (including unprocessed IKE_SA_INITs) + # for a single peer IP. + # block_threshold = 5 + + # Whether Certificate Revocation Lists (CRLs) fetched via HTTP or LDAP + # should be saved under a unique file name derived from the public key of + # the Certification Authority (CA) to /etc/ipsec.d/crls (stroke) or + # /etc/swanctl/x509crl (vici), respectively. + # cache_crls = no + + # Whether relations in validated certificate chains should be cached in + # memory. + # cert_cache = yes + + # Whether to use DPD to check if the current path still works after any + # changes to interfaces/addresses. + # check_current_path = no + + # Send the Cisco FlexVPN vendor ID payload (IKEv2 only). + # cisco_flexvpn = no + + # Send Cisco Unity vendor ID payload (IKEv1 only). + # cisco_unity = no + + # Close the IKE_SA if setup of the CHILD_SA along with IKE_AUTH failed. + # close_ike_on_child_failure = no + + # Number of half-open IKE_SAs (including unprocessed IKE_SA_INITs) that + # activate the cookie mechanism. + # cookie_threshold = 30 + + # Number of half-open IKE_SAs (including unprocessed IKE_SA_INITs) for a + # single peer IP that activate the cookie mechanism. + # cookie_threshold_ip = 3 + + # Delete CHILD_SAs right after they got successfully rekeyed (IKEv1 only). + # delete_rekeyed = no + + # Delay in seconds until inbound IPsec SAs are deleted after rekeyings + # (IKEv2 only). + # delete_rekeyed_delay = 5 + + # Use ANSI X9.42 DH exponent size or optimum size matched to cryptographic + # strength. + # dh_exponent_ansi_x9_42 = yes + + # Use RTLD_NOW with dlopen when loading plugins and IMV/IMCs to reveal + # missing symbols immediately. + # dlopen_use_rtld_now = no + + # DNS server assigned to peer via configuration payload (CP). + # dns1 = + + # DNS server assigned to peer via configuration payload (CP). + # dns2 = + + # Enable Denial of Service protection using cookies and aggressiveness + # checks. + # dos_protection = yes + + # Free objects during authentication (might conflict with plugins). + # flush_auth_cfg = no + + # Whether to follow IKEv2 redirects (RFC 5685). + # follow_redirects = yes + + # Violate RFC 5998 and use EAP-only authentication even if the peer did not + # send an EAP_ONLY_AUTHENTICATION notify during IKE_AUTH. + # force_eap_only_authentication = no + + # Maximum size (complete IP datagram size in bytes) of a sent IKE fragment + # when using proprietary IKEv1 or standardized IKEv2 fragmentation, defaults + # to 1280 (use 0 for address family specific default values, which uses a + # lower value for IPv4). If specified this limit is used for both IPv4 and + # IPv6. + # fragment_size = 1280 + + # Name of the group the daemon changes to after startup. + # group = + + # Timeout in seconds for connecting IKE_SAs (also see IKE_SA_INIT DROPPING). + # half_open_timeout = 30 + + # Enable hash and URL support. + # hash_and_url = no + + # Allow IKEv1 Aggressive Mode with pre-shared keys as responder. + # i_dont_care_about_security_and_use_aggressive_mode_psk = no + + # Whether to ignore the traffic selectors from the kernel's acquire events + # for IKEv2 connections (they are not used for IKEv1). + # ignore_acquire_ts = no + + # A space-separated list of routing tables to be excluded from route + # lookups. + # ignore_routing_tables = + + # Maximum number of IKE_SAs that can be established at the same time before + # new connection attempts are blocked. + # ikesa_limit = 0 + + # Number of exclusively locked segments in the hash table. + # ikesa_table_segments = 1 + + # Size of the IKE_SA hash table. + # ikesa_table_size = 1 + + # Whether to close IKE_SA if the only CHILD_SA closed due to inactivity. + inactivity_close_ike = yes + + # Limit new connections based on the current number of half open IKE_SAs, + # see IKE_SA_INIT DROPPING in strongswan.conf(5). + # init_limit_half_open = 0 + + # Limit new connections based on the number of queued jobs. + # init_limit_job_load = 0 + + # Causes charon daemon to ignore IKE initiation requests. + # initiator_only = no + + # Install routes into a separate routing table for established IPsec + # tunnels. + install_routes = no + + # Install virtual IP addresses. + install_virtual_ip = no + + # The name of the interface on which virtual IP addresses should be + # installed. + # install_virtual_ip_on = + + # Check daemon, libstrongswan and plugin integrity at startup. + # integrity_test = no + + # A comma-separated list of network interfaces that should be ignored, if + # interfaces_use is specified this option has no effect. + # interfaces_ignore = + + # A comma-separated list of network interfaces that should be used by + # charon. All other interfaces are ignored. + # interfaces_use = + + # NAT keep alive interval. + # keep_alive = 20s + + # Number of seconds the keep alive interval may be exceeded before a DPD is + # sent instead of a NAT keep alive (0 to disable). This is only useful if a + # clock is used that includes time spent suspended (e.g. CLOCK_BOOTTIME). + # keep_alive_dpd_margin = 0s + + # Plugins to load in the IKE daemon charon. + # load = + + # Determine plugins to load via each plugin's load option. + # load_modular = no + + # Initiate IKEv2 reauthentication with a make-before-break scheme. + # make_before_break = no + + # Maximum number of IKEv1 phase 2 exchanges per IKE_SA to keep state about + # and track concurrently. + # max_ikev1_exchanges = 3 + + # Maximum packet size accepted by charon. + # max_packet = 10000 + + # Enable multiple authentication exchanges (RFC 4739). + # multiple_authentication = yes + + # WINS servers assigned to peer via configuration payload (CP). + # nbns1 = + + # WINS servers assigned to peer via configuration payload (CP). + # nbns2 = + + # UDP port used locally. If set to 0 a random port will be allocated. + # port = 500 + + # UDP port used locally in case of NAT-T. If set to 0 a random port will be + # allocated. Has to be different from charon.port, otherwise a random port + # will be allocated. + # port_nat_t = 4500 + + # Whether to prefer updating SAs to the path with the best route. + # prefer_best_path = no + + # Prefer locally configured proposals for IKE/IPsec over supplied ones as + # responder (disabling this can avoid keying retries due to + # INVALID_KE_PAYLOAD notifies). + # prefer_configured_proposals = yes + + # Controls whether permanent or temporary IPv6 addresses are used as source, + # or announced as additional addresses if MOBIKE is used. + # prefer_temporary_addrs = no + + # Process RTM_NEWROUTE and RTM_DELROUTE events. + # process_route = yes + + # How RDNs in subject DNs of certificates are matched against configured + # identities (strict, reordered, or relaxed). + # rdn_matching = strict + + # Delay in ms for receiving packets, to simulate larger RTT. + # receive_delay = 0 + + # Delay request messages. + # receive_delay_request = yes + + # Delay response messages. + # receive_delay_response = yes + + # Specific IKEv2 message type to delay, 0 for any. + # receive_delay_type = 0 + + # Size of the AH/ESP replay window, in packets. + # replay_window = 32 + + # Base to use for calculating exponential back off, see IKEv2 RETRANSMISSION + # in strongswan.conf(5). + # retransmit_base = 1.8 + + # Maximum jitter in percent to apply randomly to calculated retransmission + # timeout (0 to disable). + # retransmit_jitter = 0 + + # Upper limit in seconds for calculated retransmission timeout (0 to + # disable). + # retransmit_limit = 0 + + # Timeout in seconds before sending first retransmit. + # retransmit_timeout = 4.0 + + # Number of times to retransmit a packet before giving up. + # retransmit_tries = 5 + + # Interval in seconds to use when retrying to initiate an IKE_SA (e.g. if + # DNS resolution failed), 0 to disable retries. + # retry_initiate_interval = 0 + + # Initiate CHILD_SA within existing IKE_SAs (always enabled for IKEv1). + # reuse_ikesa = yes + + # Numerical routing table to install routes to. + # routing_table = + + # Priority of the routing table. + # routing_table_prio = + + # Whether to use RSA with PSS padding instead of PKCS#1 padding by default. + # rsa_pss = no + + # Whether to encode an explicit trailerField value of 0x01 in the RSA-PSS + # algorithmIdentifier (CONTEXT3) or using the DEFAULT value by omitting it. + # rsa_pss_trailerfield = no + + # Delay in ms for sending packets, to simulate larger RTT. + # send_delay = 0 + + # Delay request messages. + # send_delay_request = yes + + # Delay response messages. + # send_delay_response = yes + + # Specific IKEv2 message type to delay, 0 for any. + # send_delay_type = 0 + + # Send strongSwan vendor ID payload + # send_vendor_id = no + + # Whether to enable Signature Authentication as per RFC 7427. + # signature_authentication = yes + + # Whether to enable constraints against IKEv2 signature schemes. + # signature_authentication_constraints = yes + + # Value mixed into the local IKE SPIs after applying spi_mask. + # spi_label = 0x0000000000000000 + + # Mask applied to local IKE SPIs before mixing in spi_label (bits set will + # be replaced with spi_label). + # spi_mask = 0x0000000000000000 + + # The upper limit for SPIs requested from the kernel for IPsec SAs. + # spi_max = 0xcfffffff + + # The lower limit for SPIs requested from the kernel for IPsec SAs. + # spi_min = 0xc0000000 + + # Number of worker threads in charon. + # threads = 16 + + # Name of the user the daemon changes to after startup. + # user = + + crypto_test { + + # Benchmark crypto algorithms and order them by efficiency. + # bench = no + + # Buffer size used for crypto benchmark. + # bench_size = 1024 + + # Time in ms during which crypto algorithm performance is measured. + # bench_time = 50 + + # Test crypto algorithms during registration (requires test vectors + # provided by the test-vectors plugin). + # on_add = no + + # Test crypto algorithms on each crypto primitive instantiation. + # on_create = no + + # Strictly require at least one test vector to enable an algorithm. + # required = no + + # Whether to test RNG with TRUE quality; requires a lot of entropy. + # rng_true = no + + } + + host_resolver { + + # Maximum number of concurrent resolver threads (they are terminated if + # unused). + # max_threads = 3 + + # Minimum number of resolver threads to keep around. + # min_threads = 0 + + } + + leak_detective { + + # Includes source file names and line numbers in leak detective output. + # detailed = yes + + # Threshold in bytes for allocations to be included in usage reports (0 + # to include all). + # usage_threshold = 10240 + + # Threshold in number of allocations for allocations to be included in + # usage reports (0 to include all). + # usage_threshold_count = 0 + + } + + processor { + + # Section to configure the number of reserved threads per priority class + # see JOB PRIORITY MANAGEMENT in strongswan.conf(5). + priority_threads { + + } + + } + + # Section containing a list of scripts (name = path) that are executed when + # the daemon is started. + start-scripts { + + } + + # Section containing a list of scripts (name = path) that are executed when + # the daemon is terminated. + stop-scripts { + + } + + tls { + + # List of TLS encryption ciphers. + # cipher = + + # List of TLS key exchange groups. + # ke_group = + + # List of TLS key exchange methods. + # key_exchange = + + # List of TLS MAC algorithms. + # mac = + + # Whether to include CAs in a server's CertificateRequest message. + # send_certreq_authorities = yes + + # List of TLS signature schemes. + # signature = + + # List of TLS cipher suites. + # suites = + + # Maximum TLS version to negotiate. + # version_max = 1.2 + + # Minimum TLS version to negotiate. + # version_min = 1.2 + + } + + x509 { + + # Discard certificates with unsupported or unknown critical extensions. + # enforce_critical = yes + + } + +} + diff --git a/roles/common/files/etc/strongswan.d/charon/socket-default.conf b/roles/common/files/etc/strongswan.d/charon/socket-default.conf new file mode 100644 index 0000000..abf4650 --- /dev/null +++ b/roles/common/files/etc/strongswan.d/charon/socket-default.conf @@ -0,0 +1,23 @@ +socket-default { + + # Firewall mark to set on outbound packets. + # fwmark = + + # Whether to load the plugin. Can also be an integer to increase the + # priority of this plugin. + load = yes + + # Set source address on outbound packets, if possible. + # set_source = yes + + # Force sending interface on outbound packets, if possible. + # set_sourceif = no + + # Listen on IPv4, if possible. + # use_ipv4 = yes + + # Listen on IPv6, if possible. + # use_ipv6 = yes + +} + diff --git a/roles/common/files/etc/systemd/system/bacula-fd.service.d/override.conf b/roles/common/files/etc/systemd/system/bacula-fd.service.d/override.conf new file mode 100644 index 0000000..537bf1e --- /dev/null +++ b/roles/common/files/etc/systemd/system/bacula-fd.service.d/override.conf @@ -0,0 +1,13 @@ +[Service] +# Hardening +NoNewPrivileges=yes +ProtectHome=read-only +ProtectSystem=strict +ReadWriteDirectories=/var/lib/bacula +PrivateTmp=yes +PrivateDevices=yes +ProtectControlGroups=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 +CapabilityBoundingSet=CAP_DAC_READ_SEARCH diff --git a/roles/common/files/etc/systemd/system/fail2ban.service.d/override.conf b/roles/common/files/etc/systemd/system/fail2ban.service.d/override.conf new file mode 100644 index 0000000..b34d130 --- /dev/null +++ b/roles/common/files/etc/systemd/system/fail2ban.service.d/override.conf @@ -0,0 +1,21 @@ +[Unit] +After=nftables.service + +[Service] +ExecStartPre= +ExecStart= +ExecStart=/usr/bin/fail2ban-server -xf --logtarget=sysout start + +# Need explicit rights to read logs as we don't grant CAP_DAC_READ_SEARCH +SupplementaryGroups=adm + +# Hardening +NoNewPrivileges=yes +ProtectSystem=strict +RuntimeDirectory=fail2ban +PrivateDevices=yes +ProtectControlGroups=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +RestrictAddressFamilies=AF_UNIX AF_NETLINK +CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW diff --git a/roles/common/files/etc/systemd/system/munin-node.service.d/override.conf b/roles/common/files/etc/systemd/system/munin-node.service.d/override.conf new file mode 100644 index 0000000..fee16b3 --- /dev/null +++ b/roles/common/files/etc/systemd/system/munin-node.service.d/override.conf @@ -0,0 +1,14 @@ +[Service] +ExecStartPre= + +# Hardening +NoNewPrivileges=yes +ProtectSystem=strict +ReadWriteDirectories=/var/lib/munin-node/plugin-state +ReadWriteDirectories=/var/log/munin +RuntimeDirectory=munin +ProtectControlGroups=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 +CapabilityBoundingSet=CAP_SETUID CAP_SETGID diff --git a/roles/common/files/etc/systemd/system/stunnel4.service b/roles/common/files/etc/systemd/system/stunnel4.service new file mode 100644 index 0000000..990e07b --- /dev/null +++ b/roles/common/files/etc/systemd/system/stunnel4.service @@ -0,0 +1,14 @@ +# This service is actually a systemd target, +# but we are using a service since targets cannot be reloaded. + +[Unit] +Description=SSL tunnel for network daemons (multi-instance-master) + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/bin/true +ExecReload=/bin/true + +[Install] +WantedBy=multi-user.target diff --git a/roles/common/files/etc/systemd/system/stunnel4@.service b/roles/common/files/etc/systemd/system/stunnel4@.service new file mode 100644 index 0000000..4d69702 --- /dev/null +++ b/roles/common/files/etc/systemd/system/stunnel4@.service @@ -0,0 +1,32 @@ +[Unit] +Description=SSL tunnel for network daemons (instance %i) +Documentation=man:stunnel4(8) +After=network.target nss-lookup.target +PartOf=stunnel4.service +ReloadPropagatedFrom=stunnel4.service + +[Service] +DynamicUser=yes +; force dynamic user/group allocation (stunnel4 user exists already) +User=_stunnel4-%i +Group=_stunnel4-%i +ExecStart=/usr/bin/stunnel4 /etc/stunnel/%i.conf +ExecReload=/bin/kill -HUP ${MAINPID} +KillSignal=SIGINT +TimeoutStartSec=120 +TimeoutStopSec=60 +Restart=on-failure + +# Hardening +NoNewPrivileges=yes +PrivateDevices=yes +ProtectHome=yes +ProtectSystem=strict +PrivateDevices=yes +ProtectControlGroups=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +RestrictAddressFamilies=AF_INET AF_INET6 + +[Install] +WantedBy=multi-user.target diff --git a/roles/common/files/lib/systemd/system/bacula-fd.service b/roles/common/files/lib/systemd/system/bacula-fd.service deleted file mode 100644 index 6e2bbd4..0000000 --- a/roles/common/files/lib/systemd/system/bacula-fd.service +++ /dev/null @@ -1,12 +0,0 @@ -[Unit] -Description=Bacula File Daemon service -After=network.target - -[Service] -Type=forking -PIDFile=/var/run/bacula/bacula-fd.9112.pid -StandardOutput=syslog -ExecStart=/usr/sbin/bacula-fd -c /etc/bacula/bacula-fd.conf - -[Install] -WantedBy=multi-user.target diff --git a/roles/common/files/usr/local/bin/gendhparam.sh b/roles/common/files/usr/local/bin/gendhparam.sh index 074986b..a94175a 100755 --- a/roles/common/files/usr/local/bin/gendhparam.sh +++ b/roles/common/files/usr/local/bin/gendhparam.sh @@ -1,13 +1,10 @@ #!/bin/sh set -ue PATH=/usr/bin:/bin -privkey="$1" +out="$1" bits="${2:-2048}" -rand= -mv -f "$(mktemp)" "$privkey" -chmod og-rwx "$privkey" - -openssl dhparam -rand "${rand:-/dev/urandom}" "$bits" >"$privkey" +install --mode=0644 /dev/null "$out" +openssl dhparam -rand /dev/urandom "$bits" >"$out" diff --git a/roles/common/files/usr/local/bin/genkeypair.sh b/roles/common/files/usr/local/bin/genkeypair.sh index 5bf67f2..72102f4 100755 --- a/roles/common/files/usr/local/bin/genkeypair.sh +++ b/roles/common/files/usr/local/bin/genkeypair.sh @@ -4,202 +4,194 @@ # certificates or Certificate Signing Requests, or DKIM private keys. # Inspired from make-ssl-cert(8) and opendkim-genkey(8). # # Copyright © 2014 Guilhem Moulin <guilhem@fripost.org> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. set -ue PATH=/usr/bin:/bin +export PATH # Default values type=rsa bits= hash= force=0 config= pubkey=pubkey.pem privkey=privkey.pem dns= ou= cn= usage= -chmod= -chown= -rand= +mode= +owner= +group= usage() { cat >&2 <<- EOF Usage: $0 command [OPTIONS] Command: x509: generate a self-signed X.509 server certificate csr: generate a Certificate Signing Request dkim: generate a private key (to use for DKIM signing) + keypair: generate a key pair Options: -t type: key type (default: rsa) -b bits: key length or EC curve (default: 2048 for RSA, 1024 for DSA, secp224r1 for ECDSA) -h digest: digest algorithm --ou: organizational Unit Name; can be repeated --cn: common Name (default: \$(hostname --fqdn) --dns: hostname for AltName; can be repeated -f: force; can be repeated (0: don't overwrite, default; 1: reuse private key if it exists; 2: overwrite both keys if they exist) --config: configuration file --pubkey: public key file (default: pubkey.pem) - --privkey: private key file (default: privkey.pem; created with og-rwx) + --privkey: private key file (default: privkey.pem) --usage: key usage (default: digitalSignature,keyEncipherment,keyCertSign) - --chmod: chmod the private key - --chown: chown the private key + --mode: set privkey's permission mode (default: 0600) + --owner: set privkey's owner (default: the process' current owner) + --group: set privkey's group (default: the process' current group) Return values: 0 The key pair was successfully generated 1 The public or private key file exists, and -f is not set 2 The key generation failed EOF } -dkiminfo() { - echo "Add the following TXT record to your DNS zone:" - echo "${cn:-$(date +%Y%m%d)}._domainkey\tIN\tTXT ( " - # See https://tools.ietf.org/html/rfc4871#section-3.6.1 - # t=s: the "i=" domain in signature headers MUST NOT be a subdomain of "d=" - # s=email: limit DKIM signing to email - openssl pkey -pubout <"$privkey" | sed '/^--.*--$/d' \ - | { echo -n "v=DKIM1; k=$type; t=s; s=email; p="; tr -d '\n'; } \ - | fold -w 250 \ - | { sed 's/.*/\t"&"/'; echo ' )'; } -} - [ $# -gt 0 ] || { usage; exit 2; } cmd="$1"; shift case "$cmd" in - x509|csr|dkim) ;; + x509|csr|dkim|keypair) ;; *) echo "Unrecognized command: $cmd" >&2; exit 2 esac nou=1 while [ $# -gt 0 ]; do case "$1" in -t) shift; type="$1";; -t*) type="${1#-t}";; -b) shift; bits="$1";; -b*) bits="${1#-b}";; -h) shift; hash="$1";; -h*) hash="${1#-h}";; --dns=?*) dns="${dns:+$dns, }DNS:${1#--dns=}";; --cn=?*) cn="${1#--cn=}";; --ou=?*) ou="${ou:+$ou\n}$nou.organizationalUnitName = ${1#--ou=}" nou=$(( 1 + $nou ));; -f) force=$(( 1 + $force ));; --pubkey=?*) pubkey="${1#--pubkey=}";; --privkey=?*) privkey="${1#--privkey=}";; --usage=?*) usage="${usage:+$usage,}${1#--usage=}";; - --config=?*) dns="${1#--config=}";; + --config=?*) config="${1#--config=}";; - --chmod=?*) chmod="${1#--chmod=}";; - --chown=?*) chown="${1#--chown=}";; + --mode=?*) mode="${1#--mode=}";; + --owner=?*) owner="${1#--owner=}";; + --group=?*) group="${1#--group=}";; --help) usage; exit;; *) echo "Unrecognized argument: $1" >&2; exit 2 esac shift; done case "$type" in # XXX: genrsa and dsaparam have been deprecated in favor of genpkey. # genpkey can also create explicit EC parameters, but not named. - rsa) genkey=genrsa; genkeyargs="-f4 ${bits:-2048}";; - dsa) genkey=dsaparam; genkeyargs="-noout -genkey ${bits:-1024}";; + rsa) genkey=genrsa; genkeyargs="-rand /dev/urandom -f4 ${bits:-2048}";; + dsa) genkey=dsaparam; genkeyargs="-rand /dev/urandom -noout -genkey ${bits:-1024}";; # See 'openssl ecparam -list_curves' for the list of supported # curves. StrongSwan doesn't support explicit curve parameters # (however explicit parameters might be required to make exotic # curves work with some clients.) ecdsa) genkey=ecparam - genkeyargs="-noout -name ${bits:-secp224r1} -param_enc named_curve -genkey";; + genkeyargs="-rand /dev/urandom -noout -name ${bits:-secp224r1} -param_enc named_curve -genkey";; + x25519|x448|ed25519|ed448) genkey=genpkey + genkeyargs="-algorithm $type";; *) echo "Unrecognized key type: $type" >&2; exit 2 esac if [ "$cmd" = x509 -o "$cmd" = csr ]; then case "$hash" in md5|rmd160|sha1|sha224|sha256|sha384|sha512|'') ;; *) echo "Invalid digest algorithm: $hash" >&2; exit 2; esac [ "$cn" ] || cn="$(hostname --fqdn)" [ ${#cn} -le 64 ] || { echo "CommonName too long: $cn" >&2; exit 2; } fi if [ -z "$config" -a \( "$cmd" = x509 -o "$cmd" = csr \) ]; then config=$(mktemp) || exit 2 trap 'rm -f "$config"' EXIT # see /usr/share/ssl-cert/ssleay.cnf cat >"$config" <<- EOF [ req ] distinguished_name = req_distinguished_name prompt = no policy = policy_anything req_extensions = v3_req x509_extensions = v3_req [ req_distinguished_name ] organizationName = Fripost organizationalUnitName = SSLcerts $(echo "$ou") - commonName = $cn + commonName = ${cn:-/} [ v3_req ] subjectAltName = email:admin@fripost.org${dns:+, $dns} basicConstraints = critical, CA:FALSE # https://security.stackexchange.com/questions/24106/which-key-usages-are-required-by-each-key-exchange-method keyUsage = critical, ${usage:-digitalSignature, keyEncipherment, keyCertSign} subjectKeyIdentifier = hash EOF fi if [ -s "$privkey" -a $force -eq 0 ]; then echo "Error: private key exists: $privkey" >&2 - [ "$cmd" = dkim ] && dkiminfo exit 1 elif [ ! -s "$privkey" -o $force -ge 2 ]; then - # Ensure "$privkey" is created with umask 0077 - mv -f "$(mktemp)" "$privkey" || exit 2 - chmod "${chmod:-og-rwx}" "$privkey" || exit 2 - [ -z "$chown" ] || chown "$chown" "$privkey" || exit 2 - openssl $genkey -rand "${rand:-/dev/urandom}" $genkeyargs >"$privkey" || exit 2 - [ "$cmd" = dkim ] && { dkiminfo; exit; } + install --mode="${mode:-0600}" ${owner:+--owner="$owner"} ${group:+--group="$group"} /dev/null "$privkey" || exit 2 + openssl $genkey $genkeyargs >"$privkey" || exit 2 + [ "$cmd" = dkim ] && exit fi if [ "$cmd" = x509 -a "$pubkey" = "$privkey" ]; then pubkey=$(mktemp) openssl req -config "$config" -new -x509 ${hash:+-$hash} -days 3650 -key "$privkey" >"$pubkey" || exit 2 cat "$pubkey" >>"$privkey" || exit 2 rm -f "$pubkey" elif [ "$cmd" = x509 -o "$cmd" = csr ]; then if [ -s "$pubkey" -a $force -eq 0 ]; then echo "Error: public key exists: $pubkey" >&2 exit 1 else [ "$cmd" = x509 ] && x509=-x509 || x509= openssl req -config "$config" -new $x509 ${hash:+-$hash} -days 3650 -key "$privkey" >"$pubkey" || exit 2 fi +elif [ "$cmd" = keypair -a "$pubkey" ]; then + openssl pkey -pubout <"$privkey" >"$pubkey" fi diff --git a/roles/common/files/usr/local/sbin/update-firewall b/roles/common/files/usr/local/sbin/update-firewall new file mode 100755 index 0000000..e11e8a9 --- /dev/null +++ b/roles/common/files/usr/local/sbin/update-firewall @@ -0,0 +1,61 @@ +#!/bin/bash + +set -ue +PATH=/usr/sbin:/usr/bin:/sbin:/bin +export PATH + +NFTABLES="/etc/nftables.conf" + +script="$(mktemp --tmpdir=/dev/shm)" +oldrules="$(mktemp --tmpdir=/dev/shm)" +newrules="$(mktemp --tmpdir=/dev/shm)" +netns= +cleanup(){ + rm -f -- "$script" "$oldrules" "$newrules" + [ -z "$netns" ] || ip netns del "$netns" +} +trap cleanup EXIT INT TERM + +echo "flush ruleset" >"$script" # should be included already, but... +cat <"$NFTABLES" >>"$script" + +ip netns add "nft-dryrun" +netns="nft-dryrun" + +declare -a INTERFACES=() +for iface in /sys/class/net/*; do + idx="$(< "$iface/ifindex")" + INTERFACES[idx]="${iface#/sys/class/net/}" +done + +# create dummy interfaces so we can use iif/oif in the nft rules +# (we preserve indices to preserve canonical set representation) +for idx in "${!INTERFACES[@]}"; do + [ "${INTERFACES[idx]}" != "lo" ] || continue + ip netns exec "$netns" ip link add "${INTERFACES[idx]}" index "$idx" type dummy +done + +# clear sets in the old rules before diff'ing with the new ones +nft -sn list ruleset >"$oldrules" +ip netns exec "$netns" nft -f - <"$oldrules" +ip netns exec "$netns" nft flush set inet filter fail2ban || true +ip netns exec "$netns" nft flush set inet filter fail2ban6 || true +ip netns exec "$netns" nft -sn list ruleset >"$oldrules" + +ip netns exec "$netns" nft -f - <"$script" +ip netns exec "$netns" nft -sn list ruleset >"$newrules" +ip netns del "$netns" +netns= + +if [ ! -t 0 ] || [ ! -t 1 ]; then + diff -q -- "$oldrules" "$newrules" && exit 0 || exit 1 +elif ! diff -u --color=auto --label=a/ruleset --label=b/ruleset \ + -- "$oldrules" "$newrules" && nft -f - <"$script"; then + read -p "Ruleset applied. Revert? [Y/n] " -r -t10 r || r="y" + if [ "${r,,[a-z]}" != "n" ]; then + echo "Reverting..." + echo "flush ruleset" >"$script" + cat <"$oldrules" >>"$script" + nft -f - <"$script" + fi +fi diff --git a/roles/common/files/usr/local/sbin/update-firewall.sh b/roles/common/files/usr/local/sbin/update-firewall.sh deleted file mode 100755 index f25f507..0000000 --- a/roles/common/files/usr/local/sbin/update-firewall.sh +++ /dev/null @@ -1,475 +0,0 @@ -#!/bin/bash - -# Create iptables (v4 and v6) rules. Unless one of [-f] or [-c] is -# given, or if the ruleset is unchanged, a confirmation is asked after -# loading the new rulesets; if the user answers No or doesn't answer, -# the old ruleset is restored. If the user answer Yes (or if the flag -# [-f] is given), the new ruleset is made persistent (requires a pre-up -# hook) by moving it to /etc/iptables/rules.v[46]. -# -# The [-c] flag switch to dry-run (check) mode. The rulesets are not -# applied, but merely checked against the existing ones. The return -# value is 0 iff. they do not differ. -# -# This firewall is only targeted towards end-servers, not gateways. In -# particular, there is no NAT'ing at the moment. -# -# Dependencies: netmask(1) -# -# Copyright © 2013 Guilhem Moulin <guilhem@fripost.org> -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -set -ue -PATH=/usr/sbin:/usr/bin:/sbin:/bin -timeout=10 - -force=0 -check=0 -verbose=0 -addrfam= - -secmark=0xA99 # must match that in /etc/network/if-up.d/ipsec -secproto=esp # must match /etc/ipsec.conf; ESP is the default (vs AH/IPComp) - -fail2ban_re='^(\[[0-9]+:[0-9]+\]\s+)?-A fail2ban-\S' -IPSec_re=" -m policy --dir (in|out) --pol ipsec --reqid [0-9]+ --proto $secproto -j ACCEPT$" -declare -A rss=() tables=() - -usage() { - cat >&2 <<- EOF - Usage: $0 [OPTIONS] - - Options: - -f force: no confirmation asked - -c check: check (dry-run) mode - -v verbose: see the difference between old and new ruleset - -4 IPv4 only - -6 IPv6 only - EOF - exit 1 -} - -log() { - /usr/bin/logger -st firewall -p user.info -- "$@" -} -fatal() { - /usr/bin/logger -st firewall -p user.err -- "$@" - exit 1 -} - -iptables() { - # Fake iptables/ip6tables(8); use the more efficient - # iptables-restore(8) instead. - echo "$@" >> "$new"; -} -commit() { - # End a table - echo COMMIT >> "$new" -} -inet46() { - case "$1" in - 4) echo "$2";; - 6) echo "$3";; - esac -} -ipt-chains() { - # Define new (tables and) chains. - while [ $# -gt 0 ]; do - case "$1" in - ?*:*) echo ":${1%:*} ${1##*:} [0:0]";; - ?*) echo "*$1";; - esac - shift - done >> "$new" -} - -ipt-trim() { - # Remove dynamic chain/rules from the input stream, as they are - # automatically included by third-party servers (such as strongSwan - # or fail2ban). The output is ready to be made persistent. - grep -Ev -e '^:fail2ban-\S' \ - -e "$IPSec_re" \ - -e '-j fail2ban-\S+$' \ - -e "$fail2ban_re" -} - -ipt-diff() { - # Get the difference between two rulesets. - if [ $verbose -eq 1 ]; then - /usr/bin/diff -u -I '^#' "$1" "$2" - else - /usr/bin/diff -q -I '^#' "$1" "$2" >/dev/null - fi -} - -ipt-persist() { - # Make the current ruleset persistent. (Requires a pre-up hook - # script to load the rules before the network is configured.) - - log "Making ruleset persistent... " - [ -d /etc/iptables ] || mkdir /etc/iptables - - local f rs table - for f in "${!tables[@]}"; do - ipts=/sbin/$(inet46 $f iptables ip6tables)-save - rs=/etc/iptables/rules.v$f - - for table in ${tables[$f]}; do - /bin/ip netns exec $netns $ipts -t $table - done | ipt-trim > "$rs" - chmod 0600 "$rs" - done -} - -ipt-revert() { - [ $check -eq 0 ] || return - log "Reverting to old ruleset... " - - local rs - for f in "${!rss[@]}"; do - /sbin/$(inet46 $f iptables ip6tables)-restore -c < "${rss[$f]}" - rm -f "${rss[$f]}" - done - exit 1 -} - -run() { - # Build and apply the firewall for IPv4/6. - local f="$1" - local ipt=/sbin/$(inet46 $f iptables ip6tables) - tables[$f]=filter - - # The default interface associated with this address. - local if=$( /bin/ip -$f route show to default scope global \ - | sed -nr '/^default via \S+ dev (\S+).*/ {s//\1/p;q}' ) - - # The virtual interface reserved for IPSec. - local ifsec=$( /bin/ip -o -$f link show \ - | sed -nr "/^[0-9]+:\s+(sec[0-9]+)@$if:\s.*/ {s//\1/p;q}" ) - - # The (host-scoped) IP reserved for IPSec. - local ipsec= - if [ "$ifsec" -a $f = 4 ]; then - tables[$f]='mangle nat filter' - ipsec=$( /bin/ip -$f address show dev "$ifsec" scope host \ - | sed -nr '/^\s+inet\s(\S+).*/ {s//\1/p;q}' ) - fi - - # Store the old (current) ruleset - local old=$(mktemp --tmpdir current-rules.v$f.XXXXXX) \ - new=$(mktemp --tmpdir new-rules.v$f.XXXXXX) - for table in ${tables[$f]}; do - $ipt-save -ct $table - done > "$old" - rss[$f]="$old" - - local fail2ban=0 - # XXX: As of Wheezy, fail2ban is IPv4 only. See - # https://github.com/fail2ban/fail2ban/issues/39 for the current - # state of the art. - if [ "$f" = 4 ] && which /usr/bin/fail2ban-server >/dev/null; then - fail2ban=1 - fi - - # The usual chains in filter, along with the desired default policies. - ipt-chains filter INPUT:DROP FORWARD:DROP OUTPUT:DROP - - if [ ! "$if" ]; then - # If the interface is not configured, we stop here and DROP all - # packets by default. Thanks to the pre-up hook this tight - # policy will be activated whenever the interface goes up. - mv "$new" /etc/iptables/rules.v$f - return 0 - fi - - # Fail2ban-specific chains and traps - if [ $fail2ban -eq 1 ]; then - echo ":fail2ban - [0:0]" - # Don't remove existing rules & traps in the current rulest - grep -- '^:fail2ban-\S' "$old" || true - grep -E -- ' -j fail2ban-\S+$' "$old" || true - grep -E -- "$fail2ban_re" "$old" || true - fi >> "$new" - - if [ "$ipsec" ]; then - # (Host-to-host) IPSec tunnels come first. TODO: test IPSec with IPv6. - grep -E -- "$IPSec_re" "$old" >> "$new" || true - - # Allow any IPsec $secproto protocol packets to be sent and received. - iptables -A INPUT -i $if -p $secproto -j ACCEPT - iptables -A OUTPUT -o $if -p $secproto -j ACCEPT - fi - - - ######################################################################## - # DROP all RFC1918 addresses, martian networks, multicasts, ... - # Credits to http://newartisans.com/2007/09/neat-tricks-with-iptables/ - # http://baldric.net/loose-iptables-firewall-for-servers/ - - local ip - if [ "$f" = 4 ]; then - # Private-use networks (RFC 1918) and link local (RFC 3927) - local MyNetwork=$( /bin/ip -4 address show dev $if scope global \ - | sed -nr 's/^\s+inet\s(\S+).*/\1/p') - [ "$MyNetwork" ] && \ - for ip in 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 169.254.0.0/16; do - # Don't lock us out if we are behind a NAT ;-) - [ "$ip" = "$(/usr/bin/netmask -nc $ip $MyNetwork | sed 's/ //g')" ] \ - || iptables -A INPUT -i $if -s "$ip" -j DROP - done - - # Other martian packets: "This" network, multicast, broadcast (RFCs - # 1122, 3171 and 919). - for ip in 0.0.0.0/8 224.0.0.0/4 240.0.0.0/4 255.255.255.255/32; do - iptables -A INPUT -i $if -s "$ip" -j DROP - iptables -A INPUT -i $if -d "$ip" -j DROP - done - - elif [ "$f" = 6 ]; then - # Martian IPv6 packets: ULA (RFC 4193) and site local addresses - # (RFC 3879). - for ip in fc00::/7 fec0::/10; do - iptables -A INPUT -i $if -s "$ip" -j DROP - iptables -A INPUT -i $if -d "$ip" -j DROP - done - fi - - # DROP INVALID packets immediately. - iptables -A INPUT -m state --state INVALID -j DROP - iptables -A OUTPUT -m state --state INVALID -j DROP - - # DROP bogus TCP packets. - iptables -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP - iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP - iptables -A INPUT -p tcp \! --syn -m state --state NEW -j DROP - - # Allow all input/output to/from the loopback interface. - local localhost=$(inet46 $f '127.0.0.1/8' '::1/128') - iptables -A INPUT -i lo -s "$localhost" -d "$localhost" -j ACCEPT - iptables -A OUTPUT -o lo -s "$localhost" -d "$localhost" -j ACCEPT - - if [ "$ipsec" ]; then - # ACCEPT any, *IPSec* traffic destinating to the non-routable - # $ipsec. Also ACCEPT all traffic originating from $ipsec, as - # it is MASQUERADE'd. - iptables -A INPUT -d "$ipsec" -i $if -m policy --dir in \ - --pol ipsec --proto $secproto -j ACCEPT - iptables -A OUTPUT -m mark --mark "$secmark" -o $if -j ACCEPT - fi - - # Prepare fail2ban. We make fail2ban insert its rules in a - # dedicated chain, so that it doesn't mess up the existing rules. - [ $fail2ban -eq 1 ] && iptables -A INPUT -i $if -j fail2ban - - if [ "$f" = 4 ]; then - # Allow only ICMP of type 0, 3 and 8. The rate-limiting is done - # directly by the kernel (net.ipv4.icmp_ratelimit and - # net.ipv4.icmp_ratemask runtime options). See icmp(7). - local t - for t in 'echo-reply' 'destination-unreachable' 'echo-request'; do - iptables -A INPUT -p icmp -m icmp --icmp-type $t -j ACCEPT - iptables -A OUTPUT -p icmp -m icmp --icmp-type $t -j ACCEPT - done - elif [ $f = 6 ]; then - iptables -A INPUT -p icmpv6 -j ACCEPT - iptables -A OUTPUT -p icmpv6 -j ACCEPT - fi - - - ######################################################################## - # ACCEPT new connections to the services we provide, or to those we want - # to connect to. - - sed -re 's/#.*//; /^\s*$/d' -e "s/^(in|out|inout)$f?(\s.*)/\1\2/" \ - /etc/iptables/services | \ - grep -Ev '^(in|out|inout)\S\s' | \ - while read dir proto dport sport; do - # We add two entries per config line: we need to accept the new - # connection, and latter the reply. - local stNew=NEW,ESTABLISHED - local stEst=ESTABLISHED - - # In-Out means full-duplex - [[ "$dir" =~ ^inout ]] && stEst="$stNew" - - local iptNew= iptEst= optsNew= optsEst= - case "$dport" in - *,*|*:*) optsNew="--match multiport --dports $dport" - optsEst="--match multiport --sports $dport";; - ?*) optsNew="--dport $dport" - optsEst="--sport $dport";; - esac - case "$sport" in - *,*|*:*) optsNew+=" --match multiport --sports $sport" - optsEst+=" --match multiport --dports $sport";; - ?*) optsNew+=" --sport $sport" - optsEst+=" --dport $sport";; - esac - case "$dir" in - in|inout) iptNew="-A INPUT -i"; iptEst="-A OUTPUT -o";; - out) iptNew="-A OUTPUT -o"; iptEst="-A INPUT -i";; - *) fatal "Error: Unknown direction: '$dir'." - esac - - iptables $iptNew $if -p $proto $optsNew -m state --state $stNew -j ACCEPT - iptables $iptEst $if -p $proto $optsEst -m state --state $stEst -j ACCEPT - done - - ######################################################################## - commit - - if [ "$ipsec" ]; then - # DNAT the IPSec paquets to $ipsec after decapsulation, and SNAT - # them before encapsulation. We need to do the NAT'ing before - # packets enter the IPSec stack because they are signed - # afterwards, and NAT'ing would mess up the signature. - ipt-chains mangle PREROUTING:ACCEPT INPUT:ACCEPT \ - FORWARD:DROP \ - OUTPUT:ACCEPT POSTROUTING:ACCEPT - - # Packets which destination is $ipsec *must* be associated with - # an IPSec policy. - iptables -A INPUT -d "$ipsec" -i $if -m policy --dir in \ - --pol ipsec --proto $secproto -j ACCEPT - iptables -A INPUT -d "$ipsec" -i $if -j DROP - - # Packets originating from our (non-routable) $ipsec are marked; - # if there is no xfrm lookup (i.e., no matching IPSec - # association), the packet will retain its mark and be null - # routed later on. Otherwise, the packet is re-queued unmarked. - iptables -A OUTPUT -o $if -j MARK --set-mark 0x0 - iptables -A OUTPUT -s "$ipsec" -o $if -m policy --dir out \ - --pol none -j MARK --set-mark $secmark - commit - - ipt-chains nat PREROUTING:ACCEPT INPUT:ACCEPT \ - OUTPUT:ACCEPT POSTROUTING:ACCEPT - - # DNAT all marked packets after decapsulation. - iptables -A PREROUTING \! -d "$ipsec" -i $if -m policy --dir in \ - --pol ipsec --proto $secproto -j DNAT --to "${ipsec%/*}" - - # Packets originating from our IPSec are SNAT'ed (MASQUERADE). - # (And null-routed later on unless there is an xfrm - # association.) - iptables -A POSTROUTING -m mark --mark $secmark -o $if -j MASQUERADE - commit - fi - - ######################################################################## - - - local rv1=0 rv2=0 persistent=/etc/iptables/rules.v$f - local oldz=$(mktemp --tmpdir current-rules.v$f.XXXXXX) - - # Reset the counters. They are not useful for comparing and/or - # storing persistent ruleset. (We don't use sed -i because we want - # to restore the counters when reverting.) - sed -r -e '/^:/ s/\[[0-9]+:[0-9]+\]$/[0:0]/' \ - -e 's/^\[[0-9]+:[0-9]+\]\s+//' \ - "$old" > "$oldz" - - /usr/bin/uniq "$new" | /bin/ip netns exec $netns $ipt-restore || ipt-revert - - for table in ${tables[$f]}; do - /bin/ip netns exec $netns $ipt-save -t $table - done > "$new" - - ipt-diff "$oldz" "$new" || rv1=$? - - if ! [ -f "$persistent" -a -x /etc/network/if-pre-up.d/iptables ]; then - rv2=1 - else - ipt-trim < "$oldz" | ipt-diff - "$persistent" || rv2=$? - fi - - local update="Please run '${0##*/}'." - if [ $check -eq 0 ]; then - /usr/bin/uniq "$new" | $ipt-restore || ipt-revert - else - if [ $rv1 -ne 0 ]; then - log "WARN: The IPv$f firewall is not up to date! $update" - fi - if [ $rv2 -ne 0 ]; then - log "WARN: The current IPv$f firewall is not persistent! $update" - fi - fi - - rm -f "$oldz" "$new" - return $(( $rv1 | $rv2 )) -} - - -# Parse options -while [ $# -gt 0 ]; do - case "$1" in - -?*) for (( k=1; k<${#1}; k++ )); do - o="${1:$k:1}" - case "$o" in - 4|6) addrfam="$o";; - c) check=1;; - f) force=1;; - v) verbose=1;; - *) usage;; - esac - done - ;; - *) usage;; - esac - shift -done - -# If we are going to apply the ruleset, we should either have a TTY, or -# use -f. -if ! /usr/bin/tty -s && [ $force -eq 0 -a $check -eq 0 ]; then - echo "Error: Not a TTY. Try with -f (at your own risks!)" >&2 - exit 1 -fi - -# Create an alternative net namespace in which we apply the ruleset, so -# we can easily get a normalized version we can compare latter. See -# http://bugzilla.netfilter.org/show_bug.cgi?id=790 -netns="ipt-firewall-test-$$" -/bin/ip netns add $netns - -trap '/bin/ip netns del $netns 2>/dev/null || true; ipt-revert' SIGINT -trap '/bin/ip netns del $netns; rm -f "${rss[@]}"' EXIT - -rv=0 -for f in ${addrfam:=4 6}; do - run $f || rv=$(( $rv | $? )) -done - -if [ $force -eq 1 ]; then - # At the user's own risks... - ipt-persist - -elif [ $check -eq 1 -o $rv -eq 0 ]; then - # Nothing to do, we're all set. - exit $rv - -else - echo "Try now to establish NEW connections to the machine." - - read -n1 -t$timeout \ - -p "Are you sure you want to use the new ruleset? (y/N) " \ - ret 2>&1 || { [ $? -gt 128 ] && echo -n "Timeout..."; } - case "${ret:-N}" in - [yY]*) echo; ipt-persist - ;; - *) echo; ipt-revert - ;; - esac -fi diff --git a/roles/common/handlers/main.yml b/roles/common/handlers/main.yml index a852c4d..18462cb 100644 --- a/roles/common/handlers/main.yml +++ b/roles/common/handlers/main.yml @@ -1,54 +1,57 @@ # 'service: name=... state=started' tasks should NOT run if there is a # corresponding state=restarted handler. (Register the task notifying # the handler, and add a conditional.) --- - name: systemctl daemon-reload command: /bin/systemctl daemon-reload - name: Refresh hostname service: name=hostname.sh state=restarted - name: apt-get update apt: update_cache=yes -- name: Reload samhain - service: name=samhain state=reloaded +- name: Restart unbound + service: name=unbound state=restarted - name: Update rkhunter's data file command: /usr/bin/rkhunter --propupd +- name: Update firewall + command: /usr/local/sbin/update-firewall -c + - name: Restart fail2ban service: name=fail2ban state=restarted -- name: Reload networking - # /etc/init.d/networking doesn't answer the status command; but since - # it should be "up" whenever ansible has access to the machine, we use - # pattern=init as a dummy assumption. - service: name=networking pattern=init state=reloaded +- name: Restart IPsec + service: name=ipsec state=restarted - name: Restart rsyslog service: name=rsyslog state=restarted +- name: Restart systemd-resolved + service: name=systemd-resolved.service state=restarted + +- name: Restart systemd-timesyncd + service: name=systemd-timesyncd state=restarted + - name: Restart ntp service: name=ntp state=restarted - name: Restart Postfix service: name=postfix state=restarted - name: Reload Postfix service: name=postfix state=reloaded -- name: Restart stunnel - service: name=stunnel4 pattern=/usr/bin/stunnel4 state=restarted - - name: Restart bacula-fd service: name=bacula-fd state=restarted -- name: Update certificate - command: update-ca-certificates - - name: Restart munin-node service: name=munin-node state=restarted - name: Restart freshclam service: name=clamav-freshclam state=restarted + +- name: Update initramfs + command: /usr/sbin/update-initramfs -u diff --git a/roles/common/tasks/apt.yml b/roles/common/tasks/apt.yml index f444315..8df3e8f 100644 --- a/roles/common/tasks/apt.yml +++ b/roles/common/tasks/apt.yml @@ -1,49 +1,43 @@ - name: Install various APT tools - apt: pkg={{ item }} - with_items: + apt: pkg={{ packages }} + vars: + packages: - apt - apt-listchanges - apt-show-versions - debian-archive-keyring - debian-goodies - needrestart - unattended-upgrades - debfoster - deborphan - - debsecan - debsums - name: Configure APT (1) template: src=etc/apt/{{ item }}.j2 dest=/etc/apt/{{ item }} owner=root group=root mode=0644 with_items: - sources.list - preferences notify: - apt-get update - name: Configure APT (2) copy: src=etc/apt/{{ item }} dest=/etc/apt/{{ item }} owner=root group=root mode=0644 with_items: - listchanges.conf - apt.conf.d/10periodic - apt.conf.d/50unattended-upgrades -- name: Configure the Debian Security Analyzer - template: src=etc/default/debsecan.j2 - dest=/etc/default/debsecan - owner=root group=root - mode=0644 - - name: Start cron service: name=cron state=started tags: - cron # We should run 'apt-get update' before proceeding to any other task. - meta: flush_handlers diff --git a/roles/common/tasks/bacula.yml b/roles/common/tasks/bacula.yml index 248d47d..308e358 100644 --- a/roles/common/tasks/bacula.yml +++ b/roles/common/tasks/bacula.yml @@ -1,111 +1,33 @@ -- name: Install stunnel - apt: pkg=stunnel4 - -- name: Auto-enable stunnel - lineinfile: dest=/etc/default/stunnel4 - regexp='^(\s*#)?\s*ENABLED=' - line='ENABLED=1' - owner=root group=root - mode=0644 - -- name: Create /etc/stunnel/certs - file: path=/etc/stunnel/certs - state=directory - owner=root group=root - mode=0755 - -- name: Generate a private key and a X.509 certificate for Bacula FD - command: genkeypair.sh x509 - --pubkey=/etc/stunnel/certs/{{ inventory_hostname_short }}-fd.pem - --privkey=/etc/stunnel/certs/{{ inventory_hostname_short }}-fd.key - --ou=BaculaFD --cn={{ inventory_hostname }} --dns={{ inventory_hostname }} - -t rsa -b 4096 -h sha512 - register: r1 - changed_when: r1.rc == 0 - failed_when: r1.rc > 1 - notify: - - Restart stunnel - tags: - - genkey - -- name: Fetch Bacula FD X.509 certificate - # Ensure we don't fetch private data - sudo: False - fetch: src=/etc/stunnel/certs/{{ inventory_hostname_short }}-fd.pem - dest=certs/bacula/ - fail_on_missing=yes - flat=yes - tags: - - genkey - -- name: Copy Bacula Dir X.509 certificates - assemble: src=certs/bacula regexp="-dir\.pem$" remote_src=no - dest=/etc/stunnel/certs/bacula-dirs.pem - owner=root group=root - mode=0644 - register: r2 - when: "'bacula-dir' not in group_names" - notify: - - Restart stunnel - -- name: Copy Bacula SD X.509 certificates - copy: src=certs/bacula/{{ hostvars[item].inventory_hostname_short }}-sd.pem - dest=/etc/stunnel/certs/ - owner=root group=root - mode=0644 - register: r3 - with_items: groups['bacula-sd'] | difference([inventory_hostname]) - notify: - - Restart stunnel - -- name: Configure stunnel - template: src=etc/stunnel/bacula-fd.conf.j2 - dest=/etc/stunnel/bacula-fd.conf - owner=root group=root - mode=0644 - register: r4 - when: "'bacula-dir' not in group_names or 'bacula-sd' not in group_names" - notify: - - Restart stunnel - -- name: Start stunnel - service: name=stunnel4 pattern=/usr/bin/stunnel4 state=started - when: not (r1.changed or r2.changed or r3.changed or r4.changed) - -- meta: flush_handlers - - - - name: Install bacula-fd apt: pkg=bacula-fd - name: Create /var/lib/bacula/tmp file: path=/var/lib/bacula/tmp state=directory owner=root group=root mode=0700 - name: Delete /etc/bacula/common_default_passwords file: path=/etc/bacula/common_default_passwords state=absent -# Create with: +# Populate with: # echo $director-dir $(pwgen -sn 64 1) | sudo tee -a /etc/bacula/passwords-fd - name: Ensure /etc/bacula/passwords-fd exists file: path=/etc/bacula/passwords-fd state=file owner=root group=root mode=0600 - name: Configure bacula template: src=etc/bacula/bacula-fd.conf.j2 dest=/etc/bacula/bacula-fd.conf owner=root group=root mode=0644 notify: - Restart bacula-fd - name: Create /etc/bacula/ssl file: path=/etc/bacula/ssl state=directory owner=root group=root mode=0755 @@ -115,36 +37,42 @@ --pubkey=/etc/bacula/ssl/{{ inventory_hostname_short }}.pem --privkey=/etc/bacula/ssl/{{ inventory_hostname_short }}.pem --ou=BaculaFD --cn={{ inventory_hostname }} --dns={{ inventory_hostname }} -t rsa -b 4096 -h sha512 register: r changed_when: r.rc == 0 failed_when: r.rc > 1 notify: - Restart bacula-fd tags: - genkey - name: Copy the master public key for data encryption copy: src=certs/bacula/data-master.pem dest=/etc/bacula/ssl/master.pem owner=root group=root mode=0644 tags: - genkey -- name: Copy bacula-fd.service - copy: src=lib/systemd/system/bacula-fd.service - dest=/lib/systemd/system/bacula-fd.service +- name: Create /etc/systemd/system/bacula-fd.service.d + file: path=/etc/systemd/system/bacula-fd.service.d + state=directory + owner=root group=root + mode=0755 + +- name: Copy bacula-fd.service override + copy: src=etc/systemd/system/bacula-fd.service.d/override.conf + dest=/etc/systemd/system/bacula-fd.service.d/override.conf owner=root group=root mode=0644 notify: - systemctl daemon-reload - Restart bacula-fd - meta: flush_handlers - name: Enable bacula-fd service: name=bacula-fd enabled=yes - name: Start bacula-fd service: name=bacula-fd state=started diff --git a/roles/common/tasks/clamav.yml b/roles/common/tasks/clamav.yml index e1ece0d..437387b 100644 --- a/roles/common/tasks/clamav.yml +++ b/roles/common/tasks/clamav.yml @@ -1,22 +1,32 @@ - name: Install ClamAV - apt: pkg={{ item }} - with_items: + apt: pkg={{ packages }} + vars: + packages: - clamav - clamav-daemon - clamav-freshclam - name: Configure FreshClam - lineinfile: "dest=/etc/clamav/freshclam.conf - line='DatabaseMirror {{ item }}'" - with_items: - - db.local.clamav.net - - database.clamav.net - - db.other.clamav.net + template: src=etc/clamav/freshclam.conf.j2 + dest=/etc/clamav/freshclam.conf + owner=clamav group=adm + mode=0444 + tags: freshclam notify: - Restart freshclam - name: Start ClamAV service: name={{ item }} state=started with_items: - clamav-daemon - clamav-freshclam + +- name: Add a 'clamav' alias + lineinfile: dest=/etc/aliases create=yes + regexp="^clamav{{':'}} " + line="clamav{{':'}} root" + +- name: Compile the static local Postfix database + postmap: cmd=postalias src=/etc/aliases db=lmdb + owner=root group=root + mode=0644 diff --git a/roles/common/tasks/fail2ban.yml b/roles/common/tasks/fail2ban.yml index be26c79..563075f 100644 --- a/roles/common/tasks/fail2ban.yml +++ b/roles/common/tasks/fail2ban.yml @@ -1,28 +1,63 @@ - name: Install fail2ban apt: pkg=fail2ban -- name: Add addititional filters - copy: src=etc/fail2ban/filter.d/{{ item }} - dest=/etc/fail2ban/filter.d/{{ item }} +- name: Configure fail2ban (fail2ban.local) + copy: src=etc/fail2ban/fail2ban.local + dest=/etc/fail2ban/fail2ban.local owner=root group=root mode=0644 register: r1 - with_items: - - roundcube.conf notify: - Restart fail2ban -- name: Configure fail2ban +- name: Configure fail2ban (jail.local) template: src=etc/fail2ban/jail.local.j2 dest=/etc/fail2ban/jail.local owner=root group=root mode=0644 register: r2 notify: - Restart fail2ban +- name: Configure fail2ban (action.d/nftables-allports.local) + copy: src=etc/fail2ban/action.d/nftables-allports.local + dest=/etc/fail2ban/action.d/nftables-allports.local + owner=root group=root + mode=0644 + register: r3 + notify: + - Restart fail2ban + +- name: Copy filters + copy: src=etc/fail2ban/filter.d/ + dest=/etc/fail2ban/filter.d/ + owner=root group=root + mode=0644 + register: r4 + notify: + - Restart fail2ban + +- name: Create directory /etc/systemd/system/fail2ban.service.d + file: path=/etc/systemd/system/fail2ban.service.d + state=directory + owner=root group=root + mode=0755 + +- name: Harden fail2ban.service + copy: src=etc/systemd/system/fail2ban.service.d/override.conf + dest=/etc/systemd/system/fail2ban.service.d/override.conf + owner=root group=root + mode=0644 + register: r5 + notify: + - systemctl daemon-reload + - Restart fail2ban + - name: Start fail2ban service: name=fail2ban state=started - when: not (r1.changed or r2.changed) + when: not (r1.changed or r2.changed or r3.changed or r4.changed or r5.changed) - meta: flush_handlers + +- name: Delete /var/lib/fail2ban/fail2ban.sqlite3 + file: path=/var/lib/fail2ban/fail2ban.sqlite3 state=absent diff --git a/roles/common/tasks/firewall.yml b/roles/common/tasks/firewall.yml index 29c0e2b..fd1ad92 100644 --- a/roles/common/tasks/firewall.yml +++ b/roles/common/tasks/firewall.yml @@ -1,40 +1,27 @@ -- name: Install some packages required for the firewall - apt: pkg={{ item }} - with_items: - - iptables - - netmask - - bsdutils +- name: Install nftables + apt: pkg=nftables -- name: Create directory /etc/iptables - file: path=/etc/iptables - state=directory - owner=root group=root +- name: Copy /usr/local/sbin/update-firewall + copy: src=usr/local/sbin/update-firewall + dest=/usr/local/sbin/update-firewall + owner=root group=staff mode=0755 -- name: Generate /etc/iptables/services - template: src=etc/iptables/services.j2 - dest=/etc/iptables/services +- name: Copy /etc/nftables.conf + template: src=etc/nftables.conf.j2 + dest=/etc/nftables.conf owner=root group=root - mode=0600 - -- name: Copy /usr/local/sbin/update-firewall.sh - copy: src=usr/local/sbin/update-firewall.sh - dest=/usr/local/sbin/update-firewall.sh - owner=root group=root - mode=0755 - -- name: Make the rulesets persistent - copy: src=etc/network/{{ item }} - dest=/etc/network/{{ item }} - owner=root group=root - mode=0755 - with_items: - - if-pre-up.d/iptables - - if-post-down.d/iptables + mode=0644 - name: Ensure the firewall is up to date - command: /usr/local/sbin/update-firewall.sh -c + command: /usr/local/sbin/update-firewall -c register: rv # A non-zero return value will make ansible stop and show stderr. This # is what we want. changed_when: rv.rc + +- name: Enable nftables.service + service: name=nftables enabled=yes + +- name: Start nftables.service + service: name=nftables state=started diff --git a/roles/common/tasks/haveged.yml b/roles/common/tasks/haveged.yml deleted file mode 100644 index 3f03a28..0000000 --- a/roles/common/tasks/haveged.yml +++ /dev/null @@ -1,5 +0,0 @@ -- name: Install haveged - apt: pkg=haveged - -- name: Start haveged - service: name=haveged state=started diff --git a/roles/common/tasks/ipsec.yml b/roles/common/tasks/ipsec.yml new file mode 100644 index 0000000..917c687 --- /dev/null +++ b/roles/common/tasks/ipsec.yml @@ -0,0 +1,93 @@ +- name: Install strongSwan + apt: pkg={{ packages }} + vars: + packages: + - strongswan-charon + - strongswan-starter + # for the GCM and openssl plugins + - libstrongswan-standard-plugins + notify: + - Update firewall + - Restart IPsec + +- name: Auto-create a dedicated virtual subnet for IPsec + template: src=etc/network/if-up.d/ipsec.j2 + dest=/etc/network/if-up.d/ipsec + owner=root group=root + mode=0755 + +- name: Auto-deactivate the dedicated virtual subnet for IPsec + file: src=../if-up.d/ipsec + dest=/etc/network/if-down.d/ipsec + owner=root group=root state=link force=yes + + +- name: Configure IPsec + template: src=etc/ipsec.conf.j2 + dest=/etc/ipsec.conf + owner=root group=root + mode=0644 + register: r1 + notify: + - Restart IPsec + +- name: Configure IPsec's secrets + template: src=etc/ipsec.secrets.j2 + dest=/etc/ipsec.secrets + owner=root group=root + mode=0600 + register: r2 + notify: + - Restart IPsec + +- name: Configure Charon + copy: src=etc/strongswan.d/{{ item }} + dest=/etc/strongswan.d/{{ item }} + owner=root group=root + mode=0644 + with_items: + - charon.conf + - charon/socket-default.conf + register: r3 + notify: + - Restart IPsec + +- name: Generate a key pair for IPsec public key authentication + command: genkeypair.sh keypair + --pubkey=/etc/ipsec.d/certs/{{ inventory_hostname_short }}.pem + --privkey=/etc/ipsec.d/private/{{ inventory_hostname_short }}.key + -t rsa -b 4096 + register: r4 + changed_when: r4.rc == 0 + failed_when: r4.rc > 1 + notify: + - Restart IPsec + tags: + - genkey + +- name: Fetch the public part of IPsec host key + # Ensure we don't fetch private data + become: False + fetch: src=/etc/ipsec.d/certs/{{ inventory_hostname_short }}.pem + dest=certs/ipsec/{{ inventory_hostname_short }}.pem + fail_on_missing=yes flat=yes + tags: + - genkey + +# Don't copy our pubkey due to a possible race condition. Only the +# remote machine has authority regarding its key. +- name: Copy the public part of IPsec peers' key + copy: src=certs/ipsec/{{ hostvars[item].inventory_hostname_short }}.pem + dest=/etc/ipsec.d/certs/{{ hostvars[item].inventory_hostname_short }}.pem + owner=root group=root + mode=0644 + with_items: "{{ groups.all | difference([inventory_hostname]) }}" + register: r5 + tags: + - genkey + notify: + - Restart IPsec + +- name: Start IPsec + service: name=ipsec state=started + when: not (r1.changed or r2.changed or r3.changed or r4.changed or r5.changed) diff --git a/roles/common/tasks/logging.yml b/roles/common/tasks/logging.yml index 3b86294..699c6e3 100644 --- a/roles/common/tasks/logging.yml +++ b/roles/common/tasks/logging.yml @@ -1,82 +1,83 @@ - name: Install logging server & utilities - apt: pkg={{ item }} - with_items: + apt: pkg={{ packages }} + vars: + packages: - rsyslog - - syslog-summary - logcheck - logcheck-database - logrotate - name: Configure rsyslog copy: src=etc/rsyslog.conf dest=/etc/rsyslog.conf owner=root group=root mode=0644 register: r1 notify: - Restart rsyslog tags: - syslog - name: Configure postfix's custom rsyslog rules template: src=etc/rsyslog.d/postfix.conf.j2 dest=/etc/rsyslog.d/postfix.conf owner=root group=root mode=0644 register: r2 notify: - Restart rsyslog tags: - syslog - name: Start rsyslog service: name=rsyslog state=started when: not (r1.changed or r2.changed) tags: - syslog - meta: flush_handlers - name: Configure logcheck (1) copy: src=etc/logcheck/{{ item }} dest=/etc/logcheck/{{ item }} - owner=root group=logcheck + owner=root group=root mode=0644 with_items: - logcheck.conf - ignore.d.server/common-local - ignore.d.server/dovecot-local - ignore.d.server/postfix-local + - ignore.d.server/strongswan-local # logcheck-sudo already exists, but changing the filename for our # local modifications would defeat the ruleset - violations.ignore.d/logcheck-sudo tags: - logcheck - name: Configure logcheck (2) lineinfile: dest=/etc/logcheck/logcheck.logfiles line={{ item }} state=present create=yes - owner=root group=logcheck - mode=0640 + owner=root group=root + mode=0644 with_items: - /var/log/syslog - /var/log/auth.log - /var/log/mail.log tags: - logcheck - name: Minimal logging policy (1) lineinfile: dest=/etc/logrotate.d/rsyslog regexp="^/var/log/mail\\.(log|info|sasl)$" state=absent owner=root group=root mode=0644 - name: Minimal logging policy (2) copy: src=etc/logrotate.d/fripost-mail dest=/etc/logrotate.d/fripost-mail owner=root group=root mode=0644 tags: diff --git a/roles/common/tasks/mail.yml b/roles/common/tasks/mail.yml index 1873928..139386f 100644 --- a/roles/common/tasks/mail.yml +++ b/roles/common/tasks/mail.yml @@ -1,114 +1,63 @@ - name: Install Postfix - apt: pkg={{ item }} - with_items: + apt: pkg={{ packages }} + vars: + packages: # That one is nicer than GNU mailutils' mailx(1) - - heirloom-mailx + - s-nail - postfix - - postfix-cdb + - postfix-lmdb - name: Create Postfix instances postmulti: instance={{ postfix_instance[item].name }} group={{ postfix_instance[item].group | default('') }} register: r1 - with_items: postfix_instance.keys() | intersect(group_names) | list + with_items: "{{ postfix_instance.keys() | intersect(group_names) | list }}" notify: - Restart Postfix -- name: Link the dynamic maps & master.cf of each children to the master's - # main.cf is specialized to each dedicated role, though - file: src=../postfix/{{ item.1 }} - dest=/etc/postfix-{{ postfix_instance[item.0].name }}/{{ item.1 }} +- name: Link the dynamic maps of each children to the master's + # main.cf and master.cf are specialized to each dedicated role, though + file: src=../postfix/dynamicmaps.cf + dest=/etc/postfix-{{ postfix_instance[item].name }}/dynamicmaps.cf owner=root group=root state=link force=yes register: r2 - with_nested: - - postfix_instance.keys() | intersect(group_names) | list - - [ 'dynamicmaps.cf', 'master.cf' ] - notify: - - Restart Postfix - -- name: Configure Postfix (1) - copy: src=etc/postfix/master.cf - dest=/etc/postfix/master.cf - owner=root group=root - mode=0644 - register: r3 + with_items: "{{ postfix_instance.keys() | intersect(group_names) | list }}" notify: - Restart Postfix -- name: Configure Postfix (2) - template: src=etc/postfix/main.cf.j2 - dest=/etc/postfix/main.cf +- name: Configure Postfix + template: src=etc/postfix/{{ item }}.j2 + dest=/etc/postfix/{{ item }} owner=root group=root mode=0644 + with_items: + - main.cf + - master.cf notify: - Reload Postfix -- name: Create directory /etc/postfix/ssl - file: path=/etc/postfix/ssl - state=directory - owner=root group=root - mode=0755 - tags: - - genkey - -- name: Generate a private key and a X.509 certificate for Postfix - command: genkeypair.sh x509 - --pubkey=/etc/postfix/ssl/{{ ansible_fqdn }}.pem - --privkey=/etc/postfix/ssl/{{ ansible_fqdn }}.key - --ou=Postfix --cn={{ ansible_fqdn }} - -t ecdsa -b secp384r1 -h sha512 - register: r4 - changed_when: r4.rc == 0 - failed_when: r4.rc > 1 - notify: - - Restart Postfix - tags: - - genkey - -- name: Fetch Postfix's X.509 certificate - # Ensure we don't fetch private data - sudo: False - fetch: src=/etc/postfix/ssl/{{ ansible_fqdn }}.pem - dest=certs/postfix/ - fail_on_missing=yes - flat=yes - tags: - - genkey - -- name: Add a 'root' alias +- name: Add some common aliases lineinfile: dest=/etc/aliases create=yes - regexp="^root:"" " - line="root:"" root@fripost.org" + regexp='^{{ item.src }}{{':'}} ' + line='{{ item.src }}{{':'}} {{ item.dst }}' + with_items: + - { src: mailer-daemon, dst: 'postmaster' } + - { src: postmaster, dst: 'root' } + - { src: nobody, dst: 'root' } + - { src: root, dst: 'root@fripost.org' } - name: Compile the static local Postfix database - postmap: cmd=postalias src=/etc/aliases db=cdb + postmap: cmd=postalias src=/etc/aliases db=lmdb owner=root group=root mode=0644 -# We're using CDB +# We're using LMDB - name: Delete /etc/aliases.db file: path=/etc/aliases.db state=absent -- name: Copy the Postfix TLS policy map - template: src=etc/postfix/tls_policy.j2 - dest=/etc/postfix/tls_policy - owner=root group=root - mode=0644 - when: "'out' not in group_names or 'MX' in group_names" - tags: - - tls_policy - -- name: Compile the Postfix TLS policy map - postmap: cmd=postmap src=/etc/postfix/tls_policy db=cdb - owner=root group=root - mode=0644 - when: "'out' not in group_names or 'MX' in group_names" - tags: - - tls_policy - - name: Start Postfix service: name=postfix state=started - when: not (r1.changed or r2.changed or r3.changed or r4.changed) + when: not (r1.changed or r2.changed) - meta: flush_handlers diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml index 470a6b2..1dc286e 100644 --- a/roles/common/tasks/main.yml +++ b/roles/common/tasks/main.yml @@ -1,70 +1,102 @@ --- -- include: sysctl.yml tags=sysctl -- include: hosts.yml -- include: apt.yml tags=apt +- import_tasks: sysctl.yml + tags: sysctl +- import_tasks: hosts.yml +- import_tasks: apt.yml + tags: apt - name: Install intel-microcode apt: pkg=intel-microcode - when: "ansible_processor[0] | search('^(Genuine)?Intel.*') and not (ansible_virtualization_role == 'guest' and ansible_virtualization_type == 'xen')" + when: "ansible_processor[1] is search('^(Genuine)?Intel.*') and not ansible_virtualization_role == 'guest'" tags: intel -- include: firewall.yml tags=firewall,iptables -- include: samhain.yml tags=samhain -- include: auditd.yml tags=auditd -- include: rkhunter.yml tags=rkhunter -- include: clamav.yml tags=clamav -- include: fail2ban.yml tags=fail2ban -- include: smart.yml tags=smartmontools,smart - when: "not ((ansible_virtualization_role == 'guest' and ansible_virtualization_type == 'xen') or ansible_system_vendor == 'QEMU')" -- include: haveged.yml tags=haveged,entropy +- import_tasks: firewall.yml + tags: + - firewall + - iptables + - nftables + +- import_tasks: stunnel.yml + tags: stunnel + when: "'webmail' in group_names and 'LDAP_provider' not in group_names" +- import_tasks: auditd.yml + tags: auditd +- import_tasks: resolved.yml + tags: + - resolv + - resolved + - dns +- import_tasks: unbound.yml + tags: + - unbound + - dns + when: "ansible_processor[1] is search('^(Genuine)?Intel.*') and not ansible_virtualization_role == 'guest'" +- import_tasks: rkhunter.yml + tags: rkhunter +- import_tasks: clamav.yml + tags: clamav +- import_tasks: fail2ban.yml + tags: fail2ban +- import_tasks: smart.yml + tags: + - smartmontools + - smart + when: "not ansible_virtualization_role == 'guest'" - name: Copy genkeypair.sh and gendhparam.sh copy: src=usr/local/bin/{{ item }} dest=/usr/local/bin/{{ item }} - owner=root group=root + owner=root group=staff mode=0755 tags: genkey with_items: - genkeypair.sh - gendhparam.sh - name: Generate DH parameters - command: gendhparam.sh /etc/ssl/private/dhparams.pem creates=/etc/ssl/private/dhparams.pem + command: gendhparam.sh /etc/ssl/dhparams.pem 2048 + creates=/etc/ssl/dhparams.pem tags: genkey -- include: logging.yml tags=logging -- include: ntp.yml tags=ntp -- include: mail.yml tags=mail,postfix -- include: bacula.yml tags=bacula-fd,bacula -- include: munin-node.yml tags=munin-node,munin +- import_tasks: ipsec.yml + tags: + - strongswan + - ipsec + when: "groups.all | length > 1" +- import_tasks: logging.yml + tags: logging +- import_tasks: ntp.yml + tags: ntp +- import_tasks: mail.yml + tags: + - mail + - postfix +- import_tasks: bacula.yml + tags: + - bacula-fd + - bacula +- import_tasks: munin-node.yml + tags: + - munin-node + - munin - name: Install common packages - apt: pkg={{ item }} - with_items: + apt: pkg={{ packages }} + vars: + packages: - ca-certificates - etckeeper - ethtool - git - htop - molly-guard - rsync - screen - - telnet-ssl - -# XXX: this is a workaround the CAcert root CAs not being present in -# Jessie. In stretch, we would merely install the 'ca-cacert' package. -- name: Create directory /usr/local/share/ca-certificates/CAcert - file: path=/usr/local/share/ca-certificates/CAcert - state=directory - owner=root group=root - mode=0755 - tags: - - certs + - bind9-dnsutils -- name: Copy CAcert root CAs - copy: src=certs/CAcert/{{ item }} - dest=/usr/local/share/ca-certificates/CAcert/{{ item }} +- name: Disable resume device + # Cf. initramfs-tools(7) and initramfs.conf(5). + copy: src=etc/initramfs-tools/conf.d/resume + dest=/etc/initramfs-tools/conf.d/resume owner=root group=root mode=0644 - with_items: - - root.crt - - class3.crt tags: - - certs + - initramfs + - resume notify: - - Update certificate + - Update initramfs diff --git a/roles/common/tasks/munin-node.yml b/roles/common/tasks/munin-node.yml index 9e5d8f4..2411b59 100644 --- a/roles/common/tasks/munin-node.yml +++ b/roles/common/tasks/munin-node.yml @@ -1,23 +1,24 @@ - name: Install munin-node - apt: pkg={{ item }} - with_items: + apt: pkg={{ packages }} + vars: + packages: - munin-node - munin-plugins-extra ### - acpi - lm-sensors - ethtool - hdparm - libwww-perl - libxml-simple-perl - logtail - name: Create directory /usr/local/share/munin/plugins file: path=/usr/local/share/munin/plugins state=directory owner=root group=root mode=0755 - name: Copy our own Munin plugins copy: src={{ item }} dest=/usr/local/share/munin/plugins/ @@ -44,68 +45,90 @@ owner=root group=root state=link force=yes register: r2 with_items: - cpu - df - df_inode - diskstats - entropy - fail2ban - forks - fw_conntrack - fw_forwarded_local - fw_packets - hddtemp_smartctl - interrupts - irqstats - load - memory - netstat - - ntp_kernel_err - - ntp_kernel_pll_freq - - ntp_kernel_pll_off - - ntp_offset - open_files - open_inodes - processes - proc_pri - swap - threads - uptime - users - vmstat notify: - Restart munin-node -- name: Delete Munin plugins +- name: Install Munin plugins + file: src=/usr/share/munin/plugins/{{ item }} + dest=/etc/munin/plugins/{{ item }} + owner=root group=root + state=link force=yes + with_items: + - ntp_kernel_err + - ntp_kernel_pll_freq + - ntp_kernel_pll_off + - ntp_offset + when: "'NTP_master' in group_names" + notify: + - Restart munin-node + +- name: Delete unnecessary Munin plugins file: path=/etc/munin/plugins/{{ item }} state=absent register: r3 with_items: - http_loadtime - ip_255.255.255.255 - postfix_mailqueue - postfix_mailvolume notify: - Restart munin-node +- name: Delete unnecessary Munin plugins + file: path=/etc/munin/plugins/{{ item }} + state=absent + with_items: + - ntp_kernel_err + - ntp_kernel_pll_freq + - ntp_kernel_pll_off + - ntp_offset + when: "'NTP_master' not in group_names" + notify: + - Restart munin-node + - name: Install 'if_' Munin wildcard plugin file: src=/usr/share/munin/plugins/{{ item.0 }}_ dest=/etc/munin/plugins/{{ item.0 }}_{{ item.1 }} owner=root group=root state=link force=yes register: r4 with_nested: - [ if, if_err ] - [ lo, "{{ ansible_default_ipv4.interface }}" ] notify: - Restart munin-node - name: Install 'postfix_mailvolume2' Munin plugin file: src=/usr/local/share/munin/plugins/postfix_mailvolume2 dest=/etc/munin/plugins/postfix_mailvolume2 owner=root group=root state=link force=yes register: r5 notify: - Restart munin-node @@ -115,93 +138,49 @@ dest=/etc/munin/plugins/postfix_mailqueue_postfix owner=root group=root state=link force=yes register: r6 notify: - Restart munin-node - name: Install 'postfix_stats_' Munin wildcard plugin file: src=/usr/local/share/munin/plugins/postfix_stats_ dest=/etc/munin/plugins/postfix_stats_{{ item }}_postfix owner=root group=root state=link force=yes register: r7 with_items: - smtpd - qmgr - smtp notify: - Restart munin-node -- name: Start munin-node - service: name=munin-node state=started - when: not (r1.changed or r2.changed or r3.changed or r4.changed or r5.changed or r6.changed or r7.changed) - -- meta: flush_handlers - - - -- name: Install stunnel - apt: pkg=stunnel4 - -- name: Auto-enable stunnel - lineinfile: dest=/etc/default/stunnel4 - regexp='^(\s*#)?\s*ENABLED=' - line='ENABLED=1' - owner=root group=root - mode=0644 - -- name: Create /etc/stunnel/certs - file: path=/etc/stunnel/certs +- name: Create directory /etc/systemd/system/munin-node.service.d + file: path=/etc/systemd/system/munin-node.service.d state=directory owner=root group=root mode=0755 -- name: Generate a private key and a X.509 certificate for munin-node - command: genkeypair.sh x509 - --pubkey=/etc/stunnel/certs/munin-{{ inventory_hostname_short }}.pem - --privkey=/etc/stunnel/certs/munin-{{ inventory_hostname_short }}.key - --ou=Munin --cn={{ inventory_hostname }} --dns={{ inventory_hostname }} - -t rsa -b 4096 -h sha512 - register: r1 - changed_when: r1.rc == 0 - failed_when: r1.rc > 1 - notify: - - Restart stunnel - tags: - - genkey - -- name: Fetch Munin X.509 certificate - # Ensure we don't fetch private data - sudo: False - fetch: src=/etc/stunnel/certs/munin-{{ inventory_hostname_short }}.pem - dest=certs/munin/{{ inventory_hostname }}.pem - fail_on_missing=yes - flat=yes - tags: - - genkey - -- name: Copy munin-master X.509 certificates - assemble: src=certs/munin regexp="{{ groups['munin-master'] | join('|') }}\.pem$" remote_src=no - dest=/etc/stunnel/certs/munin-master.pem - owner=root group=root - mode=0644 - register: r2 - when: "'munin-master' not in group_names" +- name: Copy munin-node.service override + copy: src=etc/systemd/system/munin-node.service.d/override.conf + dest=/etc/systemd/system/munin-node.service.d/override.conf + owner=root group=root + mode=0644 + register: r8 notify: - - Restart stunnel + - systemctl daemon-reload + - Restart munin-node -- name: Configure stunnel - template: src=etc/stunnel/munin-node.conf.j2 - dest=/etc/stunnel/munin-node.conf - owner=root group=root - mode=0644 - register: r3 - when: "'munin-master' not in group_names" - notify: - - Restart stunnel +# We use RuntimeDirectory in our overrride unit to avoid permission +# issues caused by the restrictive Capability Bounding Set +- name: Mask /usr/lib/tmpfiles.d/munin-common.conf + file: src=/dev/null + dest=/etc/tmpfiles.d/munin-common.conf + owner=root group=root + state=link -- name: Start stunnel - service: name=stunnel4 pattern=/usr/bin/stunnel4 state=started - when: not (r1.changed or r2.changed or r3.changed) +- name: Start munin-node + service: name=munin-node state=started + when: not (r1.changed or r2.changed or r3.changed or r4.changed or r5.changed or r6.changed or r7.changed or r8.changed) - meta: flush_handlers diff --git a/roles/common/tasks/ntp.yml b/roles/common/tasks/ntp.yml index f9a01c8..2ff9e49 100644 --- a/roles/common/tasks/ntp.yml +++ b/roles/common/tasks/ntp.yml @@ -1,15 +1,33 @@ -- name: Install ntp - apt: pkg=ntp +- name: Remove ntp package + apt: pkg=ntp state={{ state }} purge=yes + vars: + state: "{{ ('NTP_master' in group_names) | ternary('present', 'absent') }}" + +- name: Install systemd-timesyncd package + apt: pkg=systemd-timesyncd state=present purge=yes + when: "'NTP_master' not in group_names" + +- name: Create /etc/systemd/timesyncd.conf.d + file: path=/etc/systemd/timesyncd.conf.d + state=directory + owner=root group=root + mode=0755 + when: "'NTP_master' not in group_names" - name: Configure ntp - template: src=etc/ntp.conf.j2 - dest=/etc/ntp.conf + template: src=etc/{{ conf }}.j2 + dest=/etc/{{ conf }} owner=root group=root mode=0644 + vars: + conf: "{{ ('NTP_master' in group_names) | ternary('ntp.conf', 'systemd/timesyncd.conf.d/fripost.conf') }}" + service: "{{ ('NTP_master' in group_names) | ternary('ntp', 'systemd-timesyncd') }}" notify: - - Restart ntp + - Restart {{ service }} - meta: flush_handlers -- name: Start ntp - service: name=ntp state=started +- name: Start and enable ntp + service: name={{ service }}.service state=started enabled=true + vars: + service: "{{ ('NTP_master' in group_names) | ternary('ntp', 'systemd-timesyncd') }}" diff --git a/roles/common/tasks/resolved.yml b/roles/common/tasks/resolved.yml new file mode 100644 index 0000000..2834eaa --- /dev/null +++ b/roles/common/tasks/resolved.yml @@ -0,0 +1,36 @@ +- name: Install systemd-resolved + apt: pkg={{ packages }} + vars: + packages: + - systemd-resolved + - libnss-resolve + - libnss-myhostname + +- name: Create directory /etc/systemd/resolved.conf.d + file: path=/etc/systemd/resolved.conf.d + state=directory + owner=root group=root + mode=0755 + +- name: Configure systemd-resolved + template: src=etc/systemd/resolved.conf.d/local.conf.j2 + dest=/etc/systemd/resolved.conf.d/local.conf + owner=root group=root + mode=0644 + notify: + - Restart systemd-resolved + +- name: Start systemd-resolved + service: name=systemd-resolved.service enabled=true state=started + +- meta: flush_handlers + +- name: Remove resolvconf + apt: pkg=resolvconf state=absent purge=yes + +- name: Configure /etc/nsswitch.conf + lineinfile: "dest=/etc/nsswitch.conf create=no + regexp='^(hosts:\\s+).*' + line='\\1resolve [!UNAVAIL=return] files myhostname dns' + backrefs=true" + tags: nsswitch diff --git a/roles/common/tasks/rkhunter.yml b/roles/common/tasks/rkhunter.yml index c9d26fa..64f2aac 100644 --- a/roles/common/tasks/rkhunter.yml +++ b/roles/common/tasks/rkhunter.yml @@ -1,23 +1,24 @@ - name: Install rkhunter - apt: pkg={{ item }} - with_items: + apt: pkg={{ packages }} + vars: + packages: - rkhunter - curl - iproute2 - lsof - unhide # To test the configuration: # ansible all -m command -a '/usr/bin/rkhunter -c --nomow --rwo' - name: Configure rkhunter copy: src=etc/{{ item }} dest=/etc/{{ item }} owner=root group=root mode=0644 with_items: - rkhunter.conf - default/rkhunter notify: # This might not always be necessary, but it's not like we would # change the config every day... - Update rkhunter's data file diff --git a/roles/common/tasks/samhain.yml b/roles/common/tasks/samhain.yml deleted file mode 100644 index dd5c09b..0000000 --- a/roles/common/tasks/samhain.yml +++ /dev/null @@ -1,26 +0,0 @@ -- name: Install samhain - apt: pkg=samhain - # XXX: Doesn't work out of the box, see #660197. - # Every once in a while, or after a major upgrade, you may want to - # update Samhain's database: - # - # sudo samhain -t update --foreground -l none - # - # To update the database interactively, without sending mails: - # - # sudo samhain -t update --interactive -l none -m none - -- name: Configure samhain - copy: src=etc/samhain/samhainrc - dest=/etc/samhain/samhainrc - owner=root group=root - mode=0644 - notify: - - Reload samhain - -- name: Start samhain - # This task is inconditional because samhain is reloaded not - # restarted. - service: name=samhain state=started - -- meta: flush_handlers diff --git a/roles/common/tasks/smart.yml b/roles/common/tasks/smart.yml index 8d35d9f..68e507f 100644 --- a/roles/common/tasks/smart.yml +++ b/roles/common/tasks/smart.yml @@ -1,12 +1,5 @@ - name: Install smartmontools apt: pkg=smartmontools -- name: Auto-enable smartmontools - lineinfile: dest=/etc/default/smartmontools - regexp='^(\s*#)?\s*start_smartd=' - line='start_smartd=yes' - owner=root group=root - mode=0644 - - name: Start smartd service: name=smartmontools state=started diff --git a/roles/common/tasks/stunnel.yml b/roles/common/tasks/stunnel.yml new file mode 100644 index 0000000..1522f1f --- /dev/null +++ b/roles/common/tasks/stunnel.yml @@ -0,0 +1,16 @@ +- name: Install stunnel4 + apt: pkg=stunnel4 + +- name: Copy stunnel4 service files + copy: src=etc/systemd/system/{{ item }} + dest=/etc/systemd/system/{{ item }} + owner=root group=root + mode=0644 + notify: + - systemctl daemon-reload + with_items: + - stunnel4.service + - stunnel4@.service + +- name: Disable stunnel4 service + service: name=stunnel4.service enabled=false diff --git a/roles/common/tasks/sysctl.yml b/roles/common/tasks/sysctl.yml index 6ac7feb..08a1b13 100644 --- a/roles/common/tasks/sysctl.yml +++ b/roles/common/tasks/sysctl.yml @@ -1,49 +1,48 @@ -- sysctl: name={{ item.name }} "value={{ item.value }}" sysctl_set=yes +- sysctl: name={{ item.name }} value={{ item.value }} sysctl_set=yes with_items: - { name: 'kernel.domainname', value: '{{ ansible_domain }}' } # Networking. See # https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt # Enable Spoof protection (reverse-path filter). Turn on Source # Address Verification in all interfaces to prevent some spoofing # attacks. - { name: 'net.ipv4.conf.default.rp_filter', value: 1 } - { name: 'net.ipv4.conf.all.rp_filter', value: 1 } - # Enable TCP/IP SYN cookies to avoid TCP SYN flood attacks. We - # rate-limit not only the default ICMP types 3, 4, 11 and 12 + # Disable SYN cookies and improve SYN backlog handling, see tcp(7) and + # https://levelup.gitconnected.com/linux-kernel-tuning-for-high-performance-networking-high-volume-incoming-connections-196e863d458a + - { name: 'net.ipv4.tcp_syncookies', value: 0 } + - { name: 'net.ipv4.tcp_synack_retries', value: 1 } + - { name: 'net.ipv4.tcp_max_syn_backlog', value: 32768 } + + # We rate-limit not only the default ICMP types 3, 4, 11 and 12 # (0x1818), but also types 0 and 8. See icmp(7). - - { name: 'net.ipv4.tcp_syncookies', value: 1 } - { name: 'net.ipv4.icmp_ratemask', value: 6425 } - { name: 'net.ipv4.icmp_ratelimit', value: 1000 } - # Disable paquet forwarding between interfaces (we are not a router). + # Disable packet forwarding between interfaces (we are not a router). - { name: 'net.ipv4.ip_forward', value: 0 } - { name: 'net.ipv6.conf.all.forwarding', value: 0 } - # Enable IPv6 Privacy Extensions. - - { name: 'net.ipv6.conf.default.use_tempaddr', value: 2 } - - { name: 'net.ipv6.conf.all.use_tempaddr', value: 2 } - - { name: 'net.ipv6.conf.all.autoconf', value: 0 } - # Do not accept ICMP redirects (prevent MITM attacks). - { name: 'net.ipv4.conf.all.accept_redirects', value: 0 } - { name: 'net.ipv6.conf.all.accept_redirects', value: 0 } # Do not send ICMP redirects (we are not a router). - { name: 'net.ipv4.conf.default.send_redirects', value: 0 } - { name: 'net.ipv4.conf.all.send_redirects', value: 0 } # Do not accept IP source route packets (we are not a router). - { name: 'net.ipv4.conf.all.accept_source_route', value: 0 } - { name: 'net.ipv6.conf.all.accept_source_route', value: 0 } # Log Martian Packets. - { name: 'net.ipv4.conf.all.log_martians', value: 1 } # Ignore ICMP broadcasts. - { name: 'net.ipv4.icmp_echo_ignore_broadcasts', value: 1 } # Ignore bogus ICMP errors. - { name: 'net.ipv4.icmp_ignore_bogus_error_responses', value: 1 } diff --git a/roles/common/tasks/unbound.yml b/roles/common/tasks/unbound.yml new file mode 100644 index 0000000..dda6769 --- /dev/null +++ b/roles/common/tasks/unbound.yml @@ -0,0 +1,21 @@ +- name: Install unbound + apt: pkg={{ packages }} + vars: + packages: + - unbound + - dns-root-data + +- name: Copy unbound configuration + template: src=templates/etc/unbound/unbound.conf.j2 + dest=/etc/unbound/unbound.conf + owner=root group=root + mode=0644 + register: r + notify: + - Restart unbound + +- name: Start unbound + service: name=unbound state=started + when: not r.changed + +#- meta: flush_handlers diff --git a/roles/common/templates/etc/apt/preferences.j2 b/roles/common/templates/etc/apt/preferences.j2 index ba10834..39b610e 100644 --- a/roles/common/templates/etc/apt/preferences.j2 +++ b/roles/common/templates/etc/apt/preferences.j2 @@ -1,38 +1,38 @@ # {{ ansible_managed }} # Do NOT edit this file directly! -# Install updates as soon as they're available -Package: * -Pin: release a={{ ansible_lsb.codename }}-updates -Pin-Priority: 990 +## Install updates as soon as they're available +#Package: * +#Pin: release o=Debian, n={{ ansible_lsb.codename }}-updates +#Pin-Priority: 990 {% if 'backports' in group_names -%} # Automatically packages from backports (those manually installed) Package: * -Pin: release a={{ ansible_lsb.codename }}-backports +Pin: release o=Debian Backports, n={{ ansible_lsb.codename }}-backports Pin-Priority: 200 {% endif %} -{% if 'non-free' in group_names -%} +{% if inventory_hostname_short in non_free_packages.keys() -%} # Automatically upgrade non-free firmwares (when manually installed) -Package: firmware-linux-nonfree +Package: {{ non_free_packages[inventory_hostname_short] | join (' ') }} +Pin: release o=Debian Pin-Priority: 200 {% endif %} -{% if ansible_processor[0] | search('^(Genuine)?Intel.*') and - not (ansible_virtualization_role == 'guest' and ansible_virtualization_type == 'xen') -%} +{% if ansible_processor[1] is search('^(Genuine)?Intel.*') and not ansible_virtualization_role == 'guest' and ansible_lsb.major_release | int < 12 -%} # Automatically upgrade the microcode (when manually installed) Package: intel-microcode iucode-tool -Pin: version * +Pin: release o=Debian Pin-Priority: 200 {% endif %} # Never, ever install things from contrib or non-free unless they have been # whitelisted above Package: * Pin: release c=contrib Pin-Priority: -1 Package: * Pin: release c=non-free Pin-Priority: -1 diff --git a/roles/common/templates/etc/apt/sources.list.j2 b/roles/common/templates/etc/apt/sources.list.j2 index 5788ade..f524f2f 100644 --- a/roles/common/templates/etc/apt/sources.list.j2 +++ b/roles/common/templates/etc/apt/sources.list.j2 @@ -1,13 +1,13 @@ # {{ ansible_managed }} # Do NOT edit this file directly! # vim: set filetype=debsources : -deb http://ftp.se.debian.org/debian/ {{ ansible_lsb.codename }} main{% if 'non-free' in group_names or (ansible_processor[0] | search("^(Genuine)?Intel.*") and not (ansible_virtualization_role == 'guest' and ansible_virtualization_type == 'xen')) %} contrib non-free{% endif %} +deb https://deb.debian.org/debian {{ ansible_lsb.codename }} main{% if inventory_hostname_short in non_free_packages.keys() or (ansible_processor[1] is search("^(Genuine)?Intel.*") and not ansible_virtualization_role == 'guest' and ansible_lsb.major_release | int < 12) %} contrib non-free{% endif %}{% if ansible_lsb.major_release | int >= 12 %} non-free-firmware{% endif %} -deb http://security.debian.org/ {{ ansible_lsb.codename }}/updates main{% if 'non-free' in group_names or (ansible_processor[0] | search("^(Genuine)?Intel.*") and not (ansible_virtualization_role == 'guest' and ansible_virtualization_type == 'xen')) %} contrib non-free{% endif %} +deb https://deb.debian.org/debian-security {{ ansible_lsb.codename }}{% if ansible_lsb.major_release | int < 11 %}/updates{% else %}-security{% endif %} main{% if inventory_hostname_short in non_free_packages.keys() or (ansible_processor[1] is search("^(Genuine)?Intel.*") and not ansible_virtualization_role == 'guest' and ansible_lsb.major_release | int < 12) %} contrib non-free{% endif %}{% if ansible_lsb.major_release | int >= 12 %} non-free-firmware{% endif %} -deb http://ftp.se.debian.org/debian/ {{ ansible_lsb.codename }}-updates main +deb https://deb.debian.org/debian {{ ansible_lsb.codename }}-updates main{% if ansible_lsb.major_release | int >= 12 %} non-free-firmware{% endif %} {% if 'backports' in group_names -%} -deb http://ftp.debian.org/debian/ {{ ansible_lsb.codename }}-backports main +deb https://deb.debian.org/debian {{ ansible_lsb.codename }}-backports main {% endif %} diff --git a/roles/common/templates/etc/bacula/bacula-fd.conf.j2 b/roles/common/templates/etc/bacula/bacula-fd.conf.j2 index a47bb90..d0af395 100644 --- a/roles/common/templates/etc/bacula/bacula-fd.conf.j2 +++ b/roles/common/templates/etc/bacula/bacula-fd.conf.j2 @@ -1,41 +1,46 @@ # # Default Bacula File Daemon Configuration file # -# For Bacula release 5.2.6 (21 February 2012) -- debian jessie/sid +# For Bacula release 9.6.7 (10 December 2020) -- debian bullseye/sid +# +# There is not much to change here except perhaps the +# File daemon Name to +# +# +# Copyright (C) 2000-2020 Kern Sibbald +# License: BSD 2-Clause; see file LICENSE-FOSS +# # # List Directors who are permitted to contact this File daemon # -{% for dir in groups['bacula-dir'] | sort %} +{% for dir in groups['bacula_dir'] | sort %} Director { Name = {{ hostvars[dir].inventory_hostname_short }}-dir @|"sed -n '/^{{ hostvars[dir].inventory_hostname_short }}-dir\\s/ {s//Password = /p; q}' /etc/bacula/passwords-fd" } # Send all messages except skipped files back to Director Messages { Name = Standard director = {{ hostvars[dir].inventory_hostname_short }}-dir = all, !skipped, !restored } {% endfor %} # # "Global" File daemon configuration specifications # FileDaemon { # define myself Name = {{ inventory_hostname_short }}-fd Working Directory = /var/lib/bacula - Pid Directory = /var/run/bacula + Pid Directory = /run/bacula Maximum Concurrent Jobs = 20 - FDAddress = 127.0.0.1 - FDPort = 9112 - FDSourceAddress = 127.0.0.1 -{% if 'bacula-dir' not in group_names or 'bacula-sd' not in group_names %} - Heartbeat Interval = 60s -{% endif %} + FDAddress = {{ ipsec[inventory_hostname_short] }} + FDPort = 9102 + SDConnectTimeout = 5 min PKI Signatures = Yes # Enable Data Signing PKI Encryption = Yes # Enable Data Encryption PKI Keypair = /etc/bacula/ssl/{{ inventory_hostname_short }}.pem # Public and Private Keys PKI Master Key = /etc/bacula/ssl/master.pem # ONLY the Public Key } diff --git a/roles/common/templates/etc/clamav/freshclam.conf.j2 b/roles/common/templates/etc/clamav/freshclam.conf.j2 new file mode 100644 index 0000000..650a2b3 --- /dev/null +++ b/roles/common/templates/etc/clamav/freshclam.conf.j2 @@ -0,0 +1,31 @@ +# Automatically created by the clamav-freshclam postinst +# Comments will get lost when you reconfigure the clamav-freshclam package + +DatabaseOwner clamav +UpdateLogFile /var/log/clamav/freshclam.log +LogVerbose false +LogSyslog false +LogFacility LOG_LOCAL6 +LogFileMaxSize 0 +LogRotate true +LogTime true +Foreground false +Debug false +MaxAttempts 5 +DatabaseDirectory /var/lib/clamav +DNSDatabaseInfo current.cvd.clamav.net +ConnectTimeout 30 +ReceiveTimeout 30 +TestDatabases yes +ScriptedUpdates yes +CompressLocalDatabase no +Bytecode true +NotifyClamd /etc/clamav/clamd.conf +# Check for new database 24 times a day +Checks 24 +DatabaseMirror db.{{ geoip | default('local') }}.clamav.net +{% if geoip is defined and ansible_default_ipv6 %} +DatabaseMirror db.{{ geoip }}.ipv6.clamav.net +{% endif %} +DatabaseMirror database.clamav.net +DatabaseMirror db.other.clamav.net diff --git a/roles/common/templates/etc/default/debsecan.j2 b/roles/common/templates/etc/default/debsecan.j2 deleted file mode 100644 index 71fee1c..0000000 --- a/roles/common/templates/etc/default/debsecan.j2 +++ /dev/null @@ -1,17 +0,0 @@ -# Configuration file for debsecan. Contents of this file should -# adhere to the KEY=VALUE shell syntax. This file may be edited by -# debsecan's scripts, but your modifications are preserved. - -# If true, enable daily reports, sent by email. -REPORT=true - -# For better reporting, specify the correct suite here, using the code -# name (that is, "sid" instead of "unstable"). -SUITE={{ ansible_lsb.codename }} - -# Mail address to which reports are sent. -MAILTO=admin@fripost.org - -# The URL from which vulnerability data is downloaded. Empty for the -# built-in default. -SOURCE= diff --git a/roles/common/templates/etc/fail2ban/jail.local.j2 b/roles/common/templates/etc/fail2ban/jail.local.j2 index a34cb70..3cd19cc 100644 --- a/roles/common/templates/etc/fail2ban/jail.local.j2 +++ b/roles/common/templates/etc/fail2ban/jail.local.j2 @@ -1,93 +1,46 @@ # {{ ansible_managed }} # Do NOT edit this file directly! [DEFAULT] # Destination email address used solely for the interpolations in # jail.{conf,local} configuration files. destemail = admin@fripost.org -# Specify chain where jumps would need to be added in iptables-* actions -chain = fail2ban +# "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.0/8, ::1, {{ ipsec_subnet }} -# Choose default action. -action = %(action_)s +banaction = nftables-allports -# Don't ban ourselves. -ignoreip = 127.0.0.0/8 {{ groups.all | sort | join(' ') }} +# must match nftables.conf's blackholes timeouts +bantime = 10m # # JAILS # -[ssh] - -enabled = true -port = {{ ansible_ssh_port|default('22') }} -filter = sshd -logpath = /var/log/auth.log -maxretry = 5 - -[ssh-ddos] - -enabled = true -port = {{ ansible_ssh_port|default('22') }} -filter = sshd-ddos -logpath = /var/log/auth.log -maxretry = 2 - - -# Generic filter for pam. Has to be used with action which bans all ports -# such as iptables-allports, shorewall -[pam-generic] - -enabled = true -# pam-generic filter can be customized to monitor specific subset of 'tty's -filter = pam-generic -# port actually must be irrelevant but lets leave it all for some possible uses -port = anyport -banaction = iptables-allports -logpath = /var/log/auth.log -maxretry = 6 +[sshd] +enabled = true -{% if 'MX' in group_names %} [postfix] +enabled = {{ 'MX' in group_names }} -enabled = true -port = smtp -filter = postfix -logpath = /var/log/mail.log -maxretry = 10 -{% endif %} - - -{% if 'IMAP' in group_names %} [dovecot] +enabled = {{ 'IMAP' in group_names }} -enabled = true -port = imap2,imap3,imaps,pop3,pop3s -filter = dovecot -logpath = /var/log/mail.log -{% endif %} - - -{% if 'MSA' in group_names %} -[sasl] - -enabled = true -port = submission -filter = postfix-sasl -logpath = /var/log/mail.warn -{% endif %} - +[postfix-sasl] +enabled = {{ 'MSA' in group_names }} -{% if 'webmail' in group_names %} -[roundcube] +[roundcube-auth] +enabled = {{ 'webmail' in group_names }} +logpath = /var/log/roundcube/errors.log -enabled = true -port = http,https -filter = roundcube -logpath = /var/log/roundcube/errors -{% endif %} +[nextcloud] +enabled = {{ 'nextcloud' in group_names }} +port = http,https +filter = nextcloud +logpath = /var/log/nextcloud/nextcloud.log # vim: set filetype=dosini : diff --git a/roles/common/templates/etc/ipsec.conf.j2 b/roles/common/templates/etc/ipsec.conf.j2 new file mode 100644 index 0000000..eaa9a08 --- /dev/null +++ b/roles/common/templates/etc/ipsec.conf.j2 @@ -0,0 +1,45 @@ +# {{ ansible_managed }} +# Do NOT edit this file directly! + +config setup + charondebug = "dmn 0, lib 0, cfg 0, ike 0, enc 0, net 0" + +conn %default + keyexchange = ikev2 + keyingtries = %forever + ike = aes256gcm16-prfsha384-ecp384! + esp = aes256gcm16-ecp384! +{% if 'NATed' not in group_names %} + mobike = no +{% endif %} +{% if 'DynDNS' in group_names %} + leftallowany = yes +{% endif %} + leftauth = pubkey + left = %defaultroute + leftsubnet = {{ ipsec[inventory_hostname_short] | ansible.utils.ipv4 }}/32 + leftid = {{ inventory_hostname }} + leftsigkey = {{ inventory_hostname_short }}.pem + leftfirewall = no + lefthostaccess = yes + rightauth = pubkey + auto = route + dpdaction = hold + inactivity = 30m + modeconfig = push + +{% for host in groups.all | difference([inventory_hostname]) | sort %} + +conn {{ hostvars[host].inventory_hostname_short }} + right = {{ hostvars[host].inventory_hostname }} +{% if 'DynDNS' in hostvars[host].group_names %} + rightallowany = yes +{% endif %} + rightsigkey = {{ hostvars[host].inventory_hostname_short }}.pem + rightsubnet = {{ ipsec[ hostvars[host].inventory_hostname_short ] | ansible.utils.ipv4 }}/32 + reqid = {{ ipsec[ hostvars[host].inventory_hostname_short ].replace(":",".").split(".")[-1] }} +{% if 'NATed' not in group_names and 'NATed' in hostvars[host].group_names %} + mobike = yes +{% endif %} + +{%- endfor %} diff --git a/roles/common/templates/etc/ipsec.secrets.j2 b/roles/common/templates/etc/ipsec.secrets.j2 new file mode 100644 index 0000000..6ed670d --- /dev/null +++ b/roles/common/templates/etc/ipsec.secrets.j2 @@ -0,0 +1,5 @@ +# {{ ansible_managed }} +# Do NOT edit this file directly! + +# Our VPN uses RSA only. +: RSA {{ inventory_hostname_short }}.key diff --git a/roles/common/templates/etc/iptables/services.j2 b/roles/common/templates/etc/iptables/services.j2 deleted file mode 100644 index 8792771..0000000 --- a/roles/common/templates/etc/iptables/services.j2 +++ /dev/null @@ -1,81 +0,0 @@ -# {{ ansible_managed }} -# Do NOT edit this file directly! -# -# direction protocol destination port source port -# (in|out|inout)[46]? (tcp|udp|..) (port|port:port|port,port) (port|port:port|port,port) - -out tcp 80,443 # HTTP/HTTPS -out tcp 9418 # GIT -out udp 53 # DNS -out udp 67 # DHCP -out tcp 22 # SSH -{% if 'NTP-master' in group_names %} -in udp 123 # NTP -out udp 123 # NTP -{% else %} -out udp 123 123 # NTP -{% endif %} - -in tcp {{ ansible_ssh_port|default('22') }} # SSH -{% if 'LDAP-provider' in group_names %} -in tcp 636 # LDAPS -{% elif 'MX' in group_names or 'lists' in group_names %} -out tcp 636 # LDAPS -{% endif %} -{% if 'MX' in group_names %} -in tcp 25 # SMTP -{% if 'MDA' not in group_names %} -out tcp {{ postfix_instance.IMAP.port }} -{% endif %} -{% if 'lists' not in group_names %} -out tcp {{ postfix_instance.lists.port }} -{% endif %} -{% endif %} -{% if 'out' in group_names %} -{% if groups.all | difference([inventory_hostname]) %} -in tcp {{ postfix_instance.out.port }} -{% endif %} -out tcp 25 # SMTP -{% else %} -out tcp {{ postfix_instance.out.port }} -{% endif %} -{% if 'IMAP' in group_names %} -in tcp 993 # IMAPS -in tcp 4190 # MANAGESIEVE -{% endif %} -{% if 'MDA' in group_names and 'MX' not in group_names %} -in tcp {{ postfix_instance.IMAP.port }} -{% endif %} -{% if 'lists' in group_names and 'MX' not in group_names %} -in tcp {{ postfix_instance.lists.port }} -{% endif %} -{% if 'MSA' in group_names %} -in tcp 587 # SMTP-AUTH -{% endif %} -{% if 'webmail' in group_names or 'lists' in group_names or 'wiki' in group_names %} -in tcp 80,443 # HTTP/HTTPS -{% endif %} -{% if 'webmail' in group_names and 'IMAP' not in group_names %} -out tcp 993 # IMAP -out tcp 4190 # MANAGESIEVE -{% endif %} -{% if 'bacula-dir' in group_names and groups.all | difference(groups['bacula-dir']) %} -out tcp 9102 # BACULA-FD -{% elif groups['bacula-dir'] | difference([inventory_hostname]) %} -in tcp 9102 # BACULA-FD -{% endif %} -{% if 'bacula-sd' in group_names and groups.all | difference(groups['bacula-sd']) %} -in tcp 9103 # BACULA-SD -{% elif groups['bacula-sd'] | difference([inventory_hostname]) %} -out tcp 9103 # BACULA-SD -{% endif %} -{% if 'munin-master' in group_names and groups.all | difference([inventory_hostname]) %} -out tcp 4949 # MUNIN -{% endif %} -{% if groups['munin-master'] | difference([inventory_hostname]) %} -in tcp 4949 # MUNIN -{% endif %} -{% if 'LDAP-provider' in group_names %} -out tcp 11371 # HKP -out tcp 43 # WHOIS -{% endif %} diff --git a/roles/common/templates/etc/munin/munin-node.conf.j2 b/roles/common/templates/etc/munin/munin-node.conf.j2 index de4098a..1aba053 100644 --- a/roles/common/templates/etc/munin/munin-node.conf.j2 +++ b/roles/common/templates/etc/munin/munin-node.conf.j2 @@ -1,51 +1,52 @@ # # Example config-file for munin-node # log_level 4 log_file /var/log/munin/munin-node.log -pid_file /var/run/munin/munin-node.pid +pid_file /run/munin/munin-node.pid background 1 setsid 1 user root group root # This is the timeout for the whole transaction. # Units are in sec. Default is 15 min # # global_timeout 900 # This is the timeout for each plugin. # Units are in sec. Default is 1 min # # timeout 60 # Regexps for files to ignore ignore_file [\#~]$ ignore_file DEADJOE$ ignore_file \.bak$ ignore_file %$ ignore_file \.dpkg-(tmp|new|old|dist)$ ignore_file \.rpm(save|new)$ ignore_file \.pod$ # Set this if the client doesn't report the correct hostname when -# telnetting to localhost, port 4949 +# telnetting to {{ ipsec[inventory_hostname_short] }}, port 4949 # host_name {{ inventory_hostname_short }} # A list of addresses that are allowed to connect. This must be a # regular expression, since Net::Server does not understand CIDR-style # network notation unless the perl module Net::CIDR is installed. You # may repeat the allow line as many times as you'd like -allow ^127\.0\.0\.1$ -allow ^::1$ +{% for host in groups['munin_master'] %} +allow ^{{ ipsec[ hostvars[host].inventory_hostname_short ] | ansible.utils.ipv4 | replace(".","\.") }}$ +{% endfor %} # Which address to bind to; -host 127.0.0.1 +host {{ ipsec[inventory_hostname_short] }} # And which port port 4994 diff --git a/roles/common/templates/etc/munin/plugin-conf.d/munin-node.j2 b/roles/common/templates/etc/munin/plugin-conf.d/munin-node.j2 index 6cfa3f9..ec471eb 100644 --- a/roles/common/templates/etc/munin/plugin-conf.d/munin-node.j2 +++ b/roles/common/templates/etc/munin/plugin-conf.d/munin-node.j2 @@ -19,77 +19,78 @@ env.MUNIN_MKTEMP /bin/mktemp -p /tmp/ $1 env.amavislog /var/log/mail.info [apt] user root [courier_mta_mailqueue] group daemon [courier_mta_mailstats] group adm [courier_mta_mailvolume] group adm [cps*] user root [df*] env.warning 92 env.critical 98 +env.exclude_re ^/run/user [exim_mailqueue] group adm, (Debian-exim) [exim_mailstats] group adm, (Debian-exim) env.logdir /var/log/exim4/ env.logname mainlog [fw_conntrack] user root [fw_forwarded_local] user root [hddtemp_smartctl] user root [hddtemp2] user root [if_*] user root [if_err_*] user nobody [ip_*] user root [ipmi_*] user root [mysql*] user root env.mysqlopts --defaults-file=/etc/mysql/debian.cnf -env.mysqluser debian-sys-maint +env.mysqluser root env.mysqlconnection DBI:mysql:mysql;mysql_read_default_file=/etc/mysql/debian.cnf [postfix_mailqueue_*] user postfix [postfix_stats_*] group adm [postfix_sasl_*] group adm [postfix_mailvolume2] group adm env.postmulti postfix{% for g in postfix_instance.keys() | sort %}{% if g in group_names %} postfix-{{ postfix_instance[g].name }}{% endif %}{% endfor %} [dovecot_logins] group adm [dovecot_stats_*] diff --git a/roles/common/templates/etc/network/if-up.d/ipsec.j2 b/roles/common/templates/etc/network/if-up.d/ipsec.j2 new file mode 100755 index 0000000..9f183d3 --- /dev/null +++ b/roles/common/templates/etc/network/if-up.d/ipsec.j2 @@ -0,0 +1,46 @@ +#!/bin/sh + +# A post-up/down hook to automatically create/delete a virtual subnet +# for IPsec (inet4 only). +# Copyright © 2016 Guilhem Moulin <guilhem@fripost.org> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +set -ue +PATH=/usr/sbin:/usr/bin:/sbin:/bin + +# Ignore the loopback interface and non inet4 families. +[ "$IFACE" != lo -a "$ADDRFAM" = inet ] || exit 0 + +# Only the device with the default, globally-scoped route, is of +# interest here. +iface="$( ip -o route show to default scope global \ + | sed -nr '/^default via \S+ dev (\S+).*/ {s//\1/p;q}' )" +[ "$iface" = "$IFACE" ] || exit 0 + +vip="{{ ipsec[inventory_hostname_short] }}" +vsubnet="{{ ipsec_subnet }}" + +case "$MODE" in + start) ip address add "$vip/32" dev "$IFACE" scope global || true + # Nullroute the subnet used for IPsec to avoid data leaks + # in the absence of xfrm lookup (i.e., when there is no + # matching IPsec Security Association). + ip route replace prohibit "$vsubnet" proto static || true + ip route replace table 220 to "$vsubnet" dev "$IFACE" proto static src "$vip" || true + ;; + stop) ip route del table 220 to "$vsubnet" dev "$IFACE" proto static src "$vip" || true + ip route del prohibit "$vsubnet" proto static || true + ip address del "$vip/32" dev "$IFACE" scope global || true +esac diff --git a/roles/common/templates/etc/nftables.conf.j2 b/roles/common/templates/etc/nftables.conf.j2 new file mode 100755 index 0000000..f603ed9 --- /dev/null +++ b/roles/common/templates/etc/nftables.conf.j2 @@ -0,0 +1,238 @@ +#!/usr/sbin/nft -f + +define in-tcp-ports = { + {{ ansible_port|default(22) }} +{% if 'MX' in group_names %} + , 25 # SMTP +{% endif %} +{% if 'LDAP_provider' in group_names %} + , 636 # ldaps +{% endif %} +{% if 'IMAP' in group_names %} + , 993 # imaps + , 4190 # ManageSieve +{% endif %} +{% if 'MSA' in group_names %} + , 587 # submission [RFC4409] + , 465 # submission over TLS [RFC8314] +{% endif %} +{% if 'webmail' in group_names or 'lists' in group_names or 'wiki' in group_names or 'nextcloud' in group_names %} + , 80 # HTTP + , 443 # HTTP over SSL/TLS +{% endif %} +} + +define out-tcp-ports = { + 22 + , 80 # HTTP + , 443 # HTTP over SSL/TLS +{% if 'out' in group_names or 'MSA' in group_names %} + , 25 # SMTP +{% endif %} +{% if 'LDAP_provider' in group_names %} + , 11371 # OpenPGP HTTP Keyserver + , 43 # whois +{% elif 'MX' in group_names or 'lists' in group_names or 'nextcloud' in group_names %} + , 636 # ldaps +{% endif %} +{% if 'IMAP' in group_names %} + , 2703 # Razor2 +{% endif %} +} + + +############################################################################### + +flush ruleset + +table netdev filter { +{% for if in ansible_interfaces %} +{% if if != "lo" and ansible_facts[if].active %} +{% set addr = (ansible_facts[if].ipv4 | default({'address': '0.0.0.0'})).address %} + chain INGRESS-{{ if }} { + type filter hook ingress device {{ if }} priority -499 + policy accept + + # IPsec traffic (refined later in the filter rule) + ip saddr {{ ipsec_subnet }} ip daddr {{ ipsec[inventory_hostname_short] }} meta secpath exists accept + + # rate-limiting is done directly by the kernel (net.ipv4.icmp_{ratelimit,ratemask} runtime options) + icmp type { echo-reply, echo-request, destination-unreachable, time-exceeded } counter accept + icmpv6 type { echo-reply, echo-request, destination-unreachable, + packet-too-big, time-exceeded, parameter-problem } counter accept + + # accept neighbour discovery for autoconfiguration, RFC 4890 sec. 4.4.1 + ip6 hoplimit 255 icmpv6 type { 133,134,135,136,141,142 } counter accept + + # accept link-local multicast receiver notification messages + ip6 saddr fe80::/10 ip6 daddr ff02::/16 ip6 hoplimit 1 icmpv6 type { 130,131,132,143 } counter accept + + # drop all remaining ICMP/ICMPv6 traffic + meta l4proto { icmp, icmpv6 } counter drop + + # bogon filter (cf. RFC 6890 for non-global ip addresses) + define bogon = { + 0.0.0.0/8 # this host, on this network (RFC 1122 sec. 3.2.1.3) +{% if not addr | ansible.utils.ipaddr('10.0.0.0/8') %} + , 10.0.0.0/8 # private-use (RFC 1918) +{% endif %} + , 100.64.0.0/10 # shared address space (RFC 6598) + , 127.0.0.0/8 # loopback (RFC 1122, sec. 3.2.1.3) + , 169.254.0.0/16 # link local (RFC 3927) + , 172.16.0.0/12 # private-use (RFC 1918) + , 192.0.0.0/24 # IETF protocol assignments (RFC 6890 sec. 2.1) + , 192.0.2.0/24 # documentation (RFC 5737) +{% if not addr | ansible.utils.ipaddr('192.168.0.0/16') %} + , 192.168.0.0/16 # private-use (RFC 1918) +{% endif %} + , 198.18.0.0/15 # benchmarking (RFC 2544) + , 198.51.100.0/24 # documentation (RFC 5737) + , 203.0.113.0/24 # documentation (RFC 5737) + , 224.0.0.0/3 # multicast - class D 224.0.0.0/4 + class E 240.0.0.0/4 (RFC 1112 sec. 4) + , 255.255.255.255/32 # limited broadcast (RFC 0919 sec. 7) + } + + ip saddr $bogon counter drop + ip daddr $bogon counter drop + + # See also https://www.team-cymru.org/Services/Bogons/fullbogons-ipv6.txt + define bogon6 = { + ::1/128 # loopback address (RFC 4291) + , ::/128 # unspecified (RFC 4291) + , ::ffff:0:0/96 # IPv4-mapped address (RFC 4291) + , 100::/64 # discard-only address block (RFC 6666) + , 2001::/23 # IETF protocol assignments (RFC 2928) + , 2001::/32 # TEREDO (RFC 4380) + , 2001:2::/48 # benchmarking (RFC 5180) + , 2001:db8::/32 # documentation (RFC 3849) + , 2001:10::/28 # ORCHID (RFC 4843) + , 2002::/16 # 6to4 (RFC 3056) + , fc00::/7 # unique-local (RFC 4193) + , fe80::/10 # linked-scoped unicast (RFC 4291) + } + + ip6 saddr $bogon6 counter drop + ip6 saddr $bogon6 counter drop + } +{% endif %} +{% endfor %} +} + +table inet raw { + chain PREROUTING-stateless { + # XXX can't add that to the ingress hook as that happens before IP defragmentation + # so we don't have the TCP header in later fragments (we don't want to drop IP + # fragments, see https://blog.cloudflare.com/ip-fragmentation-is-broken/ ) + type filter hook prerouting priority -399 # > NF_IP_PRI_CONNTRACK_DEFRAG (-400) + policy accept + + # stateless filter for bogus TCP packets + tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 counter drop # null packet + tcp flags & (fin|psh|urg) == fin|psh|urg counter drop # XMAS packet + tcp flags & (syn|rst) == syn|rst counter drop + tcp flags & (fin|rst) == fin|rst counter drop + tcp flags & (fin|syn) == fin|syn counter drop + tcp flags & (fin|psh|ack) == fin|psh counter drop + } + + chain PREROUTING { + type filter hook prerouting priority -199 # > NF_IP_PRI_CONNTRACK (-200) + policy accept + + # stateful filter + ct state invalid counter drop + } +} + +table inet filter { + # blackholes (timeout must match /etc/fail2ban/jail.local) + set fail2ban { type ipv4_addr; timeout 10m; } + set fail2ban6 { type ipv6_addr; timeout 10m; } + + chain input { + type filter hook input priority 0 + policy drop + + iif lo accept + + meta l4proto esp accept + ip daddr {{ ipsec[inventory_hostname_short] }} jump ipsec-in + + # incoming ICMP/ICMPv6 traffic was filtered in the ingress chain already + meta l4proto { icmp, icmpv6 } counter accept + + # NTP (ntpd uses sport 123 but systemd-timesyncd does not) + udp sport 123 ct state related,established accept + +{% if groups.all | length > 1 %} + udp sport 500 udp dport 500 ct state new,related,established accept +{% if groups.NATed | length > 0 %} + udp sport 4500 udp dport 4500 ct state new,related,established accept +{% endif %} +{% endif %} + + udp sport 53 ct state related,established accept + tcp sport 53 ct state related,established accept +{% if 'dhclient' in group_names %} + ip version 4 udp sport 67 udp dport 68 ct state related,established accept + ip6 version 6 udp sport 547 udp dport 546 ct state related,established accept +{% endif %} + + ip saddr @fail2ban counter drop + ip6 saddr @fail2ban6 counter drop + + tcp dport $in-tcp-ports ct state related,established accept + tcp dport $in-tcp-ports ct state new counter accept + tcp sport $out-tcp-ports ct state related,established accept + } + + chain output { + type filter hook output priority 0 + policy drop + + oif lo accept + + meta l4proto esp accept + ip saddr {{ ipsec[inventory_hostname_short] }} jump ipsec-out + + meta l4proto { icmp, icmpv6 } counter accept + + # NTP (ntpd uses sport 123 but systemd-timesyncd does not) + udp dport 123 ct state new,related,established accept + +{% if groups.all | length > 1 %} + udp sport 500 udp dport 500 ct state new,related,established accept +{% if groups.NATed | length > 0 %} + udp sport 4500 udp dport 4500 ct state new,related,established accept +{% endif %} +{% endif %} + + udp dport 53 ct state new,related,established accept + tcp dport 53 ct state new,related,established accept +{% if 'dhclient' in group_names %} + ip version 4 udp sport 68 udp dport 67 ct state new,related,established accept + ip6 version 6 udp sport 546 udp dport 547 ct state new,related,established accept +{% endif %} + + tcp sport $in-tcp-ports ct state related,established accept + tcp dport $out-tcp-ports ct state related,established accept + tcp dport $out-tcp-ports ct state new counter accept + + meta l4proto tcp counter reject with tcp reset + meta l4proto udp counter reject + counter reject + } + + chain ipsec-in { +{% for h in ipsec.keys() | difference([inventory_hostname_short]) | sort %} + ip saddr {{ ipsec[h] }} ipsec in reqid {{ ipsec[h].replace(":",".").split(".")[-1] }} counter accept +{% endfor %} + log prefix "ipsec-in " drop + } + chain ipsec-out { +{% for h in ipsec.keys() | difference([inventory_hostname_short]) | sort %} + ip daddr {{ ipsec[h] }} ipsec out reqid {{ ipsec[h].replace(":",".").split(".")[-1] }} counter accept +{% endfor %} + log prefix "ipsec-out " drop + } +} diff --git a/roles/common/templates/etc/ntp.conf.j2 b/roles/common/templates/etc/ntp.conf.j2 index d46ba18..b76f0dd 100644 --- a/roles/common/templates/etc/ntp.conf.j2 +++ b/roles/common/templates/etc/ntp.conf.j2 @@ -1,63 +1,59 @@ # /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help driftfile /var/lib/ntp/ntp.drift +# Leap seconds definition provided by tzdata +leapfile /usr/share/zoneinfo/leap-seconds.list # Enable this if you want statistics to be logged. #statsdir /var/log/ntpstats/ statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable # You do need to talk to an NTP server or two (or three). -{% if 'NTP-master' in group_names %} # Use Stratum One Time Servers: # http://support.ntp.org/bin/view/Servers/StratumOneTimeServers -server ntp1.sp.se iburst -server ntp2.sp.se iburst -server ntp2.gbg.netnod.se iburst -server ntp1.sth.netnod.se iburst -server ntp2.sth.netnod.se iburst -{% else %} -# Sychronize to our (stratum 2) NTP server, to ensure our network has a -# consistent time. -# TODO: use to pubkey authentication to unsure an attacker doesn't -# impersonate our NTP server and gives us incorrect time. -server ntp.fripost.org iburst -server 0.se.pool.ntp.org iburst -server 1.se.pool.ntp.org iburst -{% endif %} +server sth1.ntp.se iburst +server sth2.ntp.se iburst +server gbg1.ntp.se iburst +server gbg2.ntp.se iburst +server ntp1.sp.se iburst +server ntp2.sp.se iburst # Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for # details. The web page <http://support.ntp.org/bin/view/Support/AccessRestrictions> # might also be helpful. # # Note that "restrict" applies to both servers and clients, so a configuration # that might be intended to block requests from certain clients could also end # up blocking replies from your own upstream servers. # By default, exchange time with everybody, but don't allow configuration. -restrict -4 default limited kod nomodify notrap nopeer noquery -restrict -6 default limited kod nomodify notrap nopeer noquery +restrict -4 default kod notrap nomodify nopeer noquery limited +restrict -6 default kod notrap nomodify nopeer noquery limited # Local users may interrogate the ntp server more closely. restrict 127.0.0.1 restrict ::1 +# Needed for adding pool entries +restrict source notrap nomodify noquery + # Clients from this (example!) subnet have unlimited access, but only if # cryptographically authenticated. #restrict 192.168.123.0 mask 255.255.255.0 notrust # If you want to provide time to your local subnet, change the next line. # (Again, the address is an example only.) #broadcast 192.168.123.255 # If you want to listen to time broadcasts on your local subnet, de-comment the # next lines. Please do this only if you trust everybody on the network! #disable auth #broadcastclient diff --git a/roles/common/templates/etc/postfix/main.cf.j2 b/roles/common/templates/etc/postfix/main.cf.j2 index 1b0bc4a..5ac7920 100644 --- a/roles/common/templates/etc/postfix/main.cf.j2 +++ b/roles/common/templates/etc/postfix/main.cf.j2 @@ -1,70 +1,48 @@ ######################################################################## # Nullmailer configuration # # {{ ansible_managed }} # Do NOT edit this file directly! -smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU) -biff = no -readme_directory = no -mail_owner = postfix +smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU) +biff = no +readme_directory = no +compatibility_level = 2 +smtputf8_enable = no myorigin = /etc/mailname myhostname = {{ ansible_fqdn }} mydomain = {{ ansible_domain }} append_dot_mydomain = no # This server is for internal use only mynetworks_style = host inet_interfaces = loopback-only # No local delivery mydestination = local_transport = error:5.1.1 Mailbox unavailable alias_maps = local_recipient_maps = # All aliases are virtual -default_database_type = cdb -virtual_alias_maps = cdb:/etc/aliases +default_database_type = lmdb +virtual_alias_maps = lmdb:/etc/aliases alias_database = $virtual_alias_maps # Forward everything to our internal outgoing proxy -{% if 'out' in group_names %} -relayhost = [127.0.0.1]:{{ postfix_instance.out.port }} -{% else %} -relayhost = [outgoing.fripost.org]:{{ postfix_instance.out.port }} -{% endif %} +relayhost = [{{ postfix_instance.out.addr | ansible.utils.ipaddr }}]:{{ postfix_instance.out.port }} relay_domains = -{% if 'out' in group_names %} -smtp_tls_security_level = none -smtp_bind_address = 127.0.0.1 -{% else %} -smtp_tls_security_level = encrypt -smtp_tls_cert_file = $config_directory/ssl/{{ ansible_fqdn }}.pem -smtp_tls_key_file = $config_directory/ssl/{{ ansible_fqdn }}.key -smtp_tls_session_cache_database = btree:$data_directory/smtp_tls_session_cache -smtp_tls_policy_maps = cdb:$config_directory/tls_policy -smtp_tls_fingerprint_digest = sha256 -{% endif %} -smtpd_tls_security_level = none - -# Turn off all TCP/IP listener ports except that dedicated to -# samhain(8), which sadly cannot use pickup through the sendmail binary. -master_service_disable = !127.0.0.1:16132.inet inet +smtp_tls_security_level = none +smtpd_tls_security_level = none -{% set multi_instance = False %} -{%- for g in postfix_instance.keys() | sort -%} - {%- if g in group_names -%} - {%- if not multi_instance -%} - {%- set multi_instance = True -%} -## Other postfix instances +{% set instances = postfix_instance.keys() | intersect(group_names) | list %} +{%- if instances | length > 0 -%} +# Other postfix instances multi_instance_wrapper = $command_directory/postmulti -p -- multi_instance_enable = yes -multi_instance_directories = - {%- endif %} /etc/postfix-{{ postfix_instance[g].name }} - {%- endif %} -{% endfor %} +multi_instance_directories ={% for i in instances | sort %} /etc/postfix-{{ postfix_instance[i].name }}{% endfor %} +{% endif %} # vim: set filetype=pfmain : diff --git a/roles/common/templates/etc/postfix/master.cf.j2 b/roles/common/templates/etc/postfix/master.cf.j2 new file mode 100644 index 0000000..3954085 --- /dev/null +++ b/roles/common/templates/etc/postfix/master.cf.j2 @@ -0,0 +1,114 @@ +######################################################################## +# Postfix master process configuration file. For details on the format +# of the file, see the master(5) manual page (command: "man 5 master"). +# +# {{ ansible_managed }} +# Do NOT edit this file directly! +# +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (yes) (never) (100) +# ========================================================================== + +{% if inst is not defined %} +[127.0.0.1]:16132 inet n - y - - smtpd +{% elif inst == 'MX' %} +smtpd pass - - y - - smtpd +smtp inet n - y - 1 postscreen +tlsproxy unix - - y - 0 tlsproxy +dnsblog unix - - y - 0 dnsblog +{% elif inst == 'MSA' %} +submission inet n - y - - smtpd +submissions inet n - y - - smtpd + -o smtpd_tls_wrappermode=yes +{% if groups.webmail | difference([inventory_hostname]) | length > 0 %} +[{{ postfix_instance.MSA.addr }}]:{{ postfix_instance.MSA.port }} inet n - y - - smtpd + -o broken_sasl_auth_clients=no + -o smtpd_tls_security_level=none + -o smtpd_sasl_security_options=noanonymous + -o smtpd_sasl_exceptions_networks= + -o smtpd_authorized_xforward_hosts=127.0.0.0/8,[::1]/128{{ ipsec_subnet is defined | ternary(','+ipsec_subnet, '') }} + -o smtpd_peername_lookup=no +{% endif %} +{% elif inst in ['IMAP', 'out', 'lists'] %} +[{{ postfix_instance[inst].addr }}]:{{ postfix_instance[inst].port }} inet n - y - - smtpd + -o smtpd_authorized_xforward_hosts=127.0.0.0/8,[::1]/128{{ ipsec_subnet is defined | ternary(','+ipsec_subnet, '') }} + -o smtpd_peername_lookup=no +{% endif %} +pickup unix n - y 60 1 pickup +cleanup unix n - y - 0 cleanup +qmgr unix n - n 300 1 qmgr +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 +# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 +{% if inst is defined and inst == 'MSA' %} +smtp_verify unix - - y - - smtp + -o smtp_helo_name=noreply.$mydomain + -o smtp_tls_security_level=may + -o smtp_tls_ciphers=medium + -o smtp_tls_protocols=!SSLv2,!SSLv3 + -o smtp_tls_note_starttls_offer=yes + -o smtp_tls_session_cache_database=lmdb:$data_directory/smtp_tls_session_cache + -o smtp_tls_fingerprint_digest=sha256 + -o smtp_tls_policy_maps=lmdb:$config_directory/smtp_tls_policy +{% endif %} +relay unix - - y - - smtp +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 +{% if inst is defined and inst == 'MSA' %} +policyd-spf unix - n n - 0 spawn + user=policyd-spf argv=/usr/bin/policyd-spf +{% endif %} +{% if inst is defined and inst == 'MX' %} +reserved-alias unix - n n - - pipe + flags=Rhu user=nobody argv=/usr/local/bin/reserved-alias.pl ${sender} ${original_recipient} @fripost.org +{% endif %} +{% if inst is defined and inst == 'lists' %} +sympa unix - n n - - pipe + flags=Rhu user=sympa argv=/usr/local/bin/sympa-queue ${user} +{% endif %} + +{% if inst is defined and inst == 'out' %} +# Client part (lmtp) - amavis +amavisfeed unix - - y - 5 lmtp + -o lmtp_destination_recipient_limit=1000 + -o lmtp_send_xforward_command=yes + -o lmtp_data_done_timeout=1200s + -o disable_dns_lookups=yes + +# Server part (smtpd) - amavis +[127.0.0.1]:10025 inet n - y - - smtpd + -o content_filter= + -o smtpd_delay_reject=no + -o smtpd_client_restrictions=permit_mynetworks,reject + -o smtpd_helo_restrictions= + -o smtpd_sender_restrictions= + -o smtpd_relay_restrictions=permit_mynetworks,reject + -o smtpd_data_restrictions=reject_unauth_pipelining + -o smtpd_end_of_data_restrictions= + -o smtpd_restriction_classes= + -o mynetworks_style=host + -o smtpd_error_sleep_time=0 + -o smtpd_soft_error_limit=1001 + -o smtpd_hard_error_limit=1000 + -o smtpd_client_connection_count_limit=0 + -o smtpd_client_connection_rate_limit=0 + -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_milters + -o local_header_rewrite_clients= + -o smtpd_authorized_xforward_hosts=127.0.0.0/8 +{% endif %} diff --git a/roles/common/templates/etc/postfix/tls_policy.j2 b/roles/common/templates/etc/postfix/tls_policy.j2 deleted file mode 100644 index 5ff7d26..0000000 --- a/roles/common/templates/etc/postfix/tls_policy.j2 +++ /dev/null @@ -1,25 +0,0 @@ -# {{ ansible_managed }} -# /!\ WARNING: smtp_tls_fingerprint_digest MUST be sha256! - -{% if 'out' not in group_names %} -[outgoing.fripost.org]:{{ postfix_instance.out.port }} fingerprint ciphers=high protocols=TLSv1.2 -{% for h in groups.out | sort %} - match={{ lookup('pipe', 'openssl x509 -in certs/postfix/'+h+'.pem -noout -fingerprint -sha256 | cut -d= -f2') }} -{% endfor %} -{% endif %} - -{% if 'MX' in group_names %} -{% if 'IMAP' not in group_names %} -[mda.fripost.org]:{{ postfix_instance.IMAP.port }} fingerprint ciphers=high protocols=TLSv1.2 -{% for h in groups.IMAP | sort %} - match={{ lookup('pipe', 'openssl x509 -in certs/postfix/'+h+'.pem -noout -fingerprint -sha256 | cut -d= -f2') }} -{% endfor %} -{% endif %} - -{% if 'lists' not in group_names %} -[lists.fripost.org]:{{ postfix_instance.lists.port }} fingerprint ciphers=high protocols=TLSv1.2 -{% for h in groups.lists | sort %} - match={{ lookup('pipe', 'openssl x509 -in certs/postfix/'+h+'.pem -noout -fingerprint -sha256 | cut -d= -f2') }} -{% endfor %} -{% endif %} -{% endif %} diff --git a/roles/common/templates/etc/rsyslog.d/postfix.conf.j2 b/roles/common/templates/etc/rsyslog.d/postfix.conf.j2 index 5acb56d..52f9ea3 100644 --- a/roles/common/templates/etc/rsyslog.d/postfix.conf.j2 +++ b/roles/common/templates/etc/rsyslog.d/postfix.conf.j2 @@ -1,17 +1,17 @@ # Create an additional socket in postfix's chroot in order not to break # mail logging when rsyslog is restarted. If the directory is missing, # rsyslog will silently skip creating the socket. $AddUnixListenSocket /var/spool/postfix/dev/log {% for g in postfix_instance.keys() | sort %} {% if g in group_names %} $AddUnixListenSocket /var/spool/postfix-{{ postfix_instance[g].name }}/dev/log {% endif %} {% endfor %} {% if 'MSA' in group_names %} # User of our Authenticated SMTP server can choose the envelope from and From: # header of their choice. As the SASL username is not logged in the mail # header, we keep a mapping Postfix's message ID -> SASL username in a separate # log file that is only rotated monthly. -if $programname == 'postfix-msa' and $syslogfacility-text == 'mail' and $msg contains 'sasl_username=' then /var/log/mail.sasl +if $programname == 'postfix-{{ postfix_instance.MSA.name }}' and $syslogfacility-text == 'mail' and $msg contains 'sasl_username=' then /var/log/mail.sasl {% endif %} diff --git a/roles/common/templates/etc/stunnel/bacula-fd.conf.j2 b/roles/common/templates/etc/stunnel/bacula-fd.conf.j2 deleted file mode 100644 index 74364c9..0000000 --- a/roles/common/templates/etc/stunnel/bacula-fd.conf.j2 +++ /dev/null @@ -1,62 +0,0 @@ -; ************************************************************************** -; * Global options * -; ************************************************************************** - -; setuid()/setgid() to the specified user/group in daemon mode -setuid = stunnel4 -setgid = stunnel4 - -; PID is created inside the chroot jail -pid = /var/run/stunnel4/bacula-fd.pid - -; Only log messages at severity warning (4) and higher -debug = 4 - -; ************************************************************************** -; * Service defaults may also be specified in individual service sections * -; ************************************************************************** - -; Certificate/key is needed in server mode and optional in client mode -cert = /etc/stunnel/certs/{{ inventory_hostname_short }}-fd.pem -key = /etc/stunnel/certs/{{ inventory_hostname_short }}-fd.key - -; Some performance tunings -socket = l:TCP_NODELAY=1 -socket = r:TCP_NODELAY=1 - -; Prevent MITM attacks -verify = 4 - -; Disable support for insecure protocols -options = NO_SSLv2 -options = NO_SSLv3 -options = NO_TLSv1 -options = NO_TLSv1.1 - -; These options provide additional security at some performance degradation -options = SINGLE_ECDH_USE -options = SINGLE_DH_USE - -; Select permitted SSL ciphers -ciphers = EECDH+AES:EDH+AES:!MEDIUM:!LOW:!EXP:!aNULL:!eNULL:!SSLv2:!SSLv3:!TLSv1:!TLSv1.1 - -; ************************************************************************** -; * Service definitions (remove all services for inetd mode) * -; ************************************************************************** - -[{{ inventory_hostname_short }}-fd] -client = no -accept = 9102 -connect = 9112 -CAfile = /etc/stunnel/certs/bacula-dirs.pem - -{% if 'bacula-sd' not in group_names %} -[{{ hostvars[ groups['bacula-sd'][0] ].inventory_hostname_short }}-sd] -client = yes -accept = 127.0.0.1:9113 -connect = {{ groups['bacula-sd'][0] }}:9103 -delay = yes -CAfile = /etc/stunnel/certs/{{ hostvars[ groups['bacula-sd'][0] ].inventory_hostname_short }}-sd.pem -{% endif %} - -; vim:ft=dosini diff --git a/roles/common/templates/etc/stunnel/munin-node.conf.j2 b/roles/common/templates/etc/stunnel/munin-node.conf.j2 deleted file mode 100644 index de6c156..0000000 --- a/roles/common/templates/etc/stunnel/munin-node.conf.j2 +++ /dev/null @@ -1,53 +0,0 @@ -; ************************************************************************** -; * Global options * -; ************************************************************************** - -; setuid()/setgid() to the specified user/group in daemon mode -setuid = stunnel4 -setgid = stunnel4 - -; PID is created inside the chroot jail -pid = /var/run/stunnel4/munin-node.pid - -; Only log messages at severity warning (4) and higher -debug = 4 - -; ************************************************************************** -; * Service defaults may also be specified in individual service sections * -; ************************************************************************** - -; Certificate/key is needed in server mode and optional in client mode -cert = /etc/stunnel/certs/munin-{{ inventory_hostname_short }}.pem -key = /etc/stunnel/certs/munin-{{ inventory_hostname_short }}.key - -; Some performance tunings -socket = l:TCP_NODELAY=1 -socket = r:TCP_NODELAY=1 - -; Prevent MITM attacks -verify = 4 - -; Disable support for insecure protocols -options = NO_SSLv2 -options = NO_SSLv3 -options = NO_TLSv1 -options = NO_TLSv1.1 - -; These options provide additional security at some performance degradation -options = SINGLE_ECDH_USE -options = SINGLE_DH_USE - -; Select permitted SSL ciphers -ciphers = EECDH+AES:EDH+AES:!MEDIUM:!LOW:!EXP:!aNULL:!eNULL:!SSLv2:!SSLv3:!TLSv1:!TLSv1.1 - -; ************************************************************************** -; * Service definitions (remove all services for inetd mode) * -; ************************************************************************** - -[munin-node] -client = no -accept = 4949 -connect = 127.0.0.1:4994 -CAfile = /etc/stunnel/certs/munin-master.pem - -; vim:ft=dosini diff --git a/roles/common/templates/etc/systemd/resolved.conf.d/local.conf.j2 b/roles/common/templates/etc/systemd/resolved.conf.d/local.conf.j2 new file mode 100644 index 0000000..044170a --- /dev/null +++ b/roles/common/templates/etc/systemd/resolved.conf.d/local.conf.j2 @@ -0,0 +1,11 @@ +[Resolve] +LLMNR=no +{% if ansible_processor[1] is search('^(Genuine)?Intel.*') and not ansible_virtualization_role == 'guest' %} +DNS=127.0.0.1 +# Quad9 +FallbackDNS=9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net +{% else %} +# Quad9 +DNS=9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net +{% endif %} +Domains=fripost.org diff --git a/roles/common/templates/etc/systemd/timesyncd.conf.d/fripost.conf.j2 b/roles/common/templates/etc/systemd/timesyncd.conf.d/fripost.conf.j2 new file mode 100644 index 0000000..f578cd9 --- /dev/null +++ b/roles/common/templates/etc/systemd/timesyncd.conf.d/fripost.conf.j2 @@ -0,0 +1,9 @@ +[Time] +# Sychronize to our (stratum 2) NTP server, to ensure our network has a +# consistent time. +{%- set ntp = [] -%} +{%- for host in groups['NTP_master'] -%} +{%- set _ = ntp.append(ipsec[ hostvars[host].inventory_hostname_short ]) -%} +{%- endfor %} + +NTP={{ ntp | join(' ') }} diff --git a/roles/common/templates/etc/unbound/unbound.conf.j2 b/roles/common/templates/etc/unbound/unbound.conf.j2 new file mode 100644 index 0000000..e75e66f --- /dev/null +++ b/roles/common/templates/etc/unbound/unbound.conf.j2 @@ -0,0 +1,32 @@ +# Unbound configuration file for Debian. +# +# See the unbound.conf(5) man page. +# +# See /usr/share/doc/unbound/examples/unbound.conf for a commented +# reference config file. + +remote-control: + control-enable: no + +server: + interface: 127.0.0.1 + root-hints: "/usr/share/dns/root.hints" + hide-identity: yes + hide-version: yes + prefetch: yes + qname-minimisation: yes + rrset-roundrobin: yes + use-caps-for-id: yes + + # RFC 1918 + private-address: 10.0.0.0/8 + private-address: 172.16.0.0/12 + private-address: 192.168.0.0/16 + private-address: 169.254.0.0/16 + private-address: fd00::/8 + private-address: fe80::/10 + +# +# The following line includes additional configuration files from the +# /etc/unbound/unbound.conf.d directory. +include-toplevel: "/etc/unbound/unbound.conf.d/*.conf" |