105 Commits

Author SHA1 Message Date
Râu Cao
401b03cc1e Use Ubuntu 22.04 for new VMs
Also, remove the custom config image generation and replace it with
`--cloud-init` options.
2024-06-07 20:53:20 +02:00
f843a31e03 Merge pull request 'Improve mail server TLS certificate management' (#556) from chore/mail_server_cert into master
Reviewed-on: #556
Reviewed-by: Greg <greg@noreply.kosmos.org>
2024-06-05 14:49:01 +00:00
ff313525c8 Reload postfix and dovecot on cert renewal
closes #552

Co-authored-by: Greg Karékinian <greg@karekinian.com>
2024-06-05 16:44:18 +02:00
cfb379741e Add imap and smtp subdomains to mail server cert
closes #543

Co-authored-by: Greg Karékinian <greg@karekinian.com>
2024-06-05 15:55:29 +02:00
0c29fad404 Remove superfluous license header
Co-authored-by: Greg Karékinian <greg@karekinian.com>
2024-06-05 15:50:09 +02:00
416935d8b5 Merge pull request 'Upgrade Gitea to 1.22' (#555) from chore/upgrade_gitea into master
Reviewed-on: #555
2024-06-02 21:18:07 +00:00
2b6f81c5d6 Upgrade Gitea to 1.22 2024-06-02 23:17:16 +02:00
18496bb0da Merge pull request 'Configure akkounts for nostr zaps' (#554) from chore/akkounts_config into master
Reviewed-on: #554
2024-06-02 21:05:15 +00:00
d878b4208e Configure akkounts for nostr zaps 2024-06-02 23:03:06 +02:00
d31440d235 Add CORS headers to kosmos.social LNURL paths 2024-06-02 23:02:22 +02:00
6f287f14ef Deploy live branch 2024-06-02 23:01:49 +02:00
b77df3d0db Update email aliases 2024-05-16 14:34:09 +02:00
f7f5a0069d Merge pull request 'Add support for proxy domain validation to tls_cert resource' (#553) from feature/letsencrypt_proxy_validation into master
Reviewed-on: #553
Reviewed-by: Greg <greg@noreply.kosmos.org>
2024-05-08 12:30:29 +00:00
989185f951 Support proxy domain validation for Garage web domains
Also rename the data bag item
2024-04-30 12:23:36 +02:00
4cbda69a6b Add support for proxy domain validation to tls_cert resource 2024-04-26 12:24:17 +02:00
6931fe05d0 Hide Gitea version and load times in footer 2024-04-07 13:16:19 +03:00
b248ef70db Upgrade Gitea to 1.21.10 2024-04-07 13:10:10 +03:00
45159ad4e7 Resolve Mastodon addresses as Lightning Address 2024-03-31 08:27:20 +04:00
612cd0c55e Merge pull request 'Configure LDAP login for Mastodon (merge .social and .org accounts)' (#551) from feature/mastodon_ldap_integration into master
Reviewed-on: #551
Reviewed-by: Greg <greg@noreply.kosmos.org>
2024-03-29 09:51:42 +00:00
83380047bb Configure LDAP integration for Mastodon 2024-03-29 09:28:13 +04:00
8aebb386a4 Configure Mastodon user address domain for akkounts 2024-03-27 20:19:24 +04:00
a8c4f0bd0e Merge pull request 'Only allow ejabberd logins when XMPP service is enabled for user' (#550) from feature/xmpp_service_enabled into master
Reviewed-on: #550
2024-03-27 16:17:04 +00:00
12b4fb37fa Only allow ejabberd logins when XMPP service is enabled 2024-03-27 20:12:33 +04:00
263eb88b72 Add new env var for akkounts 2024-03-14 23:05:05 +01:00
25ee38fe27 Update kredits-ipfs-pinner 2024-03-14 23:04:27 +01:00
e701938442 Merge pull request 'Support letsencrypt proxy validation via CNAMEs' (#548) from feature/letsencrypt_proxy_validation into master
Reviewed-on: #548
Reviewed-by: greg <greg@noreply.kosmos.org>
2024-03-12 14:11:14 +00:00
309bc45791 Merge pull request 'Fix backup script removing image after unsuccessful pivot' (#549) from bugfix/vm_backups into master
Reviewed-on: #549
2024-03-11 15:35:50 +00:00
82a4af05ef Fix backup script removing image after unsuccessful pivot
If pivoting the VM backing storage back to the original image fails
(e.g. VM being down at that time), the script currently still deletes
the hotswap image, which means that all changes since the creation of
the hotswap image are lost.
2024-03-11 16:26:14 +01:00
4a8ab3abe3 Support letsencrypt proxy validation via CNAMEs
Allows to point other domains' `_acme-challenge.example.com` entries at
`example.com.letsencrypt.kosmos.chat` so we can validate from our side
without access to the other domain's DNS records.

Used for 5apps.com XMPP for now. Can be used for others later.

Co-authored-by: Greg Karékinian <greg@karekinian.com>
2024-03-11 16:21:28 +01:00
21de964e1b Upgrade nbxplorer, btcpay 2024-03-11 16:14:03 +01:00
b4ddfd19e3 Upgrade Ruby for latest Mastodon release 2024-03-11 16:13:48 +01:00
08c604962c Upgrade Ruby for latest akkounts release 2024-03-11 16:13:30 +01:00
089574d0de Merge pull request 'Update Gitea and act_runner, improve recipes' (#547) from chore/upgrade_gitea into master
Reviewed-on: #547
2024-03-11 15:12:00 +00:00
d19a8eebfb Update Gitea and act_runner, improve recipes 2024-03-11 16:11:12 +01:00
c0487d0e13 Deploy 5apps Gitea act runner 2024-03-11 16:08:22 +01:00
023a4261cd Update node info 2024-03-11 16:07:32 +01:00
fea65404cf Deploy new garage node 2024-03-11 16:03:22 +01:00
5139f242a4 Merge pull request 'Switch postgresql primary, deploy new replica' (#546) from switch_postgres_primary into master
Reviewed-on: #546
2024-03-11 14:59:57 +00:00
9c2aa9faaa Add info about required, unautomated step to script 2024-03-11 15:57:46 +01:00
164b974eb8 Switch postgresql primary, deploy new replica 2024-03-11 15:55:05 +01:00
6e4cc48068 Upgrade Gitea to 1.21.5 2024-02-05 14:39:12 +02:00
c2bd03dc23 Update node info 2024-02-05 10:14:27 +02:00
210a83a686 Increase max user offline messages for ejabberd 2024-02-04 15:47:55 +02:00
49db14869d Merge pull request 'Add Liquor Cabinet cookbooks and configs, deploy to production' (#541) from feature/535-liquor_cabinet into master
Reviewed-on: #541
2024-02-04 13:47:05 +00:00
000a13cec4 Merge pull request 'Set up coturn, switch from ejabberd in production' (#532) from feature/coturn into master
Reviewed-on: #532
2024-02-04 13:46:50 +00:00
5f7701c288 Fix missing listen IP for storage proxy 2024-01-29 18:16:07 +02:00
bcaee3bb21 Fix ActiveStorage not liking the local S3 endpoint 2024-01-29 18:15:36 +02:00
f352901582 Consolidate akkounts well-known proxying, add Webfinger and Nostr
refs #158
2024-01-29 14:17:15 +02:00
5c1c63f94e Add S3/Garage config for akkounts 2024-01-26 10:40:36 +03:00
98543f3e7d Configure RS integration for akkounts 2024-01-26 09:01:55 +03:00
7ab83d3d82 Section header comments for ENV vars
Improve readability of recipe
2024-01-26 09:00:25 +03:00
b5020efdd5 Merge branch 'master' into feature/535-liquor_cabinet 2024-01-26 08:19:50 +03:00
2763244fdc Merge pull request 'Config updates and improvements for new akkounts release' (#542) from chore/akkounts_updates into master
Reviewed-on: #542
2024-01-26 05:19:16 +00:00
e10e54c12a Deploy liquor-cabinet proxy to production 2024-01-26 08:16:26 +03:00
6114f0f799 Add liquor-cabinet proxy recipe 2024-01-26 08:15:53 +03:00
a2ec41b68a Add/use kosmos_liquor-cabinet cookbook 2024-01-25 17:42:56 +03:00
715fdbc2ba Node-attribute ALL THE THINGS 2024-01-25 17:40:42 +03:00
211a613e5c Add liquor-cabinet configs, deploy to production 2024-01-25 16:27:31 +03:00
d3c22ea787 Add liquor_cabinet cookbook 2024-01-25 16:26:41 +03:00
6047ea3f84 Merge pull request 'Add support for Redis replication, set up in production' (#540) from feature/redis_replication into master
Reviewed-on: #540
2024-01-25 10:19:12 +00:00
7d478f0183 Set up Redis replication in production 2024-01-24 18:12:22 +03:00
88e96747e3 Add Redis replica recipe and role 2024-01-24 18:11:58 +03:00
4b04aa7cd9 Let akkounts API proxy forward all API requests
... instead of just a specific subdirectory/path
2024-01-24 16:19:04 +03:00
2597e211ed Add new akkounts configs 2024-01-24 16:18:50 +03:00
f96faf9fa2 Install libvips for image manipulation in akkounts 2024-01-24 16:18:19 +03:00
c32e8bc9e5 Add new garage nodes 2024-01-11 18:38:22 +03:00
Râu Cao
24b22b8f91 Merge pull request 'Add email service' (#526) from feature/email into master
Reviewed-on: #526
2024-01-10 12:09:21 +00:00
456ec7a5fa Deploy new email VM 2024-01-09 15:57:04 +03:00
daadd9374f Use attribute for root dir 2024-01-08 11:35:04 +03:00
98acd429de Add configs for virtual email aliases 2024-01-08 11:29:56 +03:00
cfa7da2051 Create vmail dir on fresh systems 2024-01-08 10:47:19 +03:00
0d3082e1c8 Upgrade Gitea to 1.21.3 2024-01-01 16:13:15 +03:00
e1007f7886 ejabberd disco config additions 2023-12-18 13:23:21 +01:00
292366a77f Domain vs realm vs IP 2023-12-18 13:23:05 +01:00
ed998fc1d3 Use TCP for TLS connections 2023-12-18 13:22:34 +01:00
8a97ebf4f8 Use domain instead of IP, add TLS endpoints 2023-12-17 17:57:49 +01:00
ca3f06f831 Increase size of port range for TURN 2023-12-17 17:05:06 +01:00
1576a8e731 Set up coturn, switch from ejabberd in production
https://github.com/coturn/coturn
2023-12-17 15:20:11 +01:00
6e3fb80565 Upgrade CLN 2023-12-16 19:23:09 +01:00
Râu Cao
295d95c048 Upgrade Gitea to 1.21.1 2023-12-16 11:49:35 +01:00
789532fae9 Merge pull request 'Upgrade bitcoind, LND, CLN, RTL, NBXplorer, BTCPay' (#531) from chore/upgrade_bitcoin_software into master
Reviewed-on: #531
2023-12-14 17:15:40 +00:00
Râu Cao
404f492e6e Update node info 2023-12-14 18:14:37 +01:00
Râu Cao
574f78f128 Upgrade bitcoind, LND, CLN, RTL, NBXplorer, BTCPay
Also required upgrading node.js and the .NET SDK.
2023-12-14 18:12:29 +01:00
f4d1009473 Merge pull request 'Switch to virtual domains/aliases/mailboxes' (#530) from feature/email_virtual_domains into feature/email
Reviewed-on: #530
2023-12-13 12:06:44 +00:00
Râu Cao
69af908f6b Virtual domain configs 2023-12-13 13:05:31 +01:00
Râu Cao
e8880ded90 Remove vagrant (dev) node config files
No need for sharing them, since the actual roles etc. are defined in the
Vagrantfile.
2023-12-07 10:37:09 +01:00
Râu Cao
10dd3bf16e Add new RSK testnet node, don't serve from current one 2023-12-07 09:55:29 +01:00
Râu Cao
ca580bcfe2 Set email report contact in production 2023-12-07 09:37:37 +01:00
5b0cb438ba Merge pull request 'Set up SpamAssassin' (#529) from feature/spamassassin into feature/email
Reviewed-on: #529
2023-12-06 11:28:14 +00:00
Râu Cao
5a4cdf9c30 Prevent local users from impersonating other local users 2023-12-06 12:27:38 +01:00
Râu Cao
b3f2ca415e Set up SpamAssassin
Scan incoming and outgoing email for spam. Use a local Unbound for DNS,
so we don't run into blocks for RBL queries.
2023-12-06 12:22:24 +01:00
Râu Cao
05ccbcc58f Merge branch 'master' into feature/email 2023-12-05 18:37:43 +01:00
Râu Cao
e3c4bf8969 Update node config 2023-12-05 18:21:26 +01:00
Râu Cao
cc6cebb8a2 Increase TURN throughput allowance 2023-12-05 18:20:27 +01:00
Râu Cao
4dbc960eed Switch ejabberd node handling TURN
Should use the same outgoing IP as for incoming
2023-12-05 18:19:48 +01:00
ce47072b0d Merge pull request 'Improve VM backups, configure backups on "her"' (#528) from feature/backup_improvements into master
Reviewed-on: #528
2023-12-05 17:18:40 +00:00
Râu Cao
7805182457 Change borg backup default interval to 3 hrs 2023-12-05 18:16:15 +01:00
Râu Cao
769ac4a081 Support node-specific borg repo config 2023-12-05 18:09:44 +01:00
Râu Cao
b1763cd032 Pattern-match node names for VM backup exclusion 2023-12-05 18:04:57 +01:00
Râu Cao
c746b38ebf Update node info 2023-12-05 14:19:52 +01:00
0a58cac0cf Merge pull request 'Set up DKIM signing and verification' (#527) from feature/email_dkim into feature/email
Reviewed-on: #527
2023-12-04 12:42:37 +00:00
Râu Cao
42c04538d8 Set up DKIM signing and verification 2023-12-04 13:40:37 +01:00
Râu Cao
c9ad3c2d18 Create/configure common default mailboxes 2023-12-04 13:33:23 +01:00
Râu Cao
fbad0bf896 More explicit postfix configs 2023-12-03 18:33:12 +01:00
Râu Cao
8a7eeb1dd9 Change INBOX location 2023-12-03 18:32:55 +01:00
150 changed files with 5017 additions and 16130 deletions

View File

@@ -37,6 +37,7 @@ 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

@@ -33,6 +33,7 @@ DEPENDENCIES
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)
@@ -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)

View File

@@ -1,4 +0,0 @@
{
"name": "garage-3",
"public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtRSB8/ObjvQq6WuOVS/f\nypdX/2fLsUlt5tQ8GNuSY9rSM8gdvcXUvnPlxthZO4yvcPX85wmtBZX8fRJFdkJg\nYRCJbuVKO9sLTq8OUWXYpfU1q10FUhl034zxOMslpxVB6toirnk025vyq9jbuKP+\nYO+c40KZr67mgm0hveJfylayfiKP1HGm4HrV0maFivCgC8D+MPDDv75CsqRe5WSc\nh2CoauDJwVlhKZ92yq87ugGBhJJRUGOQZcfEvkUGj/HNAS6tuHl8YmVmhO8hBdee\nNto6RF54E1zB80R9oT/qitw23miEyUcHHVxhTR4tTWflZgd8l4wDOhX3Nf20xknu\nFQIDAQAB\n-----END PUBLIC KEY-----\n"
}

4
clients/garage-6.json Normal file
View File

@@ -0,0 +1,4 @@
{
"name": "garage-6",
"public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwasYgWLM8ShvirFiKRE6\nGWqc3pMlvcrk4YnWAUW5Y/H26EnyexxWNfnwlEcq8thJ3M3hs7zkoF3Yk4uqX869\n4/niYqXwYgeE1K3gzLp4K1+w3yVupYAFVFStVEHJyuMlLJ+ulDEGvNdQDuIfw7+E\nr6DcDLa1o92Eo0wL1ihYyMilduH0LdFTixL+tEBXbbPWBa3RDJJCFsRF1+UC6hAH\nzmaWL661Gdzdabxjm/FlGUYkdbDqeInZq/1GMQqv+9/DcNRkWA9H7i4Ykrfpx4/2\nRZ8xtx/DbnJVB1zYoORygFMMAkTu5E+R8ropeI7Wi77Yq0S7laiRlYQYQml3x9ak\nzQIDAQAB\n-----END PUBLIC KEY-----\n"
}

4
clients/garage-7.json Normal file
View File

@@ -0,0 +1,4 @@
{
"name": "garage-7",
"public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwoAigZUSwsfbBHx2PQ6W\n38Ght6eCvbpW1lsS58hTieRmRn+pgZVjvixhsBh57rUasCjaBywXk9BpNj2Foxck\nReHeoDI0RHsgniClyMrYj80y2NhoB6J8NB+cHkhdzIKplm6AH6M5xaAedtZU639a\n1nHMtpDlJhzgIYsiq1q06Aqd1w0Z9tf1RXQ1WvMDhTY4wlE5RZ2epBb6Usnlbjo2\nSqCIGIjRLmZxdsSWoiUUTlVPdUCzTNsN5G/ZVdRswhgseDmVJCIkK2Aji/XzhIrR\nh4RvUv9dhFemOVsFctJ/dQILXz5MZLUgakKf970M5R/Zggv//pqRSsYcB2UfaBpV\nLQIDAQAB\n-----END PUBLIC KEY-----\n"
}

4
clients/garage-8.json Normal file
View File

@@ -0,0 +1,4 @@
{
"name": "garage-8",
"public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt4hXODzgHsIeWxXJm/F6\nSTFJ8JC89mWru7pOFzPWenOVMHgp4UpUB4rDTwQqojsWTDiq0x3ckUyOPw3Nj0jv\nxP4MMGS4SI0oRSJKzrYYss0hgUDTOBBd+Wxn0UiNEpN/PfQo9VZj9v/jak57cz7z\n5+rpl5v27fhgUIChjsHxdy+EamvCrYc+1JhyrLOlwlt8JxkZ8UPhoeZLWAbDgGLS\nEzHWSSVtBUPK+KYmVb2OK4lB56zPfek0U3gKN+04a1650jzOit8LzE6NaT180QDv\nX+gG6tk53vSXDmkBXsQ1mtB8aF+HaEG2Pra5HyihlweCPYdJT+e28wpq6+P5l3YR\ndQIDAQAB\n-----END PUBLIC KEY-----\n"
}

View File

@@ -1,4 +0,0 @@
{
"name": "postgres-4",
"public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6fPxOZeKloF/EgYvU0k\nOwv8bJjsCQcWaMTPle5//mRTszA6PM2z9RI+Mfr45qxTlsL9pQY8WJOWF6QOK31x\nszuqcr7oOjtAhrLI8f/oNDEDjcx325FqG9gNKQEAD7d4zodh+PhDe6x7GIyIS7lG\nIcD5Zre9iDwv8FGLR+5GLqS8SJOPL/wJkQ8w+N0f8YDFw81kiTta5NLhAx3fMDs0\n2kmoNlbmKlNZTtLjCfCV+/pa9oY6wycjck3GvobiFE/4cWaNkeGlPc+uAwlfmrOv\nHy0tq1XBX/BCvE5kMXmhnMT23JXjm2s2PgCLgEVGAXilXk/T597KDm+z4oBpAQma\nnQIDAQAB\n-----END PUBLIC KEY-----\n"
}

4
clients/postgres-6.json Normal file
View File

@@ -0,0 +1,4 @@
{
"name": "postgres-6",
"public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtVzM0fwlimmq11jTGTko\nK87LRYSar61tNF3qVWp9axNSMa6BSxVark9eYOqY4eLh/5vJVDqXDFq30/IUWg40\nH8hHWaOEvQrP2dm/XFw1RmunfbfN9gN07TuhaT3xFD5t+jFBuOSoJ4cPnFIABuVt\nFLrjgtYYjtZe5hGE9ZPmS7o2ATM5EU9mxeQ+TkgDbr8StvSPGdZ1ykhagf1pegGU\nRIfZ+4ZKzyDUAq+fYNhIbmlm5h2gP+XdtakPy43j7n0iN1vwDgBqJ2pdaVs/GcFf\nvaztoltguoknI2NPSez1N217asTTLuth0nHxVXiKCVXnqwDjxgWmuP6X2B7VYjyc\nxQIDAQAB\n-----END PUBLIC KEY-----\n"
}

View File

@@ -0,0 +1,4 @@
{
"name": "rsk-testnet-5",
"public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx/UHlgcSeh9Do7CTCKXC\n/4/aO2OvT+ijDVmrMYCNtE4sMeuFqKPnV1zxJZmRm4VNhkSQDkdWYD+6XvuFYW60\nyjB/N6D5lLlyjG4HD6fTkfh0K6f7t5mOYV7o4T59OoA3cBZuSROjtWmJ8jEFJ+k9\nII2kcyhPQcFN01ckzvZKRSPbVRccMoc+AKTjB3ZUfs/ERtlVoDrK4jEHluXOxUJO\nBKCcLonjJuLlpRLh7QfKrKFcR4idn5Ir43R6aSUesI/ipKwKsXnR3Bu7vXp74VF3\nMJ3EkdSBG+qJzy51fbRfQiUPAr/vSoVQZwW7FkIhIqqLkMaYCymn7qKfTGujoNU7\nlwIDAQAB\n-----END PUBLIC KEY-----\n"
}

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

@@ -1,37 +1,72 @@
{
"id": "akkounts",
"postgresql_username": {
"encrypted_data": "W+Ia820+uYCAED9LRkQ1ZVe//56GRS5u0HrG\n",
"iv": "NpuVENC7C5FCjsEz\n",
"auth_tag": "KbqVv27nTc4qm7kzRWcjUQ==\n",
"encrypted_data": "bDlOkEmhvMgyVzPeTNUzYnzRLf3T9cc0cDxt\n",
"iv": "GCCUoqU5pxQ7fGkv\n",
"auth_tag": "Q7mrSHIBluMe3CGVmoR86Q==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"postgresql_password": {
"encrypted_data": "gPzUikJ3vBhjEzor0ie2341VPLRHNIvGvuD+HBwldw==\n",
"iv": "Jsnldm8Bx9IzXMNy\n",
"auth_tag": "63YXFGVxHn23X+/11qwTSA==\n",
"encrypted_data": "wD0HtdsNe/hl4ZaOy8hyr2k4z8TXQrrSja3KNVE47w==\n",
"iv": "tb5yz8WDer0CsGvJ\n",
"auth_tag": "/+K2anuCff/6M7Pu70Smqw==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"sentry_dsn": {
"encrypted_data": "3aC1Nc+WiJIn+jc4HY4Rb1WAqCqEurbOLXhbah4zSIbVIaNGEKzaoC+IA+qi\nV1jAVxbE0A1w91MrGE6HNa+oMjiTMurYx7JzVBIpCm01rgo=\n",
"iv": "SxEbTBYY2Pa5BzAF\n",
"auth_tag": "zGkIpM/aeyuNm2F0I3VAcA==\n",
"encrypted_data": "jCz681x0WVixHYZUb62TO+1cgyJMiJ2UMqWcaztx57yDBOIiKW3oSZjuXdhP\n9WCesfXQF/lgzITZno3IKDqzlKjWgbGLC75y8FLguxidCHI=\n",
"iv": "IRNOzN/hLwg1iqax\n",
"auth_tag": "eg9dWnEK04JDb94e4CFa9Q==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"rails_master_key": {
"encrypted_data": "cWOeQYNzOjgDNi7ZpkMC/jN7nSPyODYRhA6EIhhihzPxkEDt+/4HGNAhLHGK\nlJiQeRD/\n",
"iv": "Svsvx9gsO9OQs9RV\n",
"auth_tag": "mXVNNo13F6FddhWnri1yHQ==\n",
"encrypted_data": "nUB77VLRp41rluH7hLBwQqPtnh/HsmfLr2VbcIZHWawL3o2TGuY+mj648f9L\n7XsEpgqY\n",
"iv": "fpdbDitqTRHxEKiv\n",
"auth_tag": "I44fn8Ott3L/Y5LYr56U/Q==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"discourse_connect_secret": {
"encrypted_data": "BQcE5fUkiqJyuOR1dR9vNyxWzgWGX1Wl1WINJDGJ1sJiajrgAspPgDt0dX5L\nhxG8CQ==\n",
"iv": "UKpt0F1FODuosQ9u\n",
"auth_tag": "MLgv0jR9MhWGmQNUkA8GUQ==\n",
"encrypted_data": "ENtMn+1XTVFmdEZw7LU6WGoMbSZY654ggm3vPACGfFgqo6r0LhG60c5OTdqv\nZvT5/Q==\n",
"iv": "bL1BmvRhgxFqSM1P\n",
"auth_tag": "sEBZzGWwwYFHn+4B4SsyCA==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"lndhub_admin_token": {
"encrypted_data": "4LPGFoARzI8UYnsJPIk8sax/rAA16pUULEZWn86e2C7L\n",
"iv": "nvjXrOwgfgutwEVw\n",
"auth_tag": "A89RUf1sdcS3FVscNPWYLg==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"btcpay_auth_token": {
"encrypted_data": "ky5iWYF06os0Ek6vIRzWqMTekqJhCOh/Q9DTDIeKhSyk8TnT3O71lCNEt1F5\nXCNq6ux3V6oyHVLWj0o=\n",
"iv": "zk6WnxsY89oNW1F9\n",
"auth_tag": "FAIMXKvQ1T7QKezVSNJbwQ==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"s3_access_key": {
"encrypted_data": "KfhfEGwPjOonlz6rpnNTinXFPqX/sIbqQn/aby0UDi/G/7cvEcOiNcCkfuSz\n",
"iv": "Q3rg06v6K9pUDLDY\n",
"auth_tag": "G5ugdlJ896KtYtObKLclJA==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"s3_secret_key": {
"encrypted_data": "N8s1OoDrYXHjqSydQA0kY7dd68Aelq4+/cgmJlYfP92u4YA17V4TR7fsvQZL\nkqjuUSClNYPc0XiCwf/5gxVirE9AO6OmmvSV7lUyu4hcEY6unrU=\n",
"iv": "bXzIVWnX6V0P6PRb\n",
"auth_tag": "1EOjCfsX9P6ETjUsgBvBsA==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"nostr_private_key": {
"encrypted_data": "Sf8PEyQ0sqcgxddSlIDxLOVzPjOkTFObsYuTgcxkbEV7igrati4e8QVVUEBD\n1yoLJXelp8jlCr28Ectci29jc53gYSMTLSQsw97uYas2R0dGCqQ=\n",
"iv": "+1CIUyvIUOveLrY4\n",
"auth_tag": "GDqS+IuAIfMBmHIeFXaV7A==\n",
"version": 3,
"cipher": "aes-256-gcm"
}

View File

@@ -1,23 +1,30 @@
{
"id": "borg",
"ssh_key": {
"encrypted_data": "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\n",
"iv": "3uagVTqoXUcWvs9W\n",
"auth_tag": "s3wlsnLRHCI2NjC6/ZwbiQ==\n",
"encrypted_data": "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\n",
"iv": "bhJZlhYQTG/xAvuY\n",
"auth_tag": "oqYQGqNaSFqpxfoJi/oOBQ==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"passphrase": {
"encrypted_data": "wzSJQ+VfZuXmqrL3xW/LxiUvF/B6EYHAQtmhrJjt2oMT1G2OEgp5\n",
"iv": "BqTyfQwKKCTOn3q3\n",
"auth_tag": "sh1e8UuQSrq1o5G0O5fXCA==\n",
"encrypted_data": "5n1l4Mi3ik1RgcF+c71fQbTS1kAOgNaGEcpdKV11uDbzHDVuw21S\n",
"iv": "N+AVJrfPxoRJlWOO\n",
"auth_tag": "x5Wr3zuJhCXzTIl3gAOA0w==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"repository": {
"encrypted_data": "Ezc5YMp0VM82dlq0+ikk2xZeqNHi+XETlsc2cDlFG/NxY408JO3ErPDEa9d9\nzud+jcCt/01GKqPdslGhP3jsUUb/f3kWMkTWqGkyWXV1121E0uHwyrva62NT\n5A==\n",
"iv": "QtNBUjJ5NrQS0JD7\n",
"auth_tag": "ZQImzlvHWwX1OsxMZK1jGA==\n",
"encrypted_data": "Jz0IoAeeeF5lXMTgpkanRqshOxUW0IAJ8tUYFEQckWB13tmsEwNd+val8g+d\nkQ6NQMg8oLRtPbDOi6bTgmTykFrYW5JS5EiD2/ynQQktWA/ZIxnyuoHocX+A\naw==\n",
"iv": "BGl1aUBCHzuG61H+\n",
"auth_tag": "mlYt/CKamtPZTaESlG/lFA==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"nodes": {
"encrypted_data": "v9vXGwyAu2fqj5blo/6Jeht3R7SLlxMSWCuC2nTlURBODz9fled1z/LAoABc\nOaVLXKrgHYUnYgriSF7Q9zemrRnrcsPmqKFVLKqNDIjjyd1LnxwdopG9EGxD\nKNVY3GQI1L511kY+0ahZj6OJ63o0MSccysabSnptWNHCsD2eFh+77oMpYfYy\n3OWWLOT4kzK1lbNDmI8IM6JywLE=\n",
"iv": "r4LctfXGF86FNXbZ\n",
"auth_tag": "P01f5Vcxz8EyY6BohQWzOA==\n",
"version": 3,
"cipher": "aes-256-gcm"
}

View File

@@ -0,0 +1,24 @@
{
"id": "gandi_api",
"key": {
"encrypted_data": "d3/rJMX6B9GuzUt0/mIk/lgQ3qGyQdbNXH6UEm3ZX7DeSl+rbW9FPJCRWg==\n",
"iv": "15YVAYla7PqqVOab\n",
"auth_tag": "xQSq+ld6SDOAER07N4ZkUQ==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"access_token": {
"encrypted_data": "geQwcNosiJZmqbbMpD/I+a2yueBzpV6C8Rb7vrCD8kR161ZRjvqLe+g/1XpT\n2/65wKYDMTrdto1I030=\n",
"iv": "1sj58eyooOZ8FTYn\n",
"auth_tag": "yBNfgWXaToc06VDLly/HUw==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"domains": {
"encrypted_data": "p5rIQTyCE+0d4HIuA4GKEAFekh7qEC4xe9Rm/kP0DyzY83FO0/4uKIvYoZRB\n",
"iv": "LWlx98NSS1/ngCH1\n",
"auth_tag": "FID+x/LjTZ3cgQV5U2xZLA==\n",
"version": 3,
"cipher": "aes-256-gcm"
}
}

View File

@@ -1,9 +0,0 @@
{
"id": "gandi_api_5apps",
"key": {
"encrypted_data": "+tcD9x5MkNpf2Za5iLM7oTGrmAXxuWFEbyg4xrcWypSkSTjdIncOfD1UoIoS\nGzy1\n",
"iv": "ymls2idI/PdiRZCgsulwrA==\n",
"version": 1,
"cipher": "aes-256-cbc"
}
}

View File

@@ -1,58 +1,58 @@
{
"id": "gitea",
"jwt_secret": {
"encrypted_data": "HHKq1HcxV9uC0aBdkn2AAA9C3dn2o8DnL2uDtZBf+epGC8sOko6/BSvsm8wV\nuG7yVmeFajgyCePSv4M8Or8=\n",
"iv": "raypiojdRL+DkiDa\n",
"auth_tag": "JZmWJyLTHNHAHNufRizL+w==\n",
"encrypted_data": "wMxs1Ec4vKRSzFtL2KuU1XfmR1t5KDx/7XBbI7V0QfgK+JwYbxU5w6feQCBE\nxOMepAXVUwU7RxPZ+hwQgPg=\n",
"iv": "F4vtuOL2B9e9LQnb\n",
"auth_tag": "NHATxHbr+3Y3Kxa68NwnjQ==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"internal_token": {
"encrypted_data": "VFez8gOv5hnpBkURlufdPHvfQsL+lFlL8M9vywgKEi4XrXcNlDvoKKqdtSMv\nxGuoKqF/4NFcl2X3JRwp1j5iut+Jdg5CpnVVQLWKHc022LjD7K9nRsdmiD9Q\nLsLnU1Trzqg8VZS2ryqdjI4elkgoc15lmXwJvTNgRUzDqw==\n",
"iv": "q7H4q7kBfRt4floS\n",
"auth_tag": "vyd4ZwVxeFTTfvjI4k5irQ==\n",
"encrypted_data": "mlvUtIjs6kcv7XcYCUOgOE/kDSE4Ts5G+CZuPrJapW9XwkebmyOnHJvXdihY\np/chUtar0pNB5Q16LeeZF9KrzOiDo/OXb40TPUzpsB0/607zV1z829STd4l7\nu5g4Zur13nxC9jT0zQL9QgDEobYdjgf/xu1BXxFT+Ue3lQ==\n",
"iv": "25+1a2OJYFNxdf1N\n",
"auth_tag": "aF8Gn6Mm7AwLjbR8cDnitg==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"secret_key": {
"encrypted_data": "7tD4E/5AuxxmNdu4arWj/BBNTUv6JX+m2ITbcLfE+VE2WacsCZUEyi1d1v0B\nyujQ9bljJn3z0zV4PxKFJILKjQb35PSiA8b86X/75Y1B9Gl64ds=\n",
"iv": "gE2O5aN+Nea6VXi7\n",
"auth_tag": "3+EmAUgBBDyChRBHsUtLig==\n",
"encrypted_data": "xQuHuijNHoo2WicM2UvSGpwPHd0UilxlIl4BM2Rgyih5bdhjxB6UtUcY9uJQ\nYgxEd7y7R5+XhUAu87CEs4qAGtguDDxGtSGwgTSopvAYZewPFLw=\n",
"iv": "Kxwqagjps8kP7Dhz\n",
"auth_tag": "WGz5TzBzksf36hKPzBZTQQ==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"postgresql_password": {
"encrypted_data": "mWN2sTOjZ1EPUH/KAJ8owoPM7v/+IfIHEPACN7gFDrqG8dWGjfiu+fvILw==\n",
"iv": "ldm57dVSdiPnk5l3\n",
"auth_tag": "D+r/0obCYWx53vIeUDPGMQ==\n",
"encrypted_data": "ZziPtXhQM/TQBE+077smnjEPzfJOSo9Cj/CUnG/Be1AN0UAfielf68EhLg==\n",
"iv": "iBdSrY15vOc3eycF\n",
"auth_tag": "km2CkraKlpOygaz7Xy548Q==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"s3_key_id": {
"encrypted_data": "AvlsAInGyPMvHle5YZT3EHMTG89PggqmFaddvHSQLEkvI2EycktxJ/btjGOP\n",
"iv": "qGkILPp5EWc21wwa\n",
"auth_tag": "eIpCgZAnWZR7nlllj+IXMQ==\n",
"encrypted_data": "1j0znqBgNbHMyJIf51MmfkjkpU3SPv+EL8F30mrfQ44vsGziyeiWfp91hGUM\n",
"iv": "dzJM1EX/X8Qy5KbR\n",
"auth_tag": "2YUCCFG/oTph3svFYhhYzg==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"s3_secret_key": {
"encrypted_data": "TAo4ViF7cL+ibIuHM77irZW08ilD46S8N5BV91gc2wegvHpHqLHw5zrsDxfu\nDiJHGUfjge/NBOGN5VSKKC0nFfMJ4sLPxVSiKyON4RMBSuzSqmo=\n",
"iv": "tjK8XdaCZOdLUHyo\n",
"auth_tag": "Qu1z6e1/4gPIyaCwBjaWsw==\n",
"encrypted_data": "7P3JUyl0LsGuGi8GhSYdXHm4bQhnkGfSrbEMGyfzjSYB5hqm17kYZwNbNA0O\nIUmJ6Kq9Nby7IFTd1qFo7aA+dXuvxJD5QXO8T5E+D0xIaWMHPco=\n",
"iv": "+ivHjYpQG/3gQWAi\n",
"auth_tag": "fftxN0Z/Kfrn+oFk07jKYQ==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"s3_bucket": {
"encrypted_data": "NTp9+KyzlblporEwM7SEwoClXu5cI10SfVrJ/uywcf/x2l8=\n",
"iv": "TFTeQ8yKUhblmrFK\n",
"auth_tag": "L9nrXEeJhxcLO4YgGk4zpg==\n",
"encrypted_data": "98UnmjwIlLjNFQojZlQRMZAWpI/7s9xJkgvh4sU5I2jWmYk=\n",
"iv": "zLck9Dp6OP+L3BwX\n",
"auth_tag": "Zc5G6bd7CbZfDCZ31YWxMg==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"runners": {
"encrypted_data": "yTCk4/hqw/4vEaXobdYU4vZRxErNp0GX4qDMuHwdr7UOQk2qQ8O8j44njPv2\ncKcIm6CQiip+GRuvl6+zETd8gctC0W14n5Rfep4zQbMp/BW3ypGambVk6z1m\nRnT4dMEl32rwcXG8c3w+vAFpx8smrK5iyy4ca0ZijC+eeysk4OAwn0XkvQuV\nB1Jy9CmVm9xiZ6sXaiU13tTry8A=\n",
"iv": "+biM/42g5doJNOax\n",
"auth_tag": "WwNgd6aqm26GcekYVOeBDQ==\n",
"encrypted_data": "f0RRLCrGT7LDUEXcM6m2dJ7C95UPqVZz9dfNLsYa/3SZLDcm1p4FDIy0Su6R\nrXMoAI9IdLBN7/BDMMvqkULEq3Bx5vXn+oTUsUYuKxWmvKEUhC4virOApxh6\n5GbuqcOEPKaf9lHByL+2HKdAmJMzVRGD0t78ePS2pU4H6IFnS9V1p6opOEPr\nzTJ+0PM98eQ/voFKDHGNHUqgDs2qu9wUYNmcHe1eSimFdJiOCN0Mlszu3HL0\nXkHfrGbLrcW+8Ol7dTXdDJB7WAd3R3vddoZQ+mrwzGGDeSMm+ezeMzAX\n",
"iv": "NtZ9SbbscX47BXGH\n",
"auth_tag": "ZGBzxjNFB5WPnJCpdFwtAQ==\n",
"version": 3,
"cipher": "aes-256-gcm"
}

View File

@@ -0,0 +1,17 @@
{
"id": "liquor-cabinet",
"s3_access_key": {
"encrypted_data": "TKYUWVboQZUKvw4bqrKsL28dH2DGR5iDBQclAwm5I7GqkxFfkG2d91qLv+BA\n",
"iv": "B8YYzXeFGxMG34WI\n",
"auth_tag": "HOIfcpJOFYIVvf5o8lk4mg==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"s3_secret_key": {
"encrypted_data": "GRqGJkGJ/f0zQVtO0r9TcXBqlpnfC5PiwTZK8QmsqEhzQI6U67NAf62QqTgl\nGVI1h8G5ITgC3l0xVhcvH6m2bcs9fjNzFIqnhoZhzGwEt51A5Zk=\n",
"iv": "UAlmoUWLedpd79xa\n",
"auth_tag": "2F/EJhY5/59dtFFwkd106A==\n",
"version": 3,
"cipher": "aes-256-gcm"
}
}

View File

@@ -1,79 +1,93 @@
{
"id": "mastodon",
"paperclip_secret": {
"encrypted_data": "orOIbqFANPCkd4sUTCyyoh4z1o6SBudgH4wKJudTo9dANaHGhWcBUFKrhZi1\nMJTBQx/d0hiDI1P2XN3h+hROCg3JJ8OClUSJH9CfN5GlbWvXh0Nhq7hqy8L3\nLAPL+uigiXI6ObrnKQoD8LeJIB46233uwaCA/7zB6gah0ExJ2DXGH6qq9JSS\nqmTFiy+hT+VHGrUo\n",
"iv": "U4E4NLYLkP0/tTTs\n",
"auth_tag": "WKQ+pDPZp7B791lhC5j3iQ==\n",
"encrypted_data": "VJn4Yd2N7qFV+nWXPjPA8Y2KEXL/gZs2gK5E3DZZc9ogFXV7RtpDtq+NKGJU\ndpR8ohtEZvkyC+iBkMAlnS1sSVKiLdQ1xXvbzkj04mYgjnLvwsZ19uVpBGwR\nt/DON7Bhe5Fw+OyrBQksqNcZQSpB9sMBfgA1IgCpdVGHQ8PmkMbFTaZZYcoF\n7gg3yUw5/0t3vRdL\n",
"iv": "X5atp/KaIurfln/u\n",
"auth_tag": "mVnBoUb5HwhXNYUddJbq8Q==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"secret_key_base": {
"encrypted_data": "vweClhdY8SqQkK+p0OYUL2B6Fsz5eQDpEYWCtd/eRJfwwYAObbLcMWRC6MwE\neQVMw59bOqYc3RBuv/+WPLtENazA1bYCXBXQr1J6xqjJAz0Mo6KbRyxy5n78\nv8q6RSiao1VVIUXohtFlQgWeV6x5sz34bJxjlHinKvKsgiGXiuVBxYUUfzWQ\nuzrGug09cpZBqfpc\n",
"iv": "Z0/csEBH5/X1+MR+\n",
"auth_tag": "fTvBN6eovi3JVEK0ZX97Nw==\n",
"encrypted_data": "d0sNREFhzQEJhkRzielbCNBJOVAdfThv7zcYTZ1vFZ20i/mzB9GWW2nb+1yn\nNFjAq8wCLpLXn9n3FClE+WOqnAw0jwTlyScRM5lzjKI5SxHKkBQHGyFs2AF8\nqFjEvpiqxhjsc4kNOJGO8DdcyHuulXyaO9fJg8HDnU1ov1vSSuTc0ABKgycY\nMq/Xt10UXnhP8cPw\n",
"iv": "HFT7fdGQ2KRJ2NFy\n",
"auth_tag": "C55JT2msLQCoI+09VKf+Jw==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"otp_secret": {
"encrypted_data": "o1ts1bUgPIzFQXjJ2MpBMLntWkyPxDaJAaU1K3WzmNMXnw5MVlkKKCEFVccd\nPss/MwDuBkbNPhri3ZkH48m9SiayWETVYvw5GZzcVsw4TeMu915O44lfl9tX\nW3XHU+DBps1BVH9535R4X9M1aFW4W4XfwHtS5wcrZqtVhNhS3NSgE4JpN/Dz\nFdcFAOhflnt8fIAN\n",
"iv": "QLsxmIlX1NpxMyHz\n",
"auth_tag": "j1h/PvIoqshTBN5c5IaAsA==\n",
"encrypted_data": "1iH7mUkaUzyn9dfDwMdiJ8X059qWSUO3DqivsOFfI1f44nMnzllaYPu6nh8O\nNLNCOzvsSAonhhaq1X+foOdyPIG2mGhE/juKveDD57/AdZAayHWsbsQlPC4l\nwdShz/ANrq0YZ/zOhpT2sZj1TZavW+S+JlxJFX2kP24D4dUzwG0vNj7522+Q\n9NAApJdUte1ZYF/b\n",
"iv": "00/vs5zTdoC19+pS\n",
"auth_tag": "3cjYqebMshnmWkQ3SdRcCQ==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"aws_access_key_id": {
"encrypted_data": "YQHUx0GugKu0AtlbGLRGocFEhTGAghWA0DUs1Nxs4Hd3bTIp4lyM\n",
"iv": "54zt2tkQhHtpY7sO\n",
"auth_tag": "ofBJx3QDsjHe66ga3nji8g==\n",
"encrypted_data": "krcfpxOrAkwZR2GP4glTaFg2dw/COw8BO8I+KICqyl4bvpL5NrB9\n",
"iv": "paoDKp6EIU8bjxzF\n",
"auth_tag": "p6Pt/tz5dgGXzW5cO06nBg==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"aws_secret_access_key": {
"encrypted_data": "FAz6xZ+wsCz/KFA+DK6f4V04rxJt+9U/yXUGF9tvce0VqB3scH+T0KDDn1/n\nZ/0G0Tbxt2urRPbPUdI=\n",
"iv": "iapSpeM6lfDMIfNk\n",
"auth_tag": "HlkwUnNeJlOUrZ3ieN5xAQ==\n",
"encrypted_data": "aQySCT7gxeNiMMocq81KtIi+YzrZwMBeTd4LrRSN8iNEikWReJrrfagBwozy\n+Gfdw4bMGzY1dhF1Sl4=\n",
"iv": "R/hvvOvmqq/uoKbx\n",
"auth_tag": "QBJY/3+OprBXO/FSNwv2OQ==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"ldap_bind_dn": {
"encrypted_data": "wDPABdL+DlXz2WWV4XwW20kM4EWPSwc/ajBmbdYMnjFau6c76CIBpbFhrFoj\n3mwDbHz8cgOnLNvozXSV4w6N7URCN/mWWTBHNhd3ppw=\n",
"iv": "8rQ0M4LT1HbCNpq9\n",
"auth_tag": "AuO5R6WCtd75TGJNfgFSCg==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"ldap_password": {
"encrypted_data": "y0t8RuptVYiTKmUhaAWsC4c2ZzhQsYeVLeMPiQBn+Q==\n",
"iv": "mixYzDKkPSIDQ/l+\n",
"auth_tag": "DbLlZG7rlgBmyCdJ3nhSYA==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"smtp_user_name": {
"encrypted_data": "ivB09/mCRrUaz9X4NFRBiqytjgy/vxN5Nha7gopFq5eSu9v4K9MkaLRqHh1I\nYw==\n",
"iv": "a8WKhRKsUjqBtfmn\n",
"auth_tag": "ib5WJNNaO7bRIspdACmOLw==\n",
"encrypted_data": "Ugc29HUFcirv6jOOlYNs9uvmhfwa2rG41im/MusCx0Vu0AZKcdy0krGi/kCZ\nKg==\n",
"iv": "ZlDK854w+vTNmeJe\n",
"auth_tag": "Nj95g0JMxrT419OLQIX26g==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"smtp_password": {
"encrypted_data": "FxPz2e7fUNqcAu+DDJKlqn8rcSBLmnzigTFf5moZlQ1zz4YVl6pqHisa22Qz\nbfUx9rjU\n",
"iv": "GvRlNDV/b1WawtOP\n",
"auth_tag": "kyRCGfSJQelIwThDT4iQQQ==\n",
"encrypted_data": "D1TGjRfmM1ZeUmzwewlKXfQvvqTSzpzNlK5MKIU8dxbAH175UKn5qiemDEWe\nRYPe1LWT\n",
"iv": "D1OVfD5bMcefM5DP\n",
"auth_tag": "2E/q2gTbdXiLVnOMDeJv9w==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"vapid_private_key": {
"encrypted_data": "DlbEAhd+SkSJoOSuwGhd5bdFlJADnT0w4u0+6m8AJoWJjoSCGAnzzmdHWT/k\nVUDkwiBCkqmEPK0oTvxnl/a8\n",
"iv": "6e0Gay7GVrQad1rI\n",
"auth_tag": "jjVundJ/ITxP/oYgEgzElg==\n",
"encrypted_data": "+87bVrbd/XvWhZH1IYusc4Hla7ZZmylptAyJf48CMG/F3SMEO33OqW2I+UWh\nSkqbxai5+GaMhvZHB8U2Clod\n",
"iv": "HVhNdFQl0TvCcjsa\n",
"auth_tag": "EEQXuQ5keOHXmchhBh+Ixw==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"vapid_public_key": {
"encrypted_data": "+m37w/eWYqdEjsEYQw27FvQC+37ucruOFjZAjo0OgCwA0SoVz4VHX2eSA2AK\njX4CnM91cY4e/WG/ZHKlOMN1PftyQn2bdGaw35nXDanep8z0ROa01JEEi5DE\nUFRKvBmPInTeR6xvemuj7GM=\n",
"iv": "loYbGrAsWGLUZ+BK\n",
"auth_tag": "lAfpEEVQq+n7MLLm/kpmIA==\n",
"encrypted_data": "nBm1lXbn1+Kzol95+QSEjsUI/n7ObhdEqEyfYcVSP/LiLy57KOBQDu6CjSMz\n+PN9yEP4lOjtscqHS29jTC2vi3PSui9XpOFHRxFBnDuyKxczrnID2KlLCNRQ\n228G3VRgFIMAWMYKACgzUk0=\n",
"iv": "xHrVl+4JGkQbfUW3\n",
"auth_tag": "rfFoBMocq17YiDSlOCvWqw==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"s3_key_id": {
"encrypted_data": "4B8OQ0iVCCna4FvC+EuS5prEUWaHRm1+tzXGmFoCQ4WZfhUA1HwT3x651e/R\n",
"iv": "1/zGwcQPQQQCiXIs\n",
"auth_tag": "siK9ph1q3/VVEycy91wkqQ==\n",
"encrypted_data": "pq0+VZhjoxzLuyY34f23wOmuks9Wevt8Wu6muKZAsZMSuU0iJvlRoK/65Qa0\n",
"iv": "QTxO+IfYcpI170ON\n",
"auth_tag": "4ZHva2iBYgDv6DyhMRRXzA==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"s3_secret_key": {
"encrypted_data": "BSAc8dE/rQUiVvTGV6Ee/ZUDpq4HZlpoaCZ+lbQAbcnxui4ib0OTLPFwhVJ9\n4OQWahtSzkqxMc6MKWpadLT1a3oTnvnae9b3u40X5b2P3VyZYCM=\n",
"iv": "bqw8GTqLMTs5vD5n\n",
"auth_tag": "+e48L1lYVNda7VE3uLOAHA==\n",
"encrypted_data": "YMZqKtOXDPAME8IWWC+lO8TsxHMzawlbTju9z/Hcb5DnQAOy82QufTN90m73\n/xikUboAdKcA5YGn0mkm+Rt/ygVR6DFirYV3kwi2M3qyGVJifug=\n",
"iv": "9AwabheRFOgC8IKR\n",
"auth_tag": "iU2kkA1q8OsblN5jaZrWGQ==\n",
"version": 3,
"cipher": "aes-256-gcm"
}

View File

@@ -2,12 +2,19 @@
"name": "production",
"override_attributes": {
"akkounts": {
"btcpay": {
"public_url": "https://btcpay.kosmos.org",
"store_id": "FNJVVsrVkKaduPDAkRVchdegjwzsNhpceAdonCaXAwBX"
},
"ejabberd": {
"admin_url": "https://xmpp.kosmos.org:5443/admin"
},
"lndhub": {
"public_url": "https://lndhub.kosmos.org",
"public_key": "024cd3be18617f39cf645851e3ba63f51fc13f0bb09e3bb25e6fd4de556486d946"
},
"nostr": {
"public_key": "b3e1b7c1660b7db0ecb93ec55c09e67961171a5c4e9e2602f1b47477ea61c50a"
}
},
"discourse": {
@@ -17,11 +24,21 @@
"public_url": "https://drone.kosmos.org"
},
"ejabberd": {
"turn_ip_address": "148.251.83.201"
"turn_domain": "turn.kosmos.org"
},
"email": {
"domain": "kosmos.org",
"hostname": "mail.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"
}
},
"garage": {
"replication_mode": "2",
@@ -29,8 +46,9 @@
"s3_web_root_domain": "web.s3.kosmos.org",
"s3_web_domains": [
"media.kosmos.chat",
"s3.kosmos.social",
"s3.community.kosmos.org"
"s3.accounts.kosmos.org",
"s3.community.kosmos.org",
"s3.kosmos.social"
],
"xmpp_upload_bucket": "kosmos-xmpp-uploads"
},
@@ -49,14 +67,16 @@
"kosmos_kvm": {
"backup": {
"nodes_excluded": [
"garage-2", "garage-3", "garage-4",
"postgres-5",
"rsk-mainnet-2", "rsk-testnet-3"
"garage-",
"lq-",
"rsk-",
"postgres-6"
]
}
},
"kosmos-mastodon": {
"domain": "kosmos.social",
"user_address_domain": "kosmos.social",
"s3_endpoint": "http://localhost:3900",
"s3_region": "garage",
"s3_bucket": "kosmos-social",
@@ -66,6 +86,16 @@
"mastodon.w7nooprauv6yrnhzh2ajpcnj3doinked2aaztlwfyt6u6pva2qdxqhid.onion"
]
},
"liquor-cabinet": {
"ufw_source_allowed": "10.1.1.0/24",
"redis_port": 6379,
"redis_db": 1,
"s3_endpoint": "http://localhost:3900",
"s3_region": "garage",
"s3_bucket": "rs-kosmos",
"domain": "storage.kosmos.org",
"root_redirect_url": "https://accounts.kosmos.org"
},
"mediawiki": {
"url": "https://wiki.kosmos.org"
},

View File

@@ -17,6 +17,7 @@
"kvm_guest",
"ldap_client",
"sentry_client",
"garage_gateway",
"akkounts",
"postgresql_client"
],
@@ -26,6 +27,9 @@
"kosmos_kvm::guest",
"kosmos-dirsrv::hostsfile",
"kosmos_sentry::client",
"kosmos_garage",
"kosmos_garage::default",
"kosmos_garage::firewall_rpc",
"kosmos_postgresql::hostsfile",
"kosmos-akkounts",
"kosmos-akkounts::default",
@@ -43,6 +47,7 @@
"postfix::_attributes",
"postfix::sasl_auth",
"hostname::default",
"firewall::default",
"redisio::default",
"redisio::_install_prereqs",
"redisio::install",
@@ -76,6 +81,7 @@
"role[kvm_guest]",
"role[ldap_client]",
"role[sentry_client]",
"role[garage_gateway]",
"role[akkounts]"
]
}

View File

@@ -8,7 +8,7 @@
"automatic": {
"fqdn": "bitcoin-2",
"os": "linux",
"os_version": "5.4.0-131-generic",
"os_version": "5.4.0-163-generic",
"hostname": "bitcoin-2",
"ipaddress": "192.168.122.148",
"roles": [

View File

@@ -47,11 +47,11 @@
"kosmos_assets::nginx_site",
"kosmos_discourse::nginx",
"kosmos_drone::nginx",
"kosmos-ejabberd::nginx",
"kosmos_garage::nginx_web",
"kosmos_garage::nginx_s3",
"kosmos_gitea::nginx",
"kosmos_gitea::nginx_ssh",
"kosmos_liquor-cabinet::nginx",
"kosmos_rsk::nginx_testnet",
"kosmos_rsk::nginx_mainnet",
"kosmos_website",

View File

@@ -24,7 +24,8 @@
"openresty",
"garage_gateway",
"tor_proxy",
"zerotier_controller"
"zerotier_controller",
"turn_server"
],
"recipes": [
"kosmos-base",
@@ -40,11 +41,11 @@
"kosmos_assets::nginx_site",
"kosmos_discourse::nginx",
"kosmos_drone::nginx",
"kosmos-ejabberd::nginx",
"kosmos_garage::nginx_web",
"kosmos_garage::nginx_s3",
"kosmos_gitea::nginx",
"kosmos_gitea::nginx_ssh",
"kosmos_liquor-cabinet::nginx",
"kosmos_rsk::nginx_testnet",
"kosmos_rsk::nginx_mainnet",
"kosmos_website",
@@ -63,6 +64,7 @@
"kosmos_zerotier::controller",
"kosmos_zerotier::firewall",
"kosmos_zerotier::zncui",
"kosmos-ejabberd::coturn",
"kosmos-ejabberd::firewall",
"kosmos-ipfs::firewall_swarm",
"sockethub::firewall",
@@ -115,6 +117,7 @@
"role[kvm_host]",
"role[openresty_proxy]",
"role[zerotier_controller]",
"role[turn_server]",
"recipe[kosmos-ejabberd::firewall]",
"recipe[kosmos-ipfs::firewall_swarm]",
"recipe[kosmos_zerotier::firewall]",

View File

@@ -1,17 +1,17 @@
{
"name": "garage-3",
"name": "garage-6",
"chef_environment": "production",
"normal": {
"knife_zero": {
"host": "10.1.1.39"
"host": "10.1.1.161"
}
},
"automatic": {
"fqdn": "garage-3",
"fqdn": "garage-6",
"os": "linux",
"os_version": "5.4.0-132-generic",
"hostname": "garage-3",
"ipaddress": "192.168.122.191",
"os_version": "5.4.0-1090-kvm",
"hostname": "garage-6",
"ipaddress": "192.168.122.213",
"roles": [
"base",
"kvm_guest",
@@ -61,4 +61,4 @@
"role[kvm_guest]",
"role[garage_node]"
]
}
}

View File

@@ -1,32 +1,30 @@
{
"name": "postgres-4",
"name": "garage-7",
"chef_environment": "production",
"normal": {
"knife_zero": {
"host": "10.1.1.107"
"host": "10.1.1.182"
}
},
"automatic": {
"fqdn": "postgres-4",
"fqdn": "garage-7",
"os": "linux",
"os_version": "5.4.0-122-generic",
"hostname": "postgres-4",
"ipaddress": "192.168.122.3",
"os_version": "5.4.0-1090-kvm",
"hostname": "garage-7",
"ipaddress": "192.168.122.86",
"roles": [
"base",
"kvm_guest",
"postgresql_primary"
"garage_node"
],
"recipes": [
"kosmos-base",
"kosmos-base::default",
"kosmos_kvm::guest",
"kosmos_postgresql::primary",
"kosmos_postgresql::firewall",
"kosmos-bitcoin::lndhub-go_pg_db",
"kosmos-bitcoin::nbxplorer_pg_db",
"kosmos_drone::pg_db",
"kosmos_gitea::pg_db",
"kosmos-mastodon::pg_db",
"kosmos_garage",
"kosmos_garage::default",
"kosmos_garage::firewall_rpc",
"kosmos_garage::firewall_apis",
"apt::default",
"timezone_iii::default",
"timezone_iii::debian",
@@ -40,7 +38,8 @@
"postfix::_common",
"postfix::_attributes",
"postfix::sasl_auth",
"hostname::default"
"hostname::default",
"firewall::default"
],
"platform": "ubuntu",
"platform_version": "20.04",
@@ -60,6 +59,6 @@
"run_list": [
"role[base]",
"role[kvm_guest]",
"role[postgresql_primary]"
"role[garage_node]"
]
}
}

64
nodes/garage-8.json Normal file
View File

@@ -0,0 +1,64 @@
{
"name": "garage-8",
"chef_environment": "production",
"normal": {
"knife_zero": {
"host": "10.1.1.61"
}
},
"automatic": {
"fqdn": "garage-8",
"os": "linux",
"os_version": "5.4.0-1090-kvm",
"hostname": "garage-8",
"ipaddress": "192.168.122.207",
"roles": [
"base",
"kvm_guest",
"garage_node"
],
"recipes": [
"kosmos-base",
"kosmos-base::default",
"kosmos_kvm::guest",
"kosmos_garage",
"kosmos_garage::default",
"kosmos_garage::firewall_rpc",
"kosmos_garage::firewall_apis",
"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",
"postfix::default",
"postfix::_common",
"postfix::_attributes",
"postfix::sasl_auth",
"hostname::default",
"firewall::default"
],
"platform": "ubuntu",
"platform_version": "20.04",
"cloud": null,
"chef_packages": {
"chef": {
"version": "18.4.2",
"chef_root": "/opt/chef/embedded/lib/ruby/gems/3.1.0/gems/chef-18.4.2/lib",
"chef_effortless": null
},
"ohai": {
"version": "18.1.11",
"ohai_root": "/opt/chef/embedded/lib/ruby/gems/3.1.0/gems/ohai-18.1.11/lib/ohai"
}
}
},
"run_list": [
"role[base]",
"role[kvm_guest]",
"role[garage_node]"
]
}

View File

@@ -1,5 +1,6 @@
{
"name": "her",
"chef_environment": "production",
"normal": {
"knife_zero": {
"host": "10.1.1.222"
@@ -19,6 +20,7 @@
"kosmos-base",
"kosmos-base::default",
"kosmos_kvm::host",
"kosmos_kvm::backup",
"apt::default",
"timezone_iii::default",
"timezone_iii::debian",

View File

@@ -1,5 +1,6 @@
{
"name": "lq-1",
"chef_environment": "production",
"normal": {
"knife_zero": {
"host": "10.1.1.87"
@@ -8,17 +9,24 @@
"automatic": {
"fqdn": "lq-1",
"os": "linux",
"os_version": "5.4.0-1090-kvm",
"os_version": "5.4.0-1104-kvm",
"hostname": "lq-1",
"ipaddress": "192.168.122.158",
"roles": [
"base",
"kvm_guest"
"kvm_guest",
"garage_gateway",
"liquor_cabinet"
],
"recipes": [
"kosmos-base",
"kosmos-base::default",
"kosmos_kvm::guest",
"kosmos_garage",
"kosmos_garage::default",
"kosmos_garage::firewall_rpc",
"kosmos_liquor-cabinet",
"kosmos_liquor-cabinet::default",
"apt::default",
"timezone_iii::default",
"timezone_iii::debian",
@@ -32,7 +40,9 @@
"postfix::_common",
"postfix::_attributes",
"postfix::sasl_auth",
"hostname::default"
"hostname::default",
"firewall::default",
"liquor_cabinet::default"
],
"platform": "ubuntu",
"platform_version": "20.04",
@@ -51,6 +61,8 @@
},
"run_list": [
"role[base]",
"role[kvm_guest]"
"role[kvm_guest]",
"role[garage_gateway]",
"role[liquor_cabinet]"
]
}

View File

@@ -1,5 +1,6 @@
{
"name": "lq-2",
"chef_environment": "production",
"normal": {
"knife_zero": {
"host": "10.1.1.188"
@@ -8,17 +9,24 @@
"automatic": {
"fqdn": "lq-2",
"os": "linux",
"os_version": "5.4.0-1090-kvm",
"os_version": "5.4.0-1104-kvm",
"hostname": "lq-2",
"ipaddress": "192.168.122.47",
"roles": [
"base",
"kvm_guest"
"kvm_guest",
"garage_gateway",
"liquor_cabinet"
],
"recipes": [
"kosmos-base",
"kosmos-base::default",
"kosmos_kvm::guest",
"kosmos_garage",
"kosmos_garage::default",
"kosmos_garage::firewall_rpc",
"kosmos_liquor-cabinet",
"kosmos_liquor-cabinet::default",
"apt::default",
"timezone_iii::default",
"timezone_iii::debian",
@@ -32,7 +40,9 @@
"postfix::_common",
"postfix::_attributes",
"postfix::sasl_auth",
"hostname::default"
"hostname::default",
"firewall::default",
"liquor_cabinet::default"
],
"platform": "ubuntu",
"platform_version": "20.04",
@@ -51,6 +61,8 @@
},
"run_list": [
"role[base]",
"role[kvm_guest]"
"role[kvm_guest]",
"role[garage_gateway]",
"role[liquor_cabinet]"
]
}

View File

@@ -3,15 +3,15 @@
"chef_environment": "production",
"normal": {
"knife_zero": {
"host": "10.1.1.141"
"host": "10.1.1.95"
}
},
"automatic": {
"fqdn": "mail.kosmos.org",
"os": "linux",
"os_version": "5.15.0-1045-kvm",
"os_version": "5.15.0-1048-kvm",
"hostname": "mail",
"ipaddress": "192.168.122.127",
"ipaddress": "192.168.122.131",
"roles": [
"base",
"kvm_guest",
@@ -36,6 +36,9 @@
"kosmos-postfix::default",
"hostname::default",
"kosmos-base::letsencrypt",
"unbound::default",
"kosmos_email::opendkim",
"kosmos_email::spamassassin",
"kosmos_email::postfix",
"postfix::server",
"postfix::default",

View File

@@ -14,6 +14,7 @@
"ipaddress": "192.168.122.161",
"roles": [
"kvm_guest",
"ldap_client",
"garage_gateway",
"mastodon",
"postgresql_client"
@@ -22,6 +23,7 @@
"kosmos-base",
"kosmos-base::default",
"kosmos_kvm::guest",
"kosmos-dirsrv::hostsfile",
"kosmos_garage",
"kosmos_garage::default",
"kosmos_garage::firewall_rpc",
@@ -84,6 +86,7 @@
"run_list": [
"recipe[kosmos-base]",
"role[kvm_guest]",
"role[ldap_client]",
"role[garage_gateway]",
"role[mastodon]"
]

View File

@@ -13,12 +13,20 @@
"ipaddress": "192.168.122.211",
"roles": [
"base",
"kvm_guest"
"kvm_guest",
"postgresql_primary"
],
"recipes": [
"kosmos-base",
"kosmos-base::default",
"kosmos_kvm::guest",
"kosmos_postgresql::primary",
"kosmos_postgresql::firewall",
"kosmos-bitcoin::lndhub-go_pg_db",
"kosmos-bitcoin::nbxplorer_pg_db",
"kosmos_drone::pg_db",
"kosmos_gitea::pg_db",
"kosmos-mastodon::pg_db",
"apt::default",
"timezone_iii::default",
"timezone_iii::debian",
@@ -52,6 +60,6 @@
"run_list": [
"role[base]",
"role[kvm_guest]",
"role[postgresql_replica]"
"role[postgresql_primary]"
]
}

57
nodes/postgres-6.json Normal file
View File

@@ -0,0 +1,57 @@
{
"name": "postgres-6",
"normal": {
"knife_zero": {
"host": "10.1.1.196"
}
},
"automatic": {
"fqdn": "postgres-6",
"os": "linux",
"os_version": "5.4.0-173-generic",
"hostname": "postgres-6",
"ipaddress": "192.168.122.60",
"roles": [
"base",
"kvm_guest"
],
"recipes": [
"kosmos-base",
"kosmos-base::default",
"kosmos_kvm::guest",
"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",
"postfix::default",
"postfix::_common",
"postfix::_attributes",
"postfix::sasl_auth",
"hostname::default"
],
"platform": "ubuntu",
"platform_version": "20.04",
"cloud": null,
"chef_packages": {
"chef": {
"version": "18.4.2",
"chef_root": "/opt/chef/embedded/lib/ruby/gems/3.1.0/gems/chef-18.4.2/lib",
"chef_effortless": null
},
"ohai": {
"version": "18.1.11",
"ohai_root": "/opt/chef/embedded/lib/ruby/gems/3.1.0/gems/ohai-18.1.11/lib/ohai"
}
}
},
"run_list": [
"role[base]",
"role[kvm_guest]",
"role[postgresql_replica]"
]
}

View File

@@ -1,5 +1,6 @@
{
"name": "redis-1",
"chef_environment": "production",
"normal": {
"knife_zero": {
"host": "10.1.1.225"
@@ -8,7 +9,7 @@
"automatic": {
"fqdn": "redis-1",
"os": "linux",
"os_version": "5.4.0-1090-kvm",
"os_version": "5.4.0-1104-kvm",
"hostname": "redis-1",
"ipaddress": "192.168.122.83",
"roles": [
@@ -22,6 +23,8 @@
"kosmos_kvm::guest",
"kosmos_redis",
"kosmos_redis::default",
"kosmos_redis::firewall",
"kosmos_redis::backup",
"apt::default",
"timezone_iii::default",
"timezone_iii::debian",
@@ -43,7 +46,6 @@
"redisio::disable_os_default",
"redisio::configure",
"redisio::enable",
"kosmos_redis::firewall",
"backup::default",
"logrotate::default"
],

View File

@@ -1,5 +1,6 @@
{
"name": "redis-2",
"chef_environment": "production",
"normal": {
"knife_zero": {
"host": "10.1.1.208"
@@ -8,17 +9,20 @@
"automatic": {
"fqdn": "redis-2",
"os": "linux",
"os_version": "5.4.0-1090-kvm",
"os_version": "5.4.0-1104-kvm",
"hostname": "redis-2",
"ipaddress": "192.168.122.98",
"roles": [
"base",
"kvm_guest"
"kvm_guest",
"redis_replica"
],
"recipes": [
"kosmos-base",
"kosmos-base::default",
"kosmos_kvm::guest",
"kosmos_redis::replica",
"kosmos_redis::firewall",
"apt::default",
"timezone_iii::default",
"timezone_iii::debian",
@@ -32,7 +36,14 @@
"postfix::_common",
"postfix::_attributes",
"postfix::sasl_auth",
"hostname::default"
"hostname::default",
"redisio::default",
"redisio::_install_prereqs",
"redisio::install",
"redisio::ulimit",
"redisio::disable_os_default",
"redisio::configure",
"redisio::enable"
],
"platform": "ubuntu",
"platform_version": "20.04",
@@ -51,6 +62,7 @@
},
"run_list": [
"role[base]",
"role[kvm_guest]"
"role[kvm_guest]",
"role[redis_replica]"
]
}

View File

@@ -55,7 +55,6 @@
},
"run_list": [
"role[base]",
"role[kvm_guest]",
"role[rskj_testnet]"
"role[kvm_guest]"
]
}

61
nodes/rsk-testnet-5.json Normal file
View File

@@ -0,0 +1,61 @@
{
"name": "rsk-testnet-5",
"normal": {
"knife_zero": {
"host": "10.1.1.194"
}
},
"automatic": {
"fqdn": "rsk-testnet-5",
"os": "linux",
"os_version": "5.4.0-1103-kvm",
"hostname": "rsk-testnet-5",
"ipaddress": "192.168.122.171",
"roles": [
"base",
"kvm_guest",
"rskj_testnet"
],
"recipes": [
"kosmos-base",
"kosmos-base::default",
"kosmos_kvm::guest",
"kosmos_rsk::rskj",
"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",
"postfix::default",
"postfix::_common",
"postfix::_attributes",
"postfix::sasl_auth",
"hostname::default",
"kosmos_rsk::firewall",
"firewall::default"
],
"platform": "ubuntu",
"platform_version": "20.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[rskj_testnet]"
]
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

5
roles/liquor_cabinet.rb Normal file
View File

@@ -0,0 +1,5 @@
name "liquor_cabinet"
run_list %w(
kosmos_liquor-cabinet::default
)

View File

@@ -21,11 +21,11 @@ production_run_list = %w(
kosmos_assets::nginx_site
kosmos_discourse::nginx
kosmos_drone::nginx
kosmos-ejabberd::nginx
kosmos_garage::nginx_web
kosmos_garage::nginx_s3
kosmos_gitea::nginx
kosmos_gitea::nginx_ssh
kosmos_liquor-cabinet::nginx
kosmos_rsk::nginx_testnet
kosmos_rsk::nginx_mainnet
kosmos_website::default

15
roles/redis_replica.rb Normal file
View File

@@ -0,0 +1,15 @@
name "redis_replica"
run_list %w(
kosmos_redis::replica
kosmos_redis::firewall
)
default_attributes({
'redisio' => {
'default_settings' => {
'slaveservestaledata' => 'yes',
'slavereadonly' => 'yes'
}
}
})

View File

@@ -7,6 +7,7 @@ default_run_list = %w(
production_run_list = %w(
kosmos_redis::default
kosmos_redis::firewall
kosmos_redis::backup
)
env_run_lists(
@@ -14,5 +15,3 @@ env_run_lists(
'development' => default_run_list,
'production' => production_run_list
)
default_attributes({})

5
roles/turn_server.rb Normal file
View File

@@ -0,0 +1,5 @@
name "turn_server"
run_list %w(
kosmos-ejabberd::coturn
)

View File

@@ -21,3 +21,4 @@ bundle exec knife ssh roles:postgresql_client -a knife_zero.host "sudo sed -r \"
# TODO
# 1. Change roles in node configs
# 2. Converge new primary
echo "You need to update the role in the '$new_primary_hostname' node config to 'postgres_primary' and converge it now."

View File

@@ -1,5 +1,5 @@
node.default['akkounts']['repo'] = 'https://gitea.kosmos.org/kosmos/akkounts.git'
node.default['akkounts']['revision'] = 'master'
node.default['akkounts']['revision'] = 'live'
node.default['akkounts']['port'] = 3000
node.default['akkounts']['domain'] = 'accounts.kosmos.org'
node.default['akkounts']['primary_domain'] = 'kosmos.org'
@@ -11,9 +11,20 @@ node.default['akkounts']['smtp']['domain'] = 'kosmos.org'
node.default['akkounts']['smtp']['auth_method'] = 'plain'
node.default['akkounts']['smtp']['enable_starttls'] = 'auto'
node.default['akkounts']['btcpay']['public_url'] = nil
node.default['akkounts']['btcpay']['store_id'] = nil
node.default['akkounts']['ejabberd']['admin_url'] = nil
node.default['akkounts']['lndhub']['api_url'] = nil
node.default['akkounts']['lndhub']['public_url'] = nil
node.default['akkounts']['lndhub']['public_key'] = nil
node.default['akkounts']['lndhub']['postgres_db'] = 'lndhub'
node.default['akkounts']['nostr']['public_key'] = nil
node.default['akkounts']['s3_enabled'] = true
node.default['akkounts']['s3_endpoint'] = "https://s3.kosmos.org"
node.default['akkounts']['s3_region'] = "garage"
node.default['akkounts']['s3_bucket'] = "akkounts-production"
node.default['akkounts']['s3_alias_host'] = "https://s3.accounts.kosmos.org"

View File

@@ -20,6 +20,7 @@ user deploy_user do
end
package "libpq-dev"
package "libvips"
include_recipe 'redisio::default'
include_recipe 'redisio::enable'
@@ -29,12 +30,12 @@ npm_package "yarn" do
version "1.22.4"
end
ruby_version = "2.7.5"
ruby_version = "3.3.0"
ruby_path = "/opt/ruby_build/builds/#{ruby_version}"
bundle_path = "#{ruby_path}/bin/bundle"
rails_env = node.chef_environment == "development" ? "development" : "production"
ruby_build_install 'v20230615'
ruby_build_install 'v20240221'
ruby_build_definition ruby_version do
prefix_path ruby_path
end
@@ -68,15 +69,34 @@ if webhooks_allowed_ips.length > 0
env[:webhooks_allowed_ips] = webhooks_allowed_ips
end
#
# BTCPay Server
#
if btcpay_host
env[:btcpay_api_url] = "http://#{btcpay_host}:23001/api/v1"
env[:btcpay_public_url] = node['akkounts']['btcpay']['public_url']
env[:btcpay_store_id] = node['akkounts']['btcpay']['store_id']
env[:btcpay_auth_token] = credentials["btcpay_auth_token"]
end
#
# Discourse
#
env[:discourse_public_url] = "https://#{node['discourse']['domain']}"
env[:discourse_connect_secret] = credentials['discourse_connect_secret']
#
# Drone CI
#
env[:droneci_public_url] = node["droneci"]["public_url"]
#
# ejabberd
#
ejabberd_private_ip_addresses = []
search(:node, "role:ejabberd").each do |node|
ejabberd_private_ip_addresses << node["knife_zero"]["host"]
@@ -98,12 +118,21 @@ if ejabberd_private_ip_addresses.size > 0
env[:ejabberd_admin_url] = node['akkounts']['ejabberd']['admin_url']
end
#
# Gitea
#
env[:gitea_public_url] = "https://#{node['gitea']['domain']}"
#
# lndhub.go
#
if lndhub_host
node.override["akkounts"]["lndhub"]["api_url"] = "http://#{lndhub_host}:3026"
env[:lndhub_legacy_api_url] = node["akkounts"]["lndhub"]["api_url"]
env[:lndhub_api_url] = node["akkounts"]["lndhub"]["api_url"]
env[:lndhub_admin_token] = credentials["lndhub_admin_token"]
env[:lndhub_public_url] = node["akkounts"]["lndhub"]["public_url"]
env[:lndhub_public_key] = node["akkounts"]["lndhub"]["public_key"]
if postgres_readonly_host
@@ -115,10 +144,57 @@ if lndhub_host
end
end
#
# Mastodon
#
env[:mastodon_public_url] = "https://#{node['kosmos-mastodon']['domain']}"
env[:mastodon_address_domain] = node['kosmos-mastodon']['user_address_domain']
#
# MediaWiki
#
env[:mediawiki_public_url] = node['mediawiki']['url']
#
# Nostr
#
env[:nostr_private_key] = credentials['nostr_private_key']
env[:nostr_public_key] = node['akkounts']['nostr']['public_key']
#
# remoteStorage / Liquor Cabinet
#
env[:rs_storage_url] = "https://#{node['liquor-cabinet']['domain']}"
rs_redis_host = search(:node, "role:redis_server").first["knife_zero"]["host"] rescue nil
rs_redis_port = node['liquor-cabinet']['redis_port']
rs_redis_db = node['liquor-cabinet']['redis_db']
if rs_redis_host
env[:rs_redis_url] = "redis://#{rs_redis_host}:#{rs_redis_port}/#{rs_redis_db}"
end
#
# S3
#
if node['akkounts']['s3_enabled']
env[:s3_enabled] = true
env[:s3_endpoint] = node['akkounts']['s3_endpoint']
env[:s3_region] = node['akkounts']['s3_region']
env[:s3_bucket] = node['akkounts']['s3_bucket']
env[:s3_alias_host] = node['akkounts']['s3_alias_host']
env[:s3_access_key] = credentials['s3_access_key']
env[:s3_secret_key] = credentials['s3_secret_key']
end
#
# Akkounts Deployment
#
systemd_unit "akkounts.service" do
content({
Unit: {

View File

@@ -18,7 +18,7 @@ server {
access_log <%= node[:openresty][:log_dir] %>/<%= @domain %>.access.log json;
error_log <%= node[:openresty][:log_dir] %>/<%= @domain %>.error.log warn;
location /kredits/ {
location / {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
@@ -31,6 +31,6 @@ server {
proxy_buffers 1024 8k;
proxy_http_version 1.1;
proxy_pass http://_akkounts_api/api/kredits/;
proxy_pass http://_akkounts_api/api/;
}
}

View File

@@ -2,27 +2,6 @@
# Cookbook Name:: kosmos-base
# Recipe:: letsencrypt
#
# 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.
unless platform?('ubuntu')
raise "This recipe only supports Ubuntu installs"

View File

@@ -3,6 +3,8 @@ provides :tls_cert_for
property :domain, [String, Array], name_property: true
property :auth, [String, NilClass], default: nil
property :deploy_hook, [String, NilClass], default: nil
property :acme_domain, [String, NilClass], default: nil
default_action :create
@@ -17,13 +19,35 @@ action :create do
case new_resource.auth
when "gandi_dns"
gandi_api_data_bag_item = data_bag_item('credentials', 'gandi_api_5apps')
gandi_api_credentials = data_bag_item('credentials', 'gandi_api')
hook_path = "/root/gandi_dns_certbot_hook.sh"
hook_auth_command = "#{hook_path} auth"
hook_cleanup_command = "#{hook_path} cleanup"
if new_resource.acme_domain
hook_auth_command += " #{new_resource.acme_domain}"
hook_cleanup_command += " #{new_resource.acme_domain}"
end
template hook_path do
cookbook "kosmos-base"
variables gandi_api_key: gandi_api_data_bag_item["key"]
mode 0770
variables access_token: gandi_api_credentials["access_token"]
mode 0700
sensitive true
end
if new_resource.deploy_hook
deploy_hook_path = "/etc/letsencrypt/renewal-hooks/#{domains.first}"
file deploy_hook_path do
content new_resource.deploy_hook
mode 0755
owner "root"
group "root"
end
elsif node.run_list.roles.include?("openresty_proxy")
deploy_hook_path = "/etc/letsencrypt/renewal-hooks/post/openresty"
end
# Generate a Let's Encrypt cert (only if no cert has been generated before).
@@ -34,10 +58,10 @@ action :create do
--preferred-challenges dns \
--manual-public-ip-logging-ok \
--agree-tos \
--manual-auth-hook '#{hook_path} auth' \
--manual-cleanup-hook '#{hook_path} cleanup' \
--manual-auth-hook '#{hook_auth_command}' \
--manual-cleanup-hook '#{hook_cleanup_command}' \
--email ops@kosmos.org \
#{node.run_list.roles.include?("openresty_proxy") ? '--deploy-hook /etc/letsencrypt/renewal-hooks/post/openresty' : nil } \
#{"--deploy-hook #{deploy_hook_path}" if defined?(deploy_hook_path)} \
#{domains.map {|d| "-d #{d}" }.join(" ")}
CMD
not_if do

View File

@@ -1,21 +1,16 @@
#!/usr/bin/env bash
#
set -euf -o pipefail
# ************** USAGE **************
#
# Example usage (with this hook file saved in /root/):
# Example usage:
#
# sudo su -
# certbot certonly --manual --preferred-challenges dns --manual-public-ip-logging-ok --agree-tos -d "5apps.com" -d muc.5apps.com -d "xmpp.5apps.com" \
# --manual-auth-hook "/root/letsencrypt_hook.sh auth" --manual-cleanup-hook "/root/letsencrypt_hook.sh cleanup"
#
# This hook requires configuration, continue reading.
#
# ************** CONFIGURATION **************
#
# GANDI_API_KEY: Your Gandi Live API key
# ACCESS_TOKEN: Your Gandi Live API key
#
# PROVIDER_UPDATE_DELAY:
# How many seconds to wait after updating your DNS records. This may be required,
@@ -25,10 +20,16 @@ set -euf -o pipefail
#
# Defaults to 30 seconds.
#
GANDI_API_KEY="<%= @gandi_api_key %>"
# VALIDATION_DOMAIN:
# Domain to create ACME DNS entries on. Use this when redirecting ACME subdomains
# from the original domain to a proxy validation domain that we control.
#
ACCESS_TOKEN="<%= @access_token %>"
PROVIDER_UPDATE_DELAY=10
VALIDATION_DOMAIN="${2:-}"
regex='.*\.(.*\..*)'
if [[ $CERTBOT_DOMAIN =~ $regex ]]
then
DOMAIN="${BASH_REMATCH[1]}"
@@ -36,25 +37,41 @@ else
DOMAIN="${CERTBOT_DOMAIN}"
fi
if [[ -n "$VALIDATION_DOMAIN" ]]
then
if [[ $VALIDATION_DOMAIN =~ $regex ]]
then
ACME_BASE_DOMAIN="${BASH_REMATCH[1]}"
else
echo "Validation domain has to be a subdomain, but it is not: \"${VALIDATION_DOMAIN}\""
exit 1
fi
ACME_DOMAIN="${CERTBOT_DOMAIN}.${VALIDATION_DOMAIN}"
else
ACME_BASE_DOMAIN="${DOMAIN}"
ACME_DOMAIN="_acme-challenge.${CERTBOT_DOMAIN}"
fi
# To be invoked via Certbot's --manual-auth-hook
function auth {
curl -s -D- -H "Content-Type: application/json" \
-H "X-Api-Key: ${GANDI_API_KEY}" \
-d "{\"rrset_name\": \"_acme-challenge.${CERTBOT_DOMAIN}.\",
\"rrset_type\": \"TXT\",
\"rrset_ttl\": 3600,
\"rrset_values\": [\"${CERTBOT_VALIDATION}\"]}" \
"https://dns.api.gandi.net/api/v5/domains/${DOMAIN}/records"
curl -s -D- \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-d "{\"rrset_name\": \"${ACME_DOMAIN}.\",
\"rrset_type\": \"TXT\",
\"rrset_ttl\": 300,
\"rrset_values\": [\"${CERTBOT_VALIDATION}\"]}" \
"https://api.gandi.net/v5/livedns/domains/${ACME_BASE_DOMAIN}/records"
sleep ${PROVIDER_UPDATE_DELAY}
sleep ${PROVIDER_UPDATE_DELAY}
}
# To be invoked via Certbot's --manual-cleanup-hook
function cleanup {
curl -s -X DELETE -H "Content-Type: application/json" \
-H "X-Api-Key: ${GANDI_API_KEY}" \
https://dns.api.gandi.net/api/v5/domains/${DOMAIN}/records/_acme-challenge.${CERTBOT_DOMAIN}./TXT
curl -s -X DELETE \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
"https://api.gandi.net/v5/livedns/domains/${ACME_BASE_DOMAIN}/records/${ACME_DOMAIN}./TXT"
}
HANDLER=$1; shift;

View File

@@ -1,5 +1,5 @@
node.default['bitcoin']['version'] = '25.0'
node.default['bitcoin']['checksum'] = '5df67cf42ca3b9a0c38cdafec5bbb517da5b58d251f32c8d2a47511f9be1ebc2'
node.default['bitcoin']['version'] = '26.0'
node.default['bitcoin']['checksum'] = 'ab1d99276e28db62d1d9f3901e85ac358d7f1ebcb942d348a9c4e46f0fcdc0a1'
node.default['bitcoin']['username'] = 'satoshi'
node.default['bitcoin']['usergroup'] = 'bitcoin'
node.default['bitcoin']['network'] = 'mainnet'
@@ -31,7 +31,7 @@ node.default['bitcoin']['conf'] = {
node.default['bitcoin']['tor_enabled'] = true
node.default['c-lightning']['repo'] = 'https://github.com/ElementsProject/lightning'
node.default['c-lightning']['revision'] = 'v0.10.2'
node.default['c-lightning']['revision'] = 'v23.11.1'
node.default['c-lightning']['source_dir'] = '/opt/c-lightning'
node.default['c-lightning']['lightning_dir'] = "/home/#{node['bitcoin']['username']}/.lightning"
node.default['c-lightning']['alias'] = 'ln3.kosmos.org'
@@ -40,7 +40,7 @@ node.default['c-lightning']['log_level'] = 'info'
node.default['c-lightning']['public_ip'] = '148.251.237.73'
node.default['lnd']['repo'] = 'https://github.com/lightningnetwork/lnd'
node.default['lnd']['revision'] = 'v0.16.4-beta'
node.default['lnd']['revision'] = 'v0.17.3-beta'
node.default['lnd']['source_dir'] = '/opt/lnd'
node.default['lnd']['lnd_dir'] = "/home/#{node['bitcoin']['username']}/.lnd"
node.default['lnd']['alias'] = 'ln2.kosmos.org'
@@ -59,7 +59,7 @@ node.default['lnd']['tor'] = {
}
node.default['boltz']['repo'] = 'https://github.com/BoltzExchange/boltz-lnd.git'
node.default['boltz']['revision'] = 'v1.2.6'
node.default['boltz']['revision'] = 'v1.2.7'
node.default['boltz']['source_dir'] = '/opt/boltz'
node.default['boltz']['boltz_dir'] = "/home/#{node['bitcoin']['username']}/.boltz-lnd"
node.default['boltz']['grpc_host'] = '127.0.0.1'
@@ -70,7 +70,7 @@ node.default['boltz']['rest_port'] = '9003'
node.default['boltz']['no_macaroons'] = 'false'
node.default['rtl']['repo'] = 'https://github.com/Ride-The-Lightning/RTL.git'
node.default['rtl']['revision'] = 'v0.12.1'
node.default['rtl']['revision'] = 'v0.15.0'
node.default['rtl']['host'] = '10.1.1.163'
node.default['rtl']['port'] = '3000'
@@ -98,7 +98,7 @@ node.default['dotnet']['ms_packages_src_url'] = "https://packages.microsoft.com/
node.default['dotnet']['ms_packages_src_checksum'] = "4df5811c41fdded83eb9e2da9336a8dfa5594a79dc8a80133bd815f4f85b9991"
node.default['nbxplorer']['repo'] = 'https://github.com/dgarage/NBXplorer'
node.default['nbxplorer']['revision'] = 'v2.3.66'
node.default['nbxplorer']['revision'] = 'v2.5.0'
node.default['nbxplorer']['source_dir'] = '/opt/nbxplorer'
node.default['nbxplorer']['config_path'] = "/home/#{node['bitcoin']['username']}/.nbxplorer/Main/settings.config"
node.default['nbxplorer']['port'] = '24445'
@@ -106,7 +106,7 @@ node.default['nbxplorer']['postgres']['database'] = 'nbxplorer'
node.default['nbxplorer']['postgres']['user'] = 'nbxplorer'
node.default['btcpay']['repo'] = 'https://github.com/btcpayserver/btcpayserver'
node.default['btcpay']['revision'] = 'v1.11.6'
node.default['btcpay']['revision'] = 'v1.12.5'
node.default['btcpay']['source_dir'] = '/opt/btcpay'
node.default['btcpay']['config_path'] = "/home/#{node['bitcoin']['username']}/.btcpayserver/Main/settings.config"
node.default['btcpay']['log_path'] = "/home/#{node['bitcoin']['username']}/.btcpayserver/debug.log"

View File

@@ -30,4 +30,4 @@ execute 'apt_update' do
action :nothing
end
apt_package 'dotnet-sdk-7.0'
apt_package 'dotnet-sdk-8.0'

View File

@@ -3,6 +3,7 @@
# Recipe:: rtl
#
node.override["nodejs"]["repo"] = "https://deb.nodesource.com/node_18.x"
include_recipe 'kosmos-nodejs'
app_name = "rtl"

View File

@@ -1,7 +1,9 @@
node.default["ejabberd"]["version"] = "23.10"
node.default["ejabberd"]["package_version"] = "1"
node.default["ejabberd"]["checksum"] = "1b02108c81e22ab28be84630d54061f0584b76d5c2702e598352269736b05e77"
node.default["ejabberd"]["turn_ip_address"] = nil
node.default["ejabberd"]["turn_domain"] = "turn.kosmos.org"
node.default["ejabberd"]["stun_auth_realm"] = "kosmos.org"
node.default["ejabberd"]["stun_turn_port"] = 3478
node.default["ejabberd"]["stun_turn_port_tls"] = 5349
node.default["ejabberd"]["turn_min_port"] = 50000
node.default["ejabberd"]["turn_max_port"] = 50050
node.default["ejabberd"]["turn_max_port"] = 50999

View File

@@ -0,0 +1,52 @@
#
# Cookbook:: kosmos-ejabberd
# Recipe:: coturn
#
apt_package 'coturn'
domain = node["ejabberd"]["turn_domain"]
credentials = data_bag_item("credentials", "ejabberd")
tls_cert_for domain do
auth "gandi_dns"
action :create
end
template "/etc/turnserver.conf" do
source "turnserver.conf.erb"
mode 0644
variables listening_port: node["ejabberd"]["stun_turn_port"],
tls_listening_port: node["ejabberd"]["stun_turn_port_tls"],
listening_ip: node["ipaddress"],
relay_ip: node["ipaddress"],
min_port: node["ejabberd"]["turn_min_port"],
max_port: node["ejabberd"]["turn_max_port"],
realm: node["ejabberd"]["stun_auth_realm"],
static_auth_secret: credentials["stun_secret"],
cert: "/etc/letsencrypt/live/#{domain}/fullchain.pem",
pkey: "/etc/letsencrypt/live/#{domain}/privkey.pem"
notifies :restart, "service[coturn]", :delayed
end
firewall_rule 'ejabberd_stun_turn' do
port node["ejabberd"]["stun_turn_port"]
protocol :udp
command :allow
end
firewall_rule 'ejabberd_stun_turn_tls' do
port node["ejabberd"]["stun_turn_port_tls"]
protocol :tcp
command :allow
end
firewall_rule 'ejabberd_turn' do
port node["ejabberd"]["turn_min_port"]..node["ejabberd"]["turn_max_port"]
protocol :udp
command :allow
end
service "coturn" do
action [:enable, :start]
end

View File

@@ -154,6 +154,11 @@ admin_users = ejabberd_credentials['admins']
hosts.each do |host|
ldap_rootdn = "uid=service,ou=#{host[:name]},cn=applications,dc=kosmos,dc=org"
if host[:name] == "kosmos.org"
ldap_filter = "(&(objectClass=person)(serviceEnabled=xmpp))"
else
ldap_filter = "(objectClass=person)"
end
template "/opt/ejabberd/conf/#{host[:name]}.yml" do
source "vhost.yml.erb"
@@ -167,7 +172,8 @@ hosts.each do |host|
ldap_base: ldap_base,
ldap_server: ldap_domain,
ldap_rootdn: ldap_rootdn,
ldap_encryption_type: ldap_encryption_type
ldap_encryption_type: ldap_encryption_type,
ldap_filter: ldap_filter
notifies :reload, "service[ejabberd]", :delayed
end
end
@@ -183,10 +189,10 @@ template "/opt/ejabberd/conf/ejabberd.yml" do
sensitive true
variables hosts: hosts,
admin_users: admin_users,
stun_auth_realm: "kosmos.org",
turn_domain: node["ejabberd"]["turn_domain"],
stun_secret: ejabberd_credentials['stun_secret'],
turn_ip_address: node["ejabberd"]["turn_ip_address"],
stun_turn_port: node["ejabberd"]["stun_turn_port"],
stun_turn_port_tls: node["ejabberd"]["stun_turn_port_tls"],
turn_min_port: node["ejabberd"]["turn_min_port"],
turn_max_port: node["ejabberd"]["turn_max_port"],
private_ip_address: node["knife_zero"]["host"],

View File

@@ -33,11 +33,11 @@ file "/etc/letsencrypt/renewal-hooks/post/ejabberd" do
group "root"
end
gandi_api_data_bag_item = data_bag_item('credentials', 'gandi_api_5apps')
gandi_api_credentials = data_bag_item('credentials', 'gandi_api')
template "/root/gandi_dns_certbot_hook.sh" do
variables gandi_api_key: gandi_api_data_bag_item["key"]
mode 0770
variables access_token: gandi_api_credentials["access_token"]
mode 0700
end
# Generate a Let's Encrypt cert (only if no cert has been generated before).
@@ -52,7 +52,7 @@ end
# Generate a Let's Encrypt cert (only if no cert has been generated before).
# The systemd timer will take care of renewing
execute "letsencrypt cert for 5apps xmpp" do
command "certbot certonly --manual --preferred-challenges dns --manual-public-ip-logging-ok --agree-tos --manual-auth-hook \"/root/gandi_dns_certbot_hook.sh auth\" --manual-cleanup-hook \"/root/gandi_dns_certbot_hook.sh cleanup\" --deploy-hook \"/etc/letsencrypt/renewal-hooks/post/ejabberd\" --email ops@5apps.com -d 5apps.com -d muc.5apps.com -d xmpp.5apps.com -d uploads.xmpp.5apps.com -n"
command "certbot certonly --manual --preferred-challenges dns --manual-public-ip-logging-ok --agree-tos --manual-auth-hook \"/root/gandi_dns_certbot_hook.sh auth letsencrypt.kosmos.chat\" --manual-cleanup-hook \"/root/gandi_dns_certbot_hook.sh cleanup letsencrypt.kosmos.chat\" --deploy-hook \"/etc/letsencrypt/renewal-hooks/post/ejabberd\" --email ops@5apps.com -d 5apps.com -d muc.5apps.com -d xmpp.5apps.com -d uploads.xmpp.5apps.com -n"
not_if do
File.exist?("/etc/letsencrypt/live/5apps.com/fullchain.pem")
end

View File

@@ -19,7 +19,7 @@ end
openresty_stream "ejabberd" do
template "nginx_conf_streams.erb"
variables ejabberd_hosts: ["10.1.1.113"],
variables ejabberd_hosts: ["10.1.1.123"],
stun_turn_port: node["ejabberd"]["stun_turn_port"],
turn_min_port: node["ejabberd"]["turn_min_port"],
turn_max_port: node["ejabberd"]["turn_max_port"]

View File

@@ -87,16 +87,6 @@ listen:
## "/pub/archive": mod_http_fileserver
## register: true
captcha: false
-
port: <%= @stun_turn_port %>
transport: udp
module: ejabberd_stun
auth_realm: <%= @stun_auth_realm %>
use_turn: true
tls: false
turn_ipv4_address: <%= @turn_ip_address %>
turn_min_port: <%= @turn_min_port %>
turn_max_port: <%= @turn_max_port %>
s2s_use_starttls: optional
@@ -106,8 +96,10 @@ auth_method: sql
default_db: sql
shaper:
normal: 1000
fast: 50000
normal:
rate: 3000
burst_size: 20000
fast: 100000
max_fsm_queue: 10000
@@ -131,7 +123,7 @@ shaper_rules:
max_user_sessions: 10
max_user_offline_messages:
- 5000: admin
- 100
- 1000
c2s_shaper:
- none: admin
- normal
@@ -238,20 +230,34 @@ modules:
store_current_id: true
mod_shared_roster: {}
mod_stun_disco:
offer_local_services: false
credentials_lifetime: 300
secret: <%= @stun_secret %>
services:
-
host: <%= @turn_ip_address %>
host: <%= @turn_domain %>
port: <%= @stun_turn_port %>
type: stun
transport: udp
restricted: false
-
host: <%= @turn_ip_address %>
host: <%= @turn_domain %>
port: <%= @stun_turn_port_tls %>
type: stuns
transport: tcp
restricted: false
-
host: <%= @turn_domain %>
port: <%= @stun_turn_port %>
type: turn
transport: udp
restricted: true
-
host: <%= @turn_domain %>
port: <%= @stun_turn_port_tls %>
type: turns
transport: tcp
restricted: true
mod_vcard:
search: false
mod_vcard_xupdate: {}

View File

@@ -1,21 +1,16 @@
#!/usr/bin/env bash
#
set -euf -o pipefail
# ************** USAGE **************
#
# Example usage (with this hook file saved in /root/):
# Example usage:
#
# sudo su -
# certbot certonly --manual --preferred-challenges dns --manual-public-ip-logging-ok --agree-tos -d "5apps.com" -d muc.5apps.com -d "xmpp.5apps.com" \
# --manual-auth-hook "/root/letsencrypt_hook.sh auth" --manual-cleanup-hook "/root/letsencrypt_hook.sh cleanup"
#
# This hook requires configuration, continue reading.
#
# ************** CONFIGURATION **************
#
# GANDI_API_KEY: Your Gandi Live API key
# ACCESS_TOKEN: Your Gandi Live API key
#
# PROVIDER_UPDATE_DELAY:
# How many seconds to wait after updating your DNS records. This may be required,
@@ -25,10 +20,16 @@ set -euf -o pipefail
#
# Defaults to 30 seconds.
#
GANDI_API_KEY="<%= @gandi_api_key %>"
PROVIDER_UPDATE_DELAY=30
# VALIDATION_DOMAIN:
# Domain to create ACME DNS entries on. Use this when redirecting ACME subdomains
# from the original domain to a proxy validation domain that we control.
#
ACCESS_TOKEN="<%= @access_token %>"
PROVIDER_UPDATE_DELAY=10
VALIDATION_DOMAIN="${2:-}"
regex='.*\.(.*\..*)'
if [[ $CERTBOT_DOMAIN =~ $regex ]]
then
DOMAIN="${BASH_REMATCH[1]}"
@@ -36,25 +37,41 @@ else
DOMAIN="${CERTBOT_DOMAIN}"
fi
if [[ -n "$VALIDATION_DOMAIN" ]]
then
if [[ $VALIDATION_DOMAIN =~ $regex ]]
then
ACME_BASE_DOMAIN="${BASH_REMATCH[1]}"
else
echo "Validation domain has to be a subdomain, but it is not: \"${VALIDATION_DOMAIN}\""
exit 1
fi
ACME_DOMAIN="${CERTBOT_DOMAIN}.${VALIDATION_DOMAIN}"
else
ACME_BASE_DOMAIN="${DOMAIN}"
ACME_DOMAIN="_acme-challenge.${CERTBOT_DOMAIN}"
fi
# To be invoked via Certbot's --manual-auth-hook
function auth {
curl -s -D- -H "Content-Type: application/json" \
-H "X-Api-Key: ${GANDI_API_KEY}" \
-d "{\"rrset_name\": \"_acme-challenge.${CERTBOT_DOMAIN}.\",
\"rrset_type\": \"TXT\",
\"rrset_ttl\": 3600,
\"rrset_values\": [\"${CERTBOT_VALIDATION}\"]}" \
"https://dns.api.gandi.net/api/v5/domains/${DOMAIN}/records"
curl -s -D- \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-d "{\"rrset_name\": \"${ACME_DOMAIN}.\",
\"rrset_type\": \"TXT\",
\"rrset_ttl\": 300,
\"rrset_values\": [\"${CERTBOT_VALIDATION}\"]}" \
"https://api.gandi.net/v5/livedns/domains/${ACME_BASE_DOMAIN}/records"
sleep ${PROVIDER_UPDATE_DELAY}
sleep ${PROVIDER_UPDATE_DELAY}
}
# To be invoked via Certbot's --manual-cleanup-hook
function cleanup {
curl -s -X DELETE -H "Content-Type: application/json" \
-H "X-Api-Key: ${GANDI_API_KEY}" \
https://dns.api.gandi.net/api/v5/domains/${DOMAIN}/records/_acme-challenge.${CERTBOT_DOMAIN}./TXT
curl -s -X DELETE \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
"https://api.gandi.net/v5/livedns/domains/${ACME_BASE_DOMAIN}/records/${ACME_DOMAIN}./TXT"
}
HANDLER=$1; shift;

View File

@@ -0,0 +1,708 @@
# Coturn TURN SERVER configuration file
#
# Boolean values note: where boolean value is supposed to be used,
# you can use '0', 'off', 'no', 'false', 'f' as 'false,
# and you can use '1', 'on', 'yes', 'true', 't' as 'true'
# If the value is missed, then it means 'true'.
#
# Listener interface device (optional, Linux only).
# NOT RECOMMENDED.
#
#listening-device=eth0
# TURN listener port for UDP and TCP (Default: 3478).
# Note: actually, TLS & DTLS sessions can connect to the
# "plain" TCP & UDP port(s), too - if allowed by configuration.
#
listening-port=<%= @listening_port %>
# TURN listener port for TLS (Default: 5349).
# Note: actually, "plain" TCP & UDP sessions can connect to the TLS & DTLS
# port(s), too - if allowed by configuration. The TURN server
# "automatically" recognizes the type of traffic. Actually, two listening
# endpoints (the "plain" one and the "tls" one) are equivalent in terms of
# functionality; but we keep both endpoints to satisfy the RFC 5766 specs.
# For secure TCP connections, we currently support SSL version 3 and
# TLS version 1.0, 1.1 and 1.2.
# For secure UDP connections, we support DTLS version 1.
#
tls-listening-port=<%= @tls_listening_port %>
# Alternative listening port for UDP and TCP listeners;
# default (or zero) value means "listening port plus one".
# This is needed for RFC 5780 support
# (STUN extension specs, NAT behavior discovery). The TURN Server
# supports RFC 5780 only if it is started with more than one
# listening IP address of the same family (IPv4 or IPv6).
# RFC 5780 is supported only by UDP protocol, other protocols
# are listening to that endpoint only for "symmetry".
#
#alt-listening-port=0
# Alternative listening port for TLS and DTLS protocols.
# Default (or zero) value means "TLS listening port plus one".
#
#alt-tls-listening-port=0
# Listener IP address of relay server. Multiple listeners can be specified.
# If no IP(s) specified in the config file or in the command line options,
# then all IPv4 and IPv6 system IPs will be used for listening.
#
listening-ip=<%= @listening_ip %>
#listening-ip=10.207.21.238
#listening-ip=2607:f0d0:1002:51::4
# Auxiliary STUN/TURN server listening endpoint.
# Aux servers have almost full TURN and STUN functionality.
# The (minor) limitations are:
#
# 1) Auxiliary servers do not have alternative ports and
# they do not support STUN RFC 5780 functionality (CHANGE REQUEST).
#
# 2) Auxiliary servers also are never returning ALTERNATIVE-SERVER reply.
#
# Valid formats are 1.2.3.4:5555 for IPv4 and [1:2::3:4]:5555 for IPv6.
#
# There may be multiple aux-server options, each will be used for listening
# to client requests.
#
#aux-server=172.17.19.110:33478
#aux-server=[2607:f0d0:1002:51::4]:33478
# (recommended for older Linuxes only)
# Automatically balance UDP traffic over auxiliary servers (if configured).
# The load balancing is using the ALTERNATE-SERVER mechanism.
# The TURN client must support 300 ALTERNATE-SERVER response for this
# functionality.
#
#udp-self-balance
# Relay interface device for relay sockets (optional, Linux only).
# NOT RECOMMENDED.
#
#relay-device=eth1
# Relay address (the local IP address that will be used to relay the
# packets to the peer).
# Multiple relay addresses may be used.
# The same IP(s) can be used as both listening IP(s) and relay IP(s).
#
# If no relay IP(s) specified, then the turnserver will apply the default
# policy: it will decide itself which relay addresses to be used, and it
# will always be using the client socket IP address as the relay IP address
# of the TURN session (if the requested relay address family is the same
# as the family of the client socket).
#
relay-ip=<%= @relay_ip %>
#relay-ip=2607:f0d0:1002:51::5
# For Amazon EC2 users:
#
# TURN Server public/private address mapping, if the server is behind NAT.
# In that situation, if a -X is used in form "-X <ip>" then that ip will be reported
# as relay IP address of all allocations. This scenario works only in a simple case
# when one single relay address is be used, and no RFC5780 functionality is required.
# That single relay address must be mapped by NAT to the 'external' IP.
# The "external-ip" value, if not empty, is returned in XOR-RELAYED-ADDRESS field.
# For that 'external' IP, NAT must forward ports directly (relayed port 12345
# must be always mapped to the same 'external' port 12345).
#
# In more complex case when more than one IP address is involved,
# that option must be used several times, each entry must
# have form "-X <public-ip/private-ip>", to map all involved addresses.
# RFC5780 NAT discovery STUN functionality will work correctly,
# if the addresses are mapped properly, even when the TURN server itself
# is behind A NAT.
#
# By default, this value is empty, and no address mapping is used.
#
#external-ip=60.70.80.91
#
#OR:
#
#external-ip=60.70.80.91/172.17.19.101
#external-ip=60.70.80.92/172.17.19.102
# Number of the relay threads to handle the established connections
# (in addition to authentication thread and the listener thread).
# If explicitly set to 0 then application runs relay process in a
# single thread, in the same thread with the listener process
# (the authentication thread will still be a separate thread).
#
# If this parameter is not set, then the default OS-dependent
# thread pattern algorithm will be employed. Usually the default
# algorithm is the most optimal, so you have to change this option
# only if you want to make some fine tweaks.
#
# In the older systems (Linux kernel before 3.9),
# the number of UDP threads is always one thread per network listening
# endpoint - including the auxiliary endpoints - unless 0 (zero) or
# 1 (one) value is set.
#
#relay-threads=0
# Lower and upper bounds of the UDP relay endpoints:
# (default values are 49152 and 65535)
#
min-port=<%= @min_port %>
max-port=<%= @max_port %>
# Uncomment to run TURN server in 'normal' 'moderate' verbose mode.
# By default the verbose mode is off.
verbose
# Uncomment to run TURN server in 'extra' verbose mode.
# This mode is very annoying and produces lots of output.
# Not recommended under any normal circumstances.
#
#Verbose
# Uncomment to use fingerprints in the TURN messages.
# By default the fingerprints are off.
#
#fingerprint
# Uncomment to use long-term credential mechanism.
# By default no credentials mechanism is used (any user allowed).
#
#lt-cred-mech
# This option is opposite to lt-cred-mech.
# (TURN Server with no-auth option allows anonymous access).
# If neither option is defined, and no users are defined,
# then no-auth is default. If at least one user is defined,
# in this file or in command line or in usersdb file, then
# lt-cred-mech is default.
#
#no-auth
# TURN REST API flag.
# (Time Limited Long Term Credential)
# Flag that sets a special authorization option that is based upon authentication secret.
#
# This feature's purpose is to support "TURN Server REST API", see
# "TURN REST API" link in the project's page
# https://github.com/coturn/coturn/
#
# This option is used with timestamp:
#
# usercombo -> "timestamp:userid"
# turn user -> usercombo
# turn password -> base64(hmac(secret key, usercombo))
#
# This allows TURN credentials to be accounted for a specific user id.
# If you don't have a suitable id, the timestamp alone can be used.
# This option is just turning on secret-based authentication.
# The actual value of the secret is defined either by option static-auth-secret,
# or can be found in the turn_secret table in the database (see below).
#
# Read more about it:
# - https://tools.ietf.org/html/draft-uberti-behave-turn-rest-00
# - https://www.ietf.org/proceedings/87/slides/slides-87-behave-10.pdf
#
# Be aware that use-auth-secret overrides some part of lt-cred-mech.
# Notice that this feature depends internally on lt-cred-mech, so if you set
# use-auth-secret then it enables internally automatically lt-cred-mech option
# like if you enable both.
#
# You can use only one of the to auth mechanisms in the same time because,
# both mechanism use the username and password validation in different way.
#
# This way be aware that you can't use both auth mechnaism in the same time!
# Use in config either the lt-cred-mech or the use-auth-secret
# to avoid any confusion.
#
use-auth-secret
# 'Static' authentication secret value (a string) for TURN REST API only.
# If not set, then the turn server
# will try to use the 'dynamic' value in turn_secret table
# in user database (if present). The database-stored value can be changed on-the-fly
# by a separate program, so this is why that other mode is 'dynamic'.
#
static-auth-secret=<%= @static_auth_secret %>
# Server name used for
# the oAuth authentication purposes.
# The default value is the realm name.
#
#server-name=blackdow.carleon.gov
# Flag that allows oAuth authentication.
#
#oauth
# 'Static' user accounts for long term credentials mechanism, only.
# This option cannot be used with TURN REST API.
# 'Static' user accounts are NOT dynamically checked by the turnserver process,
# so that they can NOT be changed while the turnserver is running.
#
#user=username1:key1
#user=username2:key2
# OR:
#user=username1:password1
#user=username2:password2
#
# Keys must be generated by turnadmin utility. The key value depends
# on user name, realm, and password:
#
# Example:
# $ turnadmin -k -u ninefingers -r north.gov -p youhavetoberealistic
# Output: 0xbc807ee29df3c9ffa736523fb2c4e8ee
# ('0x' in the beginning of the key is what differentiates the key from
# password. If it has 0x then it is a key, otherwise it is a password).
#
# The corresponding user account entry in the config file will be:
#
#user=ninefingers:0xbc807ee29df3c9ffa736523fb2c4e8ee
# Or, equivalently, with open clear password (less secure):
#user=ninefingers:youhavetoberealistic
#
# SQLite database file name.
#
# Default file name is /var/db/turndb or /usr/local/var/db/turndb or
# /var/lib/turn/turndb.
#
#userdb=/var/db/turndb
# PostgreSQL database connection string in the case that we are using PostgreSQL
# as the user database.
# This database can be used for long-term credential mechanism
# and it can store the secret value for secret-based timed authentication in TURN RESP API.
# See http://www.postgresql.org/docs/8.4/static/libpq-connect.html for 8.x PostgreSQL
# versions connection string format, see
# http://www.postgresql.org/docs/9.2/static/libpq-connect.html#LIBPQ-CONNSTRING
# for 9.x and newer connection string formats.
#
#psql-userdb="host=<host> dbname=<database-name> user=<database-user> password=<database-user-password> connect_timeout=30"
# MySQL database connection string in the case that we are using MySQL
# as the user database.
# This database can be used for long-term credential mechanism
# and it can store the secret value for secret-based timed authentication in TURN RESP API.
#
# Optional connection string parameters for the secure communications (SSL):
# ca, capath, cert, key, cipher
# (see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the
# command options description).
#
# Use string format as below (space separated parameters, all optional):
#
#mysql-userdb="host=<host> dbname=<database-name> user=<database-user> password=<database-user-password> port=<port> connect_timeout=<seconds> read_timeout=<seconds>"
# If you want to use in the MySQL connection string the password in encrypted format,
# then set in this option the MySQL password encryption secret key file.
#
# Warning: If this option is set, then mysql password must be set in "mysql-userdb" in encrypted format!
# If you want to use cleartext password then do not set this option!
#
# This is the file path which contain secret key of aes encryption while using password encryption.
#
#secret-key-file=/path/
# MongoDB database connection string in the case that we are using MongoDB
# as the user database.
# This database can be used for long-term credential mechanism
# and it can store the secret value for secret-based timed authentication in TURN RESP API.
# Use string format is described at http://hergert.me/docs/mongo-c-driver/mongoc_uri.html
#
#mongo-userdb="mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]"
# Redis database connection string in the case that we are using Redis
# as the user database.
# This database can be used for long-term credential mechanism
# and it can store the secret value for secret-based timed authentication in TURN RESP API.
# Use string format as below (space separated parameters, all optional):
#
#redis-userdb="ip=<ip-address> dbname=<database-number> password=<database-user-password> port=<port> connect_timeout=<seconds>"
# Redis status and statistics database connection string, if used (default - empty, no Redis stats DB used).
# This database keeps allocations status information, and it can be also used for publishing
# and delivering traffic and allocation event notifications.
# The connection string has the same parameters as redis-userdb connection string.
# Use string format as below (space separated parameters, all optional):
#
#redis-statsdb="ip=<ip-address> dbname=<database-number> password=<database-user-password> port=<port> connect_timeout=<seconds>"
# The default realm to be used for the users when no explicit
# origin/realm relationship was found in the database, or if the TURN
# server is not using any database (just the commands-line settings
# and the userdb file). Must be used with long-term credentials
# mechanism or with TURN REST API.
#
# Note: If default realm is not specified at all, then realm falls back to the host domain name.
# If domain name is empty string, or '(None)', then it is initialized to am empty string.
#
realm=<%= @realm %>
# The flag that sets the origin consistency
# check: across the session, all requests must have the same
# main ORIGIN attribute value (if the ORIGIN was
# initially used by the session).
#
#check-origin-consistency
# Per-user allocation quota.
# default value is 0 (no quota, unlimited number of sessions per user).
# This option can also be set through the database, for a particular realm.
#
#user-quota=0
# Total allocation quota.
# default value is 0 (no quota).
# This option can also be set through the database, for a particular realm.
#
#total-quota=0
# Max bytes-per-second bandwidth a TURN session is allowed to handle
# (input and output network streams are treated separately). Anything above
# that limit will be dropped or temporary suppressed (within
# the available buffer limits).
# This option can also be set through the database, for a particular realm.
#
#max-bps=0
#
# Maximum server capacity.
# Total bytes-per-second bandwidth the TURN server is allowed to allocate
# for the sessions, combined (input and output network streams are treated separately).
#
# bps-capacity=0
# Uncomment if no UDP client listener is desired.
# By default UDP client listener is always started.
#
#no-udp
# Uncomment if no TCP client listener is desired.
# By default TCP client listener is always started.
#
#no-tcp
# Uncomment if no TLS client listener is desired.
# By default TLS client listener is always started.
#
#no-tls
# Uncomment if no DTLS client listener is desired.
# By default DTLS client listener is always started.
#
#no-dtls
# Uncomment if no UDP relay endpoints are allowed.
# By default UDP relay endpoints are enabled (like in RFC 5766).
#
#no-udp-relay
# Uncomment if no TCP relay endpoints are allowed.
# By default TCP relay endpoints are enabled (like in RFC 6062).
#
#no-tcp-relay
# Uncomment if extra security is desired,
# with nonce value having limited lifetime.
# By default, the nonce value is unique for a session,
# and has unlimited lifetime.
# Set this option to limit the nonce lifetime.
# It defaults to 600 secs (10 min) if no value is provided. After that delay,
# the client will get 438 error and will have to re-authenticate itself.
#
#stale-nonce=600
# Uncomment if you want to set the maximum allocation
# time before it has to be refreshed.
# Default is 3600s.
#
#max-allocate-lifetime=3600
# Uncomment to set the lifetime for the channel.
# Default value is 600 secs (10 minutes).
# This value MUST not be changed for production purposes.
#
#channel-lifetime=600
# Uncomment to set the permission lifetime.
# Default to 300 secs (5 minutes).
# In production this value MUST not be changed,
# however it can be useful for test purposes.
#
#permission-lifetime=300
# Certificate file.
# Use an absolute path or path relative to the
# configuration file.
#
cert=<%= @cert %>
# Private key file.
# Use an absolute path or path relative to the
# configuration file.
# Use PEM file format.
#
pkey=<%= @pkey %>
# Private key file password, if it is in encoded format.
# This option has no default value.
#
#pkey-pwd=...
# Allowed OpenSSL cipher list for TLS/DTLS connections.
# Default value is "DEFAULT".
#
#cipher-list="DEFAULT"
# CA file in OpenSSL format.
# Forces TURN server to verify the client SSL certificates.
# By default it is not set: there is no default value and the client
# certificate is not checked.
#
# Example:
#CA-file=/etc/ssh/id_rsa.cert
# Curve name for EC ciphers, if supported by OpenSSL
# library (TLS and DTLS). The default value is prime256v1,
# if pre-OpenSSL 1.0.2 is used. With OpenSSL 1.0.2+,
# an optimal curve will be automatically calculated, if not defined
# by this option.
#
#ec-curve-name=prime256v1
# Use 566 bits predefined DH TLS key. Default size of the key is 1066.
#
#dh566
# Use 2066 bits predefined DH TLS key. Default size of the key is 1066.
#
#dh2066
# Use custom DH TLS key, stored in PEM format in the file.
# Flags --dh566 and --dh2066 are ignored when the DH key is taken from a file.
#
#dh-file=<DH-PEM-file-name>
# Flag to prevent stdout log messages.
# By default, all log messages are going to both stdout and to
# the configured log file. With this option everything will be
# going to the configured log only (unless the log file itself is stdout).
#
#no-stdout-log
# Option to set the log file name.
# By default, the turnserver tries to open a log file in
# /var/log, /var/tmp, /tmp and current directories directories
# (which open operation succeeds first that file will be used).
# With this option you can set the definite log file name.
# The special names are "stdout" and "-" - they will force everything
# to the stdout. Also, the "syslog" name will force everything to
# the system log (syslog).
# In the runtime, the logfile can be reset with the SIGHUP signal
# to the turnserver process.
#
#log-file=/var/tmp/turn.log
# Option to redirect all log output into system log (syslog).
#
syslog
# This flag means that no log file rollover will be used, and the log file
# name will be constructed as-is, without PID and date appendage.
# This option can be used, for example, together with the logrotate tool.
#
#simple-log
# Option to set the "redirection" mode. The value of this option
# will be the address of the alternate server for UDP & TCP service in form of
# <ip>[:<port>]. The server will send this value in the attribute
# ALTERNATE-SERVER, with error 300, on ALLOCATE request, to the client.
# Client will receive only values with the same address family
# as the client network endpoint address family.
# See RFC 5389 and RFC 5766 for ALTERNATE-SERVER functionality description.
# The client must use the obtained value for subsequent TURN communications.
# If more than one --alternate-server options are provided, then the functionality
# can be more accurately described as "load-balancing" than a mere "redirection".
# If the port number is omitted, then the default port
# number 3478 for the UDP/TCP protocols will be used.
# Colon (:) characters in IPv6 addresses may conflict with the syntax of
# the option. To alleviate this conflict, literal IPv6 addresses are enclosed
# in square brackets in such resource identifiers, for example:
# [2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478 .
# Multiple alternate servers can be set. They will be used in the
# round-robin manner. All servers in the pool are considered of equal weight and
# the load will be distributed equally. For example, if we have 4 alternate servers,
# then each server will receive 25% of ALLOCATE requests. A alternate TURN server
# address can be used more than one time with the alternate-server option, so this
# can emulate "weighting" of the servers.
#
# Examples:
#alternate-server=1.2.3.4:5678
#alternate-server=11.22.33.44:56789
#alternate-server=5.6.7.8
#alternate-server=[2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478
# Option to set alternative server for TLS & DTLS services in form of
# <ip>:<port>. If the port number is omitted, then the default port
# number 5349 for the TLS/DTLS protocols will be used. See the previous
# option for the functionality description.
#
# Examples:
#tls-alternate-server=1.2.3.4:5678
#tls-alternate-server=11.22.33.44:56789
#tls-alternate-server=[2001:db8:85a3:8d3:1319:8a2e:370:7348]:3478
# Option to suppress TURN functionality, only STUN requests will be processed.
# Run as STUN server only, all TURN requests will be ignored.
# By default, this option is NOT set.
#
#stun-only
# Option to suppress STUN functionality, only TURN requests will be processed.
# Run as TURN server only, all STUN requests will be ignored.
# By default, this option is NOT set.
#
#no-stun
# This is the timestamp/username separator symbol (character) in TURN REST API.
# The default value is ':'.
# rest-api-separator=:
# Flag that can be used to allow peers on the loopback addresses (127.x.x.x and ::1).
# This is an extra security measure.
#
# (To avoid any security issue that allowing loopback access may raise,
# the no-loopback-peers option is replaced by allow-loopback-peers.)
#
# Allow it only for testing in a development environment!
# In production it adds a possible security vulnerability, so for security reasons
# it is not allowed using it together with empty cli-password.
#
#allow-loopback-peers
# Flag that can be used to disallow peers on well-known broadcast addresses (224.0.0.0 and above, and FFXX:*).
# This is an extra security measure.
#
#no-multicast-peers
# Option to set the max time, in seconds, allowed for full allocation establishment.
# Default is 60 seconds.
#
#max-allocate-timeout=60
# Option to allow or ban specific ip addresses or ranges of ip addresses.
# If an ip address is specified as both allowed and denied, then the ip address is
# considered to be allowed. This is useful when you wish to ban a range of ip
# addresses, except for a few specific ips within that range.
#
# This can be used when you do not want users of the turn server to be able to access
# machines reachable by the turn server, but would otherwise be unreachable from the
# internet (e.g. when the turn server is sitting behind a NAT)
#
# Examples:
# denied-peer-ip=83.166.64.0-83.166.95.255
# allowed-peer-ip=83.166.68.45
# File name to store the pid of the process.
# Default is /var/run/turnserver.pid (if superuser account is used) or
# /var/tmp/turnserver.pid .
#
#pidfile="/var/run/turnserver.pid"
# Require authentication of the STUN Binding request.
# By default, the clients are allowed anonymous access to the STUN Binding functionality.
#
#secure-stun
# Mobility with ICE (MICE) specs support.
#
#mobility
# Allocate Address Family according
# If enabled then TURN server allocates address family according the TURN
# Client <=> Server communication address family.
# (By default coTURN works according RFC 6156.)
# !!Warning: Enabling this option breaks RFC6156 section-4.2 (violates use default IPv4)!!
#
#keep-address-family
# User name to run the process. After the initialization, the turnserver process
# will make an attempt to change the current user ID to that user.
#
#proc-user=<user-name>
# Group name to run the process. After the initialization, the turnserver process
# will make an attempt to change the current group ID to that group.
#
#proc-group=<group-name>
# Turn OFF the CLI support.
# By default it is always ON.
# See also options cli-ip and cli-port.
#
no-cli
#Local system IP address to be used for CLI server endpoint. Default value
# is 127.0.0.1.
#
#cli-ip=127.0.0.1
# CLI server port. Default is 5766.
#
#cli-port=5766
# CLI access password. Default is empty (no password).
# For the security reasons, it is recommended to use the encrypted
# for of the password (see the -P command in the turnadmin utility).
#
# Secure form for password 'qwerty':
#
#cli-password=$5$79a316b350311570$81df9cfb9af7f5e5a76eada31e7097b663a0670f99a3c07ded3f1c8e59c5658a
#
# Or unsecure form for the same password:
#
#cli-password=qwerty
# Enable Web-admin support on https. By default it is Disabled.
# If it is enabled it also enables a http a simple static banner page
# with a small reminder that the admin page is available only on https.
#
#web-admin
# Local system IP address to be used for Web-admin server endpoint. Default value is 127.0.0.1.
#
#web-admin-ip=127.0.0.1
# Web-admin server port. Default is 8080.
#
#web-admin-port=8080
# Web-admin server listen on STUN/TURN worker threads
# By default it is disabled for security resons! (Not recommended in any production environment!)
#
#web-admin-listen-on-workers
# Server relay. NON-STANDARD AND DANGEROUS OPTION.
# Only for those applications when we want to run
# server applications on the relay endpoints.
# This option eliminates the IP permissions check on
# the packets incoming to the relay endpoints.
#
#server-relay
# Maximum number of output sessions in ps CLI command.
# This value can be changed on-the-fly in CLI. The default value is 256.
#
#cli-max-output-sessions
# Set network engine type for the process (for internal purposes).
#
#ne=[1|2|3]
# Do not allow an TLS/DTLS version of protocol
#
#no-tlsv1
#no-tlsv1_1
#no-tlsv1_2

View File

@@ -16,7 +16,7 @@ host_config:
ldap_password: "<%= @host[:ldap_password] %>"
ldap_encrypt: <%= @ldap_encryption_type %>
ldap_base: "ou=<%= @host[:name] %>,<%= @ldap_base %>"
ldap_filter: "(objectClass=person)"
ldap_filter: "<%= @ldap_filter %>"
<% end -%>
append_host_config:

View File

@@ -62,4 +62,4 @@ node.default['kosmos-ipfs']['ipfs']['config'] = {
node.default['kosmos-ipfs']['nginx']['domain'] = "ipfs.kosmos.org"
node.default['kosmos-ipfs']['nginx']['external_api_port'] = 5444
node.default['kosmos-ipfs']['kredits-pinner']['revision'] = "v2.2.0"
node.default['kosmos-ipfs']['kredits-pinner']['revision'] = "v2.3.0"

View File

@@ -44,7 +44,7 @@ end
elasticsearch_service 'elasticsearch'
postgresql_data_bag_item = data_bag_item('credentials', 'postgresql')
postgresql_credentials = data_bag_item('credentials', 'postgresql')
mastodon_path = node["kosmos-mastodon"]["directory"]
mastodon_user = "mastodon"
@@ -75,7 +75,7 @@ npm_package "yarn" do
version "1.22.4"
end
ruby_version = "3.0.6"
ruby_version = "3.3.0"
ruby_path = "/opt/ruby_build/builds/#{ruby_version}"
bundle_path = "#{ruby_path}/bin/bundle"
@@ -168,7 +168,22 @@ execute "restart mastodon services" do
notifies :restart, "service[mastodon-streaming]", :delayed
end
mastodon_credentials = data_bag_item('credentials', 'mastodon')
credentials = data_bag_item('credentials', 'mastodon')
ldap_config = {
host: "ldap.kosmos.local",
port: 389,
method: "plain",
base: "ou=kosmos.org,cn=users,dc=kosmos,dc=org",
bind_dn: credentials["ldap_bind_dn"],
password: credentials["ldap_password"],
uid: "cn",
mail: "mail",
search_filter: "(&(|(cn=%{email})(mail=%{email}))(serviceEnabled=mastodon))",
uid_conversion_enabled: "true",
uid_conversion_search: "-",
uid_conversion_replace: "_"
}
template "#{mastodon_path}/.env.#{rails_env}" do
source "env.erb"
@@ -178,21 +193,22 @@ template "#{mastodon_path}/.env.#{rails_env}" do
variables redis_url: node["kosmos-mastodon"]["redis_url"],
domain: node["kosmos-mastodon"]["domain"],
alternate_domains: node["kosmos-mastodon"]["alternate_domains"],
paperclip_secret: mastodon_credentials['paperclip_secret'],
secret_key_base: mastodon_credentials['secret_key_base'],
otp_secret: mastodon_credentials['otp_secret'],
smtp_login: mastodon_credentials['smtp_user_name'],
smtp_password: mastodon_credentials['smtp_password'],
paperclip_secret: credentials['paperclip_secret'],
secret_key_base: credentials['secret_key_base'],
otp_secret: credentials['otp_secret'],
ldap: ldap_config,
smtp_login: credentials['smtp_user_name'],
smtp_password: credentials['smtp_password'],
smtp_from_address: "mail@#{node['kosmos-mastodon']['domain']}",
s3_endpoint: node["kosmos-mastodon"]["s3_endpoint"],
s3_region: node["kosmos-mastodon"]["s3_region"],
s3_bucket: node["kosmos-mastodon"]["s3_bucket"],
s3_alias_host: node["kosmos-mastodon"]["s3_alias_host"],
aws_access_key_id: mastodon_credentials['s3_key_id'],
aws_secret_access_key: mastodon_credentials['s3_secret_key'],
vapid_private_key: mastodon_credentials['vapid_private_key'],
vapid_public_key: mastodon_credentials['vapid_public_key'],
db_pass: postgresql_data_bag_item['mastodon_user_password'],
aws_access_key_id: credentials['s3_key_id'],
aws_secret_access_key: credentials['s3_secret_key'],
vapid_private_key: credentials['vapid_private_key'],
vapid_public_key: credentials['vapid_public_key'],
db_pass: postgresql_credentials['mastodon_user_password'],
db_host: "pg.kosmos.local",
default_locale: node["kosmos-mastodon"]["default_locale"],
allowed_private_addresses: node["kosmos-mastodon"]["allowed_private_addresses"],

View File

@@ -34,6 +34,7 @@ end
tls_cert_for server_name do
auth "gandi_dns"
acme_domain "letsencrypt.kosmos.org"
action :create
end

View File

@@ -29,6 +29,23 @@ SMTP_LOGIN=<%= @smtp_login %>
SMTP_PASSWORD=<%= @smtp_password %>
SMTP_FROM_ADDRESS=<%= @smtp_from_address %>
<% if @ldap %>
# LDAP configuration
LDAP_ENABLED=true
LDAP_HOST=<%= @ldap[:host] %>
LDAP_PORT=<%= @ldap[:port] %>
LDAP_METHOD='<%= @ldap[:method] %>'
LDAP_BASE='<%= @ldap[:base] %>'
LDAP_BIND_DN='<%= @ldap[:bind_dn] %>'
LDAP_PASSWORD='<%= @ldap[:password] %>'
LDAP_UID=<%= @ldap[:uid] %>
LDAP_MAIL=<%= @ldap[:mail] %>
LDAP_SEARCH_FILTER='<%= @ldap[:search_filter] %>'
LDAP_UID_CONVERSION_ENABLED=<%= @ldap[:uid_conversion_enabled] %>
LDAP_UID_CONVERSION_SEARCH=<%= @ldap[:uid_conversion_search] %>
LDAP_UID_CONVERSION_REPLACE=<%= @ldap[:uid_conversion_replace] %>
<% end %>
# Optional asset host for multi-server setups
# CDN_HOST=assets.example.com

View File

@@ -32,6 +32,12 @@ server {
<% if @onion_address %>
add_header Onion-Location https://mastodon.<%= @onion_address %>$request_uri;
<% end %>
location ~ ^/.well-known/(lnurlp|keysend) {
add_header 'Access-Control-Allow-Origin' '*';
proxy_ssl_server_name on;
proxy_pass https://accounts.kosmos.org;
}
}
<% if @onion_address %>

View File

@@ -1,4 +1,9 @@
node.default["email"]["domain"] = "example.com"
node.default["email"]["hostname"] = "mail.example.com"
# node.default["email"]["user"] = "ray"
# node.default["email"]["group"] = "email"
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

@@ -7,4 +7,5 @@ version '0.1.0'
chef_version '>= 18.0'
depends "hostname"
depends "unbound"
depends "postfix"

View File

@@ -5,13 +5,28 @@
domain = node["email"]["domain"]
hostname = node["email"]["hostname"]
root_dir = node["email"]["root_directory"]
ip_addr = node["knife_zero"]["host"]
extra_hostnames = ["smtp.#{domain}", "imap.#{domain}"]
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
domain ([hostname]+extra_hostnames)
auth "gandi_dns"
deploy_hook "systemctl reload postfix.service && systemctl reload dovecot.service"
action :create
end
@@ -21,5 +36,8 @@ firewall_rule "private network access" do
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

@@ -15,15 +15,13 @@ end
domain = node["email"]["domain"]
hostname = node["email"]["hostname"]
root_dir = node["email"]["root_directory"]
ip_addr = node["knife_zero"]["host"]
credentials = Chef::EncryptedDataBagItem.load('credentials', 'email')
ldap_search_base = node["email"]["ldap_search_base"]
ldap_user_filter = "(&(objectClass=person)(mailRoutingAddress=%u))"
user "vmail" do
gid "mail"
system true
manage_home false
end
credentials = Chef::EncryptedDataBagItem.load('credentials', 'email')
template "/etc/dovecot/dovecot.conf" do
source "dovecot.conf.erb"
@@ -41,11 +39,11 @@ template "/etc/dovecot/dovecot-ldap.conf.ext" do
variables uris: "ldap://ldap.kosmos.local", # TODO add list of all IPs instead?
dn: credentials['ldap_dn'],
dnpass: credentials['ldap_dnpass'],
base: "ou=kosmos.org,cn=users,dc=kosmos,dc=org",
user_attrs: "mailhome=home",
user_filter: "(&(objectClass=person)(cn=%u))",
pass_attrs: "cn=user,mailpassword=password",
pass_filter: "(&(objectClass=person)(cn=%u))",
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
@@ -60,7 +58,9 @@ 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_gid: "mail",
mail_location: "mbox:~/mail:INBOX=~/mail/INBOX",
mail_home: "#{root_dir}/%d/%n"
notifies :restart, "service[dovecot]", :delayed
end
@@ -79,6 +79,12 @@ template "/etc/dovecot/conf.d/10-ssl.conf" do
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,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

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