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):
# Add the tap
brew tap cloudnetip/tap
# Install CLI only
brew install cloudnetip-spn
# Install GUI + CLI (recommended)
brew install --cask cloudnetip-spnThe 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:
brew update
brew reinstall --formula cloudnetip/tap/cloudnetip-spn
brew reinstall --cask --force cloudnetip/tap/cloudnetip-spnLinux
Build from source:
# 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 installThe 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:
- Install WireGuard for your platform
- Download the
.conffile from the SPN portal - 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):
# Open the browser, pick your SPN account, config is saved automatically
netip-spn auth loginWhat happens:
- The CLI launches your browser at cloudnetip.com/app/shared/authorize.
- You choose which SPN to connect to in the web UI.
- The WireGuard config is saved:
- macOS:
/Library/Application Support/Cloudnetip SPN/spn.conf(root:wheel, mode600). macOS asks for an administrator password when the protected config is installed or replaced. - Linux:
~/.cloudnetip/spn.conf(mode600).
- macOS:
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.
# Remove the saved config
netip-spn auth logoutOn 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:
# Install config with file picker
netip-spn config
# Or specify path directly
netip-spn config ~/Downloads/spn.confThe 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
# Bring tunnel up (requires sudo)
netip-spn connectThe 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
# Check tunnel state (no sudo needed)
netip-spn statusDisconnect
# Bring tunnel down
netip-spn disconnectGUI 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
- Launch
Cloudnetip SPN.appfrom Applications. - Click the menubar icon.
- Choose Sign In or Choose config. macOS asks for an administrator password to install the configuration as
/Library/Application Support/Cloudnetip SPN/spn.conf. - Click Connect. On the first connection, macOS asks once for an administrator password to install the bundled WireGuard runtime and the minimal passwordless helper.
- Future Connect and Disconnect actions do not ask for a password unless the bundled WireGuard runtime changes.
Configuration Files
macOS
| Path | Purpose |
|---|---|
/Library/Application Support/Cloudnetip SPN/spn.conf | Active 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-spn | Narrow NOPASSWD rules for GUI check, up, and down only |
~/Library/Logs/Cloudnetip SPN/wireguard.log | GUI connection log |
~/Library/Logs/Cloudnetip SPN/update.log | Homebrew update log |
/var/run/netip-spn/ | Temporary root-owned runtime state while a tunnel is active |
/var/run/wireguard/wg-netip.name | Current WireGuard utun interface marker |
Linux
| Path | Purpose |
|---|---|
~/.cloudnetip/spn.conf | Saved WireGuard config (mode 600) |
/var/run/netip-spn/wg-netip.conf | Temporary sanitized config passed to wg-quick while connected |
/var/run/wireguard/wg-netip.name | Current WireGuard interface marker |
The client uses standard WireGuard configuration format. Example:
[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 = 25On 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:
# 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 || truenetip-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:
brew untap cloudnetip/tapLinux
If the CLI was installed with sudo make install:
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:
# 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:
sudo wg show
netip-spn statusPermission 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:
netip-spn sudoers checkThe CLI still requires wg-quick and sudo:
# macOS CLI
brew install wireguard-tools
# Debian/Ubuntu CLI
sudo apt install wireguard-toolsConfig Not Found
Check the platform-specific config path:
# macOS
sudo ls -l "/Library/Application Support/Cloudnetip SPN/spn.conf"
# Linux
ls -l ~/.cloudnetip/spn.confRe-save the config with:
netip-spn config ~/path/to/your/spn.confForce 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:
sudo "/Library/PrivilegedHelperTools/cloudnetip-spn/helper" _privileged downIf the GUI/helper crashed and the Cloudnetip DNS entry remains registered, remove it manually:
printf 'remove State:/Network/Service/cloudnetip-spn/DNS\nquit\n' \
| sudo /usr/sbin/scutil
sudo /usr/bin/dscacheutil -flushcache
sudo /usr/bin/killall -HUP mDNSResponderAs a last resort, if the bundled wireguard-go process itself is stuck, terminate only the Cloudnetip copy:
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:
sudo wg-quick down /var/run/netip-spn/wg-netip.confAfter cleanup you can run netip-spn connect again.