Repository navigation
Releases: robert-patrick-texas/radiator-yubikey
Release list
1.12.1
A fix for the anycast check, which sometimes took the anycast addresses
off lo twice when it stopped, and logged an error the second time (see
Fixed). Nothing else changes. To upgrade, install this release's package
as before; on a turn-key setup, run this release's yubikey-turnkey with
the same site.toml and secrets.toml and its package (-p; it makes
no new secrets), copy the folders, and run setup.sh on the primary
first, then on the other two (see
Upgrade a turn-key setup).
Fixed
yubikey-anycast.sh run: at a stop, it sometimes took the anycast
addresses offlotwice at once, the second time loggingerror: cannot remove ADDRESS from lo(they were removed either way). Bash also ran
its exit trap in the backgroundsleepbetween two checks, when the
stop's TERM reached that child while it was still working out how long
to sleep. The trap now runs only in the check's own shell, and the time
is worked out before thesleepstarts.tests/run-tests.sh's
anycast_runfailed on it once; a stress test of its stop, 2 times in
150.
Tests
tests/radiator/upgrade.shstarts from 1.12.0 (its git tag), not
1.11.0, withturnkey.sh's wholesite.toml([backup]too), and
checks thatyubikey-turnkeymakes no new secrets. The guide's
Upgrade a turn-key setup
keeps the line from 1.11.0 to 1.12.0 as its example.
Download
radiator-yubikey_1.12.1_all.deb is the package, and install.sh installs it
with the packages that it and Radiator need. Download both into one
directory, check them, and run install.sh there:
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.12.1/radiator-yubikey_1.12.1_all.deb
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.12.1/radiator-yubikey_1.12.1_all.deb.sha256
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.12.1/install.sh
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.12.1/install.sh.sha256
sha256sum -c radiator-yubikey_1.12.1_all.deb.sha256 install.sh.sha256
sudo bash install.shFrom 1.10.0, 1.11.0 or 1.12.0, there is nothing to do after upgrading (a
turn-key setup: see above). From an older version, run init once, as the 1.10.0
notes say: sudo /opt/radiator-yubikey/yubikey-db.sh init
with SQLite, or /opt/radiator-yubikey/yubikey-db.sh -b pg init as an admin,
against the primary, with PostgreSQL.
For the turn-key setup, the same radiator-yubikey_1.12.1_all.deb and
install.sh go next to each server's setup.sh (or yubikey-turnkey --packages DIR puts them there), with Radiator's packages.
radiator-yubikey-1.12.1.tar.gz unpacks to radiator-yubikey-1.12.1/ with the
scripts, the guide (Markdown and HTML), the example files, the packaging and
the tests. Check it before use:
sha256sum -c radiator-yubikey-1.12.1.tar.gz.sha256
tar -xzf radiator-yubikey-1.12.1.tar.gzThe guide is also at https://robert-patrick-texas.github.io/radiator-yubikey/.
Radiator itself is not included; it comes from Radiator Software.
1.12.0
Day two for the turn-key setup: setup.sh --status checks a server;
encrypted daily backups with yubikey-backup.sh (also for an installation
set up by hand); a lost server set up again, and setup.sh --alone when
two are lost; a server replaced with new addresses or a new name; new
passwords and keys with yubikey-turnkey --rotate; and upgrades, of
radiator-yubikey, of Radiator's packages and Ubuntu's (see the guide's
Turn-key setup). Nothing changes for an
installation that doesn't use it, except that the package adds the
backups' units, neither enabled nor started. To upgrade a turn-key setup
from 1.11.0, run this release's yubikey-turnkey with the same
site.toml and secrets.toml (it adds two SCRAM verifiers), copy the
folders, and run setup.sh on the primary first, then on the other two
(see Upgrade a turn-key setup).
Added
setup.sh --status(and the package'syubikey-turnkey-setup.sh --status, without the folder): checks a turn-key server without
changing anything (its services, etcd, Patroni, Radiator's listeners,
the anycast check and its key, partition mode, BGP, the firewall, the
certificates, the disk, the clock, and whethersetup.shhas made what
its folder holds) and sums it up in its first line,OK,WARNINGor
CRITICAL, with the exit status that monitoring tools expect (0, 1, 2;
3 when it can't check). See the guide's
Check a turn-key server.yubikey-backup.sh, withyubikey-backup.serviceand
yubikey-backup.timer(installed, not enabled): an encrypted backup of
a PostgreSQL database every day on each server, from its own
PostgreSQL (a standby's too), withpg_dumpandopenssl cms
(AES-256-GCM, RSA-OAEP) for a certificate whose private key is kept off
the servers; the dump is never on disk in clear. It keepsKEEPof
them, 7 by default, in/var/backups(yubikey-db.cms.0, the newest,
to.6, groupadm).checkdecrypts one and reads it back whole,
decryptwrites it out, both only when the file is whole and
unchanged, and on any machine withopensslandpg_restore.
restore, on the primary, says what it would undo (YubiKeys, service
accounts and groups added, deleted or changed since), asks, and
replaces every table in one transaction, keeping the counters that are
ahead and the anycast checks' keys; it waits at most 10 s for a lock.
statusexits 0 while the newest is less than 26 hours old. See the
guide's Automatic backups.- Turn-key setup:
[backup]insite.toml(certificate,keep; in
site.example.toml):setup.shinstalls the certificate and the
settings, starts the timer and makes the first backup;--statuswarns
when the newest backup is more than 26 hours old, the last one failed,
or the timer is off;--resetleaves the backups.yubikey-turnkey
checks the certificate (RSA, 3072 bits or more, no private key in the
file), and writessecrets.tomlencrypted for it
(out/secrets.toml.cms, and on each server
/var/backups/yubikey-turnkey-secrets.toml.cms), made again only when
secrets.tomlor the certificate changes. Without[backup]it says
that the servers make no backups. See the guide's
Turn-key backups. - Turn-key: a lost server is set up again with the same name and
addresses, while the other two run: its folder andsetup.sh, on a new
server, or aftersetup.sh --reset NAMEon it alone.setup.shremoves
the server's etcd member from before and adds it again (as a learner
until it has caught up), and its etcd joins the cluster that runs;
Patroni copies the database, on the first server too, which is then a
standby (--statussays to move the primary back); the database is
left as it is; and the anycast check takes its key (renewed since,
perhaps) and counter from the database. While two
servers' etcd is down, it stops at etcd, before starting it, and says
why; when all three's was, it joins once the others run again. The
runbook says what to do when a server is lost. See the guide's
Rebuild a turn-key server. - Turn-key:
setup.sh --alone, for when two servers are lost for good: on
the third, it makes its etcd a cluster of one, with its data, and its
PostgreSQL the primary (which Patroni, in quorum mode, doesn't do by
itself), after checking that the other two answer on none of etcd's,
PostgreSQL's and Patroni's ports, and asking (--yes: it doesn't). Then
setup.shon the other two, set up again, joins them to it, at the same
time too, and the third's partition mode moves the counters of the
logins in between into the database. The runbook has a "Two servers
lost" section. See the guide's
Two servers lost. - Turn-key: a server replaced, with new addresses or a new name (when a
site moves, say): aftersite.tomlandyubikey-turnkey,setup.sh
with the new folders on the two that stay, then on the new server, which
removes the old server's etcd member before adding its own (and stops
while that one still answers).yubikey-turnkeysays when a server has
new addresses (a new certificate), or is gone fromsite.toml(its
anycast key and certificate with it). The runbook has an "A server
replaced" section. See the guide's
Replace a turn-key server. - Turn-key:
yubikey-turnkey --rotate WHAT[,WHAT]makes new passwords,
secrets or keys insecrets.toml:radiator(Radiator's database
password),patroni(Patroni's REST API password, and the passwords of
the rolesreplicatorandrewinder),adminsoradmin:LOGIN,
localhost(the secret and TACACS+ key of each server's own client),
catch-all,devicesordevice:ADDRESS; it says in what order to run
setup.sh. On the primary,setup.shgives the database's roles their
new passwords (Patroni setsreplicator's andrewinder's only when it
makes the cluster); on the other two, it waits until the primary has,
from their own copy of the database, before Patroni or Radiator use
them. An admin's password is set only whensecrets.tomlhas a new one,
so one the admin changed stays until then (the role's comment names the
one set last). The anycast checks' PINs and TACACS+ passwords aren't
rotated: their logins work only from the server itself, and each check
renews its key by itself. See the guide's
Rotate passwords and keys. - Turn-key upgrades:
setup.shinstalls Radiator's packages from its
folder when they are newer than those installed (a patch release): the
newest of each (a folder copied over the one before keeps the old ones),
over the old ones, keeping the server'sradiator.conf(the package's
new sample goes beside it, asradiator.conf.dpkg-dist), and restarts
Radiator; never older ones. Its ownapt-getruns keepneedrestart,
which Ubuntu Server has, to listing the services to restart: it would
restart Patroni, which on the primary is a failover. The guide's
Upgrade a turn-key setup says
how to upgrade radiator-yubikey (from 1.11.0), Radiator and Ubuntu's
packages, one server at a time, and what Ubuntu's automatic updates and
needrestartdo to the cluster (left as Ubuntu has them).
Changed
yubikey-partition.sh statussays why the copy isn't updated, while it
isn't (copy not updated: ...).- The turn-key runbook checks each server with
setup.sh --status, and
says where the backups are. yubikey-turnkeysaysremoved out/FILEfor a file of its own it
removed fromout/.- Turn-key: every server's folder has
db/and the roles' SCRAM
verifiers, and whichever server is the primary applies them when its
setup.shruns (it was the first server only): the anycast checks of
the three servers, each once, and those of servers no longer in
site.tomlremoved. A first server that isn't the primary waits for its
anycast check instead of stopping. - Turn-key: on a server whose etcd already ran,
setup.shneeds only
etcd's quorum (it waited for all three), and doesn't restart etcd when
only itsETCD_INITIAL_*settings changed. setup.sh --reset NAMEsays what to run next:setup.shon this server
alone joins the other two again; after--reseton all three, on all
three.- Turn-key:
setup.shsets the roles' passwords only when they are new
(it set radiator's and the admins' on every run on the primary, which
undid an admin's own change).secrets.tomlgets the SCRAM verifiers
of the replication and rewind passwords (the first run of this version
makes them), andsecrets.envhas those passwords and verifiers.
Tests
tests/radiator/run.shruns the labs named (run.sh DIR turnkey upgrade), and stops a lab after about twice its usual time (60 minutes
forturnkey, 30 forgeo), then goes on with the next;e2eand
groupsrun withdocker run --init, so they stop too. Inturnkey.sh
andupgrade.sh, `...
1.11.0
The turn-key setup: three sites, with partition mode, anycast, groups and
TACACS+, set up from one input file with yubikey-turnkey (see the
guide's new section, Turn-key setup).
Nothing changes for an installation that doesn't use it, and there is
nothing to do after upgrading from 1.10.0. The package now depends on
python3.
Added
yubikey-turnkey: the setup of three sites (with partition mode,
anycast, groups and TACACS+) from one input file,site.toml(see
site.example.toml). It makes every password, key and certificate once,
insecrets.toml(mode0600), and writes a folder for each server with
asetup.shthat installs and configures everything on it: the
packages,/etc/hosts, etcd, PostgreSQL under Patroni, the database
with the anycast checks' keys and service accounts and the groups to
start with, Radiator with the devices, partition mode, FRR and the
anycast check, and an iptables firewall. The three servers run it at the
same time, and it can be run again: it changes only what differs. It
also writes a runbook, a sheet for the routers and one for the devices
(with their secrets and keys), and the admins' PostgreSQL settings. The
guide has a new section, Turn-key setup.- The package has
yubikey-turnkey,yubikey-turnkey-setup.sh(which it
copies as each server'ssetup.sh) andsite.example.toml, and depends
onpython3.
Tests
tests/run-tests.sh: scenariosturnkey(the example input, with fixed
secrets: everything it writes),turnkey_errors(the input checks) and
turnkey_secrets(the secrets it makes, and changed by hand); 46 scenarios
in all.tests/radiator/turnkey.sh(run.sh DIR turnkey, 96 checks): the
folders thatyubikey-turnkeymakes, run on three fresh Ubuntu 26.04
servers at once, with two routers at one site and a device behind them:
logins at the anycast addresses over RADIUS and TACACS+, IPv4 and IPv6,
refused for a group without access; a server withdrawn from both of its
routers when only its TACACS+ login fails; the firewall;setup.shrun
again, a reboot, a new device, new certificates, and--reset.tests/radiator/tacacs.plconnects over IPv6 without
libio-socket-inet6-perl.
Download
radiator-yubikey_1.11.0_all.deb is the package, and install.sh installs it
with the packages that it and Radiator need. Download both into one
directory, check them, and run install.sh there:
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.11.0/radiator-yubikey_1.11.0_all.deb
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.11.0/radiator-yubikey_1.11.0_all.deb.sha256
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.11.0/install.sh
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.11.0/install.sh.sha256
sha256sum -c radiator-yubikey_1.11.0_all.deb.sha256 install.sh.sha256
sudo bash install.shFrom 1.10.0, there is nothing to do after upgrading. From an older version,
run init once, as the 1.10.0 notes say: sudo /opt/radiator-yubikey/yubikey-db.sh init
with SQLite, or /opt/radiator-yubikey/yubikey-db.sh -b pg init as an admin,
against the primary, with PostgreSQL.
For the turn-key setup, the same radiator-yubikey_1.11.0_all.deb and
install.sh go next to each server's setup.sh (or yubikey-turnkey --packages DIR puts them there), with Radiator's packages.
radiator-yubikey-1.11.0.tar.gz unpacks to radiator-yubikey-1.11.0/ with the
scripts, the guide (Markdown and HTML), the example files, the packaging and
the tests. Check it before use:
sha256sum -c radiator-yubikey-1.11.0.tar.gz.sha256
tar -xzf radiator-yubikey-1.11.0.tar.gzThe guide is also at https://robert-patrick-texas.github.io/radiator-yubikey/.
Radiator itself is not included; it comes from Radiator Software.
1.10.0
TACACS+, service accounts and groups, and an anycast check that also logs
in over TACACS+ and renews its own key. Nothing changes for an installation
that doesn't use them. To use them, run yubikey-db.sh init (or -b pg init), which adds their tables, and follow the guide's new section,
Groups and TACACS+. A clause written
again with config for a remote PostgreSQL has three DBAuth lines, one
for each clause: put Radiator's password on each. With PostgreSQL, init
also adds the function with which the anycast check renews its key; until
then, the check logs that it can't, and works as before.
Added
- Service accounts (
svc.NAME), which log in with a password instead of a
YubiKey:yubikey-db.sh service add|password|list|enable|disable|delete|label.
Passwords are at least 12 characters, asked for twice, read from standard
input, or generated (--generate), and stored as{crypt}SHA-512
hashes. - Groups:
group add|delete|list|label,member add|delete,
access set|delete|list|checkandrule add|delete|list. A group may
log in to a device group (theIdentifierof the devices'<Client>
clauses, or*) at a TACACS+ privilege level, with RADIUS reply
attributes and TACACS+ command rules. An account gets the most
privileged of its groups allowed on the device, and only while it has an
active YubiKey or is an active service account.access checkshows
what Radiator finds for an account on a device group. - Tables
service_accounts,user_groups,group_members,
group_accessandgroup_rules, and the viewaccess_replies, in both
databases.initadds them to an existing database and prints
Added the service-account and group tables. In PostgreSQL, Radiator's
role may read only the view and the service accounts' names, password
hashes andactive. configalso prints the clausesServiceAccountsandGroupAccess(for
PostgreSQL, reading from any server that answers, the primary or a
standby). Both haveNoDefault, so Radiator never falls back to an
account calledDEFAULT.radiator-groups.example.conf: RADIUS and TACACS+ (port 49) through the
same Handlers, the YubiKey or password check followed by the group check,
devices in/etc/radiator/clients.d, TACACS+ accounting to a file. Every
TACACS+ authorization asks the groups again (AllowAuthorizeOnly,
AuthorizationTimeout 0), so a change, or a disabled account, applies to
sessions already open within 2 seconds, whichever of Radiator's
processes answers. It works around Radiator 4.30 answering a refused
TACACS+ authorization with an authentication packet, which devices take
for an error.dictionary.yubikey, with the attributeYubiKey-Viathat marks TACACS+
requests; a RADIUS client can't send it.- Partition mode: the copy also holds the service accounts and groups, and
a copy made by an older version gets their tables at the next sync.
setupnow runsyubikey-db.sh initon an existing copy too. config: the YubiKey clause hasNoDefault, so Radiator never falls
back to a user calledDEFAULT. Radiator 4.30's YubiKey clauses already
don't, by default (and look up the login's own username in any case), so
nothing changes; the line keeps it so.e2e.shchecks that a YubiKey
stored forDEFAULTlogs in no one else, with and without the line.yubikey-db-migrate.shcopies only the YubiKeys, as before, and warns
when the SQLite database has service accounts or groups, which it doesn't
copy.- The anycast check can log in over TACACS+ too. With
TACACS_KEY(the
TACACSPLUSKeyof<Client 127.0.0.1>) in/etc/radiator/anycast.conf,
each check ofyubikey-anycast.shalso logs in over TACACS+, at the same
time as the RADIUS login, as the service accountsvc.anycast-HOSTNAME;
asks for the session's authorization, as a device does; and checks that
Radiator listens on TCP port 49 on the anycast addresses. The addresses
come offlowhen either login fails.yubikey-anycast.sh enroll-tacacs
makes the account's password and prints it foryubikey-db.sh service add.radiator-groups.example.confaccepts these accounts only from
127.0.0.1 and doesn't log their logins; they need a group with access to
device grouplocalhost. WithoutTACACS_KEY, the check works as before. - The anycast check renews its key by itself: every 365 days
(RENEW_DAYS), or sooner when only 30 days of OTPs are left, after a
good check, it gives the key a new private ID and AES key, in the
database and in its key file, and its counters start again. It writes
with Radiator's own login (fromyubikey-cluster.conf, or
yubikey.conf) through the new PostgreSQL functionanycast_renew,
which Radiator's role may run and which changes only the keys of
anycast-*users. A renewal whose answer was lost is finished with the
same key. Not in partition mode, and not with SQLite.statusshows the
next renewal;yubikey-anycast.sh renewrenews the key at once. The key
file has a new line,made=; a key file from before has the date it was
written.
Tests
tests/run-tests.sh: scenariosgroupsandpg_groups(42 in all),
which also run Radiator'sGroupAccessquery (on PostgreSQL as
Radiator's role);pg_partitionchecks the copied groups.tests/radiator/groups.sh(run.sh DIR groups): Radiator with
radiator-groups.example.conf, logins over TACACS+ and RADIUS on SQLite
and PostgreSQL, withtests/radiator/tacacs.pl, a small TACACS+ client
on Radiator's own modules, and the anycast check over both.- The
anycastandanycast_runscenarios also run the check against a
stand-in TACACS+ server: its answers, a wrong key, no answer, and the
addresses withdrawn when only the TACACS+ login fails. tests/run-tests.sh: scenariopg_anycast(43 in all), the key renewed
in PostgreSQL: by hand and by the running check, hex and base64 keys, a
lost answer, no function, partition mode, and what Radiator's role may
do with the function.e2e.sh: the check renews its key over TLS with Radiator's login, then
logs in with the new key, and Radiator refuses the old one.geo.sh:
West's check renews its key under systemd, with partition mode set up,
and West's copy gets it.
Download
radiator-yubikey_1.10.0_all.deb is the package, and install.sh installs it
with the packages that it and Radiator need. Download both into one
directory, check them, and run install.sh there:
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.10.0/radiator-yubikey_1.10.0_all.deb
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.10.0/radiator-yubikey_1.10.0_all.deb.sha256
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.10.0/install.sh
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.10.0/install.sh.sha256
sha256sum -c radiator-yubikey_1.10.0_all.deb.sha256 install.sh.sha256
sudo bash install.shAfter upgrading, run init once: sudo /opt/radiator-yubikey/yubikey-db.sh init
with SQLite, or /opt/radiator-yubikey/yubikey-db.sh -b pg init as an admin,
against the primary, with PostgreSQL. It adds the service-account and group
tables, and in PostgreSQL the function with which the anycast check renews
its key. Upgrading from 1.8.1 or earlier, init also adds what 1.9.0
brought; with PostgreSQL, then write Radiator's clause again as the 1.9.0
notes say. Nothing else changes until you use the new features (see the
guide's section Groups and TACACS+).
radiator-yubikey-1.10.0.tar.gz unpacks to radiator-yubikey-1.10.0/ with the
scripts, the guide (Markdown and HTML), the example files, the packaging and
the tests. Check it before use:
sha256sum -c radiator-yubikey-1.10.0.tar.gz.sha256
tar -xzf radiator-yubikey-1.10.0.tar.gzThe guide is also at https://robert-patrick-texas.github.io/radiator-yubikey/.
Radiator itself is not included; it comes from Radiator Software.
1.9.0
A planned switchover no longer leaves a login unanswered now and then. After
upgrading, run yubikey-db.sh -b pg init (once, against the primary), and
write Radiator's clause again with yubikey-db.sh -b pg config on each
Radiator server, then restart Radiator. Either can come first; until both
are done, Radiator works as before.
Fixed
- In a planned switchover, or a clean restart of the primary, a login whose
counters were waiting for the standby when the old primary stopped got no
answer. PostgreSQL had saved them (canceling the wait for synchronous replication ... The transaction has already committed locally), but
Radiator only saw its connection drop, saved them again on the new
primary, and the trigger refused that as a replay (counter violation,
thenDatabase update failed). On three sites, with four logins at a
time at each site, 6 of 24 switchovers left 1 to 3 logins unanswered (10
of 9,180 logins), which madegeo.shfail now and then since 1.7.0. The
same login may now save the same counters again; with this version, 26
more switchovers left none unanswered.
Added
- PostgreSQL: a
login_idcolumn, the ID of the Radiator login that last
saved the counters, kept by the trigger. Radiator's role can neither read
nor write it.initadds it to an existing table and prints
Added the login_id column to the yubikeys table; the other commands
work with or without it.
Changed
configfor PostgreSQL:YubiKeyConnectgives each login a random ID (16
bytes from/dev/urandom), andUpdateQuerynames the login with
set_config('yubikey.login_id', ID, true), a condition that is always
true, for that save only. It also works with a table made before this
version, as before.- The trigger
yubikeys_counters_forward(PostgreSQL) runs on every save of
the counters. It still refuses counters that don't move forward, except
the same counters saved again by the login that the save names, and it
keeps that login's ID inlogin_id(empty after a save that names none,
from the scripts or from a clause written before this version). The same
OTP sent twice at the same moment is still refused the second time: the
two logins have different IDs.
Tests
e2e.shloses the answer to a save: every commit waits for a standby that
doesn't exist, and Radiator's session is ended once its save waits, as a
primary's fast shutdown ends it. With theUpdateQueryof 1.8.1 the
login gets no answer, though the save was committed; with this version's
it is accepted, and the same OTP is then a replay.pg_radiatorruns theUpdateQueryfromconfigas Radiator's role: the
same counters saved again by the same login pass; by another login, by a
save that names none, and older counters by the same login are refused;
Radiator's role can't read or writelogin_id; a table made by 1.8.1
(without the column, with the old trigger) works with the new clause, and
initadds the column.
Download
radiator-yubikey_1.9.0_all.deb is the package, and install.sh installs it
with the packages that it and Radiator need. Download both into one
directory, check them, and run install.sh there:
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.9.0/radiator-yubikey_1.9.0_all.deb
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.9.0/radiator-yubikey_1.9.0_all.deb.sha256
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.9.0/install.sh
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.9.0/install.sh.sha256
sha256sum -c radiator-yubikey_1.9.0_all.deb.sha256 install.sh.sha256
sudo bash install.shUpgrading with PostgreSQL, run /opt/radiator-yubikey/yubikey-db.sh -b pg init
as an admin (once, against the primary) to add the login_id column, and on
each Radiator server write the clause again with
/opt/radiator-yubikey/yubikey-db.sh -b pg config (with partition mode, as
yubikey-cluster.conf), put Radiator's password back on the DBAuth line,
and restart Radiator. Either can come first. Upgrading from 1.7.0 or
earlier, init also adds the label column that 1.8.0 brought (SQLite:
sudo /opt/radiator-yubikey/yubikey-db.sh init). SQLite needs nothing else.
radiator-yubikey-1.9.0.tar.gz unpacks to radiator-yubikey-1.9.0/ with the
scripts, the guide (Markdown and HTML), the example files, the packaging and
the tests. Check it before use:
sha256sum -c radiator-yubikey-1.9.0.tar.gz.sha256
tar -xzf radiator-yubikey-1.9.0.tar.gzThe guide is also at https://robert-patrick-texas.github.io/radiator-yubikey/.
Radiator itself is not included; it comes from Radiator Software.
1.8.1
The scripts are the same as in 1.8.0; this release adds a test with real
Radiator of a user with two YubiKeys. Nothing to do after upgrading from
1.8.0.
Tests
e2e.shlogs in, on SQLite and PostgreSQL, as a user with two YubiKeys:
each is found by its public ID, with its own counters (the second's lower
counter is accepted), its own PIN (the other's is refused) and its own
active; another user's YubiKey is refused, andverifyshows the label
of the YubiKey that typed the OTP; 125 checks.
Download
radiator-yubikey_1.8.1_all.deb is the package, and install.sh installs it
with the packages that it and Radiator need. Download both into one
directory, check them, and run install.sh there:
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.8.1/radiator-yubikey_1.8.1_all.deb
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.8.1/radiator-yubikey_1.8.1_all.deb.sha256
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.8.1/install.sh
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.8.1/install.sh.sha256
sha256sum -c radiator-yubikey_1.8.1_all.deb.sha256 install.sh.sha256
sudo bash install.shUpgrading from 1.7.0 or earlier, run sudo /opt/radiator-yubikey/yubikey-db.sh init
(SQLite) or /opt/radiator-yubikey/yubikey-db.sh -b pg init as an admin
(PostgreSQL; once, against the primary) to add the label column that 1.8.0
brought. Radiator's configuration doesn't change.
radiator-yubikey-1.8.1.tar.gz unpacks to radiator-yubikey-1.8.1/ with the
scripts, the guide (Markdown and HTML), the example files, the packaging and
the tests. Check it before use:
sha256sum -c radiator-yubikey-1.8.1.tar.gz.sha256
tar -xzf radiator-yubikey-1.8.1.tar.gzThe guide is also at https://robert-patrick-texas.github.io/radiator-yubikey/.
Radiator itself is not included; it comes from Radiator Software.
1.8.0
Each YubiKey can have a label, such as primary, slot 1 or spare, slot 2,
to tell a user's YubiKeys apart. After upgrading, run yubikey-db.sh init
(with -b pg for PostgreSQL, once, against the primary) to add the label
column; until then the other commands ask for it, and Radiator keeps
working either way.
Added
- A label for each YubiKey, such as
primary, slot 1orspare, slot 2, to
tell a user's YubiKeys apart: a newlabelcolumn (UTF-8 text, up to 255
characters, no control characters; empty for none). Radiator never reads
it, and Radiator's PostgreSQL role can't. label USER PUBLIC_ID LABELsets the label of one of a user's YubiKeys;
''removes it.add -l LABEL. On a terminal,addwithout-lasks for a label (Enter
for none).importtakes the label as an optional 7th CSV field, afteractive.
Files with 4 to 6 fields load as before.listshows each YubiKey's label, andverifyshows it on its first line.exportwrites the label as a 12th column, andimport --from-export
restores it. Exports made before this version (11 columns) still restore.yubikey-db-migrate.shcopies the labels, from a SQLite database with or
without the label column, and includes them in its row-by-row check;
--mode synclists a row whose label differs, without changing it.yubikey-db-user.example.shhascred_label.
Changed
- With
--updateor--replace(inadd,importand
import --from-export), a YubiKey given no label keeps the label it has,
even when its private ID or AES key changed. A label that is given
replaces it. initadds thelabelcolumn to a table made by an older version, and
says so. Until then, the other commands stop with a message to run
init; Radiator keeps working either way. With two database servers or
three sites, run it once, against the primary.yubikey-db-migrate.shrefuses a PostgreSQL table without thelabel
column, with a message to runyubikey-db.sh -b pg initfirst.- Your own
INSERT INTO yubikeys VALUES (...)statements that don't name
the columns, like those of the old example commands, fail once the table
has thelabelcolumn: name the columns, or useaddorimport. - The version is in one file,
VERSION, which each script reads from next
to it (-Vshows it;unknownwithout the file). The package's scripts,
and theinstall.shattached to a release, have it written in, so that
each also runs on its own. - The README's and the guide's download commands take the latest release
instead of naming a version.
Tests
- New scenarios
labelsandpg_labels: labels set byadd,importand
label, invalid labels, kept and replaced by--updateand--replace,
exported and restored (also from an export made before this version),
hidden from Radiator's role, and added byinitto a database made by
1.7.0.migrate_newmigrates a 1.7.0 SQLite database,migrate_invalid
rejects invalid labels, andmigrate_errorsrefuses a 1.7.0 PostgreSQL
table. The table dumps in every scenario show the label. e2e.shlogs in with a labeled YubiKey on both databases.- The transcripts show the scripts' version as
<VERSION>, so a new version
changes none.package.shchecks that the package's version is the one
inVERSION, and that theinstall.shbuilt with it has it written in.
Download
radiator-yubikey_1.8.0_all.deb is the package, and install.sh installs it
with the packages that it and Radiator need. Download both into one
directory, check them, and run install.sh there:
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.8.0/radiator-yubikey_1.8.0_all.deb
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.8.0/radiator-yubikey_1.8.0_all.deb.sha256
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.8.0/install.sh
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.8.0/install.sh.sha256
sha256sum -c radiator-yubikey_1.8.0_all.deb.sha256 install.sh.sha256
sudo bash install.shAfter an upgrade, run sudo /opt/radiator-yubikey/yubikey-db.sh init (SQLite)
or /opt/radiator-yubikey/yubikey-db.sh -b pg init as an admin (PostgreSQL;
once, against the primary) to add the label column. Radiator's configuration
doesn't change.
radiator-yubikey-1.8.0.tar.gz unpacks to radiator-yubikey-1.8.0/ with the
scripts, the guide (Markdown and HTML), the example files, the packaging and
the tests. Check it before use:
sha256sum -c radiator-yubikey-1.8.0.tar.gz.sha256
tar -xzf radiator-yubikey-1.8.0.tar.gzThe guide is also at https://robert-patrick-texas.github.io/radiator-yubikey/.
Radiator itself is not included; it comes from Radiator Software.
1.7.0
Planned switchovers and clean restarts of the primary no longer reject
logins: while no server accepts writes but every server answers, Radiator
holds each login until the new primary is ready, for up to 5 s. After a
database failure, Radiator tries again after 2 s instead of 10 s.
Added
configfor PostgreSQL adds two hooks to Radiator's clause
(ConnectionHookandNoConnectionsHook). While no server accepts
writes but every listed server answers, as during a planned switchover or
a clean restart of the primary, Radiator holds each login and tries again
every 0.5 s, for up to 5 s, instead of rejecting it; when a server doesn't
answer at all, it backs off as before. For 10 s after each new
connection, a query may take 6 s instead of 2: a primary just promoted
saves a change only once a standby streams from it (1.5 to 3 s in the
test), and a counter update cut short at 2 s was saved anyway, so
Radiator's second try failed as a replay and the login got no answer. On
three sites, with four logins at a time at each site, a planned
switchover now rejects no login and leaves none unanswered; the slowest
login at each site took 3.5 to 5.5 s. Radiator builds a login's query before it runs it, and
needs a connection to build it, soconfigalso writes a clause
YubiKeyConnectthat connects first (holding the login the same way),
and makesYubiKeyLocal, the name the Handlers use, a group of
YubiKeyConnectand the YubiKey clause, nowYubiKeySQL. Existing
configurations are not changed: writeconfigagain and restart
Radiator.
Changed
configfor PostgreSQL writesFailureBackoffTime 2instead of 10. Each
of Radiator's processes that finds no server accepting writes rejects
logins without trying for that long, so a planned switchover on three
sites rejected logins for about 10 s, though the new primary was ready
2 to 3 s after the old one began to hand over; with 2 s, and without the
hooks above, for 2 to 5 s. The guide's "about 5 s" was measured with one
login a second, which missed the processes still waiting. In return,
while there is no primary, more rejects wait for servers that don't
answer: with the primary powered off, about 16% of rejects took about 3 s
(5% before); at a site cut off from the other two, about 14% took about
4 s (3% before).
Tests
geo.shswitches the primary over twice while four users at each site log
in at the same time, and checks that every login is accepted, within 8 s,
and that none of their OTPs is a replay.ha.shchecks that Radiator compiles the hooks, that a login is held
until the standby is promoted and then accepted, and that with no
primary for longer it is held for 5 s, then rejected.
Download
radiator-yubikey_1.7.0_all.deb is the package, and install.sh installs it
with the packages that it and Radiator need. Download both into one
directory, check them, and run install.sh there:
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.7.0/radiator-yubikey_1.7.0_all.deb
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.7.0/radiator-yubikey_1.7.0_all.deb.sha256
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.7.0/install.sh
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.7.0/install.sh.sha256
sha256sum -c radiator-yubikey_1.7.0_all.deb.sha256 install.sh.sha256
sudo bash install.shAfter an upgrade, with PostgreSQL, write Radiator's clause again with
yubikey-db.sh config (the hooks and the YubiKeyLocal group are new), put
Radiator's password on its DBAuth line, and restart Radiator. Nothing
changes with SQLite.
radiator-yubikey-1.7.0.tar.gz unpacks to radiator-yubikey-1.7.0/ with the
scripts, the guide (Markdown and HTML), the example files, the packaging and
the tests. Check it before use:
sha256sum -c radiator-yubikey-1.7.0.tar.gz.sha256
tar -xzf radiator-yubikey-1.7.0.tar.gzThe guide is also at https://robert-patrick-texas.github.io/radiator-yubikey/.
Radiator itself is not included; it comes from Radiator Software.
1.6.0
The scripts as a Debian package, radiator-yubikey, in
/opt/radiator-yubikey, and install.sh, which installs it with the
packages that it and Radiator need, after checking that Radiator is
installed, from Radiator Software's packages or from their source.
Added
- The MIT license (
LICENSE). - The
radiator-yubikeypackage, built bypackaging/build-deb.shfrom
packaging/debian/(the same files always build the same package): the
scripts, their examples,tests/make-otp.sh, the HTML guide, README and
changelog in/opt/radiator-yubikey, andyubikey-partition.serviceand
yubikey-anycast.service, neither enabled nor started. An upgrade
restarts the services that run and leaves stopped ones stopped; a removal
stops them. It depends onperlandsqlite3orpostgresql-client, not
on Radiator, so that either kind of Radiator works. install.sh: looks for Radiator (Radiator Software'sradiatoror
radiator-lockedpackage, or aradiusdfrom their source, in
/opt/radiator/radiator, on thePATH, or given with--radiusd).
Without it, says how to install it and asks whether to go on; with no
terminal, stops (exit status 3) unless--yes. Then installs with
apt-getthe Perl modules that Radiator's YubiKey support and
DupCache sharedneed, the SQLite and PostgreSQL drivers and tools, and
the package; checks that Radiator's Perl loads Radiator's SQLYUBIKEY
module and those modules; and lists what is left to do (for Radiator from
source, a missingradiatoruser orradiator.service; units installed
by hand that hide the package's, with the commands that replace them).
--checkchanges nothing.tests/radiator/package.sh(inrun.sh), 48 checks: the package builds
the same twice, lintian finds nothing, and nothing is outside
/opt/radiator-yubikeybut its units;install.shon fresh Ubuntu 26.04
containers without Radiator, with Radiator Software's packages, and with
Radiator's source unpacked in/opt/radiator/radiatoror installed with
make install, each with a login through Radiator; the units under
systemd through an install, an upgrade, a removal and a purge.tests/run-tests.sh: theinstallscenario,install.shwith stand-ins
forapt-get,dpkg-queryand Radiator.
Changed
yubikey-partition.serviceandyubikey-anycast.servicerun the scripts
in/opt/radiator-yubikey, not/usr/local/sbin.- Guide: installs the scripts with the package (or a clone in
/opt/radiator-yubikey, not/opt/yubikey-db), covers Radiator from its
source, and says how to move from scripts and units installed by hand.
Partition mode and anycast no longer copy scripts and units. tests/radiator/geo.shinstalls the package on the three sites; the test
image has debhelper and lintian.
Fixed
yubikey-partition.shread its copy of the keys without waiting for a
writer to finish. While Radiator was saving a counter in the copy, or the
copy was being updated, leaving partition mode failed with "database is
locked" and waited for a later check, and the copy's size insetup,
sync,statusand the service's log could be blank. Its reads now wait
up to 10 s, as its writes already did (and the size shows?if the copy
still can't be read).tests/run-tests.sh:pg_partitionleaves
partition mode while the copy is locked.tests/radiator/geo.shcould fail now and then: reading a site's copy of
the keys while partition mode's service was updating it ("database is
locked"; it now waits for the lock), and the replayed OTP at West right
after its cut was healed, before every Radiator process had reconnected
(it now retries while the answer is "secret not found", as other checks
after a cut do).
Download
radiator-yubikey_1.6.0_all.deb is the package, and install.sh installs it
with the packages that it and Radiator need. Download both into one
directory, check them, and run install.sh there:
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.6.0/radiator-yubikey_1.6.0_all.deb
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.6.0/radiator-yubikey_1.6.0_all.deb.sha256
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.6.0/install.sh
curl -fLO https://github.com/robert-patrick-texas/radiator-yubikey/releases/download/v1.6.0/install.sh.sha256
sha256sum -c radiator-yubikey_1.6.0_all.deb.sha256 install.sh.sha256
sudo bash install.shradiator-yubikey-1.6.0.tar.gz unpacks to radiator-yubikey-1.6.0/ with the
scripts, the guide (Markdown and HTML), the example files, the packaging and
the tests. Check it before use:
sha256sum -c radiator-yubikey-1.6.0.tar.gz.sha256
tar -xzf radiator-yubikey-1.6.0.tar.gzThe guide is also at https://robert-patrick-texas.github.io/radiator-yubikey/.
Radiator itself is not included; it comes from Radiator Software.
1.5.0
Partition mode: a site that can reach no other site logs users in from a
copy of the keys on its own server, and copies the counters back to the
primary when the network returns.
Added
yubikey-partition.sh, withyubikey-partition.serviceand
yubikey-partition.example.conf: every 5 minutes it updates a SQLite
copy of the keys from the server's own PostgreSQL (counters only move
forward). When neither of the other servers has answered for 3 checks (5 s
apart), it updates the copy once more (a standby that is cut off still
answers reads), points Radiator'syubikey.conf(now a link) at the
copy's clause and restarts Radiator. A former primary, whose PostgreSQL
Patroni is stopping, uses the last copy until PostgreSQL answers again. When another server answers and the primary can be reached, it
copies the counters that moved forward in the copy to the primary (only
forward, with Radiator's own login), points the link back at the cluster,
restarts Radiator, and copies once more.- Guide: "Partition mode": how it works, the risks it accepts (an OTP used
at another site works once more at the cut-off site; changes reach it
only when the network is back), what users see, as measured, the setup,
running it, security notes and troubleshooting rows. tests/radiator/geo.sh: partition mode with West cut off, the primary's
site cut off, two servers down at once, and the link between the East
sites broken (no partition mode: East2 still reaches West).tests/run-tests.sh: thepg_partitionscenario: the copy follows the
database, the counters go back only forward, and the service switches
Radiator's clause both ways.
Fixed
tests/radiator/ha.shcould fail now and then on a replayed OTP right
after a failover: one of Radiator's four processes had not reconnected yet
and answeredYubikey secret not found in database. Those checks now
wait for an answer from the database.
Download
radiator-yubikey-1.5.0.tar.gz unpacks to radiator-yubikey-1.5.0/ with the
scripts, the guide (Markdown and HTML), the example files and the tests.
Check it before use:
sha256sum -c radiator-yubikey-1.5.0.tar.gz.sha256
tar -xzf radiator-yubikey-1.5.0.tar.gzThe guide is also at https://robert-patrick-texas.github.io/radiator-yubikey/.
Radiator itself is not included; it comes from Radiator Software.