Softether VPN

Softether VPN Remote Access with Duo Multi-Factor Authentication (MFA)

This guide assumes you have a working Softether VPN server configured for remote access along with Active Directory for remote user authentication and a Duo account with your users and their mobile devices pre-enrolled and the Duo app pre-installed and configured for your Duo account.

Please note this MFA implementation ONLY works by utilizing the Duo Mobile app Push Notifications.

If you don't have a Duo account, you can sign up for a free trial on the Duo website. Additionally, you also need to deploy a Duo Authentication Proxy server on your network using Linux or Windows.

This guide specifically focuses on a Duo Authentication Proxy on Linux but it can be easily adapted to a Windows based installation.

If you need to deploy a Softether VPN server you can take a look at our docker compose example to deploy using Docker, Traefik as the reverse proxy and Lets Encrypt support.

Configure Softether Application in Duo Admin Panel

Figure 1

image.png

Figure 2

image.png

Figure 3

image.png

Figure 4

image.png

Create an AD service account to enumerate users in Active Directory

Figure 5

image.png

Configure Duo Authentication Proxy

The Duo Authentication Proxy integrates with the Duo cloud to perform Duo push notifications, integrates with Active Directory to perform user authentication and it also serves as a RADIUS server which Softether utilizes to authenticate users. You could use a separate RADIUS server to integrate with Active Directory and configure Duo Authentication Proxy with it but that's outside the scope of this guide.

If you followed the Duo Authentication Proxy - Reference New Proxy Install for Linux, the proxy gets installed in the /opt/duoauthproxy directory by default. If you did a custom installation, adjust the paths below as necessary.

vi /opt/duoauthproxy/conf/authproxy.cfg
[ad_client]
host=<AD_DOMAIN_CONTROLLER>
service_account_username=<AD_DUO_SERVICE_ACCOUNT_USERNAME>
service_account_password=<AD_DUO_SERVICE_ACCOUNT_PASSWORD>
search_dn=DC=DOMAIN,DC=TLD

[radius_server_auto]
ikey=<DUO_INTEGRATION_KEY>
skey=<DUO_SECRET_KEY>
api_host=<DUO_API_HOSTNAME>
radius_ip_1=<SOFTETHER_VPN_SERVER_IP>
radius_secret_1=<RADIUS_SHARED_SECRET>
failmode=safe
client=ad_client
port=1812

Configure Softether VPN Server

Figure 6

image.png

Figure 7

image.png

Figure 8

image.png

Configure Softether VPN Server Users

When adding users in Softether VPN server to authenticate using Duo MFA, the username that you are adding in Softether VPN MUST match an existing username in the Duo Admin panel.

Figure 9

image.png

Figure 10

image.png

If everything is setup correctly, when this user connects to your Softether VPN they should be prompted by the Duo app on their mobile device to approve the login. There is a hard coded limit of 10 seconds for Softether to wait for authentication to complete. The user must approve the Duo MFA prompt within those 10 seconds or authentication will fail.

Install Softether VPN client on Linux Script

Save the following into a install-softether-vpnclient.sh file and ensure you make it executable (chmod +x install-softether-vpn-client.sh:

#!/usr/bin/env bash
#
# install-softether-client.sh — relocate a built SoftEther VPN *Client* into
# /usr/local/vpnclient, symlink binaries onto PATH, and install a systemd unit.
#
# Usage:  sudo ./install-softether-client.sh /path/to/built/vpnclient
#         (the folder that contains: vpnclient, vpncmd, hamcore.se2)
#
set -euo pipefail

SRC="${1:-}"
DEST="/usr/local/vpnclient"

[ -n "$SRC" ] || { echo "Usage: sudo $0 /path/to/built/vpnclient"; exit 1; }
[ "$(id -u)" -eq 0 ] || { echo "Run with sudo."; exit 1; }

# Validate the source has the pieces that must stay together
for f in vpnclient vpncmd hamcore.se2; do
  [ -e "$SRC/$f" ] || { echo "ERROR: '$SRC' is missing $f — point me at the built vpnclient dir."; exit 1; }
done

echo ">> Installing $SRC -> $DEST"
if [ -e "$DEST" ]; then
  echo ">> $DEST exists; stopping any running client and backing it up."
  "$DEST/vpnclient" stop 2>/dev/null || true
  mv "$DEST" "${DEST}.bak.$(date +%s 2>/dev/null || echo old)" 2>/dev/null || rm -rf "$DEST"
fi

cp -a "$SRC" "$DEST"
chown -R root:root "$DEST"
chmod 700 "$DEST/vpnclient" "$DEST/vpncmd"
chmod 600 "$DEST/hamcore.se2"

echo ">> Symlinking binaries onto PATH (symlinks resolve real path, so hamcore is still found)"
ln -sf "$DEST/vpncmd"    /usr/bin/vpncmd
ln -sf "$DEST/vpnclient" /usr/bin/vpnclient

echo ">> Installing systemd unit: softether-vpnclient.service"
cat > /etc/systemd/system/softether-vpnclient.service <<UNIT
[Unit]
Description=SoftEther VPN Client
After=network-online.target
Wants=network-online.target

[Service]
Type=forking
ExecStart=$DEST/vpnclient start
ExecStop=$DEST/vpnclient stop
Restart=on-failure
RestartSec=3

[Install]
WantedBy=multi-user.target
UNIT

systemctl daemon-reload
systemctl enable --now softether-vpnclient

sleep 2
echo ">> Verifying..."
if vpncmd localhost /CLIENT /CMD About >/dev/null 2>&1; then
  echo "OK — vpncmd can reach the running client service."
  echo "   vpncmd  -> $(readlink -f "$(command -v vpncmd)")"
  systemctl --no-pager --property=ActiveState,SubState show softether-vpnclient | sed 's/^/   /'
else
  echo "WARN: client service not reachable yet. Check: systemctl status softether-vpnclient"
fi

Download the Softether VPN Client for LInux from https://www.softether.org/5-download/ and extract it to a directory of your choice. Then run the script you created above as root (sudo) and point it to the "/vpnclient/ directory of your extracted download:

install-softether-vpnclient.sh /Downloads/softether-vpnclient-v4.44-9807-rtm-2025.04.16-linux-x64-64bit/vpnclient