๐ Recent release history (last 2 versions)
[2.246] - 2026-10-27
Added
- ACME proxy: optional DNS UPDATE (RFC 2136) listener, off by default, so standard rfc2136 solvers can answer DNS-01 through the proxy with per-account TSIG keys (#416).
Fixed
- PostgreSQL: the web worker reused the database connections that the main process opened at startup and kept using for scheduled tasks, so the replies of both could interleave (intermittent
PGRES_TUPLES_OKerrors, rows of another query, an unhealthy container). Each worker now opens its own. - The HTTP protocol server (CDP, OCSP, AIA, HTTP-01) stopped after
systemctl reload ucmuntil the next restart, because the new worker could not take the port from the old one; it now waits for the port to be released. - ACME proxy: a challenge response now carries
Link: rel="up"even when the upstream CA omits it (Pebble), which certbot and lego require (#420, reported by @WMP). - ACME: deactivating an authorization (RFC 8555 ยง7.5.2), as lego does after a failed validation, got
malformedfrom the native server and the proxy. Both now accept it; the proxy deactivates the upstream authorization only when no other pending order shares it (#422, reported by @WMP). - ACME:
newAccountwith an already registered key gotexternalAccountRequired, or a refusal of its used EAB, when EAB is required. The native server and the proxy now return the existing account, as RFC 8555 ยง7.3.1 requires (reported by @WMP). - UI: the
danger-softandwarning-softbuttons, the red icon tiles, the outline button hover and a few tinted panels (CA details, login, reports) referred to colour tokens that were never defined and rendered without their colour. A test now fails the suite when the source uses an undeclared token.
Documentation
- New guide
docs/integrations/acme-proxy-clients.md: how to use the ACME proxy from hosts without DNS API access, with a no-op DNS-01 step for certbot, acme.sh, lego, cert-manager (stub acme-dns example inexamples/kubernetes/cert-manager/), win-acme and Posh-ACME, and the DNS resolver limits of each client (#416).
[2.245] - 2026-10-23
Security
- The forced password change now holds on the server: until the first-boot
admin, or any account asked for a new password, sets one, its session gets403for everything but the change, logout and a 2FA enrolment that is itself required, API and WebSocket included. Before, only the web UI asked, so the documented default password gave full API access to a fresh install (reported privately by @EQSTLab). - Certificate Transparency submission now goes through the pinned SSRF guard: a log URL could be redirected, or its name rebound, to loopback or a cloud metadata address after it was checked (reported privately by @fredlubrano). A log URL aimed at loopback or a cloud metadata address is now also refused when saved.
- ACME HTTP-01 and TLS-ALPN-01 validation now pins its connection under the default policy too, where private addresses are allowed: a name could answer one address to the metadata check and the cloud metadata service to the fetch (reported privately by @heidrickla).
- The PowerDNS and Plesk DNS providers now reach their server through the pinned SSRF guard: their API key, sent in a header of its own, followed a redirect to another host. A server on the same host stays reachable.
- SSH: a CA with no allowed principals signed for any name,
rootincluded. It now signs nothing unless Allow any principal is ticked (reported privately by @heidrickla). - Pillow 13.0.0 is now the minimum: 12.x carries 39 published advisories, mostly in image decoders.
- GitHub Actions are pinned to commit SHAs, kept up to date by Dependabot, and a test refuses an unpinned one.
Changed
- The forced password prompt no longer offers Skip for now or a close button: it offers a logout, and the pages load only once the password is changed, so they no longer fill the screen with refused requests behind it.
- A first-boot admin password set through
INITIAL_ADMIN_PASSWORD(DockerUCM_INITIAL_ADMIN_PASSWORD, HelminitialAdminPassword) no longer has to be changed at first login: only the public defaultchangeme123does, so automated deployments keep API access. - The packages and the Docker image no longer install pytest, black and flake8: development tools moved to
backend/requirements-dev.txt.
Fixed
- ACME proxy: with External Account Binding on, an
onlyReturnExistinglookup was refused withexternalAccountRequired, so cert-manager got no account URL and its orders failed; the lookup is now answered before the EAB check and never creates an account (#409, by @WMP). - ACME proxy: the account URL it returns now answers reads, contact updates and deactivation, along with its orders list, and
new-accountrefuses an unknown or disabled endpoint path instead of handing out an account URL under it (#410, #411, reported by @WMP). - ACME server and proxy:
new-accountrefuses a payload that is not an object, a non-booleantermsOfServiceAgreedoronlyReturnExisting, and a malformed contact withmalformedorinvalidContactinstead of a 500 or a stored value; a deactivated or revoked account getsunauthorizedinstead of its URL (#412, #413, reported by @WMP). - ACME server and proxy: every request signed by a deactivated or revoked account now gets
unauthorized(401) instead ofmalformed, and the proxy removes the new account when another registration consumed its EAB credential first, as the server already did. - ACME proxy: a stale nonce or an unusable account key now gets
badNonceorbadPublicKeyinstead ofmalformed, so clients retry a stale nonce; on both servers a kid that names no account getsaccountDoesNotExist.
Upgrade notes
- SSH: existing CAs without allowed principals get Allow any principal ticked, so they keep signing; untick it once their principals are listed. A CA created through the API without a list now signs nothing unless
allow_any_principalistrue.
Full history: CHANGELOG.md
Installation
Docker (Recommended)
# From Docker Hub
docker pull neyslim/ultimate-ca-manager:2.247-rc3
# Or from GitHub Container Registry
docker pull ghcr.io/neyslim/ultimate-ca-manager:2.247-rc3
# Run
docker run -d -p 8443:8443 \
-e SECRET_KEY=$(openssl rand -hex 32) \
--name ucm neyslim/ultimate-ca-manager:2.247-rc3Debian/Ubuntu
wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.247-rc3/ucm_2.247.rc3_all.deb
sudo dpkg -i ucm_2.247.rc3_all.deb
sudo apt-get install -fFedora
wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.247-rc3/ucm-2.247.rc3-1.fc43.noarch.rpm
sudo dnf install ./ucm-2.247.rc3-1.fc43.noarch.rpmRHEL, AlmaLinux, Rocky Linux 9
wget https://github.com/NeySlim/ultimate-ca-manager/releases/download/v2.247-rc3/ucm-el9-2.247.rc3-1.el9.noarch.rpm
sudo dnf install ./ucm-el9-2.247.rc3-1.el9.noarch.rpmFIPS mode (preview)
FIPS mode is a preview: feedback is welcome on #399. Full guide: FIPS Mode.
Docker, any Linux host (amd64, arm64):
docker run -d -p 8443:8443 -e UCM_FIPS=1 \
-v ucm-data:/opt/ucm/data -v ucm-config:/etc/ucm \
--name ucm neyslim/ultimate-ca-manager:2.247-rc3-fipsUbuntu 24.04 with Ubuntu Pro (sudo pro enable fips-updates, then reboot):
sudo apt-get install -y gcc pkg-config python3-dev python3-venv libpq-dev libxml2-dev libxslt1-dev \
zlib1g-dev libssl-dev libxmlsec1-dev libxmlsec1t64-openssl rustc-1.91 cargo-1.91
sudo install -d -m 750 /etc/ucm && echo 'UCM_FIPS_BUILD=1' | sudo tee /etc/ucm/ucm.env
sudo apt install ./ucm_2.247.rc3_all.debRHEL, AlmaLinux, Rocky Linux 9 (sudo fips-mode-setup --enable, then reboot; on RHEL, enable CodeReady Builder instead of CRB):
sudo dnf config-manager --set-enabled crb
sudo dnf install -y python3.12-devel gcc pkgconf-pkg-config libpq-devel libxml2-devel libxslt-devel \
openssl-devel xmlsec1-devel xmlsec1-openssl libtool-ltdl-devel rust cargo
sudo install -d -m 750 /etc/ucm && echo 'UCM_FIPS_BUILD=1' | sudo tee /etc/ucm/ucm.env
sudo dnf install ./ucm-el9-2.247.rc3-1.el9.noarch.rpmThe package builds its crypto libraries against the system OpenSSL (about five minutes), sets UCM_FIPS=1 on a host in FIPS mode and prints a readiness report. Fedora, Debian and other distributions are not supported in FIPS mode: use the Docker image.
Silent/Automated Install
# Skip firewall prompts for CI/automation
sudo UCM_PORT=8443 UCM_FIREWALL=no dpkg -i ucm_2.247.rc3_all.debDefault Credentials
- Username:
admin - Password:
changeme123
Change the password immediately after first login!
Documentation
- Installation Guide
- API Documentation