Giter Club home page Giter Club logo

dns-proxy's Introduction

DNS Proxy

DNS proxy running on NodeJS. It acts as DNS server running locally, that returns specified fake responses for given particular host names, and passes real responses from upstream DNS server for others transparently byte-to-byte (so, these passed responses can be of any type, not necesarily supported by the application). Currently, the application supports forging responses of type "A" (IPv4 address) and "CNAME" (canonical name).

Forging of IPv6 responses is not supported. If request of type "AAAA" (IPv6) is received and hostname appears in list of hostnames to forge responses for, then "Not implemented" response is returned to sender. This is done for cases when local clients use both IPv4 and IPv6 protocols to resolve host IP. Otherwise, they could be able to fetch real IPv6 address, while getting fake IPv4 one.

Usage:

To start the application, open console in application root directory and run the command:

node index

On PC whose DNS requests should be proxied, set the IP address of PC running DNS Proxy. If this is one and the same PC, set 127.0.0.1.

Configuration File Options

Configuration is stored in config.json file in root directory of the project. Configuration parameters are defined as properties of that JSON file:

{
    "remoteDnsConnectionMode": "udp",
    "upstreamDnsUdpHost": "8.8.8.8",
    "upstreamDnsUdpPort": 53,
    "localDnsPort": 53,
    "forgedRequestsTTL": 10,
    "upstreamDnsTlsHost": "8.8.8.8",
    "upstreamDnsTlsPort": 853,

    "requestsToForge": []
}

Please mention: By default, the application has example config.json file with default settings listed above.

The file may be edited and saved while the proxy is running, the updated configuration will be fetched on the fly in this case, with no need to restart the application. The only exclusions are:

  • switching connection type from 'udp' to 'tls',
  • changing local connection parameters,
  • changing TLS connection parameters.

These changes will require restarting of the application.

As configuration is stored in JSON file, coments are not supported. As a workaround, one may add some arbitrarily named field, and fill its value with comment text, like:

"comment_1": "this is comment"

Upstream Connection Parameters

These parameters define how the application will connect to upstream (up-level) DNS server:

  • remoteDnsConnectionMode [udp or tls]: connection protocol for upstream DNS server. UDP and TLS are currently supported. Default: udp.
  • upstreamDnsUdpHost: IP address of upstream DNS server for UDP protocol (only one address is supported for now). Default: 8.8.8.8 (Google DNS).
  • upstreamDnsUdpPort: port to connect on upstream DNS server with UDP protocol. Default: 53.
  • upstreamDnsTlsHost: IP address of upstream DNS server for TLS protocol (only one address is supported for now). Default: 8.8.8.8 (Google DNS).
  • upstreamDnsTlsPort: port to connect on upstream DNS server with TLS protocol. Default 853.

upstreamDnsUdpHost and upstreamDnsUdpPort are required and applied only if remoteDnsConnectionMode is udp. And vise versa, upstreamDnsTlsHost and upstreamDnsTlsPort are required and applied only if remoteDnsConnectionMode is tls.

Local Connection Parameters

These parameters specify, how the application will accept incoming local connections from clients:

  • localDnsPort: local port for incoming connections. Default: 53 (standard DNS port).
  • forgedRequestsTTL: TTL (time to live) for forged responses, in seconds. Default: 10.

Incoming local requests are only accepted over UDP protocol.

Please mention: application accepts network connections on all available network interfaces. Whether you need to limit it, please concider using firewall.

Forging DNS response for particular requested host names

Hostnames and related responses are specified in requestsToForge section of the config. This section is in form of JSON array, where each target hostname is specified in separate array item, along with given response. The hostname to forge response for should be specified in hostName field of that item. Other fields of the item define parameters of the response that will be returned when that particulad hostname is requested.

     "requestsToForge": [
        {
            "comment": "Serve requests to 'example.com' locally, returning ip address 127.0.0.1",
            "hostName": "example.com",
            "ip": "127.0.0.1"
        },
        {
            "comment": "Serve requests to 'prod.example.com' like it is an alias for canonical name 'dev.example.com', i.e. CNAME behavior",
            "hostName": "prod.example.com",
            "cname": "dev.example.com"
        },
        {
            "comment": "Forward requests for subdomains of 'example.com' to local network ip 192.168.0.15",
            "hostName": "*.example.com",
            "ip": "192.168.0.15"
        },
        {
            "comment": "Serve requests to 'another-example.com' locally",
            "hostName": "another-example.com",
            "ip": "127.0.0.1"
        }
    ]

Please mention: four entrances mentioned above will present in default config as example, feel free to remove them before using the application.

Changes in this section are applied on the fly, without restarting the application.

Currently, the application supports mocking responses of type "A" (IPv4 address) and "CNAME" (canonical name).

Matching incoming requests' hostnames with these in requestsToForge section

Request hostnames may be specified literally (i.e. example.com) or using wildcard templates (like *.example.com, *example*, example.*.com or so). * symbol means that group of any symbols may appear in its place, including none symbols at all. Concider the following examples:

  • Pattern example.com will match hostname example.com and only it.
  • Pattern *example.com will match hostnames of a kind example.com and www.example.com.
  • Pattern *.example.com will match www.example.com and www.test.example.com, but NOT example.com.
  • Pattern *example* will match www.example.com, example.net and test-example.org.net.
  • Pattern test*.example.com will match test.example.com, test1.example.com, and test.test.test.example.com.

requestsToForge's items are iterated one by one, till the first match occurs. Say, if you have records with patterns *.example.com and www.example.com (in that order) in your config, and hostname www.example.com is requested, it will match first pattern *.example.com and stop on it, not reaching www.example.com record. So, the more specific records should be placed above the less specific ones in the config.

Forge IPv4 address in response

If you need to return specific IP address for given hostname, create a record in requestsToForge section, contaning the hostname in hostName field, and IP address in ip field respectively, like that:

        {
            "comment": "Serve requests to 'example.com' locally",
            "hostName": "example.com",
            "ip": "127.0.0.1"
        }

Edit it according to your needs, specifying proper hostName and ip.

Currently, only one IP can be set for specific hostname.

As mentioned above, if request of type "AAAA" (IPv6) matches the hostname, then "Not implemented" response is returned. So, if some local client sends two requests: one to resolve IPv4 address, and another for IPv6, then the application sends fake response for IPv4, and "Not implemented" for IPv6. Otherwise, client could bypass proxy and get real IPv6 address.

Forge CNAME response

Instead of fake IP, there is an ability to return response of CNAME type. In other words, application can return specific canonical name for given requested hostname, as if it was an alias for the returned hostname. To achieve that, add a record contaning hostName field with the target hostname (that we'll pretend is an alias), and cname field with fake canonical hostname, to requestsToForge section. Like the following:

        {
            "comment": "Serve requests to 'prod.example.com' like it is an alias for canonical name 'dev.example.com'",
            "hostName": "prod.example.com",
            "cname": "dev.example.com"
        }

If incoming request itself is of type CNAME, then forged response will contain fake canonical name only. If request is of type A (IPv4 address), then response, in addition to canonical name, will contain IP address(es) for it, resolving them with up-level DNS server. See explanation in RFC-1034, Section 5.2.2.

Tests

Tests are very basic, assuming that if running tests produce some output in console without throwing an error, they are concidered to pass. To run tests, in application root directory, run in console:

node tests/test.js

License

This project is licensed under the terms of the MIT license (see the LICENSE file in root directory of the project).

dns-proxy's People

Contributors

kolobok86 avatar vkolokolov avatar sevaontheweb avatar

Watchers

James Cloos avatar

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.