Map an internal IP address to a domain name, when on a particular network

dnshostsipnetworkingvpn

I have a server at home, with internal IP 192.168.1.100. I use a dynamic DNS service so that I can reach it at http://foo.dynu.com when I am out. When I have my laptop at home, I know that I could directly connect to the server by adding the following line to /etc/hosts.

192.168.1.100    foo.dynu.com

However, is there a way to automatically apply this redirect only when I'm on my home network? (I usually connect via a particular wifi connection, although I occasionally connect via ethernet. If this complicates matters, then I'm happy to only set it for the wifi connection.) I use Network Manager.

Also, I connect to the internet via a VPN, so presumably any configuration on my (OpenWRT) router is unlikely to work.

Best Answer

As per @garethTheRed's suggestion in the comments, I created a Network Manager Dispatcher hook.

Create the following file at /etc/NetworkManager/dispatcher.d/99_foo.dynu.com.sh. This progresses when a new network connection is detected (i.e. ethernet or wifi). It then identifies my "home network" in two ways: the BSSID/SSID and the static IP that my router assigns me. (At the moment it doesn't work when I connect via ethernet, since that's relatively rare.) It then appends the mapping to the hosts file if we are in the home network; if not, then it removes this line.

#!/bin/sh
# Map domain name to internal IP when connected to home network (via wifi)
# Partially inspired by http://sysadminsjourney.com/content/2008/12/18/use-networkmanager-launch-scripts-based-network-location/

WIFI_ID_TEST='Connected to 11:11:11:11:11:11 (on wlp3s0)
    SSID: WifiName'
LOCAL_IP_TEST='192.168.1.90'
MAPPING='192.168.1.100    foo.dynu.com'
HOSTS_PATH=/etc/hosts

IF=$1
STATUS=$2
# Either wifi or ethernet goes up
if [ "$STATUS" = 'up' ] && { [ "$IF" = 'wlp3s0' ] || [ "$IF" = 'enp10s0' ]; }; then
  # BSSID and my static IP, i.e. home network
  if [ "$(iw dev wlp3s0 link | head -n 2)" = "$WIFI_ID_TEST" ] && [ -n "$(ip addr show wlp3s0 to ${LOCAL_IP_TEST})" ]; then
    grep -qx "$MAPPING" "$HOSTS_PATH" || echo "$MAPPING" >> "$HOSTS_PATH"
  else
    ESC_MAPPING="^$(<<<"$MAPPING" sed 's/\./\\./g')$"
    sed -i "/${ESC_MAPPING}/d" "$HOSTS_PATH"
  fi
fi
Related Question