My thoughts on Slackware, life and everything

Tag: vpn

Put your application inside a VPN jail

The premise

Note; political rant with European bias follows. If you don’t want to be exposed to my political views but still want to read the technical content of this article, simply skip the “Premise” and scroll down to “My data under my control”.

Looking at the rapidly deteriorating situation in the United States of America with disgust and shock, my prediction is that the soft approach to opposing Donald Trump’s hostile take-over of the country is going to fail horribly, and will result in the next fascist dictatorship within two years (mark my words).
Therefore I am withdrawing my data from the US based companies as much and as fast as I can. If you live outside the United States, the possibility that US-based companies may just cut-off access to your Cloud data when the Orange Clown instructs them to, is all to real.
It’s not just me; there is a real and irreversible push in the European Union to put an end to the imbalance and invest in a European open-source based Cloud infrastructure to rival the US companies that have gladly received our money for years and still can’t make hard commitments that they won’t apply the kill-switch when the Fascist-in-Chief demands it.

My data under my control

The desire to have more control over your own data is not new of course. Discussions about what that means on a wider scale are simply accelerated by current events.
You can already access a lot of detailed information on how to become independent of the big tech companies via my own series of blog articles called “Slackware Cloud Server“. I am researching two additional installments to that series: one about how to setup Joplin Server as an alternative to OneNote (Joplin can actually import OneNote files easily), and another one about how to setup a cheap-ish remote storage to make safe backups of all your locally stored data. Data to be stored inside Europe of course. More on that in due time.

A necessary step to move away from Google and friends was purchasing a Proton family account. The realization hit me a long while ago of course, that free services like GMail are only free because Google harvests, uses and sells your data that you store on their platform.
Proton on the other hand is a Swiss-based company with a focus on privacy. It costs money to use their services, yes, but the data you store with Proton will be secure and safe from those prying eyes.
If  you have not yet implemented my Slackware Cloud Server, then you are most likely subscribed to one or more Cloud-based streaming services like Netflix, HBO, AppleTV, Disney+ and so on – you pay when you determine you get your money’s worth. So I pay to get my data off Google, Microsoft and Dropbox servers.

VPN as a privacy tool

Looking at the services that come with a Proton account, I noticed that they offer a VPN service as part of the package. This reminded me of the importance to have a proper VPN installed. People who already live inside a dictatorship know that a VPN can be a lifeline to the free world, and my American friends: you will need that VPN too, soon!

I am not in favor of free VPN’s. Speeds are never great and you have no certainty or guarantee that the free VPN provider is not actually harvesting and selling your personal data.
Unless you yourself run the VPN server. At home I implemented an actual Virtual Private Network using Wireguard. WireGuard is a VPN protocol which is part of the Linux kernel and the user-space is a simple binary, controlled by simple configuration files. It connects my family’s laptops, phones and also the network infrastructure of our camper van to our home, combining all devices into a single network with one exit point towards the Internet which is here, at home.
This kind of VPN server is not meant to prevent other parties spying on you. Instead it is the type of VPN that securely connects devices (one server and many roaming clients) into a single ‘local’ network; the traditional interpretation of VPN. All devices inside the network can communicate with each other; this is how I can access my home automation even when I am out of the country in my camper van.

The VPN solution I want to discuss here, is of the other kind: the one that hides your activities from prying eyes. A privacy-enhancing tool.
This kind of VPN connection creates a tunnel between your local computer and one of many remote servers operated by a VPN provider. You can get a subscription from companies like NordVPN, PIA to name a few, or in my case: ProtonVPN. The VPN allows you to ‘go anonymous’ with the click of a button. Whatever information you access on the Internet through a VPN tunnel can never be traced back to you personally because your IP address is effectively hidden and replaced by the IP address of the VPN access point.

Installing the VPN client offered by any of these providers is trivial, applications offered for Linux, Windows, Android and iOS. The standard usage is also well-documented. It becomes more interesting when your use-case is more un-common.

This article shows how you can install a VPN (WireGuard in this case), place the VPN network interface inside a jail so that your Slackware computer does not even know it is there, and then add programs to that jail. The programs inside that network jail will be forced to access the internet through the VPN tunnel, they cannot circumvent the jail and therefore do not have access to your regular network connection. Your privacy-sensitive information will not be able leak out of your regular network connection. These jailed applications will still be able to communicate with local applications and services via the loopback interface.

Intrigued? Read on!

Put the VPN in a network jail

As a Slackware Linux user, text-based configuration files are always preferred over Graphical Users Interfaces, right 🙂

Obtain a WireGuard configuration

I downloaded the WireGuard configuration file that allows me to connect to the Proton VPN service from my own account’s dashboard. There’s documentation on how to do that.
The contents of this configuration file are really simple. All they describe are the characteristics of the two endpoints: yours (using a private key for encryption) and the remote server (identified by a public key and an IP address or hostname). The remote server in turn has a copy of your public key so that they can validate your identity:

PrivateKey = 2QLYsfx89Lpc24iBtZmygieXYwq1WZwPok8joqB/Fys=
Address = 10.2.0.2/32
DNS = 10.2.0.1

[Peer]
PublicKey = dOJQd38biobpWxq4wpF7mk2oUiJnjHZlDZ7s8X/z+xs=
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = XXX.XXX.XXX.XXX:51820

The two key values are of course bogus. The “XXX.XXX.XXX.XXX” will be the IP address of the VPN server at the other end of the connection.

Move the Wireguard configuration file to ‘/etc/wireguard/proton0.conf‘.  You could now run the command “wg-quick up proton0” to activate the VPN interface but that has a potentially unwanted side effect if your computer is also a server. The ‘wg-quick‘ command installs a new default route forcing all your external traffic through the VPN tunnel.
If you run network services on that computer then your clients will be in for a world of hurt.

How to prevent that the ‘proton0‘ interface forces itself as the default route?

Tame the beast

To prevent ‘wg-quick‘ from overriding your default route and instead keep your physical network interface as your primary gateway always, you must modify the WireGuard configuration file that you just installed.
By default, wg-quick interprets the line “AllowedIPs = 0.0.0.0/0” as a trigger to automatically install a new default route through the VPN interface.

Modify the Configuration File

Open your configuration file  /etc/wireguard/proton0.conf and add the following line into the [Interface] section. This instructs wg-quick to bring up the interface and set the IP, but not touch the system routing table:

Table = off # This prevents the default route override

Save the file and now bring up the interface (using the name of the configuration file “proton0“as argument, this will also determine the name of the VPN interface):

# wg-quick up proton0

Verify your default route is still going via your physical interface:

# ip route show | grep default

You should see a line like this: default via <your_gateway_ip> dev eth0

Verify the ‘proton0‘ interface is active:

# wg show

And finally, verify that all other services that are running on your computer are still accessible.

Routing traffic through the VPN

Since we have disabled automatic routing, no traffic will go through the VPN by default. The question remains of course… how should I access and use this new VPN network interface?
There are as many ways as there are use-cases, but for the sake of this article we focus on a single use-case.
We want to route specific traffic through the ‘proton0‘ network interface while keeping ‘eth0‘ (or whatever your default network interface is named) as the default for everything else. More specifically, I want to be able to determine which application(s) should access the Internet exclusively via the VPN interface. We can do this and at the same time leave the main system completely untouched; no ‘iptables‘ or ‘fwmark‘ rules are required to create this separation. How?

We are going to use Network Namespaces (netns).

A Network Namespace gives us the power to place the VPN interface into a “jail.” Basically it creates a separate network stack which is isolated from the computer’s regular network stack. Applications launched inside this jail use the VPN, while everything else on your system continues to use the default gateway. Here are the steps to do just that.

  • Configure WireGuard to handle network isolation.
    The only manual modification that we need to make to ‘/etc/wireguard/proton0.conf‘ in order to prevent it from updating the computer’s routing table has already been shown higher up in the article: Add the line
    Table = off
    to the [Interface] section of the configuration file.
  • Create a boot script (since this is Slackware we call it a “rc script”) to create the VPN jail every time the computer boots.
    Save the following bash script as “/etc/rc.d/rc.protonvpn-jail” and make it executable via the command
    chmod +x /etc/rc.d/rc.protonvpn-jail
# --- 8< ---
#!/bin/bash
# Configuration of a VPN "jail"
NS_NAME="vpn_jail"
WG_CONF_PATH="/etc/wireguard/proton0.conf"
WG_IF="proton0"

if [[ $EUID -ne 0 ]]; then
  echo ">> This script must be run as root!"
  exit 1
fi

case "$1" in
  start)
    # Automatically find the IP address assigned by Proton
    echo "Extracting IP from $WG_CONF_PATH..."
    VPN_IP=$(grep -Po '(?<=^Address = )[^, \n]+' "$WG_CONF_PATH")
    echo "Extracting DNS resolver from $WG_CONF_PATH..."
    DNS_IP=$(grep -Po '(?<=^DNS = )[^, \n]+' "$WG_CONF_PATH")

    if [ -z "$VPN_IP" ]; then
      echo ">> Error: Could not find Address in $WG_CONF_PATH"
      exit 1
    fi

    echo "Starting VPN Jail for IP $VPN_IP..."

    # Create the network namespace
    ip netns add $NS_NAME

    # Setup a Kill-Switch (using nftables)
    ip netns exec $NS_NAME nft flush ruleset
    ip netns exec $NS_NAME nft add table inet filter
    ip netns exec $NS_NAME nft add chain inet filter output \
      { type filter hook output priority 0 \; policy drop \; }
    ip netns exec $NS_NAME nft add rule inet filter output oifname "lo" accept
    ip netns exec $NS_NAME nft add rule inet filter output oifname "$WG_IF" accept

    # Bring up WireGuard in the default namespace
    wg-quick up proton0

    # Move the interface into the jail and re-assign the IP (which was lost during move)
    ip link set $WG_IF netns $NS_NAME
    ip netns exec $NS_NAME ip addr add $VPN_IP dev $WG_IF

    # Bring the network link up (don't forget loopback!)
    # and configure the default route inside the jail
    ip netns exec $NS_NAME ip link set lo up
    ip netns exec $NS_NAME ip link set $WG_IF up
    ip netns exec $NS_NAME ip route add default dev $WG_IF

    # Configure a working DNS for the jail namespace
    mkdir -p /etc/netns/$NS_NAME
    echo "nameserver $DNS_IP" > /etc/netns/$NS_NAME/resolv.conf

    echo "VPN Jail is READY. IP: $VPN_IP"
    ;;

  stop)
    echo "Cleaning up VPN Jail..."
    ip netns del $NS_NAME
    # The interface moves back to default namespace on netns delete; shut it down
    wg-quick down proton0 2>/dev/null
    rm -rf /etc/netns/$NS_NAME
    echo "VPN Jail removed."
    ;;

  *)
    echo "Usage: $0 {start|stop}"
    exit 1
    ;;
esac
# --- 8< ---

Let’s quickly run through the script’s “start” section.

  • The script greps for the “Address =” line in our WireGuard configuration which makes it resistant against a future change in VPN provider or when Proton updates your local VPN endpoint IP address.
  • The IP address of the DNS resolver for the VPN connection is parsed in a similar fashion.
  • A new network namespace is created to serve as our VPN jail.
  • When you choose to run an application behind a VPN, you certainly need a “killswitch“.
    The script uses nftables to ensure that you regular network interface is firewalled from the applications that will run inside the jail. All traffic from the application to Internet will be cut as soon as the VPN interface goes down, so that the application is not suddenly exposing your regular Internet IP address to the whole world.
    How the Kill-Switch Works – A nftables rule sets a default “drop” policy for the output chain inside the jail. Then another nftables rule  only allows network traffic to leave either via the loopback interface (lo: for local inter-application communication) or the WireGuard interface (proton0). If the proton0 interface goes down or is deleted, there is no “accept” rule for any other path. Since the jail doesn’t even “see” your physical interface, the application will simply lose connectivity rather than falling back to your real IP.
  • The WireGuard interface is created and then moved into the jail.
  • After the move to the new namespace we re-associate the IP address of the interface that was stripped by the kernel. Moving an interface to a new namespace is like unplugging it from one stack and plugging it into another; the new namespace has no record of what the previous namespace had configured for the interface.
  • Then the script ensures that the interface is up even if it was previously down.
  • A DNS resolver is configured. We create the “resolv.conf” file in a subdirectory called “/etc/netns/vpn_jail“, because the Linux kernel will automatically bind that directory to /etc/ whenever commands are run inside the “vpn_jail” namespace. This ensures that your DNS queries inside the VPN jail are also routed through Proton VPN, preventing DNS leaks on your primary connection. It cannot get safer!

Add the boot script to Slackware

Add these lines to /etc/rc.d/rc.local :

if [ -x /etc/rc.d/rc.protonvpn-jail ]; then
  echo "Starting Proton VPN jail: /etc/rc.d/rc.protonvpn-jail start"
  /etc/rc.d/rc.protonvpn-jail start
fi

And add these following lines to /etc/rc.d/rc.local_shutdown (if that file does not exist yet, just create it and make it executable):

if [ -x /etc/rc.d/rc.protonvpn-jail ]; then
  echo "Stopping Proton VPN jail: /etc/rc.d/rc.protonvpn-jail stop"
  /etc/rc.d/rc.protonvpn-jail stop
fi

Configuring sudo

Our regular user account will be executing the “ip” command to run applications inside the VPN jail. Since usage of the Linux “ip” command is by default restricted to the root user, we need to create  a “sudoers” rule to allow your regular user account to execute it.

And to be able to launch graphical applications from a desktop shortcut without a prompt popping up to ask for your password, we will arrange for passwordless execution.
The danger when doing this carelessly is that the user can gain access to a root shell by abusing the “sudo” privilege elevation. Therefore we implement a secure wrapper that prevents a user from gaining root access via /sbin/ip netns exec.
As root, create a script that explicitly forces the transition back to the original user once inside the namespace. Call the script “/usr/local/bin/netns-proton” and give it the following content:

#!/bin/bash
# Usage: sudo netns-proton [args...]

NAMESPACE="vpn_jail"
COMMAND="$1"

if [ -z "$COMMAND" ]; then
  echo "Usage: $0   [args...]"
  exit 1
fi

# Remove command from argument list,
# leaving only the extra arguments
shift 1

# Execute inside the namespace,
# forcing a drop to the calling user.
# "$SUDO_USER" is an environment variable set by sudo.
/sbin/ip netns exec "$NAMESPACE" /usr/bin/sudo -u "$SUDO_USER" "$COMMAND" "$@"

Then make that script executable while ensuring that only root can edit it:

# chmod 755 /usr/local/bin/netns-proton

Next, configure sudo. Create a new file named “/etc/sudoers.d/vpn_jail” and add the following line (replace your_username with your actual username):

your_username ALL=(ALL) NOPASSWD: /usr/local/bin/netns-proton *
Using the wildcard * allows you to launch any command inside the namespace without a password. You should replace “your_username” with your own login name of course.

And it is safe: if you run “sudo /usr/local/bin/netns-proton bash“, the resulting shell will be restricted to your regular user permissions, even though it is inside the namespace. Your usage of sudo to enter a namespace is restricted to only the “vpn_jail”.

Quick Verification

You could reboot now, but you can also manually run

# /etc/rc.d/rc.protonvpn-jail start

as root, to create the VPN interface and the associated network jail. Then run the following command as your regular user to show the assigned IP inside the jail:

$ sudo /usr/local/bin/netns-proton ip addr show proton0

And finally, verify that the outside world sees a different IP address coming out of the VPN jail than your regular Internet IP address:

$ sudo /usr/local/bin/netns-proton curl http://myip.slackware.nl

Some trivial usage scenarios

You can now manually launch any application inside the VPN jail by prefixing it with the “sudo /usr/local/bin/netns-proton” command.

To run a web browser:

$ sudo /usr/local/bin/netns-proton firefox

To run a bash prompt inside the VPN jail:

$ sudo /usr/local/bin/netns-proton bash

A more complex usage scenario

A typical application you would want to put inside this VPN jail is a torrenting application. We’ll create a desktop shortcut for a VPN-jailed qBittorrent.
You can of course apply the below to any program but a torrent client can be used to demonstrate that the VPN connection actually works.

  • Copy the regular desktop file into your $HOME:
    $ cp -ia /usr/share/applications/org.qbittorrent.qBittorrent.desktop ~/.local/share/applications/
    and create a shortcut to this on your desktop backdrop. Name it “qBittorrent via VPN”. We will edit the copy, not the original:

    • Open the copied desktop file in an ascii editor and change the “Exec =” line into:
      Exec=sudo /usr/local/bin/netns-proton qbittorrent %U
  • Alternatively create a new file on your desktop directly.  Call it “qBittorrent via VPN”. This will create a file “~/.local/share/applications/qBittorrent via VPN.desktop” – then paste the following content into it:
[Desktop Entry]
Categories=Network;FileTransfer;P2P;Qt;
Comment=Launch qBittorrent inside the VPN Jail
# This uses sudo (permitted by the NOPASSWD rule) to exec in the jail
Exec=sudo /usr/local/bin/netns-proton qbittorrent %U
GenericName=BitTorrent client
Comment=Download and share files over BitTorrent
Icon=qbittorrent
MimeType=application/x-bittorrent;x-scheme-handler/magnet;
Name=qBittorrent
Terminal=false
Type=Application
StartupNotify=false
StartupWMClass=qbittorrent
Keywords=bittorrent;torrent;magnet;download;p2p;
SingleMainWindow=true

Depending on the Desktop Environment , you make have to make this desktop file executable to allow for application-startup via a double-click.

Double-clicking the icon will launch the qBittorrent application inside the isolated network namespace. It’s usage is safe because it will communicate through the VPN and is secured by the built-in “kill-switch” against any accidental exposure.

You can verify that your Torrent client accesses the internet via your VPN:
Open https://ipleak.net/ in your browser (no VPN needed), scroll down to “Torrent Address Detection”, copy the Magnet link that appears there into your qBittorrent application and watch the ipleak page for connection confirmation.
Then bring the VPN down via:

# /etc/rc.d/rc.protonvpn-jail stop

and you should see an immediate loss of connectivity for the qBittorrent program.

Troubleshooting

Proton VPN configurations (not just WireGuard but also OpenVPN) have a habit of breaking at any point as a result of reshuffling of the VPN end point servers. This will be immediately visible to you: the flow of network traffic stops all of a sudden without visible cause (i.e. you did not perform local maintenance or upgrades recently).

This is fairly straight-forward to debug fortunately. There’s two halves to a VPN tunnel:

  1. The underlay (encrypted UDP, initialization of the net namespace,  your actual connection via eth0): is the handshake with Proton completing at all?
  2. The overlay (cleartext communications, inside the jail): packet routing, DNS, MTU, and the working of the killswitch.

Follow this structured approach to determine the root cause of your problem: from inside the VPN jail, ping the WireGuard tunnel’s inner gateway, then ping a public IP address by number (not by hostname). Just two command-lines that will most likely show what the fault is:
# ip netns exec vpn_jail ping -c3 10.2.0.1 # Proton's end of the tunnel
# ip netns exec vpn_jail ping -c3 1.1.1.1 # anything past it, by IP

Reaching 10.2.0.1 is impossible without a completed VPN handshake, which means that if you get a reply there, this  confirms the tunnel is healthy. You don’t even have to execute a  “wg show” command.
Pinging 1.1.1.1 by number rather than by name removes DNS from the picture.
Now, if you examine what is the gap between the two answers, it should point you straight at the layer that broke.

  • The VPN gateway replies, but the public IP does not:
    The VPN tunnel is up but Proton is not forwarding your traffic. This points to an issue with the Proton VPN endpoint server.
    Regenerate the WireGuard configuration on the Proton web page and make sure to switch to a different server IP. Restart the jail; done.
  • The VPN gateway also fails:
    The handshake itself is dead. Now it is worth checking your local side. Is your proton0 interface even up? Is the the namespace firewall working? Was there a local (kernel) upgrade which broke your VPN?

If the above is all working, then there’s still the possible issue with DNS or MTU settings.

Run this command to test DNS:

# ip netns exec vpn_jail curl http://myip.slackware.nl

And run these commands to diagnose MTU settings:

# ip netns exec vpn_jail ping -c3 -M do -s 1392 1.1.1.1 # 1392+28 = 1420, must pass
# ip netns exec vpn_jail ping -c3 -M do -s 1500 1.1.1.1 # should fail cleanly if MTU is honored

What to search for:

  • A ping to a public IP address replies but pinging a hostname does not:
    Forwarding is fine, your problem is DNS (look at the nameserver line in the /etc/netns/vpn_jail/resolv.conf resolver file for this jail).
  • Small pings are passing the tunnel but large ones fail:
    You have a MTU problem, not a forwarding issue.

The rule of thumb is to ping the inside of the tunnel, then ping through it by number, look at the asymmetry and hope that this points to the culprit.

Summarizing

I hope this helps keeping you safe 🙂

Setting up an Outline server to bypass state firewalls

If you live or work (as a journalist for example) in a country which limits free access to information, and you have difficulties penetrating the state firewalls for access to the outside world, you may want to read on. In this article I will inform you about an interesting Open Source VPN solution called Outline which puts you (or your company) in full control. I will also show in great detail how to setup such a VPN server yourself.
One caveat though – you’ll have to rent an online Linux server in a ‘free country’.
Luckily, the cost can be fairly low especially if you share your VPN server with friends or colleagues.

What is Outline

Jigsaw is a daughter company of Alphabet, which is also Google’s parent company. It’s mission: “Jigsaw is a unit within Google that forecasts and confronts emerging threats, creating future-defining research and technology to keep our world safer.”

Jigsaw created the Open Source program “Outline” specifically to enable journalists and news organizations to work in adverse and hostile environments such as dictatorships with state-controlled and censored access to information. Access to information should always be free, uncensored and uncontrolled!

Outline is a client-server solution which uses the VPN capabilities of your device’s Operating System to encrypt and tunnel all your device’s traffic (like web searches, DNS queries) through a SOCKS proxy running on a remote server that you, or your organization, controls.
Outline is able to bypass the Great Firewall for instance. Note that Outline does not provide anonymity; all your traffic will exit from your Outline server. Your online activity will appear to originate there and not from the location you are actually in. Once you have installed an Outline client on your device (an Android phone, a Windows/Linux/Mac computer) you can try sites like dnsleak.com and ipv6leak.com to verify that your network communication is indeed not leaking data that may be snooped by your country’s enforcers. The pixelprivacy website provides a guide to help you understand, find and fix DNS leaks: https://pixelprivacy.com/resources/dns-leak/

The Outline Server runs on a Linux server. You use Outline’s Server Manager program to create the Outline Server configuration. The Manager application comes with pre-configured setups for Google Cloud Platform, Azure Web Services and DigitalOcean. While that’s nice, I will focus in this article on installing Outline on an online Linux machine that you yourself manage – any Linux cloud server, VPS or even your machine at home will do.
No commercial VPN offering will be as secure as the one that you run and control yourself! And if you wonder about the quality of the Outline source code – Jigsaw had their code audited twice, by Radically Open Security (in 2017) and Cure53 (in 2018) and you can read their reports online.

Outline Clients are available for Windows, Android, Linux, macOS and iOS. The client is what sets up the VPN connection to an Outline Server.

Use your own online VPS

Or any other kind of online subscription really. I am happy with the price, feature set and performance of the small dedicated servers offered by online.net aka scaleway. Especially the unmetered 1 Gbps connectivity is important when you want to offer a proxy server to accommodate your users’ secure internet access.
Your linux server needs to be able to run Docker, the light-weight containerization program. For obvious reasons, I will assume that your server is running Slackware, and you’ll have to install a couple of packages first through slackbuilds.org.

Setting up your Slackware server

The Outline Server runs as a docker container. We need to install docker first because it is not a standard offering in the Slackware distro.
Docker has a set of dependencies which we also need to install first: tini, google-go-lang, docker-proxy, libseccomp, runc and containerd.

To make our life easier, we will use sbopkg to manage building and installing these packages from the slackbuilds.org scripts.
If you did not yet install sbopkg, download and install it now (the current version of sbopkg may differ from the package version in the example below):

# wget https://github.com/sbopkg/sbopkg/releases/download/0.38.1/sbopkg-0.38.1-noarch-1_wsr.tgz
# installpkg sbopkg-0.38.1-noarch-1_wsr.tgz

If you are running Slackware-current instead of a stable release like 14.2, then you need to edit the following two files before you run sbopkg for the first time:

# vi /etc/sbopkg/sbopkg.conf
# vi /usr/sbin/sqg

… and change the lines:

REPO_NAME=${REPO_NAME:-SBo}
REPO_BRANCH=${REPO_BRANCH:-14.2}

to:

REPO_NAME=${REPO_NAME:-SBo-git}
REPO_BRANCH=${REPO_BRANCH:-current}

When that’s been taken care of, we need to initialize the local sbopkg database by letting it clone the git repository of slackbuilds.org. Next we run the SlackBuild Queuefile Generator (sqg) script which is part of the sbopkg package. The sqg script examines the “.info” files of the complete slackbuilds.org locally downloaded copy. It uses the dependency information inside these info files to generate “queue files”. A queue file contains the list of packages which have to be built before the actual program you are interested in… aka “the dependencies”. This saves us from reading these info files ourselves to find out what it is that we need to build and in what order.

# sbopkg -r
# sqg -a

After you have initialized the sbopkg program this way, you could now simply run:

# sbopkg -k -i docker

And that should compile and install all the docker dependencies (skipping those packages that are already installed to avoid duplicate effort) and finally, also the docker package.
There’s a snag however… when you install the “google-go-lang” package, it is not ready for use yet. The google-go-lang package installs a profile script “/etc/profile.d/go.sh” which is essential to compile the “runc” and “containerd” packages. So, we cut the compilation in two halves and run the “go.sh” script in between:

# sbopkg -k -i google-go-lang
# source /etc/profile.d/go.sh
# sbopkg -k -i docker

Note that sbopkg checks whether a queuefile exists with the name of the program you attempt to compile. Therefore you will be asked the question whether you want to compile just the “docker” SlackBuild script or the “docker” queuefile. You must select “Queuefile (Q)”.

Assuming the compilation runs error-free you end up with a batch of packages which sbopkg will automatically have installed for you. If you want to save these packages for re-use, you will find them in the “/tmp” directory or whatever your $TMP variable points to. Save them to a less volatile location.

When the packages are installed, we still do not have a system which runs Docker containers automatically. So we add the following block of script code to the file “/etc/rc.d/rc.local” – this causes the Docker daemon to start automatically on every boot:

if [ -x /etc/rc.d/rc.docker ]; then
  # Start Docker daemon
  echo "Starting Docker Daemon: /etc/rc.d/rc.docker start"
  /etc/rc.d/rc.docker start
fi

And to achieve a proper shutdown of your Docker containers when you want to shutdown your server, add the following code block to the file “/etc/rc.d/rc.local_shutdown” – note that this file does not exist by default on a Slackware server, so you may have to create the file “/etc/rc.d/rc.local_shutdown” first, and make it executable:

if [ -x /etc/rc.d/rc.docker ]; then
  # Stop Docker daemon
  echo "Stopping Docker Daemon: /etc/rc.d/rc.docker stop"
  /etc/rc.d/rc.docker stop
fi

We will start docker manually this one time, because I do not want to reboot:

 # /etc/rc.d/rc.docker start

This ends the Slackware server preparation for Outline.

Setting up the Outline server

The Outline website offers downloads for the Outline Manager. This software sets up and manages your Outline VPN server and it also generates the access keys that a computer or smartphone needs in order to connect with your Outline Server. You’ll generate separate access keys for every user of your Outline server. Never share a key with more than one user or they will be able to see the other’s online activity and all data!
Outline Manager is available as a Windows or MacOS binary and a Linux AppImage. We’ll proceed to download the variant which suits our OS:

Again, I guess it is logical that I downloaded the Linux AppImage because my laptop runs Slackware 🙂
Start the binary after making it executable:

alien@hogan:~$ chmod +x ~/Downloads/Outline-Manager.AppImage
alien@hogan:~$ ~/Downloads/Outline-Manager.AppImage
(electron) 'getName function' is deprecated and will be removed. Please use 'name property' instead.
Outline Manager is starting
Launching web app from outline://web_app/index.html?version=1.3.0&sentryDsn=https%3A%2F%2F533e56d1b2d64314bd6092a574e6d0f1%40sentry.io%2F215496
(node:13952) ProtocolDeprecateCallback: The callback argument of protocol module APIs is no longer needed.
(node:13952) ProtocolDeprecateCallback: The callback argument of protocol module APIs is no longer needed.
Checking for update
Generated new staging user ID: 7d7c2930-c574-5d3f-afd9-20401310d20f
Update for version 1.3.0 is not available (latest version: 1.3.0, downgrade is disallowed).

.. and the GUI appears:

The first screen in the Outline Manager offers four choices in setting up an Outline Server. If you already have a paid account with DigitalOcean, Google Cloud Platform or Azure Web Services, you can click the corresponding square and you’ll have a server setup in no time. As I saiod before, I am more interested in a self-hosted VPN on a server which I control. So click the fourth square labeled “Set up Ouline anywhere”  and this brings us to the second screen:

This shows a two-stage approach: the first box shows a command we need to run on a server we control; the command will download and prep an Outline Docker container. You’ll notice below that “Shadowbox” is started, this is the ShadowSocks server which is the actual proxy implementation. Additionally a “Watchtower” is started, this is a service which will keep your Outline Docker container updated automatically with security/bugfixes and new features.

At the end of the setup, a unique configuration string will be emitted which we then have to enter in the Manager‘s input field as proof that we control the server. This is what that looks like:

alien@server:~$ sudo bash -c "$(wget -qO- https://raw.githubusercontent.com/Jigsaw-Code/outline-server/master/src/server_manager/install_scripts/install_server.sh)"
> Verifying that Docker is installed .......... OK
> Verifying that Docker daemon is running ..... OK
> Creating persistent state dir ............... OK
> Generating secret key ....................... OK
> Generating TLS certificate .................. OK
> Generating SHA-256 certificate fingerprint .. OK
> Writing config .............................. OK
> Starting Shadowbox .......................... OK
> Starting Watchtower ......................... OK
> Waiting for Outline server to be healthy .... OK
> Creating first user ......................... OK
> Adding API URL to config .................... OK
> Checking host firewall ...................... OK

CONGRATULATIONS! Your Outline server is up and running.

To manage your Outline server, please copy the following line (including curly
brackets) into Step 2 of the Outline Manager interface:

{"apiUrl":"https://xx.xx.xx.xx:yyyyy/zzzzzzzzzzzzzzzzzz","certSha256":"e4888ec20b2302bcec440655e515625de7a9b6dfe180d7ecd54791a644a6ae32"}

If you have connection problems, it may be that your router or cloud provider
blocks inbound connections, even though your machine seems to allow them.

Make sure to open the following ports on your firewall, router or cloud provider:
- Management port yyyyy, for TCP
- Access key port bbbbb, for TCP and UDP

These last two lines mention the (randomly chosen during installation) TCP and UDP ports which are used by the Outline Server. If your online server is firewalled (and it should be… if not, go to http://www.slackware.com/~alien/efg and generate a firewall configuration stat) you need to open these TCP & UDP ports in your firewall before pasting the red line into your Outline Manager window.

If the firewall is OK, and you enter the above red line, then the Manager will contact the Server to validate the setup. And once that succeeds, you’re all set!

The Outline Manager window will look like below with a configured Outline Server. One single access key has already been generated for you as part of the server installation, and you can add more. You can also revoke keys that you shared and that are in use by people you don’t trust, and you see the amounts of data traffic each user consumes (but you can not see the actual content):

Install an Outline Client

On your computer you can download and install an Outline Client from the getoutline.org web site, for your phone you can get the Outline app from the respective Store. The Linux Outline Client is offered as an AppImage similar to the Manager application, and it runs on Slackware:

   
The client needs an access key so it knows where to connect and how to authenticate. An access key is nothing more than a URI which starts with “ss://

As a server administrator, you use the Outline Manager application to create and share these access keys with your prospective users in a secure manner – by using a chat app with end-to-end encryption or encrypted emails for instance. The Access key contains the IP address of your server, not a hostname, so that DNS lookups are not needed to make the initial connection.

After connecting the Client to the Server and establishing a VPN tunnel (or rather a sophisticated encrypted proxy setup), all subsequent DNS queries (and the rest of your online requests) are tunneled to the Outline Server.
And once the access key is loaded into the Client, all you need to setup a VPN at any time is just to open the application and press the big “Connect” button.

Summarizing

I hope this article helps some groups of people or organizations in non-free countries to re-gain their access to sources of uncensored information. The Outline VPN software is Open Source, free to use and security-audited. There’s a (small) cost involved to run an online Linux server – either a cheap Virtual Private Server (VPS) or a real server in a network you control. Take good care to rent a server with a generous monthly bandwidth plan to avoid unexpected high cost afterwards. Online.net offers servers with unlimited bandwidth for instance.

Good luck out there!
Eric

 

Last week’s package harvest and more

Last week I made my build server at home churn through a lot of packages, let me summarize what became available recently in my slackbuilds repository:

  • I added ‘NetworkManager-openvpn‘ which is a plugin for NM adding support for OpenVPN connections. I needed this for myself since I recently started using the services of Private Internet Access (PIA). All I needed in addition was the ZIP file with OpenVPN configurations. If you need more instructions about how to setup the PIA VPN let me know and I will wrote some more about that. I also added this plugin to my PLASMA5 Live Edition.
  • I upgraded ‘Handbrake‘ to 1.0.3 which also fixed the libvpx library error on -current.
  • I updated the Flash Player plugins for Mozilla and Chromium browsers to 25.0.0.127 (this is a security update).
  • I updated Chromium and its Widevine plugin to 57.0.2987.98. There is a slightly newer release out already but that will have to wait a bit.
  • I updated LibreOffice to 5.3.1 (packages for -current only but I will build them for 14.2 too).

I did more than that; I also updated the front page of my ‘bear’ server with the information that you can access it over secure HTTP (https), and added a link to my post about the CACert issue with Mozilla and Google browsers. Furthermore I added more detail about the dynamically generated ISOs for Slackware-current (the installation DVD and the Live Edition).

I will spend my next post writing about the new KDE 5_17.03 edition which I uploaded to my ‘ktown’ repository, but let me mention here that I already uploaded a new PLASMA5 variant of the Slackware Live Edition which contains a “work in progress” version of this new Plasma 5 release (work in progress because I decided to add more packages later). I did not mention that in any previous post.
Along with that Plasma 5 Live ISO I also uploaded a variant containing the very fresh MATE 1.18 (thanks to Willy for providing me with the tried & tested packages). So there is enough to play with 🙂
I am actually considering a new spin of the PLASMA5 Live ISO because it allows me to offer the complete KDE-5_17.03 including the Kdenlive non-linear video editor in the Live OS, along with the latest LibreOffice.

Enough for now, check out my follow-up post for the news about my new Plasma 5 ‘ktown’ release.

Have fun! Eric

© 2026 Alien Pastures

Theme by Anders NorenUp ↑