Merge pull request 'Add email service' (#526) from feature/email into master

Reviewed-on: #526
This commit is contained in:
Râu Cao 2024-01-10 12:09:21 +00:00
commit 24b22b8f91
113 changed files with 4998 additions and 187 deletions

View File

@ -32,11 +32,12 @@ cookbook 'ntp', '= 3.4.0'
cookbook 'ohai', '~> 5.2.5'
cookbook 'openssl', '~> 8.5.5'
cookbook 'php', '~> 8.0.0'
cookbook 'postfix', '= 5.0.2'
cookbook 'postfix', '~> 6.0.26'
cookbook 'timezone_iii', '= 1.0.4'
cookbook 'ulimit', '~> 1.0.0'
cookbook 'users', '~> 5.3.1'
cookbook 'zerotier', '~> 1.0.7'
cookbook 'unbound', '~> 3.0.2'
# openresty dependency
cookbook 'jemalloc', '~> 0.1.7'

View File

@ -28,11 +28,12 @@ DEPENDENCIES
ohai (~> 5.2.5)
openssl (~> 8.5.5)
php (~> 8.0.0)
postfix (= 5.0.2)
postfix (~> 6.0.26)
redisio (~> 6.4.1)
ruby_build (~> 2.5.0)
timezone_iii (= 1.0.4)
ulimit (~> 1.0.0)
unbound (~> 3.0.2)
users (~> 5.3.1)
yum
zerotier (~> 1.0.7)
@ -89,7 +90,7 @@ GRAPH
openssl (8.5.5)
php (8.0.1)
yum-epel (>= 0.0.0)
postfix (5.0.2)
postfix (6.0.26)
redisio (6.4.1)
selinux (>= 0.0.0)
ruby_build (2.5.0)
@ -99,6 +100,7 @@ GRAPH
seven_zip (4.2.2)
timezone_iii (1.0.4)
ulimit (1.0.0)
unbound (3.0.2)
users (5.3.1)
windows (7.0.2)
yum (7.4.13)

4
clients/email-1.json Normal file
View File

@ -0,0 +1,4 @@
{
"name": "email-1",
"public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxDRdvMYKRjejoFsOxS6s\n4gj0Gsaxk/j25A5VPHBcEhr+NOh8W/6NnTTHuFMaorEIl/2kscgrcwriDN7xIFmO\nz/C1+spDLPMGSWd+422KSS3fjVfByLlMwxh171RDZBlZVze7H7CIV/rxCG7Ri85y\nPvyp2rT4ioyVGyYK3e8CiXwQckpFC1ex9VRk/GR8zbCYUIw+qbTFRcl/mQuxKqWK\n22vrgAR+6OL8lcyhssmKiQ1r3GtxwJusgffw4/5S8sRR1z8OB4wiwgOWR1E36EbF\nhTBjFzPiKVjVjP/TQpUoYdnBhuD223M8nPWJl1HMVQPMjL6R2BBOF+iK0Wx9SiFD\nJwIDAQAB\n-----END PUBLIC KEY-----\n"
}

View File

@ -0,0 +1,5 @@
config:
ul-indent: false # MD007
line-length: false # MD013
no-duplicate-heading: false # MD024
reference-links-images: false # MD052

View File

@ -2,6 +2,176 @@
This file is used to list changes made in each version of the postfix cookbook.
## 6.0.26 - *2023-10-03*
- add installation of postfix addon packages for RHEL 8
## 6.0.25 - *2023-10-03*
Fix markdown
## 6.0.24 - *2023-09-28*
Standardise files with files in sous-chefs/repo-management
## 6.0.23 - *2023-09-04*
Standardise files with files in sous-chefs/repo-management
## 6.0.22 - *2023-08-29*
Standardise files with files in sous-chefs/repo-management
## 6.0.21 - *2023-05-17*
Standardise files with files in sous-chefs/repo-management
## 6.0.20 - *2023-04-17*
Fix CI permissions
## 6.0.19 - *2023-04-17*
Standardise files with files in sous-chefs/repo-management
## 6.0.18 - *2023-04-07*
Standardise files with files in sous-chefs/repo-management
## 6.0.17 - *2023-04-01*
Standardise files with files in sous-chefs/repo-management
## 6.0.16 - *2023-04-01*
Standardise files with files in sous-chefs/repo-management
## 6.0.15 - *2023-04-01*
Standardise files with files in sous-chefs/repo-management
## 6.0.14 - *2023-03-20*
Standardise files with files in sous-chefs/repo-management
## 6.0.13 - *2023-03-15*
Standardise files with files in sous-chefs/repo-management
## 6.0.12 - *2023-02-23*
Standardise files with files in sous-chefs/repo-management
## 6.0.11 - *2023-02-16*
Standardise files with files in sous-chefs/repo-management
## 6.0.10 - *2023-02-14*
Standardise files with files in sous-chefs/repo-management
## 6.0.9 - *2023-02-14*
Standardise files with files in sous-chefs/repo-management
## 6.0.8 - *2022-12-08*
Standardise files with files in sous-chefs/repo-management
## 6.0.7 - *2022-02-03*
Standardise files with files in sous-chefs/repo-management
## 6.0.6 - *2022-02-02*
- Update tested platforms
- Remove delivery and move to calling RSpec directly via a reusable workflow
## 6.0.5 - *2022-01-08*
- resolved cookstyle error: test/integration/helpers/serverspec/spec_helper.rb:9:21 convention: `Style/FileRead`
## 6.0.4 - *2021-08-19*
## 6.0.3 - *2021-08-19*
- Fixed TLS configuration
## 6.0.2 - *2021-06-30*
- Make sure we write the main.conf and master.conf before we try to use any commands (like postmap)
## 6.0.1 - *2021-06-01*
## 6.0.0 - *2020-11-23*
- Disabled SSLv3 by default
## 5.4.1 - 2020-10-20
- Ensure all postmap files are rebuilt immediately if needed
## 5.4.0 - 2020-10-11
### Changed
- Sous Chefs Adoption
- Update to use Sous Chefs GH workflow
- Update README to sous-chefs
- Update metadata.rb to Sous Chefs
- Update test-kitchen to Sous Chefs
### Added
- Standardise files with files in sous-chefs/repo-management
- Add Ubuntu 20.04 testing
### Fixed
- Cookstyle fixes
- ChefSpec fixes
- Yamllint fixes
- MDL fixes
- Fix OpenSUSE installation issues
### Removed
- Remove EL 6 testing
- Remove Amazon Linux 1 testing
## 5.3.1 (2018-07-24)
- Fixed sbin issue with Chef13
## 5.3.0 (2018-05-23)
- support multiple sasl_passwd entries
- Add `packages` attribute so different postfix packages can be installed
- add ability to set network connection port for a remote relayhost
## 5.2.1 (2017-11-22)
- Properly support FreeBSD
- Do not run service restart for solaris which fails
## 5.2.0 (2017-08-07)
- Lazily evaluate the config template variables to allow overrides to properly apply
- Avoid Chefspec deprecation warnings
## 5.1.1 (2017-07-28)
- Fix support for Amazon Linux on Chef 13
- Expand testing to cover Debian 9 in Travis
## 5.1.0 (2017-07-28)
- Add an option to allow recipient canonical maps
## 5.0.3 (2017-06-26)
- Correct attribute line for use_relay_restrictions_maps to prevent converge failures
## 5.0.2 (2017-05-17)
- Fix use_relay_restrictions_maps attribute misspelling in attributes file
@ -117,51 +287,51 @@ Reverting #37 - [COOK-3418] Virtual Domain Support PR - duplicate of #55
### Bug
- **[COOK-4357](https://tickets.chef.io/browse/COOK-4357)** - postfix::sasl_auth recipe fails to converge
- postfix::sasl_auth recipe fails to converge
## v3.1.0 (2014-02-19)
### Bug
- **[COOK-4322](https://tickets.chef.io/browse/COOK-4322)** - Postfix cookbook has incorrect default path for sasl_passwd
- Postfix cookbook has incorrect default path for sasl_passwd
### New Feature
- **[COOK-4086](https://tickets.chef.io/browse/COOK-4086)** - use conf_dir attribute for sasl recipe, and add omnios support
- **[COOK-2551](https://tickets.chef.io/browse/COOK-2551)** - Support creating the sender_canonical map file
- use conf_dir attribute for sasl recipe, and add omnios support
- Support creating the sender_canonical map file
## v3.0.4
### Bug
- **[COOK-3824](https://tickets.chef.io/browse/COOK-3824)** - main.cf.erb mishandles lists
- main.cf.erb mishandles lists
### Improvement
- **[COOK-3822](https://tickets.chef.io/browse/COOK-3822)** - postfix cookbook readme has an incorrect example
- postfix cookbook readme has an incorrect example
- Got rubocop errors down to 32
### New Feature
- **[COOK-2551](https://tickets.chef.io/browse/COOK-2551)** - Support creating the sender_canonical map file
- Support creating the sender_canonical map file
## v3.0.2
### Bug
- **[COOK-3617](https://tickets.chef.io/browse/COOK-3617)** - Fix error when no there is no FQDN
- **[COOK-3530](https://tickets.chef.io/browse/COOK-3530)** - Update `client.rb` after 3.0.0 refactor
- **[COOK-2499](https://tickets.chef.io/browse/COOK-2499)** - Do not use resource cloning
- Fix error when no there is no FQDN
- Update `client.rb` after 3.0.0 refactor
- Do not use resource cloning
### Improvement
- **[COOK-3116](https://tickets.chef.io/browse/COOK-3116)** - Add SmartOS support
- Add SmartOS support
## v3.0.0
### Improvement
- **[COOK-3328](https://tickets.chef.io/browse/COOK-3328)** - Postfix main/master and attributes refactor
- Postfix main/master and attributes refactor
**Breaking changes**:

View File

@ -1 +0,0 @@
Please refer to <https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD>

202
cookbooks/postfix/LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
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.

View File

@ -1,15 +0,0 @@
<!-- This is a generated file. Please do not edit directly -->
# Maintainers
This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead.
Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead.
# Project Maintainer
* [Tim Smith](https://github.com/tas50)
# Maintainers
* [Jennifer Davis](https://github.com/sigje)
* [Tim Smith](https://github.com/tas50)
* [Thom May](https://github.com/thommay)

View File

@ -1,19 +1,28 @@
# postfix Cookbook
[![Build Status](https://travis-ci.org/chef-cookbooks/postfix.svg?branch=master)](https://travis-ci.org/chef-cookbooks/postfix) [![Cookbook Version](https://img.shields.io/cookbook/v/postfix.svg)](https://supermarket.chef.io/cookbooks/postfix)
[![Cookbook Version](https://img.shields.io/cookbook/v/postfix.svg)](https://supermarket.chef.io/cookbooks/postfix)
[![CI State](https://github.com/sous-chefs/postfix/workflows/ci/badge.svg)](https://github.com/sous-chefs/postfix/actions?query=workflow%3Aci)
[![OpenCollective](https://opencollective.com/sous-chefs/backers/badge.svg)](#backers)
[![OpenCollective](https://opencollective.com/sous-chefs/sponsors/badge.svg)](#sponsors)
[![License](https://img.shields.io/badge/License-Apache%202.0-green.svg)](https://opensource.org/licenses/Apache-2.0)
Installs and configures postfix for client or outbound relayhost, or to do SASL authentication.
On RHEL-family systems, sendmail will be replaced with postfix.
## Maintainers
This cookbook is maintained by the Sous Chefs. The Sous Chefs are a community of Chef cookbook maintainers working together to maintain important cookbooks. If youd 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).
## Requirements
### Platforms
- Ubuntu 12.04+
- Debian 7.0+
- RHEL/CentOS/Scientific 5.7+, 6.2+
- Ubuntu
- Debian
- RHEL/CentOS/Scientific
- Amazon Linux (as of AMIs created after 4/9/2012)
- FreeBSD
May work on other platforms with or without modification.
@ -33,6 +42,7 @@ See `attributes/default.rb` for default values.
- `node['postfix']['mail_type']` - Sets the kind of mail configuration. `master` will set up a server (relayhost).
- `node['postfix']['relayhost_role']` - name of a role used for search in the client recipe.
- `node['postfix']['relayhost_port']` - listening network port of the relayhost.
- `node['postfix']['multi_environment_relay']` - set to true if nodes should not constrain search for the relayhost in their own environment.
- `node['postfix']['use_procmail']` - set to true if nodes should use procmail as the delivery agent.
- `node['postfix']['use_alias_maps']` - set to true if you want the cookbook to use/configure alias maps
@ -43,7 +53,7 @@ See `attributes/default.rb` for default values.
- `node['postfix']['aliases']` - hash of aliases to create with `recipe[postfix::aliases]`, see below under **Recipes** for more information.
- `node['postfix']['transports']` - hash of transports to create with `recipe[postfix::transports]`, see below under **Recipes** for more information.
- `node['postfix']['access']` - hash of access to create with `recipe[postfix::access]`, see below under **Recipes** for more information.
- `node['postfix']['virtual_aliases']` - hash of virtual_aliases to create with `recipe[postfix::virtual_aliases]`, see below under __Recipes__ for more information.
- `node['postfix']['virtual_aliases']` - hash of virtual_aliases to create with `recipe[postfix::virtual_aliases]`, see below under **Recipes** for more information.
- `node['postfix']['main_template_source']` - Cookbook source for main.cf template. Default 'postfix'
- `node['postfix']['master_template_source']` - Cookbook source for master.cf template. Default 'postfix'
@ -75,10 +85,20 @@ This change in namespace to `node['postfix']['main']` should allow for greater f
- `node['postfix']['main']['smtp_sasl_password_maps']` - Set to `hash:/etc/postfix/sasl_passwd` template file
- `node['postfix']['main']['smtp_sasl_security_options']` - Set to noanonymous
- `node['postfix']['main']['relayhost']` - Set to empty string
- `node['postfix']['sasl']['smtp_sasl_user_name']` - SASL user to authenticate as. Default empty
- `node['postfix']['sasl']['smtp_sasl_passwd']` - SASL password to use. Default empty.
- `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.
- `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.
- `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.
- `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.
- `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.
- `node['postfix']['sasl']` = ```json {
"relayhost1" => {
'username' => 'foo',
'password' => 'bar'
},
"relayhost2" => {
...
}
}``` - You must set the following attribute, otherwise the attribute will default to empty
Example of json role config, for setup *_map_entries:
@ -331,8 +351,14 @@ override_attributes(
"smtp_sasl_auth_enable" => "yes"
},
"sasl" => {
"smtp_sasl_passwd" => "your_password",
"smtp_sasl_user_name" => "your_username"
"relayhost1" => {
"username" => "your_password",
"password" => "your_username"
},
"relayhost2" => {
...
},
...
}
}
)
@ -425,22 +451,27 @@ override_attributes(
)
```
## License & Authors
## Contributors
**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))
This project exists thanks to all the people who [contribute.](https://opencollective.com/sous-chefs/contributors.svg?width=890&button=false)
**Copyright:** 2009-2016, Chef Software, Inc.
### Backers
```
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
Thank you to all our backers!
http://www.apache.org/licenses/LICENSE-2.0
![https://opencollective.com/sous-chefs#backers](https://opencollective.com/sous-chefs/backers.svg?width=600&avatarHeight=40)
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.
```
### Sponsors
Support this project by becoming a sponsor. Your logo will show up here with a link to your website.
![https://opencollective.com/sous-chefs/sponsor/0/website](https://opencollective.com/sous-chefs/sponsor/0/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/1/website](https://opencollective.com/sous-chefs/sponsor/1/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/2/website](https://opencollective.com/sous-chefs/sponsor/2/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/3/website](https://opencollective.com/sous-chefs/sponsor/3/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/4/website](https://opencollective.com/sous-chefs/sponsor/4/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/5/website](https://opencollective.com/sous-chefs/sponsor/5/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/6/website](https://opencollective.com/sous-chefs/sponsor/6/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/7/website](https://opencollective.com/sous-chefs/sponsor/7/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/8/website](https://opencollective.com/sous-chefs/sponsor/8/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/9/website](https://opencollective.com/sous-chefs/sponsor/9/avatar.svg?avatarHeight=100)

View File

@ -1,5 +1,5 @@
# Author:: Joshua Timberman <joshua@chef.io>
# Copyright:: 2009-2017, Chef Software, Inc.
# Copyright:: 2009-2019, Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@ -14,12 +14,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
default['postfix']['packages'] = %w(postfix)
# Generic cookbook attributes
default['postfix']['mail_type'] = 'client'
default['postfix']['relayhost_role'] = 'relayhost'
default['postfix']['relayhost_port'] = '25'
default['postfix']['multi_environment_relay'] = false
default['postfix']['use_procmail'] = false
default['postfix']['use_alias_maps'] = (node['platform'] == 'freebsd')
default['postfix']['use_alias_maps'] = platform?('freebsd')
default['postfix']['use_transport_maps'] = false
default['postfix']['use_access_maps'] = false
default['postfix']['use_virtual_aliases'] = false
@ -33,6 +36,7 @@ default['postfix']['main_template_source'] = 'postfix'
default['postfix']['master_template_source'] = 'postfix'
default['postfix']['sender_canonical_map_entries'] = {}
default['postfix']['smtp_generic_map_entries'] = {}
default['postfix']['recipient_canonical_map_entries'] = {}
default['postfix']['access_db_type'] = 'hash'
default['postfix']['aliases_db_type'] = 'hash'
default['postfix']['transport_db_type'] = 'hash'
@ -84,6 +88,10 @@ default['postfix']['main']['myorigin'] = '$myhostname'
default['postfix']['main']['mydestination'] = [node['postfix']['main']['myhostname'], node['hostname'], 'localhost.localdomain', 'localhost'].compact
default['postfix']['main']['smtpd_use_tls'] = 'yes'
default['postfix']['main']['smtp_use_tls'] = 'yes'
default['postfix']['main']['smtpd_tls_mandatory_protocols'] = '!SSLv2,!SSLv3'
default['postfix']['main']['smtp_tls_mandatory_protocols'] = '!SSLv2,!SSLv3'
default['postfix']['main']['smtpd_tls_protocols'] = '!SSLv2,!SSLv3'
default['postfix']['main']['smtp_tls_protocols'] = '!SSLv2,!SSLv3'
default['postfix']['main']['smtp_sasl_auth_enable'] = 'no'
default['postfix']['main']['mailbox_size_limit'] = 0
default['postfix']['main']['mynetworks'] = nil
@ -99,6 +107,11 @@ when 'smartos'
default['postfix']['cafile'] = '/opt/local/etc/postfix/cacert.pem'
when 'rhel'
default['postfix']['cafile'] = '/etc/pki/tls/cert.pem'
when 'amazon'
default['postfix']['cafile'] = '/etc/pki/tls/cert.pem'
when 'suse'
default['postfix']['main']['setgid_group'] = 'maildrop'
default['postfix']['main']['daemon_directory'] = '/usr/lib/postfix/bin'
else
default['postfix']['cafile'] = "#{node['postfix']['conf_dir']}/cacert.pem"
end
@ -374,27 +387,24 @@ default['postfix']['master']['bsmtp']['command'] = 'pipe'
default['postfix']['master']['bsmtp']['args'] = ['flags=Fq. user=foo argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient']
# OS Aliases
default['postfix']['aliases'] = case node['platform']
when 'freebsd'
default['postfix']['aliases'] = if platform?('freebsd')
{
'MAILER-DAEMON' => 'postmaster',
'bin' => 'root',
'daemon' => 'root',
'named' => 'root',
'nobody' => 'root',
'uucp' => 'root',
'www' => 'root',
'ftp-bugs' => 'root',
'postfix' => 'root',
'manager' => 'root',
'dumper' => 'root',
'operator' => 'root',
'abuse' => 'postmaster',
'MAILER-DAEMON' => 'postmaster',
'bin' => 'root',
'daemon' => 'root',
'named' => 'root',
'nobody' => 'root',
'uucp' => 'root',
'www' => 'root',
'ftp-bugs' => 'root',
'postfix' => 'root',
'manager' => 'root',
'dumper' => 'root',
'operator' => 'root',
'abuse' => 'postmaster',
}
else
{}
end
if node['postfix']['use_relay_restrictions_maps']
default['postfix']['main']['smtpd_relay_restrictions'] = "hash:#{node['postfix']['relay_restrictions_db']}, reject"
end
default['postfix']['main']['smtpd_relay_restrictions'] = "hash:#{node['postfix']['relay_restrictions_db']}, reject" if node['postfix']['use_relay_restrictions_maps']

View File

@ -0,0 +1,115 @@
# Put files/directories that should be ignored in this file when uploading
# to a Chef Infra Server or Supermarket.
# Lines that start with '# ' are comments.
# OS generated files #
######################
.DS_Store
ehthumbs.db
Icon?
nohup.out
Thumbs.db
.envrc
# EDITORS #
###########
.#*
.project
.settings
*_flymake
*_flymake.*
*.bak
*.sw[a-z]
*.tmproj
*~
\#*
REVISION
TAGS*
tmtags
.vscode
.editorconfig
## COMPILED ##
##############
*.class
*.com
*.dll
*.exe
*.o
*.pyc
*.so
*/rdoc/
a.out
mkmf.log
# Testing #
###########
.circleci/*
.codeclimate.yml
.delivery/*
.foodcritic
.kitchen*
.mdlrc
.overcommit.yml
.rspec
.rubocop.yml
.travis.yml
.watchr
.yamllint
azure-pipelines.yml
Dangerfile
examples/*
features/*
Guardfile
kitchen*.yml
mlc_config.json
Procfile
Rakefile
spec/*
test/*
# SCM #
#######
.git
.gitattributes
.gitconfig
.github/*
.gitignore
.gitkeep
.gitmodules
.svn
*/.bzr/*
*/.git
*/.hg/*
*/.svn/*
# Berkshelf #
#############
Berksfile
Berksfile.lock
cookbooks/*
tmp
# Bundler #
###########
vendor/*
Gemfile
Gemfile.lock
# Policyfile #
##############
Policyfile.rb
Policyfile.lock.json
# Documentation #
#############
CODE_OF_CONDUCT*
CONTRIBUTING*
documentation/*
TESTING*
UPGRADING*
# Vagrant #
###########
.vagrant
Vagrantfile

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,20 @@
name 'postfix'
maintainer 'Sous Chefs'
maintainer_email 'help@sous-chefs.org'
license 'Apache-2.0'
description 'Installs and configures postfix for client or outbound relayhost, or to do SASL auth'
version '6.0.26'
source_url 'https://github.com/sous-chefs/postfix'
issues_url 'https://github.com/sous-chefs/postfix/issues'
chef_version '>= 12.15'
supports 'amazon'
supports 'centos'
supports 'debian'
supports 'fedora'
supports 'freebsd'
supports 'oracle'
supports 'redhat'
supports 'scientific'
supports 'smartos'
supports 'ubuntu'

View File

@ -1,4 +1,4 @@
# Copyright:: 2012-2017, Chef Software, Inc.
# Copyright:: 2012-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -13,9 +13,7 @@
# limitations under the License.
#
if node['postfix']['use_procmail']
node.default_unless['postfix']['main']['mailbox_command'] = '/usr/bin/procmail -a "$EXTENSION"'
end
node.default_unless['postfix']['main']['mailbox_command'] = '/usr/bin/procmail -a "$EXTENSION"' if node['postfix']['use_procmail']
if node['postfix']['main']['smtpd_use_tls'] == 'yes'
node.default_unless['postfix']['main']['smtpd_tls_cert_file'] = '/etc/ssl/certs/ssl-cert-snakeoil.pem'
@ -38,34 +36,18 @@ if node['postfix']['main']['smtp_sasl_auth_enable'] == 'yes'
node.default_unless['postfix']['main']['relayhost'] = ''
end
if node['postfix']['use_alias_maps']
node.default_unless['postfix']['main']['alias_maps'] = ["hash:#{node['postfix']['aliases_db']}"]
end
node.default_unless['postfix']['main']['alias_maps'] = ["hash:#{node['postfix']['aliases_db']}"] if node['postfix']['use_alias_maps']
if node['postfix']['use_transport_maps']
node.default_unless['postfix']['main']['transport_maps'] = ["hash:#{node['postfix']['transport_db']}"]
end
node.default_unless['postfix']['main']['transport_maps'] = ["hash:#{node['postfix']['transport_db']}"] if node['postfix']['use_transport_maps']
if node['postfix']['use_access_maps']
node.default_unless['postfix']['main']['access_maps'] = ["hash:#{node['postfix']['access_db']}"]
end
node.default_unless['postfix']['main']['access_maps'] = ["hash:#{node['postfix']['access_db']}"] if node['postfix']['use_access_maps']
if node['postfix']['use_virtual_aliases']
node.default_unless['postfix']['main']['virtual_alias_maps'] = ["#{node['postfix']['virtual_alias_db_type']}:#{node['postfix']['virtual_alias_db']}"]
end
node.default_unless['postfix']['main']['virtual_alias_maps'] = ["#{node['postfix']['virtual_alias_db_type']}:#{node['postfix']['virtual_alias_db']}"] if node['postfix']['use_virtual_aliases']
if node['postfix']['use_virtual_aliases_domains']
node.default_unless['postfix']['main']['virtual_alias_domains'] = ["#{node['postfix']['virtual_alias_domains_db_type']}:#{node['postfix']['virtual_alias_domains_db']}"]
end
node.default_unless['postfix']['main']['virtual_alias_domains'] = ["#{node['postfix']['virtual_alias_domains_db_type']}:#{node['postfix']['virtual_alias_domains_db']}"] if node['postfix']['use_virtual_aliases_domains']
if node['postfix']['use_relay_restrictions_maps']
default['postfix']['main']['smtpd_relay_restrictions'] = "hash:#{node['postfix']['relay_restrictions_db']}, reject"
end
node.default_unless['postfix']['main']['smtpd_relay_restrictions'] = "hash:#{node['postfix']['relay_restrictions_db']}, reject" if node['postfix']['use_relay_restrictions_maps']
if node['postfix']['master']['maildrop']['active']
node.default_unless['postfix']['main']['maildrop_destination_recipient_limit'] = 1
end
node.default_unless['postfix']['main']['maildrop_destination_recipient_limit'] = 1 if node['postfix']['master']['maildrop']['active']
if node['postfix']['master']['cyrus']['active']
node.default_unless['postfix']['main']['cyrus_destination_recipient_limit'] = 1
end
node.default_unless['postfix']['main']['cyrus_destination_recipient_limit'] = 1 if node['postfix']['master']['cyrus']['active']

View File

@ -2,7 +2,7 @@
# Cookbook:: common
# Recipe:: default
#
# Copyright:: 2009-2017, Chef Software, Inc.
# Copyright:: 2009-2020, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -19,12 +19,19 @@
include_recipe 'postfix::_attributes'
package 'postfix'
# use multi-package when we can
if node['os'] == 'linux'
package node['postfix']['packages']
else
node['postfix']['packages'].each do |pkg|
package pkg
end
end
package 'procmail' if node['postfix']['use_procmail']
case node['platform_family']
when 'rhel', 'fedora'
when 'rhel', 'fedora', 'amazon'
service 'sendmail' do
action :nothing
end
@ -35,6 +42,8 @@ when 'rhel', 'fedora'
notifies :start, 'service[postfix]'
not_if '/usr/bin/test /etc/alternatives/mta -ef /usr/sbin/sendmail.postfix'
end
when 'suse'
file '/var/adm/postfix.configured'
when 'omnios'
manifest_path = ::File.join(Chef::Config[:file_cache_path], 'manifest-postfix.xml')
@ -67,7 +76,68 @@ when 'omnios'
execute 'load postfix manifest' do
action :nothing
command "svccfg import #{manifest_path}"
notifies :restart, 'service[postfix]'
notifies :restart, 'service[postfix]' unless platform_family?('solaris2')
end
when 'freebsd'
# Actions are based on docs provided by FreeBSD:
# https://www.freebsd.org/doc/handbook/mail-changingmta.html
service 'sendmail' do
action :nothing
end
template '/etc/mail/mailer.conf' do
source 'mailer.erb'
owner 'root'
group 0
notifies :restart, 'service[postfix]' unless platform_family?('solaris2')
end
execute 'switch_mailer_to_postfix' do
command [
'sysrc',
'sendmail_enable=NO',
'sendmail_submit_enable=NO',
'sendmail_outbound_enable=NO',
'sendmail_msp_queue_enable=NO',
'postfix_enable=YES',
]
notifies :stop, 'service[sendmail]', :immediately
notifies :disable, 'service[sendmail]', :immediately
notifies :start, 'service[postfix]', :delayed
only_if "sysrc sendmail_enable sendmail_submit_enable sendmail_outbound_enable sendmail_msp_queue_enable | egrep -q '(YES|unknown variable)' || sysrc postfix_enable | egrep -q '(NO|unknown variable)'"
end
execute 'disable_periodic' do
# rubocop:disable Lint/ParenthesesAsGroupedExpression
environment ({ 'RC_CONFS' => '/etc/periodic.conf' })
command [
'sysrc',
'daily_clean_hoststat_enable=NO',
'daily_status_mail_rejects_enable=NO',
'daily_status_include_submit_mailq=NO',
'daily_submit_queuerun=NO',
]
only_if "RC_CONFS=/etc/periodic.conf sysrc daily_clean_hoststat_enable daily_status_mail_rejects_enable daily_status_include_submit_mailq daily_submit_queuerun | egrep -q '(YES|unknown variable)'"
end
end
# We need to write the config first as the below postmap immediately commands assume config is correct
# Which is not the case as ipv6 is assumed to be available by the postfix package
# And if someone wants to disable this first we need to update the config first aswell
%w( main master ).each do |cfg|
template "#{node['postfix']['conf_dir']}/#{cfg}.cf" do
source "#{cfg}.cf.erb"
owner 'root'
group node['root_group']
mode '0644'
# restart service for solaris on chef-client has a bug
# unless condition can be removed after
# https://github.com/chef/chef/pull/6596 merge/release
notifies :restart, 'service[postfix]' unless platform_family?('solaris2')
variables(
lazy { { settings: node['postfix'][cfg] } }
)
cookbook node['postfix']["#{cfg}_template_source"]
end
end
@ -81,13 +151,11 @@ unless node['postfix']['sender_canonical_map_entries'].empty?
owner 'root'
group node['root_group']
mode '0644'
notifies :run, 'execute[update-postfix-sender_canonical]'
notifies :run, 'execute[update-postfix-sender_canonical]', :immediately
notifies :reload, 'service[postfix]'
end
unless node['postfix']['main'].key?('sender_canonical_maps')
node.normal['postfix']['main']['sender_canonical_maps'] = "hash:#{node['postfix']['conf_dir']}/sender_canonical"
end
node.default['postfix']['main']['sender_canonical_maps'] = "hash:#{node['postfix']['conf_dir']}/sender_canonical" unless node['postfix']['main'].key?('sender_canonical_maps')
end
execute 'update-postfix-smtp_generic' do
@ -100,28 +168,31 @@ unless node['postfix']['smtp_generic_map_entries'].empty?
owner 'root'
group node['root_group']
mode '0644'
notifies :run, 'execute[update-postfix-smtp_generic]'
notifies :run, 'execute[update-postfix-smtp_generic]', :immediately
notifies :reload, 'service[postfix]'
end
unless node['postfix']['main'].key?('smtp_generic_maps')
node.normal['postfix']['main']['smtp_generic_maps'] = "hash:#{node['postfix']['conf_dir']}/smtp_generic"
end
node.default['postfix']['main']['smtp_generic_maps'] = "hash:#{node['postfix']['conf_dir']}/smtp_generic" unless node['postfix']['main'].key?('smtp_generic_maps')
end
%w( main master ).each do |cfg|
template "#{node['postfix']['conf_dir']}/#{cfg}.cf" do
source "#{cfg}.cf.erb"
execute 'update-postfix-recipient_canonical' do
command "postmap #{node['postfix']['conf_dir']}/recipient_canonical"
action :nothing
end
unless node['postfix']['recipient_canonical_map_entries'].empty?
template "#{node['postfix']['conf_dir']}/recipient_canonical" do
owner 'root'
group node['root_group']
mode '0644'
notifies :restart, 'service[postfix]'
variables(settings: node['postfix'][cfg])
cookbook node['postfix']["#{cfg}_template_source"]
notifies :run, 'execute[update-postfix-recipient_canonical]', :immediately
notifies :reload, 'service[postfix]'
end
node.default['postfix']['main']['recipient_canonical_maps'] = "hash:#{node['postfix']['conf_dir']}/recipient_canonical" unless node['postfix']['main'].key?('recipient_canonical_maps')
end
service 'postfix' do
supports status: true, restart: true, reload: true
action :enable
action [:enable, :start]
end

View File

@ -1,4 +1,4 @@
# Copyright:: 2012-2017, Chef Software, Inc.
# Copyright:: 2012-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -23,5 +23,5 @@ end
template node['postfix']['access_db'] do
source 'access.erb'
notifies :run, 'execute[update-postfix-access]'
notifies :run, 'execute[update-postfix-access]', :immediately
end

View File

@ -1,4 +1,4 @@
# Copyright:: 2012-2017, Chef Software, Inc.
# Copyright:: 2012-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -25,5 +25,5 @@ end
template node['postfix']['aliases_db'] do
source 'aliases.erb'
notifies :run, 'execute[update-postfix-aliases]'
notifies :run, 'execute[update-postfix-aliases]', :immediately
end

View File

@ -2,7 +2,7 @@
# Cookbook:: postfix
# Recipe:: client
#
# Copyright:: 2009-2017, Chef Software, Inc.
# Copyright:: 2009-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -24,6 +24,9 @@ end
query = "role:#{node['postfix']['relayhost_role']}"
relayhost = ''
# if the relayhost_port attribute is not port 25, append to the relayhost
relayhost_port = node['postfix']['relayhost_port'].to_s != '25' ? ":#{node['postfix']['relayhost_port']}" : ''
# results = []
if node.run_list.roles.include?(node['postfix']['relayhost_role'])
@ -36,6 +39,6 @@ else
relayhost = results.map { |n| n['ipaddress'] }.first
end
node.normal['postfix']['main']['relayhost'] = "[#{relayhost}]"
node.default['postfix']['main']['relayhost'] = "[#{relayhost}]#{relayhost_port}"
include_recipe 'postfix'

View File

@ -2,7 +2,7 @@
# Cookbook:: postfix
# Recipe:: default
#
# Copyright:: 2009-2017, Chef Software, Inc.
# Copyright:: 2009-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.

View File

@ -1,5 +1,4 @@
# encoding: utf-8
# Copyright:: 2012-2017, Chef Software, Inc.
# Copyright:: 2012-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -15,7 +14,11 @@
#
node['postfix']['maps'].each do |type, maps|
if node['platform_family'] == 'debian'
if platform_family?('debian')
package "postfix-#{type}" if %w(pgsql mysql ldap cdb).include?(type)
end
if platform?('redhat') && node['platform_version'].to_i == 8
package "postfix-#{type}" if %w(pgsql mysql ldap cdb).include?(type)
end
@ -38,9 +41,7 @@ node['postfix']['maps'].each do |type, maps|
map: content,
separator: separator
)
if %w(btree cdb dbm hash sdbm).include?(type)
notifies :run, "execute[update-postmap-#{file}]"
end
notifies :run, "execute[update-postmap-#{file}]" if %w(btree cdb dbm hash sdbm).include?(type)
notifies :restart, 'service[postfix]'
end
end

View File

@ -1,4 +1,4 @@
# Copyright:: 2012-2017, Chef Software, Inc.
# Copyright:: 2012-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -15,13 +15,15 @@
include_recipe 'postfix::_common'
postmap_command = platform_family?('rhel') ? '/usr/sbin/postmap' : 'postmap'
execute 'update-postfix-relay-restrictions' do
command "postmap #{node['postfix']['relay_restrictions_db']}"
command "#{postmap_command} #{node['postfix']['relay_restrictions_db']}"
environment PATH: "#{ENV['PATH']}:/opt/omni/bin:/opt/omni/sbin" if platform_family?('omnios')
action :nothing
end
template node['postfix']['relay_restrictions_db'] do
source 'relay_restrictions.erb'
notifies :run, 'execute[update-postfix-relay-restrictions]'
notifies :run, 'execute[update-postfix-relay-restrictions]', :immediately
end

View File

@ -3,7 +3,7 @@
# Cookbook:: postfix
# Recipe:: sasl_auth
#
# Copyright:: 2009-2017, Chef Software, Inc.
# Copyright:: 2009-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -28,11 +28,9 @@ case node['platform_family']
when 'debian'
sasl_pkgs = %w(libsasl2-2 libsasl2-modules ca-certificates)
when 'rhel'
sasl_pkgs = if node['platform_version'].to_i < 6
%w(cyrus-sasl cyrus-sasl-plain openssl)
else
%w(cyrus-sasl cyrus-sasl-plain ca-certificates)
end
sasl_pkgs = %w(cyrus-sasl cyrus-sasl-plain ca-certificates)
when 'amazon'
sasl_pkgs = %w(cyrus-sasl cyrus-sasl-plain ca-certificates)
when 'fedora'
sasl_pkgs = %w(cyrus-sasl cyrus-sasl-plain ca-certificates)
end

View File

@ -3,7 +3,7 @@
# Cookbook:: postfix
# Recipe:: server
#
# Copyright:: 2009-2017, Chef Software, Inc.
# Copyright:: 2009-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright:: 2012-2017, Chef Software, Inc.
# Copyright:: 2012-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -15,13 +15,15 @@
include_recipe 'postfix::_common'
postmap_command = platform_family?('rhel') ? '/usr/sbin/postmap' : 'postmap'
execute 'update-postfix-transport' do
command "postmap #{node['postfix']['transport_db']}"
command "#{postmap_command} #{node['postfix']['transport_db']}"
environment PATH: "#{ENV['PATH']}:/opt/omni/bin:/opt/omni/sbin" if platform_family?('omnios')
action :nothing
end
template node['postfix']['transport_db'] do
source 'transport.erb'
notifies :run, 'execute[update-postfix-transport]'
notifies :run, 'execute[update-postfix-transport]', :immediately
end

View File

@ -1,4 +1,4 @@
# Copyright:: 2012-2017, Chef Software, Inc.
# Copyright:: 2012-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -23,6 +23,6 @@ end
template node['postfix']['virtual_alias_db'] do
source 'virtual_aliases.erb'
notifies :run, 'execute[update-postfix-virtual-alias]'
notifies :run, 'execute[update-postfix-virtual-alias]', :immediately
notifies :restart, 'service[postfix]'
end

View File

@ -1,4 +1,4 @@
# Copyright:: 2012-2017, Chef Software, Inc.
# Copyright:: 2012-2019, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -23,6 +23,6 @@ end
template node['postfix']['virtual_alias_domains_db'] do
source 'virtual_aliases_domains.erb'
notifies :run, 'execute[update-postfix-virtual-alias-domains]'
notifies :run, 'execute[update-postfix-virtual-alias-domains]', :immediately
notifies :restart, 'service[postfix]'
end

View File

@ -0,0 +1,17 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:base"],
"packageRules": [{
"groupName": "Actions",
"matchUpdateTypes": ["patch", "pin", "digest"],
"automerge": true,
"addLabels": ["Release: Patch", "Skip: Announcements"]
},
{
"groupName": "Actions",
"matchUpdateTypes": ["major"],
"automerge": false,
"addLabels": ["Release: Patch", "Skip: Announcements"]
}
]
}

View File

@ -1,4 +0,0 @@
# Auto-generated by Chef.
# Local modifications will be overwritten.
#
<%= node['postfix']['main']['relayhost'] %> <%= @settings['smtp_sasl_user_name'] %>:<%= @settings['smtp_sasl_passwd'] %>

View File

@ -0,0 +1,10 @@
#
# Auto-generated by Chef.
# Local modifications will be overwritten.
#
# Execute the Postfix sendmail program, named /usr/local/sbin/sendmail
#
sendmail /usr/local/sbin/sendmail
send-mail /usr/local/sbin/sendmail
mailq /usr/local/sbin/sendmail
newaliases /usr/local/sbin/sendmail

View File

@ -0,0 +1,9 @@
#
# Auto-generated by Chef.
# Local modifications will be overwritten.
#
# See man 5 canonical for format
<% node['postfix']['recipient_canonical_map_entries'].each do |name, value| %>
<%= name %> <%= value %>
<% end unless node['postfix']['recipient_canonical_map_entries'].nil? %>

View File

@ -0,0 +1,8 @@
# Auto-generated by Chef.
# Local modifications will be overwritten.
<% if !@settings.nil? && !@settings.empty? -%>
<% @settings.sort.map do |relayhost,value| -%>
<%= relayhost %> <%= value['username'] %>:<%= value['password'] %>
<% end -%>
<% end -%>

View File

@ -0,0 +1,64 @@
# CHANGELOG
This file is used to list changes made in each version of the unbound cookbook.
## 3.0.2 - *2023-10-02*
- Update Ci files and remove CircleCI config
## 3.0.1 - *2022-09-30*
- Add missing `fallback-enable` setting to `config_authority_zone`
## 3.0.0 - *2022-04-04*
- Add separate configuration resources
- Default recipe now only runs installation
- Refactor configuration template to be Hash driven
## 2.0.3 - *2022-03-04*
- resolved cookstyle error: .delivery/project.toml:2:8 convention: `Style/StringLiterals`
- resolved cookstyle error: .delivery/project.toml:4:10 convention: `Style/StringLiterals`
- resolved cookstyle error: .delivery/project.toml:5:13 convention: `Style/StringLiterals`
- resolved cookstyle error: .delivery/project.toml:6:10 convention: `Style/StringLiterals`
- resolved cookstyle error: .delivery/project.toml:7:9 convention: `Style/StringLiterals`
- resolved cookstyle error: .delivery/project.toml:8:14 convention: `Style/StringLiterals`
- resolved cookstyle error: .delivery/project.toml:9:11 convention: `Style/StringLiterals`
## 2.0.2 - *2021-08-31*
- Standardise files with files in sous-chefs/repo-management
## 2.0.1 - *2021-06-01*
- Updated tests folder to match other cookbooks
- Updated spec platform to supported version
## 2.0.0 - 2020-05-05
- Upgraded to circleci for testing
- Minimum Chef Infra Client version is now **13.0**
- Removed unused long_description metadata.rb field
- Simplify overly complex platform logic
- Migrate to actions for testing
## [1.0.1]
- Simplify logic with root_group
- Fix `root_group` not using new_resource
- Use strings for file modes
- Resolve foodcritic warnings in the `rr` resource
- Fix platform_family logic on the service Update platforms.
- Use dokken images for travis testing.
- Don't test on debian-8/9 and centos-6 as these services don't currently start.
- Account for a list of forward-addrs / effectively disable remote control (#27)
## [1.0.0]
- Add new custom resources `unbound_install` & `unbound_configure`
## [0.1.1]
- Adding support and kitchen testing for forward_zone generation
- Updating to use Sous Chefs guidelines

201
cookbooks/unbound/LICENSE Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

View File

@ -0,0 +1,78 @@
# Unbound Cookbook
[![Cookbook Version](https://img.shields.io/cookbook/v/unbound.svg)](https://supermarket.chef.io/cookbooks/unbound)
[![Build Status](https://img.shields.io/circleci/project/github/sous-chefs/unbound/master.svg)](https://circleci.com/gh/sous-chefs/unbound)
[![OpenCollective](https://opencollective.com/sous-chefs/backers/badge.svg)](#backers)
[![OpenCollective](https://opencollective.com/sous-chefs/sponsors/badge.svg)](#sponsors)
[![License](https://img.shields.io/badge/License-Apache%202.0-green.svg)](https://opensource.org/licenses/Apache-2.0)
Installs and manages the unbound DNS server.
- [http://unbound.net](http://unbound.net)
## Maintainers
This cookbook is maintained by the Sous Chefs. The Sous Chefs are a community of Chef cookbook maintainers working together to maintain important cookbooks. If youd 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).
## Requirements
### Platform
A platform with unbound available as a native package. The following platforms have unbound packaged, but note that the filesystem locations are not consistent and at this time only Linux + FHS is supported.
- Ubuntu/Debian
- Red Hat/CentOS/Fedora (requires EPEL)
- FreeBSD
### Chef
- Chef 16
## Resources
- [unbound_config_authority_zone](documentation/unbound_config_authority_zone.md)
- [unbound_config_cachedb](documentation/unbound_config_cachedb.md)
- [unbound_config_dns64](documentation/unbound_config_dns64.md)
- [unbound_config_dnscrypt](documentation/unbound_config_dnscrypt.md)
- [unbound_config_dnstap](documentation/unbound_config_dnstap.md)
- [unbound_config_dynamic_library](documentation/unbound_config_dynamic_library.md)
- [unbound_config_forward_zone](documentation/unbound_config_forward_zone.md)
- [unbound_config_python_script](documentation/unbound_config_python_script.md)
- [unbound_config_remote_control](documentation/unbound_config_remote_control.md)
- [unbound_config_rpz_zone](documentation/unbound_config_rpz_zone.md)
- [unbound_config_server](documentation/unbound_config_server.md)
- [unbound_config_stub_zone](documentation/unbound_config_stub_zone.md)
- [unbound_config_view](documentation/unbound_config_view.md)
- [unbound_package](documentation/unbound_package.md)
- [unbound_service](documentation/unbound_service.md)
## Recipes
### default
Installs unbound using defaults.
## Contributors
This project exists thanks to all the people who [contribute.](https://opencollective.com/sous-chefs/contributors.svg?width=890&button=false)
### Backers
Thank you to all our backers!
![https://opencollective.com/sous-chefs#backers](https://opencollective.com/sous-chefs/backers.svg?width=600&avatarHeight=40)
### Sponsors
Support this project by becoming a sponsor. Your logo will show up here with a link to your website.
![https://opencollective.com/sous-chefs/sponsor/0/website](https://opencollective.com/sous-chefs/sponsor/0/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/1/website](https://opencollective.com/sous-chefs/sponsor/1/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/2/website](https://opencollective.com/sous-chefs/sponsor/2/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/3/website](https://opencollective.com/sous-chefs/sponsor/3/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/4/website](https://opencollective.com/sous-chefs/sponsor/4/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/5/website](https://opencollective.com/sous-chefs/sponsor/5/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/6/website](https://opencollective.com/sous-chefs/sponsor/6/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/7/website](https://opencollective.com/sous-chefs/sponsor/7/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/8/website](https://opencollective.com/sous-chefs/sponsor/8/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/9/website](https://opencollective.com/sous-chefs/sponsor/9/avatar.svg?avatarHeight=100)

View File

@ -0,0 +1,115 @@
# Put files/directories that should be ignored in this file when uploading
# to a Chef Infra Server or Supermarket.
# Lines that start with '# ' are comments.
# OS generated files #
######################
.DS_Store
ehthumbs.db
Icon?
nohup.out
Thumbs.db
.envrc
# EDITORS #
###########
.#*
.project
.settings
*_flymake
*_flymake.*
*.bak
*.sw[a-z]
*.tmproj
*~
\#*
REVISION
TAGS*
tmtags
.vscode
.editorconfig
## COMPILED ##
##############
*.class
*.com
*.dll
*.exe
*.o
*.pyc
*.so
*/rdoc/
a.out
mkmf.log
# Testing #
###########
.circleci/*
.codeclimate.yml
.delivery/*
.foodcritic
.kitchen*
.mdlrc
.overcommit.yml
.rspec
.rubocop.yml
.travis.yml
.watchr
.yamllint
azure-pipelines.yml
Dangerfile
examples/*
features/*
Guardfile
kitchen.yml*
mlc_config.json
Procfile
Rakefile
spec/*
test/*
# SCM #
#######
.git
.gitattributes
.gitconfig
.github/*
.gitignore
.gitkeep
.gitmodules
.svn
*/.bzr/*
*/.git
*/.hg/*
*/.svn/*
# Berkshelf #
#############
Berksfile
Berksfile.lock
cookbooks/*
tmp
# Bundler #
###########
vendor/*
Gemfile
Gemfile.lock
# Policyfile #
##############
Policyfile.rb
Policyfile.lock.json
# Documentation #
#############
CODE_OF_CONDUCT*
CONTRIBUTING*
documentation/*
TESTING*
UPGRADING*
# Vagrant #
###########
.vagrant
Vagrantfile

View File

@ -0,0 +1,56 @@
---
driver:
name: dokken
privileged: true
chef_version: <%= ENV['CHEF_VERSION'] || 'current' %>
transport:
name: dokken
provisioner:
name: dokken
platforms:
- name: centos-7
driver:
image: dokken/centos-7
pid_one_command: /usr/lib/systemd/systemd
- name: centos-stream-8
driver:
image: dokken/centos-stream-8
pid_one_command: /usr/lib/systemd/systemd
- name: fedora-latest
driver:
image: dokken/fedora-latest
pid_one_command: /usr/lib/systemd/systemd
- name: ubuntu-18.04
driver:
image: dokken/ubuntu-18.04
pid_one_command: /bin/systemd
intermediate_instructions:
- RUN /usr/bin/apt-get update
- name: ubuntu-20.04
driver:
image: dokken/ubuntu-20.04
pid_one_command: /bin/systemd
intermediate_instructions:
- RUN /usr/bin/apt-get update
- name: debian-10
driver:
image: dokken/debian-10
pid_one_command: /bin/systemd
intermediate_instructions:
- RUN /usr/bin/apt-get update
- name: debian-11
driver:
image: dokken/debian-11
pid_one_command: /bin/systemd
intermediate_instructions:
- RUN /usr/bin/apt-get update
...

View File

@ -0,0 +1,59 @@
#
# Cookbook:: unbound
# Library:: helpers
#
# 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.
#
module Unbound
module Cookbook
module Helpers
def default_config_dir
return '/etc/unbound' if %i(unbound_config unbound_configure unbound_config_server).include?(declared_type)
return '/etc/unbound/unbound.conf.d' if platform?('debian', 'ubuntu')
case declared_type
when :unbound_config_local
'/etc/unbound/local.d'
when :unbound_config_key
'/etc/unbound/keys.d'
else
'/etc/unbound/conf.d'
end
end
def default_includes_dir
case node['platform_family']
when 'rhel', 'fedora'
%w(/etc/unbound/conf.d/*.conf /etc/unbound/local.d/*.conf)
when 'debian'
%w(/etc/unbound/unbound.conf.d/*.conf)
else
raise "Unsupported platform family #{node['platform_family']}"
end
end
def unbound_yes_no?(value)
case value
when true
'yes'
when false
'no'
when 'yes', 'YES', 'no', 'NO'
value.downcase
end
end
end
end
end

View File

@ -0,0 +1,26 @@
#
# Cookbook:: unbound
# Library:: template
#
# 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.
#
module Unbound
module Cookbook
module TemplateHelpers
def template_partial_indent(output, level, spaces = 2)
output.split("\n").each { |l| l.prepend(' ' * (level * spaces)) }.join("\n")
end
end
end
end

View File

@ -0,0 +1,42 @@
{
"name": "unbound",
"description": "Manages unbound DNS resolver",
"long_description": "",
"maintainer": "Sous Chefs",
"maintainer_email": "help@sous-chefs.org",
"license": "Apache-2.0",
"platforms": {
"debian": ">= 0.0.0",
"ubuntu": ">= 0.0.0",
"centos": ">= 0.0.0",
"redhat": ">= 0.0.0",
"scientific": ">= 0.0.0",
"oracle": ">= 0.0.0",
"amazon": ">= 0.0.0"
},
"dependencies": {
},
"providing": {
},
"recipes": {
},
"version": "3.0.2",
"source_url": "https://github.com/sous-chefs/unbound",
"issues_url": "https://github.com/sous-chefs/unbound/issues",
"privacy": false,
"chef_versions": [
[
">= 16"
]
],
"ohai_versions": [
],
"gems": [
],
"eager_load_libraries": true
}

View File

@ -0,0 +1,13 @@
name 'unbound'
maintainer 'Sous Chefs'
maintainer_email 'help@sous-chefs.org'
license 'Apache-2.0'
description 'Manages unbound DNS resolver'
version '3.0.2'
issues_url 'https://github.com/sous-chefs/unbound/issues'
source_url 'https://github.com/sous-chefs/unbound'
chef_version '>= 16'
%w(debian ubuntu centos redhat scientific oracle amazon).each do |os|
supports os
end

View File

@ -0,0 +1,25 @@
#
# Cookbook:: unbound
# Recipe:: default
#
# Copyright:: 2011, Joshua Timberman
#
# 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.
#
log 'v3_warning' do
message 'Version 3.0.0 of this cookbook removed all configuration actions from the default recipe'
level :warn
end
unbound_package 'unbound'

View File

@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
]
}

View File

@ -0,0 +1,93 @@
#
# Cookbook:: unbound
# Resource:: config_authority_zone
#
# 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.
#
unified_mode true
provides :unbound_config_auth_zone
use 'partials/_config_file'
property :config_file, String,
default: lazy { "#{config_dir}/authority-zone-#{name}.conf" },
desired_state: false,
description: 'Set to override unbound configuration file.'
property :zone_name, String,
default: lazy { name }
property :primary, [String, Array],
coerce: proc { |p| Array(p) }
property :master, [String, Array],
coerce: proc { |p| Array(p) }
property :url, [String, Array],
coerce: proc { |p| Array(p) }
property :allow_notify, [String, Array],
coerce: proc { |p| Array(p) }
property :fallback_enabled, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :for_downstream, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :for_upstream, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :zonemd_check, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :zonemd_reject_absence, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :zonefile, String
load_current_value do |new_resource|
current_value_does_not_exist! unless ::File.exist?(new_resource.config_file)
if ::File.exist?(new_resource.config_file)
owner ::Etc.getpwuid(::File.stat(new_resource.config_file).uid).name
group ::Etc.getgrgid(::File.stat(new_resource.config_file).gid).name
mode ::File.stat(new_resource.config_file).mode.to_s(8)[-4..-1]
end
end
action_class do
def do_template_action
zone_config = {
'name' => new_resource.zone_name,
'primary' => new_resource.primary.dup,
'master' => new_resource.master.dup,
'url' => new_resource.url.dup,
'allow-notify' => new_resource.allow_notify.dup,
'fallback-enabled' => new_resource.fallback_enabled,
'for-downstream' => new_resource.for_downstream,
'for-upstream' => new_resource.for_upstream,
'zonemd-check' => new_resource.zonemd_check,
'zonemd-reject-absence' => new_resource.zonemd_reject_absence,
'zonefile' => new_resource.zonefile,
}.compact
config = {
'auth-zone' => zone_config,
}
perform_config_action(config)
end
end

View File

@ -0,0 +1,67 @@
#
# Cookbook:: unbound
# Resource:: config_cachedb
#
# 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.
#
unified_mode true
use 'partials/_config_file'
property :config_file, String,
default: lazy { "#{config_dir}/cachedb.conf" },
desired_state: false,
description: 'Set to override unbound configuration file.'
property :backend, String
property :secret_seed, String
property :redis_server_host, String
property :redis_server_port, Integer
property :redis_timeout, Integer
property :redis_expire_records, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
load_current_value do |new_resource|
current_value_does_not_exist! unless ::File.exist?(new_resource.config_file)
if ::File.exist?(new_resource.config_file)
owner ::Etc.getpwuid(::File.stat(new_resource.config_file).uid).name
group ::Etc.getgrgid(::File.stat(new_resource.config_file).gid).name
mode ::File.stat(new_resource.config_file).mode.to_s(8)[-4..-1]
end
end
action_class do
def do_template_action
cachedb_config = {
'backend' => new_resource.backend,
'secret-seed' => new_resource.secret_seed,
'redis-server-host' => new_resource.redis_server_host,
'redis-server-port' => new_resource.redis_server_port,
'redis-timeout' => new_resource.redis_timeout,
'redis-expire-records' => new_resource.redis_expire_records,
}.compact
config = {
'cachedb' => cachedb_config,
}
perform_config_action(config)
end
end

View File

@ -0,0 +1,58 @@
#
# Cookbook:: unbound
# Resource:: config_dns64
#
# 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.
#
unified_mode true
use 'partials/_config_file'
property :config_file, String,
default: lazy { "#{config_dir}/dns64.conf" },
desired_state: false,
description: 'Set to override unbound configuration file.'
property :dns64_prefix, String
property :dns64_synthall, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :dns64_ignore_aaaa, String
load_current_value do |new_resource|
current_value_does_not_exist! unless ::File.exist?(new_resource.config_file)
if ::File.exist?(new_resource.config_file)
owner ::Etc.getpwuid(::File.stat(new_resource.config_file).uid).name
group ::Etc.getgrgid(::File.stat(new_resource.config_file).gid).name
mode ::File.stat(new_resource.config_file).mode.to_s(8)[-4..-1]
end
end
action_class do
def do_template_action
dns64_config = {
'dns64-prefix' => new_resource.dns64_prefix,
'dns64-synthall' => new_resource.dns64_synthall,
'dns64-ignore-aaaa' => new_resource.dns64_ignore_aaaa,
}.compact
config = {
'server' => dns64_config,
}
perform_config_action(config)
end
end

View File

@ -0,0 +1,80 @@
#
# Cookbook:: unbound
# Resource:: config_dnscrypt
#
# 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.
#
unified_mode true
use 'partials/_config_file'
property :config_file, String,
default: lazy { "#{config_dir}/dnscrypt.conf" },
desired_state: false,
description: 'Set to override unbound configuration file.'
property :dnscrypt_enable, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :dnscrypt_port, Integer
property :dnscrypt_provider, [String, Array],
coerce: proc { |p| Array(p) }
property :dnscrypt_secret_key, String
property :dnscrypt_provider_cert, String
property :dnscrypt_provider_cert_rotated, String
property :dnscrypt_shared_secret_cache_size, String
property :dnscrypt_shared_secret_cache_slabs, Integer
property :dnscrypt_nonce_cache_size, String
property :dnscrypt_nonce_cache_slabs, Integer
load_current_value do |new_resource|
current_value_does_not_exist! unless ::File.exist?(new_resource.config_file)
if ::File.exist?(new_resource.config_file)
owner ::Etc.getpwuid(::File.stat(new_resource.config_file).uid).name
group ::Etc.getgrgid(::File.stat(new_resource.config_file).gid).name
mode ::File.stat(new_resource.config_file).mode.to_s(8)[-4..-1]
end
end
action_class do
def do_template_action
dnscrypt_config = {
'dnscrypt-enable' => new_resource.dnscrypt_enable,
'dnscrypt-port' => new_resource.dnscrypt_port,
'dnscrypt-provider' => new_resource.dnscrypt_provider.dup,
'dnscrypt-secret-key' => new_resource.dnscrypt_secret_key,
'dnscrypt-provider-cert' => new_resource.dnscrypt_provider_cert,
'dnscrypt-provider-cert-rotated' => new_resource.dnscrypt_provider_cert_rotated,
'dnscrypt-shared-secret-cache-size' => new_resource.dnscrypt_shared_secret_cache_size,
'dnscrypt-shared-secret-cache-slabs' => new_resource.dnscrypt_shared_secret_cache_slabs,
'dnscrypt-nonce-cache-size' => new_resource.dnscrypt_nonce_cache_size,
'dnscrypt-nonce-cache-slabs' => new_resource.dnscrypt_nonce_cache_slabs,
}.compact
config = {
'dnscrypt' => dnscrypt_config,
}
perform_config_action(config)
end
end

View File

@ -0,0 +1,116 @@
#
# Cookbook:: unbound
# Resource:: config_dnstap
#
# 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.
#
unified_mode true
use 'partials/_config_file'
property :config_file, String,
default: lazy { "#{config_dir}/dnstap.conf" },
desired_state: false,
description: 'Set to override unbound configuration file.'
property :dnstap_enable, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :dnstap_bidirectional, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :dnstap_socket_path, String
property :dnstap_ip, String
property :dnstap_tls, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :dnstap_tls_server_name, String
property :dnstap_tls_cert_bundle, String
property :dnstap_tls_client_key_file, String
property :dnstap_tls_client_cert_file, String
property :dnstap_send_identity, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :dnstap_send_version, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :dnstap_identity, String
property :dnstap_version, String
property :dnstap_log_resolver_query_messages, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :dnstap_log_resolver_response_messages, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :dnstap_log_client_query_messages, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :dnstap_log_client_response_messages, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :dnstap_log_forwarder_query_messages, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :dnstap_log_forwarder_response_messages, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
load_current_value do |new_resource|
current_value_does_not_exist! unless ::File.exist?(new_resource.config_file)
if ::File.exist?(new_resource.config_file)
owner ::Etc.getpwuid(::File.stat(new_resource.config_file).uid).name
group ::Etc.getgrgid(::File.stat(new_resource.config_file).gid).name
mode ::File.stat(new_resource.config_file).mode.to_s(8)[-4..-1]
end
end
action_class do
def do_template_action
zone_config = {
'dnstap-enable' => new_resource.dnstap_enable,
'dnstap-bidirectional' => new_resource.dnstap_bidirectional,
'dnstap-socket-path' => new_resource.dnstap_socket_path,
'dnstap-ip' => new_resource.dnstap_ip,
'dnstap-tls' => new_resource.dnstap_tls,
'dnstap-tls-server-name' => new_resource.dnstap_tls_server_name,
'dnstap-tls-cert-bundle' => new_resource.dnstap_tls_cert_bundle,
'dnstap-tls-client-key-file' => new_resource.dnstap_tls_client_key_file,
'dnstap-tls-client-cert-file' => new_resource.dnstap_tls_client_cert_file,
'dnstap-send-identity' => new_resource.dnstap_send_identity,
'dnstap-send-version' => new_resource.dnstap_send_version,
'dnstap-identity' => new_resource.dnstap_identity,
'dnstap-version' => new_resource.dnstap_version,
'dnstap-log-resolver-query-messages' => new_resource.dnstap_log_resolver_query_messages,
'dnstap-log-resolver-response-messages' => new_resource.dnstap_log_resolver_response_messages,
'dnstap-log-client-query-messages' => new_resource.dnstap_log_client_query_messages,
'dnstap-log-client-response-messages' => new_resource.dnstap_log_client_response_messages,
'dnstap-log-forwarder-query-messages' => new_resource.dnstap_log_forwarder_query_messages,
'dnstap-log-forwarder-response-messages' => new_resource.dnstap_log_forwarder_response_messages,
}.compact
config = {
'dnstap' => zone_config,
}
perform_config_action(config)
end
end

View File

@ -0,0 +1,48 @@
#
# Cookbook:: unbound
# Resource:: config_dynamic_library
#
# 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.
#
unified_mode true
use 'partials/_config_file'
property :config_file, String,
default: lazy { "#{config_dir}/dyn-lib-#{name}.conf" },
desired_state: false,
description: 'Set to override unbound configuration file.'
property :dynlib_file, [String, Array],
coerce: proc { |p| Array(p) }
load_current_value do |new_resource|
current_value_does_not_exist! unless ::File.exist?(new_resource.config_file)
if ::File.exist?(new_resource.config_file)
owner ::Etc.getpwuid(::File.stat(new_resource.config_file).uid).name
group ::Etc.getgrgid(::File.stat(new_resource.config_file).gid).name
mode ::File.stat(new_resource.config_file).mode.to_s(8)[-4..-1]
end
end
action_class do
def do_template_action
config = {
'dynlib-file' => new_resource.dynlib_file.dup,
}
perform_config_action(config)
end
end

View File

@ -0,0 +1,80 @@
#
# Cookbook:: unbound
# Resource:: config_forward_zone
#
# 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.
#
unified_mode true
use 'partials/_config_file'
property :config_file, String,
default: lazy { "#{config_dir}/forward-zone-#{name}.conf" },
desired_state: false,
description: 'Set to override unbound configuration file.'
property :zone_name, String,
default: lazy { name }
property :forward_host, [String, Array],
coerce: proc { |p| Array(p) }
property :forward_addr, [String, Array],
coerce: proc { |p| Array(p) }
property :forward_first, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :forward_tls_upstream, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :forward_ssl_upstream, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :forward_tcp_upstream, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :forward_no_cache, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
load_current_value do |new_resource|
current_value_does_not_exist! unless ::File.exist?(new_resource.config_file)
if ::File.exist?(new_resource.config_file)
owner ::Etc.getpwuid(::File.stat(new_resource.config_file).uid).name
group ::Etc.getgrgid(::File.stat(new_resource.config_file).gid).name
mode ::File.stat(new_resource.config_file).mode.to_s(8)[-4..-1]
end
end
action_class do
def do_template_action
zone_config = {
'name' => new_resource.zone_name,
'forward-host' => new_resource.forward_host.dup,
'forward-addr' => new_resource.forward_addr.dup,
'forward-first' => new_resource.forward_first,
'forward-tls-upstream' => new_resource.forward_tls_upstream,
'forward-ssl-upstream' => new_resource.forward_ssl_upstream,
'forward-tcp-upstream' => new_resource.forward_tcp_upstream,
'forward-no-cache' => new_resource.forward_no_cache,
}.compact
config = {
'forward-zone' => zone_config,
}
perform_config_action(config)
end
end

View File

@ -0,0 +1,53 @@
#
# Cookbook:: unbound
# Resource:: config_python_script
#
# 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.
#
unified_mode true
use 'partials/_config_file'
property :config_file, String,
default: lazy { "#{config_dir}/python-script-#{name}.conf" },
desired_state: false,
description: 'Set to override unbound configuration file.'
property :python_script, [String, Array],
coerce: proc { |p| Array(p) },
required: true
load_current_value do |new_resource|
current_value_does_not_exist! unless ::File.exist?(new_resource.config_file)
if ::File.exist?(new_resource.config_file)
owner ::Etc.getpwuid(::File.stat(new_resource.config_file).uid).name
group ::Etc.getgrgid(::File.stat(new_resource.config_file).gid).name
mode ::File.stat(new_resource.config_file).mode.to_s(8)[-4..-1]
end
end
action_class do
def do_template_action
declare_resource(:package, 'python3-unbound')
config = {
'python' => {
'python-script' => new_resource.python_script.dup,
},
}
perform_config_action(config)
end
end

View File

@ -0,0 +1,77 @@
#
# Cookbook:: unbound
# Resource:: config_remote_control
#
# 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.
#
unified_mode true
use 'partials/_config_file'
property :config_file, String,
default: lazy { "#{config_dir}/remote-control.conf" },
desired_state: false,
description: 'Set to override unbound configuration file.'
property :control_enable, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :control_interface, [String, Array],
coerce: proc { |p| Array(p) }
property :control_port, Integer
property :control_use_cert, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :control_key_file, String
property :control_cert_file, String
property :server, String
property :server_key_file, String
property :server_cert_file, String
load_current_value do |new_resource|
current_value_does_not_exist! unless ::File.exist?(new_resource.config_file)
if ::File.exist?(new_resource.config_file)
owner ::Etc.getpwuid(::File.stat(new_resource.config_file).uid).name
group ::Etc.getgrgid(::File.stat(new_resource.config_file).gid).name
mode ::File.stat(new_resource.config_file).mode.to_s(8)[-4..-1]
end
end
action_class do
def do_template_action
remote_control = {
'control-enable' => new_resource.control_enable,
'control-interface' => new_resource.control_interface.dup,
'control-port' => new_resource.control_port,
'control-use-cert' => new_resource.control_use_cert,
'control-key-file' => new_resource.control_key_file,
'control-cert-file' => new_resource.control_cert_file,
'server-key-file' => new_resource.server_key_file,
'server-cert-file' => new_resource.server_cert_file,
}.compact
config = {
'remote-control' => remote_control,
}
perform_config_action(config)
end
end

View File

@ -0,0 +1,98 @@
#
# Cookbook:: unbound
# Resource:: config_rpz_zone
#
# 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.
#
unified_mode true
use 'partials/_config_file'
property :config_file, String,
default: lazy { "#{config_dir}/rpz-zone-#{name}.conf" },
desired_state: false,
description: 'Set to override unbound configuration file.'
property :zone_name, String,
default: lazy { name }
property :primary, [String, Array],
coerce: proc { |p| Array(p) }
property :master, [String, Array],
coerce: proc { |p| Array(p) }
property :url, [String, Array],
coerce: proc { |p| Array(p) }
property :allow_notify, [String, Array],
coerce: proc { |p| Array(p) }
property :zonefile, String
property :rpz_action_override, [String, Symbol],
equal_to: %w(nxdomain nodata passthru drop disabled cname),
coerce: proc { |p| p.to_s }
property :rpz_cname_override, String
property :rpz_log, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :rpz_log_name, String
property :rpz_signal_nxdomain_ra, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :for_downstream, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :tags, [String, Array],
coerce: proc { |p| "\"#{p.to_a.join(' ')} \"" }
load_current_value do |new_resource|
current_value_does_not_exist! unless ::File.exist?(new_resource.config_file)
if ::File.exist?(new_resource.config_file)
owner ::Etc.getpwuid(::File.stat(new_resource.config_file).uid).name
group ::Etc.getgrgid(::File.stat(new_resource.config_file).gid).name
mode ::File.stat(new_resource.config_file).mode.to_s(8)[-4..-1]
end
end
action_class do
def do_template_action
zone_config = {
'name' => new_resource.zone_name,
'primary' => new_resource.primary.dup,
'master' => new_resource.master.dup,
'url' => new_resource.url.dup,
'allow-notify' => new_resource.allow_notify.dup,
'zonefile' => new_resource.zonefile,
'rpz-action-override' => new_resource.rpz_action_override,
'rpz-cname-override' => new_resource.rpz_cname_override,
'rpz-log' => new_resource.rpz_log,
'rpz-log-name' => new_resource.rpz_log_name,
'rpz-signal-nxfomain-ra' => new_resource.rpz_signal_nxdomain_ra,
'for-downstream' => new_resource.for_downstream,
'tags' => new_resource.tags.dup,
}.compact
config = {
'rpz' => zone_config,
}
perform_config_action(config)
end
end

View File

@ -0,0 +1,58 @@
#
# Cookbook:: unbound
# Resource:: config_server
#
# 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.
#
unified_mode true
provides :unbound_config_server
provides :unbound_configure
provides :unbound_config
use 'partials/_config_file'
property :config_file, String,
default: lazy { "#{config_dir}/unbound.conf" },
desired_state: false,
description: 'Set to override unbound configuration file.'
property :include, [String, Array],
default: lazy { default_includes_dir },
coerce: proc { |p| Array(p) }
property :server, Hash,
default: {},
description: 'Server configuration as a Hash'
load_current_value do |new_resource|
current_value_does_not_exist! unless ::File.exist?(new_resource.config_file)
if ::File.exist?(new_resource.config_file)
owner ::Etc.getpwuid(::File.stat(new_resource.config_file).uid).name
group ::Etc.getgrgid(::File.stat(new_resource.config_file).gid).name
mode ::File.stat(new_resource.config_file).mode.to_s(8)[-4..-1]
end
end
action_class do
def do_template_action
config = {
'include' => new_resource.include.dup,
'server' => new_resource.server.dup,
}.compact
perform_config_action(config)
end
end

View File

@ -0,0 +1,84 @@
#
# Cookbook:: unbound
# Resource:: config_stub_zone
#
# 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.
#
unified_mode true
use 'partials/_config_file'
property :config_file, String,
default: lazy { "#{config_dir}/stub-zone-#{name}.conf" },
desired_state: false,
description: 'Set to override unbound configuration file.'
property :zone_name, String,
default: lazy { name }
property :stub_host, [String, Array],
coerce: proc { |p| Array(p) }
property :stub_addr, [String, Array],
coerce: proc { |p| Array(p) }
property :stub_prime, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :stub_first, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :stub_tls_upstream, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :stub_ssl_upstream, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :stub_tcp_upstream, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
property :stub_no_cache, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
load_current_value do |new_resource|
current_value_does_not_exist! unless ::File.exist?(new_resource.config_file)
if ::File.exist?(new_resource.config_file)
owner ::Etc.getpwuid(::File.stat(new_resource.config_file).uid).name
group ::Etc.getgrgid(::File.stat(new_resource.config_file).gid).name
mode ::File.stat(new_resource.config_file).mode.to_s(8)[-4..-1]
end
end
action_class do
def do_template_action
zone_config = {
'name' => new_resource.zone_name,
'stub-host' => new_resource.stub_host.dup,
'stub-addr' => new_resource.stub_addr.dup,
'stub-prime' => new_resource.stub_prime,
'stub-first' => new_resource.stub_first,
'stub-tls-upstream' => new_resource.stub_tls_upstream,
'stub-ssl-upstream' => new_resource.stub_ssl_upstream,
'stub-tcp-upstream' => new_resource.stub_tcp_upstream,
'stub-no-cache' => new_resource.stub_no_cache,
}.compact
config = {
'stub-zone' => zone_config,
}
perform_config_action(config)
end
end

View File

@ -0,0 +1,68 @@
#
# Cookbook:: unbound
# Resource:: config_view
#
# 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.
#
unified_mode true
use 'partials/_config_file'
property :config_file, String,
default: lazy { "#{config_dir}/view-#{name}.conf" },
desired_state: false,
description: 'Set to override unbound configuration file.'
property :zone_name, String,
default: lazy { name }
property :local_zone, [String, Array],
coerce: proc { |p| Array(p) }
property :local_data, [String, Array],
coerce: proc { |p| Array(p) }
property :local_data_ptr, [String, Array],
coerce: proc { |p| Array(p) }
property :view_first, [String, true, false],
coerce: proc { |p| unbound_yes_no?(p) }
load_current_value do |new_resource|
current_value_does_not_exist! unless ::File.exist?(new_resource.config_file)
if ::File.exist?(new_resource.config_file)
owner ::Etc.getpwuid(::File.stat(new_resource.config_file).uid).name
group ::Etc.getgrgid(::File.stat(new_resource.config_file).gid).name
mode ::File.stat(new_resource.config_file).mode.to_s(8)[-4..-1]
end
end
action_class do
def do_template_action
zone_config = {
'name' => new_resource.zone_name,
'local-zone' => new_resource.local_zone.dup,
'local-data' => new_resource.local_data.dup,
'local-data-ptr' => new_resource.local_data_ptr.dup,
'view-first' => new_resource.view_first,
}.compact
config = {
'view' => zone_config,
}
perform_config_action(config)
end
end

View File

@ -0,0 +1,36 @@
#
# Cookbook:: unbound
# Resource:: package
#
# 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.
#
unified_mode true
provides :unbound_install
property :packages, [String, Array],
coerce: proc { |p| p.is_a?(Array) ? p : [ p ] },
default: %w(unbound),
description: 'Unbound packages to install.'
action_class do
def do_package_action(action)
package 'unbound' do
package_name new_resource.packages
action action
end
end
end
%i(install upgrade remove).each { |pkg_action| action(pkg_action) { do_package_action(action) } }

View File

@ -0,0 +1,122 @@
#
# Cookbook:: unbound
# Resource:: _config_file
#
# 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.
#
unified_mode true
include Unbound::Cookbook::Helpers
property :owner, String,
default: 'root',
description: 'Set to override config file owner. Defaults to root.'
property :group, String,
default: 'unbound',
description: 'Set to override config file group. Defaults to unbound.'
property :mode, String,
default: '0640',
description: 'Set to override config file mode. Defaults to 0640.'
property :directory_mode, String,
default: '0750',
description: 'Set to override config directory mode. Defaults to 0750.'
property :config_dir, String,
default: lazy { default_config_dir },
desired_state: false,
description: 'Set to override unbound configuration directory.'
property :config_file, String,
default: lazy { "#{config_dir}/#{name}.conf" },
desired_state: false,
description: 'Set to override unbound configuration file.'
property :cookbook, String,
default: 'unbound',
desired_state: false,
description: 'Template source cookbook for the unbound configuration file.'
property :template, String,
default: 'unbound.conf.erb',
desired_state: false,
description: 'Template source file for the unbound configuration file.'
property :sensitive, [true, false],
desired_state: false,
description: 'Ensure that sensitive resource data is not output by Chef Infra Client.'
property :sort, [true, false],
default: true
property :template_properties, Hash,
default: {}
property :extra_options, Hash,
default: {}
action_class do
def deepsort?
return if defined?(DeepSort)
begin
Gem::Specification.find_by_name('deepsort')
rescue Gem::MissingSpecError
declare_resource(:chef_gem, 'deepsort')
end
require 'deepsort'
true
end
def perform_config_action(config)
directory new_resource.config_dir do
owner new_resource.owner
group new_resource.group
mode new_resource.directory_mode
recursive true
action new_resource.action.eql?(:delete) ? :delete : :create
end
config.merge!(new_resource.extra_options.dup) unless new_resource.extra_options.empty?
if new_resource.sort
deepsort?
config.deep_sort!
end
template new_resource.config_file do
cookbook new_resource.cookbook
source new_resource.template
owner new_resource.owner
group new_resource.group
mode new_resource.mode
sensitive new_resource.sensitive
helpers(Unbound::Cookbook::TemplateHelpers)
variables(content: config)
action new_resource.action
end
end
end
%i(create create_if_missing delete).each { |action_type| action(action_type) { do_template_action } }

View File

@ -0,0 +1,69 @@
#
# Cookbook:: unbound
# Resource:: service
#
# 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.
#
unified_mode true
property :service_name, String,
default: 'unbound',
description: 'The service name to perform actions upon'
property :config_test, [true, false],
default: true,
description: 'Perform configuration file test before performing service action'
property :config_test_fail_action, Symbol,
equal_to: %i(raise log),
default: :raise,
description: 'Action to perform upon configuration test failure.'
action_class do
def perform_config_test
cmd = shell_out('/usr/sbin/unbound-checkconf')
cmd.error!
rescue Mixlib::ShellOut::ShellCommandFailed
if new_resource.config_test_fail_action.eql?(:log)
Chef::Log.error("Configuration test failed, #{new_resource.service_name} #{action} action aborted!\n\n"\
"Error\n-----\n#{cmd.stderr}")
else
raise "Configuration test failed, #{new_resource.service_name} #{action} action aborted!\n\n"\
"Error\n-----\nAction: #{action}\n#{cmd.stderr}"
end
end
def do_service_action(service_action)
with_run_context(:root) do
if %i(start restart reload).include?(service_action)
if new_resource.config_test
perform_config_test
Chef::Log.info("Configuration test passed, creating #{new_resource.service_name} #{new_resource.declared_type} resource with action #{service_action}")
else
Chef::Log.info("Configuration test disabled, creating #{new_resource.service_name} #{new_resource.declared_type} resource with action #{service_action}")
end
declare_resource(:service, new_resource.service_name) { delayed_action(service_action) }
else
declare_resource(:service, new_resource.service_name) { action(service_action) }
end
end
end
end
%i(start stop restart reload enable disable).each { |action_type| action(action_type) { do_service_action(action_type) } }
action :test do
converge_by('Performing configuration test') { perform_config_test }
end

View File

@ -0,0 +1,22 @@
<% unless @content.nil? -%>
<% @content.each do |key, value| %>
<% case value %>
<% when nil %>
<%= key %>
<% when String, Numeric %>
<%= key %><% if @separator %><%= @separator %><% end %> <%= value %>
<% when Array %>
<% value.each do |val| %>
<% if val.is_a?(Hash) %>
<%= key %><% if @separator %><%= @separator %><% end %>
<%= template_partial_indent(render('partials/_generic_config.erb', cookbook: 'unbound', variables: { content: val, separator: ':' }), 1, 2) %>
<% else %>
<%= key %><% if @separator %><%= @separator %><% end %> <%= val %>
<% end %>
<% end %>
<% when Hash %>
<%= key %><% if @separator %><%= @separator %><% end %>
<%= template_partial_indent(render('partials/_generic_config.erb', cookbook: 'unbound', variables: { content: value, separator: ':' }), 1, 2) %>
<% end %>
<% end %>
<% end %>

View File

@ -0,0 +1,5 @@
#
# Generated by Chef Infra for <%= node['fqdn'] %>
# Do NOT modify this file by hand, any changes will be overwritten.
<%= render('partials/_generic_config.erb', cookbook: 'unbound', variables: { content: @content, separator: ':' }) %>

View File

@ -0,0 +1,17 @@
{
"id": "email",
"ldap_dn": {
"encrypted_data": "jMHHa8DeU4HCieF/ElOxrNJcHLRzjXGGFB1eJubtiARFpMYx+4hG\n",
"iv": "ojKHl8Va1GOj1sfr\n",
"auth_tag": "wkHLRyFF7WYllh+hXRIBJA==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"ldap_dnpass": {
"encrypted_data": "mCyzownpB0Q7BW4k7E+yXIwzSzaChPTEZHAWGiEcnXo2ioQ=\n",
"iv": "jc9/VY7AlQ5ttMm8\n",
"auth_tag": "mAZuoZOIJ4zRLdYbaetiag==\n",
"version": 3,
"cipher": "aes-256-gcm"
}
}

View File

@ -19,6 +19,21 @@
"ejabberd": {
"turn_ip_address": "148.251.83.201"
},
"email": {
"domain": "kosmos.org",
"hostname": "mail.kosmos.org",
"report_contact": "abuse@kosmos.org",
"virtual_aliases": {
"admin@kosmos.org": "ops@kosmos.org",
"ops@kosmos.org": "ops@5apps.com",
"webmaster": "mail@kosmos.org",
"hostmaster@kosmos.org": "mail@kosmos.org",
"postmaster@kosmos.org": "mail@kosmos.org",
"abuse@kosmos.org": "mail@kosmos.org",
"mail@kosmos.org": "foundation@kosmos.org",
"hackerhouse@kosmos.org": "mail@lagrange6.com"
}
},
"garage": {
"replication_mode": "2",
"s3_api_root_domain": "s3.kosmos.org",

View File

@ -26,6 +26,7 @@
"roles": [
"base",
"kvm_host",
"email_proxy",
"openresty_proxy",
"openresty",
"garage_gateway",
@ -36,6 +37,7 @@
"kosmos-base::default",
"kosmos_kvm::host",
"kosmos_kvm::backup",
"kosmos_email::firewall",
"kosmos_openresty",
"kosmos_openresty::default",
"kosmos_openresty::firewall",
@ -119,6 +121,7 @@
"run_list": [
"role[base]",
"role[kvm_host]",
"role[email_proxy]",
"role[openresty_proxy]",
"recipe[kosmos_encfs]",
"recipe[kosmos-ejabberd::firewall]",

View File

@ -1,5 +1,6 @@
{
"name": "ldap-4.kosmos.org",
"chef_environment": "production",
"normal": {
"knife_zero": {
"host": "10.1.1.106"

View File

@ -0,0 +1,70 @@
{
"name": "mail.kosmos.org",
"chef_environment": "production",
"normal": {
"knife_zero": {
"host": "10.1.1.95"
}
},
"automatic": {
"fqdn": "mail.kosmos.org",
"os": "linux",
"os_version": "5.15.0-1048-kvm",
"hostname": "mail",
"ipaddress": "192.168.122.131",
"roles": [
"base",
"kvm_guest",
"email_server",
"ldap_client"
],
"recipes": [
"kosmos-base",
"kosmos-base::default",
"kosmos_kvm::guest",
"kosmos-dirsrv::hostsfile",
"kosmos_email",
"kosmos_email::default",
"apt::default",
"timezone_iii::default",
"timezone_iii::debian",
"ntp::default",
"ntp::apparmor",
"kosmos-base::systemd_emails",
"apt::unattended-upgrades",
"kosmos-base::firewall",
"kosmos-postfix::default",
"hostname::default",
"kosmos-base::letsencrypt",
"unbound::default",
"kosmos_email::opendkim",
"kosmos_email::spamassassin",
"kosmos_email::postfix",
"postfix::server",
"postfix::default",
"postfix::_common",
"postfix::_attributes",
"postfix::relay_restrictions",
"kosmos_email::dovecot"
],
"platform": "ubuntu",
"platform_version": "22.04",
"cloud": null,
"chef_packages": {
"chef": {
"version": "18.3.0",
"chef_root": "/opt/chef/embedded/lib/ruby/gems/3.1.0/gems/chef-18.3.0/lib",
"chef_effortless": null
},
"ohai": {
"version": "18.1.4",
"ohai_root": "/opt/chef/embedded/lib/ruby/gems/3.1.0/gems/ohai-18.1.4/lib/ohai"
}
}
},
"run_list": [
"role[base]",
"role[kvm_guest]",
"role[email_server]"
]
}

5
roles/email_proxy.rb Normal file
View File

@ -0,0 +1,5 @@
name "email_proxy"
run_list %w(
kosmos_email::firewall
)

6
roles/email_server.rb Normal file
View File

@ -0,0 +1,6 @@
name "email_server"
run_list %w(
role[ldap_client]
kosmos_email::default
)

View File

@ -36,8 +36,8 @@ action :create do
--agree-tos \
--manual-auth-hook '#{hook_path} auth' \
--manual-cleanup-hook '#{hook_path} cleanup' \
--deploy-hook /etc/letsencrypt/renewal-hooks/post/openresty \
--email ops@kosmos.org \
#{node.run_list.roles.include?("openresty_proxy") ? '--deploy-hook /etc/letsencrypt/renewal-hooks/post/openresty' : nil } \
#{domains.map {|d| "-d #{d}" }.join(" ")}
CMD
not_if do

View File

@ -2,39 +2,21 @@
# Cookbook Name:: kosmos-postfix
# Recipe:: default
#
# The MIT License (MIT)
#
# Copyright:: 2019, Kosmos Developers
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
node.default['postfix']['main']['smtp_tls_CAfile'] = '/etc/ssl/certs/ca-certificates.crt'
node.default['postfix']['main']['smtpd_tls_CAfile'] = '/etc/ssl/certs/ca-certificates.crt'
return if node.run_list.roles.include?("email_server")
smtp_credentials = Chef::EncryptedDataBagItem.load('credentials', 'smtp')
node.override['postfix']['sasl']['smtp_sasl_user_name'] = smtp_credentials['user_name']
node.override['postfix']['sasl']['smtp_sasl_passwd'] = smtp_credentials['password']
node.override['postfix']['sasl_password_file'] = "#{node['postfix']['conf_dir']}/sasl_passwd"
node.default['postfix']['sasl']['smtp_sasl_user_name'] = smtp_credentials['user_name']
node.default['postfix']['sasl']['smtp_sasl_passwd'] = smtp_credentials['password']
node.default['postfix']['sasl_password_file'] = "#{node['postfix']['conf_dir']}/sasl_passwd"
# Postfix doesn't support smtps relayhost, use STARTSSL instead
node.override['postfix']['main']['relayhost'] = smtp_credentials['relayhost']
node.override['postfix']['main']['smtp_sasl_auth_enable'] = 'yes'
node.override['postfix']['main']['smtp_sasl_password_maps'] = "hash:#{node['postfix']['sasl_password_file']}"
node.override['postfix']['main']['smtp_sasl_security_options'] = 'noanonymous'
node.override['postfix']['main']['smtp_tls_CAfile'] = '/etc/ssl/certs/ca-certificates.crt'
node.override['postfix']['main']['smtpd_tls_CAfile'] = '/etc/ssl/certs/ca-certificates.crt'
node.default['postfix']['main']['relayhost'] = smtp_credentials['relayhost']
node.default['postfix']['main']['smtp_sasl_auth_enable'] = 'yes'
node.default['postfix']['main']['smtp_sasl_password_maps'] = "hash:#{node['postfix']['sasl_password_file']}"
node.default['postfix']['main']['smtp_sasl_security_options'] = 'noanonymous'
include_recipe 'postfix::default'

25
site-cookbooks/kosmos_email/.gitignore vendored Normal file
View File

@ -0,0 +1,25 @@
.vagrant
*~
*#
.#*
\#*#
.*.sw[a-z]
*.un~
# Bundler
Gemfile.lock
gems.locked
bin/*
.bundle/*
# test kitchen
.kitchen/
kitchen.local.yml
# Chef Infra
Berksfile.lock
.zero-knife.rb
Policyfile.lock.json
.idea/

View File

@ -0,0 +1,7 @@
# kosmos_email CHANGELOG
This file is used to list changes made in each version of the kosmos_email cookbook.
## 0.1.0
Initial release.

View File

@ -0,0 +1,20 @@
Copyright (c) Kosmos Developers
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,9 @@
node.default["email"]["root_directory"] = "/var/vmail"
node.default["email"]["domain"] = "example.com"
node.default["email"]["hostname"] = "mail.example.com"
node.default["email"]["report_contact"] = "abuse@example.com"
node.default["email"]["ldap_host"] = "ldap.kosmos.local"
node.default["email"]["ldap_search_base"] = "cn=users,dc=kosmos,dc=org"
node.default["email"]["virtual_aliases"] = {
"admin@example.com" => "administrator@example.com"
}

View File

@ -0,0 +1,115 @@
# Put files/directories that should be ignored in this file when uploading
# to a Chef Infra Server or Supermarket.
# Lines that start with '# ' are comments.
# OS generated files #
######################
.DS_Store
ehthumbs.db
Icon?
nohup.out
Thumbs.db
.envrc
# EDITORS #
###########
.#*
.project
.settings
*_flymake
*_flymake.*
*.bak
*.sw[a-z]
*.tmproj
*~
\#*
REVISION
TAGS*
tmtags
.vscode
.editorconfig
## COMPILED ##
##############
*.class
*.com
*.dll
*.exe
*.o
*.pyc
*.so
*/rdoc/
a.out
mkmf.log
# Testing #
###########
.circleci/*
.codeclimate.yml
.delivery/*
.foodcritic
.kitchen*
.mdlrc
.overcommit.yml
.rspec
.rubocop.yml
.travis.yml
.watchr
.yamllint
azure-pipelines.yml
Dangerfile
examples/*
features/*
Guardfile
kitchen.yml*
mlc_config.json
Procfile
Rakefile
spec/*
test/*
# SCM #
#######
.git
.gitattributes
.gitconfig
.github/*
.gitignore
.gitkeep
.gitmodules
.svn
*/.bzr/*
*/.git
*/.hg/*
*/.svn/*
# Berkshelf #
#############
Berksfile
Berksfile.lock
cookbooks/*
tmp
# Bundler #
###########
vendor/*
Gemfile
Gemfile.lock
# Policyfile #
##############
Policyfile.rb
Policyfile.lock.json
# Documentation #
#############
CODE_OF_CONDUCT*
CONTRIBUTING*
documentation/*
TESTING*
UPGRADING*
# Vagrant #
###########
.vagrant
Vagrantfile

View File

@ -0,0 +1,25 @@
# compliance
This directory contains Chef InSpec profile, waiver and input objects which are used with the Chef Infra Compliance Phase.
Detailed information on the Chef Infra Compliance Phase can be found in the [Chef Documentation](https://docs.chef.io/chef_compliance_phase/).
```plain
./compliance
├── inputs
├── profiles
└── waivers
```
Use the `chef generate` command from Chef Workstation to create content for these directories:
```sh
# Generate a Chef InSpec profile
chef generate profile PROFILE_NAME
# Generate a Chef InSpec waiver file
chef generate waiver WAIVER_NAME
# Generate a Chef InSpec input file
chef generate input INPUT_NAME
```

View File

@ -0,0 +1,53 @@
---
driver:
name: dokken
chef_version: 18.2.7
pull_platform_image: false
pull_chef_image: false
memory_limit: 2147483648 # 2GB
volumes:
# saves the apt archieves outside of the container
- /var/cache/apt/archives/:/var/cache/apt/archives/
## The forwarded_port port feature lets you connect to ports on the VM guest via
## localhost on the host.
## see also: https://www.vagrantup.com/docs/networking/forwarded_ports
# network:
# - ["forwarded_port", { guest: 4444, host: 4444 }]
transport:
name: dokken
provisioner:
name: dokken
# clean_dokken_sandbox: false
# You may wish to disable always updating cookbooks in CI or other testing environments.
# For example:
# always_update_cookbooks: <%= !ENV['CI'] %>
# always_update_cookbooks: false
## product_name and product_version specifies a specific Chef product and version to install.
## see the Chef documentation for more details: https://docs.chef.io/workstation/config_yml_kitchen/
# product_name: chef
# product_version: 16
verifier:
name: inspec
platforms:
- name: ubuntu-22.04
driver:
image: dokken/ubuntu-22.04
privileged: true
pid_one_command: /usr/lib/systemd/systemd
intermediate_instructions:
# prevent APT from deleting the APT folder
- RUN rm /etc/apt/apt.conf.d/docker-clean
suites:
- name: default
run_list:
- recipe[kosmos_email::default]
verifier:
inspec_tests:
- test/integration/default
attributes:

View File

@ -0,0 +1,11 @@
name 'kosmos_email'
maintainer 'Kosmos Developers'
maintainer_email 'ops@kosmos.org'
license 'MIT'
description 'Installs/configures an email service'
version '0.1.0'
chef_version '>= 18.0'
depends "hostname"
depends "unbound"
depends "postfix"

View File

@ -0,0 +1,40 @@
#
# Cookbook:: kosmos_email
# Recipe:: default
#
domain = node["email"]["domain"]
hostname = node["email"]["hostname"]
root_dir = node["email"]["root_directory"]
ip_addr = node["knife_zero"]["host"]
node.override["set_fqdn"] = hostname
include_recipe "hostname"
user "vmail" do
gid "mail"
system true
manage_home false
end
directory root_dir do
owner "vmail"
group "mail"
end
tls_cert_for hostname do
auth "gandi_dns"
action :create
end
firewall_rule "private network access" do
command :allow
protocol :tcp
source "10.1.1.0/24"
end
include_recipe 'unbound'
include_recipe 'kosmos_email::opendkim'
include_recipe 'kosmos_email::spamassassin'
include_recipe 'kosmos_email::postfix'
include_recipe 'kosmos_email::dovecot'

View File

@ -0,0 +1,90 @@
#
# Cookbook:: kosmos_email
# Recipe:: dovecot
#
%w[
dovecot-core
dovecot-imapd
dovecot-ldap
dovecot-lmtpd
dovecot-pop3d
].each do |pkg|
apt_package pkg
end
domain = node["email"]["domain"]
hostname = node["email"]["hostname"]
root_dir = node["email"]["root_directory"]
ip_addr = node["knife_zero"]["host"]
ldap_search_base = node["email"]["ldap_search_base"]
ldap_user_filter = "(&(objectClass=person)(mailRoutingAddress=%u))"
credentials = Chef::EncryptedDataBagItem.load('credentials', 'email')
template "/etc/dovecot/dovecot.conf" do
source "dovecot.conf.erb"
mode 0644
# TODO variables protocols: "imap pop3 lmtp"
variables protocols: "imap lmtp",
# TODO find by email_proxy role
haproxy_trusted_networks: "10.1.1.167/32"
notifies :restart, "service[dovecot]", :delayed
end
template "/etc/dovecot/dovecot-ldap.conf.ext" do
source "dovecot-ldap.conf.ext.erb"
mode 0600
variables uris: "ldap://ldap.kosmos.local", # TODO add list of all IPs instead?
dn: credentials['ldap_dn'],
dnpass: credentials['ldap_dnpass'],
base: ldap_search_base,
user_filter: ldap_user_filter,
user_attrs: "",
pass_filter: ldap_user_filter,
pass_attrs: "mailRoutingAddress=user,mailpassword=password",
default_pass_scheme: "BLF-CRYPT"
notifies :restart, "service[dovecot]", :delayed
end
template "/etc/dovecot/conf.d/10-auth.conf" do
source "dovecot_10-auth.conf.erb"
mode 0644
notifies :restart, "service[dovecot]", :delayed
end
template "/etc/dovecot/conf.d/10-mail.conf" do
source "dovecot_10-mail.conf.erb"
mode 0644
variables mail_uid: "vmail",
mail_gid: "mail",
mail_location: "mbox:~/mail:INBOX=~/mail/INBOX",
mail_home: "#{root_dir}/%d/%n"
notifies :restart, "service[dovecot]", :delayed
end
template "/etc/dovecot/conf.d/10-master.conf" do
source "dovecot_10-master.conf.erb"
mode 0644
notifies :restart, "service[dovecot]", :delayed
end
template "/etc/dovecot/conf.d/10-ssl.conf" do
source "dovecot_10-ssl.conf.erb"
mode 0644
variables ssl: "required",
ssl_cert: node['postfix']['main']['smtpd_tls_cert_file'],
ssl_key: node['postfix']['main']['smtpd_tls_key_file']
notifies :restart, "service[dovecot]", :delayed
end
template "/etc/dovecot/conf.d/15-mailboxes.conf" do
source "dovecot_15-mailboxes.conf.erb"
mode 0644
notifies :restart, "service[dovecot]", :delayed
end
service "dovecot" do
action [:enable, :start]
end

View File

@ -0,0 +1,34 @@
#
# Cookbook:: kosmos_email
# Recipe:: firewall
#
firewall_rule "SMTP" do
command :allow
port 25
protocol :tcp
end
firewall_rule "SMTPS" do
command :allow
port 465
protocol :tcp
end
firewall_rule "SMTPS" do
command :allow
port 587
protocol :tcp
end
firewall_rule "IMAP" do
command :allow
port 143
protocol :tcp
end
firewall_rule "IMAPS" do
command :allow
port 993
protocol :tcp
end

View File

@ -0,0 +1,74 @@
#
# Cookbook:: kosmos_email
# Recipe:: opendkim
#
%w[
opendkim
opendkim-tools
].each do |pkg|
apt_package pkg
end
domain = node["email"]["domain"]
selector = "mail"
socket = "inet:12301@localhost"
template "/etc/opendkim.conf" do
source "opendkim.conf.erb"
mode 0644
variables domain: domain,
selector: selector,
socket: socket
notifies :restart, "service[opendkim]", :delayed
end
template "/etc/default/opendkim" do
source "opendkim_default.erb"
mode 0644
variables socket: socket
notifies :restart, "service[opendkim]", :delayed
end
directory "/run/opendkim" do
owner "opendkim"
group "opendkim"
action :create
end
directory "/etc/opendkim"
template "/etc/opendkim/keytable" do
source "opendkim_keytable.erb"
mode 0644
variables domain: domain,
selector: selector
notifies :restart, "service[opendkim]", :delayed
end
template "/etc/opendkim/signingtable" do
source "opendkim_signingtable.erb"
mode 0644
variables domain: domain,
selector: selector
notifies :restart, "service[opendkim]", :delayed
end
directory "/etc/opendkim/keys/#{domain}" do
recursive true
end
execute "Create DKIM keys" do
cwd "/etc/opendkim/keys/#{domain}"
command "opendkim-genkey -s #{selector} -d #{domain}"
creates "/etc/opendkim/keys/#{domain}/#{selector}.private"
end
file "/etc/opendkim/keys/#{domain}/#{selector}.private" do
owner "opendkim"
group "opendkim"
end
service "opendkim" do
action [:enable, :start]
end

View File

@ -0,0 +1,197 @@
#
# Cookbook:: kosmos_email
# Recipe:: postfix
#
%w[
postfix
postfix-ldap
].each do |pkg|
apt_package pkg
end
domain = node["email"]["domain"]
hostname = node["email"]["hostname"]
root_dir = node["email"]["root_directory"]
ip_addr = node["knife_zero"]["host"]
ldap_host = node["email"]["ldap_host"]
ldap_search_base = node["email"]["ldap_search_base"]
credentials = Chef::EncryptedDataBagItem.load('credentials', 'email')
node.normal["postfix"]["mail_type"] = "master"
node.normal["postfix"]["use_relay_restrictions_maps"] = true
node.normal["postfix"]["relay_restrictions"] = { domain => "OK", hostname => "OK" }
node.normal['postfix']['main']['myhostname'] = hostname
node.normal['postfix']['main']['mydomain'] = "$myhostname"
node.normal['postfix']['main']['myorigin'] = "$myhostname"
node.normal['postfix']['main']['mynetworks'] = ["10.1.1.0/24", "127.0.0.0/8"]
node.normal['postfix']['main']['smtp_use_tls'] = "yes"
node.normal['postfix']['main']['smtp_tls_security_level'] = "may"
node.normal['postfix']['main']['smtpd_use_tls'] = "yes"
node.normal['postfix']['main']['smtpd_tls_cert_file'] = "/etc/letsencrypt/live/#{hostname}/fullchain.pem"
node.normal['postfix']['main']['smtpd_tls_key_file'] = "/etc/letsencrypt/live/#{hostname}/privkey.pem"
node.normal['postfix']['main']['smtpd_peername_lookup'] = "no"
node.normal['postfix']['main']['mailbox_transport'] = "lmtp:unix:private/dovecot-lmtp"
node.normal['postfix']['main']['virtual_transport'] = "lmtp:unix:private/dovecot-lmtp"
node.normal['postfix']['main']['smtputf8_enable'] = "no"
node.normal['postfix']['main']['recipient_delimiter'] = "+"
node.normal['postfix']['main']['virtual_alias_maps'] = "hash:#{root_dir}/aliases, ldap:/etc/postfix/ldap-virtual_alias_maps.cf"
node.normal['postfix']['main']['virtual_mailbox_domains'] = "ldap:/etc/postfix/ldap-virtual_mailbox_domains.cf"
node.normal['postfix']['main']['virtual_mailbox_maps'] = "ldap:/etc/postfix/ldap-virtual_mailbox_maps.cf"
node.normal['postfix']['main']['smtpd_sender_login_maps'] = "ldap:/etc/postfix/ldap-smtpd_sender_login_maps.cf"
node.normal['postfix']['main']['milter_protocol'] = "6"
node.normal['postfix']['main']['milter_default_action'] = "accept"
node.normal['postfix']['main']['smtpd_milters'] = "inet:localhost:12301 local:spamass/spamass.sock"
node.normal['postfix']['main']['non_smtpd_milters'] = "inet:localhost:12301"
node.normal['postfix']['master'] = {
"#{ip_addr}:2525": {
"active": true,
"order": 1,
"type": "inet",
"private": false,
"maxproc": "1",
"command": "postscreen",
"args": [
"-o postscreen_upstream_proxy_protocol=haproxy",
"-o postscreen_cache_map=btree:$data_directory/postscreen_2525_cache",
"-o syslog_name=postfix/2525"
]
},
"#{ip_addr}:10587": {
"active": true,
"order": 2,
"type": "inet",
"private": false,
"chroot": true,
"command": "smtpd",
"args": [
"-o syslog_name=postfix/10587",
"-o smtpd_tls_security_level=encrypt",
"-o smtpd_tls_wrappermode=no",
"-o smtpd_sasl_auth_enable=yes",
"-o smtpd_sender_restrictions=reject_sender_login_mismatch",
"-o smtpd_relay_restrictions=permit_sasl_authenticated,reject",
"-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject",
"-o smtpd_sasl_type=dovecot",
"-o smtpd_sasl_path=private/auth",
"-o smtpd_upstream_proxy_protocol=haproxy",
]
},
"#{ip_addr}:10465": {
"active": true,
"order": 3,
"type": "inet",
"private": false,
"chroot": true,
"command": "smtpd",
"args": [
"-o syslog_name=postfix/10465",
"-o smtpd_tls_wrappermode=yes",
"-o smtpd_sasl_auth_enable=yes",
"-o smtpd_relay_restrictions=permit_sasl_authenticated,reject",
"-o smtpd_sender_restrictions=reject_sender_login_mismatch",
"-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject",
"-o smtpd_sasl_type=dovecot",
"-o smtpd_sasl_path=private/auth",
"-o smtpd_upstream_proxy_protocol=haproxy",
]
},
"smtpd": {
"active": true,
"order": 100,
"type": "pass",
"chroot": true,
"command": "smtpd",
"args": []
},
"dnsblog": {
"active": true,
"order": 101,
"type": "unix",
"chroot": true,
"maxproc": "0",
"command": "dnsblog",
"args": []
},
"tlsproxy": {
"active": true,
"order": 102,
"type": "unix",
"chroot": true,
"maxproc": "0",
"command": "tlsproxy",
"args": []
}
}
bash "compile_postfix_aliases" do
cwd root_dir
code "postmap #{root_dir}/aliases"
action :nothing
notifies :restart, "service[postfix]", :delayed
end
template "#{root_dir}/aliases" do
source "virtual-aliases.erb"
mode 0755
variables aliases: node["email"]["virtual_aliases"]
notifies :run, "bash[compile_postfix_aliases]", :immediately
end
ldap_default_variables = {
server_host: ldap_host,
bind_dn: credentials['ldap_dn'],
bind_pw: credentials['ldap_dnpass'],
search_base: ldap_search_base
}
template "/etc/postfix/ldap-virtual_mailbox_domains.cf" do
source "postfix_ldap-map.cf.erb"
mode 0600
variables ldap_default_variables.merge({
query_filter: "mailRoutingAddress=*@%s",
result_attribute: "mailRoutingAddress",
result_format: "%d"
})
notifies :restart, "service[postfix]", :delayed
end
template "/etc/postfix/ldap-virtual_alias_maps.cf" do
source "postfix_ldap-map.cf.erb"
mode 0600
variables ldap_default_variables.merge({
query_filter: "(&(mailRoutingAddress=%s)(mailForwardingAddress=*))",
result_attribute: "mailForwardingAddress"
})
notifies :restart, "service[postfix]", :delayed
end
template "/etc/postfix/ldap-virtual_mailbox_maps.cf" do
source "postfix_ldap-map.cf.erb"
mode 0600
variables ldap_default_variables.merge({
query_filter: "mailRoutingAddress=%s",
result_attribute: "mailRoutingAddress"
})
notifies :restart, "service[postfix]", :delayed
end
template "/etc/postfix/ldap-smtpd_sender_login_maps.cf" do
source "postfix_ldap-map.cf.erb"
mode 0600
variables ldap_default_variables.merge({
query_filter: "mailRoutingAddress=%s",
result_attribute: "mailRoutingAddress, mailForwardingAddress"
})
notifies :restart, "service[postfix]", :delayed
end
include_recipe 'postfix::server'
service "postfix" do
action [:enable, :start]
end

View File

@ -0,0 +1,34 @@
#
# Cookbook:: kosmos_email
# Recipe:: spamassassin
#
%w[
spamassassin
spamc
spamass-milter
].each do |pkg|
apt_package pkg
end
domain = node["email"]["domain"]
report_contact = node["email"]["report_contact"]
template "/etc/default/spamassassin" do
source "spamassassin_default.erb"
mode 0644
variables options: "-u debian-spamd --nouser-config --max-children 10"
notifies :restart, "service[spamassassin]", :delayed
end
template "/etc/spamassassin/local.cf" do
source "spamassassin_local.cf.erb"
mode 0644
variables whitelist_auth: "*@#{domain}",
report_contact: report_contact
notifies :restart, "service[spamassassin]", :delayed
end
service "spamassassin" do
action [:enable, :start]
end

View File

@ -0,0 +1,151 @@
# This file is commonly accessed via passdb {} or userdb {} section in
# conf.d/auth-ldap.conf.ext
# This file is opened as root, so it should be owned by root and mode 0600.
#
# http://wiki2.dovecot.org/AuthDatabase/LDAP
#
# NOTE: If you're not using authentication binds, you'll need to give
# dovecot-auth read access to userPassword field in the LDAP server.
# With OpenLDAP this is done by modifying /etc/ldap/slapd.conf. There should
# already be something like this:
# access to attribute=userPassword
# by dn="<dovecot's dn>" read # add this
# by anonymous auth
# by self write
# by * none
# Space separated list of LDAP hosts to use. host:port is allowed too.
#hosts =
# LDAP URIs to use. You can use this instead of hosts list. Note that this
# setting isn't supported by all LDAP libraries.
uris = <%= @uris %>
# Distinguished Name - the username used to login to the LDAP server.
# Leave it commented out to bind anonymously (useful with auth_bind=yes).
dn = <%= @dn %>
# Password for LDAP server, if dn is specified.
dnpass = <%= @dnpass %>
# Use SASL binding instead of the simple binding. Note that this changes
# ldap_version automatically to be 3 if it's lower.
#sasl_bind = no
# SASL mechanism name to use.
#sasl_mech =
# SASL realm to use.
#sasl_realm =
# SASL authorization ID, ie. the dnpass is for this "master user", but the
# dn is still the logged in user. Normally you want to keep this empty.
#sasl_authz_id =
# Use TLS to connect to the LDAP server.
#tls = no
# TLS options, currently supported only with OpenLDAP:
#tls_ca_cert_file =
#tls_ca_cert_dir =
#tls_cipher_suite =
# TLS cert/key is used only if LDAP server requires a client certificate.
#tls_cert_file =
#tls_key_file =
# Valid values: never, hard, demand, allow, try
#tls_require_cert =
# Use the given ldaprc path.
#ldaprc_path =
# LDAP library debug level as specified by LDAP_DEBUG_* in ldap_log.h.
# -1 = everything. You may need to recompile OpenLDAP with debugging enabled
# to get enough output.
#debug_level = 1
# Use authentication binding for verifying password's validity. This works by
# logging into LDAP server using the username and password given by client.
# The pass_filter is used to find the DN for the user. Note that the pass_attrs
# is still used, only the password field is ignored in it. Before doing any
# search, the binding is switched back to the default DN.
#auth_bind = no
# If authentication binding is used, you can save one LDAP request per login
# if users' DN can be specified with a common template. The template can use
# the standard %variables (see user_filter). Note that you can't
# use any pass_attrs if you use this setting.
#
# If you use this setting, it's a good idea to use a different
# dovecot-ldap.conf.ext for userdb (it can even be a symlink, just as long as
# the filename is different in userdb's args). That way one connection is used
# only for LDAP binds and another connection is used for user lookups.
# Otherwise the binding is changed to the default DN before each user lookup.
#
# For example:
# auth_bind_userdn = cn=%u,ou=people,o=org
#
#auth_bind_userdn =
# LDAP protocol version to use. Likely 2 or 3.
#ldap_version = 3
# LDAP base. %variables can be used here.
# For example: dc=mail, dc=example, dc=org
base = <%= @base %>
# Dereference: never, searching, finding, always
#deref = never
# Search scope: base, onelevel, subtree
#scope = subtree
# User attributes are given in LDAP-name=dovecot-internal-name list. The
# internal names are:
# uid - System UID
# gid - System GID
# home - Home directory
# mail - Mail location
#
# There are also other special fields which can be returned, see
# http://wiki2.dovecot.org/UserDatabase/ExtraFields
user_attrs = <%= @user_attrs %>
# Filter for user lookup. Some variables can be used (see
# http://wiki2.dovecot.org/Variables for full list):
# %u - username
# %n - user part in user@domain, same as %u if there's no domain
# %d - domain part in user@domain, empty if user there's no domain
user_filter = <%= @user_filter %>
# Password checking attributes:
# user: Virtual user name (user@domain), if you wish to change the
# user-given username to something else
# password: Password, may optionally start with {type}, eg. {crypt}
# There are also other special fields which can be returned, see
# http://wiki2.dovecot.org/PasswordDatabase/ExtraFields
pass_attrs = <%= @pass_attrs %>
# If you wish to avoid two LDAP lookups (passdb + userdb), you can use
# userdb prefetch instead of userdb ldap in dovecot.conf. In that case you'll
# also have to include user_attrs in pass_attrs field prefixed with "userdb_"
# string. For example:
#pass_attrs = uid=user,userPassword=password,\
# homeDirectory=userdb_home,uidNumber=userdb_uid,gidNumber=userdb_gid
# Filter for password lookups
pass_filter = <%= @pass_filter %>
# Attributes and filter to get a list of all users
#iterate_attrs = uid=user
#iterate_filter = (objectClass=posixAccount)
# Default password scheme. "{scheme}" before password overrides this.
# List of supported schemes is in: http://wiki2.dovecot.org/Authentication
default_pass_scheme = <%= @default_pass_scheme %>
# By default all LDAP lookups are performed by the auth master process.
# If blocking=yes, auth worker processes are used to perform the lookups.
# Each auth worker process creates its own LDAP connection so this can
# increase parallelism. With blocking=no the auth master process can
# keep 8 requests pipelined for the LDAP connection, while with blocking=yes
# each connection has a maximum of 1 request running. For small systems the
# blocking=no is sufficient and uses less resources.
#blocking = no

View File

@ -0,0 +1,105 @@
## Dovecot configuration file
# If you're in a hurry, see http://wiki2.dovecot.org/QuickConfiguration
# "doveconf -n" command gives a clean output of the changed settings. Use it
# instead of copy&pasting files when posting to the Dovecot mailing list.
# '#' character and everything after it is treated as comments. Extra spaces
# and tabs are ignored. If you want to use either of these explicitly, put the
# value inside quotes, eg.: key = "# char and trailing whitespace "
# Most (but not all) settings can be overridden by different protocols and/or
# source/destination IPs by placing the settings inside sections, for example:
# protocol imap { }, local 127.0.0.1 { }, remote 10.0.0.0/8 { }
# Default values are shown for each setting, it's not required to uncomment
# those. These are exceptions to this though: No sections (e.g. namespace {})
# or plugin settings are added by default, they're listed only as examples.
# Paths are also just examples with the real defaults being based on configure
# options. The paths listed here are for configure --prefix=/usr
# --sysconfdir=/etc --localstatedir=/var
# Enable installed protocols
protocols = <%= @protocols %>
#!include_try /usr/share/dovecot/protocols.d/*.protocol
# A comma separated list of IPs or hosts where to listen in for connections.
# "*" listens in all IPv4 interfaces, "::" listens in all IPv6 interfaces.
# If you want to specify non-default ports or anything more complex,
# edit conf.d/master.conf.
#listen = *, ::
# Base directory where to store runtime data.
#base_dir = /var/run/dovecot/
# Name of this instance. In multi-instance setup doveadm and other commands
# can use -i <instance_name> to select which instance is used (an alternative
# to -c <config_path>). The instance name is also added to Dovecot processes
# in ps output.
#instance_name = dovecot
# Greeting message for clients.
#login_greeting = Dovecot ready.
# Space separated list of trusted network ranges. Connections from these
# IPs are allowed to override their IP addresses and ports (for logging and
# for authentication checks). disable_plaintext_auth is also ignored for
# these networks. Typically you'd specify your IMAP proxy servers here.
#login_trusted_networks =
# Space separated list of login access check sockets (e.g. tcpwrap)
#login_access_sockets =
# With proxy_maybe=yes if proxy destination matches any of these IPs, don't do
# proxying. This isn't necessary normally, but may be useful if the destination
# IP is e.g. a load balancer's IP.
#auth_proxy_self =
# Show more verbose process titles (in ps). Currently shows user name and
# IP address. Useful for seeing who are actually using the IMAP processes
# (eg. shared mailboxes or if same uid is used for multiple accounts).
#verbose_proctitle = no
# Should all processes be killed when Dovecot master process shuts down.
# Setting this to "no" means that Dovecot can be upgraded without
# forcing existing client connections to close (although that could also be
# a problem if the upgrade is e.g. because of a security fix).
#shutdown_clients = yes
# If non-zero, run mail commands via this many connections to doveadm server,
# instead of running them directly in the same process.
#doveadm_worker_count = 0
# UNIX socket or host:port used for connecting to doveadm server
#doveadm_socket_path = doveadm-server
# Space separated list of environment variables that are preserved on Dovecot
# startup and passed down to all of its child processes. You can also give
# key=value pairs to always set specific settings.
#import_environment = TZ
##
## Dictionary server settings
##
# Dictionary can be used to store key=value lists. This is used by several
# plugins. The dictionary can be accessed either directly or though a
# dictionary server. The following dict block maps dictionary names to URIs
# when the server is used. These can then be referenced using URIs in format
# "proxy::<name>".
dict {
#quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext
}
# Most of the actual configuration gets included below. The filenames are
# first sorted by their ASCII value and parsed in that order. The 00-prefixes
# in filenames are intended to make it easier to understand the ordering.
!include conf.d/*.conf
# A config file can also tried to be included without giving an error if
# it's not found:
!include_try local.conf
haproxy_trusted_networks = <%= @haproxy_trusted_networks %>
haproxy_timeout = 3s

View File

@ -0,0 +1,127 @@
##
## Authentication processes
##
# Disable LOGIN command and all other plaintext authentications unless
# SSL/TLS is used (LOGINDISABLED capability). Note that if the remote IP
# matches the local IP (ie. you're connecting from the same computer), the
# connection is considered secure and plaintext authentication is allowed.
# See also ssl=required setting.
disable_plaintext_auth = yes
# Authentication cache size (e.g. 10M). 0 means it's disabled. Note that
# bsdauth and PAM require cache_key to be set for caching to be used.
#auth_cache_size = 0
# Time to live for cached data. After TTL expires the cached record is no
# longer used, *except* if the main database lookup returns internal failure.
# We also try to handle password changes automatically: If user's previous
# authentication was successful, but this one wasn't, the cache isn't used.
# For now this works only with plaintext authentication.
#auth_cache_ttl = 1 hour
# TTL for negative hits (user not found, password mismatch).
# 0 disables caching them completely.
#auth_cache_negative_ttl = 1 hour
# Space separated list of realms for SASL authentication mechanisms that need
# them. You can leave it empty if you don't want to support multiple realms.
# Many clients simply use the first one listed here, so keep the default realm
# first.
#auth_realms =
# Default realm/domain to use if none was specified. This is used for both
# SASL realms and appending @domain to username in plaintext logins.
#auth_default_realm =
# List of allowed characters in username. If the user-given username contains
# a character not listed in here, the login automatically fails. This is just
# an extra check to make sure user can't exploit any potential quote escaping
# vulnerabilities with SQL/LDAP databases. If you want to allow all characters,
# set this value to empty.
#auth_username_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@
# Username character translations before it's looked up from databases. The
# value contains series of from -> to characters. For example "#@/@" means
# that '#' and '/' characters are translated to '@'.
#auth_username_translation =
# Username formatting before it's looked up from databases. You can use
# the standard variables here, eg. %Lu would lowercase the username, %n would
# drop away the domain if it was given, or "%n-AT-%d" would change the '@' into
# "-AT-". This translation is done after auth_username_translation changes.
auth_username_format = %Lu
# If you want to allow master users to log in by specifying the master
# username within the normal username string (ie. not using SASL mechanism's
# support for it), you can specify the separator character here. The format
# is then <username><separator><master username>. UW-IMAP uses "*" as the
# separator, so that could be a good choice.
#auth_master_user_separator =
# Username to use for users logging in with ANONYMOUS SASL mechanism
#auth_anonymous_username = anonymous
# Maximum number of dovecot-auth worker processes. They're used to execute
# blocking passdb and userdb queries (eg. MySQL and PAM). They're
# automatically created and destroyed as needed.
#auth_worker_max_count = 30
# Host name to use in GSSAPI principal names. The default is to use the
# name returned by gethostname(). Use "$ALL" (with quotes) to allow all keytab
# entries.
#auth_gssapi_hostname =
# Kerberos keytab to use for the GSSAPI mechanism. Will use the system
# default (usually /etc/krb5.keytab) if not specified. You may need to change
# the auth service to run as root to be able to read this file.
#auth_krb5_keytab =
# Do NTLM and GSS-SPNEGO authentication using Samba's winbind daemon and
# ntlm_auth helper. <doc/wiki/Authentication/Mechanisms/Winbind.txt>
#auth_use_winbind = no
# Path for Samba's ntlm_auth helper binary.
#auth_winbind_helper_path = /usr/bin/ntlm_auth
# Time to delay before replying to failed authentications.
#auth_failure_delay = 2 secs
# Require a valid SSL client certificate or the authentication fails.
#auth_ssl_require_client_cert = no
# Take the username from client's SSL certificate, using
# X509_NAME_get_text_by_NID() which returns the subject's DN's
# CommonName.
#auth_ssl_username_from_cert = no
# Space separated list of wanted authentication mechanisms:
# plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi otp
# gss-spnego
# NOTE: See also disable_plaintext_auth setting.
auth_mechanisms = plain login
##
## Password and user databases
##
#
# Password database is used to verify user's password (and nothing more).
# You can have multiple passdbs and userdbs. This is useful if you want to
# allow both system users (/etc/passwd) and virtual users to login without
# duplicating the system users into virtual database.
#
# <doc/wiki/PasswordDatabase.txt>
#
# User database specifies where mails are located and what user/group IDs
# own them. For single-UID configuration use "static" userdb.
#
# <doc/wiki/UserDatabase.txt>
#!include auth-deny.conf.ext
#!include auth-master.conf.ext
#!include auth-system.conf.ext
#!include auth-sql.conf.ext
!include auth-ldap.conf.ext
#!include auth-passwdfile.conf.ext
#!include auth-checkpassword.conf.ext
#!include auth-static.conf.ext

View File

@ -0,0 +1,386 @@
##
## Mailbox locations and namespaces
##
# Location for users' mailboxes. The default is empty, which means that Dovecot
# tries to find the mailboxes automatically. This won't work if the user
# doesn't yet have any mail, so you should explicitly tell Dovecot the full
# location.
#
# If you're using mbox, giving a path to the INBOX file (eg. /var/mail/%u)
# isn't enough. You'll also need to tell Dovecot where the other mailboxes are
# kept. This is called the "root mail directory", and it must be the first
# path given in the mail_location setting.
#
# There are a few special variables you can use, eg.:
#
# %u - username
# %n - user part in user@domain, same as %u if there's no domain
# %d - domain part in user@domain, empty if there's no domain
# %h - home directory
#
# See doc/wiki/Variables.txt for full list. Some examples:
#
# mail_location = maildir:~/Maildir
# mail_location = mbox:~/mail:INBOX=/var/mail/%u
# mail_location = mbox:/var/mail/%d/%1n/%n:INDEX=/var/indexes/%d/%1n/%n
#
# <doc/wiki/MailLocation.txt>
#
mail_location = <%= @mail_location %>
mail_home = <%= @mail_home %>
# If you need to set multiple mailbox locations or want to change default
# namespace settings, you can do it by defining namespace sections.
#
# You can have private, shared and public namespaces. Private namespaces
# are for user's personal mails. Shared namespaces are for accessing other
# users' mailboxes that have been shared. Public namespaces are for shared
# mailboxes that are managed by sysadmin. If you create any shared or public
# namespaces you'll typically want to enable ACL plugin also, otherwise all
# users can access all the shared mailboxes, assuming they have permissions
# on filesystem level to do so.
namespace inbox {
}
# Example shared namespace configuration
#namespace {
#type = shared
#separator = /
# Mailboxes are visible under "shared/user@domain/"
# %%n, %%d and %%u are expanded to the destination user.
#prefix = shared/%%u/
# Mail location for other users' mailboxes. Note that %variables and ~/
# expands to the logged in user's data. %%n, %%d, %%u and %%h expand to the
# destination user's data.
#location = maildir:%%h/Maildir:INDEX=~/Maildir/shared/%%u
# Use the default namespace for saving subscriptions.
#subscriptions = no
# List the shared/ namespace only if there are visible shared mailboxes.
#list = children
#}
# Should shared INBOX be visible as "shared/user" or "shared/user/INBOX"?
#mail_shared_explicit_inbox = no
# System user and group used to access mails. If you use multiple, userdb
# can override these by returning uid or gid fields. You can use either numbers
# or names. <doc/wiki/UserIds.txt>
mail_uid = <%= @mail_uid %>
mail_gid = <%= @mail_gid %>
# Group to enable temporarily for privileged operations. Currently this is
# used only with INBOX when either its initial creation or dotlocking fails.
# Typically this is set to "mail" to give access to /var/mail.
mail_privileged_group = mail
# Grant access to these supplementary groups for mail processes. Typically
# these are used to set up access to shared mailboxes. Note that it may be
# dangerous to set these if users can create symlinks (e.g. if "mail" group is
# set here, ln -s /var/mail ~/mail/var could allow a user to delete others'
# mailboxes, or ln -s /secret/shared/box ~/mail/mybox would allow reading it).
#mail_access_groups =
# Allow full filesystem access to clients. There's no access checks other than
# what the operating system does for the active UID/GID. It works with both
# maildir and mboxes, allowing you to prefix mailboxes names with eg. /path/
# or ~user/.
#mail_full_filesystem_access = no
# Dictionary for key=value mailbox attributes. This is used for example by
# URLAUTH and METADATA extensions.
#mail_attribute_dict =
# A comment or note that is associated with the server. This value is
# accessible for authenticated users through the IMAP METADATA server
# entry "/shared/comment".
#mail_server_comment = ""
# Indicates a method for contacting the server administrator. According to
# RFC 5464, this value MUST be a URI (e.g., a mailto: or tel: URL), but that
# is currently not enforced. Use for example mailto:admin@example.com. This
# value is accessible for authenticated users through the IMAP METADATA server
# entry "/shared/admin".
#mail_server_admin =
##
## Mail processes
##
# Don't use mmap() at all. This is required if you store indexes to shared
# filesystems (NFS or clustered filesystem).
#mmap_disable = no
# Rely on O_EXCL to work when creating dotlock files. NFS supports O_EXCL
# since version 3, so this should be safe to use nowadays by default.
#dotlock_use_excl = yes
# When to use fsync() or fdatasync() calls:
# optimized (default): Whenever necessary to avoid losing important data
# always: Useful with e.g. NFS when write()s are delayed
# never: Never use it (best performance, but crashes can lose data)
#mail_fsync = optimized
# Locking method for index files. Alternatives are fcntl, flock and dotlock.
# Dotlocking uses some tricks which may create more disk I/O than other locking
# methods. NFS users: flock doesn't work, remember to change mmap_disable.
#lock_method = fcntl
# Directory where mails can be temporarily stored. Usually it's used only for
# mails larger than >= 128 kB. It's used by various parts of Dovecot, for
# example LDA/LMTP while delivering large mails or zlib plugin for keeping
# uncompressed mails.
#mail_temp_dir = /tmp
# Valid UID range for users, defaults to 500 and above. This is mostly
# to make sure that users can't log in as daemons or other system users.
# Note that denying root logins is hardcoded to dovecot binary and can't
# be done even if first_valid_uid is set to 0.
#first_valid_uid = 500
#last_valid_uid = 0
# Valid GID range for users, defaults to non-root/wheel. Users having
# non-valid GID as primary group ID aren't allowed to log in. If user
# belongs to supplementary groups with non-valid GIDs, those groups are
# not set.
#first_valid_gid = 1
#last_valid_gid = 0
# Maximum allowed length for mail keyword name. It's only forced when trying
# to create new keywords.
#mail_max_keyword_length = 50
# ':' separated list of directories under which chrooting is allowed for mail
# processes (ie. /var/mail will allow chrooting to /var/mail/foo/bar too).
# This setting doesn't affect login_chroot, mail_chroot or auth chroot
# settings. If this setting is empty, "/./" in home dirs are ignored.
# WARNING: Never add directories here which local users can modify, that
# may lead to root exploit. Usually this should be done only if you don't
# allow shell access for users. <doc/wiki/Chrooting.txt>
#valid_chroot_dirs =
# Default chroot directory for mail processes. This can be overridden for
# specific users in user database by giving /./ in user's home directory
# (eg. /home/./user chroots into /home). Note that usually there is no real
# need to do chrooting, Dovecot doesn't allow users to access files outside
# their mail directory anyway. If your home directories are prefixed with
# the chroot directory, append "/." to mail_chroot. <doc/wiki/Chrooting.txt>
#mail_chroot =
# UNIX socket path to master authentication server to find users.
# This is used by imap (for shared users) and lda.
#auth_socket_path = /var/run/dovecot/auth-userdb
# Directory where to look up mail plugins.
#mail_plugin_dir = /usr/lib/dovecot/modules
# Space separated list of plugins to load for all services. Plugins specific to
# IMAP, LDA, etc. are added to this list in their own .conf files.
#mail_plugins =
##
## Mailbox handling optimizations
##
# Mailbox list indexes can be used to optimize IMAP STATUS commands. They are
# also required for IMAP NOTIFY extension to be enabled.
#mailbox_list_index = yes
# Trust mailbox list index to be up-to-date. This reduces disk I/O at the cost
# of potentially returning out-of-date results after e.g. server crashes.
# The results will be automatically fixed once the folders are opened.
#mailbox_list_index_very_dirty_syncs = yes
# Should INBOX be kept up-to-date in the mailbox list index? By default it's
# not, because most of the mailbox accesses will open INBOX anyway.
#mailbox_list_index_include_inbox = no
# The minimum number of mails in a mailbox before updates are done to cache
# file. This allows optimizing Dovecot's behavior to do less disk writes at
# the cost of more disk reads.
#mail_cache_min_mail_count = 0
# When IDLE command is running, mailbox is checked once in a while to see if
# there are any new mails or other changes. This setting defines the minimum
# time to wait between those checks. Dovecot can also use inotify and
# kqueue to find out immediately when changes occur.
#mailbox_idle_check_interval = 30 secs
# Save mails with CR+LF instead of plain LF. This makes sending those mails
# take less CPU, especially with sendfile() syscall with Linux and FreeBSD.
# But it also creates a bit more disk I/O which may just make it slower.
# Also note that if other software reads the mboxes/maildirs, they may handle
# the extra CRs wrong and cause problems.
#mail_save_crlf = no
# Max number of mails to keep open and prefetch to memory. This only works with
# some mailbox formats and/or operating systems.
#mail_prefetch_count = 0
# How often to scan for stale temporary files and delete them (0 = never).
# These should exist only after Dovecot dies in the middle of saving mails.
#mail_temp_scan_interval = 1w
# How many slow mail accesses sorting can perform before it returns failure.
# With IMAP the reply is: NO [LIMIT] Requested sort would have taken too long.
# The untagged SORT reply is still returned, but it's likely not correct.
#mail_sort_max_read_count = 0
protocol !indexer-worker {
# If folder vsize calculation requires opening more than this many mails from
# disk (i.e. mail sizes aren't in cache already), return failure and finish
# the calculation via indexer process. Disabled by default. This setting must
# be 0 for indexer-worker processes.
#mail_vsize_bg_after_count = 0
}
##
## Maildir-specific settings
##
# By default LIST command returns all entries in maildir beginning with a dot.
# Enabling this option makes Dovecot return only entries which are directories.
# This is done by stat()ing each entry, so it causes more disk I/O.
# (For systems setting struct dirent->d_type, this check is free and it's
# done always regardless of this setting)
#maildir_stat_dirs = no
# When copying a message, do it with hard links whenever possible. This makes
# the performance much better, and it's unlikely to have any side effects.
#maildir_copy_with_hardlinks = yes
# Assume Dovecot is the only MUA accessing Maildir: Scan cur/ directory only
# when its mtime changes unexpectedly or when we can't find the mail otherwise.
#maildir_very_dirty_syncs = no
# If enabled, Dovecot doesn't use the S=<size> in the Maildir filenames for
# getting the mail's physical size, except when recalculating Maildir++ quota.
# This can be useful in systems where a lot of the Maildir filenames have a
# broken size. The performance hit for enabling this is very small.
#maildir_broken_filename_sizes = no
# Always move mails from new/ directory to cur/, even when the \Recent flags
# aren't being reset.
#maildir_empty_new = no
##
## mbox-specific settings
##
# Which locking methods to use for locking mbox. There are four available:
# dotlock: Create <mailbox>.lock file. This is the oldest and most NFS-safe
# solution. If you want to use /var/mail/ like directory, the users
# will need write access to that directory.
# dotlock_try: Same as dotlock, but if it fails because of permissions or
# because there isn't enough disk space, just skip it.
# fcntl : Use this if possible. Works with NFS too if lockd is used.
# flock : May not exist in all systems. Doesn't work with NFS.
# lockf : May not exist in all systems. Doesn't work with NFS.
#
# You can use multiple locking methods; if you do the order they're declared
# in is important to avoid deadlocks if other MTAs/MUAs are using multiple
# locking methods as well. Some operating systems don't allow using some of
# them simultaneously.
#
# The Debian value for mbox_write_locks differs from upstream Dovecot. It is
# changed to be compliant with Debian Policy (section 11.6) for NFS safety.
# Dovecot: mbox_write_locks = dotlock fcntl
# Debian: mbox_write_locks = fcntl dotlock
#
#mbox_read_locks = fcntl
#mbox_write_locks = fcntl dotlock
# Maximum time to wait for lock (all of them) before aborting.
#mbox_lock_timeout = 5 mins
# If dotlock exists but the mailbox isn't modified in any way, override the
# lock file after this much time.
#mbox_dotlock_change_timeout = 2 mins
# When mbox changes unexpectedly we have to fully read it to find out what
# changed. If the mbox is large this can take a long time. Since the change
# is usually just a newly appended mail, it'd be faster to simply read the
# new mails. If this setting is enabled, Dovecot does this but still safely
# fallbacks to re-reading the whole mbox file whenever something in mbox isn't
# how it's expected to be. The only real downside to this setting is that if
# some other MUA changes message flags, Dovecot doesn't notice it immediately.
# Note that a full sync is done with SELECT, EXAMINE, EXPUNGE and CHECK
# commands.
#mbox_dirty_syncs = yes
# Like mbox_dirty_syncs, but don't do full syncs even with SELECT, EXAMINE,
# EXPUNGE or CHECK commands. If this is set, mbox_dirty_syncs is ignored.
#mbox_very_dirty_syncs = no
# Delay writing mbox headers until doing a full write sync (EXPUNGE and CHECK
# commands and when closing the mailbox). This is especially useful for POP3
# where clients often delete all mails. The downside is that our changes
# aren't immediately visible to other MUAs.
#mbox_lazy_writes = yes
# If mbox size is smaller than this (e.g. 100k), don't write index files.
# If an index file already exists it's still read, just not updated.
#mbox_min_index_size = 0
# Mail header selection algorithm to use for MD5 POP3 UIDLs when
# pop3_uidl_format=%m. For backwards compatibility we use apop3d inspired
# algorithm, but it fails if the first Received: header isn't unique in all
# mails. An alternative algorithm is "all" that selects all headers.
#mbox_md5 = apop3d
##
## mdbox-specific settings
##
# Maximum dbox file size until it's rotated.
#mdbox_rotate_size = 10M
# Maximum dbox file age until it's rotated. Typically in days. Day begins
# from midnight, so 1d = today, 2d = yesterday, etc. 0 = check disabled.
#mdbox_rotate_interval = 0
# When creating new mdbox files, immediately preallocate their size to
# mdbox_rotate_size. This setting currently works only in Linux with some
# filesystems (ext4, xfs).
#mdbox_preallocate_space = no
##
## Mail attachments
##
# sdbox and mdbox support saving mail attachments to external files, which
# also allows single instance storage for them. Other backends don't support
# this for now.
# Directory root where to store mail attachments. Disabled, if empty.
#mail_attachment_dir =
# Attachments smaller than this aren't saved externally. It's also possible to
# write a plugin to disable saving specific attachments externally.
#mail_attachment_min_size = 128k
# Filesystem backend to use for saving attachments:
# posix : No SiS done by Dovecot (but this might help FS's own deduplication)
# sis posix : SiS with immediate byte-by-byte comparison during saving
# sis-queue posix : SiS with delayed comparison and deduplication
#mail_attachment_fs = sis posix
# Hash format to use in attachment filenames. You can add any text and
# variables: %{md4}, %{md5}, %{sha1}, %{sha256}, %{sha512}, %{size}.
# Variables can be truncated, e.g. %{sha256:80} returns only first 80 bits
#mail_attachment_hash = %{sha1}
# Settings to control adding $HasAttachment or $HasNoAttachment keywords.
# By default, all MIME parts with Content-Disposition=attachment, or inlines
# with filename parameter are consired attachments.
# add-flags - Add the keywords when saving new mails or when fetching can
# do it efficiently.
# content-type=type or !type - Include/exclude content type. Excluding will
# never consider the matched MIME part as attachment. Including will only
# negate an exclusion (e.g. content-type=!foo/* content-type=foo/bar).
# exclude-inlined - Exclude any Content-Disposition=inline MIME part.
#mail_attachment_detection_options =

Some files were not shown because too many files have changed in this diff Show More