Last active
October 6, 2025 00:42
-
-
Save MohamedElashri/b051792140e4f3ad66f20e25df6e9119 to your computer and use it in GitHub Desktop.
Revisions
-
MohamedElashri revised this gist
Oct 6, 2025 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,8 +2,8 @@ set -euo pipefail # --- Policy --- HOME_SSIDS=("HomeNetworkI" "HomeNetworkII") # home Wi-Fi names CERN_SSID_REGEX='^(CERN|eduroam|CERN-Visitor)$' CERN_DNS="137.138.16.5 137.138.17.5" FALLBACK_DNS="9.9.9.9" -
MohamedElashri revised this gist
Oct 5, 2025 . 1 changed file with 20 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,20 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"\> <plist version="1.0"> <dict> <key>Label</key><string>com.melashri.ssid-dns</string> <key>ProgramArguments</key> <array> <string>/Users/melashri/.local/bin/ssid-dns</string> </array> <key>RunAtLoad</key><true/> <key>KeepAlive</key> <dict> <key>NetworkState</key><true/> </dict> <key>StartInterval</key><integer>60</integer> <key>StandardOutPath</key><string>/tmp/ssid-dns.out</string> <key>StandardErrorPath</key><string>/tmp/ssid-dns.err</string> </dict> </plist> -
MohamedElashri created this gist
Oct 5, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,160 @@ #!/usr/bin/env bash set -euo pipefail # --- Policy --- HOME_SSIDS=("BarHen" "BarNad") # home Wi-Fi names CERN_SSID_REGEX='^(CERN|eduroam|CERN-Visitor|CERN-Trusted)$' CERN_DNS="137.138.16.5 137.138.17.5" FALLBACK_DNS="9.9.9.9" # CERN network ranges (add as needed) CERN_NETS=( "137.138.0.0/16" "128.142.0.0/16" "188.184.0.0/15" "194.12.128.0/17" ) # --- Helpers --- get_wifi_device() { /usr/sbin/networksetup -listallhardwareports | awk ' /^Hardware Port: (Wi-Fi|AirPort)$/ {f=1; next} f && /^Device:/ {print $2; exit} ' } get_service_for_device() { local dev="$1" /usr/sbin/networksetup -listnetworkserviceorder | awk -v d="$dev" ' /^\([0-9]+\)/ {svc=$0; sub(/^\([0-9]+\) /,"",svc); gsub(/[[:space:]]+$/,"",svc)} /Device: / && $0 ~ "Device: " d {print svc; exit} ' } get_default_if() { /sbin/route -n get default 2>/dev/null | awk '/interface:/{print $2; exit}' } get_gateway_ip() { /sbin/route -n get default 2>/dev/null | awk '/gateway:/{print $2; exit}' } cidr_match() { # cidr_match <ip> <cidr> python3 - "$1" "$2" <<'PY' import ipaddress,sys try: print(ipaddress.ip_address(sys.argv[1]) in ipaddress.ip_network(sys.argv[2], strict=False)) except Exception: print(False) PY } get_search_domains() { /usr/sbin/scutil --dns | awk -F': ' ' /^resolver #[0-9]+$/ {blk=1; next} blk && NF==0 {blk=0} blk && /^[[:space:]]*search domain/ {print $2} blk && /^[[:space:]]*domain/ {print $2} ' | sed 's/[[:space:]]*$//' } get_ssid() { local ssid dev dev="$(get_wifi_device || true)" # 0) networksetup with device (handles most cases) if [[ -n "${dev:-}" ]]; then if out=$(/usr/sbin/networksetup -getairportnetwork "$dev" 2>/dev/null); then # "Current Wi-Fi Network: <SSID>" or "You are not associated ..." if [[ "$out" =~ ^Current[[:space:]]Wi-?Fi[[:space:]]Network:\ (.*)$ ]]; then printf '%s\n' "${BASH_REMATCH[1]}"; return 0 fi fi fi # 1) system_profiler ssid="$(/usr/sbin/system_profiler SPAirPortDataType 2>/dev/null | awk ' /Current Network Information:/ {f=1; next} f && /^[[:space:]]*SSID:/ {sub(/^[[:space:]]*SSID:[[:space:]]*/,""); print; exit} f && NF==0 {f=0} ')" [[ -n "${ssid:-}" ]] && { printf '%s\n' "$ssid"; return 0; } # 2) ioreg ssid="$(/usr/sbin/ioreg -l | awk -F\" '/SSID_STR/ {print $4; exit}')" [[ -n "${ssid:-}" ]] && { printf '%s\n' "$ssid"; return 0; } # 3) scutil --nwi ssid="$(/usr/sbin/scutil --nwi 2>/dev/null | awk -F': ' '/SSID:/ {print $2; exit}')" [[ -n "${ssid:-}" ]] && { printf '%s\n' "$ssid"; return 0; } # 4) airport fallbacks for p in \ /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport \ /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport \ /System/Library/PrivateFrameworks/AppleWiFi.framework/Versions/Current/Resources/airport do [[ -x "$p" ]] || continue ssid="$("$p" -I 2>/dev/null | awk -F': ' '/ SSID/ {print $2; exit}')" [[ -n "${ssid:-}" ]] && { printf '%s\n' "$ssid"; return 0; } done return 1 } get_current_dns() { /usr/sbin/networksetup -getdnsservers "$1" 2>/dev/null | awk ' /^There (are|aren.t) any DNS Servers/ {print "Empty"; exit} {print} ' | paste -sd' ' - } set_dns_if_needed() { local service="$1" target="$2" current current="$(get_current_dns "$service")" if [[ "$target" == "$current" ]]; then echo "[dns] No change ($current) on $service" return fi if [[ "$target" == "Empty" ]]; then /usr/sbin/networksetup -setdnsservers "$service" Empty else # shellcheck disable=SC2086 /usr/sbin/networksetup -setdnsservers "$service" $target fi echo "[dns] Applied: $target on $service" } # --- Detect environment --- wifi_dev="$(get_wifi_device || true)" def_if="$(get_default_if || true)" prim_svc="$(get_service_for_device "${def_if:-}" || true)" ssid="$(get_ssid || true)" gw="$(get_gateway_ip || true)" domains="$(get_search_domains || true)" # CERN heuristics (any true -> use CERN DNS) cern_ssid=false cern_gw=false cern_domain=false [[ -n "${ssid:-}" && "$ssid" =~ $CERN_SSID_REGEX ]] && cern_ssid=true if [[ -n "${gw:-}" ]]; then for net in "${CERN_NETS[@]}"; do if [[ "$(cidr_match "$gw" "$net")" == "True" ]]; then cern_gw=true; break; fi done fi if printf '%s\n' "$domains" | grep -qiE '(^|[[:space:]])([^.]*\.)?cern\.ch$'; then cern_domain=true; fi echo "[ssid-dns] def_if=${def_if:-?} prim_svc=${prim_svc:-?} ssid=${ssid:-<none>} gw=${gw:-<none>}" echo "[ssid-dns] domains: $(printf '%s' "$domains" | tr '\n' ' | ')" echo "[ssid-dns] flags: CERN_SSID=$cern_ssid CERN_GW=$cern_gw CERN_DOMAIN=$cern_domain" # --- Decide target DNS --- target="$FALLBACK_DNS" # default if [[ -n "${ssid:-}" ]] && printf '%s\n' "${HOME_SSIDS[@]}" | grep -qx -- "$ssid"; then target="Empty" # home Wi-Fi -> router DNS elif $cern_ssid || $cern_gw || $cern_domain; then target="$CERN_DNS" # CERN -> CERN DNS fi # --- Apply --- if [[ -n "${prim_svc:-}" ]]; then set_dns_if_needed "$prim_svc" "$target" else echo "[dns] Could not resolve primary service; skipping change." fi # --- Show effective default resolver (resolver #1) --- /usr/sbin/scutil --dns | awk ' $0=="resolver #1" {f=1; next} f && NF==0 {f=0} f && /nameserver\[/ {print} '