Auto change MacOS network settings with WiFiLocControl
Tags: macos, utils, shell, bash
Published: 2023-11-28 13:20:56

Repo: https://github.com/vborodulin/wifi-loc-control

[WiFiLocControl](https://github.com/vborodulin/wifi-loc-control) enables you to automatically change your macOS network location based on the Wi-Fi network (SSID) to which you are connected.

It proves particularly beneficial for users who use Wi-Fi both at work and at home, but encounter issues where the network settings, such as custom DNS configurations, used at work prevent their Mac from seamlessly connecting to a similar network at home.

I personally encountered a similar issue when I installed [Pi-Hole](https://pi-hole.net/) on my Raspberry Pi to block ads on my network. Unfortunately, I couldn't configure custom DNS settings on my router due to restrictions imposed by my internet provider, who supplied the router. As a result, my only option was to manually set custom DNS with the IP address of my Raspberry Pi on each of my devices.

For example, when configuring DNS settings on my iPhone, those settings are specific to the Wi-Fi network. This means that if I connect to a different Wi-Fi network, the DNS settings revert to default.

In macOS, however, the situation is the opposite; the settings for Wi-Fi are not specific to the Wi-Fi network but rather to the network service. This means that if I want to use my MacBook at home with Wi-Fi and at work, I have to manually add the Pi-Hole DNS at home and remove it at work to revert to the default settings (such as Google's DNS).

To address this inconvenience, we can leverage [network location](https://support.apple.com/en-us/105129), which allows the creation of multiple network profiles with different settings. However, you still need to switch profiles manually. This is where [WiFiLocControl (https://github.com/vborodulin/wifi-loc-control) comes in to automate and simplify the process!

## Usage
To set up specific preferences for your Wi-Fi networks, keep it easy: just name your network locations after your Wi-Fi names. For example, if you want special settings for "My_Home_Wi-Fi_5GHz," make a location called "My_Home_Wi-Fi_5GHz." When you connect to that Wi-Fi, your location will switch automatically. If you connect to a Wi-Fi without a special name, it defaults to "Automatic.".

## Features

- Automatically changes network locations based on current Wi-Fi name.
- Supports alias configurations for multiple Wi-Fi names.
- Executes location-specific scripts.

## Installation

1. Clone the repository to your local machine.
    ```bash
    git clone https://github.com/vborodulin/wifi-loc-control.git
    cd ./wifi-loc-control
    ```

2. Run the bootstrap script to set up the environment.
    ```bash
    ./bootstrap.sh    
    ```
   It will **ask you for a root password** to install WiFiLocControl to the `/usr/local/bin`
   directory.

## Configuration

### Aliasing

If you want to share one network location between different wireless networks (for instance, you have a wireless router which broadcasts on 2.4 and 5GHz bands simultaneously), then you can create a configuration file `~/.wifi-loc-control/alias.conf` (plain text file with simple key-value pairs, no
spaces in between):

```text
My_Home_Wi-Fi_5GHz=Home
My_Home_Wi-Fi_2.4GHz=Home
```

Where the keys are the wireless network names and the values are the desired location names.

### Run Scripts on Wi-Fi Network Connection

Sometimes you want to execute a script every time you connect to a specific Wi-Fi network. For example enable stealth or enable firewall mode. Follow these
steps:

- Place your scripts in `~/.wifi-loc-control/`.
- Name the scripts after the Wi-Fi network name, ensuring consistency with the corresponding network locations.

Example script (`~/.wifi-loc-control/My_Home_Wi-Fi_5GHz`):

```bash
#!/usr/bin/env bash
# Collect all output from this script to ~/Library/Logs/WiFiLocControl.log
exec 2>&1

# Enable stealth mode which makes your computer less visible to potential attackers
/usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate on
```

To reset changes made by specific location scripts, create corresponding reset script.
Example reset script (`~/.wifi-loc-control/Automatic`):

```bash
#!/usr/bin/env bash
exec 2>&1

# Disable stealth mode which makes your computer less visible to potential attackers
/usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off
```

Make scripts executable

```bash
chmod +x ~/.wifi-loc-control/My_Home_Wi-Fi_5GHz
chmod +x ~/.wifi-loc-control/Automatic
```

## Troubleshooting

Rich logs available at ~/Library/Logs/WiFiLocControl.log.

```bash
tail -f ~/Library/Logs/WiFiLocControl.log
```

Logs examples:

```text
[2023-11-26 13:44:49] current wifi_name 'My_Home_Wi-Fi_5GHz'
[2023-11-26 13:44:49] network locations: Automatic Home
[2023-11-26 13:44:49] current network location 'Automatic'
[2023-11-26 13:44:49] reading alias config '/Users/vborodulin/.wifi-loc-control/alias.conf'
[2023-11-26 13:44:49] for wifi name 'My_Home_Wi-Fi_5GHz' found alias 'Home'
[2023-11-26 13:44:49] location switched to 'Home'
[2023-11-26 13:44:49] finding script for location 'Home'
[2023-11-26 13:44:49] running script '/Users/vborodulin/.wifi-loc-control/Home'
```

## Contributing

[Contributions are welcome!](https://github.com/vborodulin/wifi-loc-control) If you have suggestions, improvements, or encounter issues, feel free to open an issue or submit a [pull request](https://github.com/vborodulin/wifi-loc-control/pulls).

Repo: https://github.com/vborodulin/wifi-loc-control

## License

This project is licensed under [the MIT License](https://github.com/vborodulin/wifi-loc-control/blob/main/LICENSE).