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
@dimasahmad
Copy link

I think you should edit line 79
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW CAP_SYS_NICE CAP_SYS_ADMIN CAP_SETUID

@mikeevans82
Copy link

mikeevans82 commented Nov 12, 2019

Thanks for this script! I have a few notes on the comments and issues I had.

@Akonova1enko: If you see "Fatal Error: The file "hamcore.se2" is missing or broken." its probably because you are running vpncmd without elevated permissions. Use a root account or sudo.

@amanjuman: If you see "/usr/local/env: bad interpreter: No such file or directory" you need to specify the correct path to env at line one in the script. I'm not sure how this is working for other Ubuntu users. On 18.04 Server I updated the path to /usr/bin/env.

For me /usr/local/env was missing on 18.04 Desktop, 18.04 Server, 19.04 Desktop, and 19.10 Desktop.

@bouroo: I got permission denied on line 59 when running without the sudo command. Replacing it with this fixed it for me:
${SUDO} bash -c 'cat > /lib/systemd/system/vpnserver.service' << EOF

@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