Skip to content

v2.224

Latest

Choose a tag to compare

@github-actions github-actions released this 08 Sep 05:53

What's Changed

Added

  • UCM_TRUSTED_PROXIES accepts CIDR networks, not only exact IP addresses. Behind an ingress controller or another proxy whose source address is not fixed, every allowed peer had to be listed individually; an entry such as 10.42.0.0/16 now trusts any peer inside that range, and a peer that arrives as an IPv4-mapped IPv6 address (::ffff:10.42.0.5, as a dual-stack listener reports IPv4 clients) is matched against IPv4 entries and networks as well. An entry that is neither a valid address nor a valid network is ignored with a warning in the log instead of being kept as a literal string that can never match, so a typo cannot silently narrow the trusted set. The Helm chart gained proxy.behindProxy (sets UCM_BEHIND_PROXY) and proxy.trustedProxies (sets UCM_TRUSTED_PROXIES), neither of which it templated before, so a chart deployment behind an Ingress can honour X-Forwarded-* and proxy-injected client-certificate headers without a hand-written extraEnv entry (discussion #337, requested by @szechyjs, contributed by @Hemsby)
  • The certificate template editor can build a Windows smartcard logon template. The Extended Key Usage list gained msSmartcardLogin (Microsoft Smartcard Logon, 1.3.6.1.4.1.311.20.2.2) and the SAN types gained upn, both of which the template API and the issuance path already accepted but which the editor's fixed checkbox lists did not offer, so a reusable Smartcard Logon profile could not be clicked together even though the Issue Certificate form could produce one. A built-in Smartcard Logon system template ships alongside the others (clientAuth + msSmartcardLogin, UPN SAN). The SAN type checkboxes now use the same localized labels as the issue form rather than a bare upper-cased token (discussion #336, requested by @szechyjs, contributed by @Hemsby)

Fixed

  • With UCM_BEHIND_PROXY=1, X-Forwarded-* and X-Real-IP headers are now honoured only when the request's immediate peer is in UCM_TRUSTED_PROXIES; from any other peer they are dropped before the proxy handling runs, with a warning in the log naming the peer. Previously enabling proxy support trusted those headers from every peer, so a client able to reach the backend directly, such as another pod in the same cluster, could choose its apparent IP, rotate past the per-IP rate limits and pollute the audit trail. Upgrade note: a reverse proxy running on another host must be listed in UCM_TRUSTED_PROXIES (IP or CIDR network), as the documentation already required; unset, the variable trusts loopback only, and a proxy that is not listed now sees its own address logged and rate-limited instead of its clients' (discussion #337, follow-up to #339)
  • Helm chart: appVersion now tracks the release the chart ships with. It had stayed at 2.170 while the image tag defaults to appVersion, so a chart install without an explicit image.tag deployed that old version
  • The public port of the admin and protocol URLs can now differ from the port UCM listens on. Settings > General accepted http://pki.example.com:80 as Protocol Base URL but dropped the :80 as a default port when saving, then applied the HTTP protocol port (8080 by default, and the field refuses a port below 1024) to every CDP, OCSP and AIA URL it advertised, so a reverse proxy publishing those endpoints on port 80 could not be described; the same happened to https://admin.example.com:443 and the HTTPS listen port for the admin canonical URL. An explicitly typed port is now kept as typed and honoured in the advertised URLs, while a URL without a port keeps taking the listen port as before (discussion #337, reported by @szechyjs)
  • ACME: a reused authorization now records the challenge that was performed, at the time it was performed. When an order reused a valid authorization of the same account, the built-in server created the new authorization with all three challenge types (dns-01, http-01, tls-alpn-01) marked valid and dated to the reuse, so a renewal appeared validated by methods that were never attempted, on an instance with no DNS provider. The reused authorization now carries only the challenge(s) the client completed, with their original validated timestamp; its expiry stays that of the original validation, since reuse does not extend a proof of control. The Orders tab of an ACME account derived an order's method from the first challenge row, which is always dns-01, and so reported DNS-01 for the renewal and for a rejected order alike; it now names the validated challenge(s), the challenge the client attempted when validation failed, and N/A for an order whose challenges were never answered; on a multi-identifier order the choice is made per identifier and merged, so a name proved by dns-01 next to one that failed http-01 lists both. Authorizations reused before this fix keep the three validated rows they were given and are listed with all three methods (#338, reported by @JoseGoncalves)

📜 Recent release history (last 2 versions)

[2.223] - 2026-09-06

Fixed

  • Automatic updates on the rc channel refused every release candidate with "Release checksum does not cover this package". The checksum file published with a release candidate names the package as built (ucm_2.223~rc1_all.deb) while GitHub publishes the asset with a dot (ucm_2.223.rc1_all.deb), and the updater compared the two names literally. The updater now matches the names with that transform applied, and the release build writes the published asset name into the checksum file so earlier versions can update to a release candidate too
  • Startup no longer depends on the HTTPS certificate binding being readable. The one-time backfill that binds a certificate applied before bindings existed runs under its own application context and treats a database error while reading the binding as "no binding" with a warning, instead of aborting application start; a failed read on the first boot after an update, with the database not yet available, could otherwise keep the service down
  • Certificate policy Rules are now enforced at issuance. The policy editor's Allowed Key Types and Max SANs were stored but never checked, and Max Validity only applied to requests routed through approval, so a policy shown as active could be ignored entirely. On the issue form and when an approved request is issued, a request whose key type is not in the policy's allowed list or which carries more DNS names than its maximum is refused with the rule named, and the validity is capped by the policy. Rules apply to every role, including administrators, who keep bypassing only the approval workflow; the DNS pattern keeps its role of scoping which requests a policy covers. Requests over ACME, SCEP, EST and WSTEP are not covered by policies, as before (#335, reported by @Hemsby)
  • Revoking a certificate from the web UI now asks for the revocation reason. The confirm dialog had no reason field, so every manual revocation was recorded and published on the CRL as unspecified, with no way to correct it afterwards since revocation is one-way; only automated paths such as ACME renewal recorded a reason. The revoke dialog (certificates page, detail windows, user portal and bulk operations) now offers the RFC 5280 reason codes with a short explanation of each, defaulting to unspecified, and the certificate details show the chosen reason by name. The API rejects an unknown reason with 400 instead of storing it, accepts the snake_case spellings older clients used, and the CRL builder now maps the RFC spelling cACompromise that ACME revocations store (#334, reported by @JoseGoncalves)

[2.222] - 2026-09-06

Added

  • PKCS#12 exports gained a compatibility mode. UCM's PKCS#12 archives use the OpenSSL 3 profile (PBES2 with AES-256-CBC, PBKDF2-SHA256 and an HMAC-SHA256 integrity check), which Android 15 and earlier, macOS 14 and earlier, Windows Server 2016 and earlier and Java before 8u301 / 11.0.1 cannot read and report as a wrong password. A Compatibility mode checkbox on the export dialogs (certificates, CAs, the user portal, mTLS downloads and key recovery) switches that archive to the 3DES/SHA-1 profile these importers accept, the same LegacyDES profile cert-manager and go-pkcs12 offer. The API takes it as legacy: true alongside password. AES-256 stays the default and the checkbox is a per-export choice, since the legacy profile protects the archive less well (#331, requested by @MakosHD)

Fixed

  • The certificate template API no longer accepts ED25519 as a key type. It was allowed at save time but the issuance path cannot generate an Edwards key, so every certificate request from such a template failed with a 400. POST and PUT /api/v2/templates now reject it up front, and template import skips an ED25519 entry with a reason string instead of storing a template that can never issue. An existing ED25519 template must be switched to an RSA or EC key type before it can be edited again (#321 follow-up, contributed by @Hemsby)

Full history: CHANGELOG.md


Installation

Docker (Recommended)

# From Docker Hub
docker pull neyslim/ultimate-ca-manager:2.224

# Or from GitHub Container Registry
docker pull ghcr.io/neyslim/ultimate-ca-manager:2.224

# Run
docker run -d -p 8443:8443 \
  -e SECRET_KEY=$(openssl rand -hex 32) \
  --name ucm neyslim/ultimate-ca-manager:2.224

Debian/Ubuntu

wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.224/ucm_2.224_all.deb
sudo dpkg -i ucm_2.224_all.deb
sudo apt-get install -f

Fedora/RHEL

wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.224/ucm-2.224-1.fc43.noarch.rpm
sudo dnf install ./ucm-2.224-1.fc43.noarch.rpm

Silent/Automated Install

# Skip firewall prompts for CI/automation
sudo UCM_PORT=8443 UCM_FIREWALL=no dpkg -i ucm_2.224_all.deb

Default Credentials

  • Username: admin
  • Password: changeme123

Change the password immediately after first login!

Documentation