Toggling Network Info in tmux

Monday, Jun 29, 2020 5 minute read Tags: random

I’ve been doing a bit of live streaming recently (you can catch me on Twitch or YouTube) which means that I’m sharing my desktop on recordings more often and I like doing this because, as I’ve spent a bunch of time setting up my terminal (read more here).

Recently, my colleague Brian Clark pinged me about something he’d noticed on a recent stream, that in my terminal there are some IP addresses (left side of my tmux status bar) and he asked if they were real. And that’s when I realised that I’ve been publishing my home IP address on each stream or video I have published over the last few months! 😂

Now, to the best of my knowledge this hasn’t been a problem as I haven’t been hacked (to the best of my knowledge!), but still, it’s probably not a great idea to do that, so I quickly reset the modem to get a new external IP but it left the question of how to solve this going forward? The obvious one is to just remove that from the status bar, but I do like having it there when I’m not streaming (it’s useful), so what’s the next option? Well, I could make an overlay to mask it, but that’d only work on stream, what if I’m at an event presenting, they aren’t going to want my overlay hack are they? It’s time for something more creative.

Anatomy of my IP info

The IP information on display generated by this script which is run in context of the tmux status bar, and is just a few commands to get local and remote IP information, and is included using my .tmux.config.

So, this is just a shell script, meaning that I can do anything I want to with it, and that got my thinking “how can I detect when to disable it?” and the time I (most) want it disabled is when I have OBS running for a stream. But OBS runs in Windows and tmux is in WSL, so how do we detect it?

Detecting Windows processes in WSL

You’re probably familiar with Windows Task Manager to find processes, but did you know there’s a command line equivalent, tasklist.exe? and WSL ships with Windows interop in the box, which means from WSL I can just run tasklist.exe and get all running Windows tasks! This output can then be passed straight through to grep and we can do a conditional check like so:

1
2
3
4
5
if tasklist.exe | grep -q 'obs'; then
    echo "OBS is running"
else
    echo "OBS isn't running"
fi

Now it’s just a case of swapping in some fake IP addresses when OBS is running and we’re all set!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
if tasklist.exe | grep 'obs' -q; then
  echo -n "🏠 #[fg=colour197]192.168.0.0 #[fg=black]|#[fg=colour197] 📡 255.255.255.256"
else
  # Internal IP
  IP=$(hostname -I | awk {'print $1}')

  PUBLIC_IP=$(curl -4 ifconfig.co)

  if [[ "$PUBLIC_IP" = ";; connection timed out; no servers could be reached" ]]; then
      PUBLIC_IP="Not Available"
  elif [[ "$PUBLIC_IP" = "" ]]; then
      PUBLIC_IP="No external access"
  else
      PUBLIC_IP=$(curl -4 ifconfig.co)
  fi

  echo -n "🏠 #[fg=colour197]$IP #[fg=black]|#[fg=colour197] 📡 $PUBLIC_IP"
fi

Bonus round: Set fake network info whenever you want

This works great, it targets the main scenario of when my IP addresses are being leaked, but it doesn’t cover them all, like when I’m presenting at a user group or conference and I’m not using OBS to produce the output stream. In those cases I need some other way to fake out the IP addresses.

To do this I wanted to have a key binding in tmux that I could hit which would set something that the script could then run and test against.

The first step is to create a custom option in tmux, and I couldn’t find any documentation on this but through trail and error, plus reading a lot of other tmux configs, it turns out that you prefix the option with @, so we’ll put that in our .tmux.config:

1
set -g @show-network true

set is an alias for set-option, which is run against tmux (if it wasn’t in the .tmux.config you’d do tmux set-option) and the -g flag says we’re setting this globally on all tmux windows (you can use -w for the current window, but I want it consistent on all), then we give it a name, @show-network and an initial value true.

Now, for the key binding we’ll use bind (or bind-key), provide it the key to bind to and what to do when its triggered:

1
bind o run-shell "if ! $(tmux show-option -gqv @show-network); then tmux set -g @show-network true; else tmux set -g @show-network false; fi"

For this, we’re binding to o as the key, meaning it’s modifier + o which, for me, is Ctrl + b, o, but choose whatever you want/have free. This binding will trigger run-shell, to execute either a shell script or an inline script (which I do). The script checks for to current @show-network value and flips it. You can probably write this shorter, but the verboseness means I can remember what it does in the future.

Lastly, let’s update the script that shows the network status:

1
2
3
4
5
if $(tasklist.exe | grep 'obs' -q) || ! $(tmux show-option -gqv @show-network); then
  echo -n "🏠 #[fg=colour197]192.168.0.0 #[fg=black]|#[fg=colour197] 📡 255.255.255.256"
else
  # snip
fi

Conclusion

This was a fun little dig into how you can customise tmux to fit your needs. With a few edits to the script we can detect processes running that we want to hide the IP info from, and it turned out to be possible to add our options fire off a keyboard command to hide it as well.

The scripts have been updated on my GitHub repo if you want to grab them.