Last active
March 22, 2020 15:39
-
-
Save icy/aede7b6bf5ac153073828734497808b4 to your computer and use it in GitHub Desktop.
my-dns-resolver.rb
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 characters
#!/usr/bin/env ruby | |
# Purpose : Extremely stupid dns resolver for laptop | |
# Author : Ky-Anh Huynh | |
# License : MIT | |
# Requirements | |
# | |
# * dnscrypt-proxy, or another upstream listen on 127.0.0.1:52 | |
# * NetworkManager | |
# * Enable this dns resolver and make /etc/resolv.conf immutable | |
# ( rm /etc/resolv.conf; echo nameserver 127.0.0.1 > /etc/resolv.conf; chattr +i /etc/resolv.conf ;) | |
# | |
# Dealing with captive portal (Remember to remove them after you're connected :D) | |
# | |
# $ sudo touch /root/enable_isp | |
# | |
require 'rubydns' | |
LISTEN_PORT = (ENV["MDNS_PORT"].to_s.empty? ? 53 : ENV["MDNS_PORT"].to_i) | |
# Where we are listening on | |
INTERFACES = [ | |
[:udp, "0.0.0.0", LISTEN_PORT], | |
[:tcp, "0.0.0.0", LISTEN_PORT], | |
] | |
# Alias | |
IN = Resolv::DNS::Resource::IN | |
# The main upstream | |
UPSTREAM = RubyDNS::Resolver.new( | |
[ | |
[:udp, "127.0.0.1", 52], | |
[:tcp, "127.0.0.1", 52], | |
]) | |
# To use the ISP/router resolvers, just touch a file | |
# $ sudo touch /root/enable_isp | |
# | |
# FIXME: We don't have cache here, so it's a bit slow ;) | |
def next_upstream | |
isp_resolv_conf = "/run/NetworkManager/resolv.conf" | |
resolvers = [] | |
if File.exist?("/root/enable_isp") and File.exist?(isp_resolv_conf) | |
STDERR.puts "using isp dns resolvers..." | |
lines = File.open(isp_resolv_conf, "r").readlines | |
lines.each do |line| | |
if gs = line.match(/^nameserver (.+)/) | |
STDERR.puts "found isp dns resolver: #{gs[1]}" | |
resolvers << gs[1] | |
end | |
end | |
end | |
if resolvers.size > 0 | |
STDERR.puts "using upstream: #{resolvers}" | |
ret = RubyDNS::Resolver.new(resolvers.map{|ip| [:udp, ip, 53]}) | |
else | |
STDERR.puts "using default upstream on your localhost" | |
ret = UPSTREAM | |
end | |
return ret | |
end | |
RubyDNS::run_server(INTERFACES) do | |
# This is just an example for fun | |
match("incoming.telemetry.mozilla.org") do |t| | |
t.respond!("127.0.0.1") | |
end | |
# Your own domains | |
match(%r{kyanh.net}, IN::A) do |t| | |
my_ip = "192.168.192.168" | |
my_ip = "127.0.0.1" | |
STDERR.puts "client #{t.options[:remote_address].ip_address} asked #{t.question} got #{my_ip}" | |
t.respond!(my_ip) | |
end | |
otherwise do |t| | |
t.passthrough!(next_upstream) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment