mswart / chef-postfix-full

Chef cookbook to setup and manage a postfix instance, it is designed for administrators who needs the full control about postfix
Apache License 2.0
8 stars 8 forks source link

chef-postfix-full

Code Climate Build Status

Description

Another Postfix cookbook for chef. Unlike others (e.g. the opscode/postfix) it tries to abstract all configuration possibilities of Postfix to chef with attributes and data bags.

The goal is that the cookbook does not limit your usage of Postfix in any way.

Therefore it is not designed for people who want a fast way to a working Postfix instance. The default attributes are limited to a minimum, all other configuration is up to you to adjust Postfix to your needs.

Info: Currently multi-instances are not covered. I have some ideas about that but no need. Talk to me if you need them.

Requirements

The cookbook requires:

This cookbook conflicts with the Opscode postfix cookbook because it uses the same attribute name space node['postfix']. But I can think of situations where it will work without problems. Talk to me if you have this circumstances and want the conflicts metadata to be removed.

Recipes

There are only two recipes:

main.cf

The main.cf is managed via node['postfix']['main'].

Use option name as key inside this hash. For the value multiple types are supported:

See same main.cf example configurations

master.cf

Every service of master.cf has an entry inside the hash node['postfix']['master'].

The service type and name is the key - separated by a colon. If service type is unix, the unix: prefix may be omitted. The service should be nil (works with chef 12 and higher) or false to be ignored or a hash. The hash supports the following attributes:

Use nil or do not set option to use the default value. Use false and true for y and n.

See the master(5) man page for complete documentation and an example definition on other services.

Planned: Definition to define services inside other cookbooks.

Look up tables

The cookbook can manage lookup-tables for you. It can create the configuration files for ldap or mysql. Basic tables like hash tables can be filled with content from attributes (data_bag support planed).

The tables are defined inside the hash node['postfix']['tables'].

Every table has a name (internal usage and per defined as file name) as key and a hash as value with its configuration.

The hash has two types of entries:

The following configuration entries are specified:

The following options provide shortcuts to use the table for a Postfix option. The table is registered with an identifier (type + path to file):

The content entry format depends on the table type.

An advances table example with a external service and table inheritancee

hash

Use lookup key as content entry key and result as value. The cookbook call postmap automatically.

ldap, memcache, mysql, pgsql, sqlite, tcp (tables with main.cf-like configuration syntax)

These tables have all a main.cf like configuration file. This file can be created by chef. Set the configuration values like main.cf options.

The cookbooks does not ensures that this table type is supported by Postfix. On Debian based distributions additional packages must be installed.

cidr, regexp, pcre (tables with ordering-sensitive lines)

The behavior of the cidr, regexp and pcre table depends on the ordering of the content.

The _format configuration options defines how the order is created. The following options are supported:

Other formats are planned.

Chroot files

This cookbook can handle files inside postfix chroot. You can use node['postfix']['chroot_files'] attribute for this purpose. This attribute contains a Hash with the file path as key and the action to perform as value. Currently cp is the only supported action, used for copying files.

By default chroot_files attribute contains the following value:

{
  postfix: {
    chroot_files: {
      'etc/resolv.conf'     => 'cp',
      'etc/localtime'       => 'cp',
      'etc/services'        => 'cp',
      'etc/resolv.conf'     => 'cp',
      'etc/hosts'           => 'cp',
      'etc/nsswitch.conf'   => 'cp',
      'etc/nss_mdns.config' => 'cp',
    }
  }
}

Remember, you can change the chroot directory path setting the queue_directory attribute: node['postfix']['main']['queue_directory'].

Examples

All attributes are written as 1.9+ ruby hashes - minimal overhead.

Basic changes and hash tables:

{
  postfix: {
    main: {
      # this is explicit because it is an important option
      mydomain: 'cookbooks.example',

      # we need to support bigger attachments:
      message_size_limit: 25600000,

      # some sasl configuration for smtp client:
      smtp_sasl_auth_enable: true,
      smtp_sender_dependent_authentication: true,

      smtp_sasl_password_maps: 'hash:/etc/postfix/tables/auths', # not managed by chef
      smtp_sasl_security_options: 'noanonymous',
      smtp_sasl_mechanism_filter: '!gssapi, !ntlm, plain, login',
    },
    tables: {
      relayhosts: {
        _type: 'hash',
        _set: 'sender_dependent_relayhost_maps',
        'chef@cookbooks.test' => '[192.0.2.32]',
        '@cookbooks.test' => 'mail37.mails.example',
      },
      aliases: {
        _type: 'hash',
        _set: 'alias_maps',
        _add: 'alias_database',
        _file: '/etc/aliases',
        _cmd: 'postalias',
        'postmaster:' => 'root',
        'root:' => 'sysadmin@example.com'
      }
    }
  }
}

Additional services

{
  postfix: {
    master: {
      'inet:submission' => {
        private: false,
        chroot: false,
        command: 'smtpd',
        args: [
          '-o smtpd_sender_login_maps=ldap:/etc/postfix/tables/submission-sender-login-map',
          '-o smtpd_recipient_restrictions=reject_sender_login_mismatch,permit_sasl_authenticated,permit_tls_clientcerts,reject',
        ],
      },
      mailman: {
        unprivate: false,
        chroot: false,
        command: 'pipe',
        args: [
          'flags=FR',
          'user=list',
          'argv=/usr/lib/mailman/bin/postfix-to-mailman.py ${nexthop} ${user}',
        ],
      },
    }
  }
}

Advanced table usage

{
  postfix: {
    tables: {
      ldap: {
        _abstract: true,
        _type: 'ldap',
        _proxy: true,
        version: 3,
        server_host: 'ldap.cookbooks.example',
        bind: true,
        bind_dn: 'cn=mail,ou=system,dc=cookbooks,dc=example',
        _bind_pw_from_file: '/etc/postfix/ldap.password',
        search_base: 'ou=mail,dc=cookbooks,dc=example',
        start_tls: true,
        tls_ca_cert_path: '/etc/ssl/certs',
        tls_cert: '/etc/postfix/ssl/mail.cookbooks.example_chain.pem',
        tls_key: '/etc/postfix/ssl/mail.cookbooks.example_key.pem',
        tls_require_cert: true,
      },
      aliases: {
        _parent: 'ldap',
        _add: 'virtual_alias_maps',
        query_filter: '(|(mailAliases=%s)(&(mailUser=%u)(mailDomain=%d)))',
        result_attribute: 'mailDestination',
        domain: 'cookbooks.example, chef.example',
      },
      sender_login_map: {
        _parent: 'ldap',
        _set: 'smtpd_sender_login_maps',
        search_base: 'ou=users,dc=cookbooks,dc=example',
        query_filter: '(|(mail=%s)(mailAliases=%s)(mailAccounts=%s)(mailAccount=%s)(mailAdditionalSender=%s))',
        result_attribute: 'mailAccount',
      },
      transport: {
        _type: 'hash',
        _set: 'transport_maps',
        'lists.cookbooks,example' => 'mailman:',
      },
    }
  },
}

Contributing

The cookbook is developed on github. To report bugs create an issue or open a pull request if you know what needs to be changed.

Feel free to contact me (chef@malteswart.de or mswart on freenode) if you have detailed questions about the cookbook. I am interested in your opinion, wishes and use cases.

License and Author

Author:: Malte Swart (chef@malteswart.de) Copyright:: 2013, Malte Swart

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.