Skip to content

Shared Private Network (SPN) ​

Concept ​

The Shared Private Network (SPN) is a secure infrastructure for creating a unified interaction space between servers, services, and developers. It is implemented using VPN technologies, providing secure and convenient data exchange as well as centralized access management.

Key principles
  • Security: all data is transmitted over an encrypted channel.
  • Ease of connection: employees and services connect via a single access point in accordance with company policies.
  • Management flexibility: support for changing gateways, subnets, and DNS.
  • Integration: ability to link user and node management with existing internal systems.

Benefits ​

  • A unified network map including nodes, gateways, and subnets. Allows viewing the current state of the infrastructure and managing connection parameters.

  • A visual network map showing active connections, node status, and routes. Useful for monitoring and quickly identifying issues.

  • A network management module via the SPN API, which enables integration with internal personnel and infrastructure management systems.

  • Ability to switch a node gateway (e.g., for load balancing or failover) and reconfigure subnets.

DNS ​

An internal DNS record system accessible only to employees when connected to the private network. Used for:

  • convenient access to services and nodes by name
  • configuring unified routing and name resolution rules for employees (developers)

SPN Client ​

The SPN client (github.com/cloudnetip/netip-spn) is a WireGuard-based tool for connecting to the Shared Private Network. It provides a CLI for macOS and Linux, plus a native menubar GUI app for macOS.

Installation ​

macOS ​

Install via Homebrew (recommended):

bash
# Add the tap
brew tap cloudnetip/tap

# Install CLI only
brew install cloudnetip-spn

# Install GUI + CLI (recommended)
brew install --cask cloudnetip-spn

The cask installs Cloudnetip SPN.app in /Applications and installs the netip-spn CLI through the Homebrew formula.

The macOS GUI carries its own pinned WireGuard runtime (wg + wireguard-go). On the first GUI connection, or when that runtime changes in a later release, macOS asks for an administrator password and installs a protected root-owned copy in /Library/PrivilegedHelperTools/cloudnetip-spn/. Subsequent GUI Connect/Disconnect actions do not require a password until the bundled WireGuard runtime changes again.

The CLI remains independent from the GUI runtime and uses wg-quick from wireguard-tools. Homebrew installs that dependency automatically with the CLI formula.

To update, open About Cloudnetip SPN. The app checks the Homebrew version in the background and shows Update to new version X.Y.Z when either the GUI or CLI differs from the published Homebrew version. The update runs through Homebrew and restarts the GUI automatically.

You can also update manually:

bash
brew update
brew reinstall --formula cloudnetip/tap/cloudnetip-spn
brew reinstall --cask --force cloudnetip/tap/cloudnetip-spn

Linux ​

Build from source:

bash
# Install dependencies
sudo apt install wireguard-tools zenity   # Debian/Ubuntu
# or equivalent for your distribution

# Clone and build
git clone https://github.com/cloudnetip/netip-spn.git
cd netip-spn
make build && sudo make install

The GUI is macOS-only. On Linux, use the CLI directly or create a .desktop launcher.

Other Systems ​

For Windows, Android, iOS, and other platforms, use the official WireGuard client.

Download your SPN configuration file from cloudnetip.com/app/shared and import it into the WireGuard application:

  1. Install WireGuard for your platform
  2. Download the .conf file from the SPN portal
  3. Import the configuration:
    • Windows: Click "Import tunnel(s) from file"
    • Android/iOS: Scan QR code or import file
    • Other: Follow platform-specific import instructions

CLI Usage ​

Sign In ​

The fastest way to get configured is the browser-based sign-in. It uses an OAuth 2.0 authorization-code flow with PKCE over a loopback redirect (RFC 7636 + RFC 8252):

bash
# Open the browser, pick your SPN account, config is saved automatically
netip-spn auth login

What happens:

  1. The CLI launches your browser at cloudnetip.com/app/shared/authorize.
  2. You choose which SPN to connect to in the web UI.
  3. The WireGuard config is saved:
    • macOS: /Library/Application Support/Cloudnetip SPN/spn.conf (root:wheel, mode 600). macOS asks for an administrator password when the protected config is installed or replaced.
    • Linux: ~/.cloudnetip/spn.conf (mode 600).

There is no persistent auth token: the WireGuard config itself is the credential. Re-run auth login at any time to rotate credentials or switch to a different SPN.

bash
# Remove the saved config
netip-spn auth logout

On macOS, removing the protected config requires an administrator password.

Initial Setup (manual config) ​

If you'd rather skip the browser flow, download the config file from cloudnetip.com/app/shared and install it manually:

bash
# Install config with file picker
netip-spn config

# Or specify path directly
netip-spn config ~/Downloads/spn.conf

The config is validated and stored at the same platform-specific path described above. On macOS the installed copy is root-owned and cannot be replaced by an ordinary user process.

Connect to SPN ​

bash
# Bring tunnel up (requires sudo)
netip-spn connect

The CLI uses wg-quick and prompts for your sudo password to configure the WireGuard interface. On macOS this is the Homebrew wireguard-tools installation; the CLI does not use the GUI's bundled WireGuard runtime.

Check Connection Status ​

bash
# Check tunnel state (no sudo needed)
netip-spn status

Disconnect ​

bash
# Bring tunnel down
netip-spn disconnect

GUI Usage (macOS only) ​

The menubar app uses its own bundled WireGuard runtime and a minimal root-owned helper. It does not use Homebrew wg-quick for GUI connections.

Features ​

  • Menubar Icon: Shows connection status at a glance.
  • Traffic in Menubar: Optional two-line upload/download speed display via Show stats in bar.
  • Sign In / Sign Out: Browser-based OAuth login and removal of the saved SPN config.
  • Config Management: Import an existing WireGuard config through the native file picker.
  • Connect / Disconnect: Uses the protected bundled WireGuard runtime.
  • Protected Config: On macOS the active SPN config is root-owned and cannot be replaced by an ordinary user process.
  • Passwordless Connect/Disconnect: The administrator password is required only to install/update the privileged WireGuard runtime, not on every connection.
  • Show Logs: Opens the GUI WireGuard log.
  • Built-in Update Check: About Cloudnetip SPN checks Homebrew asynchronously and can update the GUI and CLI.

First-time Setup ​

  1. Launch Cloudnetip SPN.app from Applications.
  2. Click the menubar icon.
  3. Choose Sign In or Choose config. macOS asks for an administrator password to install the configuration as /Library/Application Support/Cloudnetip SPN/spn.conf.
  4. Click Connect. On the first connection, macOS asks once for an administrator password to install the bundled WireGuard runtime and the minimal passwordless helper.
  5. Future Connect and Disconnect actions do not ask for a password unless the bundled WireGuard runtime changes.

Configuration Files ​

macOS ​

PathPurpose
/Library/Application Support/Cloudnetip SPN/spn.confActive SPN WireGuard config (root:wheel, mode 600)
/Library/PrivilegedHelperTools/cloudnetip-spn/Root-owned GUI helper, wg, wireguard-go, and runtime.version
/etc/sudoers.d/netip-spnNarrow NOPASSWD rules for GUI check, up, and down only
~/Library/Logs/Cloudnetip SPN/wireguard.logGUI connection log
~/Library/Logs/Cloudnetip SPN/update.logHomebrew update log
/var/run/netip-spn/Temporary root-owned runtime state while a tunnel is active
/var/run/wireguard/wg-netip.nameCurrent WireGuard utun interface marker

Linux ​

PathPurpose
~/.cloudnetip/spn.confSaved WireGuard config (mode 600)
/var/run/netip-spn/wg-netip.confTemporary sanitized config passed to wg-quick while connected
/var/run/wireguard/wg-netip.nameCurrent WireGuard interface marker

The client uses standard WireGuard configuration format. Example:

ini
[Interface]
PrivateKey = your-private-key
Address = 10.11.0.2/24
DNS = 10.11.0.1

[Peer]
PublicKey = server-public-key
Endpoint = internal.example.ltd:51820
AllowedIPs = 10.11.0.0/16
PersistentKeepalive = 25

On macOS, use Sign In, Choose config, netip-spn auth login, or netip-spn config to replace the protected configuration. On Linux, the saved ~/.cloudnetip/spn.conf can also be edited directly while disconnected.

Uninstall ​

macOS ​

For a complete removal, disconnect first and quit the menubar app. Then run the following while netip-spn is still installed:

bash
# Remove the protected SPN config
netip-spn auth logout

# Remove the passwordless sudo rule and the root-owned bundled WireGuard runtime/helper
netip-spn sudoers remove

# Remove GUI and CLI
brew uninstall --zap --cask cloudnetip-spn
brew uninstall cloudnetip-spn

# Remove user logs
rm -rf "$HOME/Library/Logs/Cloudnetip SPN"

# Remove the now-empty protected config directory, if present
sudo rmdir "/Library/Application Support/Cloudnetip SPN" 2>/dev/null || true

netip-spn sudoers remove stops the GUI-managed tunnel if necessary and removes /Library/PrivilegedHelperTools/cloudnetip-spn/ together with /etc/sudoers.d/netip-spn.

If the Cloudnetip tap is no longer used by any other package, it can also be removed:

bash
brew untap cloudnetip/tap

Linux ​

If the CLI was installed with sudo make install:

bash
netip-spn disconnect
netip-spn auth logout
sudo rm -f /usr/local/bin/netip-spn
rm -rf "$HOME/.cloudnetip"

Remove wireguard-tools separately only if it is no longer required by another WireGuard setup.

Troubleshooting ​

Connection Issues ​

For a GUI-managed tunnel on macOS:

bash
# Check WireGuard state using the bundled root-owned wg
sudo "/Library/PrivilegedHelperTools/cloudnetip-spn/wg" show

# Inspect the protected config
sudo cat "/Library/Application Support/Cloudnetip SPN/spn.conf"

# Follow the GUI connection log
tail -f "$HOME/Library/Logs/Cloudnetip SPN/wireguard.log"

For CLI connections, use the system/Homebrew WireGuard tools:

bash
sudo wg show
netip-spn status

Permission Issues ​

The macOS GUI asks for an administrator password when it needs to install/update the privileged WireGuard runtime or install/remove the protected config. Normal GUI Connect/Disconnect actions are passwordless after that setup.

Check the GUI helper state with:

bash
netip-spn sudoers check

The CLI still requires wg-quick and sudo:

bash
# macOS CLI
brew install wireguard-tools

# Debian/Ubuntu CLI
sudo apt install wireguard-tools

Config Not Found ​

Check the platform-specific config path:

bash
# macOS
sudo ls -l "/Library/Application Support/Cloudnetip SPN/spn.conf"

# Linux
ls -l ~/.cloudnetip/spn.conf

Re-save the config with:

bash
netip-spn config ~/path/to/your/spn.conf

Force Stop Connection ​

Use this only as an emergency recovery path.

For a macOS GUI connection, first ask the installed privileged helper to perform its normal cleanup. This removes the GUI-managed routes, DNS entry, runtime state, and WireGuard interface:

bash
sudo "/Library/PrivilegedHelperTools/cloudnetip-spn/helper" _privileged down

If the GUI/helper crashed and the Cloudnetip DNS entry remains registered, remove it manually:

bash
printf 'remove State:/Network/Service/cloudnetip-spn/DNS\nquit\n' \
  | sudo /usr/sbin/scutil

sudo /usr/bin/dscacheutil -flushcache
sudo /usr/bin/killall -HUP mDNSResponder

As a last resort, if the bundled wireguard-go process itself is stuck, terminate only the Cloudnetip copy:

bash
sudo pkill -f '/Library/PrivilegedHelperTools/cloudnetip-spn/wireguard-go utun'

If the helper could not complete its cleanup and you had to kill wireguard-go manually, reboot macOS before reconnecting. A hard process kill cannot reliably restore routes when the runtime state is damaged.

For a CLI-managed connection, try the temporary config directly:

bash
sudo wg-quick down /var/run/netip-spn/wg-netip.conf

After cleanup you can run netip-spn connect again.