Last active
March 12, 2019 15:11
-
-
Save RichardBronosky/5775326605043798ad7ddcaf0073bf87 to your computer and use it in GitHub Desktop.
Tools for masking/spoofing/proxying DNS
This file contains 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 characters
#dnsmasq config, for a complete example, see: | |
# http://oss.segetech.com/intra/srv/dnsmasq.conf | |
#log all dns queries | |
log-queries | |
#dont use host's hosts file | |
no-hosts | |
addn-hosts=./etc/hosts | |
#dont use host's nameservers | |
no-resolv | |
servers-file=./etc/servers |
This file contains 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 characters
#!/bin/bash -eux | |
main(){ | |
( | |
cd $(script_dir) | |
cmd="$1" | |
[[ $cmd == kill ]] && cmd="kill_dnsmasq" | |
shift | |
$cmd "$@" | |
) | |
} | |
update_hosts(){ | |
mkdir -p etc | |
( | |
host_alias example.com dq1dnt4af4eyy.cloudfront.net | |
) > etc/hosts | |
} | |
run(){ | |
if [[ ${1:-} == "background" ]]; then | |
cmd=start_dnsmasq | |
shift | |
else | |
cmd=start_dnsmasq_foreground | |
fi | |
$cmd "$@" | |
} | |
kill_dnsmasq(){ | |
stop_dnsmasq | |
} | |
start(){ | |
update_hosts | |
update_servers | |
if [[ ${1:-} == "background" ]]; then | |
run "$@" && | |
use_local_dns | |
else | |
use_local_dns | |
trap 'restore_dns' EXIT | |
run "$@" | |
fi | |
} | |
stop(){ | |
kill | |
restore_dns | |
} | |
reload(){ | |
reload_dnsmasq | |
} | |
############################# | |
## Begin utility functions ## | |
############################# | |
ips_to_host(){ | |
# for each line in stdin, format as an etc/hosts entry for arg1 | |
# This simulates multiple A records | |
local host="$1" | |
awk -v host="$host" '{printf("%-16s %s\n",$0,host)}' | |
} | |
hostname_to_ips(){ | |
local host="$1" | |
dig +short "$host" | |
} | |
host_alias(){ | |
local src="$1" | |
local dst="$2" | |
hostname_to_ips $dst | ips_to_host $src | |
} | |
start_dnsmasq(){ | |
sudo /usr/local/sbin/dnsmasq --conf-file=dnsmasq.conf --pid-file="$(get_pid_file)" "$@" | |
} | |
start_dnsmasq_foreground(){ | |
# In dnsmasq -d is "no-daemon" mode which is backwards from many other apps | |
start_dnsmasq -d | |
# This is the production-ready way, but it doesn't respond to SIGINT | |
# start_dnsmasq --keep-in-foreground | |
} | |
signal_dnsmasq(){ | |
local msg="" | |
if [[ -f $pid_file ]]; then | |
local pid="$(cat $pid_file)" | |
if ps -p $(cat $pid_file) >/dev/null; then | |
sudo /bin/kill "$@" $(cat $pid_file) | |
else | |
msg="The dnsmasq pid ($pid) is not running." | |
fi | |
else | |
msg="The dnsmasq pid file ($pid_file) is not present." | |
fi | |
if [[ -n $msg ]]; then | |
echo "$msg" | |
exit 255; | |
fi | |
} | |
stop_dnsmasq(){ | |
signal_dnsmasq -TERM | |
} | |
reload_dnsmasq(){ | |
signal_dnsmasq -HUP | |
} | |
get_networksetup_device(){ | |
networksetup -listallnetworkservices | \ | |
grep "$( | |
route -n get ${1:-8.8.8.8} | \ | |
awk '$1=="interface:"{ | |
iface=$2 | |
} | |
END{ | |
if(iface=="en0"){iface="Wi-Fi"} | |
print iface | |
}' | |
)" | |
} | |
uniq_ips(){ | |
echo $(grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | sort | uniq) | |
} | |
set_dns(){ | |
networksetup -setdnsservers $(get_networksetup_device) "$@" | |
} | |
clear_dns(){ | |
set_dns Empty | |
} | |
current_resolv(){ | |
grep nameserver /etc/resolv.conf | |
} | |
update_servers(){ | |
local servers_file="$(get_servers_file)" | |
current_resolv | uniq_ips | for ip in $(cat); do echo "server=$ip"; done > $servers_file | |
} | |
use_local_dns(){ | |
current_resolv | uniq_ips > etc/resolv.ips.bak | |
set_dns 127.0.0.1 | |
} | |
restore_dns(){ | |
clear_dns | |
current_resolv | uniq_ips > etc/resolv.ips.tmp | |
if ! diff etc/resolv.ips.{bak,tmp} >/dev/null; then | |
set_dns $(cat etc/resolv.ips.bak) | |
fi | |
} | |
get_pid_file(){ | |
#bash -c "$(sed -n 's/pid-file/pid_file/; /pid_file/p;' < dnsmasq.conf);"' echo $pid_file' | |
echo "$PWD/etc/dnsmasq.pid" | |
} | |
get_servers_file(){ | |
bash -c "$(sed -n 's/servers-file/servers_file/; /servers_file/p;' < dnsmasq.conf);"' echo $servers_file' | |
} | |
script_dir(){ | |
echo "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | |
} | |
################ | |
## Always run ## | |
################ | |
pid_file="$(get_pid_file)" | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment