HOWTO Setup a VPN with tinc
From Gentoo Linux Wiki
| Installation • Kernel & Hardware • Networks • Portage • Software • System • X Server • Gaming • Non-x86 • Emulators • Misc |
TINC is a light VPN software that is easy to setup, secure, and is low on maintenance. In this HOWTO, we will use it to setup a VPN between two home networks.
The deamon has some great features, like the management of unresponsive nodes. If one side of the VPN goes down, the deamon on the other side will keep running and when it detects the other side coming back up, it will reestablish the connection.
It is also very easy to add has many nodes to the VPN, as tinc will forward to every nodes the subnet it knows about, but this is beyond the scope of this document.
Contents |
[edit] Assumptions
We will be assuming that you want to create a VPN between two home networks behind gentoo routers with iptables and NAT. We are also assuming that they those routers-firewalls are already in place and everything is working fine.
If your ISP gives your IP address through DHCP, I strongly suggest that you setup a service like dyndns.org, as we will be assuming that you do.
[edit] Network topology
We will use the following networks to build our VPN. It is easy to adapt it to other network topologies if you follow the HOWTO well.
Network A : 192.168.0.0/24 Network B : 10.1.1.0/24 Gateway A : 192.168.0.1 Gateway B : 10.1.1.1 FQDN A : networka.dyndns.org FQDN B : networkb.dyndns.org
Both gateways are iptables firewalls doing NAT. They will be running the tinc daemon so each network will be accessible from inside the other network.
[edit] Installing tinc
First of all, we need to install tinc on the gateways. The tinc ebuild does not take any USE flags, and it will pull in OpenSSL, lzo, and zlib if you do not already have them.
| Code: Installing tinc |
# emerge tinc |
[edit] Configuring the kernel
Tinc uses the Linux TUN/TAP network device, so we will have to add it to the kernel of both gateways.
| Linux Kernel Configuration: TUN/TAP device |
Device Drivers > Network device support: <*> Universal TUN/TAP device driver support |
Now, recompile your kernel and reboot with it.
[edit] Configuring tinc on gateway A
First of all, we will give a name to our vpn network, and since we have plenty of imagination, we will name it vpn. Tinc will need a directory to host all the configuration files for that network, so we will create it:
| Code: Creating configuration directory |
# cd /etc/tinc # mkdir vpn # cd vpn |
We then create the main configuration file:
| Code: Editing main configuration file |
# vi tinc.conf |
And we write this in it:
| File: /etc/tinc/vpn/tinc.conf |
Name = networka AddressFamily = ipv4 BindToInterface = eth0 ConnectTo = networkb Device = /dev/net/tun Mode = router KeyExpire = 3600 PrivateKeyFile = /etc/tinc/vpn/rsa_key.priv |
We then need to define the hosts in the VPN.
| Code: Creating hosts files |
# mkdir hosts # cd hosts # touch networka networkb |
Then edit the two files and configure them like this:
| File: /etc/tinc/vpn/hosts/networka |
Address = networka.dyndns.org Subnet = 192.168.0.0/24 |
| File: /etc/tinc/vpn/hosts/networkb |
Address = networkb.dyndns.org Cipher = blowfish Digest = sha1 IndirectData = yes Subnet = 10.1.1.0/24 |
We then create a script to execute when the VPN goes up:
| Code: Creating tinc-up script |
# cd /etc/tinc/vpn # vi tinc-up |
It will contain:
| File: /etc/tinc/vpn/tinc-up |
#!/bin/sh ifconfig vpn 192.168.0.1 netmask 255.255.0.0 up route add -net 10.1.1.0/24 vpn |
Notice that the netmask on the interface is not the same as the netmask of the home network. That is because we do want to interfere with the local network routing. It must be a larger subnet than the local network.
This next step is facultative, be we will do it anyway. We create another script to execute when the VPN goes down:
| Code: Creating tinc-down script |
# vi tinc-down |
And write this in it:
| File: /etc/tinc/vpn/tinc-down |
#!/bin/sh ifconfig vpn down |
Do not forget to set the execute permission on those two files!
| Code: Setting execute bit on scripts |
# chmod +x tinc-up # chmod +x tinc-down |
We must now make the init script aware of the networks we want it to start.
| Code: Setting networks to start with the init script |
# vi /etc/conf.d/tinc.networks |
| File: /etc/conf.d/tinc.networks |
NETWORK: vpn |
We then need to generate the keypair for this host:
| Code: Generating keypair |
# tincd -K -n vpn |
Accept the defaults for the file names and get to work on the next host.
[edit] Configuring tinc on gateway B
We will be doing essentially the same thing as on host A, but with some things simply inversed. Let us go over it quickly:
| Code: Creating configuration directory |
# cd /etc/tinc # mkdir vpn # cd vpn |
We create the main configuration file:
| Code: Editing main configuration file |
# vi tinc.conf |
| File: /etc/tinc/vpn/tinc.conf |
Name = networkb AddressFamily = ipv4 BindToInterface = eth0 ConnectTo = networka Device = /dev/net/tun Mode = router KeyExpire = 3600 PrivateKeyFile = /etc/tinc/vpn/rsa_key.priv |
We define the hosts in the VPN:
| Code: Creating hosts files |
# mkdir hosts # cd hosts # touch networka networkb |
| File: /etc/tinc/vpn/hosts/networkb |
Address = networkb.dyndns.org Subnet = 10.1.1.0/24 |
| File: /etc/tinc/vpn/hosts/networka |
Address = networka.dyndns.org Cipher = blowfish Digest = sha1 IndirectData = yes Subnet = 192.168.0.0/24 |
We then create the two scripts:
| Code: Creating tinc-up script |
# cd /etc/tinc/vpn # vi tinc-up |
| File: /etc/tinc/vpn/tinc-up |
#!/bin/sh ifconfig vpn 10.1.1.1 netmask 255.255.0.0 up route add -net 192.168.0.0/24 vpn |
| Code: Creating tinc-down script |
# vi tinc-down |
| File: /etc/tinc/vpn/tinc-down |
#!/bin/sh ifconfig vpn down |
Do not forget to set the execute permission on those two files!
| Code: Setting execute bit on scripts |
# chmod +x tinc-up # chmod +x tinc-down |
Set the network to start with the init script.
| Code: Setting networks to start with the init script |
# vi /etc/conf.d/tinc.networks |
| File: /etc/conf.d/tinc.networks |
NETWORK: vpn |
We then need to generate the keypair for this host:
| Code: Generating keypair |
# tincd -K -n vpn |
Accept the defaults for the file names.
[edit] Exchanging keypairs
We then need to make each host aware of the public key of the other host. Notice how on each host, there own host file now contains their public key, for example on host A:
| File: /etc/tinc/vpn/hosts/networka |
Address = networka.dyndns.org Subnet = 192.168.0.0/24 -----BEGIN RSA PUBLIC KEY----- MIGJAoGBAODloYJYBspV/9odnYa6qiscVd61X3gb3h9ypa0+RPXJF5MbC+Ve/7BZ umWmWLr9jzFY9NWAk5pu5kyjcZMfCYQtP0Xf7bS2q/jrevEZfV8WX0oYdQFDyHgg UTsOt/5xM555vGhIY7ZurmqE5Br26zJbxY8OALWIcbwpd060B8mrAgMBAAE= -----END RSA PUBLIC KEY----- |
This is really simple. Copy and paste the part of the key (including the BEGIN and END line), and paste it in the other host's file for that host.
Example, on host B:
| File: /etc/tinc/vpn/hosts/networka |
Address = networka.dyndns.org Cipher = blowfish Digest = sha1 IndirectData = yes Subnet = 192.168.0.0/24 -----BEGIN RSA PUBLIC KEY----- MIGJAoGBAODloYJYBspV/9odnYa6qiscVd61X3gb3h9ypa0+RPXJF5MbC+Ve/7BZ umWmWLr9jzFY9NWAk5pu5kyjcZMfCYQtP0Xf7bS2q/jrevEZfV8WX0oYdQFDyHgg UTsOt/5xM555vGhIY7ZurmqE5Br26zJbxY8OALWIcbwpd060B8mrAgMBAAE= -----END RSA PUBLIC KEY----- |
Do this for each hosts.
[edit] Setting up firewalls to allow VPN traffic
We need to let our VPN traffic through our firewall, so we will add some simple rules. These rules will open the ports used by tinc to the world (it does not matter, since we are using key authentication) and will let everything through on the VPN. Of course, you can write stricter rules if you prefer.
First, we will open the port 665 UDP and TCP to the world, assuming $EXTIF is your external interface and $EXTIP is your external IP:
| Code: Letting access to the tinc deamon through the firewall |
# iptables -A INPUT -i $EXTIF -p udp -d $EXTIP --dport 655 -j ACCEPT # iptables -A INPUT -i $EXTIF -p tcp -d $EXTIP --dport 655 -j ACCEPT |
We will also let everything in and out on interface vpn:
| Code: Letting everything in and out on interface vpn |
# iptables -A INPUT -i vpn -j ACCEPT # iptables -A OUTPUT -o vpn -j ACCEPT |
The rules are needed on the two gateways.
There is still one problem with our firewalls though, in that they will not let packets coming from inside the home networks through the vpn, or the opposite. Those rules will fix this:
| Code: Letting network A talk to the VPN - Execute this on Gateway A |
# iptables -A FORWARD -i vpn -o $INTIF -s 10.1.1.0/24 -d 192.168.0.0/24 -j ACCEPT # iptables -A FORWARD -i $INTIF -o vpn -s 192.168.0.0/24 -d 10.1.1.0/24 -j ACCEPT |
| Code: Letting network B talk to the VPN - Execute this on Gateway B |
# iptables -A FORWARD -i vpn -o $INTIF -s 192.168.0.0/24 -d 10.1.1.0/24 -j ACCEPT # iptables -A FORWARD -i $INTIF -o vpn -s 10.1.1.0/24 -d 192.168.0.0/24 -j ACCEPT |
Replace all $INTIF with the respective internal interface.
[edit] Start the services and test
The only thing left to do is to launch the services on both gateways:
| Code: Launching the tinc service |
# /etc/init.d/tincd start # rc-update add tincd default |
You can now test by pinging addresses on the other side of the VPN.
