Merge branch 'master' into feature/145-sockethub_from_npm

This commit is contained in:
Greg Karékinian
2021-07-09 10:51:02 +02:00
465 changed files with 13043 additions and 6361 deletions

View File

@@ -62,12 +62,6 @@ cron "default backup model" do
end
include_recipe 'logrotate'
# Install MySQL client (includes mysqldump)
mysql_client 'default' do
action :create
version '5.7' if node[:platform_version].to_f == 18.04
not_if { node["backup"]["mysql"]["databases"].empty? }
end
# Write the credentials file to allow dumps without password for the root
# user (https://dev.mysql.com/doc/refman/5.7/en/option-files.html)

View File

@@ -1,3 +1,4 @@
node.default['akkounts-api']['revision'] = 'master'
node.default['akkounts-api']['port'] = 3200
node.default['akkounts-api']['server_name'] = 'api.accounts.kosmos.org'
node.default['akkounts']['repo'] = 'https://gitea.kosmos.org/kosmos/akkounts.git'
node.default['akkounts']['revision'] = 'master'
node.default['akkounts']['port'] = 3000
node.default['akkounts']['domain'] = 'accounts.kosmos.org'

View File

@@ -2,13 +2,17 @@ name 'kosmos-akkounts'
maintainer 'Kosmos Developers'
maintainer_email 'mail@kosmos.org'
license 'MIT'
description 'Installs/Configures kosmos-akkounts'
long_description 'Installs/Configures kosmos-akkounts'
version '0.1.0'
description 'Installs/configures kosmos-akkounts'
long_description 'Installs/configures kosmos-akkounts'
version '0.2.0'
chef_version '>= 14.0'
depends 'application_javascript'
depends 'application_git'
depends 'kosmos-nodejs'
depends 'kosmos-mastodon'
depends 'kosmos-nginx'
depends "kosmos-nodejs"
depends "kosmos-redis"
depends "poise-ruby-build"
depends "application"
depends 'application_git'
depends "postgresql"
depends "kosmos-postgresql"
depends "backup"

View File

@@ -2,33 +2,12 @@
# Cookbook:: kosmos-akkounts
# Recipe:: default
#
# The MIT License (MIT)
#
# Copyright:: 2019, Kosmos Developers
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
require 'ipaddr'
include_recipe 'kosmos-nodejs'
app_name = "akkounts-api"
app_name = "akkounts"
deploy_user = "deploy"
deploy_group = "deploy"
deploy_path = "/opt/#{app_name}"
credentials = Chef::EncryptedDataBagItem.load('credentials', app_name)
group deploy_group
@@ -37,77 +16,162 @@ user deploy_user do
group deploy_group
manage_home true
shell "/bin/bash"
comment "deploy user"
end
path_to_deploy = "/opt/#{app_name}"
application path_to_deploy do
package "libpq-dev"
include_recipe 'kosmos-nodejs'
include_recipe "kosmos-redis"
npm_package "yarn" do
version "1.22.4"
end
ruby_version = "2.6.6"
bundle_path = "/opt/ruby_build/builds/#{ruby_version}/bin/bundle"
rails_env = node.chef_environment == "development" ? "development" : "production"
systemd_unit "akkounts.service" do
content({
Unit: {
Description: "Kosmos Accounts",
Documentation: ["https://gitea.kosmos.org/kosmos/akkounts"],
After: "network.target"
},
Service: {
Type: "simple",
User: deploy_user,
WorkingDirectory: deploy_path,
Environment: "RAILS_ENV=#{rails_env}",
ExecStart: "#{bundle_path} exec puma -C config/puma.rb --pidfile #{deploy_path}/tmp/puma.pid",
ExecStop: "#{bundle_path} exec puma -C config/puma.rb --pidfile #{deploy_path}/tmp/puma.pid stop",
ExecReload: "#{bundle_path} exec pumactl -F config/puma.rb --pidfile #{deploy_path}/tmp/puma.pid phased-restart",
PIDFile: "#{deploy_path}/tmp/puma.pid",
TimeoutSec: "10",
Restart: "always",
},
Install: {
WantedBy: "multi-user.target"
}
})
verify false
triggers_reload true
action [:create, :enable]
end
systemd_unit "akkounts-sidekiq.service" do
content({
Unit: {
Description: "Kosmos Accounts async/background jobs",
Documentation: ["https://gitea.kosmos.org/kosmos/akkounts"],
Requires: "redis-server.service",
After: "syslog.target network.target redis-server.service"
},
Service: {
Type: "notify",
User: deploy_user,
WorkingDirectory: deploy_path,
Environment: "MALLOC_ARENA_MAX=2",
ExecStart: "#{bundle_path} exec sidekiq -C #{deploy_path}/config/sidekiq.yml -e production",
WatchdogSec: "10",
Restart: "on-failure",
RestartSec: "1",
StandardOutput: "syslog",
StandardError: "syslog",
SyslogIdentifier: "sidekiq"
},
Install: {
WantedBy: "multi-user.target"
}
})
verify false
triggers_reload true
action [:create, :enable]
end
application deploy_path do
owner deploy_user
group deploy_group
# Take care of application restarts manually, in the git resource
action_on_update false
environment "HOME" => deploy_path,
"PATH" => "/opt/ruby_build/builds/#{ruby_version}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
ruby_runtime ruby_version do
provider :ruby_build
version ruby_version
end
git do
user deploy_user
group deploy_group
repository "https://github.com/67P/#{app_name}.git"
revision node[app_name]['revision']
# Restart service on deployments
notifies :restart, "application[#{path_to_deploy}]", :delayed
end
npm_install do
user deploy_user
group deploy_group
repository node[app_name]["repo"]
revision node[app_name]["revision"]
# Restart services on deployments
notifies :restart, "application[#{deploy_path}]", :delayed
end
execute "systemctl daemon-reload" do
command "systemctl daemon-reload"
action :nothing
end
smtp_credentials = Chef::EncryptedDataBagItem.load('credentials', 'smtp')
template "#{path_to_deploy}/.env" do
source "dotenv.erb"
sensitive true
file "#{deploy_path}/config/master.key" do
content credentials['rails_master_key']
mode '0400'
owner deploy_user
group deploy_group
variables btcpay_url: "https://btcpay.kosmos.org",
btcpay_privkey: credentials["btcpay_privkey"],
btcpay_merchant: credentials["btcpay_merchant"],
btcpay_store_id: credentials["btcpay_store_id"],
btcpay_webhook_host: "https://#{node[app_name]["server_name"]}",
btcpay_webhook_token: credentials["btcpay_webhook_token"],
smtp_host: "smtp.mailgun.org",
smtp_use_tls: true,
smtp_username: smtp_credentials['user_name'],
smtp_password: smtp_credentials['password'],
mastodon_host: "https://#{node["kosmos-mastodon"]["server_name"]}",
mastodon_auth_token: credentials["mastodon_auth_token"]
mode '0440'
# Restart service when the config changes
notifies :restart, "application[#{path_to_deploy}]", :delayed
end
template "/lib/systemd/system/#{app_name}.service" do
source 'nodejs.systemd.service.erb'
owner 'root'
group 'root'
mode '0640'
variables(
user: deploy_user,
group: deploy_group,
app_dir: path_to_deploy,
entry: "/usr/bin/env node release/index.js"
)
notifies :run, "execute[systemctl daemon-reload]", :delayed
notifies :restart, "service[#{app_name}]", :delayed
execute "bundle install" do
environment "HOME" => deploy_path
user deploy_user
cwd deploy_path
command "/opt/ruby_build/builds/#{ruby_version}/bin/bundle install --without development,test --deployment"
end
service app_name do
execute "yarn install" do
environment "HOME" => deploy_path, "NODE_ENV" => "production"
user deploy_user
cwd deploy_path
command "yarn install --pure-lockfile"
end
execute 'rake db:migrate' do
environment "RAILS_ENV" => rails_env, "HOME" => deploy_path
user deploy_user
group deploy_group
cwd deploy_path
command "PATH=\"/opt/ruby_build/builds/#{ruby_version}/bin:$PATH\" bundle exec rake db:migrate"
end
execute 'rake assets:precompile' do
environment "RAILS_ENV" => rails_env, "HOME" => deploy_path
user deploy_user
group deploy_group
cwd deploy_path
command "PATH=\"/opt/ruby_build/builds/#{ruby_version}/bin:$PATH\" bundle exec rake assets:precompile"
end
service "akkounts" do
action [:enable, :start]
end
service "akkounts-sidekiq" do
action [:enable, :start]
end
end
ejabberd_private_ip_addresses = []
search(:node, "role:ejabberd").each do |node|
ejabberd_private_ip_addresses << node["knife_zero"]["host"]
end
ejabberd_private_ip_addresses.each do |ip_address|
IPAddr.new ip_address
hostsfile_entry ip_address do
hostname 'xmpp.kosmos.org'
action :create
end
rescue IPAddr::InvalidAddressError
next
end
include_recipe 'kosmos-akkounts::nginx'

View File

@@ -4,7 +4,7 @@
#
# The MIT License (MIT)
#
# Copyright:: 2019, Kosmos Developers
# Copyright:: 2020, 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
@@ -25,22 +25,23 @@
# THE SOFTWARE.
include_recipe "kosmos-nginx"
app_name = "akkounts-api"
server_name = node[app_name]["server_name"]
app_name = "akkounts"
domain = node[app_name]["domain"]
template "#{node['nginx']['dir']}/sites-available/#{server_name}" do
template "#{node['nginx']['dir']}/sites-available/#{domain}" do
source "nginx_conf_#{app_name}.erb"
owner 'www-data'
mode 0640
variables port: node[app_name]['port'],
server_name: server_name,
ssl_cert: "/etc/letsencrypt/live/#{server_name}/fullchain.pem",
ssl_key: "/etc/letsencrypt/live/#{server_name}/privkey.pem"
variables port: node[app_name]['port'],
domain: domain,
root_dir: "/opt/#{app_name}/public",
ssl_cert: "/etc/letsencrypt/live/#{domain}/fullchain.pem",
ssl_key: "/etc/letsencrypt/live/#{domain}/privkey.pem"
notifies :reload, 'service[nginx]', :delayed
end
nginx_site server_name do
nginx_site domain do
action :enable
end
nginx_certbot_site server_name
nginx_certbot_site domain

View File

@@ -1,13 +0,0 @@
BTCPAY_URL=<%= @btcpay_url %>
BTCPAY_PRIVKEY=<%= @btcpay_privkey %>
BTCPAY_MERCHANT=<%= @btcpay_merchant %>
BTCPAY_STORE_ID=<%= @btcpay_store_id %>
BTCPAY_WEBHOOK_HOST=<%= @btcpay_webhook_host %>
BTCPAY_WEBHOOK_TOKEN=<%= @btcpay_webhook_token %>
SMTP_HOST=<%= @smtp_host %>
SMTP_USE_TLS=true
SMTP_USERNAME=<%= @smtp_username %>
SMTP_PASSWORD=<%= @smtp_password %>
MASTODON_HOST=<%= @mastodon_host %>
MASTODON_AUTH_TOKEN=<%= @mastodon_auth_token %>
PORT=<%= node['akkounts-api']['port'] %>

View File

@@ -1,28 +0,0 @@
# Generated by Chef
<% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%>
upstream _akkounts {
server localhost:<%= @port %>;
}
server {
listen 443 ssl http2;
add_header Strict-Transport-Security "max-age=15768000";
ssl_certificate <%= @ssl_cert %>;
ssl_certificate_key <%= @ssl_key %>;
server_name <%= @server_name %>;
access_log <%= node[:nginx][:log_dir] %>/<%= @server_name %>.access.log json;
error_log <%= node[:nginx][:log_dir] %>/<%= @server_name %>.error.log warn;
location / {
# Increase number of buffers. Default is 8
proxy_buffers 1024 8k;
proxy_pass http://_akkounts;
proxy_http_version 1.1;
}
}
<% end -%>

View File

@@ -0,0 +1,54 @@
# Generated by Chef
<% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%>
upstream _akkounts {
server localhost:<%= @port %>;
}
server {
listen 443 ssl http2;
add_header Strict-Transport-Security "max-age=15768000";
ssl_certificate <%= @ssl_cert %>;
ssl_certificate_key <%= @ssl_key %>;
server_name <%= @domain %>;
access_log <%= node[:nginx][:log_dir] %>/<%= @domain %>.access.log json;
error_log <%= node[:nginx][:log_dir] %>/<%= @domain %>.error.log warn;
root <%= @root_dir %>;
location ~ ^/(assets|packs|images|javascripts|stylesheets|swfs|system)/ {
access_log off;
gzip_static on;
expires max;
add_header Cache-Control public;
}
try_files $uri/index.html $uri @app;
location @app {
# an HTTP header important enough to have its own Wikipedia entry:
# http://en.wikipedia.org/wiki/X-Forwarded-For
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# enable this if and only if you use HTTPS, this helps Rack
# set the proper protocol for doing redirects:
proxy_set_header X-Forwarded-Proto https;
# pass the Host: header from the client right along so redirects
# can be set properly within the Rack application
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
# Increase number of buffers. Default is 8
proxy_buffers 1024 8k;
proxy_pass http://_akkounts;
proxy_http_version 1.1;
}
}
<% end -%>

View File

@@ -1,15 +0,0 @@
[Unit]
Description=Start nodejs app
[Service]
ExecStart=<%= @entry %>
WorkingDirectory=<%= @app_dir %>
User=<%= @user %>
Group=<%= @group %>
<% if @environment -%>
Environment=<% @environment.each do |key, value| -%>'<%= key %>=<%= value %>' <% end %>
<% end -%>
Restart=always
[Install]
WantedBy=multi-user.target

View File

@@ -1,7 +1,6 @@
[Unit]
Description=Certbot
Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
Documentation=https://letsencrypt.readthedocs.io/en/latest/
Documentation=https://certbot.eff.org/docs/
OnFailure=status-email-ops@%n.service
[Service]
Type=oneshot

View File

@@ -29,8 +29,17 @@ include_recipe 'timezone_iii'
include_recipe 'ntp'
include_recipe 'kosmos-base::systemd_emails'
node.override["apt"]["unattended_upgrades"]["allowed_origins"] = [
"${distro_id}:${distro_codename}-security",
"${distro_id}:${distro_codename}-updates"
]
node.override["apt"]["unattended_upgrades"]["mail"] = "ops@kosmos.org"
node.override["apt"]["unattended_upgrades"]["syslog_enable"] = true
include_recipe 'apt::unattended-upgrades'
package 'mailutils'
package 'mosh'
package 'vim'
# Don't create users and rewrite the sudo config in development environment.
# It breaks the vagrant user
@@ -55,7 +64,7 @@ unless node.chef_environment == "development"
]
end
include_recipe 'kosmos-base::firewall'
include_recipe "kosmos-base::firewall"
include_recipe 'kosmos-postfix'

View File

@@ -24,13 +24,24 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# Install certbot and set up hooks
apt_repository "certbot" do
uri "ppa:certbot/certbot"
unless platform?('ubuntu')
raise "This recipe only supports Ubuntu installs"
end
package "certbot"
if node[:platform_version].to_f < 20.04
apt_repository "certbot" do
uri "ppa:certbot/certbot"
end
package "certbot"
else
bash "install_certbot_snap" do
code "snap install --classic certbot"
end
# TODO switch to snap_package resource when they fix it
# snap_package "certbot" do
# options "--classic"
# end
end
%w(deploy post pre).each do |subdir|
directory "/etc/letsencrypt/renewal-hooks/#{subdir}" do
@@ -52,22 +63,15 @@ systemctl reload nginx
group "root"
end
gandi_api_data_bag_item = data_bag_item('credentials', 'gandi_api_5apps')
template "/root/gandi_dns_certbot_hook.sh" do
variables gandi_api_key: gandi_api_data_bag_item["key"]
mode 0770
end
include_recipe 'kosmos-base::systemd_emails'
# include_recipe 'kosmos-base::systemd_emails'
# TODO Check the deployed certs expiration dates instead of overwriting supplied systemd services
# Overwrite the systemd service to add email notifications on failures
cookbook_file "/lib/systemd/system/certbot.service" do
source "certbot.service"
notifies :run, "execute[systemctl daemon-reload]", :delayed
end
execute "systemctl daemon-reload" do
command "systemctl daemon-reload"
action :nothing
end
# cookbook_file "/lib/systemd/system/certbot.service" do
# source "certbot.service"
# notifies :run, "execute[systemctl daemon-reload]", :delayed
# end
# execute "systemctl daemon-reload" do
# command "systemctl daemon-reload"
# action :nothing
# end

View File

@@ -0,0 +1,34 @@
# Delivery for Local Phases Execution
#
# This file allows you to execute test phases locally on a workstation or
# in a CI pipeline. The delivery-cli will read this file and execute the
# command(s) that are configured for each phase. You can customize them
# by just modifying the phase key on this file.
#
# By default these phases are configured for Cookbook Workflow only
#
[local_phases]
unit = "chef exec rspec spec/"
lint = "chef exec cookstyle"
# Foodcritic includes rules only appropriate for community cookbooks
# uploaded to Supermarket. We turn off any rules tagged "supermarket"
# by default. If you plan to share this cookbook you should remove
# '-t ~supermarket' below to enable supermarket rules.
syntax = "chef exec foodcritic . -t ~supermarket"
provision = "chef exec kitchen create"
deploy = "chef exec kitchen converge"
smoke = "chef exec kitchen verify"
# The functional phase is optional, you can define it by uncommenting
# the line below and running the command: `delivery local functional`
# functional = ""
cleanup = "chef exec kitchen destroy"
# Remote project.toml file
#
# Instead of the local phases above, you may specify a remote URI location for
# the `project.toml` file. This is useful for teams that wish to centrally
# manage the behavior of the `delivery local` command across many different
# projects.
#
# remote_file = "https://url/project.toml"

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,16 @@
# Policyfile.rb - Describe how you want Chef Infra Client to build your system.
#
# For more information on the Policyfile feature, visit
# https://docs.chef.io/policyfile.html
# A name that describes what the system you're building with Chef does.
name 'kosmos-bitcoin'
# Where to find external cookbooks:
default_source :supermarket
# run_list: chef-client will run these recipes in the order specified.
run_list 'kosmos-bitcoin::default'
# Specify a custom source for a single cookbook:
cookbook 'kosmos-bitcoin', path: '.'

View File

@@ -0,0 +1,3 @@
# kosmos-bitcoin
Installs/configures bitcoin core node

View File

@@ -0,0 +1,78 @@
node.default['bitcoin']['version'] = '0.21.1'
node.default['bitcoin']['checksum'] = 'caff23449220cf45753f312cefede53a9eac64000bb300797916526236b6a1e0'
node.default['bitcoin']['username'] = 'satoshi'
node.default['bitcoin']['usergroup'] = 'bitcoin'
node.default['bitcoin']['network'] = 'mainnet'
node.default['bitcoin']['conf_path'] = '/home/satoshi/.bitcoin/bitcoin.conf'
node.default['bitcoin']['walletdir'] = '/home/satoshi/.bitcoin'
node.default['bitcoin']['datadir'] = '/mnt/data/bitcoin'
node.default['bitcoin']['conf'] = {
irc: 1,
dnsseed: 1,
upnp: 1,
checkblocks: 10,
checklevel: 1,
txindex: 1,
whitelist: '127.0.0.1',
listen: 1,
server: 1,
rpcssl: 0,
rpcuser: 'satoshi',
rpcbind: "127.0.0.1:8332",
gen: 0,
zmqpubrawblock: 'tcp://127.0.0.1:8337',
zmqpubrawtx: 'tcp://127.0.0.1:8338'
}
# Also enables Tor for LND
node.default['bitcoin']['tor_enabled'] = true
node.default['c-lightning']['repo'] = 'https://github.com/ElementsProject/lightning'
node.default['c-lightning']['revision'] = 'v0.10.0'
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'
node.default['c-lightning']['rgb'] = '0D4F99'
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.13.0-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'
node.default['lnd']['color'] = '#5e0c99'
node.default['lnd']['log_level'] = 'info'
node.default['lnd']['public_ip'] = '148.251.237.111'
node.default['lnd']['public_port'] = '9735'
node.default['lnd']['port'] = '9736'
node.default['lnd']['minchansize'] = '1000000'
node.default['lnd']['basefee'] = '1000'
node.default['lnd']['feerate'] = '50'
node.default['lnd']['auto_unlock'] = true # requires credentials/lnd data bag item
node.default['rtl']['repo'] = 'https://github.com/Ride-The-Lightning/RTL.git'
node.default['rtl']['revision'] = 'v0.11.0'
node.default['rtl']['host'] = '10.1.1.163'
node.default['rtl']['port'] = '3000'
node.default['dotnet']['ms_packages_src_url'] = "https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb"
node.default['dotnet']['ms_packages_src_checksum'] = "4df5811c41fdded83eb9e2da9336a8dfa5594a79dc8a80133bd815f4f85b9991"
node.default['nbxplorer']['repo'] = 'https://github.com/dgarage/NBXplorer'
node.default['nbxplorer']['revision'] = 'v2.1.52'
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'
node.default['btcpay']['repo'] = 'https://github.com/btcpayserver/btcpayserver'
node.default['btcpay']['revision'] = 'v1.1.2'
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"
node.default['btcpay']['port'] = '23001'
node.default["btcpay"]["domain"] = 'btcpay.kosmos.org'
node.default['btcpay']['postgres']['port'] = 5432
node.default['btcpay']['postgres']['database'] = 'btcpayserver'
node.default['btcpay']['postgres']['user'] = 'satoshi'

View File

@@ -0,0 +1,110 @@
# 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
# SASS #
########
.sass-cache
# EDITORS #
###########
.#*
.project
.settings
*_flymake
*_flymake.*
*.bak
*.sw[a-z]
*.tmproj
*~
\#*
mkmf.log
REVISION
TAGS*
tmtags
## COMPILED ##
##############
*.class
*.com
*.dll
*.exe
*.o
*.pyc
*.so
*/rdoc/
a.out
# Testing #
###########
.circleci/*
.codeclimate.yml
.foodcritic
.kitchen*
.rspec
.rubocop.yml
.travis.yml
.watchr
azure-pipelines.yml
examples/*
features/*
Guardfile
kitchen.yml*
Procfile
Rakefile
spec/*
spec/*
spec/fixtures/*
test/*
# SCM #
#######
.git
.gitattributes
.gitconfig
.github/*
.gitignore
.gitmodules
.svn
*/.bzr/*
*/.git
*/.hg/*
*/.svn/*
# Berkshelf #
#############
Berksfile
Berksfile.lock
cookbooks/*
tmp
# Bundler #
###########
vendor/*
Gemfile
Gemfile.lock
# Policyfile #
##############
Policyfile.rb
Policyfile.lock.json
# Cookbooks #
#############
CHANGELOG*
CONTRIBUTING*
TESTING*
CODE_OF_CONDUCT*
# Vagrant #
###########
.vagrant
Vagrantfile

View File

@@ -0,0 +1,32 @@
---
driver:
name: vagrant
## The forwarded_port port feature lets you connect to ports on the VM guest via
## localhost on the host.
## see also: https://www.vagrantup.com/docs/networking/forwarded_ports.html
# network:
# - ["forwarded_port", {guest: 80, host: 8080}]
provisioner:
name: chef_zero
## product_name and product_version specifies a specific Chef product and version to install.
## see the Chef documentation for more details: https://docs.chef.io/config_yml_kitchen.html
# product_name: chef
# product_version: 15
verifier:
name: inspec
platforms:
- name: ubuntu-18.04
- name: centos-7
suites:
- name: default
verifier:
inspec_tests:
- test/integration/default
attributes:

View File

@@ -0,0 +1,29 @@
name 'kosmos-bitcoin'
maintainer 'Kosmos Developers'
maintainer_email 'mail@kosmos.org'
license 'MIT'
description 'Installs/configures bitcoin-related software'
long_description 'Installs/configures bitcoin-related software'
version '0.1.0'
chef_version '>= 14.0'
# The `issues_url` points to the location where issues for this cookbook are
# tracked. A `View Issues` link will be displayed on this cookbook's page when
# uploaded to a Supermarket.
#
# issues_url 'https://github.com/<insert_org_here>/kosmos-bitcoin/issues'
# The `source_url` points to the development repository for this cookbook. A
# `View Source` link will be displayed on this cookbook's page when uploaded to
# a Supermarket.
#
# source_url 'https://github.com/<insert_org_here>/kosmos-bitcoin'
depends 'ark'
depends 'git'
depends 'golang'
depends 'kosmos-nginx'
depends 'kosmos-nodejs'
depends 'firewall'
depends 'application_javascript'
depends 'tor-full'

View File

@@ -0,0 +1,122 @@
#
# Cookbook:: kosmos-bitcoin
# Recipe:: btcpay
#
build_essential
include_recipe "git"
git node['btcpay']['source_dir'] do
repository node['btcpay']['repo']
revision node['btcpay']['revision']
action :sync
notifies :stop, "systemd_unit[btcpayserver.service]", :immediately
notifies :run, 'bash[build_btcpay]', :immediately
end
bash 'build_btcpay' do
cwd node['btcpay']['source_dir']
code <<-EOH
systemctl stop btcpayserver.service
./build.sh
EOH
action :nothing
notifies :restart, "systemd_unit[btcpayserver.service]", :delayed
end
directory "/home/#{node['bitcoin']['username']}/.btcpayserver" do
owner node['bitcoin']['username']
group node['bitcoin']['usergroup']
mode '0750'
recursive true
end
directory File.dirname(node['btcpay']['config_path']) do
owner node['bitcoin']['username']
group node['bitcoin']['usergroup']
mode '0750'
recursive true
end
credentials = Chef::EncryptedDataBagItem.load('credentials', 'btcpay')
lnd_admin_macaroon_path = "#{node['lnd']['lnd_dir']}/data/chain/bitcoin/mainnet/admin.macaroon" rescue nil
template node['btcpay']['config_path'] do
source "btcpay-settings.config.erb"
owner node['bitcoin']['username']
group node['bitcoin']['usergroup']
mode '0640'
variables bitcoin_network: node['bitcoin']['network'],
nbxplorer_url: "http://127.0.0.1:#{node['nbxplorer']['port']}",
btcpay_port: node['btcpay']['port'],
btcpay_log_path: node['btcpay']['log_path'],
postgres_host: "pg.kosmos.local",
postgres_port: node['btcpay']['postgres']['port'],
postgres_database: node['btcpay']['postgres']['database'],
postgres_user: node['btcpay']['postgres']['user'],
postgres_password: credentials['postgres_password'],
lnd_admin_macaroon_path: lnd_admin_macaroon_path
notifies :restart, "systemd_unit[btcpayserver.service]", :delayed
end
directory '/run/btcpayserver' do
owner node['bitcoin']['username']
group node['bitcoin']['usergroup']
mode '0640'
end
systemd_unit 'btcpayserver.service' do
content({
Unit: {
Description: 'BTCPay Server daemon',
Documentation: ['https://docs.btcpayserver.org/ManualDeployment/'],
Requires: 'nbxplorer.service',
After: 'nbxplorer.service'
},
Service: {
User: node['bitcoin']['username'],
Group: node['bitcoin']['usergroup'],
Type: 'simple',
WorkingDirectory: node['btcpay']['source_dir'],
ExecStart: "#{node['btcpay']['source_dir']}/run.sh --conf=#{node['btcpay']['config_path']}",
PIDFile: '/run/btcpayserver/btcpayserver.pid',
Restart: 'on-failure',
PrivateTmp: true,
ProtectSystem: 'full',
NoNewPrivileges: true,
PrivateDevices: true
},
Install: {
WantedBy: 'multi-user.target'
}
})
verify false
triggers_reload true
action [:create, :enable, :start]
end
#
# HTTPS Reverse Proxy
#
include_recipe "kosmos-nginx"
server_name = node["btcpay"]["domain"]
template "#{node["nginx"]["dir"]}/sites-available/#{server_name}" do
source "nginx_conf_btcpayserver.erb"
owner node["nginx"]["user"]
mode 0640
variables btcpay_port: node["btcpay"]["port"],
server_name: server_name,
ssl_cert: "/etc/letsencrypt/live/#{server_name}/fullchain.pem",
ssl_key: "/etc/letsencrypt/live/#{server_name}/privkey.pem"
notifies :reload, "service[nginx]", :delayed
end
nginx_site server_name do
action :enable
end
nginx_certbot_site server_name

View File

@@ -0,0 +1,102 @@
#
# Cookbook:: kosmos-bitcoin
# Recipe:: c-lightning
#
build_essential
include_recipe "git"
%w{
autoconf automake libtool libgmp-dev libsqlite3-dev
python3 python3-mako net-tools zlib1g-dev
libsodium-dev gettext
}.each do |pkg|
apt_package pkg
end
git node['c-lightning']['source_dir'] do
repository node['c-lightning']['repo']
revision node['c-lightning']['revision']
action :sync
notifies :run, 'bash[compile_c-lightning]', :immediately
end
bash "compile_c-lightning" do
cwd node['c-lightning']['source_dir']
code <<-EOH
systemctl stop lightningd.service
./configure
make
make install
EOH
environment "PYTHON_VERSION" => "3"
action :nothing
notifies :restart, "systemd_unit[lightningd.service]", :delayed
end
bitcoin_user = node['bitcoin']['username']
bitcoin_group = node['bitcoin']['usergroup']
lightning_dir = node['c-lightning']['lightning_dir']
bitcoin_credentials = Chef::EncryptedDataBagItem.load('credentials', 'bitcoin')
directory lightning_dir do
owner bitcoin_user
group bitcoin_group
mode '0750'
action :create
end
template "#{lightning_dir}/config" do
source "c-lightning.config.erb"
owner bitcoin_user
group bitcoin_group
mode '0640'
variables lighting_dir: lightning_dir,
lightning_alias: node['c-lightning']['alias'],
lightning_rgb: node['c-lightning']['rgb'],
lightning_log_level: node['c-lightning']['log_level'],
bitcoin_datadir: node['bitcoin']['datadir'],
bitcoin_rpc_user: node['bitcoin']['conf']['rpcuser'],
bitcoin_rpc_password: bitcoin_credentials["rpcpassword"],
bitcoin_rpc_host: node['bitcoin']['conf']['rpcbind'],
public_ip: node['c-lightning']['public_ip']
notifies :restart, "systemd_unit[lightningd.service]", :delayed
end
systemd_unit 'lightningd.service' do
content({
Unit: {
Description: 'C-Lightning daemon',
Documentation: ['https://github.com/ElementsProject/lightning'],
Requires: 'bitcoind.service',
After: 'bitcoind.service'
},
Service: {
User: bitcoin_user,
Group: bitcoin_group,
Type: 'simple',
ExecStart: '/usr/local/bin/lightningd',
Restart: 'always',
RestartSec: '30',
TimeoutSec: '240',
PrivateTmp: true,
ProtectSystem: 'full',
NoNewPrivileges: true,
PrivateDevices: true,
MemoryDenyWriteExecute: true
},
Install: {
WantedBy: 'multi-user.target'
}
})
verify false
triggers_reload true
action [:create, :enable, :start]
end
firewall_rule 'lightningd' do
port [9735] # TODO use attribute
protocol :tcp
command :allow
end

View File

@@ -0,0 +1,33 @@
#
# Cookbook:: kosmos-bitcoin
# Recipe:: dotnet
#
build_essential
apt_repository 'universe' do
uri 'http://archive.ubuntu.com/ubuntu/'
distribution 'focal'
components ['universe']
end
apt_package 'apt-transport-https'
remote_file '/opt/packages-microsoft-prod.deb' do
source node['dotnet']['ms_packages_src_url']
checksum node['dotnet']['ms_packages_src_checksum']
action :create_if_missing
end
dpkg_package 'packages-microsoft-prod' do
source '/opt/packages-microsoft-prod.deb'
action :install
notifies :run, 'execute[apt_update]'
end
execute 'apt_update' do
command 'apt update'
action :nothing
end
apt_package 'dotnet-sdk-3.1'

View File

@@ -0,0 +1,32 @@
#
# Cookbook:: kosmos-bitcoin
# Recipe:: firewall
#
# The MIT License (MIT)
#
# Copyright:: 2020, 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.
#
firewall_rule 'bitcoind' do
port [8333] # TODO adjust for testnet
protocol :tcp
command :allow
end

View File

@@ -0,0 +1,118 @@
#
# Cookbook:: kosmos-bitcoin
# Recipe:: lnd
#
include_recipe "git"
include_recipe "golang"
git node['lnd']['source_dir'] do
repository node['lnd']['repo']
revision node['lnd']['revision']
action :sync
notifies :run, 'bash[compile_lnd]', :immediately
end
bash "compile_lnd" do
cwd node['lnd']['source_dir']
code <<-EOH
source /etc/profile.d/golang.sh
make clean && make && make install tags="signrpc walletrpc chainrpc invoicesrpc"
EOH
action :nothing
notifies :restart, "systemd_unit[lnd.service]", :delayed
end
bitcoin_user = node['bitcoin']['username']
bitcoin_group = node['bitcoin']['usergroup']
lnd_dir = node['lnd']['lnd_dir']
bitcoin_credentials = Chef::EncryptedDataBagItem.load('credentials', 'bitcoin')
directory lnd_dir do
owner bitcoin_user
group bitcoin_group
mode '0750'
action :create
end
if node['lnd']['auto_unlock']
lnd_credentials = Chef::EncryptedDataBagItem.load('credentials', 'lnd')
file "#{lnd_dir}/.unlock.txt" do
content lnd_credentials['password']
mode '0600'
owner bitcoin_user
group bitcoin_group
end
end
template "#{lnd_dir}/lnd.conf" do
source "lnd.conf.erb"
owner bitcoin_user
group bitcoin_group
mode '0640'
variables lnd_alias: node['lnd']['alias'],
lnd_color: node['lnd']['color'],
lnd_log_level: node['lnd']['log_level'],
lnd_externalip: "#{node['lnd']['public_ip']}:#{node['lnd']['public_port']}",
lnd_port: node['lnd']['port'],
lnd_minchansize: node['lnd']['minchansize'],
lnd_basefee: node['lnd']['basefee'],
lnd_feerate: node['lnd']['feerate'],
lnd_dir: lnd_dir,
auto_unlock: node['lnd']['auto_unlock'],
bitcoin_datadir: node['bitcoin']['datadir'],
bitcoin_rpc_user: node['bitcoin']['conf']['rpcuser'],
bitcoin_rpc_password: bitcoin_credentials["rpcpassword"],
bitcoin_rpc_host: node['bitcoin']['conf']['rpcbind'],
bitcoin_zmqpubrawblock: node['bitcoin']['conf']['zmqpubrawblock'],
bitcoin_zmqpubrawtx: node['bitcoin']['conf']['zmqpubrawtx']
notifies :restart, "systemd_unit[lnd.service]", :delayed
end
exec_flags = ""
exec_flags += "--tor.active --tor.v3" if node['bitcoin']['tor_enabled']
systemd_unit 'lnd.service' do
content({
Unit: {
Description: 'Lightning Network Daemon',
Documentation: ['https://github.com/lightningnetwork/lnd/tree/master/docs'],
Requires: 'bitcoind.service',
After: 'bitcoind.service'
},
Service: {
User: bitcoin_user,
Group: bitcoin_group,
Type: 'simple',
ExecStart: "/opt/go/bin/lnd #{exec_flags}",
Restart: 'always',
RestartSec: '30',
TimeoutSec: '240',
LimitNOFILE: '128000',
PrivateTmp: true,
ProtectSystem: 'full',
NoNewPrivileges: true,
PrivateDevices: true,
MemoryDenyWriteExecute: true
},
Install: {
WantedBy: 'multi-user.target'
}
})
verify false
triggers_reload true
action [:create, :enable, :start]
end
firewall_rule 'lnd' do
port [node['lnd']['port']]
protocol :tcp
command :allow
end
if node['bitcoin']['tor_enabled']
node.override['tor']['ControlPort'] = 9051
node.override['tor']['CookieAuthentication'] = true
end

View File

@@ -0,0 +1,84 @@
#
# Cookbook:: kosmos-bitcoin
# Recipe:: nbxplorer
#
build_essential
include_recipe "git"
git node['nbxplorer']['source_dir'] do
repository node['nbxplorer']['repo']
revision node['nbxplorer']['revision']
action :sync
notifies :stop, "systemd_unit[nbxplorer.service]", :immediately
notifies :run, 'bash[build_nbxplorer]', :immediately
end
bash 'build_nbxplorer' do
cwd node['nbxplorer']['source_dir']
code './build.sh'
action :nothing
end
bitcoin_credentials = Chef::EncryptedDataBagItem.load('credentials', 'bitcoin')
directory "/home/#{node['bitcoin']['username']}/.nbxplorer" do
owner node['bitcoin']['username']
group node['bitcoin']['usergroup']
mode '0750'
recursive true
end
directory File.dirname(node['nbxplorer']['config_path']) do
owner node['bitcoin']['username']
group node['bitcoin']['usergroup']
mode '0750'
recursive true
end
template node['nbxplorer']['config_path'] do
source "nbxplorer-settings.config.erb"
owner node['bitcoin']['username']
group node['bitcoin']['usergroup']
mode '0640'
variables bitcoin_rpc_user: node['bitcoin']['conf']['rpcuser'],
bitcoin_rpc_password: bitcoin_credentials["rpcpassword"],
bitcoin_rpc_url: "http://#{node['bitcoin']['conf']['rpcbind']}",
nbxplorer_port: node['nbxplorer']['port']
end
directory '/run/nbxplorer' do
owner node['bitcoin']['username']
group node['bitcoin']['usergroup']
mode '0640'
end
systemd_unit 'nbxplorer.service' do
content({
Unit: {
Description: 'NBXplorer daemon',
Documentation: ['https://github.com/dgarage/NBXplorer'],
Requires: 'bitcoind.service',
After: 'bitcoind.service'
},
Service: {
User: node['bitcoin']['username'],
Group: node['bitcoin']['usergroup'],
Type: 'simple',
ExecStart: "/usr/bin/dotnet '#{node['nbxplorer']['source_dir']}/NBXplorer/bin/Release/netcoreapp3.1/NBXplorer.dll' -c #{node['nbxplorer']['config_path']} --noauth",
PIDFile: '/run/nbxplorer/nbxplorer.pid',
Restart: 'on-failure',
PrivateTmp: true,
ProtectSystem: 'full',
NoNewPrivileges: true,
PrivateDevices: true
},
Install: {
WantedBy: 'multi-user.target'
}
})
verify false
triggers_reload true
action [:create, :enable, :start]
end

View File

@@ -0,0 +1,110 @@
#
# Cookbook:: kosmos-bitcoin
# Recipe:: rtl
#
include_recipe 'kosmos-nodejs'
app_name = "rtl"
rtl_dir = "/opt/#{app_name}"
lnd_dir = node['lnd']['lnd_dir']
bitcoin_user = node['bitcoin']['username']
bitcoin_group = node['bitcoin']['usergroup']
credentials = Chef::EncryptedDataBagItem.load('credentials', 'rtl')
rtl_config = {
host: node['rtl']['host'],
port: node['rtl']['port'],
defaultNodeIndex: 1,
SSO: {
rtlSSO: 0,
rtlCookiePath: "",
logoutRedirectLink: ""
},
nodes: [
{
index: 1,
lnNode: node['lnd']['alias'],
lnImplementation: "LND",
Authentication: {
macaroonPath: "#{lnd_dir}/data/chain/bitcoin/mainnet",
configPath: "#{lnd_dir}/lnd.conf"
},
Settings: {
userPersona: "MERCHANT",
themeMode: "NIGHT",
themeColor: "TEAL",
channelBackupPath: "",
enableLogging: true,
lnServerUrl: "https://localhost:8080",
fiatConversion: true,
currencyUnit: "EUR"
}
}
],
multiPassHashed: credentials["multiPassHashed"]
}.to_json
application rtl_dir do
owner bitcoin_user
group bitcoin_group
git do
user bitcoin_user
group bitcoin_group
repository node['rtl']['repo']
revision node['rtl']['revision']
notifies :restart, "systemd_unit[rtl.service]", :delayed
end
npm_install do
user bitcoin_user
end
file "#{rtl_dir}/RTL-Config.json" do
owner bitcoin_user
group bitcoin_group
mode '0640'
content rtl_config
notifies :restart, "systemd_unit[rtl.service]", :delayed
end
systemd_unit 'rtl.service' do
content({
Unit: {
Description: 'Ride The Lightning',
Documentation: ['https://github.com/Ride-The-Lightning/RTL'],
Requires: 'lnd.service',
After: 'lnd.service'
},
Service: {
User: bitcoin_user,
Group: bitcoin_group,
Type: 'simple',
# ExecStartPre: '/bin/sleep 120',
ExecStart: "/usr/bin/node #{rtl_dir}/rtl.js",
Restart: 'always',
RestartSec: '30',
TimeoutSec: '120',
PrivateTmp: true,
ProtectSystem: 'full',
NoNewPrivileges: true,
PrivateDevices: true,
},
Install: {
WantedBy: 'multi-user.target'
}
})
verify false
triggers_reload true
action [:create, :enable, :start]
end
end
include_recipe 'firewall'
firewall_rule 'rtl_private' do
port node['rtl']['port'].to_i
source "10.1.1.0/24"
protocol :tcp
command :allow
end

View File

@@ -0,0 +1,103 @@
#
# Cookbook:: kosmos-bitcoin
# Recipe:: snapd
#
# The MIT License (MIT)
#
# Copyright:: 2020, 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.
#
# FIXME: Switch to the snap_package resource when it gets fixed:
# https://github.com/chef/chef/issues/8827
execute "snap install bitcoin-core --channel=latest/stable"
bitcoin_user = node['bitcoin']['username']
bitcoin_group = node['bitcoin']['usergroup']
bitcoin_datadir = node['bitcoin']['datadir']
bitcoin_snapdir = "/home/#{bitcoin_user}/snap/bitcoin-core/common/.bitcoin"
user bitcoin_user do
manage_home true
shell "/bin/bash"
end
directory bitcoin_datadir do
owner bitcoin_user
group bitcoin_group
mode '0755'
recursive true
action :create
end
bitcoin_config = node['bitcoin']['conf'].merge({
rpcpassword: credentials["rpcpassword"]
})
template "#{bitcoin_datadir}/bitcoin.conf" do
owner bitcoin_user
group bitcoin_group
variables conf: bitcoin_config,
mainnet_conf: node['bitcoin']['mainnet_conf'],
testnet_conf: node['bitcoin']['testnet_conf'],
regtest_conf: node['bitcoin']['regtest_conf']
action :create
notifies :restart, "systemd_unit[bitcoind.service]", :delayed
end
directory bitcoin_snapdir do
owner bitcoin_user
group bitcoin_group
mode '0750'
recursive true
action :create
end
execute "chown -R #{bitcoin_user}:#{bitcoin_group} /home/#{bitcoin_user}/snap"
mount bitcoin_snapdir do
device bitcoin_datadir
fstype 'none'
options 'bind'
action [:mount]
end
systemd_unit 'bitcoind.service' do
content({
Unit: {
Description: 'Bitcoin Core daemon',
Documentation: ['https://bitcoincore.org'],
After: 'network.target'
},
Service: {
User: bitcoin_user,
Type: 'exec',
ExecStart: '/snap/bin/bitcoin-core.daemon',
PIDFile: "#{bitcoin_snapdir}/bitcoind.pid",
Restart: 'on-failure',
},
Install: {
WantedBy: 'multi-user.target'
}
})
verify false
triggers_reload true
action [:create, :enable, :start]
end

View File

@@ -0,0 +1,147 @@
#
# Cookbook:: kosmos-bitcoin
# Recipe:: source
#
# TODO move to custom kosmos cookbook before publshing bitcoin cookbook
systemd_unit "mnt-data-bitcoin.mount" do
content({
Unit: {
Description: 'Bitcoin Core data directory',
},
Mount: {
What: '/var/lib/vmshare-bitcoin',
Where: '/mnt/data/bitcoin',
Type: '9p',
Options: 'trans=virtio,version=9p2000.L'
},
Install: {
WantedBy: 'multi-user.target'
}
})
verify false
triggers_reload true
action [:create, :enable, :start]
end
build_essential
include_recipe 'ark'
%w{ libtool autotools-dev make automake cmake curl g++-multilib libtool
binutils-gold bsdmainutils pkg-config python3 patch }.each do |pkg|
apt_package pkg
end
ark 'bitcoind' do
url "https://bitcoincore.org/bin/bitcoin-core-#{node['bitcoin']['version']}/bitcoin-#{node['bitcoin']['version']}.tar.gz"
checksum node['bitcoin']['checksum']
action :put
notifies :run, 'execute[compile_bitcoin-core_dependencies]', :immediately
end
execute "compile_bitcoin-core_dependencies" do
cwd "/usr/local/bitcoind/depends"
command "make NO_QT=1"
action :nothing
notifies :run, 'bash[compile_bitcoin-core]', :immediately
end
bash "compile_bitcoin-core" do
cwd "/usr/local/bitcoind"
code <<-EOH
./autogen.sh
./configure --prefix=$PWD/depends/x86_64-pc-linux-gnu
make
EOH
action :nothing
notifies :restart, "systemd_unit[bitcoind.service]", :delayed
end
link "/usr/local/bin/bitcoind" do
to "/usr/local/bitcoind/src/bitcoind"
end
link "/usr/local/bin/bitcoin-cli" do
to "/usr/local/bitcoind/src/bitcoin-cli"
end
bitcoin_user = node['bitcoin']['username']
bitcoin_group = node['bitcoin']['usergroup']
bitcoin_datadir = node['bitcoin']['datadir']
bitcoin_walletdir = node['bitcoin']['walletdir']
bitcoin_conf_path = node['bitcoin']['conf_path']
credentials = Chef::EncryptedDataBagItem.load('credentials', 'bitcoin')
group bitcoin_group
user bitcoin_user do
manage_home true
uid 1006
gid bitcoin_group
shell "/bin/bash"
end
if node['bitcoin']['tor_enabled']
group 'debian-tor' do
action :modify
members bitcoin_user
append true
end
end
[bitcoin_datadir, bitcoin_walletdir].each do |path|
directory path do
owner bitcoin_user
group bitcoin_group
mode '0750'
recursive true
action :create
end
end
bitcoin_config = node['bitcoin']['conf'].merge({
rpcpassword: credentials["rpcpassword"]
})
template bitcoin_conf_path do
owner bitcoin_user
group bitcoin_group
mode '0640'
variables conf: bitcoin_config,
mainnet_conf: node['bitcoin']['mainnet_conf'],
testnet_conf: node['bitcoin']['testnet_conf'],
regtest_conf: node['bitcoin']['regtest_conf']
action :create
notifies :restart, "systemd_unit[bitcoind.service]", :delayed
end
systemd_unit 'bitcoind.service' do
content({
Unit: {
Description: 'Bitcoin Core daemon',
Documentation: ['https://bitcoincore.org'],
After: 'network.target'
},
Service: {
User: bitcoin_user,
Type: 'simple',
ExecStart: "bitcoind -conf=#{bitcoin_conf_path} -datadir=#{bitcoin_datadir} -walletdir=#{bitcoin_walletdir} -pid=#{bitcoin_datadir}/bitcoind.pid",
PIDFile: "#{bitcoin_datadir}/bitcoind.pid",
Restart: 'always',
PrivateTmp: true,
LimitNOFILE: 'infinity',
TimeoutStopSec: '60s',
TimeoutStartSec: '20s',
StartLimitInterval: '60s',
StartLimitBurst: '2'
},
Install: {
WantedBy: 'multi-user.target'
}
})
verify false
triggers_reload true
action [:create, :enable, :start]
end
include_recipe "kosmos-bitcoin::firewall"

View File

@@ -0,0 +1,2 @@
require 'chefspec'
require 'chefspec/policyfile'

View File

@@ -0,0 +1,29 @@
#
# Cookbook:: kosmos-bitcoin
# Spec:: default
#
# Copyright:: 2019, The Authors, All Rights Reserved.
require 'spec_helper'
describe 'kosmos-bitcoin::default' do
context 'When all attributes are default, on Ubuntu 18.04' do
# for a complete list of available platforms and versions see:
# https://github.com/chefspec/fauxhai/blob/master/PLATFORMS.md
platform 'ubuntu', '18.04'
it 'converges successfully' do
expect { chef_run }.to_not raise_error
end
end
context 'When all attributes are default, on CentOS 7' do
# for a complete list of available platforms and versions see:
# https://github.com/chefspec/fauxhai/blob/master/PLATFORMS.md
platform 'centos', '7'
it 'converges successfully' do
expect { chef_run }.to_not raise_error
end
end
end

View File

@@ -0,0 +1,34 @@
##
## bitcoin.conf configuration file. Lines beginning with # are comments.
##
## Generated by Chef. Do not edit directly, or your changes will be overwritten
## during the next Chef run!
##
<% @conf.sort.each do |key, value| %>
<%= "#{key}=#{value}" %>
<% end %>
<% if @mainnet_conf %>
# Options only for mainnet
[main]
<% @mainnet_conf.sort.each do |key, value| %>
<%= "#{key}=#{value}" %>
<% end %>
<% end %>
<% if @testnet_conf %>
# Options only for testnet
[test]
<% @testnet_conf.sort.each do |key, value| %>
<%= "#{key}=#{value}" %>
<% end %>
<% end %>
<% if @regtest_conf %>
# Options only for regtest
[regtest]
<% @regtest_conf.sort.each do |key, value| %>
<%= "#{key}=#{value}" %>
<% end %>
<% end %>

View File

@@ -0,0 +1,10 @@
network=<%= @bitcoin_network %>
port=<%= @btcpay_port %>
bind=127.0.0.1
chains=btc
postgres=User ID=<%= @postgres_user %>;Password=<%= @postgres_password %>;Host=<%= @postgres_host %>;Port=<%= @postgres_port %>;Database=<%= @postgres_database %>;
debuglog=<%= @btcpay_log_path %>
BTC.explorer.url=<%= @nbxplorer_url %>
<% if @lnd_admin_macaroon_path %>
BTC.lightning=type=lnd-rest;server=https://127.0.0.1:8080/;macaroonfilepath=<%= @lnd_admin_macaroon_path %>;allowinsecure=true
<% end %>

View File

@@ -0,0 +1,13 @@
network=bitcoin
bitcoin-datadir=<%= @bitcoin_datadir %>
alias=<%= @lightning_alias %>
rgb=<%= @lightning_rgb %>
bitcoin-rpcuser=<%= @bitcoin_rpc_user %>
bitcoin-rpcpassword=<%= @bitcoin_rpc_password %>
bitcoin-rpcconnect=<%= @bitcoin_rpc_host %>
log-level=<%= @lightning_log_level %>
bind-addr=0.0.0.0
announce-addr=<%= @public_ip %>
disable-dns
<%# plugin=/home/satoshi/lightning-plugins/summary/summary.py %>
<%# plugin=/home/satoshi/lightning-plugins/rebalance/rebalance.py %>

View File

@@ -0,0 +1,27 @@
[Application Options]
debuglevel=<%= @lnd_log_level %>
listen=0.0.0.0:<%= @lnd_port %>
externalip=<%= @lnd_externalip %>
alias=<%= @lnd_alias %>
color=<%= @lnd_color %>
maxpendingchannels=2
minchansize=<%= @lnd_minchansize %>
<% if @auto_unlock %>wallet-unlock-password-file=<%= @lnd_dir %>/.unlock.txt<% end %>
[autopilot]
autopilot.active=0
[Bitcoin]
bitcoin.active=1
bitcoin.mainnet=1
bitcoin.node=bitcoind
bitcoin.basefee=<%= @lnd_basefee %>
bitcoin.feerate=<%= @lnd_feerate %>
[bitcoind]
bitcoind.dir=<%= @bitcoin_datadir %>
bitcoind.rpchost=<%= @bitcoin_rpc_host %>
bitcoind.rpcuser=<%= @bitcoin_rpc_user %>
bitcoind.rpcpass=<%= @bitcoin_rpc_password %>
bitcoind.zmqpubrawblock=<%= @bitcoin_zmqpubrawblock %>
bitcoind.zmqpubrawtx=<%= @bitcoin_zmqpubrawtx %>

View File

@@ -0,0 +1,5 @@
btc.rpc.auth=<%= @bitcoin_rpc_user %>:<%= @bitcoin_rpc_password %>
btc.rpc.url=<%= @bitcoin_rpc_url %>
btc.node.endpoint=127.0.0.1:8333
port=<%= @nbxplorer_port %>
mainnet=1

View File

@@ -0,0 +1,70 @@
<% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%>
upstream _btcpayserver {
server localhost:<%= @btcpay_port %>;
}
# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
# scheme used to connect to this server
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
default $http_x_forwarded_proto;
'' $scheme;
}
# If we receive X-Forwarded-Port, pass it through; otherwise, pass along the
# server port the client connected to
map $http_x_forwarded_port $proxy_x_forwarded_port {
default $http_x_forwarded_port;
'' $server_port;
}
# If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any
# Connection header that may have been passed to this server
map $http_upgrade $proxy_connection {
default upgrade;
'' close;
}
# Set appropriate X-Forwarded-Ssl header
map $scheme $proxy_x_forwarded_ssl {
default off;
https on;
}
# HTTP 1.1 support
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
# Mitigate httpoxy attack
proxy_set_header Proxy "";
server {
client_max_body_size 100M;
server_name <%= @server_name %>;
listen 443 ssl http2;
access_log <%= node[:nginx][:log_dir] %>/btcpayserver.access.log json;
error_log <%= node[:nginx][:log_dir] %>/btcpayserver.error.log warn;
ssl_prefer_server_ciphers on;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_certificate <%= @ssl_cert %>;
ssl_certificate_key <%= @ssl_key %>;
add_header Strict-Transport-Security "max-age=15768000";
location / {
proxy_pass http://_btcpayserver;
}
}
<% end -%>

View File

@@ -0,0 +1,16 @@
# InSpec test for recipe kosmos-bitcoin::default
# The InSpec reference, with examples and extensive documentation, can be
# found at https://www.inspec.io/docs/reference/resources/
unless os.windows?
# This is an example test, replace with your own test.
describe user('root'), :skip do
it { should exist }
end
end
# This is an example test, replace it with your own test.
describe port(80), :skip do
it { should_not be_listening }
end

View File

@@ -25,7 +25,8 @@ end
nginx_certbot_site server_name
unless node.chef_environment == "development"
include_recipe "firewall"
include_recipe "kosmos-base::firewall"
firewall_rule "btcpayserver" do
port node["kosmos-btcpayserver"]["port"]
protocol :tcp

View File

@@ -0,0 +1,5 @@
dn: dc=kosmos,dc=org
changetype: modify
replace: aci
aci: (target="ldap:///dc=kosmos,dc=org") (version 3.0; acl "user-deny-all"; deny (all) userdn="ldap:///dc=kosmos,dc=org";)
aci: (target="ldap:///dc=kosmos,dc=org")(targetattr="userPassword") (version 3.0; acl "user-write-own-password"; allow (write) userdn="ldap:///self";)

View File

@@ -2,5 +2,3 @@ dn: ou=users,dc=kosmos,dc=org
objectClass: top
objectClass: organizationalUnit
ou: users
aci: (target="ldap:///dc=kosmos,dc=org") (version 3.0; acl "user-deny-all"; deny (all) userdn="ldap:///dc=kosmos,dc=org";)
aci: (target="ldap:///dc=kosmos,dc=org")(targetattr="userPassword") (version 3.0; acl "user-write-own-password"; allow (write) userdn="ldap:///self";)

View File

@@ -37,14 +37,9 @@ end
# with the run context is confusing:
#
# https://github.com/chef-cookbooks/firewall/issues/134
unless node.chef_environment == "development"
include_recipe "firewall"
firewall_rule "ldap" do
port [389, 636]
protocol :tcp
command :allow
end
include_recipe "kosmos-dirsrv::firewall"
unless node.chef_environment == "development"
# backup the data dir and the config files
node.override["backup"]["archives"]["dirsrv"] = ["/etc/dirsrv", "/var/lib/dirsrv"]
include_recipe "backup"

View File

@@ -0,0 +1,33 @@
#
# Cookbook Name:: kosmos-dirsrv
# Recipe:: firewall
#
# The MIT License (MIT)
#
# Copyright:: 2020, 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.
include_recipe "kosmos-base::firewall"
firewall_rule "ldap" do
port [389, 636]
protocol :tcp
command :allow
end

View File

@@ -11,6 +11,7 @@ property :port, Integer, default: 389
action :create do
include_recipe "apt"
package "389-ds-base"
package "python3-lib389"
include_recipe "ulimit"
user_ulimit "dirsrv" do
@@ -50,13 +51,33 @@ action :create do
subscribes :run, "template[#{setup_config}]", :immediately
notifies :restart, "service[#{service_name}]", :immediately
notifies :delete, "template[#{setup_config}]", :immediately
notifies :run, "execute[set base acis]", :delayed
notifies :run, "execute[add users group]", :delayed
notifies :run, "execute[disable anonymous access]", :delayed
end
end
service service_name do
action [:enable, :start]
action [:start]
end
# :enable on the dirsrv@master service creates the wrong file
# (/etc/systemd/system/dirsrv.target.wants/dirsrv@master.service), seems to
# be a Chef bug. Let's do it manually
link "/etc/systemd/system/multi-user.target.wants/dirsrv@master.service" do
to "/lib/systemd/system/dirsrv@.service"
end
cookbook_file "#{Chef::Config[:file_cache_path]}/acis.ldif" do
source "acis.ldif"
owner "root"
group "root"
end
execute "set base acis" do
command "ldapmodify -x -w #{new_resource.admin_password} -D '#{new_resource.bind_dn}' -f '#{Chef::Config[:file_cache_path]}/acis.ldif' -p #{new_resource.port} -h localhost"
sensitive true
action :nothing
end
cookbook_file "#{Chef::Config[:file_cache_path]}/users.ldif" do
@@ -101,24 +122,28 @@ nsslapd-allow-anonymous-access: off
include_recipe "kosmos-base::letsencrypt"
dirsrv_hook = <<-EOF
#!/usr/bin/env bash
#!/usr/bin/env bash
set -e
set -e
# Copy the dirsrv certificate and restart the server if it has been renewed
# This is necessary because dirsrv uses a different format for the certificates
for domain in $RENEWED_DOMAINS; do
case $domain in
#{new_resource.hostname})
openssl pkcs12 -export -in "${RENEWED_LINEAGE}/fullchain.pem" -inkey "${RENEWED_LINEAGE}/privkey.pem" -out #{Chef::Config[:file_cache_path]}/#{new_resource.hostname}.p12 -name 'Server-Cert' -passout pass:
pk12util -i #{Chef::Config[:file_cache_path]}/#{new_resource.hostname}.p12 -d #{inst_dir} -W ''
systemctl restart #{service_name}
;;
esac
done
# Copy the dirsrv certificate and restart the server if it has been renewed
# This is necessary because dirsrv uses a different format for the certificates
for domain in $RENEWED_DOMAINS; do
case $domain in
#{new_resource.hostname})
openssl pkcs12 -export -in "${RENEWED_LINEAGE}/fullchain.pem" -inkey "${RENEWED_LINEAGE}/privkey.pem" -out #{Chef::Config[:file_cache_path]}/#{new_resource.hostname}.p12 -name 'Server-Cert' -passout pass:
pk12util -i #{Chef::Config[:file_cache_path]}/#{new_resource.hostname}.p12 -d #{inst_dir} -W ''
# Remove the encryption key entries from the current database.
# They will be recreated on restart for the new certificate
awk '! /^dn: cn=3D|AES,cn=encrypted attribute keys,cn=userRoot/ {print; printf "\\n" ; }' RS="" #{inst_dir}/dse.ldif > #{inst_dir}/dse_new.ldif
mv #{inst_dir}/dse_new.ldif #{inst_dir}/dse.ldif
systemctl restart #{service_name}
;;
esac
done
EOF
file "/etc/letsencrypt/renewal-hooks/deploy/dirsrrv" do
file "/etc/letsencrypt/renewal-hooks/deploy/dirsrv" do
content dirsrv_hook
mode 0755
owner "root"
@@ -129,9 +154,22 @@ nsslapd-allow-anonymous-access: off
source 'nginx_conf_empty.erb'
owner node["nginx"]["user"]
mode 0640
notifies :reload, 'service[nginx]', :delayed
end
nginx_certbot_site new_resource.hostname do
notifies :run, "execute[letsencrypt cert for #{new_resource.hostname}]", :delayed
end
# Generate a Let's Encrypt cert (only if the nginx vhost exists and no cert
# has been generated before. The renew cron will take care of renewing
execute "letsencrypt cert for #{new_resource.hostname}" do
root_directory = "/var/www/#{new_resource.hostname}"
command "certbot certonly --webroot --agree-tos --email ops@kosmos.org --webroot-path #{root_directory} --deploy-hook /etc/letsencrypt/renewal-hooks/deploy/dirsrv -d #{new_resource.hostname} -n"
only_if do
::File.exist?("#{node['nginx']['dir']}/sites-enabled/#{new_resource.hostname}_certbot") &&
!::File.exist?("/etc/letsencrypt/live/#{new_resource.hostname}/fullchain.pem")
end
notifies :run, "execute[add tls config]", :immediately
end

View File

@@ -1,5 +1,7 @@
node.default["kosmos-ejabberd"]["version"] = "20.02"
node.default["kosmos-ejabberd"]["checksum"] = "2ecbf7025195afaa41996cb6f1c2b5fac661f2880238506a459779051129bc93"
node.default["kosmos-ejabberd"]["version"] = "20.12"
node.default["kosmos-ejabberd"]["checksum"] = "3d2a4e9d1aa2d189017f4f310eff4d0b6c6d7cd911209cfbcca7b0ec5b577b65"
node.default["kosmos-ejabberd"]["turn_min_port"] = 50000
node.default["kosmos-ejabberd"]["turn_max_port"] = 55000
node.override["tor"]["HiddenServices"]["ejabberd"] = {
"HiddenServicePorts" => [
@@ -8,3 +10,12 @@ node.override["tor"]["HiddenServices"]["ejabberd"] = {
"5269 127.0.0.1:5269"
]
}
node.default["kosmos-ejabberd"]["uploads"] = {
"domain" => "uploads.kosmos.chat",
"max_upload_size_mb" => "100",
"upload.pm" => {
"repo" => "https://gitea.kosmos.org/kosmos/ngx_http_upload.git",
"revision" => "0.2"
}
}

View File

@@ -19,8 +19,10 @@ chef_version '>= 12.14' if respond_to?(:chef_version)
#
# source_url 'https://github.com/<insert_org_here>/kosmos-ejabberd'
depends "kosmos-postgresql"
depends "kosmos-base"
depends "kosmos-postgresql"
depends "kosmos-nginx"
depends "kosmos-dirsrv"
depends "backup"
depends "firewall"
depends "tor-full"

View File

@@ -24,21 +24,14 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
include_recipe "kosmos-postgresql"
ejabberd_credentials = data_bag_item("credentials", "ejabberd")
cookbook_file "#{Chef::Config[:file_cache_path]}/pg.sql" do
source "pg.sql"
mode "0664"
end
ejabberd_version = node["kosmos-ejabberd"]["version"]
package_checksum = node["kosmos-ejabberd"]["checksum"]
package_path = "#{Chef::Config['file_cache_path']}/ejabberd_#{ejabberd_version}-0_amd64.deb"
remote_file package_path do
source "https://www.process-one.net/downloads/downloads-action.php?file=/ejabberd/#{ejabberd_version}/ejabberd_#{ejabberd_version}-0_amd64.deb"
source "https://www.process-one.net/downloads/downloads-action.php?file=/#{ejabberd_version}/ejabberd_#{ejabberd_version}-0_amd64.deb"
checksum package_checksum
notifies :install, "dpkg_package[ejabberd]", :immediately
end
@@ -50,13 +43,37 @@ dpkg_package "ejabberd" do
notifies :create, "file[/lib/systemd/system/ejabberd.service]", :immediately
end
postgresql_data_bag_item = data_bag_item('credentials', 'postgresql')
postgresql_user 'ejabberd' do
action :create
password postgresql_data_bag_item['ejabberd_user_password']
file "/opt/ejabberd/.erlang.cookie" do
mode "0400"
owner "ejabberd"
group "ejabberd"
content ejabberd_credentials['erlang_cookie']
end
file "/opt/ejabberd/.hosts.erlang" do
mode "0644"
owner "ejabberd"
group "ejabberd"
content <<-EOF
"andromeda.kosmos.org".
"centaurus.kosmos.org".
"draco.kosmos.org".
EOF
end
ruby_block "configure ERLANG_NODE" do
block do
file = Chef::Util::FileEdit.new("/opt/ejabberd/conf/ejabberdctl.cfg")
file.search_file_replace_line(
%r{#ERLANG_NODE=ejabberd@localhost},
"ERLAND_NODE=#{node['kosmos-ejabberd']['erlang_node']}"
)
file.write_file
end
end
postgresql_data_bag_item = data_bag_item('credentials', 'postgresql')
hosts = [
{
name: "kosmos.org",
@@ -76,6 +93,11 @@ modules:
max_user_conferences: 1000
default_room_options:
mam: true
mod_http_upload:
put_url: "https://uploads.kosmos.chat/8af2c77"
external_secret: "#{ejabberd_credentials["uploads_secret"]}"
max_size: 104857600
thumbnail: false # otherwise needs the identify command from ImageMagick installed
EOF
},
{
@@ -101,6 +123,11 @@ modules:
public_list: false
persistent: true
mam: true
mod_http_upload:
put_url: "https://uploads.kosmos.chat/2802cfe"
external_secret: "#{ejabberd_credentials["uploads_secret"]}"
max_size: 104857600
thumbnail: false # otherwise needs the identify command from ImageMagick installed
EOF
}
]
@@ -114,18 +141,6 @@ admin_users = ejabberd_credentials['admins']
hosts.each do |host|
ldap_rootdn = "uid=xmpp,ou=#{host[:name]},cn=applications,dc=kosmos,dc=org"
postgresql_database host[:sql_database] do
owner 'ejabberd'
action :create
notifies :run, "execute[create db schema #{host[:sql_database]}]", :delayed
end
execute "create db schema #{host[:sql_database]}" do
user "ejabberd"
command "psql #{host[:sql_database]}} < #{Chef::Config[:file_cache_path]}/pg.sql"
action :nothing
end
template "/opt/ejabberd/conf/#{host[:name]}.yml" do
source "vhost.yml.erb"
mode 0640
@@ -133,28 +148,32 @@ hosts.each do |host|
group 'ejabberd'
sensitive true
variables pgsql_password: postgresql_data_bag_item['ejabberd_user_password'],
sql_server: "pg.kosmos.local",
host: host,
ldap_base: ldap_base,
ldap_server: ldap_domain,
ldap_rootdn: ldap_rootdn,
ldap_encryption_type: ldap_encryption_type
# Restarting the service is needed because the LDAP options are only parsed
# on start (https://github.com/processone/ejabberd/issues/3181#issuecomment-594482546)
# This can be changed back to reloading when this is part of a release:
# https://github.com/processone/ejabberd/commit/b39a1e2d74cd4d400a7f062e31056057573298e8
#
# notifies :run, "execute[ejabberdctl reload_config]", :delayed
notifies :restart, "service[ejabberd]", :delayed
notifies :run, "execute[ejabberdctl reload_config]", :delayed
end
end
akkounts_ip_addresses = []
search(:node, "role:akkounts").each do |node|
akkounts_ip_addresses << node["knife_zero"]["host"]
end
template "/opt/ejabberd/conf/ejabberd.yml" do
source "ejabberd.yml.erb"
mode 0640
sensitive true
variables pgsql_password: postgresql_data_bag_item['ejabberd_user_password'],
hosts: hosts,
admin_users: admin_users
variables hosts: hosts,
admin_users: admin_users,
stun_auth_realm: "kosmos.org",
turn_ip_address: node['ipaddress'],
turn_min_port: node["kosmos-ejabberd"]["turn_min_port"],
turn_max_port: node["kosmos-ejabberd"]["turn_max_port"],
akkounts_ip_addresses: akkounts_ip_addresses
notifies :run, "execute[ejabberdctl reload_config]", :delayed
end
@@ -195,11 +214,7 @@ service "ejabberd" do
end
unless node.chef_environment == "development"
firewall_rule 'ejabberd' do
port [5222, 5223, 5269, 5280, 5443]
protocol :tcp
command :allow
end
include_recipe "kosmos-ejabberd::firewall"
end
#

View File

@@ -0,0 +1,57 @@
#
# Cookbook:: kosmos-ejabberd
# Recipe:: firewall
#
# The MIT License (MIT)
#
# Copyright:: 2020, 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.
include_recipe "kosmos-base::firewall"
firewall_rule "ejabberd" do
port [5222, 5223, 5269, 5443]
protocol :tcp
command :allow
end
firewall_rule 'ejabberd_cluster' do
port [4369]
protocol :tcp
command :allow
end
firewall_rule 'erlang_cluster' do
port [4200..4210]
protocol :tcp
command :allow
end
firewall_rule 'ejabberd_stun_turn' do
port 3478
protocol :tcp
command :allow
end
firewall_rule 'ejabberd_turn' do
port node["kosmos-ejabberd"]["turn_min_port"]..node["kosmos-ejabberd"]["turn_max_port"]
protocol :tcp
command :allow
end

View File

@@ -54,10 +54,17 @@ file "/etc/letsencrypt/renewal-hooks/post/ejabberd" do
group "root"
end
gandi_api_data_bag_item = data_bag_item('credentials', 'gandi_api_5apps')
template "/root/gandi_dns_certbot_hook.sh" do
variables gandi_api_key: gandi_api_data_bag_item["key"]
mode 0770
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 kosmos xmpp" do
command "/usr/bin/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@kosmos.org -d kosmos.org -d xmpp.kosmos.org -d chat.kosmos.org -d kosmos.chat -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\" --manual-cleanup-hook \"/root/gandi_dns_certbot_hook.sh cleanup\" --deploy-hook \"/etc/letsencrypt/renewal-hooks/post/ejabberd\" --email ops@kosmos.org -d kosmos.org -d xmpp.kosmos.org -d chat.kosmos.org -d kosmos.chat -d uploads.xmpp.kosmos.org -n"
not_if do
File.exist?("/etc/letsencrypt/live/kosmos.org/fullchain.pem")
end
@@ -66,7 +73,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 "/usr/bin/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 -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\" --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"
not_if do
File.exist?("/etc/letsencrypt/live/5apps.com/fullchain.pem")
end

View File

@@ -1,10 +1,10 @@
#
# Cookbook:: kosmos-postgresql
# Recipe:: default
# Cookbook:: kosmos-ejabberd
# Recipe:: pg_db
#
# The MIT License (MIT)
#
# Copyright:: 2019, Kosmos Developers
# Copyright:: 2020, 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
@@ -23,29 +23,33 @@
# 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.
return if platform?('ubuntu') && node[:platform_version].to_f < 18.04
node.override['build-essential']['compile_time'] = true
include_recipe 'build-essential::default'
package("libpq-dev") { action :nothing }.run_action(:install)
chef_gem 'pg' do
compile_time true
end
#
postgresql_data_bag_item = data_bag_item('credentials', 'postgresql')
postgresql_server_install "main" do
version "10"
setup_repo false
password postgresql_data_bag_item['server_password']
action :install
postgresql_user 'ejabberd' do
action :create
password postgresql_data_bag_item['ejabberd_user_password']
end
postgresql_client_install "main" do
version "10"
setup_repo false
action :install
databases = ["ejabberd", "ejabberd_5apps"]
databases.each do |database|
postgresql_database database do
owner 'ejabberd'
action :create
notifies :run, "execute[create db schema #{database}]", :delayed
end
cookbook_file "#{Chef::Config[:file_cache_path]}/pg.sql" do
source "pg.sql"
mode "0664"
end
execute "create db schema #{database}" do
user "postgres"
command "psql #{database} < #{Chef::Config[:file_cache_path]}/pg.sql"
action :nothing
end
end

View File

@@ -0,0 +1,64 @@
#
# Cookbook:: kosmos-ejabberd
# Recipe:: upload_service
#
include_recipe "kosmos-nginx::with_perl"
ejabberd_credentials = data_bag_item("credentials", "ejabberd")
uploads_secret = ejabberd_credentials["uploads_secret"]
upload_config = node["kosmos-ejabberd"]["uploads"]
domain = upload_config["domain"]
git "/opt/upload.pm" do
repository upload_config["upload.pm"]["repo"]
revision upload_config["upload.pm"]["revision"]
action :sync
end
directory "/var/www/upload" do
user node["nginx"]["user"]
group node["nginx"]["group"]
mode "0755"
end
ruby_block "configure uploads.pm" do
block do
file = Chef::Util::FileEdit.new("/opt/upload.pm/upload.pm")
file.search_file_replace(%r{it-is-secret}, uploads_secret)
file.search_file_replace_line(
%r{my \$uri_prefix_components = 0;},
'my $uri_prefix_components = 1;'
)
file.write_file
end
end
ruby_block "configure perl module in nginx" do
block do
file = Chef::Util::FileEdit.new("/etc/nginx/nginx.conf")
file.insert_line_after_match(
%r{types_hash_bucket_size},
"\n\n perl_modules /opt/upload.pm;\n perl_require upload.pm;"
)
file.write_file
end
end
template "#{node["nginx"]["dir"]}/sites-available/#{domain}" do
source "nginx_conf_upload_service.erb"
owner node["nginx"]["user"]
mode 0640
variables server_name: domain,
ssl_cert: "/etc/letsencrypt/live/#{domain}/fullchain.pem",
ssl_key: "/etc/letsencrypt/live/#{domain}/privkey.pem",
max_upload_size_mb: upload_config["max_upload_size_mb"]
notifies :reload, "service[nginx]", :delayed
end
nginx_site domain do
action :enable
end
nginx_certbot_site domain

View File

@@ -32,6 +32,9 @@ s2s_ciphers: 'TLS_CIPHERS'
c2s_protocol_options: 'TLS_OPTIONS'
s2s_protocol_options: 'TLS_OPTIONS'
acme:
auto: false
listen:
-
port: 5222
@@ -74,6 +77,15 @@ listen:
## "/pub/archive": mod_http_fileserver
## register: true
captcha: false
-
port: 3478
transport: tcp
module: ejabberd_stun
auth_realm: <%= @stun_auth_realm %>
use_turn: true
turn_ip: <%= @turn_ip_address %>
turn_min_port: <%= @turn_min_port %>
turn_max_port: <%= @turn_max_port %>
s2s_use_starttls: optional
@@ -162,6 +174,14 @@ api_permissions:
what:
- "status"
- "connected_users_number"
"akkounts":
who:
<% @akkounts_ip_addresses.each do |ip| -%>
- ip: "<%= ip %>/32"
<% end -%>
what:
- "add_rosteritem"
- "delete_rosteritem"
language: "en"
@@ -182,10 +202,6 @@ modules:
name: "abuse-addresses"
urls: ["mailto:abuse@@HOST@"]
mod_bosh: {}
mod_http_upload:
docroot: "/opt/ejabberd/uploads/xmpp.@HOST@/"
put_url: "https://xmpp.@HOST@:5443/upload"
thumbnail: false # otherwise needs the identify command from ImageMagick installed
mod_last: {}
mod_mam:
default: always
@@ -214,6 +230,7 @@ modules:
versioning: true
store_current_id: true
mod_shared_roster: {}
mod_stun_disco: {}
mod_vcard:
search: false
mod_vcard_xupdate: {}

View File

@@ -0,0 +1,19 @@
<% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%>
# Generated by Chef
server {
listen 443 ssl http2;
server_name <%= @server_name %>;
ssl_certificate <%= @ssl_cert %>;
ssl_certificate_key <%= @ssl_key %>;
root /var/www/upload;
client_max_body_size <%= @max_upload_size_mb %>m;
location / {
perl upload::handle;
}
}
<% end -%>

View File

@@ -1,4 +1,6 @@
# Generated by Chef for <%= @host[:name] %>
# FIXME: The files only exist after the certbot hook created them, meaning
# we need to run Chef a second time
<% if File.exist?("/opt/ejabberd/conf/#{@host[:name]}.crt") && File.exist?("/opt/ejabberd/conf/#{@host[:name]}.key") -%>
certfiles:
- "/opt/ejabberd/conf/<%= @host[:name] %>.crt"
@@ -7,7 +9,7 @@ certfiles:
host_config:
"<%= @host[:name] %>":
sql_type: pgsql
sql_server: "localhost"
sql_server: "<%= @sql_server %>"
sql_database: "<%= @host[:sql_database] %>"
sql_username: "ejabberd"
sql_password: "<%= @pgsql_password %>"

View File

@@ -6,18 +6,20 @@ node.default['botka_freenode']['domain'] = "freenode.botka.kosmos.org"
node.default['hal8000_xmpp']['http_port'] = 8082
node.default['hal8000_xmpp']['domain'] = "hal8000.chat.kosmos.org"
node.default['wormhole']['http_port'] = 8083
node.default['hal8000_xmpp']['hubot_scripts'] = [
"hubot-help", "hubot-redis-brain",
"hubot-rules", "hubot-shipit", "hubot-plusplus",
"hubot-tell", "hubot-seen", "hubot-rss-reader",
"hubot-incoming-webhook", "hubot-auth",
"hubot-kredits", "hubot-schedule"
"hubot-help", "hubot-redis-brain", "hubot-rules", "hubot-shipit",
"hubot-plusplus", "hubot-tell", "hubot-seen", "hubot-incoming-webhook",
"hubot-auth", "hubot-kredits", "hubot-schedule"
]
node.default['hal8000_xmpp']['rooms'] = [
'kosmos@kosmos.chat',
'kosmos-dev@kosmos.chat',
'kredits@kosmos.chat',
'info@kosmos.chat',
'ops@kosmos.chat',
]
node.default['hal8000_xmpp']['auth_admins'] = []

View File

@@ -4,10 +4,11 @@ maintainer_email 'mail@kosmos.org'
license 'MIT'
description 'Configures Kosmos chat bots'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version '0.1.2'
version '0.2.0'
depends 'kosmos-nodejs'
depends 'kosmos-redis'
depends 'firewall'
depends 'application_javascript'
depends 'kosmos-ipfs'
depends 'git'

View File

@@ -2,8 +2,6 @@
# Cookbook Name:: kosmos-hubot
# Recipe:: _user
#
# Copyright 2019, Kosmos
#
group "hubot" do
gid 48268

View File

@@ -2,26 +2,7 @@
# Cookbook Name:: kosmos-hubot
# Recipe:: botka_freenode
#
# 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.
#
app_name = "botka_freenode"
app_path = "/opt/#{app_name}"
app_user = "hubot"
@@ -43,7 +24,7 @@ application app_path do
git do
user app_user
group app_group
repository "https://github.com/67P/botka.git"
repository "https://gitea.kosmos.org/kosmos/botka.git"
revision "master"
end

View File

@@ -2,8 +2,6 @@
# Cookbook Name:: kosmos-hubot
# Recipe:: default
#
# Copyright 2017-2018, Kosmos
#
include_recipe "kosmos-nodejs"
include_recipe "kosmos-redis"

View File

@@ -2,26 +2,6 @@
# Cookbook Name:: kosmos-hubot
# Recipe:: hal8000
#
# 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.
#
build_essential 'hal8000' do
compile_time true
@@ -50,7 +30,7 @@ application hal8000_path do
git do
user "hubot"
group "hubot"
repository "https://github.com/67P/hal8000.git"
repository "https://gitea.kosmos.org/kosmos/hal8000.git"
revision "master"
end
@@ -67,7 +47,6 @@ application hal8000_path do
"hubot-plusplus",
"hubot-tell",
"hubot-seen",
"hubot-rss-reader",
"hubot-incoming-webhook",
"hubot-auth",
"hubot-schedule"

View File

@@ -2,26 +2,7 @@
# Cookbook Name:: kosmos-hubot
# Recipe:: hal8000_xmpp
#
# 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.
#
app_name = "hal8000_xmpp"
app_path = "/opt/#{app_name}"
app_user = "hubot"
@@ -56,7 +37,7 @@ application app_path do
git do
user app_user
group app_group
repository "https://github.com/67P/hal8000.git"
repository "https://gitea.kosmos.org/kosmos/hal8000.git"
revision "master"
end
@@ -71,6 +52,22 @@ application app_path do
user app_user
end
file "#{app_path}/node_modules/hubot-kredits/.env" do
mode "0600"
owner app_user
group app_group
content <<-EOF
GITEA_TOKEN=#{data_bag['gitea_token']}
GITHUB_TOKEN=#{data_bag['github_token']}
KREDITS_PROVIDER_URL=#{node[app_name]['kredits']['provider_url']}
IPFS_API_HOST=#{node[app_name]['kredits']['ipfs_host']}
IPFS_API_PORT=#{node[app_name]['kredits']['ipfs_port']}
IPFS_API_PROTOCOL=#{node[app_name]['kredits']['ipfs_protocol']}
KREDITS_WALLET_PATH=../../#{node[app_name]['kredits']['wallet_path']}
KREDITS_WALLET_PASSWORD=#{data_bag['kredits_wallet_password']}
EOF
end
execute "systemctl daemon-reload" do
command "systemctl daemon-reload"
action :nothing
@@ -87,39 +84,41 @@ application app_path do
app_dir: app_path,
entry: "#{app_path}/bin/hubot -a xmpp --name hal8000",
environment: {
"HUBOT_LOG_LEVEL" => node.chef_environment == "development" ? "debug" : "info",
"HUBOT_XMPP_USERNAME" => "hal8000@kosmos.org/hubot",
"HUBOT_XMPP_PASSWORD" => data_bag['xmpp_password'],
"HUBOT_XMPP_HOST" => "xmpp.kosmos.org",
"HUBOT_XMPP_ROOMS" => node[app_name]['rooms'].join(','),
"HUBOT_AUTH_ADMIN" => node[app_name]['auth_admins'].join(','),
"HUBOT_RSS_PRINTSUMMARY" => "false",
"HUBOT_RSS_PRINTERROR" => "false",
"HUBOT_RSS_IRCCOLORS" => "true",
"HUBOT_PLUSPLUS_POINTS_TERM" => "karma,karma",
"HUBOT_RSS_HEADER" => "Update:",
"HUBOT_HELP_REPLY_IN_PRIVATE" => "true",
"REDIS_URL" => "redis://localhost:6379/#{app_name}",
"EXPRESS_PORT" => node[app_name]['http_port'],
"WEBHOOK_TOKEN" => data_bag['webhook_token'],
"IPFS_API_HOST" => node[app_name]['kredits']['ipfs_host'],
"IPFS_API_PORT" => node[app_name]['kredits']['ipfs_port'],
"IPFS_API_PROTOCOL" => node[app_name]['kredits']['ipfs_protocol'],
"KREDITS_WEB_URL" => node[app_name]['kredits']['web_url'],
"KREDITS_ROOM" => node[app_name]['kredits']['room'],
"KREDITS_WEBHOOK_TOKEN" => data_bag['kredits_webhook_token'],
"KREDITS_PROVIDER_URL" => node[app_name]['kredits']['provider_url'],
"KREDITS_NETWORK_ID" => node[app_name]['kredits']['network_id'],
"KREDITS_WALLET_PATH" => node[app_name]['kredits']['wallet_path'],
"KREDITS_WALLET_PASSWORD" => data_bag['kredits_wallet_password'],
"KREDITS_MEDIAWIKI_URL" => node[app_name]['kredits']['mediawiki_url'],
"KREDITS_GITHUB_REPO_BLACKLIST" => node[app_name]['kredits']['github_repo_blacklist'],
"KREDITS_GITEA_REPO_BLACKLIST" => node[app_name]['kredits']['gitea_repo_blacklist'],
"KREDITS_GRANT_HOST" => node[app_name]['domain'],
"KREDITS_GRANT_PROTOCOL" => "https",
"KREDITS_SESSION_SECRET" => data_bag['kredits_session_secret'],
"KREDITS_GITHUB_KEY" => data_bag['kredits_github_key'],
"KREDITS_GITHUB_SECRET" => data_bag['kredits_github_secret']
"HUBOT_LOG_LEVEL" => node.chef_environment == "development" ? "debug" : "info",
"HUBOT_XMPP_USERNAME" => "hal8000@kosmos.org/hubot",
"HUBOT_XMPP_PASSWORD" => data_bag['xmpp_password'],
"HUBOT_XMPP_HOST" => "xmpp.kosmos.org",
"HUBOT_XMPP_ROOMS" => node[app_name]['rooms'].join(','),
"HUBOT_AUTH_ADMIN" => node[app_name]['auth_admins'].join(','),
"HUBOT_RSS_PRINTSUMMARY" => "false",
"HUBOT_RSS_PRINTERROR" => "false",
"HUBOT_RSS_IRCCOLORS" => "true",
"HUBOT_PLUSPLUS_POINTS_TERM" => "karma,karma",
"HUBOT_RSS_HEADER" => "Update:",
"HUBOT_HELP_REPLY_IN_PRIVATE" => "true",
"REDIS_URL" => "redis://localhost:6379/#{app_name}",
"EXPRESS_PORT" => node[app_name]['http_port'],
"WEBHOOK_TOKEN" => data_bag['webhook_token'],
"IPFS_API_HOST" => node[app_name]['kredits']['ipfs_host'],
"IPFS_API_PORT" => node[app_name]['kredits']['ipfs_port'],
"IPFS_API_PROTOCOL" => node[app_name]['kredits']['ipfs_protocol'],
"KREDITS_WEB_URL" => node[app_name]['kredits']['web_url'],
"KREDITS_ROOM" => node[app_name]['kredits']['room'],
"KREDITS_WEBHOOK_TOKEN" => data_bag['kredits_webhook_token'],
"KREDITS_PROVIDER_URL" => node[app_name]['kredits']['provider_url'],
"KREDITS_NETWORK_ID" => node[app_name]['kredits']['network_id'],
"KREDITS_WALLET_PATH" => node[app_name]['kredits']['wallet_path'],
"KREDITS_WALLET_PASSWORD" => data_bag['kredits_wallet_password'],
"KREDITS_MEDIAWIKI_URL" => node[app_name]['kredits']['mediawiki_url'],
"KREDITS_GITHUB_REPO_BLACKLIST" => node[app_name]['kredits']['github_repo_blacklist'],
"KREDITS_GITEA_REPO_BLACKLIST" => node[app_name]['kredits']['gitea_repo_blacklist'],
"KREDITS_GRANT_HOST" => node[app_name]['domain'],
"KREDITS_GRANT_PROTOCOL" => "https",
"KREDITS_SESSION_SECRET" => data_bag['kredits_session_secret'],
"KREDITS_GITHUB_KEY" => data_bag['kredits_github_key'],
"KREDITS_GITHUB_SECRET" => data_bag['kredits_github_secret'],
"KREDITS_ZOOM_JWT" => data_bag['kredits_zoom_jwt'],
"KREDITS_ZOOM_MEETING_WHITELIST" => "414901303,82557072771"
}
)
notifies :run, "execute[systemctl daemon-reload]", :delayed

View File

@@ -2,96 +2,85 @@
# Cookbook Name:: kosmos-hubot
# Recipe:: wormhole
#
# 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.
#
app_name = "wormhole"
app_path = "/opt/#{app_name}"
app_user = "hubot"
app_group = "hubot"
app_path = "/opt/#{app_name}"
data_bag = Chef::EncryptedDataBagItem.load('credentials', app_name)
build_essential app_name do
compile_time true
app_env = {
"HUBOT_LOG_LEVEL" => node.chef_environment == "development" ? "debug" : "info",
"HUBOT_IRC_SERVER" => "irc.freenode.net",
"HUBOT_IRC_ROOMS" => "#kosmos,#kosmos-dev,#kosmos-random,#sockethub",
"HUBOT_IRC_NICK" => app_name,
"HUBOT_IRC_NICKSERV_USERNAME" => app_name,
"HUBOT_IRC_NICKSERV_PASSWORD" => data_bag['nickserv_password'],
"HUBOT_IRC_UNFLOOD" => "100",
"HUBOT_WORMHOLE_XMPP_JID" => "wormhole@kosmos.org",
"HUBOT_WORMHOLE_XMPP_PASSWORD" => data_bag['xmpp_password'],
"HUBOT_WORMHOLE_XMPP_HOST" => "xmpp.kosmos.org",
"HUBOT_WORMHOLE_XMPP_PORT" => "5222",
"HUBOT_WORMHOLE_XMPP_NICKNAME" => "wormhole",
"HUBOT_WORMHOLE_XMPP_ROOMS" => "kosmos@kosmos.chat,kosmos-dev@kosmos.chat,kosmos-random@kosmos.chat,sockethub@kosmos.chat",
"EXPRESS_PORT" => node['wormhole']['http_port']
}
build_essential
include_recipe "kosmos-nodejs"
include_recipe "kosmos-hubot::_user"
include_recipe "git"
git app_path do
user app_user
group app_group
repository "https://gitea.kosmos.org/kosmos/wormhole.git"
revision "master"
action :sync
notifies :run, "bash[npm_install_#{app_name}]", :immediately
notifies :restart, "systemd_unit[#{app_name}.service]", :delayed
end
include_recipe "kosmos-nodejs"
application app_path do
data_bag = Chef::EncryptedDataBagItem.load('credentials', app_name)
bash "npm_install_#{app_name}" do
user app_user
cwd app_path
code 'npm install'
action :nothing
end
file "#{app_path}/external-scripts.json" do
mode "0640"
owner app_user
group app_group
git do
user app_user
group app_group
repository "https://gitea.kosmos.org/kosmos/wormhole.git"
revision "master"
end
file "#{app_path}/external-scripts.json" do
mode "0640"
owner app_user
group app_group
content [].to_json
end
npm_install do
user app_user
end
execute "systemctl daemon-reload" do
command "systemctl daemon-reload"
action :nothing
end
template "/lib/systemd/system/#{app_name}.service" do
source 'nodejs.systemd.service.erb'
owner 'root'
group 'root'
mode '0644'
variables(
user: app_user,
group: app_group,
app_dir: app_path,
entry: "#{app_path}/bin/hubot -a irc --name #{app_name}",
environment: {
"HUBOT_LOG_LEVEL" => node.chef_environment == "development" ? "debug" : "info",
"HUBOT_IRC_SERVER" => "irc.freenode.net",
"HUBOT_IRC_ROOMS" => "#kosmos,#kosmos-dev,#kosmos-random,#sockethub",
"HUBOT_IRC_NICK" => app_name,
"HUBOT_IRC_NICKSERV_USERNAME" => app_name,
"HUBOT_IRC_NICKSERV_PASSWORD" => data_bag['nickserv_password'],
"HUBOT_IRC_UNFLOOD" => "100",
"HUBOT_WORMHOLE_XMPP_JID" => "wormhole@kosmos.org",
"HUBOT_WORMHOLE_XMPP_PASSWORD" => data_bag['xmpp_password'],
"HUBOT_WORMHOLE_XMPP_HOST" => "xmpp.kosmos.org",
"HUBOT_WORMHOLE_XMPP_PORT" => "5222",
"HUBOT_WORMHOLE_XMPP_ROOMS" => "kosmos@kosmos.chat,kosmos-dev@kosmos.chat,kosmos-random@kosmos.chat,sockethub@kosmos.chat"
}
)
notifies :run, "execute[systemctl daemon-reload]", :delayed
notifies :restart, "service[#{app_name}]", :delayed
end
service app_name do
action [:enable, :start]
end
content [].to_json
end
systemd_unit "#{app_name}.service" do
content({
Unit: {
Description: "#{app_name} (node.js app)",
Documentation: ['https://gitea.kosmos.org/kosmos/wormhole'],
},
Service: {
User: app_user,
Group: app_group,
ExecStart: "#{app_path}/bin/hubot -a irc --name #{app_name}",
WorkingDirectory: app_path,
Environment: app_env.map{|k, v| "'#{k}=#{v}'"}.join(' '),
Type: 'simple',
Restart: 'always',
RestartSec: '2',
TimeoutSec: '10',
PrivateTmp: true,
ProtectSystem: 'full',
NoNewPrivileges: true,
PrivateDevices: true
},
Install: {
WantedBy: 'multi-user.target'
}
})
verify false
triggers_reload true
action [:create, :enable, :start]
end

View File

@@ -1,7 +1,9 @@
[Unit]
Description=Start nodejs app
<% unless @without_redis %>
Requires=redis-server.service
After=redis-server.service
<% end %>
[Service]
ExecStart=<%= @entry %>

View File

@@ -17,6 +17,7 @@ node.default['kosmos-ipfs']['ipfs']['config'] = {
node.default['kosmos-ipfs']['nginx']['api_port'] = 5001
node.default['kosmos-ipfs']['nginx']['gateway_port'] = 9090
node.default['kosmos-ipfs']['nginx']['external_api_port'] = 5444
node.default['kosmos-ipfs']['nginx']['swarm_p2p_port'] = 4001
node.default['kosmos-ipfs']['nginx']['domain'] = "ipfs.kosmos.org"
node.default['kosmos-ipfs']['kredits-pinner']['revision'] = "v1.0.2"

View File

@@ -9,5 +9,6 @@ version '0.3.0'
depends 'ipfs'
depends 'kosmos-base'
depends 'kosmos-nginx'
depends 'kosmos-nodejs'
depends 'firewall'
depends 'application_javascript'

View File

@@ -34,10 +34,5 @@ node['kosmos-ipfs']['ipfs']['config'].each do |k, v|
end
unless node.chef_environment == "development"
include_recipe 'firewall'
firewall_rule 'ipfs_swarm_p2p' do
port 4001
protocol :tcp
command :allow
end
include_recipe "kosmos-ipfs::firewall_swarm"
end

View File

@@ -0,0 +1,32 @@
#
# Cookbook Name:: kosmos-ipfs
# Recipe:: firewall_public_gateway
#
# The MIT License (MIT)
#
# Copyright:: 2020, 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.
include_recipe 'firewall'
firewall_rule 'ipfs_api' do
port node['kosmos-ipfs']['nginx']['external_api_port']
protocol :tcp
command :allow
end

View File

@@ -0,0 +1,32 @@
#
# Cookbook Name:: kosmos-ipfs
# Recipe:: firewall_swarm
#
# The MIT License (MIT)
#
# Copyright:: 2020, 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.
include_recipe 'firewall'
firewall_rule 'ipfs_swarm_p2p' do
port node['kosmos-ipfs']['nginx']['swarm_p2p_port']
protocol :tcp
command :allow
end

View File

@@ -24,6 +24,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
include_recipe 'kosmos-nodejs'
app_name = "kredits-ipfs-pinner"
deploy_user = "ipfs"
deploy_group = "ipfs"

View File

@@ -49,10 +49,5 @@ end
nginx_certbot_site domain
unless node.chef_environment == "development"
include_recipe "firewall"
firewall_rule 'ipfs_api' do
port node['kosmos-ipfs']['nginx']['external_api_port']
protocol :tcp
command :allow
end
include_recipe "kosmos-ipfs::firewall_public_gateway"
end

View File

@@ -1,4 +1,4 @@
Copyright (c) 2019 Kosmos Developers
Copyright (c) 2019-2021 Kosmos Developers
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@@ -2,11 +2,11 @@ node.default["kosmos-mastodon"]["directory"] = "/opt/mastodon"
node.default["kosmos-mastodon"]["puma_port"] = 3000
node.default["kosmos-mastodon"]["streaming_port"] = 4000
node.default["kosmos-mastodon"]["server_name"] = "kosmos.social"
node.default["kosmos-mastodon"]["redis_url"] = "redis://localhost:6379/1"
node.default["kosmos-mastodon"]["redis_url"] = "redis://localhost:6379/0"
node.default["kosmos-mastodon"]["sidekiq_threads"] = 25
# Allocate this amount of RAM to the Java heap for Elasticsearch
node.default["kosmos-mastodon"]["elasticsearch"]["allocated_memory"] = "1536m"
node.override["tor"]["HiddenServices"]["mastodon"] = {
"HiddenServicePorts" => ["80 127.0.0.1:80"]
"HiddenServicePorts" => ["80 127.0.0.1:80", "443 127.0.0.1:443"]
}

View File

@@ -2,31 +2,9 @@
# Cookbook Name:: kosmos-mastodon
# Recipe:: default
#
# The MIT License (MIT)
#
# Copyright:: 2019, Kosmos Developers
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
include_recipe "kosmos-nodejs"
include_recipe "kosmos-redis"
include_recipe "kosmos-postgresql"
include_recipe "java"
elasticsearch_user 'elasticsearch'
@@ -42,22 +20,7 @@ end
elasticsearch_service 'elasticsearch'
# TODO: Remove the condition once we have migrated mastodon to andromeda
unless platform?('ubuntu') && node[:platform_version].to_f < 18.04
postgresql_data_bag_item = data_bag_item('credentials', 'postgresql')
postgresql_user 'mastodon' do
action :create
password postgresql_data_bag_item['mastodon_user_password']
end
postgresql_database 'mastodon' do
owner 'mastodon'
action :create
end
else
postgresql_data_bag_item = {}
end
postgresql_data_bag_item = data_bag_item('credentials', 'postgresql')
mastodon_path = node["kosmos-mastodon"]["directory"]
@@ -75,14 +38,15 @@ user mastodon_user do
home mastodon_path
end
package %w(imagemagick ffmpeg libxml2-dev libxslt1-dev file git curl pkg-config
libprotobuf-dev protobuf-compiler libidn11 libidn11-dev libjemalloc1)
package %w(build-essential imagemagick ffmpeg libxml2-dev libxslt1-dev file git
curl pkg-config libprotobuf-dev protobuf-compiler libidn11
libidn11-dev libjemalloc2 libpq-dev)
npm_package "yarn" do
version "1.17.3"
version "1.22.4"
end
ruby_version = "2.6.5"
ruby_version = "2.6.6"
execute "systemctl daemon-reload" do
command "systemctl daemon-reload"
@@ -169,7 +133,9 @@ application mastodon_path do
s3_region: "eu-west-1",
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']
db_pass: postgresql_data_bag_item['mastodon_user_password'],
db_host: "pg.kosmos.local"
notifies :restart, "application[#{mastodon_path}]", :delayed
end
execute "bundle install" do
@@ -214,18 +180,3 @@ application mastodon_path do
action [:enable, :start]
end
end
#
# Backup
#
unless node.chef_environment == "development"
unless node["backup"]["postgresql"]["databases"].keys.include? 'mastodon'
node.override["backup"]["postgresql"]["databases"]["mastodon"] = {
username: "mastodon",
password: postgresql_data_bag_item['mastodon_user_password']
}
end
include_recipe "backup"
end

View File

@@ -2,31 +2,11 @@
# Cookbook Name:: kosmos-mastodon
# Recipe:: nginx
#
# 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.
mastodon_path = node["kosmos-mastodon"]["directory"]
server_name = node["kosmos-mastodon"]["server_name"]
node.override['nginx']['server_names_hash_bucket_size'] = 128
include_recipe "kosmos-nginx"
directory "#{node['nginx']['dir']}/snippets" do
@@ -45,6 +25,8 @@ template "#{node['nginx']['dir']}/snippets/mastodon.conf" do
notifies :reload, 'service[nginx]', :delayed
end
onion_address = File.read("/var/lib/tor/mastodon/hostname").strip rescue nil
template "#{node['nginx']['dir']}/sites-available/#{server_name}" do
source 'nginx_conf_mastodon.erb'
owner 'www-data'
@@ -53,7 +35,7 @@ template "#{node['nginx']['dir']}/sites-available/#{server_name}" do
ssl_cert: "/etc/letsencrypt/live/#{server_name}/fullchain.pem",
ssl_key: "/etc/letsencrypt/live/#{server_name}/privkey.pem",
shared_config_path: "#{node['nginx']['dir']}/snippets/mastodon.conf",
onion_address: File.read("/var/lib/tor/mastodon/hostname").strip
onion_address: onion_address
notifies :reload, 'service[nginx]', :delayed
end

View File

@@ -0,0 +1,31 @@
#
# Cookbook Name:: kosmos-mastodon
# Recipe:: pg_db
#
postgresql_data_bag_item = data_bag_item('credentials', 'postgresql')
postgresql_user 'mastodon' do
action :create
password postgresql_data_bag_item['mastodon_user_password']
end
postgresql_database 'mastodon' do
owner 'mastodon'
action :create
end
#
# Backup
#
unless node.chef_environment == "development"
unless node["backup"]["postgresql"]["databases"].keys.include? 'mastodon'
node.override["backup"]["postgresql"]["databases"]["mastodon"] = {
username: "mastodon",
password: postgresql_data_bag_item['mastodon_user_password']
}
end
include_recipe "backup"
end

View File

@@ -1,15 +1,9 @@
# Service dependencies
REDIS_URL=<%= @redis_url %>
DB_HOST=localhost
DB_HOST=<%= @db_host %>
DB_NAME=mastodon
# TODO: Remove the condition once we have migrated mastodon to andromeda
<% if node[:platform_version].to_f < 18.04 -%>
DB_USER=postgres
DB_PASS=<%= node['postgresql']['password']['postgres'] %>
<% else -%>
DB_USER=mastodon
DB_PASS=<%= @db_pass %>
<% end -%>
DB_PORT=5432
# Federation

View File

@@ -2,8 +2,6 @@
Description=mastodon-web
Requires=redis-server.service
After=redis-server.service
Requires=postgresql@9.4-main.service
After=postgresql@9.4-main.service
[Service]
Type=simple

View File

@@ -1,25 +1,40 @@
<% if @onion_address %>
server {
listen 80;
server_name mastodon.<%= @onion_address %>;
include <%= @shared_config_path %>;
}
<% end %>
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
<% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) %>
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name <%= @server_name %>;
include <%= @shared_config_path %>;
<% if File.exist?(@ssl_cert) &&
File.exist?(@ssl_key) -%>
ssl_certificate <%= @ssl_cert %>;
ssl_certificate_key <%= @ssl_key %>;
<% end -%>
add_header Strict-Transport-Security "max-age=31536000";
add_header Onion-Location https://mastodon.<%= @onion_address %>$request_uri;
}
<% end %>
<% if @onion_address %>
server {
listen 443 ssl http2;
server_name mastodon.<%= @onion_address %>;
include <%= @shared_config_path %>;
ssl_certificate <%= @ssl_cert %>;
ssl_certificate_key <%= @ssl_key %>;
add_header Strict-Transport-Security "max-age=31536000";
}
<% end %>

View File

@@ -1,4 +1,4 @@
node.default["mediawiki"]["url"] = "https://wiki.kosmos.org/"
node.default["mediawiki"]["hubot_base_url"] = "http://barnard.kosmos.org:8080"
node.default["mediawiki"]["hubot_room"] = "#kosmos"
node.default["mediawiki"]["hubot_base_url"] = "https://hal8000.chat.kosmos.org"
node.default["mediawiki"]["hubot_room"] = "info@kosmos.chat"
node.default["mediawiki"]["ldap_enabled"] = true

View File

@@ -30,10 +30,10 @@ include_recipe 'composer'
server_name = 'wiki.kosmos.org'
node.override['mediawiki']['version'] = "1.32.0"
node.override['mediawiki']['version'] = "1.34.2"
node.override['mediawiki']['webdir'] = "#{node['mediawiki']['docroot_dir']}/mediawiki-#{node['mediawiki']['version']}"
node.override['mediawiki']['tarball']['name'] = "mediawiki-#{node['mediawiki']['version']}.tar.gz"
node.override['mediawiki']['tarball']['url'] = "https://releases.wikimedia.org/mediawiki/1.32/#{node['mediawiki']['tarball']['name']}"
node.override['mediawiki']['tarball']['url'] = "https://releases.wikimedia.org/mediawiki/1.34/#{node['mediawiki']['tarball']['name']}"
node.override['mediawiki']['language_code'] = 'en'
node.override['mediawiki']['server_name'] = server_name
node.override['mediawiki']['site_name'] = 'Kosmos Wiki'
@@ -45,11 +45,6 @@ mediawiki_credentials = data_bag_item('credentials', 'mediawiki')
node.override['mediawiki']['db']['root_password'] = mysql_credentials["root_password"]
node.override['mediawiki']['db']['pass'] = mediawiki_credentials["db_pass"]
# Fix bug in php cookbook
if platform?('ubuntu') && node[:platform_version].to_f == 14.04
node.override['php']['ext_conf_dir'] = '/etc/php5/mods-available'
end
directory "#{node['mediawiki']['webdir']}/skins/common/images" do
owner node['nginx']['user']
group node['nginx']['group']
@@ -124,7 +119,7 @@ ark "MediawikiHubot" do
action :cherry_pick
end
hubot_credentials = Chef::EncryptedDataBagItem.load('credentials', 'hal8000_freenode')
hubot_credentials = Chef::EncryptedDataBagItem.load('credentials', 'hal8000_xmpp')
webhook_token = hubot_credentials['webhook_token']
template "#{node['mediawiki']['webdir']}/extensions/MediawikiHubot/DefaultConfig.php" do
@@ -136,31 +131,28 @@ end
if node["mediawiki"]["ldap_enabled"]
# LDAP
ark "PluggableAuth" do
url "https://github.com/wikimedia/mediawiki-extensions-PluggableAuth/archive/REL1_32.zip"
path "#{node['mediawiki']['webdir']}/extensions"
owner node["nginx"]["user"]
git "#{node['mediawiki']['webdir']}/extensions/PluggableAuth" do
repository "https://github.com/wikimedia/mediawiki-extensions-PluggableAuth.git"
revision "5.7"
user node["nginx"]["user"]
group node["nginx"]["group"]
mode 0750
action :dump
action :sync
end
ark "LDAPProvider" do
url "https://github.com/wikimedia/mediawiki-extensions-LDAPProvider/archive/REL1_31.zip"
path "#{node['mediawiki']['webdir']}/extensions"
owner node["nginx"]["user"]
git "#{node['mediawiki']['webdir']}/extensions/LDAPProvider" do
repository "https://github.com/wikimedia/mediawiki-extensions-LDAPProvider.git"
revision "1.0.3"
user node["nginx"]["user"]
group node["nginx"]["group"]
mode 0750
action :dump
action :sync
end
ark "LDAPAuthentication2" do
url "https://github.com/wikimedia/mediawiki-extensions-LDAPAuthentication2/archive/REL1_31.zip"
path "#{node['mediawiki']['webdir']}/extensions"
owner node["nginx"]["user"]
git "#{node['mediawiki']['webdir']}/extensions/LDAPAuthentication2" do
repository "https://github.com/wikimedia/mediawiki-extensions-LDAPAuthentication2.git"
revision "1.0.1"
user node["nginx"]["user"]
group node["nginx"]["group"]
mode 0750
action :dump
action :sync
end
package "php-ldap"
@@ -258,6 +250,7 @@ wfLoadExtension( 'LDAPAuthentication2' );
# Disable account creation page, since this is not possible to create an account
# when only LDAP login is enabled
$wgGroupPermissions['*']['createaccount'] = false;
$wgGroupPermissions['*']['autocreateaccount'] = true;
EOF
)

File diff suppressed because one or more lines are too long

View File

@@ -47,7 +47,7 @@ include_recipe 'nginx'
# Override the nginx package resource to set a specific version, allowing
# to upgrade it
edit_resource!(:package, 'nginx') do
version "1.17.3-1~#{node['lsb']['codename']}"
version "1.19.1-1~#{node['lsb']['codename']}"
notifies :reload, 'ohai[reload_nginx]', :immediately
end
@@ -84,11 +84,5 @@ cookbook_file "#{node["nginx"]["user_home"]}/maintenance.html" do
end
unless node.chef_environment == "development"
include_recipe 'kosmos-base::firewall'
firewall_rule 'http/https' do
port [80, 443]
protocol :tcp
command :allow
end
include_recipe "kosmos-nginx::firewall"
end

View File

@@ -0,0 +1,33 @@
#
# Cookbook Name:: kosmos-nginx
# Recipe:: firewall
#
# The MIT License (MIT)
#
# Copyright:: 2020, 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.
include_recipe "kosmos-base::firewall"
firewall_rule "http/https" do
port [80, 443]
protocol :tcp
command :allow
end

View File

@@ -0,0 +1,32 @@
#
# Cookbook Name:: kosmos-nginx
# Recipe:: with_perl
#
node.override['nginx']['default_site_enabled'] = false
node.override['nginx']['server_tokens'] = 'off'
node.override['nginx']['package_name'] = 'nginx-core'
include_recipe 'nginx'
package 'libnginx-mod-http-perl'
# Generate Strong Diffie-Hellman Group (increases security)
# https://weakdh.org/sysadmin.html
openssl_dhparam "/etc/ssl/private/dhparams.pem" do
key_length 2048
mode 0600
owner 'www-data'
end
cookbook_file "#{node['nginx']['dir']}/conf.d/tls_config.conf" do
source 'nginx_tls_config.conf'
owner 'root'
group 'root'
mode '0644'
notifies :restart, 'service[nginx]'
end
unless node.chef_environment == "development"
include_recipe 'kosmos-nginx::firewall'
end

View File

@@ -8,8 +8,6 @@ property :site, String
action :create do
return if node.chef_environment == "development"
include_recipe "kosmos-nginx"
domain = new_resource.domain
site = new_resource.site || domain
root_directory = "/var/www/#{domain}"
@@ -39,10 +37,12 @@ action :create do
include_recipe "kosmos-base::letsencrypt"
certbot_bin = node[:platform_version].to_f < 20.04 ? "/usr/bin/certbot" : "/snap/bin/certbot"
# Generate a Let's Encrypt cert (only if the nginx vhost exists and no cert
# has been generated before. The renew cron will take care of renewing
execute "letsencrypt cert for #{domain}" do
command "/usr/bin/certbot certonly --webroot --agree-tos --email ops@kosmos.org --webroot-path #{root_directory} -d #{domain} -n"
command "#{certbot_bin} certonly --webroot --agree-tos --email ops@kosmos.org --webroot-path #{root_directory} -d #{domain} -n"
only_if do
::File.exist?("#{node['nginx']['dir']}/sites-enabled/#{domain}_certbot") &&
!::File.exist?("/etc/letsencrypt/live/#{domain}/fullchain.pem")

View File

@@ -24,18 +24,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# Get package for trusty when still using vivid
if node['lsb']['codename'] == "vivid"
node.override["nodejs"]["install_repo"] = false
apt_repository "node.js" do
uri "https://deb.nodesource.com/node_8.x"
distribution "trusty"
components ["main"]
keyserver node["nodejs"]["keyserver"]
key node["nodejs"]["key"]
end
include_recipe "nodejs"
else
node.override["nodejs"]["repo"] = "https://deb.nodesource.com/node_10.x"
include_recipe "nodejs::nodejs_from_package"
end
node.override["nodejs"]["repo"] = "https://deb.nodesource.com/node_12.x"
# Allows upgrading
node.override["nodejs"]["package_action"]["nodejs"] = :upgrade
include_recipe "nodejs::nodejs_from_package"

View File

@@ -1,4 +1,4 @@
Copyright (c) 2019 Kosmos Developers
Copyright (c) 2019-2020 Kosmos Developers
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@@ -1,4 +1,57 @@
# kosmos-postgresql
TODO: Enter the cookbook description here.
## Usage
### On the primary:
Set the `postgresql_primary` role on the node
### On the replica:
Add the `postgresql_replica` role to the node's run list. Run Chef on the node
a first time.
After the initial Chef run on the replica, run Chef on the primary to add the
firewall rules and PostgreSQL access rules, then run Chef again on the replica
to set up replication.
## Caveat
[`firewall_rules`](https://github.com/chef-cookbooks/firewall/issues/134) and
[`postgresql_access`](https://github.com/sous-chefs/postgresql/issues/648) are
declared in recipes, not resources because of the way custom resources
work currently in Chef. See the `default.rb` and `replica.rb` recipes.
The primary gives access to the `replication` db to the `replication` user
connecting from a replica, and replicas to the primary. For more information
about PostgreSQL client authentication, see the
[official docs](https://www.postgresql.org/docs/12/auth-pg-hba-conf.html)
The primary opens up the PostgreSQL port (5432 TCP) to replicas, and replicas
to the primary.
## TLS self-signed certificate
A wildcard (`*.kosmos.org` certificate) was generated with the following
commands:
```
openssl req -new -nodes -text -out root.csr -keyout root.key \
-subj "/CN=root.kosmos.org"
chmod og-rwx root.key
openssl x509 -req -in root.csr -text -days 3650 \
-extfile /etc/ssl/openssl.cnf -extensions v3_ca \
-signkey root.key -out root.crt
openssl req -new -nodes -text -out server.csr \
-keyout server.key -subj "/CN=*.kosmos.org"
chmod og-rwx server.key
openssl x509 -req -in server.csr -text -days 1825 \
-CA root.crt -CAkey root.key -CAcreateserial \
-out server.crt
```
It is valid until May 12 2025.
The content of `server.crt`, `server.key` and `root.crt` an stored in the
`postgresql` encrypted data bag. The root key is stored in LastPass
("Self-signed TLS root certificate"). `server.crt` & `server.key` are used by
the PostgreSQL server.

View File

@@ -0,0 +1,3 @@
# This is set to false by default, and set to true in the server resource
# for replicas.
node.default['kosmos-postgresql']['ready_to_set_up_replica'] = false

View File

@@ -0,0 +1,45 @@
class Chef
class Recipe
def postgresql_primary
postgresql_primary = search(:node, "role:postgresql_primary AND chef_environment:#{node.chef_environment}").first
unless postgresql_primary.nil?
primary_ip = ip_for(postgresql_primary)
{ hostname: postgresql_primary[:hostname], ipaddress: primary_ip }
end
end
def postgresql_replicas
postgresql_replicas = []
search(:node, "role:postgresql_replica AND chef_environment:#{node.chef_environment}").each do |replica|
replica_ip = ip_for(replica)
postgresql_replicas << { hostname: replica[:hostname], ipaddress: replica_ip }
end
postgresql_replicas
end
def ip_for(server_node)
if node.chef_environment == "development"
server_node['network']['interfaces']['eth1']['routes'].first['src']
else
# If the server has a private Zerotier IP, use it
if server_node['knife_zero'] && server_node['knife_zero']['host'] && \
server_node['knife_zero']['host'].start_with?("10.1.1.")
server_node['knife_zero']['host']
else
server_node['ipaddress']
end
end
end
def postgresql_service_name
postgresql_version = "12"
"postgresql@#{postgresql_version}-main"
end
end
end

View File

@@ -21,3 +21,5 @@ chef_version '>= 12.14' if respond_to?(:chef_version)
depends "postgresql", ">= 7.0.0"
depends "build-essential"
depends "kosmos_encfs"
depends "hostsfile"

View File

@@ -0,0 +1,15 @@
#
# Cookbook:: kosmos-postgresql
# Recipe:: firewall
#
unless node.chef_environment == "development"
include_recipe "kosmos-base::firewall"
firewall_rule "postgresql zerotier members" do
port 5432
protocol :tcp
command :allow
source "10.1.1.0/24"
end
end

View File

@@ -0,0 +1,16 @@
#
# Cookbook:: kosmos-postgresql
# Recipe:: hostsfile
#
begin
primary_ip = postgresql_primary[:ipaddress]
rescue NoMethodError
end
unless primary_ip.nil?
hostsfile_entry primary_ip do
hostname "pg.kosmos.local"
unique true
end
end

View File

@@ -0,0 +1,33 @@
#
# Cookbook:: kosmos-postgresql
# Recipe:: primary
#
postgresql_version = "12"
postgresql_service = "postgresql@#{postgresql_version}-main"
service postgresql_service do
supports restart: true, status: true, reload: true
end
postgresql_custom_server postgresql_version do
role "primary"
end
postgresql_access "zerotier members" do
access_type "host"
access_db "all"
access_user "all"
access_addr "10.1.1.0/24"
access_method "md5"
notifies :reload, "service[#{postgresql_service}]", :immediately
end
postgresql_access "zerotier members replication" do
access_type "host"
access_db "replication"
access_user "replication"
access_addr "10.1.1.0/24"
access_method "md5"
notifies :reload, "service[#{postgresql_service}]", :immediately
end

View File

@@ -0,0 +1,56 @@
#
# Cookbook:: kosmos-postgresql
# Recipe:: replica
#
postgresql_version = "12"
postgresql_service = "postgresql@#{postgresql_version}-main"
postgresql_custom_server postgresql_version do
role "replica"
end
service postgresql_service do
supports restart: true, status: true, reload: true
end
postgresql_data_bag_item = data_bag_item('credentials', 'postgresql')
primary = postgresql_primary
unless primary.nil?
# TODO
postgresql_data_dir = "/var/lib/postgresql/#{postgresql_version}/main"
# FIXME get zerotier IP
execute "set up replication" do
command <<-EOF
systemctl stop #{postgresql_service}
mv #{postgresql_data_dir} #{postgresql_data_dir}.old
pg_basebackup -h pg.kosmos.local -U replication -D #{postgresql_data_dir} -R
chown -R postgres:postgres #{postgresql_data_dir}
systemctl start #{postgresql_service}
EOF
environment 'PGPASSWORD' => postgresql_data_bag_item['replication_password']
sensitive true
not_if { ::File.exist? "#{postgresql_data_dir}/standby.signal" }
end
postgresql_access "zerotier members" do
access_type "host"
access_db "all"
access_user "all"
access_addr "10.1.1.0/24"
access_method "md5"
notifies :reload, "service[#{postgresql_service}]", :immediately
end
postgresql_access "zerotier members replication" do
access_type "host"
access_db "replication"
access_user "replication"
access_addr "10.1.1.0/24"
access_method "md5"
notifies :reload, "service[#{postgresql_service}]", :immediately
end
end

View File

@@ -0,0 +1,77 @@
resource_name :postgresql_custom_server
property :postgresql_version, String, required: true, name_property: true
property :role, String, required: true # Can be primary or replica
action :create do
postgresql_version = new_resource.postgresql_version
postgresql_data_dir = "/var/lib/postgresql/#{postgresql_version}/main"
postgresql_service = "postgresql@#{postgresql_version}-main"
postgresql_credentials = data_bag_item('credentials', 'postgresql')
build_essential do
compile_time true
end
package("libpq-dev") { action :nothing }.run_action(:install)
chef_gem 'pg' do
compile_time true
end
user "postgres" do
manage_home false
end
postgresql_server_install "main" do
version postgresql_version
setup_repo true
password postgresql_credentials['server_password']
action :install
end
service postgresql_service do
supports restart: true, status: true, reload: true
action [:enable, :start]
end
# This service is a dependency that will auto-start our cluster service on
# boot if it's enabled, so we disable it explicitly
service "postgresql" do
action :disable
end
shared_buffers = if node['memory']['total'].to_i / 1024 < 1024 # > 1GB RAM
"128MB"
else # >= 1GB RAM, use 25% of total RAM
"#{node['memory']['total'].to_i / 1024 / 4}MB"
end
additional_config = {
max_connections: 100, # default
shared_buffers: shared_buffers,
unix_socket_directories: "/var/run/postgresql",
dynamic_shared_memory_type: "posix",
timezone: "UTC", # default is GMT
listen_addresses: "0.0.0.0"
}
additional_config[:promote_trigger_file] = "#{postgresql_data_dir}/failover.trigger"
postgresql_server_conf "main" do
version postgresql_version
additional_config additional_config
notifies :reload, "service[#{postgresql_service}]", :delayed
end
postgresql_user "replication" do
action :create
replication true
password postgresql_credentials['replication_password']
end
end
action_class do
# to use the data_dir helper
include PostgresqlCookbook::Helpers
end

View File

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

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