Skip to content
Domain Validation++
Go Shell
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


Domain Validation++


The Domain Validation++ is a distributed domain ownership verification aiming to prevent identity theft. This is done by comparing the result of multiple servers on the internet which perform the validation. It consists of two parts: the agents that perform the validation of a given domain and the orchestrator that coordinates the validation by sending validation requests to all agents and verifying the result.

The agent and orchestrator implementation are written in Go. This does not only ensure a good performance it also allows the easy compilation and cross compilation of static executables. Static executables allow an easy deployment without the need to install any runtimes or libraries. Only the shell script to generate certificates requires OpenSSL or LibreSSL.


Copy the dv++ folder from src to the src folder of you go environment. Then issue the following commands.

  go get
  go get
  go get
  go build dv++/agent
  go build dv++/orchestrator



The orchestrator and the agents use HTTPS for their communication. Currently, only one cipher suite is allowed, TLS_RSA_WITH_AES_256_GCM_SHA384, which is supported by all major browsers and command line tools like curl thus making debugging easier.

Each agent has a self-signed certificate (can be generated with the included shell script) which are bound to the IP address. Also it’s possible to use domain names the use of domain names should be avoided. The orchestrator needs to have a copy of every certificate from the vantage points it is using. If the certificate used in the HTTPS connection is unknown for the orchestrator the connection will be canceled. The orchestrator does not include certificates from other sources (e.g. the operating system).


To perform a validation the orchestrator sends a GET requests like https://[user:pass@]ip:port/<methodname>/<parameter1>/.../<parametern> to each agent. Authentication with username and password is optional but strongly recommended. Additionally, the agent can allow only certain IP addresses or ranges. If the orchestrator is accepted the agent will perform the validation and return the result using a JSON object to the orchestrator. The orchestrator will then compare the result of all responses. The orchestrator will tolerate a user defined number of failed validations and choose the majority of the responses. If the tolerance is set to zero, which is the default, then all responses have to be valid for the validation to succeed.


The agent is a single executable and will try to load a configuration file upon start. It will search for /etc/dv++/agent.yml, ~/.dv++/agent.yml and ./agent.yml. If a configuration file is passed to the command line with the ‘-f’ option it will use this as its configuration file.


Usage of ./agent:
  -d string
        DNS servers
  -f string
        Config file
  -l string

The -d option will instruct the agent to use a supplied DNS server to initiate the initial DNS request. If this option is not supplied the value from /etc/resolv.conf will be used. Multiple DNS servers need to be separated by a comma. The agent will select a random DNS server then upon start. It is also possible to supply or omit the DNS port like ./agent -d, As mentioned before the -f is used to supply a configuration file. With the -l option the output is logged to a file.


Certificate: agent.crt
Key: agent.key
Port: 8268
    username: password

The Certificate and the Key fields define the certificate and its corresponding key file. The IP and Port fields define the IP and port the agent binds to. It is recommended to use random ports for each vantage point. The Users section defines user credentials in the form of username:password. This section can be omitted to disable authentication. The Whitelist field defines allowed IP addresses or ranges in CIDR notation. This section can also be omitted to allow all IP addresses.


Like the agent, the orchestrator is also single executable and will try to load a configuration file upon start. It will search for /etc/dv++/orchestrator.yml, ~/.dv++/orchestrator.yml and ./orchestrator.yml. If a configuration file is passed to the command line with the ‘-f’ option it will use this as its configuration file.


Usage of ./orchestrator:
  -f string
        Config file (default "orchestrator.yml")
  -l string
  -v    Verbose output
  -x    XML output

The -f is used to supply a configuration file. With the -l option the output is logged to a file. -v toggles verbose output which can be helpful for debugging. If the -x switch is used the orchestrator will output XML instead of JSON.


Timeout: 1000
Tolerance: 0
PoolSize: 0
Certificates: certs
        Port: 8268
        User: username
        Pass: password

The Timeout field defines how long the orchestrator should wait for an agent to respond. This includes the connection time. The Tolerance tells the orchestrator how many invalid responses are tolerated. Because timeouts count as failed validations it is recommended to set this to a number greater than zero if a sufficient number of agents is used. The PoolSize defines how many agents should be used. The orchestrator will randomly choose these agents for every validation. If it is smaller than zero or greater than the number of agents all agents are used. Certificates defines the directory that contains the certificates of all used agents. Only the certificates are needed and not the keys!

Finally, Agents defines the agents the orchestrator uses. Only the Host field is needed. However, if a different port is used or the server uses authentication (both is recommended) Port, User and Pass must also be supplied.


> ./orchestrator cname example.domain. challenge.example.domain. response.example.domain.
    "success": true,
    "response": "response.example.domain.",
    "errors": [
        "agent4: returned HTTP code 401"

=== or with xml ===

>  ./orchestrator -x cname example.domain. challenge.example.domain. response.example.domain.
        <error>agent4: returned HTTP code 401</error>

Depending on the success the orchestrator will exit with exit status 0 (success) or 1 (no success). All occurred errors are listed for each agent. In this example the tolerance was set to one.


Currently, only one method is allowed.


The CNAME validation queries a given DNS server (e.g. to receive the authoritative server for a given domain. It is recommended to set up a local unbound server on each agent and use this as the DNS server. The validation will then send a supplied DNS CNAME query (challenge) to the authoritative server and compare the response to the one that has been provided to the server. The challenges and responses must be chosen so that only the valid domain owner can set those (like e.g. the md5 or sha1 sum of the CSR).


In the misc directory example configuration for orchestrator and agents can be found and a script to generate certificates.

Certificate generation

A simple tool is provided to generate certificates for the vantage point servers. The example agent.cnf can be edited to contain the wanted information.

countryName = XX
stateOrProvinceName = SomeState
localityName = SomeCity
organizationalUnitName = My Company
commonName = My Company Agent 1

IP.1 =

# don't edit below this line
prompt = no
req_extensions = v3_req
distinguished_name = dn

basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

Only the entries in [dn] and [alt_names] have to be modified to match the desired organization information and IP address. The file name of the certificates will be based on the filename of the configuration file. So for agent.cnf the certificate will be agent.crt and the key will be agent.key. Simply invoke the and supply the configuration file:

> ./ agent.cnf
Generating RSA private key, 4096 bit long modulus
e is 65537 (0x10001)
Signature ok
subject=/C=XX/ST=SomeState/L=SomeCity/OU=My Company/CN=My Company Agent 1
Getting Private key

> ls* agent.cnf       agent.crt       agent.key


Domain Validation++

Copyright © 2018 Fraunhofer SIT

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation version 2.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, see

You can’t perform that action at this time.