Releases: sbezpalov/easy-waf
Release list
v1.4.2
Five defects the documentation pass turned up, and the documentation pass itself.
The one that matters: a stock appliance was not validating or reloading
HAProxy. configs/defaults/easy-waf.env.example shipped
EASY_WAF_SKIP_RELOAD=0 and EASY_WAF_SKIP_VALIDATE=0 uncommented, and the
code read any non-empty value as "set" — so 0 switched both off. Apply wrote a
configuration that was never checked with haproxy -c and never loaded by the
running HAProxy, and reported success. The lines have been there since the first
commit. Upgrading fixes it without editing anything: 0 now means off.
Upgrade note. Nothing to do by hand. After upgrading, an apply will do what it
always said it did — which on an affected appliance means HAProxy picks up
everything that accumulated in the database since the last manual reload. Look at
the generated config first if that gap is large:
easy-waf-admin apply-edge after haproxy -c -f /var/lib/easy-waf/haproxy/haproxy.cfg.
Whether this bit you at all is recorded: an apply that skipped the reload wrote
"skipped_reload": true into its audit detail.
Fixed
EASY_WAF_SKIP_VALIDATE,EASY_WAF_SKIP_RELOAD,EASY_WAF_ACME_SKIP_APPLYandEASY_WAF_NO_AUTO_APPLYare parsed as booleans. They were read withos.Getenv(...) != "", which makes0mean on — the opposite of what the shipped env file, and every reader of it, intended. They now go throughinternal/envflag:1/true/yes/onenable,0/false/off/empty/unset disable, and a value that is neither is treated as off and logged once, because a typo must not be the thing that disables a safety check.easy-waf.env.exampleno longer sets any of them, and says why.- A re-issue with no
modekeeps the certificate's mode instead of forcinghttp-01. The UI's Issue and Renew buttons bothPOSTan empty body, so renewing a DNS-01 certificate through the UI rewrote the row tohttp-01and the nexteasy-waf-acmedpass attempted a challenge the domain may not answer. A certificate not yet on an ACME mode still starts onhttp-01; an explicit mode that is neitherhttp-01nordns-01is now rejected with 400 rather than stored. - The rendered
bk_acmebackend follows a setting instead of a hardcoded address.EASY_WAF_ACME_INTERNAL_HTTPmoved the HTTP-01 listener while the generated config keptserver acme 127.0.0.1:8089, so using the variable as documented silently broke HTTP-01. The address is now the global settingacme_internal_http(default127.0.0.1:8089,ip:port, validated on write and at render like every other interpolated value), which both the listener and the renderer read — the rendered config is a function of the database, as it has to be when three binaries render it. The environment variable still switches the helper off, andeasy-waf-apinow logs a warning if it is used to move the listener away from what the backend dials. easy-waf-admin doctorchecks the stats socket that exists. It probed a hardcoded/run/haproxy/admin.sock, which has not been the default since the socket was renamed, and the whole check sat behind "if the file exists" — so on a stock appliance it silently reported nothing. It now reads the path out of the generatedhaproxy.cfg, falls back to the current default, and reports a missing socket as a warning instead of saying nothing.- Diagnostics bundles collect
easy-waf-hostd. Both the API bundle andscripts/diagnostics.shgathered status and journals for the API, acmed and HAProxy but not the root broker — so a bundle taken after a failed host update, firewall apply or user change was missing the one unit that could explain it.
Changed
- The build-time specification is gone, and the status matrix stands on its own. The root
prompts.mdwas the prompt the project was built from: fully executed (Done 20, Partial 1, Missing 0) and, by 1.4.1, contradicted by the result — it prescribed a/web,/templates,/testslayout that does not exist, and an acceptance criterion of "SELinux remains enabled" on an appliance that targets Ubuntu with AppArmor and nftables. A reader arriving at the repository met a stale map competing with the real documentation. What was worth keeping — the requirements, the acceptance criteria AC-01 … AC-10, and where each one is implemented — isdocs/IMPLEMENTATION_STATUS.md, formerlydocs/PROMPTS_ALIGNMENT.md, now written to be read on its own rather than as a diff against a document that no longer exists.AGENTS.md,README.md,README.ru.md,docs/ARCHITECTURE.md,docs/SECURITY.md,docs/SECURITY.ru.mdanddocs/adr/README.mdpoint at it. - The fallback reporting channel in
SECURITY.mdandCODE_OF_CONDUCT.mdis one that exists. Both pointed at "the email address in the repository owner's GitHub profile", which that profile does not publish — a dead end for anyone who cannot use private advisories. They now point at the profile's contact links. GitHub private vulnerability reporting remains the primary channel. - Attribution now travels with the code.
NOTICEnames the original author rather than only "Easy Home WAF contributors", and every Go source file carries a two-lineCopyright/SPDX-License-Identifier: Apache-2.0header. Apache-2.0 §4(c) obliges a derivative to keepNOTICE, so that file is where authorship survives a fork — and the per-file header is what survives when somebody copies a single file rather than the repository. Both READMEs now state the obligations in a sentence, including §6: the licence grants no rights to the project's name. - CI and release workflows run on current actions —
actions/checkoutv7,actions/setup-gov7,softprops/action-gh-releasev3. - Documentation caught up with the code, and four instructions that would have failed an operator are corrected. A pass over every document against
HEADfound the reference guides had drifted furthest —docs/ACME.md,docs/DNS01.md,docs/HOST-API.md,docs/DIAGNOSTICS.md,docs/DNS.md,docs/FAIL2BAN.mdanddocs/VM-REQUIREMENTS.mdhad not been revised since May while the appliance grew a root broker, GeoIP, and packaging. The four that were actively wrong: the DNS-01 credentials file is readable byeasy-waf, not root-only asdocs/ACME.mdsaid (easy-waf-acmedruns as that user and opens the file itself, so a file only root can read fails every issuance —docs/DNS01.mdhad this right all along);POST /certificates/{id}/request-issuewith an empty body rewrote the stored row tohttp-01(fixed above);EASY_WAF_ACME_INTERNAL_HTTPcould not move the HTTP-01 listener, because the rendered HAProxy backend hardcoded127.0.0.1:8089(fixed above); and the "separatecrt+key" PEM layout does not exist — a certificate resolves to exactly one file on thecrt-listline. Alongside those: secrets live under the state directory, not/etc/easy-waf/secrets;easy-waf-hostdis now named everywhere the other two daemons are (release tarball, OVF checklist,systemctl enable, VM sizing);/var/log/easy-waf/never existed; andupgrade.shre-runs the whole installer rather than swapping a binary. docs/IMPLEMENTATION_STATUS.mdnow adds up. Its summary counts were carried over from the retired spec unchanged and did not match the tables under them — Done 20 against 36 actual, and the acceptance criteria were not summarised at all. Three rows had unclosed**markers left by the retirement edit, which GitHub rendered literally. The UI row still said 8 tabs against the 11 ininternal/webui/dist/index.html. The capability tables keep theirsee 7.*pointers into the feature sections and now also name the package or script that implements each row, so a reader can go straight to the code.- Contributor guidance states the two rules the repository now enforces socially rather than in CI — every new
.gofile carries theCopyright/SPDX-License-Identifierheader, and dependency updates land as reviewed commits because there is no Dependabot. Both inCONTRIBUTING.md; the header rule is also inAGENTS.md, which is what the AI tooling reads.