Bitten by my network settings, SwiftBar saves me 

Tags :
Menubar displaying a hand emoji with a dropdown menu offering to disable web proxy settings

Have you ever got bitten by a local network setting you forgot to disable? Like an enabled web proxy or an /etc/hosts entry?

Well, I got tricked into debugging my network setup at the office the other day, because of a proxy setting I had forgotten to disable.

I have to use a VPN + enable a web proxy to access some of my client’s virtual hosts and file repositories. It isn’t a problem per se, unless I forget to disable the proxy settings – which happened last Thursday evening.

It took me a significant amount of time the following morning to figure out what was going on. Blame it on my failing short term memory, insuffisant caffeine or an all-in busy week, I decided to take the opportunity to figure out a way to prevent this from happening again.

Web proxy settings

Unlike VPNs, there is no clear indication in macOS that you are using web proxy settings or not, unless you dig down System Settings > Network > { interface } > Proxies.

macos Ventura network proxies settings
macos system settings > network > ethernet > details

Wouldn’t it be cool if a small glyph (✋) was displayed in your menubar when those settings are enabled (or disabled depending on your use case) ?

Screenshot of my menubar with the web proxy hand emoji to the far left
The hand emoji indicates that proxy settings are enabled.

SwiftBar

SwiftBar application icon

So, I figured it would be the perfect time to give SwiftBar a test run. SwiftBar lets you add a custom menu bar program to your menubar via a shell script. I’m not a fan of menubar items, and try to keep them at a minimum with the help of Bartender, but it remains the best spot to place a small visual cue.

SwiftBar is a simple, yet powerful application. Launch it and it will ask you to point it to a folder containing your shell scripts (called plugins).

You’ll find a large library of available plugins directly from the app, great for inspiration and examples. Each enabled plugin will show up on your menubar.

The basic idea is that the output of the script will be displayed in the menubar. The first output is called the Header. Additional information or commands can be displayed by printing a --- followed by the information you wish to display (Body).

echo "Hello World" ← displayed in the menu
echo "---"
echo "Powered by SwiftBar" ← displayed in the menu dropdown

Additional parameters can be added to each line to customise its output and behaviour. Check the docs for more info.

I was looking to write a script that displayed an emoji ✋ if my proxy settings were enabled.

Command line

scutil will tell you if you’re running web proxy settings:

roessli@loki ~ % scutil --proxy
<dictionary> {
  FTPPassive : 1
  HTTPEnable : 0
  HTTPSEnable : 0
}

or, if web proxy settings are running,

roessli@loki ~ % scutil --proxy
<dictionary> {
  FTPPassive : 1
  HTTPEnable : 1
  HTTPPort : 1234
  HTTPProxy : 123.456.78.90
  HTTPSEnable : 0
  HTTPSPort : 0
  HTTPSProxy : 0
}

HTTPProxy can be an IP number or a hostname depending on your use case, and HTTPSEnable might be turned on or not.

To identify the network interface name you need to target, use networksetup to list your network services. Running it on my MacBook Pro gives,

roessli@loki ~ % networksetup -listallnetworkservices
An asterisk (*) denotes that a network service is disabled.
USB 10/100/1000 LAN
ThinkPad Lan
Belkin USB-C LAN
Wi-Fi
iPhone USB
Thunderbolt Bridge
VPN
ProtonVPN
roessli@loki ~ %

On my office iMac I will use Ethernet.

Web proxy toggle bash script

After a little tinkering, I came up with the following bash script (thanks to Derek Morgan) that echos an emoji for SwiftBar to display in the menubar if I’m running web proxy settings.

#!/bin/bash

proxyState=$(scutil --proxy | awk '\
  /HTTPEnable/ { enabled = $3; } \
  /HTTPProxy/ { server = $3; } \
  /HTTPPort/ { port = $3; } \
  END { if (enabled == "1") { print "1"; }}')

case "$proxyState" in
"1")
  echo "✋"
  ;;
*)
  echo " "
  ;;
esac

Now, how cool would it be if the web proxy could be turned off right from the menubar?

The command to disable the web proxy is,

/usr/sbin/networksetup -setwebproxystate interface off

Interface can be any of the above, and the off argument relates to HTTPS.
To enable web proxy setting, use,

/usr/sbin/networksetup -setwebproxy interface proxyIP proxyPort off

I added the following conditional to my script to add an item under the emoji:

interface="Wi-Fi"
proxyIP="123.456.78.90"
proxyPort="1234"

if [[ $proxyState -eq "1" ]]
  then
    #echo "CLIENT proxy enabled";
    echo $(scutil --proxy | awk '\
    /HTTPEnable/ { enabled = $3; } \
    /HTTPProxy/ { server = $3; } \
    /HTTPPort/ { port = $3; } \
    END { print "Proxy http://" server ":" port; }');
    echo "Disable CLIENT proxy | bash='/usr/sbin/networksetup' param1=-setwebproxystate param2=$interface param3=off terminal=false refresh=true";
  else
    echo "CLIENT proxy disabled";
    echo "Enable CLIENT proxy | bash='/usr/sbin/networksetup' param1=-setwebproxy param2=$interface param3=$proxyIP param4=$proxyPort param5=off terminal=false refresh=true";
fi

If the $proxyState equals 1, echo the running web proxy settings and the command to disable it. Otherwise, add the command to turn web proxy settings on.

The command takes 3 arguments: interface { e.g. Ethernet | Wi-Fi } proxyIP and proxyPort.

Additionally, I added settings to hide the SwiftBar commands in the dropdown menu, turning my menubar item into a web proxy toggle.

The final UI looks like:

Screenshot of the script offering to enable the proxy settings
Screenshot of the script offering to disable the proxy settings

I deliberatly chose not to display anything when the web proxy was disabled (it’s my default state, no need to publish it), but to keep the option to enable it by clicking on the space left to the last item in my menubar. Bartender enables me to specify where new items should appear in the menubar, and keep my script always on the left.

The full script is available on GitHub.

Tip: You can configure SwiftBar to run the script at a fixed intervals to make sure it is displaying the correct state by adding a fragment to the plugin name: swiftbar-proxy.{ time }.sh where time is the refresh interval (e.g. swiftbar-proxy.1m.sh). Check the ReadMe for more details.

Posted a response ? — Webmention it

This site uses webmentions. If you've posted a response and need to manually notify me, you can enter the URL of your response below.

Want more ? — prev/next entries