A low pass filter for 40m

I’m currently finishing a 20w amplifier from EI9GQ’s book “Building a Transceiver” to pair with the “Simple SSB” 40 meter transceiver I recently completed.

The amplifier was mostly complete but I still needed a low pass filter for it. I had a look at the filter design suggested in Eamon’s book, but I didn’t have all the capacitor values or toroid types recommended. I therefore decided to use LT Spice to tweak the values to see if I could get by with what was in the junk box.

What I came up with was the following:

I then went on to building the filter, using what I had specified in LT Spice. I paralleled two 430pf capacitors for both C2 and C3 and used three T68-2 toroids with 16 turns each to give the approximate inductance.

I then soldered on some temporary SMA connections and hooked up the NanoVNA.

This looked pretty good to me, with attenuation at the second harmonic being down around -50dB and a cutoff frequency at around 8MHz.

Creating a Debian mirror for Raspberry Pi using Aptly

Having a local mirror of Debian provides you more control over how and when your devices are updated. It can also be useful in situations where devices may not have access to public mirrors. In this post we will describe a method to create a local Debian mirror that can be used for Raspberry Pi devices.


Aptly is a tool for managing Debian package repositories and mirrors.

There are several steps to setup a mirror using Aptly. These consist of the following:

  1. Import keys for signature verification
  2. Create the local mirrors
  3. Perform updates to fetch the packages from the origin mirror
  4. Create snapshots
  5. Create a GPG key for signing
  6. Publish the snapshot(s) to an endpoint
Import public keys for verifying signatures:
sudo apt install debian-archive-keyring

gpg --no-default-keyring --keyring /usr/share/keyrings/debian-archive-keyring.gpg --export | gpg --no-default-keyring --keyring trustedkeys.gpg --import

gpg --no-default-keyring --keyring trustedkeys.gpg --keyserver keyserver.ubuntu.com --recv-keys 0E98404D386FA1D9 6ED0E7B82643E131 82B129927FA3303E

Note: Some Debian keys were not available and were sourced from the Ubuntu key server instead, as seen in the last line above.

Creating the mirrors

At the time of writing, the current Raspberry Pi sources.list and raspi.list for “bullseye” reference the following repos:


  • deb http://deb.debian.org/debian bullseye main contrib non-free
  • deb http://security.debian.org/debian-security bullseye-security main contrib non-free
  • deb http://deb.debian.org/debian bullseye-updates main contrib non-free


  • deb http://archive.raspberrypi.org/debian/ bullseye main

We therefore need to replicate this within our own repository.

The following demonstrates the commands to create the mirrors using Aptly:


aptly mirror create -architectures="arm64" --keyring=trustedkeys.gpg bullseye-main http://deb.debian.org/debian bullseye main contrib non-free


aptly mirror create -architectures="arm64" --keyring=trustedkeys.gpg bullseye-security http://security.debian.org/debian-security bullseye-security updates/main updates/contrib updates/non-free

Note: there is a known Aptly issue that requires the use of “updates/main” “updates/contrib” “updates/non-free” instead of the usual “main”, “contrib”, “non-free” naming of components when creating the “bullseye-security” mirror.


aptly mirror create -architectures="arm64" --keyring=trustedkeys.gpg bullseye-security http://security.debian.org/debian-security bullseye-security updates/main updates/contrib updates/non-free


aptly mirror create -architectures="arm64" --keyring=trustedkeys.gpg rasp-bullseye-main http://archive.raspberrypi.org/debian/ bullseye main
Updating the mirrors:

Updating will download the files from the origin and can take some time to complete. I recommend using screen session for updating to allow the downloads to continue if you are disconnected.

aptly mirror update bullseye-main

aptly mirror update bullseye-security

aptly mirror update bullseye-updates

aptly mirror update rasp-bullseye-main
Creating a snapshot:

Snapshots reflect a instance of the repository at a certain point in time and should be postfixed with a timestamp:

aptly snapshot create bullseye-main-20231221 from mirror bullseye-main 

aptly snapshot create bullseye-security-20231221 from mirror bullseye-security

aptly snapshot create bullseye-updates-20231221 from mirror bullseye-updates

aptly snapshot create rasp-bullseye-main-20231221 from mirror rasp-bullseye-main
Merging the snapshots in preparation for publishing:

Snapshots can be published individually or merged into a single final snapshot. A single snapshot can have the advantage that you only need to add a single URL to the client’s sources.list file. But be aware however that it can also cause security warnings because apt thinks the security updates repository is missing, since it is not specified explicitly in the sources.list.

The following will take the individual snapshots and combine them into a single final snapshot that can be used for publishing:

aptly snapshot merge -latest bullseye-final-20231221 bullseye-main-20231221 bullseye-security-20231221 bullseye-updates-20231221 rasp-bullseye-main-20231221
Key generation:

A signing key pair must be created before publishing. The public key is provided to the client (often in the public web root directory) and is used by apt to verify package signatures.

This can be done with the following:

gpg --gen-key

Export the public key to be later provided to the client:

gpg2 --export --armor > signing.pub

Publishing will write all files to ~/.aptly/public, with the expectation to then serve them via a web server:

aptly publish snapshot -distribution=bullseye bullseye-final-20231221

Once publishing is finished, you will be provided with a URL in the output that can be used to update the client device’s sources.list file:

ie. deb http://<example.com>/mirror bullseye main


Republishing a new snapshot (with updates from the remote repository) requires updating the local mirror, creating a new snapshot, merging and then performing a aptly publish switch instead of an aptly publish snapshot.

Example of performing a publish switch is below:

aptly publish switch bullseye bullseye-final-20231221

Once published, a new directory will be created: ~/.aptly/public. You can then use a web server such as NGINX to serve this directory and make it available to client devices.

Client Device Setup

To setup a new device to use the mirror, the following steps must be taken:

  1. Download and import the signing key (in this example, from the public web server’s root directory)
  2. Comment or remove existing sources.list and raspi.list entries for the existing Debian and Raspberry Pi repositories and replace them with a reference to the new mirror URL or mirror list file.
  3. Update apt against the new mirror and upgrade the existing packages
Fetching and installing the public signing key:

First make sure you have placed the signing.pub from above in the ~/.aptly/public directory to be served by your web server.

We then need to run the following from the client device to fetch the new key.

Note: since the deprecation of apt-key add, the following command is instead recommended to download the key from the mirror public root and install into the local system’s /usr/share/keyrings folder, where it can be used by apt:

wget -O - -q https://<example.com>/mirror/signing.key | sudo gpg --dearmor -o /usr/share/keyrings/mirror-keyring.gpg

Of course, replace the above example URL with your mirrror’s URL.

Updating the sources.list files:

As mentioned above the current Raspberry Pi /etc/apt/sources.list and /etc/apt/sources.list.d/raspi.list for “bullseye” reference the following repos which will need to be removed or commented out, like so:


# deb http://deb.debian.org/debian bullseye main contrib non-free
# deb http://security.debian.org/debian-security bullseye-security main contrib non-free
# deb http://deb.debian.org/debian bullseye-updates main contrib non-free


# deb http://archive.raspberrypi.org/debian/ bullseye main

Now, add a new entry to the sources.list or create a new file in /etc/sources.list.d/ that contains a reference to the new mirror:

echo "deb [signed-by=/usr/share/keyrings/mirror-keyring.gpg] https://<example.com>/mirror bullseye main" | sudo tee /etc/apt/sources.list.d/mirror-bullseye.list

Again, replace the above example URL with your own mirror’s URL.

Apt update and upgrade:

Once the sources have been updated, then an apt update will be required to refresh the package information using the new mirror:

sudo apt update

Followed by an upgrade:

sudo apt upgrade

Socket redirection with GPG

Recently, I had a scenario where my .gnupg directory was being hosted in a Docker volume instead of the standard home directory on Linux. For those that may not be aware, the default GPG directory can be changed by defining the environment variable GNUPGHOME with a different directory. However, because the sockets that GPG was using were now being persisted across containers, I was getting errors from the gpg-agent.

After some research, I discovered that GPG supports changing where it stores its socket files, by providing a redirection in place of the socket files themselves.

There are several of these files that need to be updated for redirection:

  • S.gpg-agent
  • S.gpg-agent.browser
  • S.gpg-agent.extra
  • S.gpg-agent.ssh

These are described as follows in the GnuPG ArchWiki:

  • The main gpg-agent.socket is used by gpg to connect to the gpg-agent daemon.
  • The intended use for the gpg-agent-extra.socket on a local system is to set up a Unix domain socket forwarding from a remote system. This enables to use gpg on the remote system without exposing the private keys to the remote system. See gpg-agent(1) for details.
  • The gpg-agent-browser.socket allows web browsers to access the gpg-agent daemon.
  • The gpg-agent-ssh.socket can be used by SSH to cache SSH keys added by the ssh-add program. See #SSH agent for the necessary configuration.
  • The dirmngr.socket starts a GnuPG daemon handling connections to keyservers.

To add support for socket redirection, we need to both update the GPG configuration and create three other files…

For S.gpg-agent.extra and S.gpg-agent.browser, add the following to the .gnupg/gpg-agent.conf file (create the file if it doesn’t already exist):

extra-socket /var/run/S.gpg-agent.extra
browser-socket /var/run/S.gpg-agent.browser

For S.gpg-agent, S.gpg-agent.ssh and S.dirmngr, create three separate files:

$ printf '%%Assuan%%\nsocket=/var/run/S.gpg-agent\n' > ${GNUPGHOME}/S.gpg-agent

$ printf '%%Assuan%%\nsocket=/var/run/S.gpg-agent.ssh\n' > ${GNUPGHOME}/S.gpg-agent.ssh   

$ printf '%%Assuan%%\nsocket=/var/run/S.dirmngr\n' > ${GNUPGHOME}/S.dirmngr 

In the above, you can see we are now using /var/run as the new socket location. I’m also assuming that you’ve previously set the GNUPGHOME environment variable. If not, then substitute your .gnupg directory instead.

Once complete you will want to restart the gpg-agent:

gpg-connect-agent reloadagent /bye  
Helpful References: