Skip to content

1.2.6 — the third one this week

← Blog

1.2.6 — the third one this week

1.2.4 was Wednesday. 1.2.5 was Thursday. This is Friday.

That was not a plan. It is what a week looks like when the previous release ships a tool whose entire job is to find out what is really happening — and then it does. Nearly everything below was found by looking, and two of the faults had been sitting in the product for as long as the features they broke.

So this release does both halves of that loop: the diagnostics grew two more modes, and the things worth diagnosing got fixed.

One section is not a fix and not a tool, and it is the one to read before you upgrade: mail. The rest can be read afterwards.

The collector learned two more questions

1.2.5’s ./taranac diagnose answered one question: what happened between this device and Taranac. It answers two more now.

An HA cluster, from every side of it

Terminal window
./taranac diagnose --ha

One archive describing this node’s view of the cluster: its role and timeline, the etcd ring, Patroni’s view, replication and slots, reachability to every declared member on every port — the etcd peer port included — certificates, clocks and logs. It reads state and changes nothing.

Run it on every machine, the witness included, and send all the archives. That is the point rather than a formality: almost every HA fault is a disagreement between hosts — a timeline that forked, a secret that differs, a ring one node knows and another does not — and a disagreement cannot be seen from one side of it. Each bundle prints a single cluster-fingerprint line, so checking whether every cluster-wide secret agrees is one glance rather than a diff.

It is deliberately built for the states you actually need it in, which are the states where nothing works:

  • a node whose database will not start — it takes the timeline straight off the data volume when the container is dead;
  • a node that was never converted;
  • the witness, which has no database and no api at all.

It reads .env from the host, and asks a peer’s Patroni when the local one is gone. A node that cannot start still explains itself, which is the only condition under which a cluster diagnostic is worth anything.

Every value Taranac collects appears as a short fingerprint — enough to prove that nodes agree or disagree, never enough to carry the secret. The last lines of the database, etcd and API container logs are included verbatim, because a node that will not start usually explains itself only there. Those are the services’ own words rather than ours, so give them a glance before forwarding the archive if your policy requires it.

One configuration collection, in four layers

Terminal window
./taranac diagnose --protocol ncm --config "<name>"

Configuration collection can now explain itself. This runs one real collection through the same engine a scheduled run uses and writes a single readable report to ./diagnostics. It records nothing in Taranac: no run, no result, no snapshot, no version. Exactly one login is attempted, never a retry loop — though on a source using a just-in-time credential, that login rotates the managed account’s password, exactly as a real collection would.

The report answers in four layers, each standing on its own even when the next cannot run:

  1. What we were about to do, with no network at all — transport, address, port, credential mode, recipe, and the driver we resolved together with why.
  2. Whether the port answers.
  3. What the SSH handshake agreed on — attempted without credentials, so it cannot contribute to a lockout.
  4. The collection itself, with the dialogue that produced it.

The first layer is the point rather than a preamble. The failure that prompted this tool — a driver name the library does not have — happens before a socket is ever opened, so a session recorder would have handed back an empty file and a shrug.

Passwords are removed from the transcript before it is written; the account name is kept, because which account was used is usually the question. By default the transcript stops once the session turns to fetching the configuration. Add --full-transcript and it keeps going — which means the report then contains the device’s configuration. The command says so, and the finished run says so again.

Three faults on Huawei, one of them total

Every 802.1X authentication failed as soon as the client had IPv6.

Huawei numbers its RADIUS attributes two incompatible ways — one for carrier equipment, one for campus switches — and the 802.1X service was reading campus switches with the carrier list. The two disagree about the type of eleven attribute numbers, and one of those is the attribute a switch fills with an IPv6 address. Read as text, sixteen bytes of address are not text, and the authentication was refused before any rule of yours was consulted. Seen on an S5735 running VRP V200R021, where it rejected every EAP-TLS login.

The 802.1X service now reads campus switches with the campus list. Device administration over RADIUS is deliberately left on the carrier list: 802.1X is the path these switches take, and changing both at once would have widened the blast radius of a fix that needed to ship. If you see the same symptom on device administration from a Huawei campus switch, tell us.

If you added a Huawei attribute to the vendor dictionary by hand, check it after upgrading. The two lists also disagree about the name of 28 further attribute numbers, so an entry written against a name that exists only in the carrier list will no longer be sent — silently, because a name Taranac cannot resolve is simply absent from the reply rather than an error. Nothing Taranac ships is affected; this is only about entries you added yourself. A related error in the same definition is corrected too: downloadable ACLs for Huawei were built under an attribute name that exists in neither list, so a Huawei dACL could never have reached a switch in any release.

And a Huawei port name could stop the authentication journal recording anything at all.

Configured with the newer NAS-Port-Id format, a Huawei switch sends a port description longer than the column that stored it. The write was refused, the batch containing it was retried unchanged, it failed again — so every authentication that followed queued behind a record that could never land, until the queue filled and began discarding real entries.

What made this expensive is that authentication itself kept working. The log is written after the fact, so devices authenticated normally while the operator watched a journal that had gone silent — which is the worst possible arrangement of symptoms, because the thing that looks broken is the thing that is fine. The column now holds the full length the protocol allows, and — the more important half — a record that genuinely cannot be written is dropped on its own, loudly and in its own words, instead of taking every record behind it down with it. The same protection went into device administration over RADIUS, which had the identical flaw waiting in it.

Entries lost while the log was blocked cannot be recovered; they never reached the database.

Windows machine certificates were logged as PEAP

Certificate templates on a Windows authority commonly issue machine certificates with an empty subject, putting the identity in an extension instead. Taranac decided the authentication method from the subject’s common name alone — so for those certificates it found nothing and fell back to its last-resort guess, PEAP, for a session that was EAP-TLS from beginning to end.

The consequences went well past a wrong label. A policy rule matching on EAP-TLS could not match these sessions at all, so the profile, VLAN and ACL you intended were never applied. And everything Taranac derives from a certificate — the identity, the issuer, whether it belongs to a machine or a person — was skipped in silence.

A certificate the peer presents is now recognised by any of the fields a certificate always carries, rather than by the one it may leave empty. A session that genuinely is PEAP or TTLS carrying a client certificate is still reported as PEAP or TTLS.

Two things to know. Earlier records are not rewritten — only authentications after the upgrade are classified correctly. And if you worked around this by writing a rule that matches PEAP to catch your Windows machines, that rule will stop matching them. They now present as EAP-TLS, which is what they were all along.

The interface a device authenticated on

Switches report the port in whatever shape their vendor chose. Cisco says GigabitEthernet0/3, MikroTik says ether2, and those pass through unchanged. Huawei and H3C encode it — as a key/value string, or as sixteen digits with the slot, sub-slot, port and VLAN packed inside. Both are decoded now, and the raw value is kept beside the readable one, so nothing is lost and which port was that? stops requiring a lookup table.

The readable name is what the NAS Port column shows in the NAC authentication log and in sessions, with the raw value on hover, and the log sorts on it. It appears as Interface in the detail panel of both, in endpoint discovery, in CSV and XLSX exports, and in both NAC report templates, where it is shown by default. Free-text search matches it.

It is filled in as authentications arrive. Records written before the upgrade keep an empty Interface: the raw value they stored is the only evidence there is, and reconstructing the rest would be inventing it. The digit-packed form is decoded only when every field falls inside the range the vendor documents — otherwise the raw value stands alone rather than becoming a confident wrong answer.

Masking became a setting instead of a law

Taranac has always masked passwords, keys and community strings in collected configurations even when no scrub set was assigned — a safety net running underneath your rules rather than alongside them. That made it impossible to store a configuration exactly as the device returned it, and it produced a result that read backwards: removing a scrub set masked more, not less, because the exceptions that rescue benign lines live in the set.

A scrub set now carries a Mask secrets automatically switch. Leave it on and nothing changes. Turn it off and the set’s own rules become the entire policy — with no rules at all, the configuration is stored exactly as collected. Rules are optional; a set may consist of nothing but this switch.

In that mode configurations keep their secrets in storage, and they appear that way in diffs, notifications and exports — so the form says so where you flip it, the set’s view repeats it, and the scrub-set list flags every set that has it off. Recipes with no scrub set stay fully masked: an absent set cannot express the intent, and a recipe can lose its set without anyone asking it to.

Update every standalone collector in the same maintenance window as the core. A collector on the previous version stops collecting entirely — every tracked configuration it serves, not only the ones this switch touches — rather than storing a snapshot masked differently from what the core expects. It idles rather than guesses, and resumes on its own once updated.

And a narrower way to reach a real password

Where the switch above stores the configuration in the clear for everyone who can read NCM, a recipe can instead keep an unmasked second copy: the normal configuration stays masked exactly as before, and an encrypted copy of the device output as returned — before any trimming or masking — is kept alongside it.

Reading that copy, on screen or as a download, requires the separate Reveal raw config permission, which is not implied by permission to view configurations. Every access is written to the activity log, and it is written before the copy is decrypted — so a read that gets as far as the stored ciphertext and then fails is recorded just as a successful one is.

It is off by default and set per recipe. Standalone collectors do collect it, and hold it in memory only: it is never written to the collector’s local queue, so it cannot sit on disk at a remote site. If the collector restarts, or the core is unreachable long enough for the result to be queued, that one capture arrives without its unmasked copy — the configuration snapshot itself is never lost.

Mail, and a default that loosens security

Read this one even if you never touch mail settings.

SMTP settings gain a Verify the server’s TLS certificate switch and, when it is on, an optional CA certificate field. They appear only for STARTTLS and SSL, since with encryption off there is no certificate to judge. The same trust settings are used by the test and by real delivery, so a test that passes can no longer sit beside mail that quietly fails on trust.

A pasted certificate is added on top of the system trust store rather than replacing it — the difference between fixing the common case and breaking every other one. A server whose certificate comes from a public authority but which forgets to send the intermediate is fixed by pasting just the intermediate, while everything else keeps working with the field empty. A self-signed certificate is equally valid here, and a bundle of several is accepted. Text that will not parse is refused when you save it, on the field, rather than at the next send.

Here is the part that changes your installation. Until now Taranac always verified the mail server’s certificate and gave you no way to say otherwise — which is why an internal server with a self-signed certificate could not be used at all. The new switch is off by default, and on upgrade that includes installations which were verifying successfully all along.

Mail keeps flowing everywhere it flowed before, and starts flowing where an untrusted certificate was blocking it. What changes quietly is that the connection is still encrypted but no longer authenticated — so something sitting in the path could present any certificate it liked and collect the SMTP password.

If your mail server presents a certificate worth checking, and anything signed by a public authority certainly is: turn the switch on after upgrading, and paste the missing intermediate if the server sends an incomplete chain. The default was chosen so that no installation breaks on upgrade. It was not chosen because off is the better setting.

The SMTP test says what actually went wrong

It used to answer Request failed with status code 502. Every failure — a name that does not resolve, a port nothing listens on, a rejected password, a TLS handshake that collapses — arrived as the same line of framework text, naming no cause and no setting. The reason existed, but only in the server log, which is the one place an operator configuring mail through a web interface will not be looking.

The test now answers with the cause, in your own language, and names the setting to go and change. A timeout points at the port and the encryption mode, and spells out that 587 normally means STARTTLS while 465 means implicit TLS. A refused login says the credentials were rejected. Where the mail server explained itself, its own reply is quoted after the sentence — 535 5.7.8 Username and Password not accepted settles a question no amount of guessing will. The password you typed cannot appear there: the quoted text is built from what the server sent back, never from what was sent to it.

And an untrusted certificate is called by its name rather than blamed on the port. It arrives disguised as an ordinary connection failure, so the diagnosis now follows the chain of causes down to the certificate error underneath instead of judging by the outermost one. Telling an operator whose address and port are both correct to go and check the address and port is the kind of wrong answer that costs more time than no answer at all.

Updating stopped hoarding images

./taranac update fetched the new images, started them, and never removed what they replaced. On a demo host thirteen releases had piled up 30 GB of superseded images — enough, on an appliance’s disk, to eventually stop the stack a year and a dozen updates after the change that caused it, with nothing at the point of failure pointing back at the cause.

Cleanup now runs at the end of an update, and the first update onto this version sweeps up what earlier ones left behind. It is deliberately narrow:

  • Only images belonging to this installation are ever considered. Anything else on the host, including other people’s software, is never touched — and if the installation does not record which images are its own, it removes nothing and says so.
  • Two versions are kept: the one just installed and the one it replaced. The rollback this same script offers is worthless if the previous images are gone and the registry is unreachable, which is exactly the situation a rollback happens in.
  • An image another container still uses is reported, not forced, so a standalone collector, captive portal or cluster peer sitting on a different version survives untouched.
  • Every failure here is non-fatal. An unreclaimed gigabyte must never turn a good update into a failed one.

./taranac update --keep-images skips it. One wrinkle worth knowing: the flag is read by the updater already on disk, so on the update that brings you to this version it is not understood yet and will be rejected before the update starts. Leave it off there. The cleanup itself does run on that first update; the opt-out becomes usable from the next one onward.

Smaller things

  • An update could be offered to you while you were already running it. The version pinned in .env was compared exactly as written, so a file with Windows line endings — or a value someone had put in quotes — never matched the published version, and ./taranac version reported an update available for the release already installed. Every .env value is now read the same forgiving way. As above, this takes effect from the next update onward.
  • A TACACS+ template for Extreme SLX-OS. On SLX-OS the privilege level is not the role: set it and nothing happens, the switch reports the user’s role as unavailable, and an administrator who authenticated perfectly well lands in the default role able to do nothing. The role travels in a brcd-role attribute, and the template builds that reply, with admin and user as ready choices and any role you have defined accepted as free text. Bind a profile made from this template only to SLX devices — the attribute is sent as mandatory, which SLX-OS requires, and a switch from another vendor answers an unknown mandatory attribute by failing the whole authorization rather than ignoring it.
  • A form opened over another form now submits only itself. Creating a scrub set from inside a recipe saved and closed the recipe underneath as a side effect; when the new set was invalid, the validation message was raised and then destroyed along with the component showing it, so the operator watched the form vanish with no explanation and no set. Fixed everywhere in the product, not only there.

1.2.6 ran 4561 passing, 0 failing on the dedicated runner — unit through sustained-rate load under HA failover — at 80% backend line coverage, dated 2026-08-14 and commit-pinned. That is 88 more tests than yesterday’s release at the same coverage; app/scripts/ still sits outside the paths the gate walks, so the diagnostic collector and the new NCM session recorder still do not count toward the denominator, and their own tests still pass without being wired in. End-to-end ran in the same six shards CI uses rather than one session, and all six were green on the first attempt.

Three releases in three days is not a cadence and it is not a plan. It is what happens when you build something that tells you the truth and then have to sit with what it says. Existing installations update in place with ./taranac update — read the mail section first; new ones start from the appliance. The diagnostic collector has a page of its own, and where the platform goes next is on the roadmap.

Self-hosted, artifact-only, Elastic License 2.0.