Author SHA1 Message Date
raucao 455dc47916 Update nodes/clients 2026-09-22 16:47:33 +02:00
raucao 911080ae81 Update/refactor Sockethub cookbook for 5.0
See CHANGELOG.md for the important changes
2026-09-22 16:45:16 +02:00
raucao edd7cc44de Make Redis password optional 2026-09-22 15:33:52 +02:00
18 changed files with 127 additions and 205 deletions
+4
View File
@@ -0,0 +1,4 @@
{
"name": "sockethub-1",
"public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0DbJHhPvJTaKfPHoOa+i\nr49DPFVvAgUVsbVUsgRvnAW/ngoRwhSHTaHBIfmuvNI/6yoSTy2xZzIgsDGZDeEe\n/gSlmUjbh4Udex9pZ3fotdPjTpqDQMk8KpmCjF9SWstfYwYhcx2oLiImdeSLvn6l\nyMrpx/rieDHn8rEs/cvqkrCCPLtOxLByC92iy5wkz64PouU0/VUud0G7o02pTXd4\n0WULNpehRGl3paNmqCQmShUxeRMkJYOYspHyc13qwQHD35hOBk7A6QDDRHMRbcoI\nLE36q5Mkyh2YGbDhSemoyh+lwqYOHfYJy9gWrIvPEbg6us0yXK1xq1kifPKB9zQj\n4QIDAQAB\n-----END PUBLIC KEY-----\n"
}
+1 -1
Submodule nodes updated: 9fd20154f7...a0396e959b
+1
View File
@@ -40,6 +40,7 @@ production_run_list = %w(
kosmos-ipfs::nginx_public_gateway
kosmos-mastodon::nginx
remotestorage_discourse::nginx
sockethub::nginx
role[tor_proxy]
)
+4 -3
View File
@@ -1,10 +1,11 @@
name "sockethub"
default_attributes 'sockethub' => {
'version' => '5.0.0-alpha.1'
default_attributes 'kosmos_redis' => {
'requirepass' => false
}
run_list %w(
kosmos_redis::default
sockethub::default
sockethub::proxy
sockethub::firewall
)
@@ -3,3 +3,4 @@
default["kosmos_redis"]["add_redisio_repository"] = true
default["kosmos_redis"]["package_name"] = "redis"
default["kosmos_redis"]["port"] = 6379
default["kosmos_redis"]["requirepass"] = true
@@ -7,7 +7,7 @@
include_recipe "kosmos_redis::repo" if node["kosmos_redis"]["add_redisio_repository"]
credentials = data_bag_item("credentials", "redis")
credentials = data_bag_item("credentials", "redis") if node["kosmos_redis"]["requirepass"]
redisio_install "default" do
package_install true
@@ -17,6 +17,5 @@ end
redisio_server node["kosmos_redis"]["port"].to_s do
package_install true
package_name node["kosmos_redis"]["package_name"]
requirepass credentials["password"]
breadcrumb false
requirepass credentials["password"] if node["kosmos_redis"]["requirepass"]
end
@@ -25,5 +25,4 @@ redisio_server node["kosmos_redis"]["port"].to_s do
replicaof({"address" => primary_host, "port" => node["kosmos_redis"]["port"]})
requirepass credentials["password"]
masterauth credentials["password"]
breadcrumb false
end
+11 -3
View File
@@ -1,6 +1,14 @@
sockethub CHANGELOG
===================
CHANGELOG
=========
0.3.0
-----
- Update to sockethub 5.0.0-alpha.25
- Serve via openresty proxy (tls_cert_for + openresty_site) instead of
a directly managed nginx on the VM
- Generate sockethub.config.json (trustProxy, reconnectIpSource)
- Restrict the service port to the internal 10.1.1.0/24 network
0.1.0
-----
- [Greg Karékinian] - Initial release of sockethub
- Initial release of sockethub cookbook
+6 -23
View File
@@ -7,27 +7,10 @@ Attributes
----------
#### sockethub::default
<table>
<tr>
<th>Key</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
<tr>
<td><tt>['sockethub']['port']</tt></td>
<td>Integer</td>
<td>The local port to run sockethub on</td>
<td><tt>10551</tt></td>
</tr>
<tr>
<td><tt>['sockethub']['external_port']</tt></td>
<td>Integer</td>
<td>The external port to run sockethub on. This will also open the port on the firewall</td>
<td><tt>10550</tt></td>
</tr>
</table>
Right now the nginx vhost is hardcoded: sockethub.kosmos.org
Sockethub will be available under https://sockethub.kosmos.org:10550
| Key | Type | Description | Default |
| --- | --- | --- | --- |
| `['sockethub']['version']` | String | The npm version of sockethub to install | `5.0.0-alpha.25` |
| `['sockethub']['port']` | Integer | The local port to run sockethub on | `10550` |
| `['sockethub']['domain']` | String | The public domain served by the openresty proxy | `sockethub.kosmos.org` |
| `['sockethub']['log_level']` | String | Console log level (error, warn, info, debug) | `info` |
@@ -1,5 +1,4 @@
node.default['sockethub']['port'] = '10551'
node.default['sockethub']['external_port'] = '10550'
node.default['sockethub']['version'] = '4.1.0'
node.default['sockethub']['nginx']['server_name'] = 'sockethub.kosmos.org'
node.default['sockethub']['debug_logs'] = 'sockethub*'
node.default['sockethub']['version'] = '5.0.0-alpha.25'
node.default['sockethub']['port'] = '10550'
node.default['sockethub']['domain'] = 'sockethub.kosmos.org'
node.default['sockethub']['log_level'] = 'info'
+3 -3
View File
@@ -4,9 +4,9 @@ maintainer_email 'mail@kosmos.org'
license 'MIT'
description 'Installs/Configures sockethub'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version '0.2.0'
version '0.3.0'
depends 'firewall'
depends 'redisio'
depends 'kosmos-base'
depends 'kosmos-nodejs'
depends 'kosmos-nginx'
depends 'kosmos_openresty'
+20 -16
View File
@@ -3,10 +3,7 @@
# Recipe:: default
#
include_recipe 'redisio::default'
include_recipe 'redisio::enable'
node.override["kosmos_nodejs"]["version"] = "24.18.0"
node.override["kosmos_nodejs"]["version"] = "24.21.0"
include_recipe 'kosmos-nodejs'
user = "sockethub"
@@ -27,6 +24,24 @@ end
npm_package "sockethub" do
version node['sockethub']['version']
auto_update false
end
directory "/etc/sockethub" do
owner user
group group
mode 0750
end
template "/etc/sockethub/sockethub.config.json" do
source "sockethub.config.json.erb"
owner user
group group
mode 0640
variables port: node['sockethub']['port'],
domain: node['sockethub']['domain'],
log_level: node['sockethub']['log_level']
notifies :restart, 'systemd_unit[sockethub_nodejs.service]', :delayed
end
execute "systemctl daemon-reload" do
@@ -34,17 +49,6 @@ execute "systemctl daemon-reload" do
action :nothing
end
environment_variables = {
'PORT' => node['sockethub']['port'],
# Use the second database (index starts at 0)
'REDIS_URL' => "redis://localhost:6379/1"
}
unless node['sockethub']['debug_logs'].nil?
environment_variables['DEBUG'] = node['sockethub']['debug_logs']
end
environment = environment_variables.map{|k, v| "'#{k}=#{v}'"}.join(' ')
systemd_unit "sockethub_nodejs.service" do
content <<-EOF
[Unit]
@@ -56,7 +60,7 @@ After=redis@6379.service
ExecStart=#{entry}
User=#{user}
Group=#{group}
Environment=#{environment}
Environment=SOCKETHUB_CONFIG=/etc/sockethub/sockethub.config.json
Restart=always
[Install]
+2 -1
View File
@@ -7,7 +7,8 @@ unless node.chef_environment == "development"
include_recipe "kosmos-base::firewall"
firewall_rule 'sockethub' do
port node['sockethub']['external_port'].to_i
port node['sockethub']['port'].to_i
source '10.1.1.0/24'
protocol :tcp
command :allow
end
+27
View File
@@ -0,0 +1,27 @@
#
# Cookbook Name:: sockethub
# Recipe:: nginx
#
domain = node['sockethub']['domain']
sockethub_node = search(:node, 'role:sockethub').first
if sockethub_node.nil?
Chef::Log.warn("No node found with 'sockethub' role. Not configuring openresty site.")
return
end
tls_cert_for domain do
auth 'gandi_dns'
action :create
end
openresty_site domain do
template 'nginx_conf_sockethub.erb'
variables domain: domain,
upstream_host: sockethub_node['knife_zero']['host'],
upstream_port: node['sockethub']['port'],
ssl_cert: "/etc/letsencrypt/live/#{domain}/fullchain.pem",
ssl_key: "/etc/letsencrypt/live/#{domain}/privkey.pem"
end
-58
View File
@@ -1,58 +0,0 @@
#
# Cookbook Name:: sockethub
# Recipe:: proxy
#
include_recipe 'sockethub::firewall'
include_recipe 'kosmos-nginx'
include_recipe "kosmos-base::letsencrypt"
server_name = node['sockethub']['nginx']['server_name']
nginx_post_hook = <<-EOF
#!/usr/bin/env bash
set -e
systemctl reload nginx
EOF
file "/etc/letsencrypt/renewal-hooks/post/nginx" do
content nginx_post_hook
mode 0755
owner "root"
group "root"
end
gandi_api_credentials = data_bag_item('credentials', 'gandi_api')
template "/root/gandi_dns_certbot_hook.sh" do
variables gandi_api_key: gandi_api_credentials["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 sockethub" do
command "certbot certonly --manual --preferred-challenges dns --manual-public-ip-logging-ok --agree-tos --manual-auth-hook \"/root/gandi_dns_certbot_hook.sh auth\" --manual-cleanup-hook \"/root/gandi_dns_certbot_hook.sh cleanup\" --deploy-hook \"/etc/letsencrypt/renewal-hooks/post/nginx\" --email ops@kosmos.org -d #{server_name} -n"
not_if do
File.exist?("/etc/letsencrypt/live/#{server_name}/fullchain.pem")
end
end
template "#{node['nginx']['dir']}/sites-available/#{server_name}" do
source 'nginx_conf_sockethub.erb'
owner 'www-data'
mode 0640
variables sockethub_port: node['sockethub']['port'],
sockethub_external_port: node['sockethub']['external_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
@@ -1,6 +1,5 @@
# Generated by Chef
upstream _sockethub {
server localhost:<%= @sockethub_port %>;
server <%= @upstream_host %>:<%= @upstream_port %>;
}
map $http_upgrade $connection_upgrade {
@@ -9,34 +8,25 @@ map $http_upgrade $connection_upgrade {
}
server {
<% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%>
listen <%= @sockethub_external_port %> ssl http2;
add_header Strict-Transport-Security "max-age=15768000";
<% else -%>
listen <%= @sockethub_external_port %>;
<% end -%>
server_name <%= @domain %>;
listen <%= "#{node['openresty']['listen_ip']}:" if node['openresty']['listen_ip'] %>443 ssl http2;
listen <%= "[#{node['openresty']['listen_ipv6']}]" %>:443 ssl http2;
server_name <%= @server_name %>;
access_log "/var/log/nginx/<%= @domain %>.access.log" json;
error_log "/var/log/nginx/<%= @domain %>.error.log";
access_log <%= node[:nginx][:log_dir] %>/sockethub.access.log json;
error_log <%= node[:nginx][:log_dir] %>/sockethub.error.log warn;
# We might need real ETags, disable those for now
gzip off;
ssl_certificate <%= @ssl_cert %>;
ssl_certificate_key <%= @ssl_key %>;
location / {
# Increase number of buffers. Default is 8
proxy_buffers 1024 8k;
proxy_set_header Host $host;
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 $scheme;
proxy_pass http://_sockethub;
proxy_http_version 1.1;
# Enable WebSockets
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
<% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%>
ssl_certificate <%= @ssl_cert %>;
ssl_certificate_key <%= @ssl_key %>;
<% end -%>
}
proxy_read_timeout 300s;
}
}
@@ -0,0 +1,26 @@
{
"examples": false,
"logging": {
"level": "<%= @log_level %>",
"file": ""
},
"public": {
"protocol": "https",
"host": "<%= @domain %>",
"port": 443,
"path": "/"
},
"redis": {
"url": "redis://127.0.0.1:6379/0"
},
"sockethub": {
"port": <%= @port.to_i %>,
"host": "0.0.0.0",
"path": "/sockethub",
"trustProxy": 1
},
"credentialCheck": {
"reconnectIpSource": "proxy",
"proxyHeader": "x-forwarded-for"
}
}
@@ -1,63 +0,0 @@
#!/usr/bin/env bash
#
set -euf -o pipefail
# ************** USAGE **************
#
# Example usage (with this hook file saved in /root/):
#
# sudo su -
# certbot certonly --manual --preferred-challenges dns --manual-public-ip-logging-ok --agree-tos -d "5apps.com" -d muc.5apps.com -d "xmpp.5apps.com" \
# --manual-auth-hook "/root/letsencrypt_hook.sh auth" --manual-cleanup-hook "/root/letsencrypt_hook.sh cleanup"
#
# This hook requires configuration, continue reading.
#
# ************** CONFIGURATION **************
#
# GANDI_API_KEY: Your Gandi Live API key
#
# PROVIDER_UPDATE_DELAY:
# How many seconds to wait after updating your DNS records. This may be required,
# depending on how slow your DNS host is to begin serving new DNS records after updating
# them via the API. 30 seconds is a safe default, but some providers can be very slow
# (e.g. Linode).
#
# Defaults to 30 seconds.
#
GANDI_API_KEY="<%= @gandi_api_key %>"
PROVIDER_UPDATE_DELAY=30
regex='.*\.(.*\..*)'
if [[ $CERTBOT_DOMAIN =~ $regex ]]
then
DOMAIN="${BASH_REMATCH[1]}"
else
DOMAIN="${CERTBOT_DOMAIN}"
fi
# To be invoked via Certbot's --manual-auth-hook
function auth {
curl -s -D- -H "Content-Type: application/json" \
-H "X-Api-Key: ${GANDI_API_KEY}" \
-d "{\"rrset_name\": \"_acme-challenge.${CERTBOT_DOMAIN}.\",
\"rrset_type\": \"TXT\",
\"rrset_ttl\": 3600,
\"rrset_values\": [\"${CERTBOT_VALIDATION}\"]}" \
"https://dns.api.gandi.net/api/v5/domains/${DOMAIN}/records"
sleep ${PROVIDER_UPDATE_DELAY}
}
# To be invoked via Certbot's --manual-cleanup-hook
function cleanup {
curl -s -X DELETE -H "Content-Type: application/json" \
-H "X-Api-Key: ${GANDI_API_KEY}" \
https://dns.api.gandi.net/api/v5/domains/${DOMAIN}/records/_acme-challenge.${CERTBOT_DOMAIN}./TXT
}
HANDLER=$1; shift;
if [ -n "$(type -t $HANDLER)" ] && [ "$(type -t $HANDLER)" = function ]; then
$HANDLER "$@"
fi