Coder Social home page Coder Social logo

salasberryfin / dns-over-tls-proxy Goto Github PK

View Code? Open in Web Editor NEW
0.0 3.0 0.0 39 KB

A basic proxy that allows clients to send standard DNS queries that are sent to DNS-over-TLS nameservers

License: GNU General Public License v3.0

Go 92.88% Dockerfile 3.63% Shell 3.50%

dns-over-tls-proxy's Introduction

Proxy DNS to DNS-over-TLS

This is a basic implementation of a proxy that listens for standard, non-secure, DNS requests and establishes a TLS connection with a DNS server that supports DNS-over-TLS -currently Cloudflare, but could be configured to use any other secure DNS server- and forwards the response to the original client.

This solution allows a client that doesn't support DNS-over-TLS to use a proxy that handles the DNS request with a TLS-compatible server.

Overview

  • Proxy starts a server that listens for DNS requests.
    • TCP Listener.
    • UDP Packet listener.
    • If the DNS query is sent to the UDP proxy, the data is first formatted by adding the length of the query.
  • A new connection is established with the DNS-over-TLS server.
    • The proxy starts a TLS handshake with the server.
    • The certificate received from the server is validated: hostname and expiration date.
  • The response from the DNS-over-TLS server is parsed a sent back to the client through the original connection.
    • If the DNS query was originally sent through UDP, data is truncated to create a valid UDP packet.

The process is transparent to the client, which doesn't need to be aware of the proxy configuration, and the server supports concurrent requests from multiple clients.

Build & Deploy

The proxy application can be built and deployed using docker compose:

docker compose up
  • It creates a container from an image built from the Dockerfile in the project folder.
  • The Go application is compiled and run.
  • Ports are exposed in the container for both TCP and UDP:
    • TCP container port: 53
    • UDP container port: 54
  • The compose file is configured to make the ports available to the host:
    • TCP host port: 5353
    • UDP host port: 5354

Test

Once the application is up and running, the proxy functionality can be tested using a tool like dig. dig doesn't support DNS-over-TLS, so it's a good way of simulating a real-world client for this type of application.

Considering the application is running with the default docker compose configuration:

  • Test TCP DNS resolution:
dig @127.0.0.1 -p 5353 google.com +tcp
  • Test UDP DNS resolution:
dig @127.0.0.1 -p 5354 google.com

The project includes a tests folder with two Bash scripts that send TCP/UDP requests every second that can be used to validate the server's concurrency.

Security Disclaimer

  • Due to the proxy implementation, the communication between the client application and the proxy is not secure and hence is still vulnerable to man-in-the-middle attacks.
  • DNS requests from the proxy to the DNS nameserver are encrypted but an eavesdropper can identify that DNS-encrypted traffic is going through port 853.
  • Privacy can still be a concern even when using an encrypted connection and the DNS server must be owned by a trusted entity.

Integration

Considering the massive use of the proxy, the deployment needs to be highly scalable.

  • Use a Kubernetes cluster for deployment
  • Define one pod with two containers:
    • Application: where the Go program runs.
    • Ambassador: proxy sitting between the application and the clients.
  • The application is deployed to a container where the Go binary is run.
    • This container exposes ports for TCP and UDP to containers in the pod.
  • The ambassador container, which can be an Nginx proxy.
    • This container includes an independent listener for each transport protocol.
  • Configure Horizontal Pod Autoscaling for the application.
  • Expose the service through a Load Balancer that manages traffic in case of scaling.

Improvements

  • Include protection mechanisms for clients:
    • DNS validation.
    • Blacklisting.
  • Improve performance by adding a cache of requested domains.
  • Handle invalid requests and error responses.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.