# AppGate SDP on Arch Linux

Posted on Mar 16, 2020

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.