Skip to content

Instantly share code, notes, and snippets.

@ahmgeek
Created July 20, 2021 19:53
Show Gist options
  • Save ahmgeek/813f653546a14fd04e33879c95987f27 to your computer and use it in GitHub Desktop.
Save ahmgeek/813f653546a14fd04e33879c95987f27 to your computer and use it in GitHub Desktop.
Dns To Dns Over TLS tcp proxy
require 'socket'
require "openssl"
require "logger"
HOST = "cloudflare-dns.com"
REMOTE_DNS = "1.1.1.1"
REMOTE_PORT = 853
LOCAL_PORT = 53
BLOCK_SIZE = 1024
LOGGER = Logger.new(STDOUT)
class DNServe
def initialize
self.local_server = TCPServer.open(LOCAL_PORT)
LOGGER.info("listening on port ::53")
end
def run
loop do
server = local_server.accept
connect(server)
end
end
private
attr_accessor :local_server, :remote_server
def remote_server_connection
tcp_socket = TCPSocket.new(REMOTE_DNS, REMOTE_PORT)
ctx = OpenSSL::SSL::SSLContext.new("TLSv1_2")
ctx.alpn_protocols = ["dot"]
remote = OpenSSL::SSL::SSLSocket.new(tcp_socket, ctx)
remote.sync_close = true
remote.hostname = HOST
remote.connect
remote.post_connection_check HOST
remote
end
def connect(local_server)
remote_server = remote_server_connection
# start reading from both ends
loop do
ready = IO.select([local_server, remote_server])
if ready.first.include? local_server
data = local_server.recv(BLOCK_SIZE)
break if data.empty?
remote_server.syswrite(data)
end
if ready.first.include? remote_server
data = remote_server.sysread(BLOCK_SIZE)
break if data.empty?
local_server.write(data)
end
end
local_server.close
remote_server.close
end
end
# Run the server
d = DNServe.new
d.run
@ahmgeek
Copy link
Author

ahmgeek commented Jul 20, 2021

Usage:

ruby dnserve.rb

dig +tcp ahmgeek.com @localhost

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment