view modules/postfix/manifests/init.pp @ 336:43e11af9c85d

Enable Postfix (start on boot) Somehow we've never done this before! Surprised anything ever worked without it starting until Puppet's first run.
author IBBoard <dev@ibboard.co.uk>
date Wed, 22 Apr 2020 22:28:52 +0100
parents 38bb323e8231
children a4867ea13d84
line wrap: on
line source

class postfix (
  Stdlib::Fqdn $mailserver,
  Stdlib::IP::Address $mailserver_ip,
  Optional[Stdlib::IP::Address::V6] $mailserver_proxy = undef,
  Array[Stdlib::IP::Address::V6] $proxy_upstream = [],
  Optional[Array[Stdlib::Host]] $mailrelays = [],
  Optional[Array[Stdlib::IP::Address::V6]] $nat64_ranges = [],
  Enum['all', 'ipv4', 'ipv6'] $protocols='all'
  ){
  if $mailserver_ip =~ Stdlib::IP::Address::V4 {
    $lo_ip = '127.0.0.1'
    $lo_networks = '127.0.0.0/8'
  } else {
    $lo_ip = '::1'
    $lo_networks = '::1'
  }
  
  package { 'sendmail':
    ensure => 'absent',
  }
  service { 'sendmail':
    ensure => stopped,
  }
  package { 'postfix':
    ensure => installed;
  }
  service { 'postfix':
    ensure    => running,
    enable    => true,
    subscribe => Package['postfix'],
  }
  firewall { '101 allow SMTP':
    destination => $mailserver_ip,
    dport => [25, 465, 587],
    proto => tcp,
    action => accept,
  }
  if $mailserver_proxy != undef {
    $proxy_upstream.each |Stdlib::IP::Address::V6 $upstream_addr| {
      firewall { "101 limit PROXY protocol for SMTP to upstream $upstream_addr":
        source => $upstream_addr,
        destination => $mailserver_proxy,
        dport => [25, 465, 587],
        proto => tcp,
        action => accept,
      }
    }
  }

  $nat64_ranges.each |Stdlib::IP::Address::V6 $nat64_range| {
    # Block SMTP to the NAT64 range so that we don't fail SPF checks
    # The server *should* attempt it then fall back to the relay
    firewall { "200 Prevent SMTP over NAT64 to $nat64_range":
      destination => $nat64_range,
      dport => [25, 265, 587],
      proto => tcp,
      action => 'reject',
      chain => 'OUTPUT',
    }
  }

  exec { 'postmap-files':
    command     => 'for file in helo_whitelist recipient_bcc sender_access valias valias-blacklist virtual vmailbox transport; do postmap $file; done',
    cwd         => '/etc/postfix/',
    provider    => 'shell',
    refreshonly => true,
    notify      => Service['postfix'],
  }
  File {
    ensure  => present,
    notify  => Exec['postmap-files'],
    require => Package['postfix'],
  }
  file { '/etc/postfix/main.cf':
    content => epp('postfix/main.cf.epp',
                   {
                     'mailserver' => $mailserver,
                     'lo_ip' => $lo_ip,
                     'lo_networks' => $lo_networks,
                     'protocols' => $protocols,
                   }
                  ),
  }
  file { '/etc/postfix/master.cf':
    content => epp('postfix/master.cf.epp',
                   {
                     'mailserver_ip' => $mailserver_ip,
                     'mailserver_proxy' => $mailserver_proxy,
                     'lo_ip' => $lo_ip,
                     'lo_networks' => $lo_networks,
                     'fallback_relays' => $mailrelays,
                   }
                  ),
  }
  #Hosted domains
  file { '/etc/postfix/vdomains':
    source => 'puppet:///private/postfix/vdomains',
  }
  #Hosted mailboxes
  file { '/etc/postfix/vmailbox':
    source => 'puppet:///private/postfix/vmailbox',
  }
  #Catch-alls
  file { '/etc/postfix/virtual':
    source => 'puppet:///private/postfix/virtual',
  }
  #Forwarders/aliases
  file { '/etc/postfix/valias':
    source => 'puppet:///private/postfix/valias',
  }
  #BCCing of inbound email
  file { '/etc/postfix/recipient_bcc':
    source => 'puppet:///private/postfix/recipient_bcc',
  }
  #Spammed/removed addresses
  file { '/etc/postfix/valias-blacklist':
    source => 'puppet:///private/postfix/valias-blacklist',
  }
  #Spammed/removed address patterns
  file { '/etc/postfix/valias-blacklist-regex':
    source => 'puppet:///private/postfix/valias-blacklist-regex',
  }
  #Bad headers (use sparingly)
  file { '/etc/postfix/header_checks':
    source => 'puppet:///private/postfix/header_checks',
  }
  #Bad body (use even more sparingly!)
  file { '/etc/postfix/body_checks':
    source => 'puppet:///private/postfix/body_checks',
  }
  # Outbound header manipulation
  file { '/etc/postfix/smtp_header_checks':
    source => 'puppet:///private/postfix/smtp_header_checks',
  }
  #Whitelisted HELO names
  file { '/etc/postfix/helo_whitelist':
    source => 'puppet:///private/postfix/helo_whitelist',
  }
  #Private whitelisted IPs for greylisting process
  file { '/etc/postfix/postscreen_access_private.cidr':
    source => 'puppet:///private/postfix/postscreen_access_private.cidr',
  }
  #Blacklist some domains (e.g. banks who don't do SPF that we don't bank with)
  file { '/etc/postfix/sender_access':
    source => 'puppet:///private/postfix/sender_access',
  }
  # Certificates
  file { "/etc/pki/custom/$mailserver.crt":
    ensure => present,
    source => "puppet:///private/pki/custom/$mailserver.crt",
    owner  => 'postfix',
    mode   => '0600',
  }
  file { "/etc/pki/custom/$mailserver.key":
    ensure => present,
    source => "puppet:///private/pki/custom/$mailserver.key",
    owner  => 'postfix',
    mode   => '0600',
  }

  # Mail base dir
  file { '/var/mail/vhosts/':
    ensure => directory,
    owner => 505,
    group => 505,
    mode => '0700',
  } 

  #SPF checking
  package { 'pypolicyd-spf':
    ensure => installed;
  }
  ->
  file { '/etc/python-policyd-spf/policyd-spf.conf':
    content => epp('postfix/policyd-spf.conf',
                   {
                     'fallback_relays' => $mailrelays,
                   }
                  ),
  }
}