📜 Recent release history (last 2 versions)
[2.240] - 2026-10-17
Added
- Policies: allowed signature hashes join allowed key types, and both now bind every issuance (CSR signing, ACME, SCEP, EST, WSTEP, CA creation, renewals, mTLS, TSA and OCSP responder certificates). A hash nobody chose yields to the weakest allowed one, and the issue and CA forms only offer what the policies allow (#397, requested by @Stryker-88).
Changed
- Upgrade note: an active policy with allowed key types or hashes now also refuses ACME, SCEP, EST and WSTEP requests outside them, and CAs created under them; review active policies before upgrading (#397).
- Passwords, 2FA backup codes and the EST, WSTEP and XCEP secrets are hashed with PBKDF2-HMAC-SHA256 (600,000 iterations) instead of scrypt, which a FIPS-mode host refuses and which stopped UCM from starting there. Outside FIPS mode, existing scrypt hashes keep working and are replaced at the next login; on a FIPS host they must be reset (#399).
- Docker image on Debian 13 (trixie) instead of 12: system OpenSSL 3.5 and PostgreSQL client 17. Existing volumes upgrade in place. cryptography is pinned to 50.0.2.
Fixed
- TSA: generating a signing certificate with an EC key but no curve reported an invalid curve; it now says a curve is required.
- CAs: creating a CA with keyAlgo
EC, a lowercase name or an unsupported algorithm silently produced an RSA-2048 key. Valid spellings are honoured, anything else is refused, and the CA detail view reports the real key algorithm and size. - Renewal: a certificate whose key family cannot be regenerated (DSA) was renewed with an RSA-2048 key, and a Microsoft CA rekey of an EC certificate produced an RSA-2048 request. The first is now refused and the second keeps its curve.
- ACME client: new orders ignored the configured key type and always used RSA-2048. They now take it, an unknown type fails at finalize instead of falling back to RSA-2048, and Ed25519 or P-521 CSRs are signed with the right hash.
- Key labels: Ed25519 and Ed448 CAs showed "Unknown", and the compliance grade presented secp256k1 or brainpool keys as NIST P-256 or P-384.
- HSM: syncing a PKCS#11 or Google Cloud KMS provider deleted every key row and unbound the CAs using them, because the key listing could not read any key and came back empty. The listing reads keys and their real curve again, and a sync never removes a key a CA uses nor anything when the listing reports errors.
- Templates: a key type saved in a legacy spelling (
ec:p384) was advertised to Windows clients as RSA 2048 over XCEP, and issuing from it failed with "Unsupported key type". Key types are now stored under their canonical label, existing templates at upgrade. - Certificates: only imports and renewals recorded the key algorithm (imports as "EdDSA" for Ed25519), so sorting by key algorithm or compliance grade lumped most certificates together. Every certificate now records it, existing ones at upgrade.
- HSM: a CA on a PKCS#11 RSA key failed with "Could not deserialize key data", because its public key was stored in PKCS#1 form under a SubjectPublicKeyInfo label. Keys already stored are repaired at their next use.
- Policies: an Ed25519 or Ed448 request was signed whatever the allowed key types said, and the policy form ticked key types on its own, so a new or edited policy restricted them unasked (#397).
- ACME DNS-01: UCM submitted the challenge as soon as one authoritative nameserver served the TXT record, so Let's Encrypt often got NXDOMAIN from another one. Every authoritative nameserver must now serve it, CNAME delegations included, followed by a configurable settle delay (10 s by default) (#395, reported by @ziller-hqs).
[2.239] - 2026-10-14
Added
- Let's Encrypt HTTP-01: UCM now serves the challenge file itself at
/.well-known/acme-challenge/(HTTP protocol port and HTTPS), so forwarding that path from port 80 of the domain is enough, and HTTP-01 orders renew automatically (#392). - ACME DNS-01 resolvers: the TXT checks can be limited to the system resolver or to listed resolvers, for networks where public resolvers are unreachable; listed resolvers each keep their own port (#394, reported by @lengqing5977).
Fixed
- Let's Encrypt HTTP-01: the order showed nothing to publish, so the challenge could not be answered. A pending order now shows the challenge URL and file content, with the file to download (#392, reported by @ziller-hqs).
- Let's Encrypt HTTP-01: Verify no longer submits a challenge whose file UCM cannot fetch, which made the CA invalidate the order; Force verification still submits (#392).
- ACME client: renewing an HTTP-01 or TLS-ALPN-01 order failed with "DNS provider not found"; only DNS-01 orders need a provider now, and one using the manual provider stops with an explicit message instead of invalidating a new order on every cycle (#392).
- ACME DNS-01: each propagation poll queried the public resolvers twice, adding up to 30 seconds per poll on a network that blocks them (#394).
- Installation guide: running from source or building the Docker image now includes the frontend build step (#393, reported by @ziller-hqs).
Full history: CHANGELOG.md
Installation
Docker (Recommended)
# From Docker Hub
docker pull neyslim/ultimate-ca-manager:2.241-rc1
# Or from GitHub Container Registry
docker pull ghcr.io/neyslim/ultimate-ca-manager:2.241-rc1
# Run
docker run -d -p 8443:8443 \
-e SECRET_KEY=$(openssl rand -hex 32) \
--name ucm neyslim/ultimate-ca-manager:2.241-rc1Debian/Ubuntu
wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.241-rc1/ucm_2.241.rc1_all.deb
sudo dpkg -i ucm_2.241.rc1_all.deb
sudo apt-get install -fFedora/RHEL
wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.241-rc1/ucm-2.241.rc1-1.fc43.noarch.rpm
sudo dnf install ./ucm-2.241.rc1-1.fc43.noarch.rpmSilent/Automated Install
# Skip firewall prompts for CI/automation
sudo UCM_PORT=8443 UCM_FIREWALL=no dpkg -i ucm_2.241.rc1_all.debDefault Credentials
- Username:
admin - Password:
changeme123
Change the password immediately after first login!
Documentation
- Installation Guide
- API Documentation