]> Cypherpunks.ru repositories - govpn.git/blob - README
Well, performance is not so high actually
[govpn.git] / README
1                                  GoVPN
2                                  =====
3 SYNOPSIS
4
5 govpn is simple secure virtual private network daemon.
6 It uses DH-EKE for mutual zero-knowledge authentication and
7 authenticated encrypted transport. It runs under GNU/Linux and FreeBSD.
8
9 DESCRIPTION
10
11 All packets captured on network interface are encrypted, authenticated
12 and sent to remote server, that writes them to his interface, and vice
13 versa. Client and server use pre-shared authentication key (PSK).
14 Because of stateless UDP nature, after some timeout of inactivity peers
15 forget about each other and have to retry handshake process again,
16 therefore background heartbeat process will be ran.
17
18 Handshake is used to mutually authenticate peers, exchange common secret
19 per-session encryption key and checks UDP transport availability.
20
21 Because of UDP and authentication overhead: each packet grows in size
22 during transmission, so you have to lower you maximum transmission unit
23 (MTU) on network interface.
24
25 High security is the goal for that daemon. It uses fast cryptography
26 algorithms with 128bit security margin, strong mutual zero-knowledge
27 authentication and perfect-forward secrecy property. An attacker can not
28 know anything from captured traffic, even if pre-shared key is
29 compromised. Rehandshake is performed by client every 4 GiB of
30 transfered data.
31
32 Also you can provide up and down scripts that will be executed after
33 either connection is initiated (up-script in background), or is went
34 down. The first argument for them is an interface name.
35
36 COMPARISON TO OpenVPN
37
38 * Faster handshake
39 * Perfect-forward secrecy (if long-term pre-shared keys are compromised,
40   no captured traffic can be decrypted anyway)
41 * Mutual two-side authentication (noone will send real network interface
42   data unless the other side is authenticated)
43 * Zero-knowledge authentication (pre-shared key is not transmitted in
44   any form between the peers, not even it's hash value)
45 * Fully IPv6 compatible
46
47 CONSOLE OUTPUT LEGEND
48
49 B -- bad or timeouted UDP packet (maybe network is inactive)
50 T -- bad tag on packet (MiTM, unordered packet)
51 R -- invalid sequence number (MiTM, unordered packet)
52 [HS?] -- unknown handshake message
53 w -- successful write to remote peer
54 r -- successful read from remote peer
55 [HS1], [HS2], [HS3], [HS4] -- handshake packet stage
56 [rS?] -- invalid server's random authentication number received (MiTM, bad PSK)
57 [rC?] -- invalid client's random authentication number received (MiTM, bad PSK)
58 [S?] -- invalid handshake stage is trying to perform (MiTM, duplicate packet)
59 [OK] -- handshake's stage passed
60
61 EXAMPLE USAGE
62
63 Let's assume that there is some insecure link between your computer and
64 WiFi-reachable gateway. You have got preconfigured wlan0 network
65 interface with 192.168.0/24 network. You want to create virtual
66 encrypted and authenticated 172.16.0/24 network and use it as a default
67 transport. MTU for that wlan0 is 1500 bytes. GoVPN will say that maximum
68 MTU for the link is 1476, however it does not take in account TAP's
69 Ethernet frame header length, that in my case is 14 bytes long (1476 - 14).
70
71     common% umask 066
72     common% echo MYLONG64HEXKEY > key.txt
73
74 GNU/Linux IPv4 client-server example:
75
76     server% ip addr add 192.168.0.1/24 dev wlan0
77     server% tunctl -t tap10
78     server% ip link set mtu 1462 dev tap10
79     server% ip addr add 172.16.0.1/24 dev tap10
80     server% ip link set up dev tap10
81     server% govpn -key key.txt -iface tap10 -bind 192.168.0.1:1194
82
83     client% ip addr add 192.168.0.2/24 dev wlan0
84     client% tunctl -t tap10
85     client% ip link set mtu 1462 dev tap10
86     client% ip addr add 172.16.0.2/24 dev tap10
87     client% ip link set up dev tap10
88     client% ip route add default via 172.16.0.1
89     client% while :; do govpn -key key.txt -iface tap10 -remote 192.168.0.1:1194; done
90
91 FreeBSD IPv6 client-server example:
92
93     server% ifconfig em0 inet6 fe80::1/64
94     server% ifconfig tap10 create
95     server% ifconfig tap10 inet6 fc00::1/96 mtu 1462 up
96     server% govpn -key key.txt -face tap10 -bind fe80::1%em0
97
98     client% ifconfig me0 inet6 -ifdisabled auto_linklocal
99     client% ifconfig tap10
100     client% ifconfig tap10 inet6 fc00::2/96 mtu 1462 up
101     client% route -6 add default fc00::1
102     client% while :; do govpn -key key.txt -iface tap10 -remote [fe80::1%me0]:1194; done
103
104 Example up-script:
105
106     client% cat > up.sh <<EOF
107     #!/bin/sh
108     dhclient $1
109     rtsol $1
110     EOF
111     client% chmod +x up.sh
112     client% govpn -key key.txt -iface tap10 -remote [fe80::1%me0]:1194 -up ./up.sh
113
114 If client won't finish handshake during -timeout, then it will exit.
115 If no packets are received from remote side during timeout, then daemon
116 will stop sending packets to the client and client will exit. In all
117 cases you have to rehandshake again.
118
119 TECHNICAL INTERNALS
120
121 Encryption: Salsa20
122 Message authentication: Poly1305
123 Password authenticated key agreement: Curve25519 based DH-EKE
124 Packet overhead: 24 bytes per packet
125 Handshake overhead: 4 UDP (2 from client, 2 from server) packets,
126                     232 bytes total payload
127
128                            Transport protocol
129
130     SERIAL + ENC(KEY, SERIAL, DATA) + AUTH(SERIAL + ENC_DATA)
131
132 where SERIAL is message serial number. Odds are reserved for
133 client->server, evens are for server->client. SERIAL is used as a nonce
134 for DATA encryption: encryption key is different during each handshake,
135 so (key, nonce) pair is always used once.
136
137 We generate Salsa20's output using this key and nonce for each message:
138 * first 256 bits are used as a one-time key for Poly1305 authentication
139 * next 256 bits of output are ignored
140 * and all remaining ones XORed with the data, encrypting it
141
142                            Handshake protocol
143      ┌──────┐                                  ┌──────┐
144      │Client│                                  │Server│
145      └──┬───┘                                  └──┬───┘
146         │────┐
147         │    │ R=rand(64bit); CPrivKey=rand(256bit)
148         │<───┘
149         │                                         │
150         │         R, enc(PSK, R, CPubKey)         │
151         │ ────────────────────────────────────────>
152         │                                         │
153         │                                         │────┐
154         │                                         │    │ SPrivKey=rand(256bit)
155         │                                         │<───┘
156         │                                         │
157         │                                         │────┐
158         │                                         │    │ K=DH(SPrivKey, CPubKey)
159         │                                         │<───┘
160         │                                         │
161         │                                         │────┐
162         │                                         │    │ RS=rand(64bit); SS=rand(256bit)
163         │                                         │<───┘
164         │                                         │
165         │ enc(PSK, R+1, SPubKey); enc(K, R, RS+SS)│
166         │ <────────────────────────────────────────
167         │                                         │
168         │────┐                                    │
169         │    │ K=DH(CPrivKey, SPubKey)            │
170         │<───┘                                    │
171         │                                         │
172         │────┐                                    │
173         │    │ RC=rand(64bit); SC=rand(256bit)    │
174         │<───┘                                    │
175         │                                         │
176         │          enc(K, R+1, RS+RC+SC)          │
177         │ ────────────────────────────────────────>
178         │                                         │
179         │                                         │────┐
180         │                                         │    │ compare(RS)
181         │                                         │<───┘
182         │                                         │
183         │                                         │────┐
184         │                                         │    │ MasterKey=SS XOR SC
185         │                                         │<───┘
186         │                                         │
187         │             enc(K, 0x00, RC)            │
188         │ <────────────────────────────────────────
189         │                                         │
190         │────┐                                    │
191         │    │ compare(RC)                        │
192         │<───┘                                    │
193         │                                         │
194         │────┐                                    │
195         │    │ MasterKey=SS XOR SC                │
196         │<───┘                                    │
197      ┌──┴───┐                                  ┌──┴───┐
198      │Client│                                  │Server│
199      └──────┘                                  └──────┘
200
201 * client generates CPubKey, random 64bit R that is used as a nonce
202   for encryption
203 * R + enc(PSK, R, CPubKey) + NULLs -> Server [56 bytes]
204 * server remembers clients address, decrypt CPubKey, generates
205   SPrivKey/SPubKey, computes common shared key K (based on
206   CPubKey and SPrivKey), generates 64bit random number RS and
207   256bit random SS. PSK-encryption uses incremented R (from previous
208   message) for nonce
209 * enc(PSK, SPubKey) + enc(K, RS + SS) + NULLs -> Client [88 bytes]
210 * client decrypt SPubKey, computes K, decrypts RS, SS with key K,
211   remembers SS, generates 64bit random number RC and 256bit random SC,
212 * enc(K, RS + RC + SC) + NULLs -> Server [64 bytes]
213 * server decrypt RS, RC, SC with key K, compares RS with it's own one
214   send before, computes final main encryption key S = SS XOR SC
215 * ENC(K, RC) + NULLs -> Client [24 bytes]
216 * server switches to the new client
217 * client decrypts RC and compares with it's own generated one, computes
218   final main encryption key S
219
220 Where PSK is 256bit pre-shared key, NULLs are 16 null-bytes. R* are
221 required for handshake randomization and two-way authentication. K key
222 is used only during handshake. NULLs are required to differentiate
223 common transport protocol messages from handshake ones. DH public keys
224 can be trivially derived from private ones.
225
226
227 RELATED DOCUMENTS
228
229 * http://cr.yp.to/ecdh.html
230 * http://cr.yp.to/snuffle.html
231 * http://cr.yp.to/mac.html
232 * http://grouper.ieee.org/groups/1363/passwdPK/contributions/jablon.pdf
233 * Applied Cryptography (C) 1996 Bruce Schneier
234
235 TODO
236
237 * Move decryption and encryption processes into goroutines
238 * Add identity management (client can send it's identification, server has
239   on-disk id↔key plaintext database)
240 * Implement alternative Secure Remote Password protocol (it is much slower,
241   technically has more code, but human memorized passwords can be used
242   instead of keys)
243
244 LICENCE
245
246 This program is free software: you can redistribute it and/or modify
247 it under the terms of the GNU General Public License as published by
248 the Free Software Foundation, either version 3 of the License, or
249 any later version.
250
251 This program is distributed in the hope that it will be useful,
252 but WITHOUT ANY WARRANTY; without even the implied warranty of
253 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
254 GNU General Public License for more details.