diff --git a/packages/README.md b/packages/README.md index 28573c42..7336c3ff 100644 --- a/packages/README.md +++ b/packages/README.md @@ -12,6 +12,7 @@ directory each, with its own changelog and version, released on its own | `installer/` | `keel-overlay-installer` | Keel's `inithooks` (>= 2.3.6+keel14), `confconsole` (>= 2.2.3+keel8), `keel` (>= 0.12.0) | none; its manifest names the first boot hooks the three ship | | `wireguard/` | `keel-overlay-wireguard` | trixie's `wireguard-tools` 1.0.20210914 | none; the interface is the instance spec's | | `etcd/` | `keel-overlay-etcd` | trixie's `etcd-server` 3.5.16, and `keel-overlay-wireguard`, which its manifest `requires` | `etcd.service` | +| `vip/` | `keel-overlay-vip` | `keel` (>= 0.20.0), whose `keel vip` the units run, and `keel-overlay-wireguard`, which its manifest `requires` | `keel-vip.service`, the VIP's root helper with etcd, which starts its unprivileged controller as the transient `keel-vip-control`; and `keel-vip-check.timer`, enabled in every mode | | `crowdsec/` | `keel-overlay-crowdsec` | trixie's `crowdsec` 1.4.6-10 and `crowdsec-firewall-bouncer` 0.0.25 | `crowdsec.service`, `crowdsec-firewall-bouncer.service` | | `nginx/` | `keel-overlay-nginx` | trixie's `nginx` 1.26.3 and `libnginx-mod-stream` | `nginx.service`, enabled in every mode | | `coraza/` | `keel-overlay-coraza` | Keel's `libnginx-mod-http-coraza` 0.21.0 and `coreruleset` 4.25.1 (step 5), and `keel-overlay-nginx` | none: an Nginx module; `/usr/lib/keel/overlays/coraza/state` turns it on and off | diff --git a/packages/vip/debian/changelog b/packages/vip/debian/changelog new file mode 100644 index 00000000..1a7f6a3d --- /dev/null +++ b/packages/vip/debian/changelog @@ -0,0 +1,13 @@ +keel-overlay-vip (0.1.0) trixie; urgency=medium + + * First release: the units of keel's service VIP on the WireGuard mesh + (handbook decision 0049, third round). keel-vip.service runs keel vip + tend, the root helper, with CAP_NET_ADMIN alone, AF_UNIX and + AF_NETLINK only, writing only /var/lib/keel/vip and /etc/wireguard; + it starts the controller as a transient unit with a dynamic user and + no capability, and drops every VIP the node carries once it stops; + StartLimitIntervalSec=0, so a crash loop never leaves it stopped for + good; installed disabled. + keel-vip-check.timer runs keel vip check at boot and every minute. + + -- Marcos Mendez Wed, 07 Oct 2026 12:00:00 +0000 diff --git a/packages/vip/debian/control b/packages/vip/debian/control new file mode 100644 index 00000000..e77eed1c --- /dev/null +++ b/packages/vip/debian/control @@ -0,0 +1,31 @@ +Source: keel-overlay-vip +Section: admin +Priority: optional +Maintainer: KeelLinux maintainers +Uploaders: Marcos Mendez +Build-Depends: + debhelper-compat (= 13), +Standards-Version: 4.7.2 +Rules-Requires-Root: no +Vcs-Git: https://github.com/Keel-Linux/common.git -b 19.x [packages/vip] +Vcs-Browser: https://github.com/Keel-Linux/common/tree/19.x/packages/vip + +Package: keel-overlay-vip +Architecture: all +Depends: + iproute2, + keel (>= 0.20.0), + keel-overlay-wireguard, + wireguard-tools, + ${misc:Depends}, +Description: Keel overlay: the service VIP of a replicated pair + The VIP overlay of Keel Linux (handbook decision 0049): the units of + keel's VIP on the WireGuard mesh, and the overlay manifest keel reads, + installed as /usr/share/keel/overlays/vip.yaml (decision 0041). The code + is keel's (keel vip); this package ships only the units. + . + keel-vip.service is the VIP's root helper with etcd, which starts the + unprivileged controller as its own transient unit; installed disabled and + stopped: keel spec apply enables it with the overlay. keel-vip-check.timer + runs keel vip check at boot and every minute in every mode; a node that + knows no VIP skips it. diff --git a/packages/vip/debian/copyright b/packages/vip/debian/copyright new file mode 100644 index 00000000..d1f5eef0 --- /dev/null +++ b/packages/vip/debian/copyright @@ -0,0 +1,25 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: keel-overlay-vip +Upstream-Contact: KeelLinux maintainers +Source: https://github.com/Keel-Linux/common + +Files: * +Copyright: 2026 Keel Linux maintainers +License: GPL-3+ + +License: GPL-3+ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see . + . + On Debian systems, the complete text of the GNU General Public License + version 3 can be found in /usr/share/common-licenses/GPL-3. diff --git a/packages/vip/debian/rules b/packages/vip/debian/rules new file mode 100755 index 00000000..bd90e57c --- /dev/null +++ b/packages/vip/debian/rules @@ -0,0 +1,29 @@ +#!/usr/bin/make -f +# The overlay manifest, the units and the systemd preset sit beside +# debian/ (docs/manifest-v1.md, "Kinds, and where each file lives") and +# are installed under the names keel and systemd look them up by. The +# code they run is keel's (keel vip); this package ships only the units +# (handbook decision 0049, third round, point 1). + +PKG = debian/keel-overlay-vip + +%: + dh $@ + +execute_after_dh_auto_install: + install -D -m 0644 manifest.yaml $(PKG)/usr/share/keel/overlays/vip.yaml + install -D -m 0644 keel-vip.service \ + $(PKG)/usr/lib/systemd/system/keel-vip.service + install -D -m 0644 keel-vip-check.service \ + $(PKG)/usr/lib/systemd/system/keel-vip-check.service + install -D -m 0644 keel-vip-check.timer \ + $(PKG)/usr/lib/systemd/system/keel-vip-check.timer + install -D -m 0644 keel-overlay-vip.preset \ + $(PKG)/usr/lib/systemd/system-preset/20-keel-overlay-vip.preset + +# The controller is installed disabled and stopped, the state of a simple +# installation: keel spec apply enables it with the overlay. The check's +# timer runs in every mode. +override_dh_installsystemd: + dh_installsystemd --no-enable --no-start keel-vip.service + dh_installsystemd keel-vip-check.timer diff --git a/packages/vip/debian/source/format b/packages/vip/debian/source/format new file mode 100644 index 00000000..89ae9db8 --- /dev/null +++ b/packages/vip/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/packages/vip/keel-overlay-vip.preset b/packages/vip/keel-overlay-vip.preset new file mode 100644 index 00000000..d411fd9b --- /dev/null +++ b/packages/vip/keel-overlay-vip.preset @@ -0,0 +1,5 @@ +# keel-overlay-vip: the controller is off until keel spec apply enables +# the overlay (handbook decision 0041): Debian's presets enable every unit +# they do not name, on a first boot and on `systemctl preset-all`. The +# check's timer stays enabled; its service skips a node that knows no VIP. +disable keel-vip.service diff --git a/packages/vip/keel-vip-check.service b/packages/vip/keel-vip-check.service new file mode 100644 index 00000000..55c53c7c --- /dev/null +++ b/packages/vip/keel-vip-check.service @@ -0,0 +1,36 @@ +# keel-overlay-vip: keel vip check (handbook decision 0049): every peer +# asked the epoch of each VIP this node knows, a newer claim taken (an +# old primary that comes back drops the VIP at once), the VIP dropped +# where it is not held, and WireGuard's table and wg0.conf set again from +# what this node holds. Run at boot and every minute by +# keel-vip-check.timer; a node that knows no VIP has nothing to check. +# It is a client of the members' channel only: it opens no port. +[Unit] +Description=keel vip: learn newer claims of the VIPs this node knows +Documentation=https://github.com/Keel-Linux/keel/blob/main/docs/vip.md +After=network-online.target wg-quick@wg0.service +Wants=network-online.target +ConditionDirectoryNotEmpty=/var/lib/keel/vip + +[Service] +Type=oneshot +ExecStart=/usr/bin/keel vip check +CapabilityBoundingSet=CAP_NET_ADMIN +NoNewPrivileges=yes +PrivateTmp=yes +PrivateDevices=yes +ProtectSystem=strict +ReadWritePaths=/var/lib/keel/vip /etc/wireguard +ProtectHome=yes +ProtectKernelTunables=yes +ProtectKernelModules=yes +ProtectKernelLogs=yes +ProtectControlGroups=yes +ProtectClock=yes +ProtectHostname=yes +RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK +RestrictNamespaces=yes +RestrictRealtime=yes +LockPersonality=yes +SystemCallArchitectures=native +SystemCallFilter=@system-service diff --git a/packages/vip/keel-vip-check.timer b/packages/vip/keel-vip-check.timer new file mode 100644 index 00000000..6b351436 --- /dev/null +++ b/packages/vip/keel-vip-check.timer @@ -0,0 +1,13 @@ +# keel-overlay-vip: keel vip check at boot and every minute (handbook +# decision 0049: "at boot and on a timer"). It runs in every mode: on a +# node that knows no VIP the service's condition skips it. +[Unit] +Description=keel vip: check the VIPs at boot and every minute + +[Timer] +OnBootSec=30s +OnUnitActiveSec=1min +AccuracySec=5s + +[Install] +WantedBy=timers.target diff --git a/packages/vip/keel-vip.service b/packages/vip/keel-vip.service new file mode 100644 index 00000000..9caa1f60 --- /dev/null +++ b/packages/vip/keel-vip.service @@ -0,0 +1,56 @@ +# keel-overlay-vip: the VIP's root helper with etcd (handbook decision +# 0049, third round; keel's docs/vip.md), split as keel#75 splits an +# invite. This unit is the root helper: it alone changes wg0's addresses +# and WireGuard's allowed-ips, each checked against the pair record, so +# it holds CAP_NET_ADMIN and nothing else. It reaches nothing but systemd +# and the kernel (AF_UNIX, AF_NETLINK), and writes only /var/lib/keel/vip +# and /etc/wireguard. It starts the controller, which faces etcd and the +# overlay, as the transient unit keel-vip-control: a dynamic user, no +# capability at all, on an abstract unix socket of the namespace they +# share, under a fresh random name the helper binds before it starts the +# controller, each end checked by SO_PEERCRED (the helper's against the +# unit's MainPID); it sends it the etcd client certificate's key as a +# memfd. The holder renews its etcd lease (TTL 20 s) every 2 s and +# carries the VIP only while the last renewal the majority confirmed is +# under 10 s old. ExecStopPost drops every VIP this node carries, however +# the helper stopped, and the unit is never left stopped for good: a +# crash loop is retried. +[Unit] +Description=keel vip: the VIP's root helper with etcd +Documentation=https://github.com/Keel-Linux/keel/blob/main/docs/vip.md +After=network-online.target etcd.service wg-quick@wg0.service +Wants=network-online.target +ConditionPathExists=/var/lib/keel/etcd/cluster.json +StartLimitIntervalSec=0 + +[Service] +ExecStart=/usr/bin/keel vip tend +ExecStopPost=/usr/bin/keel vip tend --stopped +Restart=always +RestartSec=5 +CapabilityBoundingSet=CAP_NET_ADMIN +NoNewPrivileges=yes +PrivateTmp=yes +PrivateDevices=yes +ProtectSystem=strict +ReadWritePaths=/var/lib/keel/vip /etc/wireguard +StateDirectory=keel/vip +StateDirectoryMode=0700 +ProtectHome=yes +ProtectKernelTunables=yes +ProtectKernelModules=yes +ProtectKernelLogs=yes +ProtectControlGroups=yes +ProtectClock=yes +ProtectHostname=yes +RestrictAddressFamilies=AF_UNIX AF_NETLINK +RestrictNamespaces=yes +RestrictRealtime=yes +LockPersonality=yes +SystemCallArchitectures=native +SystemCallFilter=@system-service +MemoryMax=128M +TasksMax=64 + +[Install] +WantedBy=multi-user.target diff --git a/packages/vip/manifest.yaml b/packages/vip/manifest.yaml new file mode 100644 index 00000000..9faf83af --- /dev/null +++ b/packages/vip/manifest.yaml @@ -0,0 +1,12 @@ +manifest_version: 1 +kind: overlay +name: vip +title: Service VIP +summary: The replicated pair's VIP on the mesh (0049); moved by keel vip +requires: [wireguard] +processes: + # the controller with etcd (keel vip tend): renews the holder's lease, + # drops the VIP 10 s after its last renewal, follows the claims and + # fails over; it runs only on a member of a formed etcd cluster + - name: keel-vip + unit: keel-vip.service