convert to vimwiki
[robinkrens.nl] / docs / fastd.txt
1 Redirecting traffic using FastD
2 =====
3
4 FastD is a VPN daemon that has many features of OpenVPN and Tinc and is optimized for small code size and small number of dependencies. Fastd became popular on small devices like routers. In this tutorial we will configure a listening peer (alpha) and a connecting peer (anyremote). On a side note, with fastD you can setup mesh networks (n:n), as opposed to classical clients server networks (1:n). This configuration can be seen as a simple (1:1) setup between the listening *alpha* peer and our connecting client *anyremote*. All traffic from anyremote is redirected to alpha, making alpha the default gateway. This configuration has a lot of similarities with the tinc tutorial (that you can find here: http://www.robinkrens.nl/tutorials/tinc.html). Documentation and manual pages of fastd can be found here http://fastd.readthedocs.io
5
6 -------------- 
7
8 Alpha peer
9 ********** 
10
11 To run the daemon you only need one configuration file. You can place it in fastd's defualt directory _/etc/fastd/fastd.conf_. Here we show a standard configuration of _fastd.conf_ with some minor changes:
12
13         # Log warnings and errors to stderr
14         log level warn;
15
16         # Log everything to syslog
17         log to syslog level debug;
18
19         # tunnel mode (default is tap). 
20         # We use tunneling mode, since we are dealing with routing
21         mode tun;
22
23         # Set the interface name
24         # you can use any name you like
25         # this is the name to configure your interface wit
26         interface "vpngateway";
27
28         # encryption method to use
29         falls back to null if salsa is not chosen.
30         method "salsa2012+umac";
31         method "null";
32
33         # Bind to a fixed port, IPv4 only
34         # If your remote ip is 1.2.3.4, make sure 1.2.3.4:10000 is accesible
35         bind 0.0.0.0:10000;
36
37         # Secret key generated by `fastd --generate-key`
38         # --generate-key outputs a file with a secret and public key
39         # secret key goes in here. Public keys is distributed amongst other peers
40         # read about PKI infrastructures if you don't know about this.
41         secret "supersecretkey";
42
43         # (see MTU selection documentation)
44         # base MTU is 1500 and you want to use TUN mode over IPv4 with any 
45         # crypto method: Choose 1500 - 52 = 1448 bytes.
46         mtu 1448;
47
48         # on up: shell script to configure the tun interface on daemon start
49         on up "./interface-up";
50
51         # on down: shell script when daemon is terminated
52         on down "./interface-down"; 
53
54         # Include peers from the directory 'peers'
55         # anyremote is a peer trying to connect to alpha
56         include peer "peers/anyremote";
57
58 Keys can be generate by running --generate-key (written to stdout):
59         
60         root@alpha:~$ fastd --generate-key > keys
61         root@alpha:~$ cat keys
62         2018-04-30 19:25:57 +0800 --- Info: Reading 32 bytes from /dev/random...
63         Secret: 5035de5b4ea448b74e9a373765207095057a9485fd9dca5fadb9c1b86347bd75
64         Public: 8cb5e8d70d34f52716b6c4de518af2edfd6794e68ef1b3f0608cf05dd6a2ef42
65
66 The secret key needs to be added to the above _fastd.conf_ file. The public needs to be spread amongst peers (as we explain later).
67 on up "./interface-up" will run a simple shell script and configures our network interface vpngateway (make sure this script is executable).
68 This is our _interface.up_ script: We create a virtual IP: 172.16.16.1.
69
70         #!/bin/bash
71         ip link set $INTERFACE up
72         ip addr add 172.16.16.1/24 dev $INTERFACE
73
74 If we terminate fastd, we run a similar script as defined in interface-down
75         
76         #!/bin/sh
77         ip addr del 172.16.16.1/24 dev $INTERFACE
78         ip link set $INTERFACE down
79
80 We will create the _peer/anyremote_ file after we finished configuring anyremote and its public key
81
82 Anyremote peer
83 *********
84
85 Similar to alpha, we create _/etc/fastd/fastd.conf_. Since we only need to connect to alpha we don't need to bind to a fixed port. 
86
87         # log arnings and errors to stderr
88         log level warn;
89
90         # Log everything to syslog
91         log to syslog level debug;
92
93         # tunnel mode (default is tap)
94         mode tun;
95
96         # Set the interface name
97         interface "vpngateway";
98
99         # Support salsa2012+umac and null methods, prefer salsa2012+umac
100         method "salsa2012+umac";
101         method "null";
102
103         # Secret key generated by `fastd --generate-key`
104         secret "supersecretkey";
105
106         # (see MTU selection documentation)
107         mtu 1448;
108
109         # daemon start
110         on up "./interface-up";
111
112         # daemon terminated
113         on down "./interface-down";
114
115         # if a connection is established set up the gateway
116         on establish "./set-gateway";
117
118         # if the connection is lost restore the default gateway
119         on disestablish "./restore-gateway";
120
121         # Include peers from the directory 'peers'
122         include peer "peers/alpha";
123
124 For anyremote we also need to generate a key pair and replace the "supersecretkey" with the secret key value. The public key will be given to alpha (explained in a little while)
125
126         root@anyremote~ $ fastd --generate-keys > anyremote-keypair
127         root@anyremote~ $ cat anyremote-keypair
128         2018-05-01 19:48:49 +0800 --- Info: Reading 32 bytes from /dev/random...
129         Secret: c0a611e0d4f3075b45cf172d3221c8427008e2c6f541b5b6adda0368cb79f271
130         Public: 2598c5d7e72f171731658ce35734ff7599e1840367422e1a9c5943c327ab5ea9
131
132         
133 *on up* and *on down* are similar to alpha (except the ip address). interface-up:
134         
135         #!/bin/bash
136         ip link set $INTERFACE up
137         ip addr add 172.16.16.2/24 dev $INTERFACE
138         
139 interface-down:
140
141         #!/bin/sh
142         ip addr del 172.16.16.1/24 dev $INTERFACE
143         ip link set $INTERFACE down
144
145 We need to include some information about how to connect to alpha. We define in a file (_/etc/fastd/peers/alpha_):
146
147         root@anyremote:/etc/fastd/peers/ $ cat alpha
148         # alpha 
149         key "8cb5e8d70d34f52716b6c4de518af2edfd6794e68ef1b3f0608cf05dd6a2ef42";
150         remote 1.2.3.4:10000;
151
152 *key* means the public key we just created with --generate-keys the alpha section. Here we add a remote ip to which anyremote tries to connect to. Make sure port numbers are the same. 
153 Don't forget to also add our our just created public key to our alpha server:
154
155         root@alpha:/etc/fastd/peers/ $ cat anyremote
156         # anyremote
157         key "2598c5d7e72f171731658ce35734ff7599e1840367422e1a9c5943c327ab5ea9";
158
159 This will allow alpha to accept connections from anyremote. Note: you don't need to specify a remote address, this will make it more dynamic and you can connect with anyremote from anywhere as long as you have the private key.
160
161 After these steps you should be able to run both alpha and anyremote. You can run the daemon as follows:
162         
163         root@alpha:~ $ fastd -c /etc/fastd/fastd.conf &
164         root@anyremote:~ $ fastd -c /etc/fastd/fastd.conf &
165
166 The interface *vpngateway* should show up and you should be able to ping to both hosts us.
167         
168 Now, in our config file of anyremote we see two additionals values: *on establish* and *on disestablish*. Once the connection is (dis)established, fastd will execute these scripts. This brings us two the last step: setting the default gateway of anyremote to point to alpha
169
170 Alpha as gateway for anyremote
171 **********
172
173 Have a look at the tinc tutorial (gateway section) about the theory of routing and gateways.  
174 We add the following scripts in _/etc/fastd_ of anyremote if a connection with alpha is established: (set-gateway)
175         
176         #!/bin/bash
177         #ip link set $INTERFACE up
178         #ip addr add 172.16.16.2/24 dev $INTERFACE
179
180         VPN_GATEWAY=172.16.16.1
181         ORIGINAL_GATEWAY=`ip route show | grep ^default | cut -d ' ' -f 2-5`
182         REMOTEADDRESS=1.2.3.4
183
184         ip route add $REMOTEADDRESS $ORIGINAL_GATEWAY
185         ip route add $VPN_GATEWAY dev $INTERFACE
186         ip route add 0.0.0.0/1 via $VPN_GATEWAY dev $INTERFACE
187         ip route add 128.0.0.0/1 via $VPN_GATEWAY dev $INTERFACE
188         
189 And, similar, if the connecting is lost: (restore-gateway):
190
191         #!/bin/sh
192         #ip addr del 172.16.16.2/24 dev $INTERFACE
193         #ip link set $INTERFACE down
194
195         ORIGINAL_GATEWAY=`ip route show | grep ^default | cut -d ' ' -f 2-5`
196         REMOTEADDRESS=45.76.159.1
197
198         ip route del $REMOTEADDRESS $ORIGINAL_GATEWAY
199         ip route del $VPN_GATEWAY dev $INTERFACE
200         ip route del 0.0.0.0/1 dev $INTERFACE
201         ip route del 128.0.0.0/1 dev $INTERFACE
202
203
204 Setup firewall
205 *******
206
207 Make sure forwarding is enabled on alpha. Make sure you have masquerading or another form of routing set up on alpha. If you don't masquerade outgoing (forwarded anyremote) packets, the source address in in the TCP/UDP package will still remain 172.16.16.2. Please have a look here: http://www.tldp.org/LDP/nag2/x-087-2-ipmasq.html if you don't know about NAT and masquerading.
208
209         #!/bin/sh
210         # iptables config line to masquerade
211         
212         echo "Enabling IPv4 forwarding"
213         echo 1 >/proc/sys/net/ipv4/ip_forward
214         
215         echo "Appending Masquerade rule to iptables"
216         iptables -t nat -A POSTROUTING -s 172.16.16.0/255.255.255.0 -o eth0 -j MASQUERADE
217
218 I use iptables to masquerade the (-s) source address on the (-o) interface eth0. 
219
220
221 Test the gateway
222 ********
223
224 Restart the daemon on alpha and anyremote. Use route -n to see check your routing tables. Ping both 172.16.16.1 and 1.2.3.4 (external address). In case of problems, trace the connections or analyze the data with tools like wireshark.
225
226 Troubleshooting help
227 *******
228
229 * DNS request are not forwarded through the gateway. Check your resolver config files (/etc/resolv.conf). Debian-based systems might have the following configuration
230
231         root@anyremote:~$ cat /etc/resolv.conf  
232         # resolv.conf file
233         nameserver 127.0.1.0
234
235 * and in your routing table you might have the following entry. A local / caching DNS server might still send packages to your router. Use wireshark to see if there are any DNS queries, not going to the VPN gateway
236         
237         IP ROUTING TABLE
238         link-local      *               255.255.0.0     U     1000   0        0 wlp7s0
239
240 * A simple fix would to change your resolv.conf and point it to nameserver 8.8.8.8
241         
242 * Fastd's log to _/var/log/syslog_ You can define these locations in your fast.conf file. You can also change the log level, in case you need more information:
243
244         --log-level error|warn|info|verbose|debug|debug2
245         Sets the stderr log level; default is info if no alternative log
246         destination is configured.
247
248 * Use tcpdump or wireshark to analyze your network devices