How to Establish SSH VPN Tunnel Without Root Access: Non-Root TUN/TAP Device Configuration


8 views

When creating SSH-based VPN tunnels using -w for TUN/TAP device forwarding, you'll encounter this common roadblock:

ssh -Nv -w 0:0 user@remotehost
channel 0: open failed: administratively prohibited: open failed

The fundamental limitation stems from Linux kernel requirements. Creating network interfaces (TUN/TAP devices) requires:

  • CAP_NET_ADMIN capability
  • Direct device file access (/dev/net/tun)

Standard users typically lack both privileges, even with sudo access configured.

1. Configure SSH Server for TUN Forwarding

Edit /etc/ssh/sshd_config on the remote server:

PermitTunnel yes
PermitRootLogin no

Then create a dedicated group for VPN users:

sudo groupadd vpnusers
sudo usermod -aG vpnusers yourusername

2. Configure Device Permissions

Create a udev rule (/etc/udev/rules.d/90-vpn.rules):

KERNEL=="tun", NAME="net/tun", MODE="0660", GROUP="vpnusers"

Reload udev rules:

sudo udevadm control --reload-rules
sudo udevadm trigger

3. Grant CAP_NET_ADMIN Capability

For specific users:

sudo setcap cap_net_admin+ep /usr/bin/ssh

Or alternatively using systemd:

# /etc/systemd/system/ssh-vpn.service
[Service]
User=yourusername
Group=vpnusers
AmbientCapabilities=CAP_NET_ADMIN
ExecStart=/usr/bin/ssh -Nv -w 0:0 user@remotehost

Using SSH ProxyCommand

For port forwarding without TUN devices:

ssh -o ProxyCommand="ssh -W %h:%p user@remotehost" user@localhost

Persistent VPN Configuration

Create a reusable configuration in ~/.ssh/config:

Host vpn-tunnel
    HostName remotehost
    User yourusername
    Tunnel ethernet
    PermitLocalCommand yes
    LocalCommand sudo ip link set tun0 up

After implementation, test with:

ssh -v -w 0:0 vpn-tunnel
ip link show tun0

You should see the tunnel interface created without root access errors.


When working with SSH VPN tunnels using -w (TUN/TAP forwarding), many administrators encounter the frustrating "administratively prohibited" error when attempting to create tunnels without root privileges. The fundamental issue stems from how Linux handles network interface creation.

The -w flag in SSH requires:

  1. Creation of network interfaces (requires CAP_NET_ADMIN)
  2. Access to /dev/net/tun device
  3. Proper SELinux/AppArmor permissions if enabled

1. Using sudo with Specific Privileges

Configure sudo to allow specific commands for TUN/TAP access:

# /etc/sudoers
username ALL=(root) NOPASSWD: /usr/bin/ssh -Nv -w *:*

Then execute:

sudo ssh -Nv -w 0:0 username@192.168.2.2 -p 50

2. Permanent CAP_NET_ADMIN Capability

Assign the capability to your SSH binary:

sudo setcap cap_net_admin=ep /usr/bin/ssh

This persists across reboots and allows any user to create tunnels.

3. Systemd-based Approach

Create a service unit with elevated privileges:

# /etc/systemd/system/ssh-tunnel.service
[Unit]
Description=SSH VPN Tunnel

[Service]
User=username
ExecStart=/usr/bin/ssh -Nv -w 0:0 username@192.168.2.2 -p 50
Restart=always
CapabilityBoundingSet=CAP_NET_ADMIN
DeviceAllow=/dev/net/tun rw

[Install]
WantedBy=multi-user.target

Each approach has different security implications:

  • sudo: Provides audit trails but broad command access
  • capabilities: More granular but complex to manage
  • systemd: Most isolated but requires service management

If TUN/TAP isn't strictly required, consider:

# Dynamic SOCKS proxy
ssh -D 1080 username@192.168.2.2 -p 50

# Port forwarding
ssh -L 8080:localhost:80 username@192.168.2.2 -p 50

These alternatives work without special permissions while still providing tunnel functionality.