{"id":13780722,"url":"https://github.com/sous-chefs/postfix","last_synced_at":"2025-12-14T20:14:20.910Z","repository":{"id":2725744,"uuid":"3720655","full_name":"sous-chefs/postfix","owner":"sous-chefs","description":"Development repository for the postfix cookbook","archived":false,"fork":false,"pushed_at":"2024-07-15T16:55:13.000Z","size":502,"stargazers_count":104,"open_issues_count":4,"forks_count":154,"subscribers_count":50,"default_branch":"main","last_synced_at":"2024-10-29T20:25:54.716Z","etag":null,"topics":["chef","chef-cookbook","chef-resource","hacktoberfest","managed-by-terraform","postfix"],"latest_commit_sha":null,"homepage":"https://supermarket.chef.io/cookbooks/postfix","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"twbs/bootstrap","license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sous-chefs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"open_collective":"sous-chefs"}},"created_at":"2012-03-14T18:18:57.000Z","updated_at":"2024-08-12T07:35:29.000Z","dependencies_parsed_at":"2023-09-24T07:17:07.954Z","dependency_job_id":"ebe1acf4-ce22-41c8-8cd9-d1b7afe9ea95","html_url":"https://github.com/sous-chefs/postfix","commit_stats":{"total_commits":460,"total_committers":80,"mean_commits":5.75,"dds":0.7804347826086957,"last_synced_commit":"355073c866797528990b2bb31db6c82476864f60"},"previous_names":[],"tags_count":68,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sous-chefs%2Fpostfix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sous-chefs%2Fpostfix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sous-chefs%2Fpostfix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sous-chefs%2Fpostfix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sous-chefs","download_url":"https://codeload.github.com/sous-chefs/postfix/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247345850,"owners_count":20924102,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chef","chef-cookbook","chef-resource","hacktoberfest","managed-by-terraform","postfix"],"created_at":"2024-08-03T18:01:19.077Z","updated_at":"2025-12-14T20:14:15.493Z","avatar_url":"https://github.com/sous-chefs.png","language":"Ruby","funding_links":["https://opencollective.com/sous-chefs"],"categories":["Cookbooks"],"sub_categories":["Web Applications"],"readme":"# postfix Cookbook\n\n[![Cookbook Version](https://img.shields.io/cookbook/v/postfix.svg)](https://supermarket.chef.io/cookbooks/postfix)\n[![CI State](https://github.com/sous-chefs/postfix/workflows/ci/badge.svg)](https://github.com/sous-chefs/postfix/actions?query=workflow%3Aci)\n[![OpenCollective](https://opencollective.com/sous-chefs/backers/badge.svg)](#backers)\n[![OpenCollective](https://opencollective.com/sous-chefs/sponsors/badge.svg)](#sponsors)\n[![License](https://img.shields.io/badge/License-Apache%202.0-green.svg)](https://opensource.org/licenses/Apache-2.0)\n\nInstalls and configures postfix for client or outbound relayhost, or to do SASL authentication.\n\nOn RHEL-family systems, sendmail will be replaced with postfix.\n\n## Maintainers\n\nThis cookbook is maintained by the Sous Chefs. The Sous Chefs are a community of Chef cookbook maintainers working together to maintain important cookbooks. If you’d like to know more please visit [sous-chefs.org](https://sous-chefs.org/) or come chat with us on the Chef Community Slack in [#sous-chefs](https://chefcommunity.slack.com/messages/C2V7B88SF).\n\n## Requirements\n\n### Platforms\n\n- Ubuntu\n- Debian\n- RHEL/CentOS/Scientific\n- Amazon Linux (as of AMIs created after 4/9/2012)\n- FreeBSD\n\nMay work on other platforms with or without modification.\n\n### Chef\n\n- Chef 12.1+\n\n### Cookbooks\n\n- none\n\n## Attributes\n\nSee `attributes/default.rb` for default values.\n\n### Generic cookbook attributes\n\n- `node['postfix']['mail_type']` - Sets the kind of mail configuration. `master` will set up a server (relayhost).\n- `node['postfix']['relayhost_role']` - name of a role used for search in the client recipe.\n- `node['postfix']['relayhost_port']` - listening network port of the relayhost.\n- `node['postfix']['multi_environment_relay']` - set to true if nodes should not constrain search for the relayhost in their own environment.\n- `node['postfix']['use_procmail']` - set to true if nodes should use procmail as the delivery agent.\n- `node['postfix']['use_alias_maps']` - set to true if you want the cookbook to use/configure alias maps\n- `node['postfix']['use_transport_maps']` - set to true if you want the cookbook to use/configure transport maps\n- `node['postfix']['use_access_maps']` - set to true if you want the cookbook to use/configure access maps\n- `node['postfix']['use_virtual_aliases']` - set to true if you want the cookbook to use/configure virtual alias maps\n- `node['postfix']['use_relay_restrictions_maps']` - set to true if you want the cookbook to use/configure a list of domains to which postfix will allow relay\n- `node['postfix']['aliases']` - hash of aliases to create with `recipe[postfix::aliases]`, see below under **Recipes** for more information.\n- `node['postfix']['transports']` - hash of transports to create with `recipe[postfix::transports]`, see below under **Recipes** for more information.\n- `node['postfix']['access']` - hash of access to create with `recipe[postfix::access]`, see below under **Recipes** for more information.\n- `node['postfix']['virtual_aliases']` - hash of virtual_aliases to create with `recipe[postfix::virtual_aliases]`, see below under **Recipes** for more information.\n- `node['postfix']['main_template_source']` - Cookbook source for main.cf template. Default 'postfix'\n- `node['postfix']['master_template_source']` - Cookbook source for master.cf template. Default 'postfix'\n\n### main.cf and sasl_passwd template attributes\n\nThe main.cf template has been simplified to include any attributes in the `node['postfix']['main']` data structure. The following attributes are still included with this cookbook to maintain some semblance of backwards compatibility.\n\nThis change in namespace to `node['postfix']['main']` should allow for greater flexibility, given the large number of configuration variables for the postfix daemon. All of these cookbook attributes correspond to the option of the same name in `/etc/postfix/main.cf`.\n\n- `node['postfix']['main']['biff']` - (yes/no); default no\n- `node['postfix']['main']['append_dot_mydomain']` - (yes/no); default no\n- `node['postfix']['main']['myhostname']` - defaults to fqdn from Ohai\n- `node['postfix']['main']['mydomain']` - defaults to domain from Ohai\n- `node['postfix']['main']['myorigin']` - defaults to $myhostname\n- `node['postfix']['main']['mynetworks']` - default is nil, which forces Postfix to default to loopback addresses.\n- `node['postfix']['main']['inet_interfaces']` - set to `loopback-only`, or `all` for server recipe\n- `node['postfix']['main']['alias_maps']` - set to `hash:/etc/aliases`\n- `node['postfix']['main']['mailbox_size_limit']` - set to `0` (disabled)\n- `node['postfix']['main']['mydestination']` - default fqdn, hostname, localhost.localdomain, localhost\n- `node['postfix']['main']['smtpd_use_tls']` - (yes/no); default yes. See conditional cert/key attributes.\n- `node['postfix']['main']['smtpd_tls_cert_file']` - conditional attribute, set to full path of server's x509 certificate.\n- `node['postfix']['main']['smtpd_tls_key_file']` - conditional attribute, set to full path of server's private key\n- `node['postfix']['main']['smtpd_tls_CAfile']` - set to platform specific CA bundle\n- `node['postfix']['main']['smtpd_tls_session_cache_database']` - set to `btree:${data_directory}/smtpd_scache`\n- `node['postfix']['main']['smtp_use_tls']` - (yes/no); default yes. See following conditional attributes.\n- `node['postfix']['main']['smtp_tls_CAfile']` - set to platform specific CA bundle\n- `node['postfix']['main']['smtp_tls_session_cache_database']` - set to `btree:${data_directory}/smtpd_scache`\n- `node['postfix']['main']['smtp_sasl_auth_enable']` - (yes/no); default no. If enabled, see following conditional attributes.\n- `node['postfix']['main']['smtp_sasl_password_maps']` - Set to `hash:/etc/postfix/sasl_passwd` template file\n- `node['postfix']['main']['smtp_sasl_security_options']` - Set to noanonymous\n- `node['postfix']['main']['relayhost']` - Set to empty string\n- `node['postfix']['sender_canonical_map_entries']` - (hash with key value pairs); default not configured. Setup generic canonical maps. See `man 5 canonical`. If has at least one value, then will be enabled in config.\n- `node['postfix']['smtp_generic_map_entries']` - (hash with key value pairs); default not configured. Setup generic postfix maps. See `man 5 generic`. If has at least one value, then will be enabled in config.\n- `node['postfix']['recipient_canonical_map_entries']` - (hash with key value pairs); default not configured. Setup generic canonical maps. See `man 5 canonical`. If has at least one value, then will be enabled in config.\n- `node['postfix']['sasl']['smtp_sasl_user_name']` - SASL user to authenticate as. Default empty. You can only use this until the current version. The new syntax is below.\n- `node['postfix']['sasl']['smtp_sasl_passwd']` - SASL password to use. Default empty. You can only use this until the current version. The new syntax is below.\n- `node['postfix']['sasl']` = ```json {\n    \"relayhost1\" =\u003e {\n      'username' =\u003e 'foo',\n      'password' =\u003e 'bar'\n    },\n    \"relayhost2\" =\u003e {\n      ...\n    }\n  }``` - You must set the following attribute, otherwise the attribute will default to empty\n\nExample of json role config, for setup *_map_entries:\n\n`postfix : {`\n\n`...`\n\n`\"smtp_generic_map_entries\" : { \"root@youinternaldomain.local\" : \"admin@example.com\", \"admin@youinternaldomain.local\" : \"admin@example.com\" }`\n\n`}`\n\n### master.cf template attributes\n\nThe master.cf template has been changed to allow full customization of the file content. For purpose of backwards compatibility default attributes generate the same master.cf. But via `node['postfix']['master']` data structure in your role for instance it can be completelly rewritten.\n\nExamples of json role config, for customize master.cf:\n\n`postfix : {`\n\n`...`\n\nturn some services off or on:\n\n```json\n  \"master\" : {\n    \"smtps\": {\n      \"active\": true\n    },\n    \"old-cyrus\": {\n      \"active\": false\n    },\n    \"cyrus\": {\n      \"active\": false\n    },\n    \"uucp\": {\n      \"active\": false\n    },\n    \"ifmail\": {\n      \"active\": false\n    },\n```\n\n`...` define you own service:\n\n```json\n    \"spamfilter\": {\n      \"comment\": \"My own spamfilter\",\n      \"active\": true,\n      \"order\": 590,\n      \"type\": \"unix\",\n      \"unpriv\": false,\n      \"chroot\": false,\n      \"command\": \"pipe\",\n      \"args\": [\"flags=Rq user=spamd argv=/usr/bin/spamfilter.sh -oi -f ${sender} ${recipient}\"]\n    }\n```\n\n`...`\n\n`}` `}`\n\nThe possible service hash fields and their meanings: hash key - have to be unique, unless you wish to override default definition.\n\nField   | Mandatory | Description\n------- | --------- | --------------------------------------------------------------------\nactive  | Yes       | Boolean. Defines whether or not the service needs to be in master.cf\ncomment | No        | String. If you would like to add a comment line before service line\norder   | Yes       | Integer. Number to define the order of lines in the file\ntype    | Yes       | String. Type of the service (inet, unix, fifo)\nprivate | No        | Boolean. If present replaced by `y` or `n`, otherwise by `-`\nunpriv  | No        | Boolean. If present replaced by `y` or `n`, otherwise by `-`\nchroot  | No        | Boolean. If present replaced by `y` or `n`, otherwise by `-`\nwakeup  | No        | String. If present value placed in file, otherwise replaced by `-`\nmaxproc | No        | String. If present value placed in file, otherwise replaced by `-`\ncommand | Yes       | String. The command to be executed.\nargs    | Yes       | Array of Strings. Arguments passed to command.\n\nFor more information about meaning of the fields consult `master (5)` manual: \u003chttp://www.postfix.org/master.5.html\u003e\n\n## Recipes\n\n### default\n\nInstalls the postfix package and manages the service and the main configuration files (`/etc/postfix/main.cf` and `/etc/postfix/master.cf`). See **Usage** and **Examples** to see how to affect behavior of this recipe through configuration. Depending on the `node['postfix']['use_alias_maps']`, `node['postfix']['use_transport_maps']`, `node['postfix']['use_access_maps']` and `node['postfix']['use_virtual_aliases']` attributes the default recipe can call additional recipes to manage additional postfix configuration files\n\nFor a more dynamic approach to discovery for the relayhost, see the `client` and `server` recipes below.\n\n### client\n\nUse this recipe to have nodes automatically search for the mail relay based which node has the `node['postfix']['relayhost_role']` role. Sets the `node['postfix']['main']['relayhost']` attribute to the first result from the search.\n\nIncludes the default recipe to install, configure and start postfix.\n\nDoes not work with `chef-solo`.\n\n### sasl_auth\n\nSets up the system to authenticate with a remote mail relay using SASL authentication.\n\n### server\n\nTo use Chef Server search to automatically detect a node that is the relayhost, use this recipe in a role that will be relayhost. By default, the role should be \"relayhost\" but you can change the attribute `node['postfix']['relayhost_role']` to modify this.\n\n**Note** This recipe will set the `node['postfix']['mail_type']` to \"master\" with an override attribute.\n\n### maps\n\nGeneral recipe to manage any number of any type postfix lookup tables. You can replace with it recipes like `transport` or `virtual_aliases`, but what is more important - you can create any kinds of maps, which has no own recipe, including database lookup maps configuration. `maps` is a hash keys of which is a lookup table type and value is another hash with filenames as the keys and hash with file content as the value. File content is an any number of key/value pairs which meaning depends on lookup table type. Examlle:\n\n```json\n  \"override_attributes\": {\n    \"postfix\": {\n      \"maps\": {\n        \"hash\": {\n          \"/etc/postfix/vmailbox\": {\n            \"john@example.com\": \"ok\",\n            \"john@example.net\": \"ok\",\n          },\n          \"/etc/postfix/virtual\": {\n            \"postmaster@example.com\": \"john@example.com\",\n            \"postmaster@example.net\": \"john@example.net\",\n            \"root@mail.example.net\": \"john@example.net\"\n          },\n          \"/etc/postfix/envelope_senders\": {\n            \"@example.com\": \"john@example.com\",\n            \"@example.net\": \"john@example.net\"\n          },\n          \"/etc/postfix/relay_recipients\": {\n            \"john@example.net\": \"ok\",\n            \"john@example.com\": \"ok\",\n            \"admin@example.com\": \"ok\",\n          }\n       },\n       \"pgsql\": {\n          \"/etc/postfix/pgtest\": {\n            \"hosts\": \"db.local:2345\",\n            \"user\": \"postfix\",\n            \"password\": \"test\",\n            \"dbname\": \"postdb\",\n            \"query\": \"SELECT replacement FROM aliases WHERE mailbox = '%s'\"\n          }\n        }\n     }\n  }\n```\n\nTo use these files in your configuration reference them in `node['postfix']['main']`, for instance:\n\n```json\n    \"postfix\": {\n      \"main\": {\n        \"smtpd_sender_login_maps\": \"hash:/etc/postfix/envelope_senders\",\n        \"relay_recipient_maps\": \"hash:/etc/postfix/relay_recipients\",\n        \"virtual_mailbox_maps\": \"hash:/etc/postfix/vmailbox\",\n        \"virtual_alias_maps\": \"hash:/etc/postfix/virtual\",\n      }\n    }\n```\n\n### aliases\n\nManage `/etc/aliases` with this recipe. Currently only Ubuntu 10.04 platform has a template for the aliases file. Add your aliases template to the `templates/default` or to the appropriate platform+version directory per the File Specificity rules for templates. Then specify a hash of aliases for the `node['postfix']['aliases']` attribute.\n\nArrays are supported as alias values, since postfix supports comma separated values per alias, simply specify your alias as an array to use this handy feature.\n\n### aliases\n\nManage `/etc/aliases` with this recipe.\n\n### transports\n\nManage `/etc/postfix/transport` with this recipe.\n\n### access\n\nManage `/etc/postfix/access` with this recipe.\n\n### virtual_aliases\n\nManage `/etc/postfix/virtual` with this recipe.\n\n### relay_restrictions\n\nManage `/etc/postfix/relay_restriction` with this recipe The postfix option smtpd_relay_restrictions in main.cf will point to this hash map db.\n\n\u003chttp://wiki.chef.io/display/chef/Templates#Templates-TemplateLocationSpecificity\u003e\n\n## Usage\n\nOn systems that should simply send mail directly to a relay, or out to the internet, use `recipe[postfix]` and modify the `node['postfix']['main']['relayhost']` attribute via a role.\n\nOn systems that should be the MX for a domain, set the attributes accordingly and make sure the `node['postfix']['mail_type']` attribute is `master`. See **Examples** for information on how to use `recipe[postfix::server]` to do this automatically.\n\nIf you need to use SASL authentication to send mail through your ISP (such as on a home network), use `postfix::sasl_auth` and set the appropriate attributes.\n\nFor each of these implementations, see **Examples** for role usage.\n\n### Examples\n\nThe example roles below only have the relevant postfix usage. You may have other contents depending on what you're configuring on your systems.\n\nThe `base` role is applied to all nodes in the environment.\n\n```ruby\nname \"base\"\nrun_list(\"recipe[postfix]\")\noverride_attributes(\n  \"postfix\" =\u003e {\n    \"mail_type\" =\u003e \"client\",\n    \"main\" =\u003e {\n      \"mydomain\" =\u003e \"example.com\",\n      \"myorigin\" =\u003e \"example.com\",\n      \"relayhost\" =\u003e \"[smtp.example.com]\",\n      \"smtp_use_tls\" =\u003e \"no\"\n    }\n  }\n)\n```\n\nThe `relayhost` role is applied to the nodes that are relayhosts. Often this is 2 systems using a CNAME of `smtp.example.com`.\n\n```ruby\nname \"relayhost\"\nrun_list(\"recipe[postfix::server]\")\noverride_attributes(\n  \"postfix\" =\u003e {\n    \"mail_type\" =\u003e \"master\",\n    \"main\" =\u003e {\n      \"mynetworks\" =\u003e [ \"10.3.3.0/24\", \"127.0.0.0/8\" ],\n      \"inet_interfaces\" =\u003e \"all\",\n      \"mydomain\" =\u003e \"example.com\",\n      \"myorigin\" =\u003e \"example.com\"\n  }\n)\n```\n\nThe `sasl_relayhost` role is applied to the nodes that are relayhosts and require authenticating with SASL. For example this might be on a household network with an ISP that otherwise blocks direct internet access to SMTP.\n\n```ruby\nname \"sasl_relayhost\"\nrun_list(\"recipe[postfix], recipe[postfix::sasl_auth]\")\noverride_attributes(\n  \"postfix\" =\u003e {\n    \"mail_type\" =\u003e \"master\",\n    \"main\" =\u003e {\n      \"mynetworks\" =\u003e \"10.3.3.0/24\",\n      \"mydomain\" =\u003e \"example.com\",\n      \"myorigin\" =\u003e \"example.com\",\n      \"relayhost\" =\u003e \"[smtp.comcast.net]:587\",\n      \"smtp_sasl_auth_enable\" =\u003e \"yes\"\n    },\n    \"sasl\" =\u003e {\n      \"relayhost1\" =\u003e {\n        \"username\" =\u003e \"your_password\",\n        \"password\" =\u003e \"your_username\"\n      },\n      \"relayhost2\" =\u003e {\n        ...\n      },\n      ...\n    }\n  }\n)\n```\n\nFor an example of using encrypted data bags to encrypt the SASL password, see the following blog post:\n\n- \u003chttp://jtimberman.github.com/blog/2011/08/06/encrypted-data-bag-for-postfix-sasl-authentication/\u003e\n\n#### Examples using the client \u0026 server recipes\n\nIf you'd like to use the more dynamic search based approach for discovery, use the server and client recipes. First, create a relayhost role.\n\n```ruby\nname \"relayhost\"\nrun_list(\"recipe[postfix::server]\")\noverride_attributes(\n  \"postfix\" =\u003e {\n    \"main\" =\u003e {\n      \"mynetworks\" =\u003e \"10.3.3.0/24\",\n      \"mydomain\" =\u003e \"example.com\",\n      \"myorigin\" =\u003e \"example.com\"\n    }\n  }\n)\n```\n\nThen, add the `postfix::client` recipe to the run list of your `base` role or equivalent role for postfix clients.\n\n```ruby\nname \"base\"\nrun_list(\"recipe[postfix::client]\")\noverride_attributes(\n  \"postfix\" =\u003e {\n    \"mail_type\" =\u003e \"client\",\n    \"main\" =\u003e {\n      \"mydomain\" =\u003e \"example.com\",\n      \"myorigin\" =\u003e \"example.com\"\n    }\n  }\n)\n```\n\nIf you wish to use a different role name for the relayhost, then also set the attribute in the `base` role. For example, `postfix_master` as the role name:\n\n```ruby\nname \"postfix_master\"\ndescription \"a role for postfix master that isn't relayhost\"\nrun_list(\"recipe[postfix::server]\")\noverride_attributes(\n  \"postfix\" =\u003e {\n    \"main\" =\u003e {\n      \"mynetworks\" =\u003e \"10.3.3.0/24\",\n      \"mydomain\" =\u003e \"example.com\",\n      \"myorigin\" =\u003e \"example.com\"\n    }\n  }\n)\n```\n\nThe base role would look something like this:\n\n```ruby\nname \"base\"\nrun_list(\"recipe[postfix::client]\")\noverride_attributes(\n  \"postfix\" =\u003e {\n    \"relayhost_role\" =\u003e \"postfix_master\",\n    \"mail_type\" =\u003e \"client\",\n    \"main\" =\u003e {\n      \"mydomain\" =\u003e \"example.com\",\n      \"myorigin\" =\u003e \"example.com\"\n    }\n  }\n)\n```\n\nTo use relay restrictions override the relay restrictions attribute in this format:\n\n```ruby\noverride_attributes(\n  \"postfix\" =\u003e {\n    \"use_relay_restrictions_maps\" =\u003e true,\n    \"relay_restrictions\" =\u003e {\n      \"chef.io\" =\u003e \"OK\",\n      \".chef.io\" =\u003e \"OK\",\n      \"example.com\" =\u003e \"OK\"\n    }\n  }\n)\n```\n\n## Contributors\n\nThis project exists thanks to all the people who [contribute.](https://opencollective.com/sous-chefs/contributors.svg?width=890\u0026button=false)\n\n### Backers\n\nThank you to all our backers!\n\n![https://opencollective.com/sous-chefs#backers](https://opencollective.com/sous-chefs/backers.svg?width=600\u0026avatarHeight=40)\n\n### Sponsors\n\nSupport this project by becoming a sponsor. Your logo will show up here with a link to your website.\n\n![https://opencollective.com/sous-chefs/sponsor/0/website](https://opencollective.com/sous-chefs/sponsor/0/avatar.svg?avatarHeight=100)\n![https://opencollective.com/sous-chefs/sponsor/1/website](https://opencollective.com/sous-chefs/sponsor/1/avatar.svg?avatarHeight=100)\n![https://opencollective.com/sous-chefs/sponsor/2/website](https://opencollective.com/sous-chefs/sponsor/2/avatar.svg?avatarHeight=100)\n![https://opencollective.com/sous-chefs/sponsor/3/website](https://opencollective.com/sous-chefs/sponsor/3/avatar.svg?avatarHeight=100)\n![https://opencollective.com/sous-chefs/sponsor/4/website](https://opencollective.com/sous-chefs/sponsor/4/avatar.svg?avatarHeight=100)\n![https://opencollective.com/sous-chefs/sponsor/5/website](https://opencollective.com/sous-chefs/sponsor/5/avatar.svg?avatarHeight=100)\n![https://opencollective.com/sous-chefs/sponsor/6/website](https://opencollective.com/sous-chefs/sponsor/6/avatar.svg?avatarHeight=100)\n![https://opencollective.com/sous-chefs/sponsor/7/website](https://opencollective.com/sous-chefs/sponsor/7/avatar.svg?avatarHeight=100)\n![https://opencollective.com/sous-chefs/sponsor/8/website](https://opencollective.com/sous-chefs/sponsor/8/avatar.svg?avatarHeight=100)\n![https://opencollective.com/sous-chefs/sponsor/9/website](https://opencollective.com/sous-chefs/sponsor/9/avatar.svg?avatarHeight=100)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsous-chefs%2Fpostfix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsous-chefs%2Fpostfix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsous-chefs%2Fpostfix/lists"}