diff --git a/ChangeLog.txt b/ChangeLog.txt index f26010e..bef947d 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,15 +1,21 @@ -## [unreleased] - in progress +## [1.2] - 2020-03-14 -- Reworked firewall rules to cover both native applications and ones - running in Docker containers. Moved most blocking to the PREROUTING - chain of the "mangle" table. This block at lower cost because it is - earlier in the process, for better performance during packet floods. - It is also before the split between INPUT (used by native apps) and - FORWARD (used by Docker) so it covers both. Also added rules for - DHCP because connection tracking can break in some situations. +- Added roles for Docker and Roundcube, plus a webmail playbook that + sets up a Roundcube container on a separate machine. + +- Reworked firewall to cover both native applications and Docker + containers. Now blocking in the PREROUTING chain of the "mangle" + table. This is lower cost because it is early in the process, and + before the split between INPUT (used by native apps) and FORWARD + (used by Docker) so it covers both. Also added rules for DHCP + because connection tracking can break in some situations. - Reworked fail2ban configuration to allow customization of the jails, - to change bantimes or retarget to the DOCKER-USER chain. + to change bantimes or retarget to the DOCKER-USER chain. + +- Tightened permissions on DKIM folder. + +- Added managesieve plugins for Dovecot and Roundcube. ## [1.1] - 2020-02-18 diff --git a/docs/firewall.html b/docs/firewall.html index f24b7f5..8bda721 100644 --- a/docs/firewall.html +++ b/docs/firewall.html @@ -54,8 +54,8 @@

firewall_services: [ 'ssh' ] # Define 'foobar' name for firewall services by defining: -#foobar_opentcp: [ 12345, 23456 ] -#foobar_openudp: [ 34567 ] +#firewall_opentcp_foobar: [ 12345, 23456 ] +#firewall_openudp_foobar: [ 34567 ]

The firewall_opentcp and firewall_openudp diff --git a/roles/common/defaults/main.yml b/roles/common/defaults/main.yml index 3baaeed..1e93f07 100644 --- a/roles/common/defaults/main.yml +++ b/roles/common/defaults/main.yml @@ -80,10 +80,10 @@ firewall_block_ips_v6: [] # SSH Ports - Usually 22, but some people change to 2222 or whatnot to # avoid the endless log spam from the constant bot attempts. -ssh_opentcp: [22] +firewall_opentcp_ssh: [22] # Web Ports - HTTP and HTTPS -web_opentcp: [80, 443] +firewall_opentcp_web: [80, 443] # Mail Ports - Just submission and imaps, no plain imap or pop3 # @@ -98,13 +98,14 @@ web_opentcp: [80, 443] # SMTP | Port 25 (Outdated and not recommended. username/password # authentication MUST be enabled if using this port.) # -mail_opentcp: [25, 465, 587, 993] +firewall_opentcp_mail: [25, 465, 587, 993] +firewall_opentcp_sieve: [4190] # DNS - UDP port 53 -dns_openudp: [53] +firewall_openudp_dns: [53] # Bacula Ports - Director (9101), File (9102), Storage (9103) -bacula_opentcp: [9101, 9102, 9103] +firewall_opentcp_bacula: [9101, 9102, 9103] # Construct the list of open TCP and UDP ports from the known services @@ -114,16 +115,16 @@ bacula_opentcp: [9101, 9102, 9103] # that service. # firewall_ports_tcp: >- - {%- set ns = namespace(ports=(firewall_opentcp + ssh_opentcp)) -%} + {%- set ns = namespace(ports=(firewall_opentcp + firewall_opentcp_ssh)) -%} {%- for i in firewall_services -%} - {{- ns.ports.extend( lookup('vars', i + '_opentcp', default=[]) ) -}} + {{- ns.ports.extend( lookup('vars', 'firewall_opentcp_'+i, default=[]) ) -}} {%- endfor -%} {{- ns.ports | sort | unique -}} firewall_ports_udp: >- {%- set ns = namespace(ports=(firewall_openudp)) -%} {%- for i in firewall_services -%} - {{- ns.ports.extend( lookup('vars', i + '_openudp', default=[]) ) -}} + {{- ns.ports.extend( lookup('vars', 'firewall_openudp_'+i, default=[]) ) -}} {%- endfor -%} {{- ns.ports | sort | unique -}} @@ -169,6 +170,9 @@ fail2ban_jail_mail: - name: postfix - name: postfix-sasl +fail2ban_jail_sieve: + - name: sieve + fail2ban_jail_web: - name: apache-auth - name: apache-overflows diff --git a/roles/mailhost/tasks/dovecot.yml b/roles/mailhost/tasks/dovecot.yml index 5c65889..36efe28 100644 --- a/roles/mailhost/tasks/dovecot.yml +++ b/roles/mailhost/tasks/dovecot.yml @@ -18,9 +18,12 @@ - dovecot-imapd - dovecot-lmtpd - dovecot-sqlite - - dovecot-sieve # spam filing and learning - -# - dovecot-managesieved # managesieve server + # sieve for moving spam to the junk folder and piping it through + # the learning process, managesieve server for client access to + # personal sieve scripts. Add "sieve" to the firewall to open + # up the ports. + - dovecot-sieve + - dovecot-managesieved # Do not start dovecot at boot, Wait until the encrypted spool is # mounted. Our "mailboot" script mounts and starts. @@ -53,6 +56,7 @@ - 15-mailboxes.conf - 20-imap.conf - 20-lmtp.conf + - 20-managesieve.conf - 90-sieve.conf - auth-sql.conf.ext notify: restart dovecot diff --git a/roles/mailhost/tasks/rspamd.yml b/roles/mailhost/tasks/rspamd.yml index c065360..04e1f82 100644 --- a/roles/mailhost/tasks/rspamd.yml +++ b/roles/mailhost/tasks/rspamd.yml @@ -100,7 +100,7 @@ - name: DKIM key directory present file: path={{ mail_dkim_root }} state=directory - owner=_rspamd group=_rspamd mode=0755 + owner=_rspamd group=_rspamd mode=0750 tags: dkim - name: DKIM keys generated diff --git a/roles/mailhost/templates/dovecot/20-managesieve.conf b/roles/mailhost/templates/dovecot/20-managesieve.conf new file mode 100644 index 0000000..e23f132 --- /dev/null +++ b/roles/mailhost/templates/dovecot/20-managesieve.conf @@ -0,0 +1,84 @@ +## +## ManageSieve specific settings +## + +# Uncomment to enable managesieve protocol: +protocols = $protocols sieve + +# Service definitions + +service managesieve-login { + inet_listener sieve { + port = 4190 + } + + #inet_listener sieve_deprecated { + # port = 2000 + #} + + # Number of connections to handle before starting a new process. Typically + # the only useful values are 0 (unlimited) or 1. 1 is more secure, but 0 + # is faster. + #service_count = 1 + + # Number of processes to always keep waiting for more connections. + #process_min_avail = 0 + + # If you set service_count=0, you probably need to grow this. + #vsz_limit = 64M +} + +service managesieve { + # Max. number of ManageSieve processes (connections) + process_limit = 1024 +} + +# Service configuration + +protocol sieve { + # Maximum ManageSieve command line length in bytes. ManageSieve usually does + # not involve overly long command lines, so this setting will not normally + # need adjustment + #managesieve_max_line_length = 65536 + + # Maximum number of ManageSieve connections allowed for a user from each IP + # address. + # NOTE: The username is compared case-sensitively. + #mail_max_userip_connections = 10 + + # Space separated list of plugins to load (none known to be useful so far). + # Do NOT try to load IMAP plugins here. + #mail_plugins = + + # MANAGESIEVE logout format string: + # %i - total number of bytes read from client + # %o - total number of bytes sent to client + # %{put_bytes} - Number of bytes saved using PUTSCRIPT command + # %{put_count} - Number of scripts saved using PUTSCRIPT command + # %{get_bytes} - Number of bytes read using GETCRIPT command + # %{get_count} - Number of scripts read using GETSCRIPT command + # %{get_bytes} - Number of bytes processed using CHECKSCRIPT command + # %{get_count} - Number of scripts checked using CHECKSCRIPT command + # %{deleted_count} - Number of scripts deleted using DELETESCRIPT command + # %{renamed_count} - Number of scripts renamed using RENAMESCRIPT command + #managesieve_logout_format = bytes=%i/%o + + # To fool ManageSieve clients that are focused on CMU's timesieved you can + # specify the IMPLEMENTATION capability that Dovecot reports to clients. + # For example: 'Cyrus timsieved v2.2.13' + #managesieve_implementation_string = Dovecot Pigeonhole + + # Explicitly specify the SIEVE and NOTIFY capability reported by the server + # before login. If left unassigned these will be reported dynamically + # according to what the Sieve interpreter supports by default (after login + # this may differ depending on the user). + #managesieve_sieve_capability = + #managesieve_notify_capability = + + # The maximum number of compile errors that are returned to the client upon + # script upload or script verification. + #managesieve_max_compile_errors = 5 + + # Refer to 90-sieve.conf for script quota configuration and configuration of + # Sieve execution limits. +} diff --git a/roles/roundcube/templates/config.inc.php.j2 b/roles/roundcube/templates/config.inc.php.j2 index aa71458..2bd217e 100644 --- a/roles/roundcube/templates/config.inc.php.j2 +++ b/roles/roundcube/templates/config.inc.php.j2 @@ -31,3 +31,10 @@ $config['product_name'] = '{{ webmail_product_name }}'; // for example array("*" => "/images/roundcube_logo.png", "messageprint" => "/images/roundcube_logo_print.png") $config['skin_logo'] = null; +// Enable the manage sieve plugin +array_push($config['plugins'], 'managesieve'); +$config['managesieve_host'] = 'tls://{{ mail_server_hostname }}'; +$config['managesieve_port'] = 4190; +$config['managesieve_auth_type'] = 'plain'; +$config['managesieve_vacation'] = 1; +$config['managesieve_forward'] = 1;