Skip to content

Instantly share code, notes, and snippets.

@username0x0a
Last active November 22, 2020 18:12
Show Gist options
  • Save username0x0a/2680b9ff505e3ccc9fd34677646cc913 to your computer and use it in GitHub Desktop.
Save username0x0a/2680b9ff505e3ccc9fd34677646cc913 to your computer and use it in GitHub Desktop.
Simple macOS Ruby script allowing to enforce VPN use for specified IPs and hostnames in case you're not into sending all your traffic via the connected VPN
#!/usr/bin/env ruby
# Check for arguments
def check_ip_ip_range(inp)
return inp =~ /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(\/[0-9]{1,2})?$/ ? true : false
end
if ARGV.count < 1 then
puts "Usage: enforcevpnhost [ip4|ip4net|hostname]"
puts "Examples: google.com | 1.1.1.1 | 1.1.1.1/24"
exit 1
end
# Check for root permission
if !Process.uid.zero? then
puts "[err] Root access required to alter routing table"
exit 1
end
# Assume the default VPN interface
iface = 'ppp0'
has_iface = `ifconfig -a | grep #{iface} | wc -l`.to_i > 0
# Check interface availability
if !has_iface then
puts '[err] No running VPN interface found'
exit 1
end
# Get currently set DNS servers
dnss = `scutil --dns | grep nameserver | awk '{print $3}'`.split("\n").uniq
# Fetch IPs for given hostnames
ips = [ ]
ARGV.each{|arg|
inp = arg.strip
if check_ip_ip_range(inp) then
ips << inp
else
dnss.each{|dns|
gotten = `dig @#{dns} +short +time=2 #{inp}`.strip.split("\n")
gotten.select!{|ip| check_ip_ip_range(ip) }
next if gotten.count == 0
gotten.map!{|ip| ip + '/24' }
ips.concat gotten
}
end
}
# Add routes to the routing table
ips.each{|ip| `route -nv add -net #{ip} -interface #{iface}` }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment