Skip to content

Instantly share code, notes, and snippets.

@bouroo
Last active May 12, 2025 03:54
Show Gist options
  • Save bouroo/30ea2e3ce065d47a44e580093aa21bb3 to your computer and use it in GitHub Desktop.
Save bouroo/30ea2e3ce065d47a44e580093aa21bb3 to your computer and use it in GitHub Desktop.
Install softether vpn server on ubuntu 16.04+
#!/usr/bin/env bash
# SoftEther VPN Server Installer Script
# Register vultr.com with free credit https://www.vultr.com/?ref=9206731-8H
# Create VPS
# Tested on Ubuntu 18.04, Debian 10.0
# Instructions:
# 1. Save this file as softether-installer.sh
# 2. chmod +x softether-installer.sh
# 3. Run: ./softether-installer.sh or bash softether-installer.sh
# 4. Initialize VPN server config: /usr/local/vpnserver/vpncmd
# 5. Set server password: ServerPasswordSet {yourPassword}
# 6. Use SoftEther VPN Server Manager to manage your server
# 7. Load your own certificate if you have one.
set -euo pipefail
# --- Configuration ---
INSTALL_DIR="/usr/local/vpnserver"
BACKUP_DIR="/usr/local/vpnserver_bak"
SYSTEMD_SERVICE_PATH="/etc/systemd/system/vpnserver.service" # Use /etc/systemd/system for local units
# --- Main Script ---
echo "Starting SoftEther VPN Server installation..."
# Check for root privileges
if [ "$(id -u)" -ne 0 ]; then
echo "Error: This script must be run as root." >&2
exit 1
fi
# Update package list and install dependencies
# Use -qq for quieter output. Install necessary packages.
echo "Updating package list and installing dependencies..."
apt update -qq
apt install -yqq build-essential wget curl gcc make tzdata git libreadline-dev libncurses-dev libssl-dev zlib1g-dev
# Fetch latest stable version URL
# Uses the /latest release URL and parses for the tarball link.
echo "Fetching latest SoftEther VPN version..."
SOFTETHER_VERSION=$(curl -s https://github.com/SoftEtherVPN/SoftEtherVPN_Stable/releases/latest | \
grep -oP 'vpnserver-v[0-9]+\.[0-9]+\.[0-9]+.*?linux-x64-64bit\.tar\.gz' | \
head -1 | \
sed 's/^vpnserver-//;s/-linux-x64-64bit\.tar\.gz$//')
if [ -z "$SOFTETHER_VERSION" ]; then
echo "Error: Could not determine the latest SoftEther VPN version." >&2
exit 1
fi
echo "Found version: $SOFTETHER_VERSION"
DOWNLOAD_URL="https://github.com/SoftEtherVPN/SoftEtherVPN_Stable/releases/download/${SOFTETHER_VERSION}/vpnserver-${SOFTETHER_VERSION}-linux-x64-64bit.tar.gz"
# Create a temporary directory for download
TEMP_DIR=$(mktemp -d)
DOWNLOAD_PATH="${TEMP_DIR}/softether-vpnserver.tar.gz"
# Download SoftEther source
echo "Downloading SoftEther VPN from ${DOWNLOAD_URL}..."
if ! wget "${DOWNLOAD_URL}" -O "${DOWNLOAD_PATH}"; then
echo "Error: Download failed." >&2
rm -rf "${TEMP_DIR}"
exit 1
fi
# Stop service if running
echo "Stopping existing vpnserver service (if running)..."
# Check if the service is active before attempting to stop
systemctl is-active --quiet vpnserver && systemctl stop vpnserver
# Backup existing installation if it exists
if [ -d "${INSTALL_DIR}" ]; then
echo "Backing up existing installation to ${BACKUP_DIR}..."
# Remove previous backup first for a clean backup
if [ -d "${BACKUP_DIR}" ]; then
echo "Removing previous backup directory ${BACKUP_DIR}..."
rm -rf "${BACKUP_DIR}"
fi
if ! mv "${INSTALL_DIR}" "${BACKUP_DIR}"; then
echo "Warning: Failed to backup existing installation. Proceeding with caution." >&2
# Do not exit, try to continue installation
fi
fi
# Extract SoftEther source
echo "Extracting SoftEther VPN to ${INSTALL_DIR}..."
if ! mkdir -p "${INSTALL_DIR}" || ! tar -xzvf "${DOWNLOAD_PATH}" -C "${INSTALL_DIR}"; then
echo "Error: Extraction failed." >&2
rm -rf "${TEMP_DIR}"
exit 1
fi
# Restore configuration file from backup if it exists
if [ -f "${BACKUP_DIR}/vpn_server.config" ]; then
echo "Restoring configuration file from backup..."
if ! cp "${BACKUP_DIR}/vpn_server.config" "${INSTALL_DIR}/vpn_server.config"; then
echo "Warning: Failed to restore configuration file from backup." >&2
# Do not exit, continue installation
else
# Optionally remove the backup after successful restore
echo "Removing backup directory ${BACKUP_DIR}..."
rm -rf "${BACKUP_DIR}"
fi
fi
# Clean up the downloaded tarball and temporary directory
echo "Cleaning up temporary files..."
rm -rf "${TEMP_DIR}"
# Build SoftEther
echo "Building SoftEther VPN..."
pushd "${INSTALL_DIR}" >/dev/null # Change directory silently
if ! ./configure || ! make; then
echo "Error: Build failed." >&2
popd >/dev/null # Return to previous directory silently
exit 1
fi
# Perform final installation steps (permissions, etc.) - as per original script's make install
echo "Performing final installation steps..."
# The 'make install' target in SoftEther's Makefile often just sets permissions or is a placeholder.
# Keeping it to match the original script's logic.
if ! make install; then
echo "Error: make install failed." >&2
popd >/dev/null
exit 1
fi
popd >/dev/null # Return to previous directory
# Set file permissions
echo "Setting file permissions..."
chmod 0600 "${INSTALL_DIR}"/*
chmod +x "${INSTALL_DIR}/vpnserver" "${INSTALL_DIR}/vpncmd"
# Add systemd service
echo "Creating systemd service unit file at ${SYSTEMD_SERVICE_PATH}..."
cat <<EOF >"${SYSTEMD_SERVICE_PATH}"
[Unit]
Description=SoftEther VPN Server
After=network.target auditd.service
ConditionPathExists=!${INSTALL_DIR}/do_not_run
[Service]
Type=forking
# NOTE: EnvironmentFile=-${INSTALL_DIR} expects a file named exactly "${INSTALL_DIR}"
# containing environment variables. This is an unusual path for an environment file.
# Keeping this to match the original script's behavior.
EnvironmentFile=-${INSTALL_DIR}
ExecStart=${INSTALL_DIR}/vpnserver start
ExecStop=${INSTALL_DIR}/vpnserver stop
KillMode=process
Restart=on-failure
PrivateTmp=yes
ProtectHome=yes
ProtectSystem=full
ReadOnlyDirectories=/
ReadWriteDirectories=-${INSTALL_DIR}
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW CAP_SYS_NICE CAP_SYS_ADMIN CAP_SETUID
[Install]
WantedBy=multi-user.target
EOF
# Reload systemd, enable and start the service
echo "Reloading systemd, enabling and starting the service..."
systemctl daemon-reload
systemctl enable vpnserver
systemctl restart vpnserver
echo "SoftEther VPN Server installation complete."
echo ""
echo "Next steps:"
echo "1. Initialize VPN server config: ${INSTALL_DIR}/vpncmd"
echo "2. Set server password using 'ServerPasswordSet {yourPassword}' in vpncmd."
echo "3. Use SoftEther VPN Server Manager to manage your server."
echo "4. Load your own certificate if you have one."
exit 0
@bouroo
Copy link
Author

bouroo commented Nov 12, 2019

@mikeevans82 thx, just fixed that line.

@mikeevans82
Copy link

@bouroo I tested your edit on line 59 and it still produces a "permission denied" error for me when running as a normal user. I believe the problem is that ">" is interpreted by the current bash shell, which is not being elevated by sudo. In your script, bash needs to be elevated to create a file in /lib/... but your sudo command is being applied to cat instead. In my solution "sudo bash -c" runs the command with an elevated(super user) bash process.

@cptafx
Copy link

cptafx commented Aug 11, 2022

Tested and works with Ubuntu 22.04.1 LTS @ Vultr VPS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment