Public Repository

Last pushed: 2 years ago
Short Description
Official build of VPN-over-DNS Perl client.
Full Description

VPN-over-DNS client


For the impatient

docker run --rm -t -i fenyoa/vpnoverdns -S HOSTNAME

This command establishes a SSH over DNS tunnel to HOSTNAME (replace HOSTNAME by the remote host name or IP address of a node on the Internet). HOSTNAME need to be directly connected to the Internet. But your container does not need to !

What can I do with this image ?

This Docker image is the easiest way to run a container that establishes DNS tunnels to the free VPN-over-DNS tunneling service.

This image contains a command-line client written in Perl, that implements the VPN-over-DNS protocol (other clients with Graphical User Interface are available for Android, Windows, MacOSX, ...).

It is ready-to-use, pre-installed and pre-configured with an anonymous account.

What is VPN-over-DNS ?

VPN-over-DNS is a free DNS tunneling service.

DNS tunneling is simply encapsulating data over DNS queries and answers, to let two parties communicate across a network of DNS resolvers and servers.

What can I do with DNS tunneling ?

Hostels, airports, train stations often provide Internet access filtered by a captive portal, for which you need to buy a data plan. Many companies also filter Internet access through firewalls and web proxies.

VPN-over-DNS is used to bypass all these filters, for instance to establish a SSH connection from a private network to a host on the Internet. VPN-over-DNS also gives you access to an open web proxy.


Download the image

docker pull fenyoa/vpnoverdns

Get the manual page

docker run --rm fenyoa/vpnoverdns

Run in a container

Simply prepend "docker run --rm -t -i fenyoa/vpnoverdns" to your traditional command line. For instance, to connect to host HOSTNAME with SSH over DNS, just run:

docker run --rm -t -i fenyoa/vpnoverdns -S HOSTNAME

Log on a VPN-over-DNS account and use advanced features

You first need to run this image with the '-i' option. This will download you uuid to the container file /root/.vpnoverdns. To make this file persistent across multiple runs, first create an empty local uuid file (for instance /tmp/.vpnoverdns) and use the docker '-v' option each time you run a new container from this image:

 1- create your local uuid file:
    "rm -rf /tmp/.vpnoverdns ; touch /tmp/.vpnoverdns"

 2- initialize /tmp/.vpnoverdns with your uuid:
    "docker run --rm -t -i fenyoa/vpnoverdns \
                -v /tmp/.vpnoverdns:/root/.vpnoverdns \
                fenyoa/vpnoverdns -i username password"

 3- run
    "docker run --rm -t -i fenyoa/vpnoverdns \
                -v /tmp/.vpnoverdns:/root/.vpnoverdns \
                fenyoa/vpnoverdns -S"


This image has been built with the following Docker file:

FROM ubuntu:xenial
MAINTAINER Alexandre Fenyo <>
RUN apt-get update && apt-get install -y build-essential ssh perl liblwp-protocol-https-perl libxml-simple-perl
RUN wget -O /root/Net-DNS-0.68.tar.gz
RUN wget -O /usr/bin/
RUN chmod 755 /usr/bin/ && ln -s /usr/bin/ /usr/bin/vpnoverdns
RUN cd /root ; tar zxf Net-DNS-0.68.tar.gz ; cd Net-DNS-0.68 ; perl Makefile.PL ; make ; make install ; make clean ; cd .. ; rm -rf Net-DNS-0.68.tar.gz Net-DNS-0.68
RUN echo -n anonymou > /root/.vpnoverdns
CMD ["/usr/bin/perl", "/usr/bin/"]

Original documentation [-dvFnsp] [NUMERIC_OPTS] -i username password [-dv]                    -u uuid [-dv]                    -A [-dvFsg]  [NUMERIC_OPTS] -L [bind_address:]port:host:hostport [-dvFsp]  [NUMERIC_OPTS] -S host [-o ssh_options] [-C command] [-dvFsg]  [NUMERIC_OPTS] -X [-dvFs]   [NUMERIC_OPTS] -c [-dvFs]   [NUMERIC_OPTS] -w [-dvFs]   [NUMERIC_OPTS] -r NUM -h

User's manual:
Other versions:

General parameters and options:
 --help          -h     displays this help text
 --debug         -d     debug protocol
 --fast          -F     use faster protocol
                        normal protocol: IN A records only
                        faster protocol: IN TXT + IN A records
 --verbose       -v     verbose output
 --silent        -s     avoid bursting - as a consequence, average throughput
                        is decreased
 --initialize    -i     associates with a mobile account on the server farm,
                        call it once at first use
                        the username and password fields are protected with
                        an SSL channel
 --uuid NUM      -u NUM associates with an account uuid,
                        call it once at first use
                        the preferred way is to use "-i" option: use "-u"
                        only if "-i" is unavailable because of a lack
                        of some Perl mandatory modules for SSL communications
 --anonymous     -A     associates with an anonymous restricted account,
                        call it once at first use
 --nocertcheck   -n     do not check server certificate
                        (in case LWP::UserAgent->VERSION < 6)
 --global        -g     allows remote hosts to connect to local forwarded
                        ports - same meaning as -g with SSH(1)
 --local         -L     specifies that the given port on the local (client)
                        host is to be forwarded to the given host and port on
                        the remote side
                        same meaning as -L with SSH(1)
 --ssh           -S     connect to remote host using a DNS tunnel.
 --sshoptions    -o     ssh command options.
                        ex.: -S mysshserver -o "-l root"
 --sshcommand    -C     optionnal ssh remote command.
                        ex.: -S mysshserver -C date
 --proxy         -X     listen on local port 3128 and tunnel this port to
                        - an open web proxy (http + https) if a mobile account
                          has been previously configured (see "-i" and
                          "-u" options)
                        - a restricted http only proxy if an anonymous
                          restricted account has been configured (see "-A"
                          option). This proxy can be used to browse
                 and a few other sites.
 --checkmails    -c     check for new mails on the mail provider and retrieve
                        any pending mail
 --sendmail      -w     post a new mail
 --rtt NUM       -r NUM compute round trip time sending NUM requests
 --port          -p NUM listening TCP port used to relay SSL/TLS on top of DNS
                        when associating with a mobile account or when
                        tunneling a ssh connection

Numeric sub options relative to DNS queries behaviour only:
 --maxwrite NUM  -m NUM change the byte count sent in one request
                        the highest possible value is 30 (default value)
                        this parameter is ignored in fast mode
 --maxread NUM   -Y NUM change the byte count received in one request
                        the default value (64) may by increased to speed up
                        the tunnel
                        this parameter is ignored in fast mode
 --delay4msg NUM -M NUM waiting delay before retry (microseconds), only used
                        when the server has not immediately processed a message
                        default value: 200000
 --delay4req NUM -R NUM waiting delay before retrying a DNS request that has
                        been lost (microseconds)
                        note that the applied delay is this value multiplied by
                        the number of tries to send the request
                        default value: 1000000
 --maxdelay NUM  -a NUM maximum waiting delay (seconds) before retrying a DNS
                        default value: 8
 --parallel NUM  -P NUM maximum number of parallel requests
                        default value: 20
 --localbuf NUM  -b NUM maximum number of local bytes sent before requesting
                        for remote bytes
                        default value: 1024
 --delaychk NUM  -D NUM delay between two checks for remote data for a
                        redirected channel (microseconds); only used when no
                        need to send local data
                        default value: 200000
 --fuzzy NUM     -f NUM add a background noise made of NUM random requests
                        for each protocol request
                        default value: 0

Non trivial example

In this tutorial, we will see how to get web content through a proxy.

First, we need to initialize our uuid, based on our VPN-over-DNS free account:

rm -rf /tmp/.vpnoverdns ; touch /tmp/.vpnoverdns
docker run --rm -t -i fenyoa/vpnoverdns \
           -v /tmp/.vpnoverdns:/root/.vpnoverdns \
           fenyoa/vpnoverdns -i USERNAME PASSWORD

Now we launch a container :

  • that listen to port TCP/3128 on the container side and connects to a proxy on the vpn server farm; for this purpose, we simply use the following Perl client option: '--proxy';
  • that accept "external" connections to port TCP/3128; note that the docker host is an "external" host from the container point of view. The Perl client inside the container must not only listen on the container loopback network interface, but on every interfaces; for this purpose, we simply use the following Perl client option: '--global';
  • that expose the TCP/3128 port; for this purpose, we simply use the following "docker run" option: '-p 3128:3128'

So, we run the following command line:

docker run --rm -t -i -v /tmp/.vpnoverdns:/root/.vpnoverdns \
           -p 3128:3128 fenyoa/vpnoverdns \
  --proxy --global

We may add the '--debug' option after '--global', in order to see DNS queries and responses.

Note that to stop this container, ^C [SIGINT] will not work, instead we need to launch:

docker ps | grep fenyoa/vpnoverdns \
          | awk '{ print $1; }' | xargs docker stop

Finally, to use this DNS proxy, we do not stop the container and we now launch the following commands in another shell on our docker host:

export http_proxy=http://localhost:3128

you may try TXT records instead of A records, to improve throughput. Just add the Perl client '--fast' option. Your download should run 3 times faster!


  • without the '--fast' option, using only A records, you should get about 30 kbit/s
  • using the '--fast' option, using TXT records, you should get about 100 kbit/s
Docker Pull Command