Happy to introduce SSH VPN integration for NetworkManager. The SSH VPN can be used just anywhere!
Basically NetworkManager-ssh integrates OpenSSH tunnel capabilities with NetworkManager and provides you with the easiest of all VPNs, as OpenSSH lives on almost any *nix machine today.
If you're using Fedora 41 or later, you can simply run:
# dnf install NetworkManager-ssh-gnome
If you're using Fedora 41 or later, with KDE Plasma 5 run:
# dnf install NetworkManager-ssh plasma-nm-ssh
That will set you up with NetworkManager and the traditional GNOME interface. I am the current maintainer of the package for Fedora.
On older versions of Fedora or CentOS, you can run the following after cloning the repository:
$ autoreconf -fvi && ./configure && make rpm
Enjoy your new RPM.
On recent Debian/Ubuntu distributions you should be able to install with:
# apt-get install network-manager-ssh
In case you want to build the package for Debian/Ubuntu, you can use the complimentary packaging this repository provides. But please do not open bugs about it on this GitHub issue tracker. The correct thing to do is to use the upstream packages provided with the distribution and open bugs on the distribution issue tracker.
Building a .deb should be straight forward with:
# apt-get install libnm-glib-dev libnm-glib-vpn-dev libnm-util-dev libnm-dev libnma-dev libgnome-keyring-dev dh-autoreconf libgtk-3-dev sshpass
$ autoreconf -fvi && ./configure && make deb
Enjoy your new .deb. (It should show up in the directory you git clone
d from.)
On old distributions with NetworkManager < 0.9.10, such as Ubuntu 14.04, use the 0.9.3 tag:
$ git checkout 0.9.3
$ autoreconf -fvi && ./configure && make deb
A package for Arch is available in the AUR - https://aur.archlinux.org/packages/networkmanager-ssh
Please edit /etc/dbus-1/system.d/org.freedesktop.NetworkManager.conf
and add the line:
<allow send_destination="org.freedesktop.NetworkManager.ssh"/>
Make sure your target host is known in ~/.ssh/known_hosts
.
If it's not there, you should add it manually or by SSHing to it:
$ ssh root@TARGET_HOST
The authenticity of host 'TARGET_HOST' can't be established.
ECDSA key fingerprint is SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.
ECDSA key fingerprint is MD5:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'TARGET_HOST' (ECDSA) to the list of known hosts.
If all went right, you should have a new VPN of type SSH when creating a new VPN.
If you are after a no full tunnel support, you can tick that option in the dialog box. This also allows you to SSH with a non-privileged user. This is handy if you'd like to have one of (or more):
- SOCKS proxy (
-D
) - Local port binding (
-L
) - Remote port binding (
-R
)
When things go wrong and you can't really figure out what's happening, have a look at /var/log/messages
as you spin up the connection.
You should be able to tell what is going wrong.
Even though this is a bit off-topic, I've decided to cover it anyway.
On the server, you'll need to enable in /etc/ssh/sshd_config
:
PermitTunnel=yes
Enable kernel packet forwarding:
# echo 1 > /proc/sys/net/ipv4/ip_forward
In terms of firewall configuration, I recommend looking at the "standard" way of editing firewall rules on your distribution. These however, should work on most GNU/Linux distributions.
Tun devices:
# iptables -I FORWARD -i tun+ -j ACCEPT
# iptables -I FORWARD -o tun+ -j ACCEPT
# iptables -I INPUT -i tun+ -j ACCEPT
# iptables -t nat -I POSTROUTING -o EXTERNAL_INTERFACE -j MASQUERADE
Tap devices:
# iptables -I FORWARD -i tap+ -j ACCEPT
# iptables -I FORWARD -o tap+ -j ACCEPT
# iptables -I INPUT -i tap+ -j ACCEPT
# iptables -t nat -I POSTROUTING -o EXTERNAL_INTERFACE -j MASQUERADE
Please use these firewall rules as a reference only.
Don't forget to replace EXTERNAL_INTERFACE with your WAN interface (eth0, ppp0, etc).
You will need ssh-agent running before you start NetworkManager-ssh.
How do you know if you have ssh-agent running? Simply run:
$ env | grep SSH
SSH_AGENT_PID=16152
SSH_AUTH_SOCK=/tmp/ssh-mGTf3Q1L2oPf/agent.16151
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
You should see something similar to that.
NetworkManager-ssh probes for the ssh-agent that is attached to your session and authenticates with its socket.
Initially, any SSH command flags were allowed to be passed. However, this could cause a privilege escalation issue - so that option was removed (#98). Therefore, as handy as it may be, please do not ask to add that feature again :)
If the destination host is not in your known_hosts file, things will not work. Check your logs to understand if that is the case.
In order to open a tunnel OpenSSH VPN, all that you have to do is run:
#!/bin/bash
# This is the WAN IP/hostname of the remote machine
REMOTE=nm-ssh.nevela.com
# Remote username will usually be root, or any other privileged user
# who can open tun/tap devices on the remote host
REMOTE_USERNAME=root
# Remote IP in the tunnel
REMOTE_IP=172.16.40.1
# Local IP in the tunnel
LOCAL_IP=172.16.40.2
# Netmask to set (on both sides)
NETMASK=255.255.255.252
# SSH port to use
PORT=22
# MTU for tunnel
MTU=1500
# Remote tunnel device (tun100/tap100)
REMOTE_DEV=100
DEV_TYPE=tun
# TUNNEL_TYPE is 'point-to-point' for tun and 'ethernet' for tap
TUNNEL_TYPE=point-to-point
# Local tunnel is calculated depending on what devices are free
# The following loop iterates from 0 to 255 and finds a free
# tun/tap device
for i in `seq 0 255`; do ! /sbin/ip link show $DEV_TYPE$i >& /dev/null && LOCAL_DEV=$i && break; done
# Finally, the command that does it all:
ssh -f -o PreferredAuthentications=publickey -o NumberOfPasswordPrompts=0 -o ServerAliveInterval=10 -o TCPKeepAlive=yes \
-o User=$REMOTE_USERNAME -o Port=$PORT -o HostName=$REMOTE -o Tunnel=$TUNNEL_TYPE -o TunnelDevice=$LOCAL_DEV:$REMOTE_DEV \
$REMOTE "/sbin/ip addr add $REMOTE_IP/$NETMASK peer $LOCAL_IP/$NETMASK dev $DEV_TYPE$REMOTE_DEV; /sbin/ip link set $MTU dev $DEV_TYPE$REMOTE_DEV up" && \
/sbin/ip addr add $LOCAL_IP/$NETMASK peer $REMOTE_IP/$NETMASK dev $DEV_TYPE$LOCAL_DEV; /sbin/ip link set $MTU dev $DEV_TYPE$LOCAL_DEV up
That's actually an edited export file of a working SSH VPN configuration I have from NetworkManager.
This will create a tunnel of 172.16.40.1<->172.16.40.2 on tun100 on both machines. If forwarding is enabled on that SSH server, you'll get pass-through internet easy.
- Thomas Young - First user!
- Whoopie - For nice debian support and testing
- Oren Held - Invaluable feedback and testing
- Lubomir Rintel (@lkundrak)- Keeping this repository up to date with upstream NetworkManager, assisting with Fedora packaging
- Lennart Weller (@lhw) - Debian packaging
- Anyone else who engaged with the project, opened tickets and/or submitted code
Choosing a connection type:
Main dialog:
Advanced dialog: