- kosmos_email: add the missing Berksfile so its declared dependencies
(hostname/unbound/postfix) resolve
- kosmos_garage: add local path deps for the internal cookbooks so
Berkshelf stops fetching them from Supermarket
- kosmos_rsk: bump rskj to 9.0.4~<codename> (current ppa:rsksmart/rskj
build) and update the matching InSpec assertion; suite now passes 9/9
- document the remaining suite work in doc/test-kitchen-open-tasks.md
Set `product_name: cinc` on the dokken provisioner so kitchen-dokken
uses cincproject/cinc and skips the Chef license prompt, and pin
chef_version where it was missing.
The root Vagrantfile used the license-gated chef_zero provisioner, and
Vagrant's built-in chef provisioner cannot provision Cinc. The
kosmos-bitcoin suite converged nothing (no run_list) and tor-full
targeted long-EOL platforms, so drop both rather than port them.
Cinc Workstation replaces Chef Workstation for driving knife-zero and
Test Kitchen; nodes run (or are moving to) Cinc Client.
- Pin .ruby-version to cinc-workstation
- Move knife config from .chef/ to .cinc/ (Cinc's USER_CONF_DIR) and
update .gitignore, README, AGENTS and docs accordingly. On-node config
now lives in /etc/cinc
- Drop the Gemfile/Gemfile.lock; install knife-zero into Cinc
Workstation's user gem dir with `cinc gem install knife-zero`
- README: rewrite setup/usage for Cinc Workstation
- scripts/postgresql/switch_primary.sh: drop `bundle exec`
CVE-2026-98432 is a use-after-free in the Linux IPv4 TCP option
handling (inet_opt/ireq_opt are freed with a plain kfree()) that is
reachable by sending a TCP SYN carrying IP options. No fixed kernel has
been released for any supported Ubuntu release yet, so mitigate in
role[base] until one is:
* Drop inbound IPv4 TCP segments that carry IP options (no legitimate
traffic uses them) and log the drops, rate limited, so probing is
visible. The rules are added to /etc/ufw/before.rules so they survive
ufw reloads, and are idempotent.
* Disable Multipath TCP where the kernel supports it (5.6+). Go
programs built with Go >= 1.24 open MPTCP listeners by default, which
is the precondition of the published exploit; nothing here needs
MPTCP. Hosts on older kernels (5.4, no MPTCP) skip this.
The sysctl drop-in is written directly rather than via the core sysctl
resource, whose reload runs `sysctl -p` against /etc/sysctl.conf - a
file that no longer exists on Ubuntu 26.04.
Opt node_exporter (Go >= 1.24, so it opened an MPTCP listener) out of
MPTCP with GODEBUG=multipathtcp=0, and restart it when the unit
changes so the change takes effect without a separate restart.
Bump the runtime Ruby to 4.0.9 (and the ruby-build definitions to
v20261023, the first release that defines it), matching upstream's
updated default Ruby for the 4.7.4 security release.
Probot 14 changed its default webhook path from "/" (Probot 7) to
"/api/github/webhooks", but the GitHub App still POSTs to
https://kredits-github.kosmos.org/. Every delivery returned 404, so the
app never processed pull_request events and never created the Kredits
check run. Serve "/" again via WEBHOOK_PATH.
Chef's systemd_unit :create only runs daemon-reload and never restarts a
running unit, so the env change above would not have taken effect until
the next repo change or reboot. Manage the unit with :create/:enable and
restart it from a service resource that subscribes to unit changes.
Apply the same fix to the kosmos-hubot bot resource.
Read the hal8000 webhook token from credentials/hubot in the mediawiki and
alertmanager recipes, and drop the now-unused botka_irc-libera-chat,
hal8000_xmpp and hal8000_freenode bags.
search(:node, 'role:hubot') also matched retired nodes outside production
(e.g. nodejs-4 in _default), so the vhosts could proxy to a dead host and
return 502. Restrict the search to chef_environment:production and pick
deterministically.
The per-bot firewall_rule declared inside the kosmos_hubot_bot custom
resource was not collected by the ufw provider when it rebuilt the rules
file, so the bots' HTTP ports were never opened. Declare the rules in the
default recipe instead, matching the pattern used by the other cookbooks,
and drop the now-unused firewall property from the resource.
hubot-auth is CoffeeScript-only (needs porting) and nothing in the bots calls
robot.auth; remove it from hal8000's external scripts and drop HUBOT_AUTH_ADMIN
from both bots.
Replace the per-bot and per-vhost recipes with a single data-driven setup.
- resources/bot.rb (kosmos_hubot_bot): git checkout, npm install, generated
external-scripts.json, extra files, and one hardened systemd unit for every
hubot (Type=simple, Restart=always, RestartSec=2, TimeoutSec=10, PrivateTmp,
ProtectSystem=full, NoNewPrivileges, PrivateDevices)
- recipes/default.rb: shared setup + loop over node['kosmos-hubot']['bots'];
recipes/nginx.rb: loop over node['kosmos-hubot']['vhosts'];
recipes/hal8000_extras.rb: augments the hal8000 bot (searched IPFS/RSK hosts,
kredits .env, wallet) and declares no resources itself
- bot config and vhosts now live in attributes; secrets come from the encrypted
credentials/hubot bag via secret_env
- Node 22.23.4; kosmos_redis replaces redisio; REDIS_URL uses ?<prefix>; the
adapter is passed as -a <module>; botka gains hubot-incoming-webhook
- roles/hubot, nginx_proxy, openresty_proxy and the chef-nodes pointer updated
Move kredits-github onto Node 22.23.4 and behind the openresty reverse proxy
on the proxy hosts, replacing its own nginx + the custom haproxy entry.
- pin Node 22.23.4; run the app with HOST=0.0.0.0 / NODE_ENV=production and
open port 3000 to 10.1.1.0/24 so the proxy can reach it over ZeroTier
- create /opt/kredits-github owned by the deploy user before cloning
- add kredits-github::nginx_proxy (tls_cert_for + openresty_site, upstream
from role:kredits_github) and register it in the openresty_proxy run list
- drop the app-node nginx recipe/template and its role entry
Pin v0.15.15 and set blockExplorerUrl (config-only since 0.15.14). Discard
local checkout changes before the pinned checkout, and use
`npm ci --omit=dev --legacy-peer-deps` per upstream guidance.
Bump Node to patched releases (mastodon/sockethub 24.22.1, RTL 22.23.4).
Force the pinned major's latest patch in kosmos-nodejs: nodejs_install only
selects the repo major and a bare `package nodejs` never upgrades an already
installed package.
For hosts stuck on Node 16 (no patched 16.x), run the services with
NODE_OPTIONS=--use-openssl-ca so they use the patched system trust store:
ipfs-pinner, kredits-github, hubot botka/hal8000, sockethub.
cacert.org is intermittently unreachable, which fails bootstraps at the
remote_file step. Ship both roots in the cookbook and install them with
cookbook_file; contents match what was already installed fleet-wide.
Resolve the client config dir at runtime (Chef::Config[:config_file] /
:client_d_dir) instead of hardcoding /etc/chef, and create client.d when
missing so fresh nodes work.
Reload only the attributes file we just wrote, not the whole client.rb:
reloading client.rb reset chef_server_url and dropped knife-zero's -S (TCP)
override, so later server calls fell back to socketless chefzero and failed
with No socketless Cinc Zero server.
The migration chain starts mastodon-search-deploy.service immediately, but the systemd_unit resource was declared later in the recipe, so the unit did not exist yet and systemctl failed with 'Unit not found'.
The stamp files' lazy git call ran as root, which git rejects on the mastodon-owned repository (dubious ownership), silently writing an empty stamp. Use execute resources with the mastodon user instead so git works and the revision is recorded.
The mastodon user's home was /opt/mastodon, i.e. the clone destination, so writing the SSH deploy key into ~/.ssh made the directory non-empty and Chef's git resource silently skipped cloning (it only clones into an empty directory). Use a dedicated /home/mastodon home for the user and keep the clone destination separate. Also clear a non-git (partial) clone destination before cloning.
Bundler 4 (shipped with Ruby 4) removed --deployment. Use 'bundle config set --local deployment true' (frozen + vendor/bundle) and the 'without' setting instead, in the Mastodon, akkounts and liquor-cabinet cookbooks.