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:
- Creation of network interfaces (requires CAP_NET_ADMIN)
- Access to
/dev/net/tun
device - 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.