This technical article is written by AI to expedite the sharing of the security patch asap.

On October 20, 2026, researchers disclosed that the private keys for eight eMudhra intermediate Certificate Authorities had been compromised. The keys were generated incorrectly and can be recovered from public certificates.

This is serious, but it does not mean that your Ubuntu server or SSH keys have been compromised. The immediate problem is with HTTPS trust. An unpatched application may accept a fraudulent certificate and connect to an attacker impersonating a legitimate service.

What can an attacker do?

An attacker with one of the compromised CA keys can create a certificate for a domain they do not own. They would still need to redirect your connection through DNS manipulation, a compromised proxy, network routing, or another interception method.

If both conditions are met, an unpatched TLS client could accept the fake certificate. That may expose API tokens, authorization headers, responses, and other data sent over the connection.

This mainly affects software that initiates HTTPS or other TLS connections, including curl, wget, Git over HTTPS, package managers, application runtimes, and background jobs. SSH and Git over SSH use a different trust mechanism and are not directly affected.

Patch Ubuntu

Canonical has released updated ca-certificates packages. On Ubuntu 24.04 LTS, the fixed version is 20260816ubuntu0.24.04.1.

To update only the affected package:

sudo apt update
sudo apt install --only-upgrade ca-certificates

Check the installed and available versions:

dpkg-query -W -f='${Version}\n' ca-certificates
apt-cache policy ca-certificates

Ubuntu 24.04 should report 20260816ubuntu0.24.04.1 or a newer version. Canonical has also published fixes for supported Ubuntu 22.04, 26.04, and 26.10 releases. Older supported releases receive the fix through Ubuntu Pro.

Do not assume every VPS provider has the same package candidate

During my rollout on October 21, my DigitalOcean servers received the fixed package, while my Hetzner servers did not. This is an observation from my own servers, not a claim about every server from either provider.

Hetzner documents that its standard cloud and dedicated server images use its own Ubuntu package mirror. A difference between providers may therefore be caused by mirror synchronization, but it can also be caused by the Ubuntu release or repository configuration on an individual server.

Check the release, configured repositories, installed package, and candidate package on every VPS:

. /etc/os-release
printf 'Ubuntu %s (%s)\n' "$VERSION_ID" "$VERSION_CODENAME"
grep -RhsE '^(deb |URIs:|Suites:)' /etc/apt/sources.list /etc/apt/sources.list.d/
sudo apt update
apt-cache policy ca-certificates

apt-cache policy reports both Installed and Candidate. If the candidate is older than Canonical’s fixed version for your Ubuntu release, that repository is not offering the fix yet. A successful apt update does not prove that the patched package was available or installed. Do not install a package built for a different Ubuntu release.

Verify that the compromised chains are rejected

The researchers provide two live test endpoints. Run these commands on the server or inside the environment you want to check:

curl https://dv-g3b-emudhra.we-have-a-problem.com/
curl https://dv-g3b-aaa-emudhra.we-have-a-problem.com/

A certificate verification error is the secure result. If either command returns a successful HTTPS response without -k or --insecure, that client still trusts a compromised chain and needs attention.

These tests check the trust store used by that particular curl process. They do not prove that every runtime or application on the machine is safe.

Apply the fix in each environment

Updating the Ubuntu host does not update CA bundles inside WSL distributions, container images, or Python virtual environments. Patch and test each one separately.

WSL

List your installed distributions from PowerShell:

wsl --list --verbose

Open each Ubuntu distribution:

wsl --distribution <distribution-name>

Then run the update and both tests inside that distribution:

sudo apt update
sudo apt install --only-upgrade ca-certificates
dpkg-query -W -f='${Version}\n' ca-certificates

curl https://dv-g3b-emudhra.we-have-a-problem.com/
curl https://dv-g3b-aaa-emudhra.we-have-a-problem.com/

Both curl commands should fail with a certificate verification error.

Docker containers

First, list the images used by running containers:


docker ps --format 'table {{.Names}}\t{{.Image}}'

For Debian or Ubuntu based images, make sure the Dockerfile installs the current CA package:

RUN apt-get update \
    && apt-get install -y --no-install-recommends ca-certificates \
    && rm -rf /var/lib/apt/lists/*

For Alpine based images, use:

RUN apk add --no-cache ca-certificates

Pull the latest base image and rebuild the affected service without using an old build cache:

docker compose build --pull --no-cache <service-name>

Test the rebuilt image before deployment if it contains curl:

docker compose run --rm --no-deps --entrypoint curl <service-name> https://dv-g3b-emudhra.we-have-a-problem.com/
docker compose run --rm --no-deps --entrypoint curl <service-name> https://dv-g3b-aaa-emudhra.we-have-a-problem.com/

Both commands should fail with a certificate verification error. Deploy the rebuilt image through your normal release process after that result.

Python Requests environments

Requests uses certifi by default. Activate the same virtual environment used by the application, then print the installed versions and CA bundle path:

python -m pip show requests certifi
python -m certifi

If the version is older than 2026.10.19, update it through the project’s dependency file and reinstall the environment. For a direct pip-managed environment, run:

python -m pip install --upgrade 'certifi>=2026.10.19'

Test certificate validation through Requests itself:

import requests

urls = (
    "https://dv-g3b-emudhra.we-have-a-problem.com/",
    "https://dv-g3b-aaa-emudhra.we-have-a-problem.com/",
)

for url in urls:
    try:
        response = requests.get(url, timeout=10)
    except requests.exceptions.SSLError:
        print("PASS: rejected", url)
    else:
        response.close()
        raise SystemExit(f"FAIL: accepted compromised chain at {url}")

Save this as check_emudhra.py and run it with python check_emudhra.py. Both URLs should print PASS. A timeout, DNS error, or other connection failure is not a passing result. Run the test in every production virtual environment that maintains its own dependencies.

What you do not need to do

This disclosure alone is not a reason to rotate SSH keys, reinstall Ubuntu, recreate WSL distributions, or replace unrelated Let’s Encrypt certificates. Those actions do not address the failed certificate trust path.

Investigate further if a client still accepts either test certificate after patching, or if your service uses an affected eMudhra certificate chain. For most Ubuntu administrators, the right response is to update the relevant trust stores, rebuild stale containers, and verify the software that makes sensitive outbound TLS connections.

Sources