minor edit
[robinkrens.nl] / tinc.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml">
4 <head>
5 <title>robinkrens.nl - TINC as a gateway</title>
6 <meta name="generator" content="HTML::TextToHTML v2.51"/>
7 <link rel="stylesheet" type="text/css" href="http://www.robinkrens.nl/files/style.css"/>
8 </head>
9 <body>
10 <h1><a name="section_1">robinkrens.nl - TINC as a gateway</a></h1>
11
12 <p>Tinc is a VPN daemon which tunnels IP packets and Ethernet frames over UDP. More on Tinc can be found on: <a href="http://tinc-vpn.org">http://tinc-vpn.org</a>
13 Here I will show a tinc setup with an <em>alpha</em> (as a listening peer) and a <em>beta</em> (a peer connecting to alpha).   After setting up the VPN, alpha will be the gateway for beta. All traffic from beta will be routed through alpha and back. I will basically retell the man page documentation: <a href="https://tinc-vpn.org/documentation-1.1/tinc.conf.5">https://tinc-vpn.org/documentation-1.1/tinc.conf.5</a> but in a more tutorial kind of way. 
14 </p>
15 <hr/>
16
17 <h2><a name="section_1_1">Alpha peer</a></h2>
18
19 <h3><a name="section_1_1_1">Create config files</a></h3>
20
21 <p><u>/etc/tinc/gatewayvpn/tinc.conf</u>
22         
23 </p><pre>
24         Name: alpha 
25         Device: /dev/net/tun
26 </pre>
27         
28 <p>The name will be used by other tinc daemons for identification. Device in here means the virtual network to bind to. Because we are going to use routing we use a tunneling device. For alpha we don't fill out a ConnectTo option, so alpha will passively listen for incoming connections.
29 </p>
30 <p><u>/etc/tinc/gatewayvpn/tinc-up</u>
31         
32 </p><pre>
33         #!/bin/sh
34         ip link set $INTERFACE up
35         ip addr add  172.16.16.1/24 dev $INTERFACE      
36 </pre>
37 <p>This is a shell script executed right after the tinc daemon has been started and has connected to the virtual network device.  It should be used to set up the corresponding network interface, but can also be used to start other things (as we show later for routing). $INTERFACE contains the name of our virtual network interface that the tinc daemon uses (in our case gatewayvpn). So later on, if you run tinc, it will show something like:
38 </p>
39 <pre>
40         $ ifconfig gatewayvpn
41         gatewayvpn   Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00  
42         inet addr:172.16.16.1  P-t-P:172.16.16.1  Mask:255.255.255.0
43         UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
44 </pre>
45 <p>We use an IP address in the private range: 172.16.16.0/24, but you can use any address that you like (i.e. 10.0.0.0). The /24 means the subnet in which the daemon is going to serve. Here, we assing 172.16.16.1 to alpha. 
46 </p>
47 <p><u>/etc/tinc/gatewayvpn/tinc-down</u>
48 </p>
49 <pre>
50         #!/bin/sh
51         ip addr del 172.16.16.1/24 dev $INTERFACE
52         ip link set $INTERFACE down
53 </pre>
54         
55 <p>Shell script that will be executed right before the tinc daemon is going to close its connection to the virtual network device. Similar to tinc-up, but in reverse.
56 </p>
57 <p><u>/etc/tinc/gatewayvpn/hosts/alpha</u>
58 </p>
59 <pre>
60         Address = 1.2.3.4
61         Port = 7999
62         Subnet = 0.0.0.0/0 
63 </pre>
64 <p>This file should be send to all the other peers (only beta in this example). We <u>create</u> this file here so we can automatically add a public key to this file. Since we want beta to connect to alpha we should assign the external IP and port number to it. Make sure this connection is accesible! We set the subnet to 0.0.0.0/0, you can read this as alpha serve on the <em>whole</em> internet (as opposed to a limiting it in a local range. If no Port option is specified, the socket will be bound to the standard port 655 of tinc.
65 </p>
66 <h3><a name="section_1_1_2">Create private keys</a></h3>
67
68 <pre>
69         $ root@alpha tincd -n gatewayvpn --generate-keys
70         Generating 2048 bits keys: ...........
71         Done
72         Please enter a file to save private RSA key to [/etc/tinc/gatewayvpn/rsa-key.priv]: 
73         Please enter a file to save public RSA key to [/etc/tinc/gatewayvpn/hosts/alpha]: 
74 </pre>
75 <p>Generate public/private RSA keypair. Private key will be written to <u>/etc/tinc/gatewayvpn/rsa-key.priv</u>. Public key will be written to all the files in /etc/tinc/gatewayvpn/hosts/*. So after running this command. <u>/etc/tinc/gatewayvpn/hosts/alpha</u> will look like this
76 </p>
77 <pre>
78         Address = 1.2.3.4
79         Port = 7999
80         Subnet = 0.0.0.0/0 
81
82         -----BEGIN RSA PUBLIC KEY-----
83         Blabla
84         -----END RSA PUBLIC KEY-----
85 </pre>
86 <h3><a name="section_1_1_3">Test your configuration</a></h3>
87
88 <p>Now alpha is setup. We can test our configuration as follows:
89 </p>
90 <pre>
91         root@alpha:~$ tincd -n gatewayvpn --logfile /root/log
92         root@alpha:~$
93 </pre>
94 <p>Logfile should show the following output:
95 </p>
96 <pre>
97         root@alpha:~# cat /root/log
98         2018-04-28 04:43:21 tinc.gatewayvpn[9589]: tincd 1.0.26 (Jul  5 2015 23:17:54) starting, debug level 0
99         2018-04-28 04:43:21 tinc.gatewayvpn[9589]: /dev/net/tun is a Linux tun/tap device (tun mode)
100         2018-04-28 04:43:21 tinc.gatewayvpn[9589]: Ready
101 </pre>
102 <p>You should also be able to ping to the tunneling device:
103         
104 </p><pre>
105         root@alpha:~$ ping 172.16.16.1
106         PING 172.16.16.1 (172.16.16.1) 56(84) bytes of data.
107         64 bytes from 172.16.16.1: icmp_seq=1 ttl=64 time=0.065 ms
108         64 bytes from 172.16.16.1: icmp_seq=2 ttl=64 time=0.060 ms
109         ^C
110         --- 172.16.16.1 ping statistics ---
111         2 packets transmitted, 2 received, 0% packet loss, time 999ms
112         rtt min/avg/max/mdev = 0.060/0.062/0.065/0.008 ms
113 </pre>
114 <p>The tinc daemon is listening on our configured port 7999:
115 </p>
116 <pre>
117         root@alpha:~$ netstat -pnaut
118         tcp        0      0 0.0.0.0:7999            0.0.0.0:               LISTEN      9828 tincd         
119         udp        0      0 0.0.0.0:7999            0.0.0.0:                           9828 tincd
120 </pre>
121 <h2><a name="section_1_2">Beta peer</a></h2>
122
123 <h3><a name="section_1_2_1">Create config files</a></h3>
124
125 <p><u>/etc/tinc/gatewayvpn/tinc.conf</u>
126         
127 </p><pre>
128         Name: beta 
129         Device: /dev/net/tun
130         ConnectTo: alpha
131 </pre>
132 <p>Beta will connect to alpha, for this connection beta will look in <u>/etc/tinc/gatewayvpn/hosts/alpha</u> and connect to this IP:PORT
133         
134 </p><p><u>/etc/tinc/gatewayvpn/tinc-up</u>
135         
136 </p><pre>
137         #!/bin/sh
138         ip link set $INTERFACE up
139         ip addr add  172.16.16.2/24 dev $INTERFACE      
140 </pre>
141 <p>Beta will get assigned 172.16.16.2
142 </p>
143 <p><u>/etc/tinc/gatewayvpn/tinc-down</u>
144 </p>
145 <pre>
146         #!/bin/sh
147         ip addr del 172.16.16.2/24 dev $INTERFACE
148         ip link set $INTERFACE down
149 </pre>
150         
151
152 <p><u>/etc/tinc/gatewayvpn/hosts/beta</u>
153 </p>
154 <pre>
155         Subnet = 172.16.16.2/32
156         Port = 7999
157 </pre>
158 <p>We don't need to set a Address. No peer will actively connect to this peer. The subnet will be limited to just the the peer itself, since it is not serving in any local network. 
159 </p>
160 <h3><a name="section_1_2_2">Create private keys</a></h3>
161
162 <pre>
163         tincd -n gatewayvpn --generate-keys
164         Generating 2048 bits keys: ...........
165         Done.
166         Please enter a file to save private RSA key to [/etc/tinc/gatewayvpn/rsa_key.priv]: 
167         Please enter a file to save public RSA key to [/etc/tinc/gatewayvpn/hosts/beta]:
168 </pre>
169 <p>So now you will also have created the private key file for beta. Public keys are written to files in the host directory.
170 *Note: don't forget to put <u>/etc/tinc/gatewayvpn/hosts/beta</u> on the alpha side and alpha on the beta side.
171 </p>
172 <pre>
173         root@beta:/etc/tinc/gatewayvpn/hosts$ sudo scp root@alpha:/etc/tinc/gatewayvpn/hosts/alpha .
174         alpha                                               100%  481     0.5KB/s   00:00    
175         root@beta:/etc/tinc/gatewayvpn/hosts$ sudo scp beta root@alpha:/etc/tinc/gatewayvpn/hosts/
176         beta                                                100%  463     0.5KB/s   00:00    
177 </pre>
178 <h3><a name="section_1_2_3">Test your configuration</a></h3>
179
180 <p>See alpha.
181 </p>
182 <h2><a name="section_1_3">Initial run</a></h2>
183
184 <p>Now let's see if the configuration is correct and both peers' connections are accepted. 
185 We, in a sense, have used a very verbose way to make a tunnel between two computers over the internet.
186 </p>
187 <p>First start alpha:
188         
189 </p><pre>
190         root@alpha:~$
191         root@alpha:~$ tincd -n gatewayvpn --log-file /root/log
192 </pre>
193 <p>Then start beta: 
194 </p>
195 <pre>
196         root@beta:~$
197         root@beta:~$ tincd -n gatewayvpn --log-file /root/log
198 </pre>
199 <p>Now test if you can ping!
200 </p>
201 <pre>
202         root@alpha:~# ping 172.16.16.2
203         PING 172.16.16.2 (172.16.16.2) 56(84) bytes of data.
204         64 bytes from 172.16.16.2: icmp_seq=1 ttl=64 time=118 ms
205         64 bytes from 172.16.16.2: icmp_seq=2 ttl=64 time=118 ms
206         64 bytes from 172.16.16.2: icmp_seq=3 ttl=64 time=118 ms
207
208         root@beta:~# ping 172.16.16.1
209         ping 172.16.16.1
210         PING 172.16.16.1 (172.16.16.1) 56(84) bytes of data.
211         64 bytes from 172.16.16.1: icmp_seq=1 ttl=64 time=118 ms
212         64 bytes from 172.16.16.1: icmp_seq=2 ttl=64 time=118 ms
213         64 bytes from 172.16.16.1: icmp_seq=3 ttl=64 time=117 ms
214 </pre>
215 <h2><a name="section_1_4">Routing gateway </a></h2>
216
217 <p>(Note: mostly copied from the tinc manual)
218 It is possible to have one peer forward all of its network traffic to another peer on the VPN, effectively using this peer as the default gateway. This behaviour can configured in the tinc-up or tinc-down scripts. First, we explain some theory about redirecting, then the example scripts will follow.
219 </p>
220 <h3><a name="section_1_4_1">Theory</a></h3>
221 <p>Normally, there are two entries in the routing table. One is the route for the local network, which tells the kernel which IP addresses are directly reachable. The second is the "default gateway", which tells the kernel that in order to reach the rest of the Internet, traffic should be sent to the gateway of the local network. Usually the gateway is a router or firewall device, and its IPv4 address usually ends in .1. An example output of route -n on Linux:
222 </p>
223 <pre>
224         Destination     Gateway         Genmask         Flags   Metric  Ref     Use     Iface
225         192.168.1.0     0.0.0.0         255.255.255.0   U       0       0       0       eth0
226         0.0.0.0         192.168.1.1     0.0.0.0         UG      0       0       0       eth0
227 </pre>
228 <p>Here, the LAN has the IPv4 address range 192.168.1.0/24, and the gateway is 192.168.1.1. Suppose we have a VPN with address range 172.16.16.0/24 (as in our case) on which a server (alpha in our setup) exists with address 172.16.16.1. If we have a VPN connection, and a peer wants to replace the standard default route with a default route pointing to 172.16.16.1, then there is a problem: the kernel does not know anymore how to send the encapsulated VPN packets to the server anymore. So we need to add an exception for traffic to the real (remote) IP address of the VPN server. Suppose its real address is 1.2.3.4, then the routing table should become:
229 </p>
230 <pre>
231         Kernel IP routing table
232         Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
233         172.16.16.1     0.0.0.0         255.255.255.255 UH    0      0        0 gatewayvpn
234         1.2.3.4         192.168.1.1     255.255.255.255 UGH   0      0        0 eth0
235         192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0
236         0.0.0.0         172.16.16.1     0.0.0.0         UG    0      0        0 gatewayvpn
237 </pre>
238 <p>This will ensure the local LAN is reachable, that the VPN server's real IP address is reachable via the original gateway, that the VPN server's VPN IP address is reachable on the vpn interface, and that all other traffic goes via the server on the VPN.
239 </p>
240 <p>It is better not to remove the original default gateway route, since someone might kill the tincd process, such that it doesn't get a chance to restore the original. Instead, we use a trick where we add two /1 routes instead of one /0 route:
241 </p>
242 <pre>
243         Kernel IP routing table
244         Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
245         172.16.16.1     0.0.0.0         255.255.255.255 UH    0      0        0 gatewayvpn
246         1.2.3.4         192.168.1.1     255.255.255.255 UGH   0      0        0 eth0
247         192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0
248         128.0.0.0       172.16.16.1     128.0.0.0       UG    0      0        0 gatewayvpn
249         0.0.0.0         172.16.16.1     128.0.0.0       UG    0      0        0 gatewayvpn
250         0.0.0.0         192.168.1.1     0.0.0.0         UG    0      0        0 eth0
251 </pre>
252 <p>Since both /1 cover all possible addresses, the real default route will never be used while the two /1 routes are present.
253 </p>
254 <h3><a name="section_1_4_2">Scripts</a></h3>
255
256 <p>To achieve this, two scripts are needed on beta. We can add the following code to the the already existing tinc-up and tinc-down files.
257 </p>
258 <p><u>/etc/tinc/gatewayvpn/tinc-up</u>
259 </p>
260 <pre>
261         #!/bin/sh
262         VPN_GATEWAY=172.16.16.1
263         REMOTEADDRESS=1.2.3.4
264         ORIGINAL_GATEWAY=`ip route show | grep ^default | cut -d ' ' -f 2-5`
265
266         ip route add $REMOTEADDRESS $ORIGINAL_GATEWAY
267         ip route add $VPN_GATEWAY dev $INTERFACE
268         ip route add 0.0.0.0/1 via $VPN_GATEWAY dev $INTERFACE
269         ip route add 128.0.0.0/1 via $VPN_GATEWAY dev $INTERFACE
270 </pre>
271 <p><u>/etc/tinc/gatewayvpn/tinc-down</u>
272 </p>
273 <pre>
274         #!/bin/sh       
275         ORIGINAL_GATEWAY=`ip route show | grep ^default | cut -d ' ' -f 2-5`
276         REMOTEADDRESS=1.2.3.4
277
278         ip route del $REMOTEADDRESS $ORIGINAL_GATEWAY
279         ip route del $VPN_GATEWAY dev $INTERFACE
280         ip route del 0.0.0.0/1 dev $INTERFACE
281         ip route del 128.0.0.0/1 dev $INTERFACE
282 </pre>
283 <p>These script use the iproute2 commands, because they are easier to work with. The VPN_GATEWAY and REMOTEADDRESS variables have to be filled in by hand. The ORIGINAL_GATEWAY variable copies the relevant information from the original default route to create the exception route to the VPN server.
284 </p>
285 <h3><a name="section_1_4_3">Setup firewall</a></h3>
286
287 <p>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 beta) packets, the source address in in the TCP/UDP package will still remain 172.16.16.2. Please have a look here: <a href="http://www.tldp.org/LDP/nag2/x-087-2-ipmasq.html">http://www.tldp.org/LDP/nag2/x-087-2-ipmasq.html</a> if you don't know about NAT and masquerading.
288 </p>
289 <pre>
290         #!/bin/sh
291         # iptables config line to masquerade
292         
293         echo "Enabling IPv4 forwarding"
294         echo 1 &gt;/proc/sys/net/ipv4/ip_forward
295         
296         echo "Appending Masquerade rule to iptables"
297         iptables -t nat -A POSTROUTING -s 172.16.16.0/255.255.255.0 -o eth0 -j MASQUERADE
298 </pre>
299 <p>Here I use iptables to masquerade the (-s) source address on the (-o) interface eth0. 
300 </p>
301 <h3><a name="section_1_4_4">Test the gateway</a></h3>
302
303 <p>Restart the daemon on alpha and beta. Use route -n to see check your routing table on beta. It should look similar to the one that is displayed above. Ping both the 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.
304 </p>
305 <h2><a name="section_1_5">Troubleshooting help</a></h2>
306
307 <ul>
308   <li>DNS request are not forwarded through the gateway. Check your resolver config files (/etc/resolv.conf). Debian-based systems might have the following configuration
309 </li></ul>
310 <pre>
311         root@beta:~$ cat /etc/resolv.conf       
312         # resolv.conf file
313         nameserver 127.0.1.0
314 </pre>
315 <ul>
316   <li>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
317         
318 </li></ul>
319 <pre>
320         IP ROUTING TABLE
321         link-local      *               255.255.0.0     U     1000   0        0 wlp7s0
322 </pre>
323 <ul>
324   <li>A simple fix would to change your resolv.conf and point it to nameserver 8.8.8.8
325         
326   </li><li>Check your logfile while running tinc (i.e. you might forgot to create a key pair):
327 </li></ul>
328 <pre>
329         2018-04-28 04:49:53 tinc.gatewayvpn[9684]: Error reading RSA private key file
330          `/etc/tinc/gatewayvpn/rsa_key.priv': No such file or directory
331 </pre>
332 <ul>
333   <li>Overview of created files
334         
335 </li></ul>
336 <pre>
337         root@alpha:~$ ls -R /etc/tinc/gatewayvpn
338         /etc/tinc/gatewayvpn:
339         hosts/  rsa-key.priv  tinc.conf  tinc-down  tinc-up
340         /etc/tinc/gatewayvpn/hosts:
341         alpha beta
342         
343         root@beta:~$ ls -R /etc/tinc/gatewayvpn
344         /etc/tinc/gatewayvpn:
345         hosts/ rsa-key.priv tinc.conf tinc-down tinc-up
346         /etc/tinc/gatewayvpn/hosts:
347         alpha beta
348 </pre>
349 <ul>
350   <li>Use tcpdump or wireshark to analyze your network devices
351 </li></ul>
352
353 </body>
354 </html>