Fortinet VPN with Docker: Setup Guide
Overview of Architecture
openfortivpn-webview(Host): Electron app that opens Microsoft SAML/SSO login, handles MFA, and captures theSVPNCOOKIE.openfortivpn(Docker): Lightweight ubuntu container that creates the actualppp0VPN network tunnel using the captured cookie.
Step 1: Directory Structure
Set up your workspace with the following file structure:
fortinet-docker-vpn/
├── Dockerfile.alpine
├── Dockerfile.ubuntu
├── config
├── openfortivpn-connect.sh
└── openfortivpn-webview/ (Cloned automatically by script)
Dockerfile.ubuntu
FROM ubuntu:latest
# Update repositories and install dependencies using apt
RUN apt-get update && apt-get install -y \
openfortivpn \
ppp \
ca-certificates \
iproute2 \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /home/admin/docker/openfortivpn
COPY config /home/admin/docker/openfortivpn/config
ENTRYPOINT ["openfortivpn", "-c", "/home/admin/docker/openfortivpn/config"]
Dockerfile.alpine
FROM alpine:latest
# Install openfortivpn and network dependencies
RUN apk add --no-cache \
--repository=https://dl-cdn.alpinelinux.org/alpine/edge/testing \
--repository=https://dl-cdn.alpinelinux.org/alpine/edge/community \
--repository=https://dl-cdn.alpinelinux.org/alpine/edge/main \
openfortivpn ppp ca-certificates iproute2
WORKDIR /home/admin/docker/openfortivpn
# Copy config into container
COPY config /home/admin/docker/openfortivpn/config
# Launch openfortivpn using local config
ENTRYPOINT ["openfortivpn", "-c", "/home/admin/docker/openfortivpn/config"]
Step 2: Create Configuration Files
File 1: config
Create a file named config in your project folder:
# Fortinet Gateway Address & Port
host = vpn.dawsoncollege.qc.ca
port = 10443
username = username@dawaoncollege.qc.ca #email
#Password = # Optional
# (Optional) Insert trusted certificate hash if prompted by gateway:
# trusted-cert = 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
Step 3: Create the Master Automation Script (openfortivpn-connect.sh
#!/bin/bash
set -e
#set -x
# Work strictly relative to script location
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$SCRIPT_DIR"
VPN_HOST="vpn.dawsoncollege.qc.ca:10443"
#IMAGE_NAME="fortinet-vpn"
#WEBVIEW_DIR="/home/admin/docker/openfortivpn/openfortivpn-webview/openfortivpn-webview-electron"
WEBVIEW_DIR="$SCRIPT_DIR/openfortivpn-webview/openfortivpn-webview-electron"
# 0. Distro Selection (Interactive prompt if no argument provided)
CHOICE="$1"
if [ -z "$CHOICE" ]; then
echo "=========================================="
echo " Select Docker Distro Image"
echo " REMEMBER TO CLOSE THE BROWSER WINDOW "
echo " TO CONTINUE WITH THE SCRIPT PROCESS "
echo "=========================================="
PS3="Please enter your choice (1-2): "
options=("alpine" "ubuntu")
select opt in "${options[@]}"; do
case $opt in
"alpine"|"ubuntu")
CHOICE="$opt"
break
;;
*)
echo "Invalid option $REPLY. Please choose 1 or 2."
;;
esac
done
echo ""
fi
case "$CHOICE" in
alpine)
DOCKERFILE="Dockerfile.alpine"
IMAGE_NAME="fortinet-vpn:alpine"
;;
ubuntu)
DOCKERFILE="Dockerfile.ubuntu"
IMAGE_NAME="fortinet-vpn:ubuntu"
;;
*)
echo "Error: Unknown target distro '$CHOICE'. Use 'alpine' or 'ubuntu'."
exit 1
;;
esac
# 0. Distro Selection (Defaults to 'alpine', accepts 'ubuntu' as argument: ./openfortivpn-connect.sh ubuntu)
#CHOICE="${1:-alpine}"
#case "$CHOICE" in
# alpine)
# DOCKERFILE="Dockerfile.alpine"
# IMAGE_NAME="fortinet-vpn:alpine"
# ;;
# ubuntu)
# DOCKERFILE="Dockerfile.ubuntu"
# IMAGE_NAME="fortinet-vpn:ubuntu"
# ;;
# *)
# echo "Error: Unknown target distro '$CHOICE'. Use 'alpine' or 'ubuntu'."
# exit 1
# ;;
#esac
echo "=========================================="
echo " Fortinet SSO VPN Automated Launcher "
echo "=========================================="
# 1. Verify Prerequisites
echo "[1/4] Checking host dependencies..."
for cmd in docker node npm git; do
if ! command -v $cmd &> /dev/null; then
echo "Error: '$cmd' is not installed. Please install it first."
exit 1
fi
done
# Check PPP device
if [ ! -e /dev/ppp ]; then
echo "Setting up /dev/ppp..."
sudo mknod /dev/ppp c 108 0 2>/dev/null || true
sudo chmod 666 /dev/ppp 2>/dev/null || true
fi
# 2. Check/Build Docker Image
echo "[2/4] Checking Docker image '$IMAGE_NAME' (using $DOCKERFILE)..."
if ! docker image inspect "$IMAGE_NAME" >/dev/null 2>&1; then
echo "Docker image not found. Building $IMAGE_NAME from $SCRIPT_DIR..."
if [ ! -f "$SCRIPT_DIR/$DOCKERFILE" ] || [ ! -f "$SCRIPT_DIR/config" ]; then
echo "Error: Missing '$DOCKERFILE' or 'config' in $SCRIPT_DIR."
exit 1
fi
#/home/admin/docker/openfortivpn
docker build -f "$SCRIPT_DIR/$DOCKERFILE" -t "$IMAGE_NAME" "$SCRIPT_DIR"
else
echo "Docker image '$IMAGE_NAME' is ready."
fi
# 3. Setup openfortivpn-webview
echo "[3/4] Preparing SAML authenticator..."
if [ ! -d "$WEBVIEW_DIR" ]; then
echo "Cloning openfortivpn-webview repository..."
git clone https://github.com/gm-vm/openfortivpn-webview.git "$WEBVIEW_DIR"
cd "$WEBVIEW_DIR"
npm install
cd ..
else
# Ensure dependencies are installed
if [ ! -d "$WEBVIEW_DIR/node_modules" ]; then
echo "Installing webview dependencies..."
cd "$WEBVIEW_DIR"
npm install
cd ..
fi
fi
# 4. Authenticate & Extract Cookie
echo "[4/4] Launching SSO Browser window. Please log in..."
cd "$WEBVIEW_DIR"
# Capture webview output to isolate the SVPNCOOKIE value
RAW_COOKIE=$(npx electron . "$VPN_HOST" --keep-open 2>&1 | grep -oP 'SVPNCOOKIE=\K[^\s]+' | tail -n 1)
cd ..
if [ -z "$RAW_COOKIE" ]; then
echo "Error: Failed to capture SVPNCOOKIE. Did authentication complete?"
exit 1
fi
echo ""
echo "=========================================="
echo " Authentication successful!"
echo " Starting VPN Tunnel..."
echo " Press Ctrl+C to disconnect."
echo "=========================================="
echo ""
# 5. Launch Docker VPN
docker run --rm -it \
--cap-add=NET_ADMIN \
--device=/dev/ppp \
--net=host \
"$IMAGE_NAME" --cookie="$RAW_COOKIE"
Make it executable once:
chmod +x openproxyvpn-connect.sh
Step 4: Daily Operational Commands
Connect
./openfortivpn.sh
Disconnect
Press Ctrl + C in the terminal running the script.
Reset Stale/Saved SSO Sessions (Force Fresh Login)
If you get stuck on “Already Logged In” or need to switch accounts, clear Electron’s session cache:
# On Linux:
rm -rf ~/.config/openfortivpn-webview
# On macOS:
rm -rf ~/Library/Application\ Support/openfortivpn-webview