apt-cacher-ng is a software to create local cache of the Debian GNU/Linux mirrors. But it can also be used to cache any other Linux distribution mirrors. As I’m using Qubes OS, I have several TemplateVMs from Debian, Arch Linux, Fedora, Ubuntu, Whonix and many more, and most were minimal templates.

Qubes is currently using tinyproxy by default to update TemplateVM. The standard tinyproxy is just a proxy. It means that as soon as you start to use more than a few TemplateVMs ― it wastes bandwidth (and time) because the same packages repeatedly are being updated. Serving the same packages over similar Linux distributions or BSD on a different TemplateVM is good to be cached. When the following TemplateVM needs to be updated, it uses the same downloaded packages.

apt-cacher-ng is a caching proxy supporting Debian-based distribution out of the box, and it can be configured to support any Linux distribution and BSD.

Install apt-cacher-ng

Create a new Debian-based TemplateVM. The example shown here is using CLI from dom0 terminal. You’re FREE to use Qube Manager if you want.

$ qvm-clone debian-11-minimal deb-11-cache

Open deb-11-cache TemplateVM’s XTerm terminal. From dom0, you can do:

$ qvm-run -u root deb-11-cache xterm

In deb-11-cache TemplateVM; install apt-cacher-ng software by running as root:

# apt install qubes-core-agent-networking apt-cacher-ng
# systemctl mask apt-cacher-ng

Shutdown deb-11-cache TemplateVM:

# poweroff

Create and Configure the Proxy Server

Create an AppVM based on deb-11-cache TemplateVM. Set enough space to private volume for caching. E.g: 10GB. Don’t worry; this can be changed later if not enough.

In dom0 terminal:

$ qvm-create acng -t deb-11-cache -l red
$ qvm-volume resize acng:private 10G

Start acng AppVM from dom0 and configure bind-dirs in acng AppVM to store related materials on the private volume.

$ qvm-run -u root acng xterm

Create a file at /rw/config/qubes-bind-dirs.d/50_user.conf in acng AppVM. Use whatever text editor you want. E.g. nano. I used vim:

# mkdir /rw/config/qubes-bind-dirs.d
# touch /rw/config/qubes-bind-dirs.d/50_user.conf
# vim /rw/config/qubes-bind-dirs.d/50_user.conf

Put this configuration inside the file:

binds+=( '/var/cache/apt-cacher-ng' )
binds+=( '/var/log/apt-cacher-ng' )
binds+=( '/etc/apt-cacher-ng' )

Edit /rw/config/rc.local to start apt-cacher-ng service:

# vim /rw/config/rc.local

Add this at the end of the line:

systemctl unmask apt-cacher-ng
systemctl start apt-cacher-ng
/sbin/iptables -I INPUT -p tcp --dport 8082 -j ACCEPT

Restart acng AppVM with root privileges, open XTerm terminal, and edit the file with vim /etc/apt-cacher-ng/acng.conf.

In /etc/apt-cacher-ng/acng.conf:

Find the line with the name Port:3142 and edit to Port:8082, save and exit.

Restart the service from acng terminal:

# systemctl restart apt-cacher-ng

Using the Proxy

To use the acng proxy, you need to edit qrexec policy in dom0. This file is located at /etc/qubes/policy.d/.

Create a new policy in dom0 /etc/qubes/policy.d/30-user.policy:

$ sudo touch /etc/qubes/policy.d/30-user.policy
$ sudo vim /etc/qubes/policy.d/30-user.policy

Add this into the file:

qubes.UpdatesProxy * @type:TemplateVM @default allow target=acng

Now all the TemplateVMs will attempt to use the caching proxy instead of the default proxy running on the sys-net.

If you’re using Whonix and found out the TemplateVM can’t be updated anymore due to this proxy’s qrexec policy, you need to add sys-whonix to the 30-user.policy. Edit /etc/qubes/policy.d/30-user.policy accordingly:

# Upgrade Whonix TemplateVMs through sys-whonix.
qubes.UpdatesProxy  *  @tag:whonix-updatevm   @default    allow target=sys-whonix
# Deny Whonix TemplateVMs using UpdatesProxy of any other VM.
qubes.UpdatesProxy  *  @tag:whonix-updatevm   @anyvm      deny
# Default rule for all TemplateVMs.
qubes.UpdatesProxy  *  @type:TemplateVM       @default    allow target=acng
qubes.UpdatesProxy  *  @anyvm                 @anyvm      deny

Whonix TemplateVM should be updated after that. But sys-whonix won’t use acng as a caching proxy, and something needs to be changed if you need sys-whonix to use the caching proxy. Refer to the NEXT section.

Configuring TemplateVMs

Some TemplateVMs use HTTPS links to the repositories, which needs to be changed. Otherwise, the traffic will be encrypted when it reaches the proxy, so the proxy will not know what to do.

It is possible to “pass-through” HTTPS traffic by editing the config file at /etc/apt-cacher-ng/acng.conf.

You can create a regex that will match the server(s) you want to pass through: PassThroughPattern: debian.org:443$

It will pass through the traffic to https://debian.org. If you do this, you will not cache that traffic.

If you want to cache this traffic, you have to rewrite the repository definition.

The simplest way to do this is to change the repository definition from https://yum.qubes-os.org/ to http://HTTPS///yum.qubes-os.org/.

It will use HTTP to the proxy – the proxy will use TLS to pick up the packages and cache any responses. It is the recommended approach.

You can make this change in the TemplateVM by running: sed -i s^https://HTTPS///^ REPO_DEFINITION - e.g. in Debian TemplateVM:

# sed -i s^https://^http://HTTPS///^ /etc/apt/sources.list

You have to make the change in every defined repository that you want to use. If you don’t, then you will see an error message like this:

Failed to fetch ....
Invalid response from proxy: HTTP/1.0 403 CONNECT denied (ask the admin to allow HTTPS tunnels)

Other Configurations

Grouping Repositories

apt-cacher-ng has a mechanism for mapping calls to different repositories on the same cache. It is called mapping, described in the excellent apt-cacher-ng manual.

There are some predefined mapping lists that you can use.

If you check the caches at var/cache/apt-cacher-ng, you may see that there are entries for individual repositories. You can edit the mapping files to include them.

For example, you may set up mapping Fedora repositories by including this line in the config file:

Remap-fedora: file:fedora_mirrors where “fedora_mirrors” is a file containing a list of Fedora repositories or URLs.

After a while, you’ll notice that the cached directories in /var/cache/apt-cacher-ng include “Fedora” with so many cached packages and mirror’s name like “mirror.telepoint.bg”.

For Fedora mirror:

You simply edit the “fedora_mirrors” file to include the name “mirror.telepoint.bg”. E.g. I have this line inside fedora_mirrors:

https://ftp.iij.ad.jp/pub/linux/Fedora/fedora/linux/
https://da.mirrors.kernel.org/fedora/
https://ftp.riken.jp/Linux/fedora/
https://ftp.yz.yamagata-u.ac.jp/pub/linux/fedora-projects/fedora/linux/
https://mirror.aarnet.edu.au/pub/fedora/linux/

Now request to that mirror will be dealt with in the main cache directory.

Ideally, you want all the packages downloaded from any Debian repository to be served from the same cache.

Fedora

Fedora TemplateVM’s configurations need to be changed because the default repository definitions use “metalinks”.

You can either change this to use BASEURL definition or to make the metalinks return HTTP repositories instead of HTTPS links.

You can do this by changing (e.g.) metalink= https://.....basearch to metalink=http://HTTPS///....basearch&protocol=http. This will make the metalink only return HTTP repositories.

There were mirrors list in /usr/lib/apt-cacher-ng/. Copy fedora_mirrors to /etc/apt-cacher-ng if it doesn’t yet exist.

Edit /etc/apt-cacher-ng/acng.conf to use the mapped data: Remap-fedora: file:fedora_mirrors

If requests fail because the filetype is not allowed, create a pattern for volatile data:

VfilePatternEx: .*metalink?repo=fedora*

For more details – All these steps are covered inside the apt-cacher-ng manual.

Troubleshooting

Apart from using “pass-through” to handle some repositories, you can exclude TemplateVMs from using the proxy by setting a policy line before the one that points to acng in /etc/qubes/policy/30-user.policy.

The new line should point TemplateVMs name to the default system proxy, like this:

qubes.UpdatesProxy * fedora-36         @default  allow target=sys-net
qubes.UpdatesProxy * @type:TemplateVM  @default  allow target=acng

Access logs are available on acng at /var/log/apt-cacher-ng.

You can see the cached data in /var/cache/apt-cacher-ng.

There is also a web interface available on the caching proxy at http://localhost:8082, which contains valuable information about how much data is cached and how often it is used, as well as tools to help control the cached data.

Read the manual.

Updates Over Tor or VPN

Set the netvm for acng AppVM to a TorVM or VPN ProxyVM.

Other Qubes

You can also use the proxy with other qubes, besides TemplateVMs.

Because the proxy is listening on port 8082, and you have configured iptables to allow inbound traffic to that port, you can use the proxy from any downstream qube simply by configuring the use of the Proxy in that qube, following whatever is the normal method.

(You will have to adjust repository definitions to handle HTTPS.)

It allows you to benefit from caching in normal qubes, and Standalones, without using qrexec.

Let’s say you want to use it to proxy something without any blocking from the proxy server. PassThroughPattern should be adjusted to allow any ports:

PassThroughPattern: .*

Or you want to pass through TLS connection using the proxy:

PassThroughPattern: ^(.*):443$

The Simple Way

Follow the instructions at https://qubes.3isec.org/tasks.html to install qubes-task.

Select the cacher package and install it.

The caching proxy will be created, and configured including all existing templates to use the proxy.

References

Credit to unman, one of the Qubes Team member, for the idea and notes. This documentation is modified to suit my use case and add more clarity.