aboutsummaryrefslogtreecommitdiff
path: root/src/vpn/README
blob: 50fb9b1197a620d04e697521d4fa65c7e4af8535 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
For Users
=========

To use the gnunet-vpn you have to have at least added "vpn" to the
"DEFAULTSERVICES" option of arm.

If you start gnunet now, you will get a new network-interface called gnunet-vpn
(you can rename it by adding the option "IFNAME" to a section called "vpn" in
your ~/.gnunet/gnunet.conf) with the IP addresses 1234::1/32 and 10.11.10.1/16
(Theese can be changed with "IPV6ADDR", "IPV6PREFIX", "IPV4ADDR" and
"IPV4MASK"). You "normal" internet-usage should not be impaired (check that!)
but you should be able to point your web browser to something like
http://gnunet.gnunet/ and get the gnunet webpage! That's it, you are set to use
gnunet to access legacy services!


Offering Services
-----------------

If you want to offer services such as your webpage via gnunet you have to have
add "exit" to the DEFAULTSERVICES and an entry like the following to
~/.gnunet/gnunet.conf:

#v+
[example.gnunet.]
ALTERNATIVE_NAMES = www
TCP_REDIRECTS = 80:example.com:80 22:localhost4:22
UDP_REDIRECTS = 69:tftp.example.com:69
TTL = 3600000
#v-

This entry creates the hostnames example.gnunet and www.example.gnunet and
send traffic to port 80 of this virtual host to the real host, sends traffic
on port 22 to your local machine (the machine running GnuNET) and traffic on
port 69 to tftp.example.com.

Note: The exit-daemon will also create a virtual network-interface with its
own set of IPv4 and IPv6 addresses. These addresses can be accessed by
localhost4 and localhost6 in the domain-configuration.

Now point you computer (or any other computer in the gnunet) to
http://example.gnunet/ and you will get your website.

Offering Internet Access
------------------------

Add "PROVIDE_EXIT = YES" to the section "dns" of your configuration if you
want to allow other peers to use your computer to resolve DNS-Queries.

If you want to allow other users to send traffic over your
internet-connection, add the options "ENABLE_UDP = YES" and "ENABLE_TCP = YES"
to the section "exit" of the configuration.

Be aware, that this enables people to use your internet connection for
nefarious things which might make you liable!

For Developers
==============

The gnunet-vpn is a combination of three programs:

- gnunet-daemon-vpn opens a tun-interface, configures it and controls the
  network
- gnunet-service-dns configures a hijack for outgoing DNS-requests, so that
  they get sent to gnunet-daemon-vpn, which sends them on to
  gnunet-service-dns which sends them on, either to their original destination
  or to gnunet. It also publishes names from dns.conf to the dht.
- gnunet-daemon-exit takes connections from the gnunet and sends them on to
  the legacy internet.

The gnunet-service-dns decides where to send the query with an easy check:

- it is a query for something.gnunet: it gets sent to the dht
- it is a query sent to the configured VIRT_DNS: it gets sent on to some other
  gnunet-service-dns somewhere in the gnunet (anyone having configured
  DNS_EXIT)
- else: it gets sent to the original destination

These programs exchange whole TCP- or UDP-packets, they only strip of the
IP-header. This way gnunet achieves translation between IPv6-services and
IPv4-clients and vice versa!

The gnunet-daemon-vpn receives packets on the tun-interface and routes them:
- everything to port 53 (dns) will be sent to the gnunet-service-dns
    replies to these queries will be sent from the gnunet-service-dns back to
    gnunet-daemon-vpn which will then fill in a newly generated IP-Adress, save
    it and a descriptor of what kind of address it is (for a .gnunet-service or for
    a "real" service) to a hashmap and send the reply back through the interface
- for every non-dns packet the hashmap is queried if the destination-adress is known
  if it is, the packet gets sent to either the peer advertising the service or
  (via the mesh by-type mechanism) to any peer that allows exit-functionality
- everything else is dropped

Hijacking the DNS-Traffic
-------------------------

For access to services provided via GNUNet we need to make sure that we can
inspect every DNS-Query made from the local machine. We briefly considered
replacing the configured nameserver (i.e. saving and then changing
\texttt{/etc/resolv.conf}) but rejected it out of practical considerations: A
plethora of tools change this file, \textit{resolvconf} and the
\textit{Network-Manager} being just the most prominent of them. We would have
to monitor this file for changes. This scheme would also run into problems if
some application would use its own nameserver without referring to
\texttt{/etc/resolv.conf}.

A solution based on \textit{destination NAT} was also rejected: Since the
captured packets would have no record of their original destination our
application would not know where to send the query if it should not be
answered internally.

We finally settled on a solution using \textit{policy based routing}. We would
\textit{MARK} every outgoing DNS-packet if it was not sent by our application.
Using a second routing table in the linux kernel these marked packets would be
routed through our virtual network interface and could thus be captured
unchanged.

Our application then reads the query and decides how to handle it: A query to
an address ending in \texttt{.gnunet} would be resolved internally using a
DHT. A reverse query for an address of the configured virtual network could be
answered with records kept about previous forward queries. A query sent
originally to our virtual address is resolved using the nearest peer that
provides name resolution. Every other query will be sent to the original
recipient. The answer to the query will always be sent back through the
virtual interface with the original nameserver as source address.

iptables -t mangle -I OUTPUT 1 -p udp --sport $LOCALPORT --dport 53 -j ACCEPT
iptables -t mangle -I OUTPUT 2 -p udp --dport 53 -j MARK --set-mark 3
ip rule add fwmark 3 table2
ip route add default via $VIRTUALDNS table2

Line 1 makes sure that all packets coming from a port our application opened
beforehand (\texttt{\$LOCALPORT}) will be routed normally. Line 2 marks every
other packet to a DNS-Server with mark $3$ (chosen arbitrarily). The third
line adds a routing policy based on this mark $3$ via the routing table
"table2" which is populated with just the default route.


Performance Measurements
========================

These tests were done between hosts (i7 with 2.67GHz and Core 2 with 2GHz)
connected by a switched Gigabit Ethernet.

scp direct (100MiB file):                                 33.3MiB/s (as shown by scp)
udp echo direct (6 Bytes of data):                        0.000333 (measured by tcpdump)

scp over gnunet (100MiB file, stopped after 5 minutes):   20KiB/s (as shown by scp)
udp echo over gnunet (6 Bytes of data):                   0.078410s (measured by tcpdump)