GithubHelp home page GithubHelp logo

nmtrust's Introduction

nmtrust

This project provides a simple framework for determining the trusted state of the current network connections, and taking action based on the result. It is intended to be used to activate certain services on trusted networks, and disable them when when there is a connection to an untrusted network or when there is no established network connection.

Requirements

Defining Trust

NetworkManager assigns a UUID to each network profile. These can be seen by running nmcli conn. The UUIDs of the trusted networks should be placed in a file. By default nmtrust will look for this file at /etc/nmtrust/trusted_networks, however an alternative location may be provided using the -t option.

If all of the current network connections are trusted, the trusted network file can be initiated with these values.

# nmcli --terse -f uuid conn show --active > /etc/nmtrust/trusted_networks

nmtrust will ask NetworkManager for a list of all active connections. It will then compare the UUIDs of the active connections against the trusted network file.

  • If all the current connections are matched in the trusted network file, nmtrust will report that all connections are trusted.
  • If none of the current connections exist in the trusted network file, nmtrust will report that all connections are untrusted.
  • If some of the current connections exist in the trusted network file, but some do not, nmtrust will report that one or more connections are untrusted.
  • If there are no active network connections, nmtrust will report this.

Exclude Networks

Network connections can be excluded from nmtrust as well.

For example, if you have Docker installed, the Docker bridge network connection(s) needs to be excluded from the active network connections list. Otherwise, if you disconnect all other connections, nmtrust still thinks there are active connections despite that you are offline.

The name of the network(s) that need to be excluded should be placed in /etc/nmtrust/excluded_networks, however an alternative location may be provided using the -e option.

You can place the exact names in the file or you can use wildcards to exclude multiple networks. For example, virbr0, virbr1, etc. pp. or just virbr?. You can also specify a range: virbr[0,1].

Usage

A unique exit code is returned for each of the four possible states.

Exit Code State
0 All connections are trusted
2 All connections are untrusted
3 One or more connections are untrusted
4 There are no active connections

This allows the user to easily script nmtrust to only execute certain actions on certain types of networks. For example, you may have a network backup script netbackup.sh that is executed every hour by cron. However, you only want the script to run when you are connected solely to a network or networks that you trust. This is easy to accomplish by creating a wrapper around netbackup.sh for cron to call.

#!/bin/sh

# Execute nmtrust
nmtrust

# Execute backups if the current connection(s) are trusted.
if [ $? -eq 0 ]; then
    netbackup.sh
fi

systemd integration

While nmtrust is a flexible script that can run anywhere NetworkManager is present, ttoggle is provided for use on systems with systemd.

The idea here is that the user has a number of systemd units that they only want to start when connected to a trusted network. The name of the trusted units should be placed in a file, one per line. By default ttoggle will look for this file at /etc/nmtrust/trusted_units, however an alternative location may be provided using the -f option.

When ttoggle is executed, it calls nmtrust to determine the state of the network connections. If nmtrust reports that all the current connections are trusted, ttoggle will start all the units listed in the trusted unit file. If nmtrust reports that there is a connection to an untrusted network or that the system is offline, ttoggle will stop all the units listed in the trusted unit file.

Usage

The user may have a timer to periodically send and receive mail, and a service that provides an IRC instant messaging gateway. These may both potentially leak personal information over the network, so they should not be started on untrusted connections.

# echo 'mailsync.timer\nircgateway.service' > /etc/nmtrust/trusted_units

Now when ttoggle is called it will start or stop these trusted units as appropriate.

Status

The -s option may be used to see an abbreviated status of all the trusted units.

$ ttoggle -s

Stop Everything

The -x option may be used to stop all of the trusted units, regardless of the network trust.

$ ttoggle -x

Start Everything

The -t option may be used to start all of the trusted units, regardless of the network trust. This may be useful for temporarily trusting a network connection.

$ ttoggle -t

Allow Offline

There may be some units that should be run on trusted networks and when there is no network connection, but not when connected to an untrusted network. For example, the git-annex assistant provides useful functionality both online and offline, but may leak personal information (such as the location of networked remotes) on untrusted networks. These units can be allowed to run offline by adding ,allow_offline to the unit entry in the trusted unit file.

# echo '[email protected],allow_offline' >> /etc/nmtrust/trusted_units'

When ttoggle is called it will now perform the following:

  • Start all units when connected to trusted networks.
  • Stop all units when connected to untrusted networks.
  • Stop all units when connected to no network, and then start units that are marked allow_offline.

User Units

User units may be specified by adding ,user:username to the unit entry in the trusted unit file. For example, if the user pigmonkey has a unit ssh-tunnel.service that should only be started on trusted networks:

# echo 'ssh-tunnel.service,user:pigmonkey' >> /etc/nmtrust/trusted_units

When starting, stopping, or checking the status of these units ttoggle will check if the calling user is the same as the user specified for the unit. If the users match, the current user will be used to take the appropriate action. If the users do not match (for instance, when ttoggle is called by root), sudo will be used to take action as the specified user.

Automation

A NetworkManager dispatcher is provided to automate the toggling of trusted units. Once installed, the dispatcher will cause NetworkManager to call ttoggle whenever a network connection is activated or deactived.

# cp dispatcher/10trust /etc/NetworkManager/dispatcher.d
# chmod 755 /etc/NetworkManager/dispatcher.d/10trust

nmtrust's People

Contributors

brett avatar ckotte avatar pigmonkey avatar stephenbrown2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

nmtrust's Issues

Ttoggle raise an error: Failed to connect to bus: No such file or directory when using user mode trusted units

Hey,
Thanks for spark and all the little gem you developed so far, really appreciate to use it.
I'm using syncthing to synchronise my stuff and my trusted_units looks like this:
syncthing.service,user:myuser
When using sudo ttoggle I get an error:
Failed to connect to bus: No such file or directory
I have other trusted units which are not user, they are working correctly.
How I can debug this problem ?
If I use journalctl -fl I see that a command is run:

fév 05 07:57:21  sudo[144802]:     myuser : TTY=pts/2 ; PWD=/home/myuser ; USER=root ; COMMAND=/usr/bin/ttoggle
fév 05 07:57:21  sudo[144802]: pam_unix(sudo:session): session opened for user root(uid=0) by myuser(uid=1337)
fév 05 07:57:21  sudo[144863]:     root : TTY=pts/4 ; PWD=/home/myuser ; USER=myuser ; COMMAND=/usr/bin/bash -c 'export XDG_RUNTIME_DIR=/run/user/1000; systemctl stop --user syncthing.service'

The command looks good, but syncthing is not stopped.
If I copy/past the same command in my shell, syncthing get stopped.

EDIT: I understand why, my uid is 1337 and not 1000, that's why it is failing in the ttoggle script
dirty fix would be in file ttoggle
https://github.com/pigmonkey/nmtrust/blob/b1a43f43da29e38bf62d4d298127299a62258417/ttoggle#L59C9-L59C87
sudo -u "$unit_user" bash -c "export XDG_RUNTIME_DIR=/run/user/$(sudo -u "$unit_user" bash -c "id -u"); $command"

I'm also wondering if we should modify in spark:

https://github.com/pigmonkey/spark/blob/1a485d95bab2842381ba5a26bcd3e0184fdffb6b/roles/base/tasks/user.yml#L5

To use also gid: "{{ user.uid }}" in case the user want to change the default uid and that we match the gid as well.

Another issue I encountered, is that using nmtrust with NetworkManager raise an error in the journalctl log:
tput: No value for $TERM and no -T specified

if which tput >/dev/null 2>&1; then

This is because the tput want a $TERM. I wrote a simple workarround using:

if tty -s; then before the whole functions, which will run only if we are in a terminal

10trust NetworkManager dispatcher script gets executed for every connection

The dispatcher script gets executed for every connection. In my case it's loopback, WiFi, Docker bridged networks, etc. pp. This only happens at the system startup. It doesn't have a real negative impact except logging many messages in the log. The services are just "started multiple times".

Sep 04 17:13:13 icarus nm-dispatcher[1537]: req:9 'up' [wlp2s0], "/etc/NetworkManager/dispatcher.d/10trust": complete: failed with Script '/etc/NetworkManager/dispatcher.d/10trust' exited w>
...
Sep 04 17:13:14 icarus nm-dispatcher[2969]: All connections are trusted
Sep 04 17:13:14 icarus nm-dispatcher[2954]: Starting trusted system units
Sep 04 17:13:14 icarus nm-dispatcher[2954]: Starting trusted user units
...
Sep 04 17:13:14 icarus nm-dispatcher[1537]: req:12 'up' [br-4d9297e3e7cb], "/etc/NetworkManager/dispatcher.d/10trust": complete: failed with Script '/etc/NetworkManager/dispatcher.d/10trust>
...
Sep 04 17:13:15 icarus nm-dispatcher[3242]: All connections are trusted
Sep 04 17:13:15 icarus nm-dispatcher[3227]: Starting trusted system units
Sep 04 17:13:15 icarus nm-dispatcher[3227]: Starting trusted user units
...
Sep 04 17:13:15 icarus nm-dispatcher[1537]: req:15 'up' [br-8e15dbfdbac6], "/etc/NetworkManager/dispatcher.d/10trust": complete: failed with Script '/etc/NetworkManager/dispatcher.d/10trust>
...
Sep 04 17:13:16 icarus nm-dispatcher[3512]: All connections are trusted
Sep 04 17:13:16 icarus nm-dispatcher[3497]: Starting trusted system units
Sep 04 17:13:16 icarus nm-dispatcher[3497]: Starting trusted user units
...
Sep 04 17:13:16 icarus nm-dispatcher[1537]: req:16 'up' [br-89e023c415a6], "/etc/NetworkManager/dispatcher.d/10trust": complete: failed with Script '/etc/NetworkManager/dispatcher.d/10trust>
...
Sep 04 17:13:16 icarus nm-dispatcher[3782]: All connections are trusted
Sep 04 17:13:16 icarus nm-dispatcher[3767]: Starting trusted system units
Sep 04 17:13:16 icarus nm-dispatcher[3767]: Starting trusted user units
...

Those networks are all excluded:

/etc/nmtrust/excluded_networks

# Ansible managed
docker?
br-*
virbr*
vnet*
lo

Does it make sense to ignore all excluded networks from the dispatcher execution? For example:

/etc/NetworkManager/dispatcher.d/10trust

#!/bin/bash
# Toggle trusted units whenever a connection is activated or deactived.

EXCLUDEFILE="/etc/nmtrust/excluded_networks"

interface=$1 action=$2

check_connection() {
    local name=$1
    local connection_excluded=false
    mapfile -t excludes < <(grep -v '^#' < $EXCLUDEFILE)
    for exclude in "${excludes[@]}"; do
        # NOTE: Cannot quote right-hand site of == because glob matching is needed [shellcheck(SC2053)]
        if [[ "$name" == $exclude ]]; then
            connection_excluded=true
            break
        fi
    done
    echo $connection_excluded
}

if [[ $(check_connection "$interface") = false ]]; then
    echo "$interface"
    case $action in
        up)
            ttoggle
            ;;
        down)
            ttoggle
            ;;
    esac
fi

exit $?

So, does it make sense to only execute it for networks not excluded or just execute it every time?

add support for 'iwd' ?

hey, i would love to contribute to your project to support iwd directly, so i can ditch network-manager as dependency.
since my coding skills are almost none existent, i would need some help to point me in the right direction and audit my lines after pr of course. hope you like the idea and there is no major breakpoint that i miss for make it to work....?

as far as i could spot out, i think the interesting parts are line 94-118 at the nmtrust script?

best regards and thanks for sharing your tools ;)

ttoggle needs additional checks

We should check if the variables with the units are not empty. I don't have units configured in OFFLINE_SYSTEM_UNITS and OFFLINE_USER_UNITS this generates the following errors:

Nov 17 13:35:04 icarus nm-dispatcher[5665]: Too few arguments.
Nov 17 13:35:04 icarus nm-dispatcher[5603]: Starting trusted user offline units
Nov 17 13:35:04 icarus nm-dispatcher[5674]: Too few arguments.
Nov 17 13:35:04 icarus nm-dispatcher[5599]: req:1 'down' [wlp2s0], "/etc/NetworkManager/dispatcher.d/10trust": complete: failed with Script '/etc/NetworkManager/dispatcher.d/10trust' exited with error status 1.
Nov 17 13:35:04 icarus NetworkManager[1450]: <warn>  [1605616504.9399] dispatcher: (21) /etc/NetworkManager/dispatcher.d/10trust failed (failed): Script '/etc/NetworkManager/dispatcher.d/10trust' exited with error status 1.
# sudo ttoggle
There are no active connections
Stopping trusted system units
Stopping trusted user units
Starting trusted system offline units
Too few arguments.
Starting trusted user offline units
usage: sudo -h | -K | -k | -V
usage: sudo -v [-AknS] [-g group] [-h host] [-p prompt] [-u user]
usage: sudo -l [-AknS] [-g group] [-h host] [-p prompt] [-U user] [-u user] [command]
usage: sudo [-AbEHknPS] [-C num] [-D directory] [-g group] [-h host] [-p prompt] [-R directory] [-T timeout] [-u user] [VAR=value] [-i|-s] [<command>]
usage: sudo -e [-AknS] [-C num] [-D directory] [-g group] [-h host] [-p prompt] [-R directory] [-T timeout] [-u user] file ...
...
Starting trusted system offline units
+ systemctl start
Too few arguments.
...
+ sudo -u '' bash -c 'export XDG_RUNTIME_DIR=/run/user/1000; systemctl start --user '
usage: sudo -h | -K | -k | -V
usage: sudo -v [-AknS] [-g group] [-h host] [-p prompt] [-u user]
usage: sudo -l [-AknS] [-g group] [-h host] [-p prompt] [-U user] [-u user] [command]
usage: sudo [-AbEHknPS] [-C num] [-D directory] [-g group] [-h host] [-p prompt] [-R directory] [-T timeout] [-u user] [VAR=value] [-i|-s] [<command>]
usage: sudo -e [-AknS] [-C num] [-D directory] [-g group] [-h host] [-p prompt] [-R directory] [-T timeout] [-u user] file ...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.