Skip to content

Instantly share code, notes, and snippets.

@doevelopper
Created August 28, 2026 08:56
Show Gist options
  • Select an option

  • Save doevelopper/4ce708ee69c2a26c15e1c191bc4e4b6c to your computer and use it in GitHub Desktop.

Select an option

Save doevelopper/4ce708ee69c2a26c15e1c191bc4e4b6c to your computer and use it in GitHub Desktop.
Private lab OTA repository and internal certificate service

A Raspberry Pi 3 can work well as a private lab OTA repository and internal certificate service, but the first architectural decision is crucial: do not treat the online Raspberry Pi as your root CA or primary firmware-signing authority. Separate certificate issuance, firmware signing, artifact storage, and deployment management from the beginning.

  1. First decide what you mean by “CA server”

You potentially need three different trust functions:

TLS certificates

HTTPS certificate for updates.example.lan Optional client certificates for individual devices Used to encrypt and authenticate network connections

Firmware-signing keys

Used to sign RAUC bundles, SWUpdate packages, or Mender Artifacts These establish whether firmware is authorized to run They are more security-critical than the HTTPS certificate

Device identity certificates

One certificate per device Used for mutual TLS, inventory identity, or API authentication

These should not automatically share the same CA, keys, or certificate hierarchy. RAUC specifically recommends avoiding reuse of its update-signing PKI for unrelated purposes because PKI configuration is easy to get subtly wrong.

  1. Recommended architecture

A sensible small-fleet design would be:

                OFFLINE OR HIGHLY PROTECTED
         +-----------------------------------+
         | Offline root CA                   |
         | Firmware release-signing key      |
         | Backup and recovery material      |
         +----------------+------------------+
                          |
              Signed artifacts and
              intermediate certificates
                          |
                          v
             ONLINE RASPBERRY PI 3
         +-----------------------------------+
         | Nginx/Caddy HTTPS endpoint        |
         | Static update repository          |
         | Metadata and release manifests    |
         | Optional issuing intermediate CA  |
         | Logs and monitoring               |
         +----------------+------------------+
                          |
                     HTTPS/mTLS
                          |
        +-----------------+------------------+
        |                 |                  |
    RAUC client      SWUpdate client     Mender client

The most important rule

The device downloading the firmware should not have to trust the update server to decide whether the firmware is legitimate.

The update client should verify the firmware package using a public verification key already installed in the production image. Therefore, even if the Pi’s web server is compromised, an attacker should not be able to produce an acceptable firmware update.

RAUC verifies a CMS signature and signer certificate against a keyring stored on the target. SWUpdate can verify a signed sw-description together with hashes for every included image. Mender clients can be configured to reject unsigned or incorrectly signed Artifacts using provisioned public verification keys.

  1. Do not use one firmware key for all three systems

Although RAUC, SWUpdate, and Mender all support signed updates, their signing formats and operational models differ.

System Update object Typical signing approach Server characteristicsRAUC .raucb bundle CMS certificate and key Static HTTPS hosting is usually sufficient SWUpdate .swu archive Signed description plus payload hashes, using RSA, CMS, or GPG Static hosting, custom downloader, hawkBit, or embedded web server Mender .mender Artifact RSA or ECDSA Artifact signature Normally needs the Mender management backend for managed deployments

RAUC explicitly states that it is not a full deployment server. You normally provide the hosting, polling, authorization, rollout logic, and fleet management around it.

I recommend separate signing keys such as:

OTA Root CA ├── RAUC Release Signing CA │ └── RAUC release signer ├── SWUpdate Release Signing CA │ └── SWUpdate release signer └── TLS Issuing CA ├── update-server TLS certificate └── device client certificates

Mender Artifact signing may use a raw RSA or ECDSA public/private key model rather than exactly the same X.509 hierarchy. Mender recommends at least RSA-3072 or ECDSA P-256 and supports PKCS#11.

  1. Is a Raspberry Pi 3 powerful enough? Good uses

A Pi 3 is generally adequate for:

Serving signed .raucb, .swu, and .mender files over HTTPS Hosting small metadata files Running Nginx or Caddy Maintaining a development intermediate CA Serving a small number of devices Running simple scripts for channel selection and update polling

The Pi 3 B+ has 1 GB RAM, microSD storage, and Ethernet limited to a maximum of approximately 300 Mbit/s because it is connected over USB 2.0. In practice, storage reliability and RAM will become constraints before raw cryptographic performance does.

Poor uses

A Pi 3 is not suitable for a current full Mender Server deployment. Current Mender documentation gives the evaluation server requirements as:

arm64 or x86_64 16 GiB RAM 2 virtual CPUs 50 GiB storage

The Docker Compose environment is also explicitly described as an insecure, non-production evaluation environment. A Pi 3 only has 1 GB RAM, and many Pi 3 installations still run a 32-bit OS.

If you need the full Mender management backend, use:

Mender’s hosted service A larger x86_64 or ARM64 server A VM with sufficient RAM and durable storage A Kubernetes environment for a production deployment

The Pi could still act as a local cache or reverse proxy for Mender artifacts, but it should not be expected to run the complete backend.

  1. Storage and power reliability

The microSD card is one of the biggest operational risks.

Use:

A high-quality industrial microSD card for the operating system Preferably a USB SSD for artifacts, CA state, logs, and databases A reliable power supply A small UPS or power-loss protection Read-only or minimized-write OS design where practical Remote backups

A simple storage arrangement could be:

/var/lib/ota/ ├── rauc/ │ ├── development/ │ ├── testing/ │ └── production/ ├── swupdate/ │ ├── development/ │ ├── testing/ │ └── production/ ├── mender-artifacts/ └── metadata/

Avoid overwriting an existing update file. Publish every artifact using an immutable versioned name:

product-a-2.4.1.raucb product-a-2.4.1.swu product-a-2.4.1.mender

Also publish a small signed metadata file that identifies the latest approved version for each hardware variant and release channel.

  1. Protect the signing keys

For a production-oriented design:

Keep the root CA offline Keep production firmware-signing keys offline or in a hardware token Use the Pi only to distribute already signed artifacts Do not copy the root CA private key onto the Pi Require a manual or controlled CI approval before release signing Maintain an auditable record of artifact hash, version, signer, date, and approver Encrypt backups of the CA state and signing keys Test key rotation before deployment

RAUC supports PKCS#11 URLs to avoid storing signing keys as ordinary files. Mender also supports PKCS#11 for signing and recommends that signing occur on an offline system, ideally after manual inspection, rather than on a general build server.

For an initial lab, a hardware token is optional. The architecture should nevertheless allow you to introduce one later without reprovisioning every device.

  1. Design key rotation now

Your devices may operate longer than the validity period of the first signing certificate.

Provision your images to support:

A current verification key A next verification key Removal of a compromised or obsolete key Intermediate CA replacement Clock problems on devices without a real-time clock Certificate expiry while devices are offline Recovery if a key is lost

Mender supports multiple verification keys, which is useful during rotation. RAUC’s CMS-based model supports intermediate CAs, certificate expiry, revocation, and more complex PKI arrangements.

A typical rotation is:

Release firmware that trusts both old and new verification keys. Start signing new releases with the new key. Confirm the fleet has migrated. Release firmware that removes the old key. Revoke or archive the old signer. 8. Define the OTA threat model

Before configuring software, write down the failures and attacks you need to survive:

Update server compromise DNS spoofing TLS private-key theft Firmware-signing key theft Rollback to a vulnerable firmware Update intended for the wrong hardware revision Power loss during installation Storage corruption Interrupted download Boot failure after update Device clock being incorrect Insider uploading an unapproved artifact Loss of the Pi or its USB storage

Package signatures provide authenticity, but you still need controls for:

Anti-rollback Hardware compatibility A/B fallback Boot attempt counters Post-install health checks Atomic publication Phased rollout

Mender Artifacts include compatibility, version, dependency, checksum, and payload metadata. RAUC and SWUpdate require you to design more of the deployment policy around their update formats and target integration.

  1. Network exposure and access control

For the Pi:

Prefer wired Ethernet Place it on a dedicated management or OTA VLAN Do not expose SSH directly to the public internet Allow SSH only from an administration subnet or VPN Use SSH keys and disable password login Put the artifact repository behind HTTPS Consider mutual TLS for device downloads Rate-limit API and authentication endpoints Run the HTTP service as an unprivileged user Use a host firewall Apply unattended security updates carefully Monitor free disk space, CPU temperature, failed authentication, and certificate expiry

If the devices communicate only on a controlled LAN, private DNS such as updates.internal.example is easier to maintain than hard-coded IP addresses.

  1. Start with one OTA framework, not all three

My practical recommendation is to avoid implementing RAUC, SWUpdate, and Mender simultaneously.

Choose based on your requirements:

RAUC: strong choice for a custom Yocto or Buildroot product where you want a compact client, A/B updates, and control over the surrounding fleet logic. SWUpdate: strong choice when you need flexible handlers, diverse flash layouts, or integration with hawkBit-style deployments. Mender: strong choice when you need inventory, device authentication, deployment groups, phased rollouts, UI, and a complete management plane.

Build one end-to-end reference implementation first:

Build image -> create update package -> validate compatibility/version -> sign on protected system -> verify signature independently -> upload atomically to Pi -> download over HTTPS -> install to inactive slot -> reboot -> run health check -> commit or roll back -> report result

Suggested first implementation

For a Pi 3 and a small internal fleet, I would begin with:

Raspberry Pi OS Lite 64-bit, if supported by your exact Pi 3 model and required software. USB SSD for update storage. Nginx or Caddy as a static HTTPS server. Offline root CA on an encrypted removable medium. Online TLS intermediate CA, only if automated TLS/device certificate issuance is required. Separate offline RAUC or SWUpdate production-signing key. Client-side verification key embedded in the read-only target image. development, testing, and production channels. A/B root filesystem and boot-attempt rollback. Automated artifact hash checking, backup, monitoring, and certificate-expiry alerts.

The Pi should initially be considered an artifact distribution node, not the ultimate source of firmware trust. That distinction will make the design significantly safer and easier to evolve.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment