AppGate SDP on Arch Linux

AppGate SDP provides a Zero Trust network. This post describes how to get AppGate SDP 4.3.2 working on Arch Linux.

Depending on the AppGate SDP Server that is running, you may require a client that is more recent than the latest package on AUR. As of right now, the latest AUR is 4.2.2-1.

These steps highlight how to get it working with Python3.8 by making a 1 line modification to AppGate source code.

Packaging

We already know the community package is currently out of date, so let’s clone it:

git clone https://aur.archlinux.org/appgate-sdp.git
cd appgate-sdp

You’ll likely notice that the version is not what we want, so let’s modify the PKGBUILD to the following:

# Maintainer: Pawel Mosakowski <pawel at mosakowski dot net>
pkgname=appgate-sdp
conflicts=('appgate-sdp-headless')
pkgver=4.3.2
_download_pkgver=4.3
pkgrel=1
epoch=
pkgdesc="Software Defined Perimeter - GUI client"
arch=('x86_64')
url="https://www.cyxtera.com/essential-defense/appgate-sdp/support"
license=('custom')
# dependecies calculated by namcap
depends=('gconf' 'libsecret' 'gtk3' 'python' 'nss' 'libxss' 'nodejs' 'dnsmasq')
source=("https://sdpdownloads.cyxtera.com/AppGate-SDP-${_download_pkgver}/clients/${pkgname}_${pkgver}_amd64.deb"
        "appgatedriver.service")
options=(staticlibs)
prepare() {
    tar -xf data.tar.xz
}
package() {
    cp -dpr "${srcdir}"/{etc,lib,opt,usr} "${pkgdir}"
    mv -v "$pkgdir/lib/systemd/system" "$pkgdir/usr/lib/systemd/"
    rm -vrf "$pkgdir/lib"
    cp -v "$srcdir/appgatedriver.service" "$pkgdir/usr/lib/systemd/system/appgatedriver.service"
    mkdir -vp "$pkgdir/usr/share/licenses/appgate-sdp"
    cp -v "$pkgdir/usr/share/doc/appgate/copyright" "$pkgdir/usr/share/licenses/appgate-sdp"
    cp -v "$pkgdir/usr/share/doc/appgate/LICENSE.github" "$pkgdir/usr/share/licenses/appgate-sdp"
    cp -v "$pkgdir/usr/share/doc/appgate/LICENSES.chromium.html.bz2" "$pkgdir/usr/share/licenses/appgate-sdp"
}
md5sums=('17101aac7623c06d5fbb95f50cf3dbdc'
         '002644116e20b2d79fdb36b7677ab4cf')

Let’s first make sure we have some dependencies. If you do not have yay, check it out.

yay -S dnsmasq gconf

Now, let’s install it:

makepkg -si

Running the client

Ok, let’s run the client by executing appgate.

It complains about not being able to connect.

Easy fix:

sudo systemctl start appgatedriver.service

Now we should be connected… but DNS is not working?

Fixing the DNS

Running resolvectl should display that something is not right.

Why is the DNS not being set by appgate?

$ head -3 /opt/appgate/linux/set_dns
#!/usr/bin/env python3
'''
This is used to set and unset the DNS.

It seems like python3 is required for the DNS setting to happen. Let’s try to run it.

$ sudo /opt/appgate/linux/set_dns
/opt/appgate/linux/set_dns:88: SyntaxWarning: "is" with a literal. Did you mean "=="?
  servers = [( socket.AF_INET if x.version is 4 else socket.AF_INET6, map(int, x.packed)) for x in servers]
Traceback (most recent call last):
  File "/opt/appgate/linux/set_dns", line 30, in <module>
    import dbus
ModuleNotFoundError: No module named 'dbus'

Ok, let’s install it:

$ sudo python3.8 -m pip install dbus-python

Will it work now? Not yet. There’s another issue:

$ sudo /opt/appgate/linux/set_dns
/opt/appgate/linux/set_dns:88: SyntaxWarning: "is" with a literal. Did you mean "=="?
  servers = [( socket.AF_INET if x.version is 4 else socket.AF_INET6, map(int, x.packed)) for x in servers]
module 'platform' has no attribute 'linux_distribution'

This is a breaking change in Python3.8.

So what is calling platform.linux_distribution?

Let’s search for it:

$ sudo grep -r 'linux_distribution' /opt/appgate/linux/
/opt/appgate/linux/nm.py:    if platform.linux_distribution()[0] != 'Fedora':

Aha! So this is in the local AppGate source code. This should be an easy fix. Let’s just replace this line with:

if True: # Since we are not using Fedora :)

Wrapping up

It turns out there are breaking changes in Python3.8.

The docs say Deprecated since version 3.5, will be removed in version 3.8: See alternative like the distro package.

I suppose this highlights one of the caveats of relying upon the system’s python, rather than having an isolated, dedicated environment for all dependencies.