Mercurial > repos > other > Puppet
view manifests/templates.pp @ 398:66c406eec60d
Update and fix firewall for Ubuntu
* Use later version of module (not latest because our Puppet
isn't supported)
* Change how we define "ensure" because Ubuntu doesn't use
IPv6 methods
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Wed, 20 Apr 2022 19:04:13 +0100 |
parents | e93588ec1ce3 |
children | 2c6065b5be5e |
line wrap: on
line source
# Make sure packages come after their repos File<| tag == 'repo-config' |> -> anchor { 'Repo-config': } -> YumRepo<| |> -> anchor { 'Repos': } -> Package<| |> # Make sure all files are in place before starting services # FIXME: Title matches are to fix a dependency cycle File<| tag != 'post-service' and title != '/etc/sysconfig/ip6tables' and title != '/etc/sysconfig/iptables' |> -> anchor { 'Pre-Service Files': } -> Service<| |> # Set some shortcut variables #$os = $operatingsystem $osver = $operatingsystemmajrelease $server = '' class basenode { include sudo include defaultusers include logwatch file { '/etc/puppet/hiera.yaml': ensure => present, content => " # Let the system set defaults version: 5 ", } if $operatingsystem == 'Ubuntu' { file { '/etc/locale.gen': ensure => present, content => "en_GB.UTF-8 UTF-8", notify => Exec['Regen locales'] } exec { 'Regen locales': command => 'locale-gen', refreshonly => true } # Don't waste space with Snap and do everything properly with system packages [ 'lxd', 'core18', 'core20', 'snapd'].each |$snap| { exec { "remove $snap snap package": command => "snap remove $snap", onlyif => "which snap && snap list $snap", tag => 'snap', } } Exec<| tag == 'snap' |> -> package { 'snapd': ensure => purged, } } } class basevpsnode ( $primary_ip, $proxy_4to6_ip_prefix = undef, $proxy_upstream = undef, $nat64_ranges = [], $mailserver, $imapserver, $mailrelays = [], $firewall_cmd = 'iptables', ) { if $firewall_cmd == 'iptables' { class { 'vpsfirewall': fw_protocol => $primary_ip =~ Stdlib::IP::Address::V6 ? { true => 'IPv6', default => 'IPv4'}, } } #VPS is a self-mastered Puppet machine, so bodge a Hosts file if $primary_ip =~ Stdlib::IP::Address::V6 { $lo_ip = '::1' } else { $lo_ip = '127.0.0.1' } file { '/etc/hosts': ensure => present, content => "${lo_ip} localhost\n${primary_ip} ${fqdn}", } if $proxy_4to6_ip_prefix != undef { # …:1 to …:9 for websites, …:10 for mail $ipv6_addresses = Integer[1, 10].map |$octet| { "$proxy_4to6_ip_prefix:$octet" } $ipv6_secondaries = join($ipv6_addresses, " ") augeas {'IPv6 secondary addresses': context => "/files/etc/sysconfig/network-scripts/ifcfg-eth0", changes => "set IPV6ADDR_SECONDARIES '\"$ipv6_secondaries\"'", } } require repos include basenode include privat include dnsresolver include ::privat::params class { '::ssh': sshd_config_port => $::privat::params::ssh_port[$::fqdn] } include vcs::server include vcs::client class { 'webserver': primary_ip => $primary_ip, proxy_4to6_ip_prefix => $proxy_4to6_ip_prefix, proxy_4to6_mask => 124, proxy_upstream => $proxy_upstream, } include cronjobs include logrotate class { 'fail2ban': firewall_cmd => $firewall_cmd, } include tools class { 'email': mailserver => $mailserver, imapserver => $imapserver, mailserver_ip => $primary_ip, proxy_ip => $proxy_4to6_ip_prefix != undef ? { true => "${proxy_4to6_ip_prefix}:10", default => undef }, proxy_upstream => $proxy_upstream, nat64_ranges => $nat64_ranges, mailrelays => $mailrelays, } } ## Classes to allow facet behaviour using preconfigured setups of classes class vpsfirewall ($fw_protocol) { resources { "firewall": purge => false, } class { "my_fw": ip_version => $fw_protocol, } # Control what does and doesn't get pruned in the main filter chain firewallchain { "INPUT:filter:$fw_protocol": purge => true, ignore => [ '-j f2b-[^ ]+$', '^(:|-A )f2b-', '--comment "Great Firewall of China"', '--comment "Do not purge', ], } if ($fw_protocol != "IPv6") { firewall { '010 Whitelist Googlebot': source => '66.249.64.0/19', dport => [80,443], proto => tcp, action => accept, } # Block a spammer hitting our contact forms (also on StopForumSpam list A LOT) firewall { '099 Blacklist spammers 1': source => '107.181.78.172', dport => [80, 443], proto => tcp, action => 'reject', } firewall { '099 Blacklist IODC bot': # IODC bot makes too many bad requests, and contact form is broken # They don't publish a robots.txt name, so firewall it! source => '86.153.145.149', dport => [ 80, 443 ], proto => tcp, action => 'reject', } firewall { '099 Blacklist Baidu Brazil': #Baidu got a Brazilian netblock and are hitting us hard #Baidu doesn't honour "crawl-delay" in robots.txt #Baidu gets firewalled source => '131.161.8.0/22', dport => [ 80, 443 ], proto => tcp, action => 'reject', } } firewallchain { "GREATFIREWALLOFCHINA:filter:$fw_protocol": ensure => present, } firewall { '050 Check our Great Firewall Against China': chain => 'INPUT', jump => 'GREATFIREWALLOFCHINA', } firewallchain { "Fail2Ban:filter:$fw_protocol": ensure => present, } firewall { '060 Check Fail2Ban': chain => 'INPUT', jump => 'Fail2Ban', } } class dnsresolver { package { 'unbound': ensure => present, } package { 'named': ensure => absent, } service { 'named': ensure => stopped, enable => false, } service { 'unbound': ensure => running, enable => true, } file { '/etc/named.conf': ensure => absent, } file { '/etc/unbound/unbound.conf': ensure => present, source => [ "puppet:///common/unbound.conf-${::hostname}", "puppet:///common/unbound.conf", ], require => Package['unbound'], notify => Service['unbound'], } file { '/etc/NetworkManager/conf.d': ensure => directory } file { '/etc/NetworkManager/conf.d/local-dns-resolver.conf': ensure => present, content => "[main] dns=none", } file { '/etc/sysconfig/named': ensure => absent, } file { '/etc/resolv.conf': ensure => file, # "ipaddress" key only exists for machines with IPv4 addresses content => has_key($facts, 'ipaddress') ? { true => "nameserver 127.0.0.1", default => "nameserver ::1" }, require => Service['unbound'], tag => 'post-service', } } class repos { if $operatingsystem == 'CentOS' { yumrepo { 'epel': mirrorlist => 'https://mirrors.fedoraproject.org/metalink?repo=epel-$releasever&arch=$basearch', descr => "Extra Packages for Enterprise Linux", enabled => 1, failovermethod => absent, gpgcheck => 1, gpgkey => "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-$osver", } file { "/etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-$osver": ensure => present, source => "puppet:///common/RPM-GPG-KEY-EPEL-$osver", tag => 'repo-config', } yumrepo { 'ibboard': baseurl => 'https://download.opensuse.org/repositories/home:/IBBoard:/server/CentOS_$releasever/', descr => 'Extra packages from IBBoard', enabled => 1, gpgcheck => 1, gpgkey => 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ibboard', } file { '/etc/pki/rpm-gpg/RPM-GPG-KEY-ibboard': ensure => present, source => 'puppet:///common/RPM-GPG-KEY-ibboard', tag => 'repo-config', } yumrepo { 'webtatic': ensure => absent, } file { '/etc/pki/rpm-gpg/RPM-GPG-KEY-webtatic-andy': ensure => absent, } file { '/etc/pki/rpm-gpg/RPM-GPG-KEY-webtatic-el7': ensure => absent, } } if $operatingsystem == 'CentOS' and versioncmp($operatingsystemrelease, '8') >= 0 { $python_ver = 'python3' # The following may possibly work to ensure a CentOS Streams install. # Or it might fail for inexplicable reasons. # FIXME: Should be "centos-release-stream" to migrate (provides repos), but then that gets replaced by centos-stream-release, # which Puppet doesn't recognise as the same and so keeps trying to re-install. May need an "unless" or maybe "allow_virtual" package { 'centos-stream-release': ensure => installed, notify => Exec['migrate to streams']; } exec { 'migrate to streams': command => '/usr/bin/dnf swap centos-linux-repos centos-stream-repos; /usr/bin/dnf distro-sync -y', refreshonly => true } } else { $python_ver = 'system' } class { 'python': ensure => 'present', version => $python_ver, pip => 'present', use_epel => false, } } class tools { $packages = [ 'sqlite', 'bash-completion', 'nano', 'bzip2', 'mlocate', 'patch', 'tmux', 'wget', 'rsync' ] package { $packages: ensure => installed; } if $osfamily == 'RedHat' { package { 'yum-utils': ensure => installed } } } class logrotate { package { 'logrotate': ensure => installed; } file { '/etc/logrotate.d/httpd': ensure => present, source => 'puppet:///common/logrotate-httpd', require => Package['logrotate'], } } class logwatch { package { 'logwatch': ensure => installed; } File { ensure => present, require => Package['logwatch'], } file { '/etc/cron.daily/0logwatch': source => 'puppet:///common/0logwatch'; } $logwatch_dirs = [ '/etc/logwatch/', '/etc/logwatch/conf/', '/etc/logwatch/conf/logfiles/', '/etc/logwatch/conf/services/', '/etc/logwatch/scripts/', '/etc/logwatch/scripts/services/', ] file { $logwatch_dirs: ensure => directory, } file { '/etc/logwatch/conf/logwatch.conf': content => 'Detail = Med', } file { '/etc/logwatch/conf/logfiles/http.conf': content => 'LogFile = apache/access_*.log', } file { '/etc/logwatch/conf/logfiles/http-error.conf': source => 'puppet:///common/logwatch/logfiles_http-error.conf', } file { '/etc/logwatch/conf/logfiles/mysql.conf': source => 'puppet:///common/logwatch/logfiles_mysql.conf', } file { '/etc/logwatch/conf/logfiles/php.conf': source => 'puppet:///common/logwatch/logfiles_php.conf', } file { '/etc/logwatch/conf/services/php.conf': source => 'puppet:///common/logwatch/services_php.conf', } file { '/etc/logwatch/conf/services/contact-form.conf': source => 'puppet:///common/logwatch/services_contact-form.conf', } file { '/etc/logwatch/scripts/services/dovecot': source => 'puppet:///common/logwatch/dovecot', } file { '/etc/logwatch/scripts/services/postfix': source => 'puppet:///common/logwatch/postfix', } file { '/etc/logwatch/scripts/services/systemd': source => 'puppet:///common/logwatch/systemd', } file { '/etc/logwatch/scripts/services/php': source => 'puppet:///common/logwatch/php', } file { '/etc/logwatch/scripts/services/contact-form': source => 'puppet:///common/logwatch/contact-form', } } #Our web server with our configs, not just a stock one class webserver ( $primary_ip, $proxy_4to6_ip_prefix = undef, $proxy_4to6_mask = undef, $proxy_upstream = undef, ) { #Setup base website parameters class { 'website': base_dir => '/srv/sites', primary_ip => $primary_ip, proxy_4to6_ip_prefix => $proxy_4to6_ip_prefix, proxy_4to6_mask => $proxy_4to6_mask, proxy_upstream => $proxy_upstream, default_owner => $defaultusers::default_user, default_group => $defaultusers::default_user, default_tld => 'co.uk', default_extra_tlds => [ 'com' ], } if $operatingsystem == 'CentOS' { $php_suffix = '' $extra_prefix = 'pecl-' $extra_extra = [ 'process' ] if versioncmp($operatingsystemrelease, '8') >= 0 { yumrepo { 'remirepo-safe': mirrorlist => 'http://cdn.remirepo.net/enterprise/$releasever/safe/$basearch/mirror', descr => "Extra CentOS packages from Remi", enabled => 1, failovermethod => absent, gpgcheck => 1, gpgkey => 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi', } yumrepo { 'remirepo-php': mirrorlist => 'http://cdn.remirepo.net/enterprise/8/modular/$basearch/mirror', descr => 'Remi\'s Modular repository for Enterprise Linux 8 - $basearch', enabled => 1, failovermethod => absent, gpgcheck => 1, gpgkey => 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi', } file { '/etc/pki/rpm-gpg/RPM-GPG-KEY-remi': ensure => present, source => 'puppet:///common/RPM-GPG-KEY-remi.el8', tag => 'repo-config', } } else { yumrepo { 'remirepo-safe': mirrorlist => 'http://cdn.remirepo.net/enterprise/$releasever/safe/mirror', descr => "Extra CentOS packages from Remi", enabled => 1, failovermethod => absent, gpgcheck => 1, gpgkey => 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi', } yumrepo { 'remirepo-php': mirrorlist => 'http://cdn.remirepo.net/enterprise/$releasever/php74/mirror', descr => "PHP7.4 for CentOS from Remi", enabled => 1, failovermethod => absent, gpgcheck => 1, gpgkey => 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi', } file { '/etc/pki/rpm-gpg/RPM-GPG-KEY-remi': ensure => present, source => 'puppet:///common/RPM-GPG-KEY-remi', tag => 'repo-config', } } } elsif $operatingsystem == 'Ubuntu' { $php_suffix = '' $extra_prefix = '' $extra_extras = [] } #Configure the PHP version to use class { 'website::php': suffix => $php_suffix, module => ($operatingsystem == 'CentOS' and versioncmp($operatingsystemrelease, '8') >= 0) ? { true => 'remi-7.4', default => undef }, extras => [ 'intl', "${extra_prefix}imagick", 'bcmath', "${extra_prefix}zip", 'json', "${extra_prefix}apcu", 'gmp', 'enchant' ] + $extra_extras, } #Setup MySQL, using (private) templates to make sure that we set non-std passwords and a default user if $operatingsystem == 'CentOS' { if versioncmp($operatingsystemrelease, '7') >= 0 { $mysqlpackage = 'mariadb' $mysqlsuffix = '' # Required for SELinux rule setting/status checks if versioncmp($operatingsystemrelease, '8') >= 0 { $semanage_package_name = 'policycoreutils-python-utils' } else { $semanage_package_name = 'policycoreutils-python' } package { 'policycoreutils-python': name => $semanage_package_name, ensure => present, } $extra_packages = [ 'perl-Sys-Syslog', #Required for Perl SPF checking ] package { $extra_packages: ensure => installed } } else { $mysqlpackage = 'mysql' $mysqlsuffix = '55w' } $phpmysqlsuffix = 'nd' } elsif $operatingsystem == 'Ubuntu' { $mysqlpackage = 'mariadb' $mysqlsuffix = '' $phpmysqlsuffix = '' } else { fail("No MySQL support for ${operatingsystem}") } class { 'website::mysql': mysqluser => template('defaultusers/mysql-user'), mysqlpassword => template('defaultusers/mysql-password'), mysqlprefix => $mysqlpackage, mysqlsuffix => $mysqlsuffix, phpsuffix => $php_suffix, phpmysqlsuffix => $phpmysqlsuffix } # Additional supporting directories that aren't served as sites file { [ '/srv/sites/errorhandling', '/srv/sites/private', '/srv/cms' ]: ensure => directory, } } class ibboardvpsnode ( $primary_ip, $proxy_4to6_ip_prefix = undef, $proxy_upstream = undef, $nat64_ranges = [], $mailserver, $imapserver, $mailrelays = [], $firewall_cmd = 'iptables', ){ class { 'basevpsnode': primary_ip => $primary_ip, proxy_4to6_ip_prefix => $proxy_4to6_ip_prefix, proxy_upstream => $proxy_upstream, nat64_ranges => $nat64_ranges, mailserver => $mailserver, imapserver => $imapserver, mailrelays => $mailrelays, firewall_cmd => $firewall_cmd, } # Set timezone to something sensible file { "/etc/localtime": ensure => 'link', target => '/usr/share/zoneinfo/Europe/London', } # Common modules used by multiple sites (mod_auth_basic is safe because we HTTPS all the things) $mods = [ 'auth_basic', 'authn_core', 'authn_file', 'authz_user', 'deflate', 'xsendfile' ] apache::mod { $mods:; } #Configure our sites, using templates for the custom fragments where the extra content is too long class { "devsite": proxy_4to6_ip => $proxy_4to6_ip_prefix != undef ? { true => "$proxy_4to6_ip_prefix:01", default => undef } } class { "adminsite": proxy_4to6_ip => $proxy_4to6_ip_prefix != undef ? { true => "$proxy_4to6_ip_prefix:02", default => undef } } website::https::multitld { 'www.ibboard': proxy_4to6_ip => $proxy_4to6_ip_prefix != undef ? { true => "$proxy_4to6_ip_prefix:03", default => undef }, custom_fragment => template("privat/apache/ibboard.fragment"), letsencrypt_name => 'ibboard.co.uk', csp_override => { "report-uri" => "https://ibboard.report-uri.com/r/d/csp/enforce", "default-src" => "'none'", "img-src" => "'self' https://live.staticflickr.com/", "script-src" => "'self'", "style-src" => "'self'", "font-src" => "'self'", "form-action" => "'self'", "connect-src" => "'self'", } } website::https::redir { 'mail.ibboard.co.uk': proxy_4to6_ip => $proxy_4to6_ip_prefix != undef ? { true => "$proxy_4to6_ip_prefix:03", default => undef }, redir => 'https://ibboard.co.uk/', docroot => "${website::basedir}/ibboard", letsencrypt_name => 'ibboard.co.uk', separate_log => true, } website::https::redir { 'imap.ibboard.co.uk': proxy_4to6_ip => $proxy_4to6_ip_prefix != undef ? { true => "$proxy_4to6_ip_prefix:03", default => undef }, redir => 'https://ibboard.co.uk/', docroot => "${website::basedir}/ibboard", letsencrypt_name => 'ibboard.co.uk', separate_log => true, } class { "hiveworldterrasite": proxy_4to6_ip => $proxy_4to6_ip_prefix != undef ? { true => "$proxy_4to6_ip_prefix:04", default => undef } } class { "bdstrikesite": proxy_4to6_ip => $proxy_4to6_ip_prefix != undef ? { true => "$proxy_4to6_ip_prefix:05", default => undef } } website::https::multitld { 'www.abiknight': proxy_4to6_ip => $proxy_4to6_ip_prefix != undef ? { true => "$proxy_4to6_ip_prefix:06", default => undef }, custom_fragment => "$website::htmlphpfragment ErrorDocument 404 /error.php", letsencrypt_name => 'abiknight.co.uk', } website::https::multitld { 'www.warfoundry': proxy_4to6_ip => $proxy_4to6_ip_prefix != undef ? { true => "$proxy_4to6_ip_prefix:07", default => undef }, letsencrypt_name => 'warfoundry.co.uk', custom_fragment => template("privat/apache/warfoundry.fragment"), } class { "webmailpimsite": proxy_4to6_ip_pim => $proxy_4to6_ip_prefix != undef ? { true => "$proxy_4to6_ip_prefix:08", default => undef }, proxy_4to6_ip_webmail => $proxy_4to6_ip_prefix != undef ? { true => "$proxy_4to6_ip_prefix:09", default => undef }, } } class adminsite ($proxy_4to6_ip) { apache::mod { 'info':; 'status':; 'cgi':; } website::https::multitld { 'admin.ibboard': proxy_4to6_ip => $proxy_4to6_ip, force_no_index => false, ssl_ca_chain => '', custom_fragment => template("privat/apache/admin.fragment"), } if $osfamily == 'RedHat' { $cron_user = 'apache' } elsif $osfamily == 'Debian' { $cron_user = 'www-data' } cron { 'loadavg': command => '/usr/local/bin/run-loadavg-logger', user => $cron_user, minute => '*/6' } cron { 'awstats': command => '/usr/local/bin/update-awstats > /srv/sites/admin/awstats.log', user => $cron_user, hour => '*/6', minute => '0' } } class hiveworldterrasite ($proxy_4to6_ip) { website::https::multitld { 'www.hiveworldterra': proxy_4to6_ip => $proxy_4to6_ip, force_no_www => false, letsencrypt_name => 'hiveworldterra.co.uk', custom_fragment => template("privat/apache/hwt.fragment"), } website::https::multitld { 'forums.hiveworldterra': proxy_4to6_ip => $proxy_4to6_ip, letsencrypt_name => 'forums.hiveworldterra.co.uk', custom_fragment => template("privat/apache/forums.fragment"), } website::https::multitld { 'skins.hiveworldterra': proxy_4to6_ip => $proxy_4to6_ip, letsencrypt_name => 'skins.hiveworldterra.co.uk', custom_fragment => template("privat/apache/skins.fragment"), } website::https::redir { 'hiveworldterra.ibboard.co.uk': proxy_4to6_ip => $proxy_4to6_ip, redir => 'https://www.hiveworldterra.co.uk/', docroot => "${website::basedir}/hiveworldterra", letsencrypt_name => 'hiveworldterra.ibboard.co.uk', separate_log => true, } } class bdstrikesite ($proxy_4to6_ip) { website::https::multitld { 'www.bdstrike': proxy_4to6_ip => $proxy_4to6_ip, docroot_owner => $defaultusers::secondary_user, docroot_group => 'editors', letsencrypt_name => 'bdstrike.co.uk', custom_fragment => template("privat/apache/bdstrike.fragment"), csp_override => {"frame-ancestors" => "'self'"}, csp_report_override => { "font-src" => "'self' https://fonts.gstatic.com/ data:", "img-src" => "'self' https://secure.gravatar.com/", "style-src" => "'self' https://fonts.googleapis.com/ 'unsafe-inline'" }, } $aliases = [ 'strikecreations.co.uk', 'strikecreations.com', 'www.strikecreations.com' ] website::https::redir { 'www.strikecreations.co.uk': proxy_4to6_ip => $proxy_4to6_ip, redir => 'https://bdstrike.co.uk/', serveraliases => $aliases, docroot => "${website::basedir}/bdstrike", docroot_owner => $defaultusers::secondary_user, docroot_group => 'editors', letsencrypt_name => 'strikecreations.com', separate_log => true, } cron { 'wordpress_cron': # Run "php -f wp-cron.php" on a schedule so that we can auto-update # without giving Apache full write access! command => "/usr/local/bin/bdstrike-cron", user => $defaultusers::default_user, minute => '*/15', } } class devsite ($proxy_4to6_ip) { if $operatingsystem == 'CentOS' and versioncmp($operatingsystemrelease, '8') >= 0 { $mod_wsgi_prefix = 'run/wsgi/' } else { $mod_wsgi_prefix = undef } class { 'apache::mod::wsgi': wsgi_socket_prefix => $mod_wsgi_prefix, } website::https::multitld { 'dev.ibboard': proxy_4to6_ip => $proxy_4to6_ip, #Make sure we're the first one hit for the tiny fraction of "no support" cases we care about (potentially Python for Mercurial!) # http://en.wikipedia.org/wiki/Server_Name_Indication#No_support priority => 1, letsencrypt_name => 'dev.ibboard.co.uk', custom_fragment => template("privat/apache/dev.fragment"), proxy_fragment => template("privat/apache/dev-proxy.fragment"), force_no_index => false, } } class webmailpimsite ($proxy_4to6_ip_pim, $proxy_4to6_ip_webmail) { # Webmail and Personal Information Management (PIM) sites website::https { 'webmail.ibboard.co.uk': proxy_4to6_ip => $proxy_4to6_ip_webmail, force_no_index => false, ssl_ca_chain => '', custom_fragment => template("privat/apache/webmail.fragment"), } include ::apache::params website::https { 'pim.ibboard.co.uk': proxy_4to6_ip => $proxy_4to6_ip_pim, docroot_owner => $apache::params::user, docroot_group => 'editors', force_no_index => false, lockdown_requests => false, ssl_ca_chain => '', csp => false, csp_report => false, custom_fragment => template("privat/apache/pim.fragment"), } cron { 'owncloudcron': command => "/usr/local/bin/owncloud-cron", user => $pim_user, minute => '*/15', } } class email ( $mailserver, $imapserver, $mailserver_ip, $proxy_ip = undef, $proxy_upstream = [], $nat64_ranges = [], $mailrelays = [], ){ class { 'postfix': mailserver => $mailserver, mailserver_ip => $mailserver_ip, mailserver_proxy => $proxy_ip, proxy_upstream => $proxy_upstream, mailrelays => $mailrelays, nat64_ranges => $nat64_ranges, protocols => $mailserver_ip =~ Stdlib::IP::Address::V6 ? { true => 'all', default => 'ipv4' }, } class { 'dovecot': imapserver => $imapserver, imapserver_ip => $mailserver_ip, imapserver_proxy => $proxy_ip, proxy_upstream => $proxy_upstream, } # Unspecified SpamAssassin config dependencies that started # showing up as errors in our logs if $osfamily == 'RedHat' { $spamassassin_deps = ['perl-File-MimeInfo'] $spamassassin_dir = '/etc/mail/spamassassin/' $amavis_dir = '/etc/amavisd/' $amavis_service = 'amavisd' # CentOS has a Clam service, but we call on demand (Ubuntu doesn't have a service) service { 'clamd@amavisd': ensure => 'stopped', enable=> 'mask', } } elsif $osfamily == 'Debian' { $spamassassin_deps = ['libfile-mimeinfo-perl'] $spamassassin_dir = '/etc/spamassassin/' $amavis_dir = '/etc/amavis/' $amavis_service = 'amavis' } package { $spamassassin_deps: ensure => installed, } package { [ 'amavisd-new' ]: ensure => installed, tag => 'av', } service { $amavis_service: ensure => 'running', enable => 'true', } file { "${amavis_dir}amavisd.conf": ensure => present, source => 'puppet:///private/postfix/amavisd.conf', tag => 'av', } file { "${spamassassin_dir}local.cf": ensure => present, source => 'puppet:///private/postfix/spamassassin-local.cf', tag => 'av', } file { "${spamassassin_dir}ole2macro.cf": ensure => present, source => 'puppet:///common/ole2macro.cf', tag => 'av', } file { "${spamassassin_dir}ole2macro.pm": ensure => present, source => 'puppet:///common/spamassassin-vba-macro-master/ole2macro.pm', tag => 'av', } Package<| tag == 'av' |> -> File<| tag == 'av' |> File<| tag == 'av' |> { notify => Service[$amavis_service], } cron { 'Postwhite': command => "/usr/local/bin/postwhite 2>&1| grep -vE '^(Starting|Recursively|Getting|Querying|Removing|Sorting|$)'", user => 'root', weekday => 0, hour => 2, minute => 0, } } class cronjobs { # Add Mutt for scripts that send emails, but stop it clogging the disk by keeping copies of emails package { 'mutt': ensure => installed, } file { '/etc/Muttrc.local': content => 'set copy = no', require => Package['mutt'], } # General server-wide cron jobs Cron { user => 'root' } cron { 'backupalldbs': command => "/usr/local/bin/backupalldbs", monthday => "*/2", hour => "4", minute => "9" } # Only run the Great Firewall Against China on IPv4 (since we don't have an IPv6 list # and the PROXY forwards the IPs to services, but not at the network level) cron { 'greatfirewallofchina': command => '/usr/local/bin/update-great-firewall-of-china', ensure => has_key($facts, 'ipaddress') ? { true => "present", default => "absent" }, hour => 3, minute => 30 } cron { 'permissions': command => '/usr/local/bin/set-permissions', hour => 3, minute => 2 } # Since we're only managing the local server, use our script that wraps "puppet apply" instead of PuppetMaster cron { 'puppet': command => '/usr/local/bin/puppet-apply | grep -v "Compiled catalog for\|Finished catalog run in\|Applied catalog in"', hour => '*/6', minute => 5 } cron { 'purgecaches': command => "/usr/local/bin/purge-caches", hour => '4', minute => '15', weekday => '1', } # Notify of uncommitted files cron { 'check-mercurial-committed': command => "/usr/local/bin/check-hg-status", hour => '4', minute => '20', weekday => '0-6/3', #Sunday, Wednesday and Saturday morning } # Notify of available updates cron { 'check-yum-updates': command => '/usr/bin/yum check-update | grep -E "^[^ ]+ +[0-9a-z_\.-]+ +[^ ]+$"', hour => '4', minute => '30', weekday => '0-6/3', #Sunday, Wednesday and Saturday morning } # And check whether anything needs restarting cron { 'check-needs-restarting': command => '/usr/bin/needs-restarting|grep -v "/usr/lib/systemd\|/usr/sbin/lvmetad\|/usr/lib/polkit-1/polkitd"', hour => '4', minute => '45', weekday => '0-6/3', #Sunday, Wednesday and Saturday morning } }