dnscrypt-proxy Revisited: Installing on Debian / Raspbian Jessie

I had originally set up dnscrypt-proxy back in late 2015 when I was still learning lots about modern Debian. It was pretty much a set-and-forget setup, so my January 2017 posts on this topic were mostly based on my original installation in 2015.

Now that I know modern Debian in much more detail, I’m realising many improvements that can be made to the setup. Rather than continue this in a patchwork fashion, I’ve decided to do everything from scratch.

Installation

In January I wrote about installing dnscrypt on Debian Jessie (stable). As dnscrypt is not in the Debian Jessie repositories, I installed it using checkinstall; which is the same as make install except it creates a .deb and installs it with dpkg. It’s better than make install in that the package can be managed (e.g. removed) with dpkg, but it’s still not a package tailored for Debian.

In February I found out about and wrote about another method – obtaining the .deb from Debian Stretch (testing) and installing it with dpkg. This is arguably better as the Debian team will have tailored the package to Debian, even if it’s from Stretch rather than Jessie.

Now it’s March, and the lightbulb finally went off in my head that I should use APT’s techniques for mixing packages from different releases for dnscrypt. Once again, this method is arguably better than the previous, removing any usage of the lower-level dpkg tool.

Configuring Stretch Sources

First off, we need to set our default release. This is important as right now the release we are using (Jessie) is governed by the sources.list file. We’re about to add Stretch to sources.list, so if we don’t specifically set the default release, our system will start to prefer newer Stretch packages all over.

This can be done in either /etc/apt/apt.conf (which probably does not already exist) or by creating a file in /etc/apt/apt.conf.d. We can either choose a branch like stable, or we can choose a release name like Jessie. I prefer to set it to Jessie – as personally when Jessie changes from stable to oldstable and Stretch changes from testing to stable, I don’t want my whole system to automatically move to Stretch.

> sudo nano /etc/apt/apt.conf
APT::Default-Release "jessie";

Now we can add the Stretch sources, either in /etc/apt/sources.list or /etc/apt/sources.list.d

> sudo nano /etc/apt/sources.list
deb http://mirrordirector.raspbian.org/raspbian/ jessie main contrib non-free rpi
deb http://mirrordirector.raspbian.org/raspbian/ stretch main contrib non-free rpi
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://archive.raspbian.org/raspbian/ jessie main contrib non-free rpi

Let’s confirm that a general dist-upgrade is still keeping us on Jessie. Run the following you should see that all packages that need upgrading (if any) are staying within Jessie, unless you have already previously installed packages from another release. If you miss out setting the default release above, you can expect to see 100s of package upgrades to Stretch.

> sudo apt-get dist-upgrade -s
# Example output
# ...
Inst bind9utils [1:9.9.5.dfsg-9+deb8u9] (1:9.9.5.dfsg-9+deb8u10 Raspbian:stable [armhf]) []
Inst libdns100 [1:9.9.5.dfsg-9+deb8u9] (1:9.9.5.dfsg-9+deb8u10 Raspbian:stable [armhf]) []
Inst libbind9-90 [1:9.9.5.dfsg-9+deb8u9] (1:9.9.5.dfsg-9+deb8u10 Raspbian:stable [armhf])
Inst bind9-doc [1:9.9.5.dfsg-9+deb8u9] (1:9.9.5.dfsg-9+deb8u10 Raspbian:stable [all])
Inst libraspberrypi-dev [1.20161215-1] (1.20170303-1 Raspberry Pi Foundation:stable [armhf]) []
Inst libraspberrypi-doc [1.20161215-1] (1.20170303-1 Raspberry Pi Foundation:stable [armhf]) []
Inst raspberrypi-kernel [1.20161215-1] (1.20170303-1 Raspberry Pi Foundation:stable [armhf]) []
Inst libraspberrypi-bin [1.20161215-1] (1.20170303-1 Raspberry Pi Foundation:stable [armhf]) []
Inst libraspberrypi0 [1.20161215-1] (1.20170303-1 Raspberry Pi Foundation:stable [armhf]) []
# ...

Playing with APT

Now let’s see if we can install a package that is only in Stretch. Let’s start with rclone – this is a simple package with a single direct dependency which is in Jessie.

> sudo apt-get install rclone -s
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  rclone
0 upgraded, 1 newly installed, 0 to remove and 32 not upgraded.
Inst rclone (1.35-1 Raspbian:testing [armhf])
Conf rclone (1.35-1 Raspbian:testing [armhf])

Yes, we can. In a way this is good, we can see that it will let us install it from Stretch / testing. However I don’t like this – rclone isn’t something we have specifically configured to install from Stretch, so this could happen for other packages too. I want apt to only install packages from testing if (a) I have explicitly said so, and/or (b) they are upgrades to testing packages I already have installed.

What we need to do is modify the priority of Stretch in the APT preferences file. Right now, APT will install a Stretch package if there is no Jessie package available.

Again, we can either modify /etc/apt/preferences or create a file in /etc/apt/preferences.d

> sudo nano /etc/apt/preferences
Package: *
Pin: release n=jessie
Pin-Priority: 900

Package: *
Pin: release o=Raspbian
Pin-Priority: -10

In short, this gives all Jessie packages a high priority, and all other packages (including Stretch) a priority low enough that they are not automatically installed. You can read more about priorities in apt_preferences(5).

Now if we try installing rclone normally, it won’t allow it to.

> sudo apt-get install rclone -s
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package rclone is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

E: Package 'rclone' has no installation candidate

But, we can explicitly install the Stretch version of rclone.

> sudo apt-get install rclone/stretch -s
Reading package lists... Done
Building dependency tree
Reading state information... Done
Selected version '1.35-1' (Raspbian:testing [armhf]) for 'rclone'
The following NEW packages will be installed:
  rclone
0 upgraded, 1 newly installed, 0 to remove and 32 not upgraded.
Inst rclone (1.35-1 Raspbian:testing [armhf])
Conf rclone (1.35-1 Raspbian:testing [armhf])

What about dnscrypt-proxy?

> sudo apt-get install dnscrypt-proxy -s
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package dnscrypt-proxy is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

E: Package 'dnscrypt-proxy' has no installation candidate

> sudo apt-get install dnscrypt-proxy/stretch -s
Reading package lists... Done
Building dependency tree
Reading state information... Done
Selected version '1.9.4-1' (Raspbian:testing [armhf]) for 'dnscrypt-proxy'
Selected version '2.4.6-2' (Raspbian:testing [armhf]) for 'libltdl7' because of 'dnscrypt-proxy'
Selected version '1.0.11-1' (Raspbian:testing [armhf]) for 'libsodium18' because of 'dnscrypt-proxy'
The following extra packages will be installed:
  libltdl7 libsodium18
The following NEW packages will be installed:
  dnscrypt-proxy libltdl7 libsodium18
0 upgraded, 3 newly installed, 0 to remove and 32 not upgraded.
Inst libltdl7 (2.4.6-2 Raspbian:testing [armhf])
Inst libsodium18 (1.0.11-1 Raspbian:testing [armhf])
Inst dnscrypt-proxy (1.9.4-1 Raspbian:testing [armhf])
Conf libltdl7 (2.4.6-2 Raspbian:testing [armhf])
Conf libsodium18 (1.0.11-1 Raspbian:testing [armhf])
Conf dnscrypt-proxy (1.9.4-1 Raspbian:testing [armhf])

Well that’s good. It will pull in any dependencies it requires.

But what will happen if we perform a general upgrade or dist-upgrade? Presumably it won’t attempt to upgrade any of these packages as the priority is -10. And we can’t override that in our apt-get dist-upgrade command without allowing all of other packages to upgrade to Stretch too. We really want these commands to keep the whole system up-to-date – specific packages on Stretch, all others on Jessie.

Let’s go back to APT preferences and see what happens if we specify a whitelist of packages. This time I will use .d files for each package / purpose.

> sudo nano /etc/apt/preferences.d/rclone
> sudo nano /etc/apt/preferences.d/dnscrypt
Package: rclone
Pin: release n=stretch
Pin-Priority: 995
Package: dnscrypt-proxy
Pin: release n=stretch
Pin-Priority: 995
> sudo apt-get install rclone -s
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  rclone
0 upgraded, 1 newly installed, 0 to remove and 32 not upgraded.
Inst rclone (1.35-1 Raspbian:testing [armhf])
Conf rclone (1.35-1 Raspbian:testing [armhf])

> sudo apt-get install dnscrypt-proxy -s
Reading package lists... Done
Building dependency tree
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 dnscrypt-proxy : Depends: libltdl7 (>= 2.4.6) but 2.4.2-1.11 is to be installed
                  Depends: libsodium18 (>= 1.0.10) but it is not installable
E: Unable to correct problems, you have held broken packages.

It’s a hard whitelist. It allows rclone, which needs no dependencies from Stretch. But it doesn’t allow dnscrypt-proxy, which needs some dependencies from Stretch. We need to include the dependencies libltdl7 and libsodium18 in /etc/apt/preferences as well.

This is a good setup to have, as it forces me to make a decision on each individual Stretch dependency whether I am happy to install it on my Jessie system. In this specific case I am happy to do that, as I know that on my system libltdl7 and libsodium18 are relatively isolated – they are only used by dnscrypt-proxy and they don’t affect the core system or anything like that. If something like coreutils came up then I would definitely not allow this!

Package: dnscrypt-proxy libltdl7 libsodium18
Pin: release n=stretch
Pin-Priority: 995

We can now install dnscrypt-proxy and its dependencies from stretch with a simple

> sudo apt-get install dnscrypt-proxy

In the next part we will revisit configuring dnscrypt-proxy.

Leave a Comment

Your email address will not be published. Required fields are marked *