It's a network dispatcher which allows to execute scrips on wifi connect/disconnect events.
It mitigates big flow in NetworkManager's dispatcher which ignores lost wifi events.
That's it, NetworkManager only reacts on proper connect/disconnect events when WIFI was disconnect button pressed.
But with laptops most common case is when laptop is often moved across different WIFI access points and connection lost
This project solves this problem by properly reacting on all WIFI connect/disconnect events.
Motivation to write it was my NAS network each time made dolphin hang since share was still mounted when wifi was lost.
Network dispatcher provides mount and umount script and handles case when the same network share needs to be mounted at home
and remotely via ssh tunnel
This project main use case was to mount network share directly when on home network
and mount the same share through ssh tunnel when everywhere else. \
- Listens to WIFI and Ethernet connect/disconnect events
- Provides convenient way to automatically mount network share when at home or remote location.
- Allows to specify configurable scripts per event. See the Usage section for more details
- Provides filters by mac address to run scripts in the specific locations.
- Includes tested scripts to properly mount and umount network shares on connects/disconnects. See the Usage section for more details
- NetworkManager. My network dispatcher listensNetworkManager low level dbus events
- Dbus. See above
- Systemd. My network dispatcher provides systemd service to run itself
- Ssh tunnel script relies on console autossh and ssh to maintain tunnel
- Install by executing
bash -c "$(curl -L https://raw.githubusercontent.com/danilovsergei/network-dispatcher/main/install.sh)" -- "$HOME/bin"
It will download and unpack latest release into "$HOME/bin"
directory and install network-dispatcher systemd service into "$HOME/.config/systemd/user/network-dispatcher.service"
Everything runs under current user.
After that network disatcher is ready to react on events. However it's necessary to define config with scripts to react. See the Usage section for examples
To react on events create network-dispatcher config in $HOME/.config/network-dispatcher/config.json
Here is example of config which mounts and umounts CIFS network share.
This config is using scripts provided in release and installed into $HOME/bin/network-dispatcher
Config consists of list of entities. Here are all available entity parameters:
IncludedMacAddresses
: script will be executed only for networks which have a gateways with given macaddressesExcludedMacAddresses
: script will be skipped for networks which have a gateways with given macaddressesScript
: path to the script to execute. Supports sh environment variables such as $HOMEEvent
: network event script will be triggered. Supported events areconnected
,disconnected
EnvVariables
: Allows to configure a script execution with key/value environment variables. See Script mounts/umount local CIFS share exampleContinueOnFail
: Scripts are executed in order specified in the entities list.IfContinueOnFail
true next scripts will still be executed even if current script failed. Default value iffalse
It's a basic example how to mount and unmount share.
Note that no filters specified which means given scripts will be triggered in ANY wifi network , at home or outside.
It's not optimal since mounted local share will hang the system when outside.
See Script mounts/umount using filter
{
"Entities": [
{
"Script": "$HOME/bin/network-dispatcher/share_mount.sh",
"Event": "connected",
"EnvVariables": {
"MOUNT_POINT": "//192.168.1.1/Storage"
}
},
{
"Script": "$HOME/bin/network-dispatcher/share_umount.sh",
"Event": "disconnected",
"EnvVariables": {
"MOUNT_POINT": "//192.168.1.1/Storage"
}
}
]
}
share_mount.sh
and share_umount.sh
relies on /etc/fstab
record to be able to work as user. So please add mount line to your /etc/fstab
//192.168.1.1/Storage /home/Storage cifs noauto,rw,users,nodev,relatime 0 0
noauto
parameter is crucial because it instruct systemd that share will be mounted manually by our scripts
Given option provides ability to run the scripts only when connected to certain gateway.
Which is typically home router at home. It allows to specify gateway mac address in the Included_MacAddresses
{
"Entities": [
{
"Script": "$HOME/bin/network-dispatcher/share_mount.sh",
"Event": "connected",
"EnvVariables": {
"MOUNT_POINT": "//192.168.1.1/Storage"
},
"Included_MacAddresses": [
"cc:ce:cc:ce:ce:cc"
]
},
{
"Script": "$HOME/bin/network-dispatcher/share_umount.sh",
"Event": "disconnected",
"EnvVariables": {
"MOUNT_POINT": "//192.168.1.1/Storage"
},
"Included_MacAddresses": [
"cc:ce:cc:ce:ce:c"
]
}
]
}
There is opposite option called Excluded_MacAddresses
which skips script execution on specified
This script is a most common scenario:
- when at home it mounts share as
//192.168.1.1/Storage
directly via cifs using home gateway mac address inIncluded_MacAddresses
.\ - when outside share is mounted as
//127.0.0.1/Storage
via ssh tunnel usingExcluded_MacAddresses
to exclude home network - mount script generates a symlink
$HOME/Storage
for both mount at home and outside cases. So share is always accessible by the same path.
{
"Entities": [
{
"Script": "$HOME/bin/network-dispatcher/cifs_ssh_tunnel.sh",
"Event": "connected",
"EnvVariables": {
"SSH_PORT": "2222",
"SSH_USER": "homeuser",
"SSH_HOST": "my-external-address.dyndns.com",
"PRIVATE_KEY": "$HOME/.ssh/cifs_id_rsa"
},
"Excluded_MacAddresses": [
"cc:ce:cc:ce:ce:cc"
]
},
{
"Script": "$HOME/bin/network-dispatcher/share_mount.sh",
"Event": "connected",
"EnvVariables": {
"MOUNT_POINT": "//127.0.0.1/Storage",
"MOUNT_LINK": "$HOME/Storage"
},
"Excluded_MacAddresses": [
"cc:ce:cc:ce:ce:cc"
]
},
{
"Script": "$HOME/bin/network-dispatcher/share_umount.sh",
"Event": "disconnected",
"EnvVariables": {
"MOUNT_POINT": "//127.0.0.1/Storage"
},
"Included_MacAddresses": [
"cc:ce:cc:ce:ce:cc"
]
},
{
"Script": "$HOME/bin/network-dispatcher/share_mount.sh",
"Event": "connected",
"EnvVariables": {
"MOUNT_POINT": "//192.168.1.1/Storage",
"MOUNT_LINK": "$HOME/Storage"
},
"Included_MacAddresses": [
"cc:ce:cc:ce:ce:cc"
]
},
{
"Script": "$HOME/bin/network-dispatcher/share_umount.sh",
"Event": "disconnected",
"EnvVariables": {
"MOUNT_POINT": "//192.168.1.1/Storage"
},
"Included_MacAddresses": [
"cc:ce:cc:ce:ce:c"
]
}
]
}
Network dispatcher relies on mount points specified in /etc/fstab
because it allows to mount and umount as user.
One limitation is /etc/fstab
does not allow to specify two different network shares pointing to the same mount directory.
Following does not work and breaks mounting as user:
#/etc/fstab
//127.0.0.1/Storage /home/storage cifs noauto,port=4445,rw,users,nodev,relatime 0 0
//192.168.1.1/Storage /home/storage cifs noauto,port=4445,rw,users,nodev,relatime 0 0
So correct /etc/fstab
looks like this.
#/etc/fstab
# noauto parameter is crucial because it instruct systemd that share will be mounted manually by our scripts
# port=4445 is local port to establish the ssh tunnel to the NAS. Its hardcoded in cifs_ssh_tunnel.sh
#
//127.0.0.1/Storage /home/storage_remote cifs noauto,port=4445,rw,users,nodev,relatime 0 0
//192.168.1.1/Storage /home/storage_local cifs noauto,port=4445,rw,users,nodev,relatime 0 0
But that add inconvenience of having two different paths when at home and outside
which is solved by specifying MOUNT_LINK
MOUNT_LINK
- when specified mount script will create a symbolic link from mounted share to specifiedMOUNT_LINK
. Provided in the script"MOUNT_LINK": "$HOME/Storage"
will automatically point /home/Storage to /home/storage_local when at home and /home/storage_remote when outside
noauto
parameter is crucial because it instruct systemd that share will be mounted manually by our scripts
port=4445
is local port to establish the ssh tunnel to the NAS. It's hardcoded in cifs_ssh_tunnel.sh
This config implements ssh tunnel to the local cifs share to make it securely accessible through internet.
See the cifs_ssh_tunnel.sh
how its implemented.
SSH_PORT
- port on external hostname to forward your ssh server local port. Local 22->SSH_PORT
port forwarding rule must be configured on the router to make it workSSH_USER
- user to login to your ssh serverSSH_HOST
- your external hostname, I use dynamic DNS provider to get my hostnamePRIVATE_KEY
- private key to login to your ssh server\
It requires autossh
package to correctly manage ssh tunnel errors and restart it
To view realtime logs from network-dispatcher and all scripts it runs use journalctl
journalctl --user -t "network-dispatcher" -f