The LVFS is a public webservice designed to allow OEMs and ODMs to upload firmware easily, and for it to be distributed securely to tens of millions of end users. For some people, this simply does not work for various reasons:
They don’t trust the LVFS team, fwupd.org, GPG, certain OEMs or the CDN we use
They don’t want thousands of computers on an internal network downloading all the files over and over again
The internal secure network has no internet connectivity
For these cases there are a few different ways to keep your hardware updated, in order of simplicity:
Deploy in immutable image¶
If the OS is shipped as an image, you can just install the
.cab files into
/usr/share/fwupd/remotes.d/vendor/firmware and then enable
fwupdmgr enable-remote vendor-directory.
Then once you have disabled the public LVFS using
fwupdmgr disable-remote lvfs,
fwupdmgr will use only the cabinet archives you deploy in your
Of course, you’re deploying a larger image because you might have several unused
firmware files included for each image, but this is how Google Chrome OS is using
Mirror the public firmware¶
You can use Pulp to mirror the entire public contents of the LVFS (but never private or embargoed firmware). Create a repo pointing to PULP_MANIFEST and then sync that on a regular basis to download the metadata and firmware. The contents will not change any more frequently than every 4 hours, so please use a polling interval of at least that.
Using a helper script¶
There is a helper script sync-pulp.py
that can be used if
pulp-server is not installed:
./contrib/sync-pulp.py https://cdn.fwupd.org/downloads /mnt/mirror
You can then use a webserver such as Nginx or Apache to export
Then, disable the LVFS by deleting or modifying
and then create a
[fwupd Remote] Enabled=true Type=download MetadataURI=https://my.private.server/mirror/firmware.xml.gz FirmwareBaseURI=https://my.private.server/mirror
To instead mirror the private embargoed files, you can use:
./contrib/sync-pulp.py https://cdn.fwupd.org/downloads /mnt/mirror \ --email@example.com \ --token=XA1A5ZV7R65FUZBZ
Do not use your login password here! Generate a token when logged in to the LVFS using the User Profile settings.
To restrict the downloaded firmware to a specific tag (perhaps a vendor Best Known Configuration) use the following command:
./contrib/sync-pulp.py https://cdn.fwupd.org/downloads /mnt/mirror \ --filter-tag=hughski-2020q1
Note, this command can be run safely multiple times with different
--filter-tag values on the
same destination directory; the superset of files will be downloaded.
By exporting the entire LVFS (including the metadata, and metadata signature) you can still delay the deployment of firmware. Using the approved firmware list the client can filter out firmware that has not been tested by your organization without creating and signing a custom remote.
The allow-list of firmware can be set using:
fwupdmgr set-approved-firmware checksum1,checksum2,checksum3
Some versions of fwupd (>= 1.7.1) also support loading the list of checksums using a filename, e.g.
fwupdmgr set-approved-firmware filename
checksum is the SHA1 or SHA256 checksum of the
org.freedesktop.fwupd.set-approved-firmware PolicyKit action
may require root permission to use.
.cab files that match your hardware and then install them
on the target hardware via Ansible or
fwupdmgr install foo.cab. You can also
fwupdagent get-devices to get the existing firmware versions of all
hardware in a format you can parse from scripts.
Building a custom remote¶
script allows you to create the metadata for a directory of
If you want to use signed metadata then please use
jcat-tool firmware.xml.gz.jcat firmware.xml.gz CERTIFICATE PRIVATE_KEY.
You will need to create a custom certificate
and you’ll also need to distribute the the PKCS#7 certificate on all clients
that are going to use the remote.
Create your own LVFS¶
The LVFS is a free software Python 3 Flask application and an instance can be set up internally if required. You have to configure much more this way, including generating your own GPG and PKCS#7 keys, uploading your own firmware and setting up users and groups on the server.
Doing all this has a few advantages, namely:
You can upload each firmware file and QA it, only pushing it to stable when ready
You don’t ship firmware which you didn’t upload
You can control the staged deployment, e.g. only allowing the same update to be deployed to 1000 servers per day
You can see failure reports from clients, to verify if the deployment is going well
You can see nice graphs about how many updates are being deployed across your organization
However, running a secure LVFS instance is a lot of work as PostgreSQL has to be used as a database, Redis has to also be set up as a queue manager, and Celery is used to manage the worker queues.
Although minor versions of the LVFS can be upgraded easily, you should review all the commits to lvfs-website to ensure that any manual migration is also performed.